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 (message) 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 (message) 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;
447 double *fiterror = NULL;
448 int *fitlines = NULL;
450 int first_row, last_row;
455 char *instrume = NULL;
458 cpl_msg_set_indentation(2);
464 cpl_msg_info(recipe,
"Recipe %s configuration parameters:", recipe);
465 cpl_msg_indent_more();
467 if (cpl_frameset_count_tags(frameset,
"GRISM_TABLE") > 1)
468 fors_wave_calib_lss_exit(
"Too many in input: GRISM_TABLE");
473 "fors.fors_wave_calib_lss.dispersion", grism_table);
475 if (dispersion <= 0.0)
476 fors_wave_calib_lss_exit(
"Invalid spectral dispersion value");
479 "fors.fors_wave_calib_lss.peakdetection", grism_table);
480 if (peakdetection <= 0.0)
481 fors_wave_calib_lss_exit(
"Invalid peak detection level");
484 "fors.fors_wave_calib_lss.wdegree", grism_table);
487 fors_wave_calib_lss_exit(
"Invalid polynomial degree");
490 fors_wave_calib_lss_exit(
"Max allowed polynomial degree is 5");
493 "fors.fors_wave_calib_lss.wradius", NULL);
496 fors_wave_calib_lss_exit(
"Invalid search radius");
499 "fors.fors_wave_calib_lss.wreject", NULL);
502 fors_wave_calib_lss_exit(
"Invalid rejection threshold");
505 "fors.fors_wave_calib_lss.wmode", NULL);
507 if (wmode < 0 || wmode > 2)
508 fors_wave_calib_lss_exit(
"Invalid interpolation mode");
511 "fors.fors_wave_calib_lss.wcolumn", NULL);
514 "fors.fors_wave_calib_lss.startwavelength", grism_table);
515 if (startwavelength > 1.0)
516 if (startwavelength < 3000.0 || startwavelength > 13000.0)
517 fors_wave_calib_lss_exit(
"Invalid wavelength");
520 "fors.fors_wave_calib_lss.endwavelength", grism_table);
521 if (endwavelength > 1.0) {
522 if (endwavelength < 3000.0 || endwavelength > 13000.0)
523 fors_wave_calib_lss_exit(
"Invalid wavelength");
524 if (startwavelength < 1.0)
525 fors_wave_calib_lss_exit(
"Invalid wavelength interval");
528 if (startwavelength > 1.0)
529 if (endwavelength - startwavelength <= 0.0)
530 fors_wave_calib_lss_exit(
"Invalid wavelength interval");
532 cpl_table_delete(grism_table); grism_table = NULL;
534 if (cpl_error_get_code())
535 fors_wave_calib_lss_exit(
"Failure reading the configuration "
539 cpl_msg_indent_less();
540 cpl_msg_info(recipe,
"Check input set-of-frames:");
541 cpl_msg_indent_more();
543 if (cpl_frameset_count_tags(frameset,
"MASTER_LINECAT") == 0)
544 fors_wave_calib_lss_exit(
"Missing required input: MASTER_LINECAT");
546 if (cpl_frameset_count_tags(frameset,
"MASTER_LINECAT") > 1)
547 fors_wave_calib_lss_exit(
"Too many in input: MASTER_LINECAT");
549 mxu = cpl_frameset_count_tags(frameset,
"LAMP_UNBIAS_MXU");
550 mos = cpl_frameset_count_tags(frameset,
"LAMP_UNBIAS_MOS");
551 lss = cpl_frameset_count_tags(frameset,
"LAMP_UNBIAS_LSS");
553 narc = mxu + mos + lss;
556 fors_wave_calib_lss_exit(
"Missing input long-slit arc lamp frame");
559 cpl_msg_error(recipe,
"Too many input arc lamp frames (%d > 1)", narc);
560 fors_wave_calib_lss_exit(NULL);
564 arc_tag =
"LAMP_UNBIAS_MXU";
565 slit_location_tag =
"SLIT_LOCATION_MXU";
566 reduced_lamp_tag =
"REDUCED_LAMP_MXU";
567 disp_residuals_tag =
"DISP_RESIDUALS_MXU";
568 disp_coeff_tag =
"DISP_COEFF_MXU";
569 wavelength_map_tag =
"WAVELENGTH_MAP_MXU";
570 spectral_resolution_tag =
"SPECTRAL_RESOLUTION_MXU";
573 arc_tag =
"LAMP_UNBIAS_MOS";
574 slit_location_tag =
"SLIT_LOCATION_MOS";
575 reduced_lamp_tag =
"REDUCED_LAMP_MOS";
576 disp_residuals_tag =
"DISP_RESIDUALS_MOS";
577 disp_coeff_tag =
"DISP_COEFF_MOS";
578 wavelength_map_tag =
"WAVELENGTH_MAP_MOS";
579 spectral_resolution_tag =
"SPECTRAL_RESOLUTION_MOS";
582 arc_tag =
"LAMP_UNBIAS_LSS";
583 slit_location_tag =
"SLIT_LOCATION_LSS";
584 reduced_lamp_tag =
"REDUCED_LAMP_LSS";
585 disp_residuals_tag =
"DISP_RESIDUALS_LSS";
586 disp_coeff_tag =
"DISP_COEFF_LSS";
587 wavelength_map_tag =
"WAVELENGTH_MAP_LSS";
588 spectral_resolution_tag =
"SPECTRAL_RESOLUTION_LSS";
593 fors_wave_calib_lss_exit(
"Input frames are not from the same grism");
596 fors_wave_calib_lss_exit(
"Input frames are not from the same filter");
599 fors_wave_calib_lss_exit(
"Input frames are not from the same chip");
610 fors_wave_calib_lss_exit(
"Cannot load arc lamp header");
612 instrume = (
char *)cpl_propertylist_get_string(header,
"INSTRUME");
613 if (instrume == NULL)
614 fors_wave_calib_lss_exit(
"Missing keyword INSTRUME in arc lamp header");
616 if (instrume[4] ==
'1')
617 snprintf(version, 80,
"%s/%s",
"fors1", VERSION);
618 if (instrume[4] ==
'2')
619 snprintf(version, 80,
"%s/%s",
"fors2", VERSION);
621 reference = cpl_propertylist_get_double(header,
"ESO INS GRIS1 WLEN");
623 if (cpl_error_get_code() != CPL_ERROR_NONE)
624 fors_wave_calib_lss_exit(
"Missing keyword ESO INS GRIS1 WLEN "
625 "in arc lamp frame header");
627 if (reference < 3000.0)
630 if (reference < 3000.0 || reference > 13000.0) {
631 cpl_msg_error(recipe,
"Invalid central wavelength %.2f read from "
632 "keyword ESO INS GRIS1 WLEN in arc lamp frame header",
634 fors_wave_calib_lss_exit(NULL);
637 cpl_msg_info(recipe,
"The central wavelength is: %.2f", reference);
639 rebin = cpl_propertylist_get_int(header,
"ESO DET WIN1 BINX");
641 if (cpl_error_get_code() != CPL_ERROR_NONE)
642 fors_wave_calib_lss_exit(
"Missing keyword ESO DET WIN1 BINX "
643 "in arc lamp frame header");
647 cpl_msg_warning(recipe,
"The rebin factor is %d, and therefore the "
648 "working dispersion used is %f A/pixel", rebin,
655 int nslits_out_det = 0;
667 treat_as_lss = fors_mos_is_lss_like(maskslits, nslits_out_det);
669 cpl_table_delete(maskslits); maskslits = NULL;
672 fors_wave_calib_lss_exit(
"Input data are not long-slit data");
676 cpl_msg_indent_less();
677 cpl_msg_info(recipe,
"Load arc lamp exposure...");
678 cpl_msg_indent_more();
680 spectra =
dfs_load_image(frameset, arc_tag, CPL_TYPE_FLOAT, 0, 0);
683 fors_wave_calib_lss_exit(
"Cannot load arc lamp exposure");
686 cpl_msg_indent_less();
687 cpl_msg_info(recipe,
"Load input line catalog...");
688 cpl_msg_indent_more();
692 if (wavelengths == NULL)
693 fors_wave_calib_lss_exit(
"Cannot load line catalog");
700 nlines = cpl_table_get_nrow(wavelengths);
703 fors_wave_calib_lss_exit(
"Empty input line catalog");
705 if (cpl_table_has_column(wavelengths, wcolumn) != 1) {
706 cpl_msg_error(recipe,
"Missing column %s in input line catalog table",
708 fors_wave_calib_lss_exit(NULL);
711 line = cpl_malloc(nlines *
sizeof(
double));
713 for (i = 0; i < nlines; i++)
714 line[i] = cpl_table_get(wavelengths, wcolumn, i, NULL);
716 cpl_table_delete(wavelengths); wavelengths = NULL;
718 lines = cpl_vector_wrap(nlines, line);
721 cpl_msg_indent_less();
722 cpl_msg_info(recipe,
"Perform wavelength calibration...");
723 cpl_msg_indent_more();
725 nx = cpl_image_get_size_x(spectra);
726 ny = cpl_image_get_size_y(spectra);
728 wavemap = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
729 idscoeff_all = cpl_table_new(ny);
732 fors_wave_calib_lss_exit(
"Cannot process saturation");
735 fors_wave_calib_lss_exit(
"Cannot subtract the background");
738 peakdetection, wradius,
739 wdegree, wreject, reference,
741 &endwavelength, NULL,
742 NULL, idscoeff_all, wavemap,
743 NULL, NULL, NULL, NULL);
745 if (rectified == NULL)
746 fors_wave_calib_lss_exit(
"Wavelength calibration failure.");
748 cpl_image_delete(rectified); rectified = NULL;
751 while (!cpl_table_is_valid(idscoeff_all,
"c0", first_row))
755 while (!cpl_table_is_valid(idscoeff_all,
"c0", last_row))
758 ylow = first_row + 1;
761 dummy = cpl_image_extract(spectra, 1, ylow, nx, yhig);
762 cpl_image_delete(spectra); spectra = dummy;
764 ny = cpl_image_get_size_y(spectra);
766 residual = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
768 fiterror = cpl_calloc(ny,
sizeof(
double));
769 fitlines = cpl_calloc(ny,
sizeof(
int));
770 idscoeff = cpl_table_new(ny);
773 fors_wave_calib_lss_exit(
"Cannot process saturation");
776 fors_wave_calib_lss_exit(
"Cannot subtract the background");
779 peakdetection, wradius,
780 wdegree, wreject, reference,
782 &endwavelength, fitlines,
783 fiterror, idscoeff, NULL,
784 residual, NULL, NULL, NULL);
786 if (rectified == NULL)
787 fors_wave_calib_lss_exit(
"Wavelength calibration failure.");
793 slits = cpl_table_new(1);
794 cpl_table_new_column(slits,
"slit_id", CPL_TYPE_INT);
795 cpl_table_new_column(slits,
"xtop", CPL_TYPE_DOUBLE);
796 cpl_table_new_column(slits,
"ytop", CPL_TYPE_DOUBLE);
797 cpl_table_new_column(slits,
"xbottom", CPL_TYPE_DOUBLE);
798 cpl_table_new_column(slits,
"ybottom", CPL_TYPE_DOUBLE);
799 cpl_table_new_column(slits,
"position", CPL_TYPE_INT);
800 cpl_table_new_column(slits,
"length", CPL_TYPE_INT);
801 cpl_table_set_column_unit(slits,
"xtop",
"pixel");
802 cpl_table_set_column_unit(slits,
"ytop",
"pixel");
803 cpl_table_set_column_unit(slits,
"xbottom",
"pixel");
804 cpl_table_set_column_unit(slits,
"ybottom",
"pixel");
805 cpl_table_set_column_unit(slits,
"position",
"pixel");
806 cpl_table_set_column_unit(slits,
"length",
"pixel");
807 cpl_table_set_int(slits,
"slit_id", 0, 0);
808 cpl_table_set_double(slits,
"xtop", 0, 0);
809 cpl_table_set_double(slits,
"ytop", 0, last_row);
810 cpl_table_set_double(slits,
"xbottom", 0, 0);
811 cpl_table_set_double(slits,
"ybottom", 0, first_row);
812 cpl_table_set_int(slits,
"position", 0, 0);
813 cpl_table_set_int(slits,
"length", 0, ny);
816 parlist, recipe, version))
817 fors_wave_calib_lss_exit(NULL);
819 cpl_table_delete(slits); slits = NULL;
822 cpl_image_delete(rectified); rectified = NULL;
823 cpl_image_delete(wavemap); wavemap = NULL;
833 startwavelength, endwavelength);
836 endwavelength, dispersion,
840 cpl_table_delete(idscoeff_all); idscoeff_all = NULL;
842 cpl_table_wrap_double(idscoeff, fiterror,
"error"); fiterror = NULL;
843 cpl_table_set_column_unit(idscoeff,
"error",
"pixel");
844 cpl_table_wrap_int(idscoeff, fitlines,
"nlines"); fitlines = NULL;
846 for (i = 0; i < ny; i++)
847 if (!cpl_table_is_valid(idscoeff,
"c0", i))
848 cpl_table_set_invalid(idscoeff,
"error", i);
850 cpl_msg_info(recipe,
"Valid solutions found: %d out of %d rows",
851 ny - cpl_table_count_invalid(idscoeff,
"c0"), ny);
853 cpl_image_delete(spectra); spectra = NULL;
858 cpl_msg_info(recipe,
"Mean residual: %f pixel", mean_rms);
860 mean_rms = cpl_table_get_column_mean(idscoeff,
"error");
862 cpl_msg_info(recipe,
"Mean model accuracy: %f pixel (%f A)",
863 mean_rms, mean_rms * dispersion);
869 cpl_msg_info(recipe,
"Mean spectral resolution: %.2f",
870 cpl_table_get_column_mean(restab,
"resolution"));
872 "Mean reference lines FWHM: %.2f +/- %.2f pixel",
873 cpl_table_get_column_mean(restab,
"fwhm") / dispersion,
874 cpl_table_get_column_mean(restab,
"fwhm_rms") / dispersion);
877 NULL, parlist, recipe, version))
878 fors_wave_calib_lss_exit(NULL);
880 cpl_table_delete(restab); restab = NULL;
884 fors_wave_calib_lss_exit(
"Cannot compute the spectral "
887 cpl_vector_delete(lines); lines = NULL;
894 save_header = cpl_propertylist_new();
895 cpl_propertylist_update_double(save_header,
"CRPIX1", 1.0);
896 cpl_propertylist_update_double(save_header,
"CRPIX2", 1.0);
897 cpl_propertylist_update_double(save_header,
"CRVAL1",
898 startwavelength + dispersion/2);
899 cpl_propertylist_update_double(save_header,
"CRVAL2", 1.0);
902 cpl_propertylist_update_double(save_header,
"CD1_1", dispersion);
903 cpl_propertylist_update_double(save_header,
"CD1_2", 0.0);
904 cpl_propertylist_update_double(save_header,
"CD2_1", 0.0);
905 cpl_propertylist_update_double(save_header,
"CD2_2", 1.0);
906 cpl_propertylist_update_string(save_header,
"CTYPE1",
"LINEAR");
907 cpl_propertylist_update_string(save_header,
"CTYPE2",
"PIXEL");
908 cpl_propertylist_update_int(save_header,
"ESO PRO DATANCOM", 1);
910 if (
dfs_save_image(frameset, rectified, reduced_lamp_tag, save_header,
911 parlist, recipe, version))
912 fors_wave_calib_lss_exit(NULL);
914 cpl_image_delete(rectified); rectified = NULL;
915 cpl_propertylist_delete(save_header); save_header = NULL;
918 parlist, recipe, version))
919 fors_wave_calib_lss_exit(NULL);
921 cpl_table_delete(idscoeff); idscoeff = NULL;
924 parlist, recipe, version))
925 fors_wave_calib_lss_exit(NULL);
927 cpl_image_delete(wavemap); wavemap = NULL;
928 cpl_propertylist_delete(header); header = NULL;
929 header = cpl_propertylist_new();
931 cpl_propertylist_update_double(header,
"CRPIX2", 1.0);
932 cpl_propertylist_update_double(header,
"CRVAL2", 1.0);
934 cpl_propertylist_update_double(header,
"CD1_1", 1.0);
935 cpl_propertylist_update_double(header,
"CD1_2", 0.0);
936 cpl_propertylist_update_double(header,
"CD2_1", 0.0);
937 cpl_propertylist_update_double(header,
"CD2_2", 1.0);
938 cpl_propertylist_update_string(header,
"CTYPE1",
"LINEAR");
939 cpl_propertylist_update_string(header,
"CTYPE2",
"PIXEL");
941 if (
dfs_save_image(frameset, residual, disp_residuals_tag, header,
942 parlist, recipe, version))
943 fors_wave_calib_lss_exit(NULL);
945 cpl_image_delete(residual); residual = NULL;
946 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.