39 #include "irplib_utils.h"
41 #include "isaac_utils.h"
42 #include "isaac_wavelength.h"
43 #include "isaac_physicalmodel.h"
44 #include "isaac_pfits.h"
45 #include "isaac_dfs.h"
51 static int isaac_spc_wlcalib_create(cpl_plugin *);
52 static int isaac_spc_wlcalib_exec(cpl_plugin *);
53 static int isaac_spc_wlcalib_destroy(cpl_plugin *);
54 static int isaac_spc_wlcalib(cpl_parameterlist *, cpl_frameset *);
55 static cpl_table * isaac_spc_wlcalib_compute(
const char *,
const char *,
56 const char *,
const char *);
57 static int isaac_spc_wlcalib_save(
const cpl_table *,
int, cpl_parameterlist *,
77 } isaac_spc_wlcalib_config;
79 static char isaac_spc_wlcalib_description[] =
80 "isaac_spc_wlcalib -- ISAAC wavelength calibration recipe\n"
81 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
82 "oh-cat.fits "ISAAC_CALPRO_OH_CAT
" or\n"
83 "xe-cat.fits "ISAAC_CALPRO_XE_CAT
" or\n"
84 "ar-cat.fits "ISAAC_CALPRO_AR_CAT
"\n";
99 int cpl_plugin_get_info(cpl_pluginlist * list)
101 cpl_recipe * recipe = cpl_calloc(1,
sizeof(*recipe));
102 cpl_plugin * plugin = &recipe->interface;
104 cpl_plugin_init(plugin,
106 ISAAC_BINARY_VERSION,
107 CPL_PLUGIN_TYPE_RECIPE,
109 "Spectro wavelength calibration",
110 isaac_spc_wlcalib_description,
114 isaac_spc_wlcalib_create,
115 isaac_spc_wlcalib_exec,
116 isaac_spc_wlcalib_destroy);
118 cpl_pluginlist_append(list, plugin);
133 static int isaac_spc_wlcalib_create(cpl_plugin * plugin)
139 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
140 recipe = (cpl_recipe *)plugin;
141 else return CPL_ERROR_UNSPECIFIED;
144 recipe->parameters = cpl_parameterlist_new();
148 p = cpl_parameter_new_value(
"isaac.isaac_spc_wlcalib.rejected",
149 CPL_TYPE_STRING,
"left right bottom top rejections",
150 "isaac.isaac_spc_wlcalib",
"-1 -1 100 100");
151 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rej");
152 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
153 cpl_parameterlist_append(recipe->parameters, p);
155 p = cpl_parameter_new_value(
"isaac.isaac_spc_wlcalib.max_offset",
156 CPL_TYPE_INT,
"maximum offset from the physical model "
157 "allowed in pixels",
"isaac.isaac_spc_wlcalib", 50);
158 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"max_offset");
159 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
160 cpl_parameterlist_append(recipe->parameters, p);
162 p = cpl_parameter_new_value(
"isaac.isaac_spc_wlcalib.lines", CPL_TYPE_INT,
163 "1 for oh, 2 for xe, 3 for ar, 4 for xe+ar",
164 "isaac.isaac_spc_wlcalib", -1);
165 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lines");
166 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
167 cpl_parameterlist_append(recipe->parameters, p);
178 static int isaac_spc_wlcalib_exec(cpl_plugin * plugin)
183 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
184 recipe = (cpl_recipe *)plugin;
185 else return CPL_ERROR_UNSPECIFIED;
187 return isaac_spc_wlcalib(recipe->parameters, recipe->frames);
197 static int isaac_spc_wlcalib_destroy(cpl_plugin * plugin)
202 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
203 recipe = (cpl_recipe *)plugin;
204 else return CPL_ERROR_UNSPECIFIED;
206 cpl_parameterlist_delete(recipe->parameters);
218 static int isaac_spc_wlcalib(
219 cpl_parameterlist * parlist,
220 cpl_frameset * framelist)
223 cpl_frame * cur_frame;
224 const char * cur_fname;
236 par = cpl_parameterlist_find(parlist,
"isaac.isaac_spc_wlcalib.rejected");
237 sval = cpl_parameter_get_string(par);
238 if (sscanf(sval,
"%d %d %d %d",
239 &isaac_spc_wlcalib_config.rej_left,
240 &isaac_spc_wlcalib_config.rej_right,
241 &isaac_spc_wlcalib_config.rej_bottom,
242 &isaac_spc_wlcalib_config.rej_top) != 4) {
243 return CPL_ERROR_UNSPECIFIED;
247 par = cpl_parameterlist_find(parlist,
"isaac.isaac_spc_wlcalib.max_offset");
248 isaac_spc_wlcalib_config.max_offset = cpl_parameter_get_int(par);
251 par = cpl_parameterlist_find(parlist,
"isaac.isaac_spc_wlcalib.lines");
252 isaac_spc_wlcalib_config.lines_table=cpl_parameter_get_int(par);
255 if (isaac_spc_wlcalib_config.lines_table < 1) {
256 cpl_msg_error(cpl_func,
"Please specify the catalog");
257 return CPL_ERROR_UNSPECIFIED;
266 cur_frame = cpl_frameset_get_position(framelist, 0);
267 cur_fname = cpl_frame_get_filename(cur_frame);
268 cpl_msg_info(cpl_func,
"Reduce %s", cur_fname);
269 cpl_msg_indent_more();
272 if ((tab = isaac_spc_wlcalib_compute(cur_fname, oh, ar, xe)) == NULL) {
273 cpl_msg_warning(cpl_func,
"cannot reduce");
276 if (isaac_spc_wlcalib_save(tab, 1, parlist, framelist) != 0) {
277 cpl_msg_warning(cpl_func,
"cannot save");
279 cpl_table_delete(tab);
281 cpl_msg_indent_less();
298 static cpl_table * isaac_spc_wlcalib_compute(
299 const char * in_name,
308 computed_disprel * disprel;
310 const char * lines_tab;
313 if ((slit_width = isaac_get_slitwidth(in_name)) == -1) {
314 cpl_msg_error(cpl_func,
"cannot get the slit width");
319 if ((order = isaac_find_order(in_name)) == -1) {
320 cpl_msg_error(cpl_func,
"cannot get the order");
325 cpl_msg_info(cpl_func,
"Compute the physical model");
326 cpl_msg_indent_more();
328 cpl_msg_error(cpl_func,
"cannot estimate the dispersion relation");
329 cpl_msg_indent_less();
332 cpl_msg_info(cpl_func,
"f(x)=%g + %g*x + %g*x^2 + %g*x^3",
333 phdisprel[0], phdisprel[1], phdisprel[2], phdisprel[3]);
334 cpl_msg_indent_less();
337 if ((in = cpl_image_load(in_name, CPL_TYPE_FLOAT, 0, 0)) == NULL) {
338 cpl_msg_error(cpl_func,
"cannot load the image");
344 switch (isaac_spc_wlcalib_config.lines_table) {
345 case 1: lines_tab =
"oh";
break;
346 case 2: lines_tab =
"Xe";
break;
347 case 3: lines_tab =
"Ar";
break;
348 case 4: lines_tab =
"Xe+Ar";
break;
350 cpl_image_delete(in);
353 cpl_msg_info(cpl_func,
"Compute the dispersion relation");
354 cpl_msg_indent_more();
355 if ((disprel = spectro_compute_disprel(in,
356 isaac_spc_wlcalib_config.rej_bottom,
357 isaac_spc_wlcalib_config.rej_top,
358 isaac_spc_wlcalib_config.rej_left,
359 isaac_spc_wlcalib_config.rej_right,
360 isaac_spc_wlcalib_config.max_offset,
361 isaac_has_thermal(in_name) > 0,
362 lines_tab, oh, ar, xe, slit_width, order,
363 (
int)(cpl_msg_get_level() == CPL_MSG_DEBUG),
364 phdisprel)) == NULL) {
365 cpl_msg_error(cpl_func,
"cannot compute the dispersion relation");
366 cpl_image_delete(in);
368 cpl_msg_indent_less();
371 cpl_image_delete(in);
374 cpl_msg_info(cpl_func,
"Cross correlation factor: %g", disprel->cc);
375 cpl_msg_info(cpl_func,
"f(x)=%g + %g*x + %g*x^2 + %g*x^3",
376 disprel->poly[0], disprel->poly[1], disprel->poly[2],
378 cpl_msg_indent_less();
381 out_tab = cpl_table_new(4);
384 cpl_table_new_column(out_tab,
"WL_coefficients", CPL_TYPE_DOUBLE);
385 cpl_table_set_double(out_tab,
"WL_coefficients", 0, disprel->poly[0]);
386 cpl_table_set_double(out_tab,
"WL_coefficients", 1, disprel->poly[1]);
387 cpl_table_set_double(out_tab,
"WL_coefficients", 2, disprel->poly[2]);
388 cpl_table_set_double(out_tab,
"WL_coefficients", 3, disprel->poly[3]);
389 isaac_spc_wlcalib_config.disprel_cc = disprel->cc;
390 isaac_spc_wlcalib_config.disprel_clines = disprel->clines;
391 isaac_spc_wlcalib_config.disprel_dlines = disprel->dlines;
392 isaac_spc_wlcalib_config.disprel_rms = disprel->rms;
395 if (disprel->poly != NULL) cpl_free(disprel->poly);
410 static int isaac_spc_wlcalib_save(
411 const cpl_table * tab,
413 cpl_parameterlist * parlist,
416 cpl_propertylist * plist;
417 cpl_propertylist * qclist;
418 cpl_propertylist * paflist;
419 const cpl_frame * ref_frame;
424 qclist = cpl_propertylist_new();
427 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
428 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
430 cpl_msg_error(cpl_func,
"getting header from reference frame");
431 cpl_propertylist_delete(qclist);
432 return CPL_ERROR_UNSPECIFIED;
435 if (cpl_error_get_code()) {
436 cpl_propertylist_delete(qclist);
437 cpl_propertylist_delete(plist);
438 return CPL_ERROR_UNSPECIFIED;
441 if (cpl_error_get_code()) cpl_error_reset();
442 else cpl_propertylist_append_string(plist,
"ESO QC FILTER OBS", sval);
443 cpl_propertylist_delete(plist);
444 cpl_propertylist_append_int(plist,
"ESO QC LAMP",
445 isaac_spc_wlcalib_config.lines_table);
446 cpl_propertylist_append_double(plist,
"ESO QC DISP XCORR",
447 isaac_spc_wlcalib_config.disprel_cc);
448 cpl_propertylist_append_int(plist,
"ESO QC DISP NUMCAT",
449 isaac_spc_wlcalib_config.disprel_clines);
450 cpl_propertylist_append_int(plist,
"ESO QC DISP NUMMATCH",
451 isaac_spc_wlcalib_config.disprel_dlines);
452 cpl_propertylist_append_double(plist,
"ESO QC DISP STDEV",
453 isaac_spc_wlcalib_config.disprel_rms);
454 cpl_propertylist_append_double(plist,
"ESO QC DISPCO1",
455 cpl_table_get_double(tab,
"WL_coefficients", 0, NULL));
456 cpl_propertylist_append_double(plist,
"ESO QC DISPCO2",
457 cpl_table_get_double(tab,
"WL_coefficients", 1, NULL));
458 cpl_propertylist_append_double(plist,
"ESO QC DISPCO3",
459 cpl_table_get_double(tab,
"WL_coefficients", 2, NULL));
460 cpl_propertylist_append_double(plist,
"ESO QC DISPCO4",
461 cpl_table_get_double(tab,
"WL_coefficients", 3, NULL));
462 cpl_propertylist_append_double(plist,
"ESO QC WLEN",
463 (
double)(cpl_table_get_double(tab,
"WL_coefficients", 0, NULL) +
464 512*cpl_table_get_double(tab,
"WL_coefficients", 1, NULL) +
465 512*512*cpl_table_get_double(tab,
"WL_coefficients", 2, NULL) +
466 512*512*512*cpl_table_get_double(tab,
"WL_coefficients", 3, NULL)));
469 filename = cpl_sprintf(
"isaac_spc_wlcalib_%d.fits", nb);
470 irplib_dfs_save_table(set,
476 ISAAC_SPC_WLCALIB_RES,
479 PACKAGE
"/" PACKAGE_VERSION,
484 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
487 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
489 cpl_msg_error(cpl_func,
"getting header from reference frame");
490 cpl_propertylist_delete(qclist);
491 return CPL_ERROR_UNSPECIFIED;
495 paflist = cpl_propertylist_new();
496 cpl_propertylist_copy_property_regexp(paflist, plist,
497 "^(ARCFILE|MJD-OBS|INSTRUME|ESO TPL ID|ESO TPL NEXP|ESO DPR CATG|"
498 "ESO DPR TECH|ESO DPR TYPE|DATE-OBS|ESO INS GRAT NAME|"
499 "ESO INS GRAT WLEN|ESO INS GRAT ORDER|ESO INS MODE|"
500 "ESO INS OPTI1 ID)$", 0);
501 cpl_propertylist_delete(plist);
504 cpl_propertylist_copy_property_regexp(paflist, qclist,
".", 0);
505 cpl_propertylist_delete(qclist);
508 cpl_propertylist_update_string(paflist, CPL_DFS_PRO_CATG,
509 ISAAC_SPC_WLCALIB_RES);
512 filename = cpl_sprintf(
"isaac_spc_wlcalib_%d.paf", nb);
513 cpl_dfs_save_paf(
"ISAAC",
518 cpl_propertylist_delete(paflist);
const char * isaac_pfits_get_filter(const cpl_propertylist *plist)
find out the filter
double * isaac_get_disprel_estimate(const char *filename, cpl_size poly_deg)
Estimate the instrument wavelength range.
const char * isaac_extract_filename(const cpl_frameset *self, const char *tag)
Extract the filename of the first frame of the given tag.
const char * isaac_get_license(void)
Get the pipeline copyright and license.