37 static int fors_wave_calib_lss_create(cpl_plugin *);
38 static int fors_wave_calib_lss_exec(cpl_plugin *);
39 static int fors_wave_calib_lss_destroy(cpl_plugin *);
40 static int fors_wave_calib_lss(cpl_parameterlist *, cpl_frameset *);
42 static char fors_wave_calib_lss_description[] =
43 "This recipe is used to wavelength calibrate one long slit spectrum, i.e.,\n"
44 "a FORS spectral obtained either in LSS mode or in MOS/MXU mode with all\n"
45 "slits at the same offset. A pattern-matching algorithm is applied as in\n"
46 "recipe fors_detect_spectra. For more details on this data reduction\n"
47 "strategy please refer to the FORS Pipeline User's Manual.\n"
49 "Note that specifying an input GRISM_TABLE will set some of the recipe\n"
50 "configuration parameters to default values valid for a particular grism.\n"
52 "In the table below the LSS acronym can be alternatively read as MOS or\n"
55 " DO category: Type: Explanation: Required:\n"
56 " LAMP_UNBIAS_LSS Calib Arc lamp exposure Y\n"
57 " MASTER_LINECAT Calib Line catalog Y\n"
58 " GRISM_TABLE Calib Grism table .\n\n"
60 " DO category: Data type: Explanation:\n"
61 " REDUCED_LAMP_LSS FITS image Calibrated arc lamp exposure\n"
62 " DISP_COEFF_LSS FITS table Inverse dispersion coefficients\n"
63 " DISP_RESIDUALS_LSS FITS image Image of modeling residuals\n"
64 " WAVELENGTH_MAP_LSS FITS image Wavelengths mapped on CCD\n"
65 " SLIT_LOCATION_LSS FITS image Background subtracted arc frame\n"
66 " SPECTRAL_RESOLUTION_LSS FITS table Spectral resolution table\n\n";
68 #define fors_wave_calib_lss_exit(message) \
70 if ((const char *)message != NULL) cpl_msg_error(recipe, message); \
71 cpl_image_delete(spectra); \
72 cpl_image_delete(residual); \
73 cpl_image_delete(rectified); \
74 cpl_image_delete(wavemap); \
75 cpl_table_delete(grism_table); \
76 cpl_table_delete(wavelengths); \
77 cpl_table_delete(maskslits); \
78 cpl_table_delete(idscoeff); \
79 cpl_table_delete(idscoeff_all); \
80 cpl_table_delete(restab); \
81 cpl_table_delete(slits); \
82 cpl_vector_delete(lines); \
83 cpl_propertylist_delete(header); \
84 cpl_propertylist_delete(save_header); \
85 cpl_msg_indent_less(); \
89 #define fors_wave_calib_lss_exit_memcheck(message) \
91 if ((const char *)message != NULL) cpl_msg_info(recipe, message); \
92 printf("free spectra (%p)\n", spectra); \
93 cpl_image_delete(spectra); \
94 printf("free residual (%p)\n", residual); \
95 cpl_image_delete(residual); \
96 printf("free rectified (%p)\n", rectified); \
97 cpl_image_delete(rectified); \
98 printf("free wavemap (%p)\n", wavemap); \
99 cpl_image_delete(wavemap); \
100 printf("free grism_table (%p)\n", grism_table); \
101 cpl_table_delete(grism_table); \
102 printf("free wavelengths (%p)\n", wavelengths); \
103 cpl_table_delete(wavelengths); \
104 printf("free maskslits (%p)\n", maskslits); \
105 cpl_table_delete(maskslits); \
106 printf("free idscoeff (%p)\n", idscoeff); \
107 cpl_table_delete(idscoeff); \
108 printf("free idscoeff_all (%p)\n", idscoeff_all); \
109 cpl_table_delete(idscoeff_all); \
110 printf("free restab (%p)\n", restab); \
111 cpl_table_delete(restab); \
112 printf("free slits (%p)\n", slits); \
113 cpl_table_delete(slits); \
114 printf("free lines (%p)\n", lines); \
115 cpl_vector_delete(lines); \
116 printf("free header (%p)\n", header); \
117 cpl_propertylist_delete(header); \
118 printf("free save_header (%p)\n", save_header); \
119 cpl_propertylist_delete(save_header); \
120 cpl_msg_indent_less(); \
138 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe );
139 cpl_plugin *plugin = &recipe->interface;
141 cpl_plugin_init(plugin,
144 CPL_PLUGIN_TYPE_RECIPE,
145 "fors_wave_calib_lss",
146 "Derive dispersion relation from long-slit arc lamp frame",
147 fors_wave_calib_lss_description,
150 "This file is currently part of the FORS Instrument Pipeline\n"
151 "Copyright (C) 2002-2010 European Southern Observatory\n\n"
152 "This program is free software; you can redistribute it and/or modify\n"
153 "it under the terms of the GNU General Public License as published by\n"
154 "the Free Software Foundation; either version 2 of the License, or\n"
155 "(at your option) any later version.\n\n"
156 "This program is distributed in the hope that it will be useful,\n"
157 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
158 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
159 "GNU General Public License for more details.\n\n"
160 "You should have received a copy of the GNU General Public License\n"
161 "along with this program; if not, write to the Free Software Foundation,\n"
162 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n",
163 fors_wave_calib_lss_create,
164 fors_wave_calib_lss_exec,
165 fors_wave_calib_lss_destroy);
167 cpl_pluginlist_append(list, plugin);
183 static int fors_wave_calib_lss_create(cpl_plugin *plugin)
192 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
193 recipe = (cpl_recipe *)plugin;
201 recipe->parameters = cpl_parameterlist_new();
207 p = cpl_parameter_new_value(
"fors.fors_wave_calib_lss.dispersion",
209 "Expected spectral dispersion (Angstrom/pixel)",
210 "fors.fors_wave_calib_lss",
212 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dispersion");
213 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
214 cpl_parameterlist_append(recipe->parameters, p);
220 p = cpl_parameter_new_value(
"fors.fors_wave_calib_lss.peakdetection",
222 "Initial peak detection threshold (ADU)",
223 "fors.fors_wave_calib_lss",
225 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"peakdetection");
226 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
227 cpl_parameterlist_append(recipe->parameters, p);
233 p = cpl_parameter_new_value(
"fors.fors_wave_calib_lss.wdegree",
235 "Degree of wavelength calibration polynomial",
236 "fors.fors_wave_calib_lss",
238 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wdegree");
239 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
240 cpl_parameterlist_append(recipe->parameters, p);
246 p = cpl_parameter_new_value(
"fors.fors_wave_calib_lss.wradius",
248 "Search radius if iterating pattern-matching "
249 "with first-guess method",
250 "fors.fors_wave_calib_lss",
252 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wradius");
253 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
254 cpl_parameterlist_append(recipe->parameters, p);
260 p = cpl_parameter_new_value(
"fors.fors_wave_calib_lss.wreject",
262 "Rejection threshold in dispersion "
263 "relation fit (pixel)",
264 "fors.fors_wave_calib_lss",
266 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wreject");
267 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
268 cpl_parameterlist_append(recipe->parameters, p);
274 p = cpl_parameter_new_value(
"fors.fors_wave_calib_lss.wcolumn",
276 "Name of line catalog table column "
278 "fors.fors_wave_calib_lss",
280 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wcolumn");
281 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
282 cpl_parameterlist_append(recipe->parameters, p);
288 p = cpl_parameter_new_value(
"fors.fors_wave_calib_lss.startwavelength",
290 "Start wavelength in spectral extraction",
291 "fors.fors_wave_calib_lss",
293 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"startwavelength");
294 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
295 cpl_parameterlist_append(recipe->parameters, p);
301 p = cpl_parameter_new_value(
"fors.fors_wave_calib_lss.endwavelength",
303 "End wavelength in spectral extraction",
304 "fors.fors_wave_calib_lss",
306 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"endwavelength");
307 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
308 cpl_parameterlist_append(recipe->parameters, p);
314 p = cpl_parameter_new_value(
"fors.fors_wave_calib_lss.wmode",
316 "Interpolation mode of wavelength solution "
317 "(0 = no interpolation, 1 = fill gaps, "
319 "fors.fors_wave_calib_lss",
321 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wmode");
322 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
323 cpl_parameterlist_append(recipe->parameters, p);
337 static int fors_wave_calib_lss_exec(cpl_plugin *plugin)
341 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
342 recipe = (cpl_recipe *)plugin;
346 return fors_wave_calib_lss(recipe->parameters, recipe->frames);
358 static int fors_wave_calib_lss_destroy(cpl_plugin *plugin)
362 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
363 recipe = (cpl_recipe *)plugin;
367 cpl_parameterlist_delete(recipe->parameters);
382 static int fors_wave_calib_lss(cpl_parameterlist *parlist,
383 cpl_frameset *frameset)
386 const char *recipe =
"fors_wave_calib_lss";
394 double peakdetection;
400 double startwavelength;
401 double endwavelength;
407 cpl_image *spectra = NULL;
408 cpl_image *rectified = NULL;
409 cpl_image *wavemap = NULL;
410 cpl_image *residual = NULL;
411 cpl_image *dummy = NULL;
412 cpl_table *grism_table = NULL;
413 cpl_table *wavelengths = NULL;
414 cpl_table *slits = NULL;
415 cpl_table *idscoeff = NULL;
416 cpl_table *idscoeff_all = NULL;
417 cpl_table *maskslits = NULL;
418 cpl_table *restab = NULL;
419 cpl_vector *lines = NULL;
420 cpl_propertylist *header = NULL;
421 cpl_propertylist *save_header = NULL;
429 const char *reduced_lamp_tag;
430 const char *wavelength_map_tag;
431 const char *disp_residuals_tag;
432 const char *disp_coeff_tag;
433 const char *slit_location_tag;
434 const char *spectral_resolution_tag;
438 int treat_as_lss = 0;
444 double *fiterror = NULL;
445 int *fitlines = NULL;
447 int first_row, last_row;
452 char *instrume = NULL;
455 cpl_msg_set_indentation(2);
461 cpl_msg_info(recipe,
"Recipe %s configuration parameters:", recipe);
462 cpl_msg_indent_more();
464 if (cpl_frameset_count_tags(frameset,
"GRISM_TABLE") > 1)
465 fors_wave_calib_lss_exit(
"Too many in input: GRISM_TABLE");
470 "fors.fors_wave_calib_lss.dispersion", grism_table);
472 if (dispersion <= 0.0)
473 fors_wave_calib_lss_exit(
"Invalid spectral dispersion value");
476 "fors.fors_wave_calib_lss.peakdetection", grism_table);
477 if (peakdetection <= 0.0)
478 fors_wave_calib_lss_exit(
"Invalid peak detection level");
481 "fors.fors_wave_calib_lss.wdegree", grism_table);
484 fors_wave_calib_lss_exit(
"Invalid polynomial degree");
487 fors_wave_calib_lss_exit(
"Max allowed polynomial degree is 5");
490 "fors.fors_wave_calib_lss.wradius", NULL);
493 fors_wave_calib_lss_exit(
"Invalid search radius");
496 "fors.fors_wave_calib_lss.wreject", NULL);
499 fors_wave_calib_lss_exit(
"Invalid rejection threshold");
502 "fors.fors_wave_calib_lss.wmode", NULL);
504 if (wmode < 0 || wmode > 2)
505 fors_wave_calib_lss_exit(
"Invalid interpolation mode");
508 "fors.fors_wave_calib_lss.wcolumn", NULL);
511 "fors.fors_wave_calib_lss.startwavelength", grism_table);
512 if (startwavelength > 1.0)
513 if (startwavelength < 3000.0 || startwavelength > 13000.0)
514 fors_wave_calib_lss_exit(
"Invalid wavelength");
517 "fors.fors_wave_calib_lss.endwavelength", grism_table);
518 if (endwavelength > 1.0) {
519 if (endwavelength < 3000.0 || endwavelength > 13000.0)
520 fors_wave_calib_lss_exit(
"Invalid wavelength");
521 if (startwavelength < 1.0)
522 fors_wave_calib_lss_exit(
"Invalid wavelength interval");
525 if (startwavelength > 1.0)
526 if (endwavelength - startwavelength <= 0.0)
527 fors_wave_calib_lss_exit(
"Invalid wavelength interval");
529 cpl_table_delete(grism_table); grism_table = NULL;
531 if (cpl_error_get_code())
532 fors_wave_calib_lss_exit(
"Failure reading the configuration "
536 cpl_msg_indent_less();
537 cpl_msg_info(recipe,
"Check input set-of-frames:");
538 cpl_msg_indent_more();
540 if (cpl_frameset_count_tags(frameset,
"MASTER_LINECAT") == 0)
541 fors_wave_calib_lss_exit(
"Missing required input: MASTER_LINECAT");
543 if (cpl_frameset_count_tags(frameset,
"MASTER_LINECAT") > 1)
544 fors_wave_calib_lss_exit(
"Too many in input: MASTER_LINECAT");
546 mxu = cpl_frameset_count_tags(frameset,
"LAMP_UNBIAS_MXU");
547 mos = cpl_frameset_count_tags(frameset,
"LAMP_UNBIAS_MOS");
548 lss = cpl_frameset_count_tags(frameset,
"LAMP_UNBIAS_LSS");
550 narc = mxu + mos + lss;
553 fors_wave_calib_lss_exit(
"Missing input long-slit arc lamp frame");
556 cpl_msg_error(recipe,
"Too many input arc lamp frames (%d > 1)", narc);
557 fors_wave_calib_lss_exit(NULL);
561 arc_tag =
"LAMP_UNBIAS_MXU";
562 slit_location_tag =
"SLIT_LOCATION_MXU";
563 reduced_lamp_tag =
"REDUCED_LAMP_MXU";
564 disp_residuals_tag =
"DISP_RESIDUALS_MXU";
565 disp_coeff_tag =
"DISP_COEFF_MXU";
566 wavelength_map_tag =
"WAVELENGTH_MAP_MXU";
567 spectral_resolution_tag =
"SPECTRAL_RESOLUTION_MXU";
570 arc_tag =
"LAMP_UNBIAS_MOS";
571 slit_location_tag =
"SLIT_LOCATION_MOS";
572 reduced_lamp_tag =
"REDUCED_LAMP_MOS";
573 disp_residuals_tag =
"DISP_RESIDUALS_MOS";
574 disp_coeff_tag =
"DISP_COEFF_MOS";
575 wavelength_map_tag =
"WAVELENGTH_MAP_MOS";
576 spectral_resolution_tag =
"SPECTRAL_RESOLUTION_MOS";
579 arc_tag =
"LAMP_UNBIAS_LSS";
580 slit_location_tag =
"SLIT_LOCATION_LSS";
581 reduced_lamp_tag =
"REDUCED_LAMP_LSS";
582 disp_residuals_tag =
"DISP_RESIDUALS_LSS";
583 disp_coeff_tag =
"DISP_COEFF_LSS";
584 wavelength_map_tag =
"WAVELENGTH_MAP_LSS";
585 spectral_resolution_tag =
"SPECTRAL_RESOLUTION_LSS";
590 cpl_msg_warning(cpl_func,
"Input frames are not from the same grism");
593 cpl_msg_warning(cpl_func,
"Input frames are not from the same filter");
596 cpl_msg_warning(cpl_func,
"Input frames are not from the same chip");
607 fors_wave_calib_lss_exit(
"Cannot load arc lamp header");
609 instrume = (
char *)cpl_propertylist_get_string(header,
"INSTRUME");
610 if (instrume == NULL)
611 fors_wave_calib_lss_exit(
"Missing keyword INSTRUME in arc lamp header");
613 if (instrume[4] ==
'1')
614 snprintf(version, 80,
"%s/%s",
"fors1", VERSION);
615 if (instrume[4] ==
'2')
616 snprintf(version, 80,
"%s/%s",
"fors2", VERSION);
618 reference = cpl_propertylist_get_double(header,
"ESO INS GRIS1 WLEN");
620 if (cpl_error_get_code() != CPL_ERROR_NONE)
621 fors_wave_calib_lss_exit(
"Missing keyword ESO INS GRIS1 WLEN "
622 "in arc lamp frame header");
624 if (reference < 3000.0)
627 if (reference < 3000.0 || reference > 13000.0) {
628 cpl_msg_error(recipe,
"Invalid central wavelength %.2f read from "
629 "keyword ESO INS GRIS1 WLEN in arc lamp frame header",
631 fors_wave_calib_lss_exit(NULL);
634 cpl_msg_info(recipe,
"The central wavelength is: %.2f", reference);
636 rebin = cpl_propertylist_get_int(header,
"ESO DET WIN1 BINX");
638 if (cpl_error_get_code() != CPL_ERROR_NONE)
639 fors_wave_calib_lss_exit(
"Missing keyword ESO DET WIN1 BINX "
640 "in arc lamp frame header");
644 cpl_msg_warning(recipe,
"The rebin factor is %d, and therefore the "
645 "working dispersion used is %f A/pixel", rebin,
652 int nslits_out_det = 0;
664 treat_as_lss = fors_mos_is_lss_like(maskslits, nslits_out_det);
666 cpl_table_delete(maskslits); maskslits = NULL;
669 fors_wave_calib_lss_exit(
"Input data are not long-slit data");
673 cpl_msg_indent_less();
674 cpl_msg_info(recipe,
"Load arc lamp exposure...");
675 cpl_msg_indent_more();
677 spectra =
dfs_load_image(frameset, arc_tag, CPL_TYPE_FLOAT, 0, 0);
680 fors_wave_calib_lss_exit(
"Cannot load arc lamp exposure");
683 cpl_msg_indent_less();
684 cpl_msg_info(recipe,
"Load input line catalog...");
685 cpl_msg_indent_more();
689 if (wavelengths == NULL)
690 fors_wave_calib_lss_exit(
"Cannot load line catalog");
697 nlines = cpl_table_get_nrow(wavelengths);
700 fors_wave_calib_lss_exit(
"Empty input line catalog");
702 if (cpl_table_has_column(wavelengths, wcolumn) != 1) {
703 cpl_msg_error(recipe,
"Missing column %s in input line catalog table",
705 fors_wave_calib_lss_exit(NULL);
708 line = cpl_malloc(nlines *
sizeof(
double));
710 for (i = 0; i < nlines; i++)
711 line[i] = cpl_table_get(wavelengths, wcolumn, i, NULL);
713 cpl_table_delete(wavelengths); wavelengths = NULL;
715 lines = cpl_vector_wrap(nlines, line);
718 cpl_msg_indent_less();
719 cpl_msg_info(recipe,
"Perform wavelength calibration...");
720 cpl_msg_indent_more();
722 nx = cpl_image_get_size_x(spectra);
723 ny = cpl_image_get_size_y(spectra);
725 wavemap = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
726 idscoeff_all = cpl_table_new(ny);
729 fors_wave_calib_lss_exit(
"Cannot process saturation");
732 fors_wave_calib_lss_exit(
"Cannot subtract the background");
735 peakdetection, wradius,
736 wdegree, wreject, reference,
738 &endwavelength, NULL,
739 NULL, idscoeff_all, wavemap,
740 NULL, NULL, NULL, NULL);
742 if (rectified == NULL)
743 fors_wave_calib_lss_exit(
"Wavelength calibration failure.");
745 cpl_image_delete(rectified); rectified = NULL;
748 while (!cpl_table_is_valid(idscoeff_all,
"c0", first_row))
752 while (!cpl_table_is_valid(idscoeff_all,
"c0", last_row))
755 ylow = first_row + 1;
758 dummy = cpl_image_extract(spectra, 1, ylow, nx, yhig);
759 cpl_image_delete(spectra); spectra = dummy;
761 ny = cpl_image_get_size_y(spectra);
763 residual = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
765 fiterror = cpl_calloc(ny,
sizeof(
double));
766 fitlines = cpl_calloc(ny,
sizeof(
int));
767 idscoeff = cpl_table_new(ny);
770 fors_wave_calib_lss_exit(
"Cannot process saturation");
773 fors_wave_calib_lss_exit(
"Cannot subtract the background");
776 peakdetection, wradius,
777 wdegree, wreject, reference,
779 &endwavelength, fitlines,
780 fiterror, idscoeff, NULL,
781 residual, NULL, NULL, NULL);
783 if (rectified == NULL)
784 fors_wave_calib_lss_exit(
"Wavelength calibration failure.");
790 slits = cpl_table_new(1);
791 cpl_table_new_column(slits,
"slit_id", CPL_TYPE_INT);
792 cpl_table_new_column(slits,
"xtop", CPL_TYPE_DOUBLE);
793 cpl_table_new_column(slits,
"ytop", CPL_TYPE_DOUBLE);
794 cpl_table_new_column(slits,
"xbottom", CPL_TYPE_DOUBLE);
795 cpl_table_new_column(slits,
"ybottom", CPL_TYPE_DOUBLE);
796 cpl_table_new_column(slits,
"position", CPL_TYPE_INT);
797 cpl_table_new_column(slits,
"length", CPL_TYPE_INT);
798 cpl_table_set_column_unit(slits,
"xtop",
"pixel");
799 cpl_table_set_column_unit(slits,
"ytop",
"pixel");
800 cpl_table_set_column_unit(slits,
"xbottom",
"pixel");
801 cpl_table_set_column_unit(slits,
"ybottom",
"pixel");
802 cpl_table_set_column_unit(slits,
"position",
"pixel");
803 cpl_table_set_column_unit(slits,
"length",
"pixel");
804 cpl_table_set_int(slits,
"slit_id", 0, 0);
805 cpl_table_set_double(slits,
"xtop", 0, 0);
806 cpl_table_set_double(slits,
"ytop", 0, last_row);
807 cpl_table_set_double(slits,
"xbottom", 0, 0);
808 cpl_table_set_double(slits,
"ybottom", 0, first_row);
809 cpl_table_set_int(slits,
"position", 0, 0);
810 cpl_table_set_int(slits,
"length", 0, ny);
813 parlist, recipe, version))
814 fors_wave_calib_lss_exit(NULL);
816 cpl_table_delete(slits); slits = NULL;
819 cpl_image_delete(rectified); rectified = NULL;
820 cpl_image_delete(wavemap); wavemap = NULL;
830 startwavelength, endwavelength);
833 endwavelength, dispersion,
837 cpl_table_delete(idscoeff_all); idscoeff_all = NULL;
839 cpl_table_wrap_double(idscoeff, fiterror,
"error"); fiterror = NULL;
840 cpl_table_set_column_unit(idscoeff,
"error",
"pixel");
841 cpl_table_wrap_int(idscoeff, fitlines,
"nlines"); fitlines = NULL;
843 for (i = 0; i < ny; i++)
844 if (!cpl_table_is_valid(idscoeff,
"c0", i))
845 cpl_table_set_invalid(idscoeff,
"error", i);
847 cpl_msg_info(recipe,
"Valid solutions found: %d out of %d rows",
848 ny - cpl_table_count_invalid(idscoeff,
"c0"), ny);
850 cpl_image_delete(spectra); spectra = NULL;
855 cpl_msg_info(recipe,
"Mean residual: %f pixel", mean_rms);
857 mean_rms = cpl_table_get_column_mean(idscoeff,
"error");
859 cpl_msg_info(recipe,
"Mean model accuracy: %f pixel (%f A)",
860 mean_rms, mean_rms * dispersion);
866 cpl_msg_info(recipe,
"Mean spectral resolution: %.2f",
867 cpl_table_get_column_mean(restab,
"resolution"));
869 "Mean reference lines FWHM: %.2f +/- %.2f pixel",
870 cpl_table_get_column_mean(restab,
"fwhm") / dispersion,
871 cpl_table_get_column_mean(restab,
"fwhm_rms") / dispersion);
874 NULL, parlist, recipe, version))
875 fors_wave_calib_lss_exit(NULL);
877 cpl_table_delete(restab); restab = NULL;
881 fors_wave_calib_lss_exit(
"Cannot compute the spectral "
884 cpl_vector_delete(lines); lines = NULL;
891 save_header = cpl_propertylist_new();
892 cpl_propertylist_update_double(save_header,
"CRPIX1", 1.0);
893 cpl_propertylist_update_double(save_header,
"CRPIX2", 1.0);
894 cpl_propertylist_update_double(save_header,
"CRVAL1",
895 startwavelength + dispersion/2);
896 cpl_propertylist_update_double(save_header,
"CRVAL2", 1.0);
899 cpl_propertylist_update_double(save_header,
"CD1_1", dispersion);
900 cpl_propertylist_update_double(save_header,
"CD1_2", 0.0);
901 cpl_propertylist_update_double(save_header,
"CD2_1", 0.0);
902 cpl_propertylist_update_double(save_header,
"CD2_2", 1.0);
903 cpl_propertylist_update_string(save_header,
"CTYPE1",
"LINEAR");
904 cpl_propertylist_update_string(save_header,
"CTYPE2",
"PIXEL");
905 cpl_propertylist_update_int(save_header,
"ESO PRO DATANCOM", 1);
907 if (
dfs_save_image(frameset, rectified, reduced_lamp_tag, save_header,
908 parlist, recipe, version))
909 fors_wave_calib_lss_exit(NULL);
911 cpl_image_delete(rectified); rectified = NULL;
912 cpl_propertylist_delete(save_header); save_header = NULL;
915 parlist, recipe, version))
916 fors_wave_calib_lss_exit(NULL);
918 cpl_table_delete(idscoeff); idscoeff = NULL;
921 parlist, recipe, version))
922 fors_wave_calib_lss_exit(NULL);
924 cpl_image_delete(wavemap); wavemap = NULL;
925 cpl_propertylist_delete(header); header = NULL;
926 header = cpl_propertylist_new();
928 cpl_propertylist_update_double(header,
"CRPIX2", 1.0);
929 cpl_propertylist_update_double(header,
"CRVAL2", 1.0);
931 cpl_propertylist_update_double(header,
"CD1_1", 1.0);
932 cpl_propertylist_update_double(header,
"CD1_2", 0.0);
933 cpl_propertylist_update_double(header,
"CD2_1", 0.0);
934 cpl_propertylist_update_double(header,
"CD2_2", 1.0);
935 cpl_propertylist_update_string(header,
"CTYPE1",
"LINEAR");
936 cpl_propertylist_update_string(header,
"CTYPE2",
"PIXEL");
938 if (
dfs_save_image(frameset, residual, disp_residuals_tag, header,
939 parlist, recipe, version))
940 fors_wave_calib_lss_exit(NULL);
942 cpl_image_delete(residual); residual = NULL;
943 cpl_propertylist_delete(header); header = NULL;
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
cpl_image * dfs_load_image(cpl_frameset *frameset, const char *category, cpl_type type, int ext, int calib)
Loading image data of given category.
const char * dfs_get_parameter_string(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe string parameter value.
cpl_error_code mos_interpolate_wavecalib(cpl_table *idscoeff, cpl_image *wavemap, int mode, int degree)
Interpolate LSS wavelength calibration.
cpl_image * mos_wavelength_calibration_raw(const cpl_image *image, cpl_vector *lines, double dispersion, float level, int sradius, int order, double reject, double refwave, double *wavestart, double *waveend, int *nlines, double *error, cpl_table *idscoeff, cpl_image *calibration, cpl_image *residuals, cpl_table *restable, cpl_mask *refmask, cpl_table *detected_lines)
Derive wavelength calibration from a raw arc lamp or sky exposure.
double mos_distortions_rms(cpl_image *rectified, cpl_vector *lines, double wavestart, double dispersion, int radius, int highres)
Estimate the spectral distortion modeling goodness.
cpl_propertylist * dfs_load_header(cpl_frameset *frameset, const char *category, int ext)
Loading header associated to data of given category.
cpl_table * mos_load_slits_fors_mxu(cpl_propertylist *header)
Create slit location table from FITS header of FORS2-MXU data.
cpl_image * mos_wavelength_calibration(cpl_image *image, double refwave, double firstLambda, double lastLambda, double dispersion, cpl_table *idscoeff, int flux)
Remap at constant wavelength step an image of rectified scientific spectra.
cpl_table * mos_load_slits_fors_mos(cpl_propertylist *header, int *nslits_out_det)
Create slit location table from FITS header of FORS1/2 MOS data.
cpl_error_code mos_subtract_background(cpl_image *image)
Subtract the background.
int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
Saving table data of given category.
cpl_image * mos_map_idscoeff(cpl_table *idscoeff, int xsize, double reference, double blue, double red)
Create a wavelengths map from an IDS coefficients table.
int dfs_save_image(cpl_frameset *frameset, const cpl_image *image, const char *category, cpl_propertylist *header, const cpl_parameterlist *parlist, const char *recipename, const char *version)
Saving image data of given category.
cpl_table * dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
Loading table data of given category.
int dfs_get_parameter_int(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe integer parameter value.
int dfs_save_table(cpl_frameset *frameset, const cpl_table *table, const char *category, cpl_propertylist *header, const cpl_parameterlist *parlist, const char *recipename, const char *version)
Saving table data of given category.
cpl_table * mos_resolution_table(cpl_image *image, double startwave, double dispersion, int saturation, cpl_vector *lines)
Compute mean spectral resolution at a given arc lamp line.
double dfs_get_parameter_double(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe double parameter value.
cpl_error_code mos_saturation_process(cpl_image *image)
Process saturation.