38 static int fors_extract_create(cpl_plugin *);
39 static int fors_extract_exec(cpl_plugin *);
40 static int fors_extract_destroy(cpl_plugin *);
41 static int fors_extract(cpl_parameterlist *, cpl_frameset *);
43 static char fors_extract_description[] =
44 "This recipe is used to reduce scientific spectra using the global\n"
45 "distortion table created by the recipe fors_calib. The spectra are\n"
46 "bias subtracted, flat fielded (if a normalised flat field is specified)\n"
47 "and remapped eliminating the optical distortions. The wavelength calibration\n"
48 "can be optionally upgraded using a number of sky lines: if no sky lines\n"
49 "catalog of wavelengths is specified, an internal one is used instead.\n"
50 "If the alignment to the sky lines is performed, the applied dispersion\n"
51 "coefficient table is upgraded and saved to disk, and a new CCD wavelengths\n"
53 "This recipe accepts both FORS1 and FORS2 frames. A grism table (typically\n"
54 "depending on the instrument mode, and in particular on the grism used)\n"
55 "may also be specified: this table contains a default recipe parameter\n"
56 "setting to control the way spectra are extracted for a specific instrument\n"
57 "mode, as it is used for automatic run of the pipeline on Paranal and in\n"
58 "Garching. If this table is specified, it will modify the default recipe\n"
59 "parameter setting, with the exception of those parameters which have been\n"
60 "explicitly modifyed on the command line. If a grism table is not specified,\n"
61 "the input recipe parameters values will always be read from the command\n"
62 "line, or from an esorex configuration file if present, or from their\n"
63 "generic default values (that are rarely meaningful).\n"
64 "In the table below the MXU acronym can be read alternatively as MOS\n"
65 "and LSS, depending on the instrument mode of the input data. Either a\n"
66 "scientific or a standard star exposure can be specified in input (not\n"
69 " DO category: Type: Explanation: Required:\n"
70 " SCIENCE_MXU Raw Scientific exposure Y\n"
71 " or STANDARD_MXU Raw Standard star exposure Y\n"
72 " MASTER_BIAS Calib Master bias Y\n"
73 " GRISM_TABLE Calib Grism table .\n"
74 " MASTER_SKYLINECAT Calib Sky lines catalog .\n"
76 " MASTER_NORM_FLAT_MXU Calib Normalised flat field .\n"
77 " MASTER_DISTORTION_TABLE Calib Global distortion model .\n"
79 " or, in case of LSS-like MOS/MXU data,\n"
81 " MASTER_NORM_FLAT_LONG_MXU Calib Normalised flat field .\n"
83 " DO category: Data type: Explanation:\n"
84 " REDUCED_SCI_MXU FITS image Extracted scientific spectra\n"
85 " REDUCED_SKY_SCI_MXU FITS image Extracted sky spectra\n"
86 " REDUCED_ERROR_SCI_MXU FITS image Errors on extracted spectra\n"
87 " UNMAPPED_SCI_MXU FITS image Sky subtracted scientific spectra\n"
88 " MAPPED_SCI_MXU FITS image Rectified scientific spectra\n"
89 " MAPPED_ALL_SCI_MXU FITS image Rectified science spectra with sky\n"
90 " MAPPED_SKY_SCI_MXU FITS image Rectified sky spectra\n"
91 " UNMAPPED_SKY_SCI_MXU FITS image Sky on CCD\n"
92 " GLOBAL_SKY_SPECTRUM_MXU FITS table Global sky spectrum\n"
93 " OBJECT_TABLE_SCI_MXU FITS table Positions of detected objects\n"
95 " Only if the sky-alignment of the wavelength solution is requested:\n"
96 " SKY_SHIFTS_LONG_SCI_MXU FITS table Sky lines offsets (LSS-like data)\n"
97 " or SKY_SHIFTS_SLIT_SCI_MXU FITS table Sky lines offsets (MOS-like data)\n"
98 " DISP_COEFF_SCI_MXU FITS table Upgraded dispersion coefficients\n"
99 " WAVELENGTH_MAP_SCI_MXU FITS image Upgraded wavelength map\n\n";
101 #define fors_extract_exit(message) \
103 if (message) cpl_msg_error(recipe, message); \
105 cpl_free(instrume); \
106 cpl_image_delete(dummy); \
107 cpl_image_delete(mapped); \
108 cpl_image_delete(mapped_sky); \
109 cpl_image_delete(mapped_cleaned); \
110 cpl_image_delete(skylocalmap); \
111 cpl_image_delete(skymap); \
112 cpl_image_delete(smapped); \
113 cpl_table_delete(offsets); \
114 cpl_table_delete(global); \
115 cpl_table_delete(sky); \
116 cpl_image_delete(bias); \
117 cpl_image_delete(spectra); \
118 cpl_image_delete(coordinate); \
119 cpl_image_delete(norm_flat); \
120 cpl_image_delete(rainbow); \
121 cpl_image_delete(rectified); \
122 cpl_image_delete(wavemap); \
123 cpl_propertylist_delete(header); \
124 cpl_propertylist_delete(save_header); \
125 cpl_table_delete(grism_table); \
126 cpl_table_delete(idscoeff); \
127 cpl_table_delete(maskslits); \
128 cpl_table_delete(overscans); \
129 cpl_table_delete(polytraces); \
130 cpl_table_delete(slits); \
131 cpl_table_delete(wavelengths); \
132 cpl_vector_delete(lines); \
133 cpl_msg_indent_less(); \
138 #define fors_extract_exit_memcheck(message) \
140 if (message) cpl_msg_info(recipe, message); \
141 printf("free exptime (%p)\n", exptime); \
143 printf("free instrume (%p)\n", instrume); \
144 cpl_free(instrume); \
145 printf("free dummy (%p)\n", dummy); \
146 cpl_image_delete(dummy); \
147 printf("free mapped (%p)\n", mapped); \
148 cpl_image_delete(mapped); \
149 printf("free mapped_cleaned (%p)\n", mapped_cleaned); \
150 cpl_image_delete(mapped_cleaned); \
151 printf("free mapped_sky (%p)\n", mapped_sky); \
152 cpl_image_delete(mapped_sky); \
153 printf("free skylocalmap (%p)\n", skylocalmap); \
154 cpl_image_delete(skylocalmap); \
155 printf("free skymap (%p)\n", skymap); \
156 cpl_image_delete(skymap); \
157 printf("free smapped (%p)\n", smapped); \
158 cpl_image_delete(smapped); \
159 printf("free offsets (%p)\n", offsets); \
160 cpl_table_delete(offsets); \
161 printf("free global (%p)\n", global); \
162 cpl_table_delete(global); \
163 printf("free sky (%p)\n", sky); \
164 cpl_table_delete(sky); \
165 printf("free bias (%p)\n", bias); \
166 cpl_image_delete(bias); \
167 printf("free spectra (%p)\n", spectra); \
168 cpl_image_delete(spectra); \
169 printf("free coordinate (%p)\n", coordinate); \
170 cpl_image_delete(coordinate); \
171 printf("free norm_flat (%p)\n", norm_flat); \
172 cpl_image_delete(norm_flat); \
173 printf("free rainbow (%p)\n", rainbow); \
174 cpl_image_delete(rainbow); \
175 printf("free rectified (%p)\n", rectified); \
176 cpl_image_delete(rectified); \
177 printf("free wavemap (%p)\n", wavemap); \
178 cpl_image_delete(wavemap); \
179 printf("free header (%p)\n", header); \
180 cpl_propertylist_delete(header); \
181 printf("free save_header (%p)\n", save_header); \
182 cpl_propertylist_delete(save_header); \
183 printf("free grism_table (%p)\n", grism_table); \
184 cpl_table_delete(grism_table); \
185 printf("free idscoeff (%p)\n", idscoeff); \
186 cpl_table_delete(idscoeff); \
187 printf("free maskslits (%p)\n", maskslits); \
188 cpl_table_delete(maskslits); \
189 printf("free overscans (%p)\n", overscans); \
190 cpl_table_delete(overscans); \
191 printf("free polytraces (%p)\n", polytraces); \
192 cpl_table_delete(polytraces); \
193 printf("free slits (%p)\n", slits); \
194 cpl_table_delete(slits); \
195 printf("free wavelengths (%p)\n", wavelengths); \
196 cpl_table_delete(wavelengths); \
197 printf("free lines (%p)\n", lines); \
198 cpl_vector_delete(lines); \
199 cpl_msg_indent_less(); \
217 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe );
218 cpl_plugin *plugin = &recipe->interface;
220 cpl_plugin_init(plugin,
223 CPL_PLUGIN_TYPE_RECIPE,
225 "Extraction of scientific spectra",
226 fors_extract_description,
229 "This file is currently part of the FORS Instrument Pipeline\n"
230 "Copyright (C) 2002-2010 European Southern Observatory\n\n"
231 "This program is free software; you can redistribute it and/or modify\n"
232 "it under the terms of the GNU General Public License as published by\n"
233 "the Free Software Foundation; either version 2 of the License, or\n"
234 "(at your option) any later version.\n\n"
235 "This program is distributed in the hope that it will be useful,\n"
236 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
237 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
238 "GNU General Public License for more details.\n\n"
239 "You should have received a copy of the GNU General Public License\n"
240 "along with this program; if not, write to the Free Software Foundation,\n"
241 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n",
244 fors_extract_destroy);
246 cpl_pluginlist_append(list, plugin);
262 static int fors_extract_create(cpl_plugin *plugin)
272 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
273 recipe = (cpl_recipe *)plugin;
281 recipe->parameters = cpl_parameterlist_new();
288 p = cpl_parameter_new_value(
"fors.fors_extract.dispersion",
290 "Resampling step (Angstrom/pixel)",
293 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dispersion");
294 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
295 cpl_parameterlist_append(recipe->parameters, p);
301 p = cpl_parameter_new_value(
"fors.fors_extract.skyalign",
303 "Polynomial order for sky lines alignment, "
304 "or -1 to avoid alignment",
307 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skyalign");
308 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
309 cpl_parameterlist_append(recipe->parameters, p);
315 p = cpl_parameter_new_value(
"fors.fors_extract.wcolumn",
317 "Name of sky line catalog table column "
321 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wcolumn");
322 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
323 cpl_parameterlist_append(recipe->parameters, p);
329 p = cpl_parameter_new_value(
"fors.fors_extract.startwavelength",
331 "Start wavelength in spectral extraction",
334 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"startwavelength");
335 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
336 cpl_parameterlist_append(recipe->parameters, p);
342 p = cpl_parameter_new_value(
"fors.fors_extract.endwavelength",
344 "End wavelength in spectral extraction",
347 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"endwavelength");
348 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
349 cpl_parameterlist_append(recipe->parameters, p);
355 p = cpl_parameter_new_value(
"fors.fors_extract.flux",
357 "Apply flux conservation",
360 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"flux");
361 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
362 cpl_parameterlist_append(recipe->parameters, p);
368 p = cpl_parameter_new_value(
"fors.fors_extract.flatfield",
373 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"flatfield");
374 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
375 cpl_parameterlist_append(recipe->parameters, p);
381 p = cpl_parameter_new_value(
"fors.fors_extract.skyglobal",
383 "Subtract global sky spectrum from CCD",
386 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skyglobal");
387 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
388 cpl_parameterlist_append(recipe->parameters, p);
407 p = cpl_parameter_new_value(
"fors.fors_extract.skymedian",
409 "Sky subtraction from extracted slit spectra",
412 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skymedian");
413 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
414 cpl_parameterlist_append(recipe->parameters, p);
420 p = cpl_parameter_new_value(
"fors.fors_extract.skylocal",
422 "Sky subtraction from CCD slit spectra",
425 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skylocal");
426 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
427 cpl_parameterlist_append(recipe->parameters, p);
433 p = cpl_parameter_new_value(
"fors.fors_extract.cosmics",
435 "Eliminate cosmic rays hits (only if global "
436 "sky subtraction is also requested)",
439 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"cosmics");
440 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
441 cpl_parameterlist_append(recipe->parameters, p);
447 p = cpl_parameter_new_value(
"fors.fors_extract.slit_margin",
449 "Number of pixels to exclude at each slit "
450 "in object detection and extraction",
453 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"slit_margin");
454 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
455 cpl_parameterlist_append(recipe->parameters, p);
461 p = cpl_parameter_new_value(
"fors.fors_extract.ext_radius",
463 "Maximum extraction radius for detected "
467 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ext_radius");
468 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
469 cpl_parameterlist_append(recipe->parameters, p);
475 p = cpl_parameter_new_value(
"fors.fors_extract.cont_radius",
477 "Minimum distance at which two objects "
478 "of equal luminosity do not contaminate "
479 "each other (pixel)",
482 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"cont_radius");
483 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
484 cpl_parameterlist_append(recipe->parameters, p);
490 p = cpl_parameter_new_value(
"fors.fors_extract.ext_mode",
492 "Object extraction method: 0 = aperture, "
493 "1 = Horne optimal extraction",
496 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ext_mode");
497 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
498 cpl_parameterlist_append(recipe->parameters, p);
504 p = cpl_parameter_new_value(
"fors.fors_extract.time_normalise",
506 "Normalise output spectra by the exposure time",
509 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"time_normalise");
510 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
511 cpl_parameterlist_append(recipe->parameters, p);
525 static int fors_extract_exec(cpl_plugin *plugin)
529 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
530 recipe = (cpl_recipe *)plugin;
534 return fors_extract(recipe->parameters, recipe->frames);
546 static int fors_extract_destroy(cpl_plugin *plugin)
550 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
551 recipe = (cpl_recipe *)plugin;
555 cpl_parameterlist_delete(recipe->parameters);
570 static int fors_extract(cpl_parameterlist *parlist, cpl_frameset *frameset)
573 const char *recipe =
"fors_extract";
583 double startwavelength;
584 double endwavelength;
602 cpl_imagelist *all_science;
605 cpl_image *bias = NULL;
606 cpl_image *norm_flat = NULL;
607 cpl_image *spectra = NULL;
608 cpl_image *rectified = NULL;
609 cpl_image *coordinate = NULL;
610 cpl_image *rainbow = NULL;
611 cpl_image *mapped = NULL;
612 cpl_image *mapped_sky = NULL;
613 cpl_image *mapped_cleaned = NULL;
614 cpl_image *smapped = NULL;
615 cpl_image *wavemap = NULL;
616 cpl_image *skymap = NULL;
617 cpl_image *skylocalmap = NULL;
618 cpl_image *dummy = NULL;
620 cpl_table *grism_table = NULL;
621 cpl_table *overscans = NULL;
622 cpl_table *wavelengths = NULL;
623 cpl_table *idscoeff = NULL;
624 cpl_table *slits = NULL;
625 cpl_table *maskslits = NULL;
626 cpl_table *polytraces = NULL;
627 cpl_table *offsets = NULL;
628 cpl_table *sky = NULL;
629 cpl_table *global = NULL;
631 cpl_vector *lines = NULL;
633 cpl_propertylist *header = NULL;
634 cpl_propertylist *save_header = NULL;
641 char *instrume = NULL;
643 const char *science_tag;
644 const char *master_norm_flat_tag;
645 const char *disp_coeff_sky_tag;
646 const char *wavelength_map_sky_tag;
647 const char *reduced_science_tag;
648 const char *reduced_sky_tag;
649 const char *reduced_error_tag;
650 const char *mapped_science_tag;
651 const char *unmapped_science_tag;
652 const char *mapped_science_sky_tag;
653 const char *mapped_sky_tag;
654 const char *unmapped_sky_tag;
655 const char *global_sky_spectrum_tag;
656 const char *object_table_tag;
657 const char *skylines_offsets_tag;
658 const char *global_distortion_tag =
"MASTER_DISTORTION_TABLE";
662 double *exptime = NULL;
678 snprintf(version, 80,
"%s-%s", PACKAGE, PACKAGE_VERSION);
680 cpl_msg_set_indentation(2);
686 cpl_msg_info(recipe,
"Recipe %s configuration parameters:", recipe);
687 cpl_msg_indent_more();
689 if (cpl_frameset_count_tags(frameset,
"GRISM_TABLE") > 1)
690 fors_extract_exit(
"Too many in input: GRISM_TABLE");
695 "fors.fors_extract.dispersion", grism_table);
697 if (dispersion <= 0.0)
698 fors_extract_exit(
"Invalid resampling step");
701 "fors.fors_extract.skyalign", NULL);
704 fors_extract_exit(
"Max polynomial degree for sky alignment is 2");
707 "fors.fors_extract.wcolumn", NULL);
710 "fors.fors_extract.startwavelength", grism_table);
711 if (startwavelength < 3000.0 || startwavelength > 13000.0)
712 fors_extract_exit(
"Invalid wavelength");
715 "fors.fors_extract.endwavelength", grism_table);
716 if (endwavelength < 3000.0 || endwavelength > 13000.0)
717 fors_extract_exit(
"Invalid wavelength");
719 if (endwavelength - startwavelength <= 0.0)
720 fors_extract_exit(
"Invalid wavelength interval");
738 if (skylocal && skyglobal)
739 fors_extract_exit(
"Cannot apply both local and global sky subtraction");
741 if (skylocal && skymedian)
742 fors_extract_exit(
"Cannot apply sky subtraction both on extracted "
743 "and non-extracted spectra");
746 "fors.fors_extract.cosmics", NULL);
749 if (!(skyglobal || skylocal))
750 fors_extract_exit(
"Cosmic rays correction requires "
751 "either skylocal=true or skyglobal=true");
754 "fors.fors_extract.slit_margin",
757 fors_extract_exit(
"Value must be zero or positive");
760 "fors.fors_extract.ext_radius",
763 fors_extract_exit(
"Value must be zero or positive");
766 "fors.fors_extract.cont_radius",
769 fors_extract_exit(
"Value must be zero or positive");
773 if (ext_mode < 0 || ext_mode > 1)
774 fors_extract_exit(
"Invalid object extraction mode");
777 "fors.fors_extract.time_normalise", NULL);
779 cpl_table_delete(grism_table); grism_table = NULL;
781 if (cpl_error_get_code())
782 fors_extract_exit(
"Failure getting the configuration parameters");
789 cpl_msg_indent_less();
790 cpl_msg_info(recipe,
"Check input set-of-frames:");
791 cpl_msg_indent_more();
794 fors_extract_exit(
"Input frames are not from the same grism");
797 fors_extract_exit(
"Input frames are not from the same filter");
800 fors_extract_exit(
"Input frames are not from the same chip");
802 mxu = cpl_frameset_count_tags(frameset,
"SCIENCE_MXU");
803 mos = cpl_frameset_count_tags(frameset,
"SCIENCE_MOS");
804 lss = cpl_frameset_count_tags(frameset,
"SCIENCE_LSS");
807 if (mxu + mos + lss == 0) {
808 mxu = cpl_frameset_count_tags(frameset,
"STANDARD_MXU");
809 mos = cpl_frameset_count_tags(frameset,
"STANDARD_MOS");
810 lss = cpl_frameset_count_tags(frameset,
"STANDARD_LSS");
814 if (mxu + mos + lss == 0)
815 fors_extract_exit(
"Missing input scientific frame");
817 nscience = mxu + mos + lss;
819 if (mxu && mxu < nscience)
820 fors_extract_exit(
"Input scientific frames must be of the same type");
822 if (mos && mos < nscience)
823 fors_extract_exit(
"Input scientific frames must be of the same type");
825 if (lss && lss < nscience)
826 fors_extract_exit(
"Input scientific frames must be of the same type");
830 cpl_msg_info(recipe,
"MXU data found");
831 science_tag =
"STANDARD_MXU";
832 reduced_science_tag =
"REDUCED_STD_MXU";
833 unmapped_science_tag =
"UNMAPPED_STD_MXU";
834 mapped_science_tag =
"MAPPED_STD_MXU";
835 mapped_science_sky_tag =
"MAPPED_ALL_STD_MXU";
836 skylines_offsets_tag =
"SKY_SHIFTS_SLIT_STD_MXU";
837 wavelength_map_sky_tag =
"WAVELENGTH_MAP_STD_MXU";
838 disp_coeff_sky_tag =
"DISP_COEFF_STD_MXU";
839 mapped_sky_tag =
"MAPPED_SKY_STD_MXU";
840 unmapped_sky_tag =
"UNMAPPED_SKY_STD_MXU";
841 object_table_tag =
"OBJECT_TABLE_STD_MXU";
842 reduced_sky_tag =
"REDUCED_SKY_STD_MXU";
843 reduced_error_tag =
"REDUCED_ERROR_STD_MXU";
846 cpl_msg_info(recipe,
"MXU data found");
847 science_tag =
"SCIENCE_MXU";
848 reduced_science_tag =
"REDUCED_SCI_MXU";
849 unmapped_science_tag =
"UNMAPPED_SCI_MXU";
850 mapped_science_tag =
"MAPPED_SCI_MXU";
851 mapped_science_sky_tag =
"MAPPED_ALL_SCI_MXU";
852 skylines_offsets_tag =
"SKY_SHIFTS_SLIT_SCI_MXU";
853 wavelength_map_sky_tag =
"WAVELENGTH_MAP_SCI_MXU";
854 disp_coeff_sky_tag =
"DISP_COEFF_SCI_MXU";
855 mapped_sky_tag =
"MAPPED_SKY_SCI_MXU";
856 unmapped_sky_tag =
"UNMAPPED_SKY_SCI_MXU";
857 object_table_tag =
"OBJECT_TABLE_SCI_MXU";
858 reduced_sky_tag =
"REDUCED_SKY_SCI_MXU";
859 reduced_error_tag =
"REDUCED_ERROR_SCI_MXU";
862 master_norm_flat_tag =
"MASTER_NORM_FLAT_MXU";
863 global_sky_spectrum_tag =
"GLOBAL_SKY_SPECTRUM_MXU";
865 if (!cpl_frameset_count_tags(frameset, master_norm_flat_tag)) {
866 master_norm_flat_tag =
"MASTER_NORM_FLAT_LONG_MXU";
872 if (cosmics && !skyglobal)
873 fors_extract_exit(
"Cosmic rays correction for LSS "
874 "data requires --skyglobal=true");
876 cpl_msg_info(recipe,
"LSS data found");
879 science_tag =
"STANDARD_LSS";
880 reduced_science_tag =
"REDUCED_STD_LSS";
881 unmapped_science_tag =
"UNMAPPED_STD_LSS";
882 mapped_science_tag =
"MAPPED_STD_LSS";
883 mapped_science_sky_tag =
"MAPPED_ALL_STD_LSS";
884 skylines_offsets_tag =
"SKY_SHIFTS_LONG_STD_LSS";
885 wavelength_map_sky_tag =
"WAVELENGTH_MAP_STD_LSS";
886 disp_coeff_sky_tag =
"DISP_COEFF_STD_LSS";
887 mapped_sky_tag =
"MAPPED_SKY_STD_LSS";
888 unmapped_sky_tag =
"UNMAPPED_SKY_STD_LSS";
889 object_table_tag =
"OBJECT_TABLE_STD_LSS";
890 reduced_sky_tag =
"REDUCED_SKY_STD_LSS";
891 reduced_error_tag =
"REDUCED_ERROR_STD_LSS";
894 science_tag =
"SCIENCE_LSS";
895 reduced_science_tag =
"REDUCED_SCI_LSS";
896 unmapped_science_tag =
"UNMAPPED_SCI_LSS";
897 mapped_science_tag =
"MAPPED_SCI_LSS";
898 mapped_science_sky_tag =
"MAPPED_ALL_SCI_LSS";
899 skylines_offsets_tag =
"SKY_SHIFTS_LONG_SCI_LSS";
900 wavelength_map_sky_tag =
"WAVELENGTH_MAP_SCI_LSS";
901 disp_coeff_sky_tag =
"DISP_COEFF_SCI_LSS";
902 mapped_sky_tag =
"MAPPED_SKY_SCI_LSS";
903 unmapped_sky_tag =
"UNMAPPED_SKY_SCI_LSS";
904 object_table_tag =
"OBJECT_TABLE_SCI_LSS";
905 reduced_sky_tag =
"REDUCED_SKY_SCI_LSS";
906 reduced_error_tag =
"REDUCED_ERROR_SCI_LSS";
909 master_norm_flat_tag =
"MASTER_NORM_FLAT_LSS";
910 global_sky_spectrum_tag =
"GLOBAL_SKY_SPECTRUM_LSS";
914 cpl_msg_info(recipe,
"MOS data found");
916 science_tag =
"STANDARD_MOS";
917 reduced_science_tag =
"REDUCED_STD_MOS";
918 unmapped_science_tag =
"UNMAPPED_STD_MOS";
919 mapped_science_tag =
"MAPPED_STD_MOS";
920 mapped_science_sky_tag =
"MAPPED_ALL_STD_MOS";
921 skylines_offsets_tag =
"SKY_SHIFTS_SLIT_STD_MOS";
922 wavelength_map_sky_tag =
"WAVELENGTH_MAP_STD_MOS";
923 disp_coeff_sky_tag =
"DISP_COEFF_STD_MOS";
924 mapped_sky_tag =
"MAPPED_SKY_STD_MOS";
925 unmapped_sky_tag =
"UNMAPPED_SKY_STD_MOS";
926 object_table_tag =
"OBJECT_TABLE_STD_MOS";
927 reduced_sky_tag =
"REDUCED_SKY_STD_MOS";
928 reduced_error_tag =
"REDUCED_ERROR_STD_MOS";
931 science_tag =
"SCIENCE_MOS";
932 reduced_science_tag =
"REDUCED_SCI_MOS";
933 unmapped_science_tag =
"UNMAPPED_SCI_MOS";
934 mapped_science_tag =
"MAPPED_SCI_MOS";
935 mapped_science_sky_tag =
"MAPPED_ALL_SCI_MOS";
936 skylines_offsets_tag =
"SKY_SHIFTS_SLIT_SCI_MOS";
937 wavelength_map_sky_tag =
"WAVELENGTH_MAP_SCI_MOS";
938 disp_coeff_sky_tag =
"DISP_COEFF_SCI_MOS";
939 mapped_sky_tag =
"MAPPED_SKY_SCI_MOS";
940 unmapped_sky_tag =
"UNMAPPED_SKY_SCI_MOS";
941 object_table_tag =
"OBJECT_TABLE_SCI_MOS";
942 reduced_sky_tag =
"REDUCED_SKY_SCI_MOS";
943 reduced_error_tag =
"REDUCED_ERROR_SCI_MOS";
946 master_norm_flat_tag =
"MASTER_NORM_FLAT_MOS";
947 global_sky_spectrum_tag =
"GLOBAL_SKY_SPECTRUM_MOS";
949 if (!cpl_frameset_count_tags(frameset, master_norm_flat_tag)) {
950 master_norm_flat_tag =
"MASTER_NORM_FLAT_LONG_MOS";
954 if (cpl_frameset_count_tags(frameset,
"MASTER_BIAS") == 0)
955 fors_extract_exit(
"Missing required input: MASTER_BIAS");
957 if (cpl_frameset_count_tags(frameset,
"MASTER_BIAS") > 1)
958 fors_extract_exit(
"Too many in input: MASTER_BIAS");
961 if (cpl_frameset_count_tags(frameset,
"MASTER_SKYLINECAT") > 1)
962 fors_extract_exit(
"Too many in input: MASTER_SKYLINECAT");
964 if (cpl_frameset_count_tags(frameset, global_distortion_tag) == 0)
965 fors_extract_exit(
"Missing required input: MASTER_DISTORTION_TABLE");
967 if (cpl_frameset_count_tags(frameset, global_distortion_tag) > 1)
968 fors_extract_exit(
"Too many in input: MASTER_DISTORTION_TABLE");
970 if (cpl_frameset_count_tags(frameset, master_norm_flat_tag) > 1) {
972 cpl_msg_error(recipe,
"Too many in input: %s",
973 master_norm_flat_tag);
974 fors_extract_exit(NULL);
977 cpl_msg_warning(recipe,
"%s in input are ignored, "
978 "since flat field correction was not requested",
979 master_norm_flat_tag);
983 if (cpl_frameset_count_tags(frameset, master_norm_flat_tag) == 1) {
985 cpl_msg_warning(recipe,
"%s in input is ignored, "
986 "since flat field correction was not requested",
987 master_norm_flat_tag);
991 if (cpl_frameset_count_tags(frameset, master_norm_flat_tag) == 0) {
993 cpl_msg_error(recipe,
"Flat field correction was requested, "
994 "but no %s are found in input",
995 master_norm_flat_tag);
996 fors_extract_exit(NULL);
1000 cpl_msg_indent_less();
1007 exptime = cpl_calloc(nscience,
sizeof(
double));
1011 cpl_msg_info(recipe,
"Load %d scientific frames and median them...",
1013 cpl_msg_indent_more();
1015 all_science = cpl_imagelist_new();
1020 fors_extract_exit(
"Cannot load scientific frame header");
1022 alltime = exptime[0] = cpl_propertylist_get_double(header,
"EXPTIME");
1024 if (cpl_error_get_code() != CPL_ERROR_NONE)
1025 fors_extract_exit(
"Missing keyword EXPTIME in scientific "
1028 cpl_propertylist_delete(header); header = NULL;
1030 cpl_msg_info(recipe,
"Scientific frame 1 exposure time: %.2f s",
1033 for (i = 1; i < nscience; i++) {
1038 fors_extract_exit(
"Cannot load scientific frame header");
1040 exptime[i] = cpl_propertylist_get_double(header,
"EXPTIME");
1042 alltime += exptime[i];
1044 if (cpl_error_get_code() != CPL_ERROR_NONE)
1045 fors_extract_exit(
"Missing keyword EXPTIME in scientific "
1048 cpl_propertylist_delete(header); header = NULL;
1050 cpl_msg_info(recipe,
"Scientific frame %d exposure time: %.2f s",
1054 spectra =
dfs_load_image(frameset, science_tag, CPL_TYPE_FLOAT, 0, 0);
1056 if (spectra == NULL)
1057 fors_extract_exit(
"Cannot load scientific frame");
1059 cpl_image_divide_scalar(spectra, exptime[0]);
1060 cpl_imagelist_set(all_science, spectra, 0); spectra = NULL;
1062 for (i = 1; i < nscience; i++) {
1067 cpl_image_divide_scalar(spectra, exptime[i]);
1068 cpl_imagelist_set(all_science, spectra, i); spectra = NULL;
1071 fors_extract_exit(
"Cannot load scientific frame");
1075 spectra = cpl_imagelist_collapse_median_create(all_science);
1076 cpl_image_multiply_scalar(spectra, alltime);
1078 cpl_imagelist_delete(all_science);
1081 cpl_msg_info(recipe,
"Load scientific exposure...");
1082 cpl_msg_indent_more();
1087 fors_extract_exit(
"Cannot load scientific frame header");
1094 wheel4 = (
char *)cpl_propertylist_get_string(header,
1095 "ESO INS OPTI9 TYPE");
1096 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1097 fors_extract_exit(
"Missing ESO INS OPTI9 TYPE in flat header");
1100 if (strcmp(
"FILT", wheel4) == 0) {
1101 wheel4 = (
char *)cpl_propertylist_get_string(header,
1102 "ESO INS OPTI9 NAME");
1103 cpl_msg_error(recipe,
"Unsupported filter: %s", wheel4);
1104 fors_extract_exit(NULL);
1108 alltime = exptime[0] = cpl_propertylist_get_double(header,
"EXPTIME");
1110 if (cpl_error_get_code() != CPL_ERROR_NONE)
1111 fors_extract_exit(
"Missing keyword EXPTIME in scientific "
1114 cpl_propertylist_delete(header); header = NULL;
1116 cpl_msg_info(recipe,
"Scientific frame exposure time: %.2f s",
1119 spectra =
dfs_load_image(frameset, science_tag, CPL_TYPE_FLOAT, 0, 0);
1122 if (spectra == NULL)
1123 fors_extract_exit(
"Cannot load scientific frame");
1125 cpl_free(exptime); exptime = NULL;
1127 cpl_msg_indent_less();
1138 fors_extract_exit(
"Cannot load scientific frame header");
1140 instrume = (
char *)cpl_propertylist_get_string(header,
"INSTRUME");
1141 if (instrume == NULL)
1142 fors_extract_exit(
"Missing keyword INSTRUME in sientific header");
1143 instrume = cpl_strdup(instrume);
1145 if (instrume[4] ==
'1')
1146 snprintf(version, 80,
"%s/%s",
"fors1", VERSION);
1147 if (instrume[4] ==
'2')
1148 snprintf(version, 80,
"%s/%s",
"fors2", VERSION);
1150 cpl_free(instrume); instrume = NULL;
1152 reference = cpl_propertylist_get_double(header,
"ESO INS GRIS1 WLEN");
1154 if (cpl_error_get_code() != CPL_ERROR_NONE)
1155 fors_extract_exit(
"Missing keyword ESO INS GRIS1 WLEN in scientific "
1158 if (reference < 3000.0)
1161 if (reference < 3000.0 || reference > 13000.0) {
1162 cpl_msg_error(recipe,
"Invalid central wavelength %.2f read from "
1163 "keyword ESO INS GRIS1 WLEN in scientific frame header",
1165 fors_extract_exit(NULL);
1168 cpl_msg_info(recipe,
"The central wavelength is: %.2f", reference);
1170 rebin = cpl_propertylist_get_int(header,
"ESO DET WIN1 BINX");
1172 if (cpl_error_get_code() != CPL_ERROR_NONE)
1173 fors_extract_exit(
"Missing keyword ESO DET WIN1 BINX in scientific "
1177 dispersion *= rebin;
1178 cpl_msg_warning(recipe,
"The rebin factor is %d, and therefore the "
1179 "resampling step used is %f A/pixel", rebin,
1183 gain = cpl_propertylist_get_double(header,
"ESO DET OUT1 CONAD");
1185 if (cpl_error_get_code() != CPL_ERROR_NONE)
1186 fors_extract_exit(
"Missing keyword ESO DET OUT1 CONAD in scientific "
1189 cpl_msg_info(recipe,
"The gain factor is: %.2f e-/ADU", gain);
1191 ron = cpl_propertylist_get_double(header,
"ESO DET OUT1 RON");
1193 if (cpl_error_get_code() != CPL_ERROR_NONE)
1194 fors_extract_exit(
"Missing keyword ESO DET OUT1 RON in scientific "
1199 cpl_msg_info(recipe,
"The read-out-noise is: %.2f ADU", ron);
1201 coll = (
char *)cpl_propertylist_get_string(header,
"ESO INS COLL NAME");
1203 if (cpl_error_get_code() != CPL_ERROR_NONE)
1204 fors_extract_exit(
"Missing keyword ESO INS COLL NAME in scientific "
1207 cpl_msg_info(recipe,
"The collimator is : %s", coll);
1209 if (strcmp(coll,
"COLL_HR") == 0)
1210 fors_extract_exit(
"HR collimator is not yet supported by this recipe");
1226 fors_extract_exit(
"Cosmic rays correction for LSS "
1227 "data requires --skyglobal=true");
1228 skymedian = skylocal;
1235 fors_extract_exit(
"Cannot load global distortion table");
1244 cpl_msg_info(recipe,
"Remove the master bias...");
1246 bias =
dfs_load_image(frameset,
"MASTER_BIAS", CPL_TYPE_FLOAT, 0, 1);
1249 fors_extract_exit(
"Cannot load master bias");
1252 cpl_propertylist_delete(header); header = NULL;
1254 cpl_image_delete(spectra); spectra = dummy; dummy = NULL;
1255 cpl_image_delete(bias); bias = NULL;
1256 cpl_table_delete(overscans); overscans = NULL;
1258 if (spectra == NULL)
1259 fors_extract_exit(
"Cannot remove bias from scientific frame");
1261 nx = cpl_image_get_size_x(spectra);
1262 ny = cpl_image_get_size_y(spectra);
1264 if (ny == 400 && nx == 2048)
1269 dummy = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
1270 cpl_image_copy(dummy, spectra, 1, 825);
1271 if (cpl_error_get_code())
1272 fors_extract_exit(
"Problems expanding scientific image");
1273 cpl_image_delete(spectra); spectra = dummy; dummy = NULL;
1276 cpl_msg_indent_less();
1277 cpl_msg_info(recipe,
"Load normalised flat field (if present)...");
1278 cpl_msg_indent_more();
1283 CPL_TYPE_FLOAT, 0, 1);
1287 dummy = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
1288 cpl_image_copy(dummy, norm_flat, 1, 825);
1289 if (cpl_error_get_code())
1290 fors_extract_exit(
"Problems expanding flat image");
1291 cpl_image_delete(norm_flat); norm_flat = dummy; dummy = NULL;
1293 cpl_msg_info(recipe,
"Apply flat field correction...");
1294 if (cpl_image_divide(spectra, norm_flat) != CPL_ERROR_NONE) {
1295 cpl_msg_error(recipe,
"Failure of flat field correction: %s",
1296 cpl_error_get_message());
1297 fors_extract_exit(NULL);
1299 cpl_image_delete(norm_flat); norm_flat = NULL;
1302 cpl_msg_error(recipe,
"Cannot load input %s for flat field "
1303 "correction", master_norm_flat_tag);
1304 fors_extract_exit(NULL);
1310 if (skyalign >= 0) {
1311 cpl_msg_indent_less();
1312 cpl_msg_info(recipe,
"Load input sky line catalog...");
1313 cpl_msg_indent_more();
1323 nlines = cpl_table_get_nrow(wavelengths);
1326 fors_extract_exit(
"Empty input sky line catalog");
1328 if (cpl_table_has_column(wavelengths, wcolumn) != 1) {
1329 cpl_msg_error(recipe,
"Missing column %s in input line "
1330 "catalog table", wcolumn);
1331 fors_extract_exit(NULL);
1334 line = cpl_malloc(nlines *
sizeof(
double));
1336 for (i = 0; i < nlines; i++)
1337 line[i] = cpl_table_get(wavelengths, wcolumn, i, NULL);
1339 cpl_table_delete(wavelengths); wavelengths = NULL;
1341 lines = cpl_vector_wrap(nlines, line);
1344 cpl_msg_info(recipe,
"No sky line catalog found in input - fine!");
1356 fors_extract_exit(
"Cannot create slits location table");
1364 if (polytraces == NULL)
1365 fors_extract_exit(
"Cannot create spectral curvature table");
1367 cpl_table_delete(maskslits); maskslits = NULL;
1369 cpl_msg_indent_less();
1370 cpl_msg_info(recipe,
"Processing scientific spectra...");
1371 cpl_msg_indent_more();
1378 coordinate = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
1381 startwavelength, endwavelength,
1382 dispersion, flux, coordinate);
1390 if (idscoeff == NULL)
1391 fors_extract_exit(
"Cannot create wavelength calibration table");
1393 cpl_table_delete(global); global = NULL;
1404 if (dispersion > 1.0)
1409 if (skyalign >= 0) {
1411 cpl_msg_info(recipe,
"Align wavelength solution to reference "
1412 "skylines applying %d order residual fit...", skyalign);
1415 cpl_msg_info(recipe,
"Align wavelength solution to reference "
1416 "skylines applying median offset...");
1421 startwavelength, endwavelength,
1422 idscoeff, lines, highres,
1423 skyalign, rainbow, 4);
1427 startwavelength, endwavelength,
1428 idscoeff, lines, highres, skyalign,
1432 cpl_vector_delete(lines); lines = NULL;
1436 cpl_msg_warning(recipe,
"Alignment of the wavelength solution "
1437 "to reference sky lines may be unreliable in "
1440 if (
dfs_save_table(frameset, offsets, skylines_offsets_tag, NULL,
1441 parlist, recipe, version))
1442 fors_extract_exit(NULL);
1444 cpl_table_delete(offsets); offsets = NULL;
1447 cpl_msg_warning(recipe,
"Alignment of the wavelength solution "
1448 "to reference sky lines could not be done!");
1455 polytraces, reference,
1456 startwavelength, endwavelength,
1459 cpl_image_delete(rainbow); rainbow = NULL;
1460 cpl_image_delete(coordinate); coordinate = NULL;
1468 startwavelength, endwavelength,
1469 dispersion, idscoeff, flux);
1471 cpl_msg_indent_less();
1472 cpl_msg_info(recipe,
"Check applied wavelength against skylines...");
1473 cpl_msg_indent_more();
1476 dispersion, 6, highres);
1478 cpl_msg_info(recipe,
"Mean residual: %f", mean_rms);
1480 mean_rms = cpl_table_get_column_mean(idscoeff,
"error");
1482 header = cpl_propertylist_new();
1483 cpl_propertylist_update_double(header,
"CRPIX1", 1.0);
1484 cpl_propertylist_update_double(header,
"CRPIX2", 1.0);
1485 cpl_propertylist_update_double(header,
"CRVAL1",
1486 startwavelength + dispersion/2);
1487 cpl_propertylist_update_double(header,
"CRVAL2", 1.0);
1490 cpl_propertylist_update_double(header,
"CD1_1", dispersion);
1491 cpl_propertylist_update_double(header,
"CD1_2", 0.0);
1492 cpl_propertylist_update_double(header,
"CD2_1", 0.0);
1493 cpl_propertylist_update_double(header,
"CD2_2", 1.0);
1494 cpl_propertylist_update_string(header,
"CTYPE1",
"LINEAR");
1495 cpl_propertylist_update_string(header,
"CTYPE2",
"PIXEL");
1497 if (time_normalise) {
1498 dummy = cpl_image_divide_scalar_create(mapped_sky, alltime);
1499 if (
dfs_save_image(frameset, dummy, mapped_science_sky_tag, header,
1500 parlist, recipe, version))
1501 fors_extract_exit(NULL);
1502 cpl_image_delete(dummy); dummy = NULL;
1506 header, parlist, recipe, version))
1507 fors_extract_exit(NULL);
1511 if (skyglobal == 0 && skymedian == 0 && skylocal == 0) {
1512 cpl_image_delete(mapped_sky); mapped_sky = NULL;
1515 if (skyglobal || skylocal) {
1517 cpl_msg_indent_less();
1520 cpl_msg_info(recipe,
"Global sky determination...");
1521 cpl_msg_indent_more();
1522 skymap = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
1526 cpl_image_subtract(spectra, skymap);
1528 cpl_image_delete(skymap); skymap = NULL;
1531 cpl_msg_info(recipe,
"Local sky determination...");
1532 cpl_msg_indent_more();
1534 startwavelength, endwavelength, dispersion);
1540 cpl_table_divide_scalar(sky,
"sky", alltime);
1542 NULL, parlist, recipe, version))
1543 fors_extract_exit(NULL);
1545 cpl_table_delete(sky); sky = NULL;
1551 cpl_image_divide_scalar(skymap, alltime);
1553 save_header, parlist, recipe, version))
1554 fors_extract_exit(NULL);
1556 cpl_image_delete(skymap); skymap = NULL;
1559 save_header, parlist, recipe, version))
1560 fors_extract_exit(NULL);
1562 cpl_propertylist_delete(save_header); save_header = NULL;
1565 cpl_msg_info(recipe,
"Removing cosmic rays...");
1574 cpl_image_delete(smapped); smapped = NULL;
1577 smapped = cpl_image_duplicate(spectra);
1581 reference, startwavelength,
1582 endwavelength, dispersion,
1587 cpl_msg_warning(recipe,
"Sky subtraction failure");
1589 cpl_msg_warning(recipe,
"Cosmic rays removal not performed!");
1590 cosmics = skylocal = skyglobal = 0;
1594 cpl_image_delete(spectra); spectra = NULL;
1595 cpl_table_delete(polytraces); polytraces = NULL;
1597 if (skyalign >= 0) {
1600 save_header, parlist, recipe, version))
1601 fors_extract_exit(NULL);
1602 cpl_propertylist_delete(save_header); save_header = NULL;
1605 cpl_image_delete(wavemap); wavemap = NULL;
1608 startwavelength, endwavelength,
1609 dispersion, idscoeff, flux);
1611 cpl_image_delete(smapped); smapped = NULL;
1615 cpl_msg_indent_less();
1616 cpl_msg_info(recipe,
"Local sky determination...");
1617 cpl_msg_indent_more();
1622 cpl_image_subtract(mapped, skylocalmap);
1628 cpl_image_delete(skylocalmap); skylocalmap = NULL;
1632 if (skyglobal || skymedian || skylocal) {
1634 skylocalmap = cpl_image_subtract_create(mapped_sky, mapped);
1636 cpl_image_delete(mapped_sky); mapped_sky = NULL;
1638 if (time_normalise) {
1639 dummy = cpl_image_divide_scalar_create(skylocalmap, alltime);
1641 parlist, recipe, version))
1642 fors_extract_exit(NULL);
1643 cpl_image_delete(dummy); dummy = NULL;
1646 if (
dfs_save_image(frameset, skylocalmap, mapped_sky_tag, header,
1647 parlist, recipe, version))
1648 fors_extract_exit(NULL);
1651 cpl_msg_indent_less();
1652 cpl_msg_info(recipe,
"Object detection...");
1653 cpl_msg_indent_more();
1655 if (cosmics || nscience > 1) {
1660 mapped_cleaned = cpl_image_duplicate(mapped);
1663 ext_radius, cont_radius);
1665 cpl_image_delete(mapped_cleaned); mapped_cleaned = NULL;
1668 cpl_image_delete(dummy); dummy = NULL;
1670 if (
dfs_save_table(frameset, slits, object_table_tag, NULL, parlist,
1672 fors_extract_exit(NULL);
1674 cpl_msg_indent_less();
1675 cpl_msg_info(recipe,
"Object extraction...");
1676 cpl_msg_indent_more();
1679 ext_mode, ron, gain, 1);
1681 cpl_image_delete(skylocalmap); skylocalmap = NULL;
1685 cpl_image_divide_scalar(images[0], alltime);
1686 if (
dfs_save_image(frameset, images[0], reduced_science_tag, header,
1687 parlist, recipe, version))
1688 fors_extract_exit(NULL);
1689 cpl_image_delete(images[0]);
1692 cpl_image_divide_scalar(images[1], alltime);
1694 parlist, recipe, version))
1695 fors_extract_exit(NULL);
1696 cpl_image_delete(images[1]);
1699 cpl_image_divide_scalar(images[2], alltime);
1700 if (
dfs_save_image(frameset, images[2], reduced_error_tag, header,
1701 parlist, recipe, version))
1702 fors_extract_exit(NULL);
1703 cpl_image_delete(images[2]);
1708 cpl_msg_warning(recipe,
"No objects found: the products "
1709 "%s, %s, and %s are not created",
1710 reduced_science_tag, reduced_sky_tag,
1716 cpl_table_delete(slits); slits = NULL;
1718 if (skyalign >= 0) {
1720 parlist, recipe, version))
1721 fors_extract_exit(NULL);
1724 cpl_table_delete(idscoeff); idscoeff = NULL;
1727 if (skyglobal || skymedian || skylocal) {
1729 cpl_image_divide_scalar(mapped, alltime);
1731 parlist, recipe, version))
1732 fors_extract_exit(NULL);
1735 cpl_image_delete(mapped); mapped = NULL;
1736 cpl_propertylist_delete(header); header = NULL;
1738 if (cpl_error_get_code()) {
1739 cpl_msg_error(cpl_error_get_where(),
"%s", cpl_error_get_message());
1740 fors_extract_exit(NULL);
cpl_image * mos_spatial_calibration(cpl_image *spectra, cpl_table *slits, cpl_table *polytraces, double reference, double blue, double red, double dispersion, int flux, cpl_image *calibration)
Spatial remapping of CCD spectra eliminating the spectral curvature.
cpl_table * mos_build_disp_coeff(cpl_table *global, cpl_table *slits)
Build the IDS coefficients table from a global distortions table.
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.
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_extract_objects(cpl_image *science, cpl_image *sky, cpl_table *objects, int extraction, double ron, double gain, int ncombined)
Extract detected objects from rectified scientific frame.
cpl_image * mos_map_wavelengths(cpl_image *spatial, cpl_image *calibration, cpl_table *slits, cpl_table *polytraces, double reference, double blue, double red, double dispersion)
Remapping of spatially rectified wavelengths to original CCD pixels.
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_sky_map_super(cpl_image *spectra, cpl_image *wavemap, double dispersion, double factor, int minpoints, cpl_image *skymap)
Create a CCD median sky map.
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_table * mos_wavelength_align(cpl_image *image, cpl_table *slits, double refwave, double firstLambda, double lastLambda, cpl_table *idscoeff, cpl_vector *skylines, int highres, int order, cpl_image *calibration, int sradius)
Modify the input wavelength solution to match reference sky lines.
cpl_image * mos_remove_bias(cpl_image *image, cpl_image *bias, cpl_table *overscans)
Subtract the bias from a CCD exposure.
cpl_image * mos_detect_objects(cpl_image *image, cpl_table *slits, int margin, int maxradius, int conradius)
Detect objects in rectified scientific frame.
cpl_image * mos_sky_local_old(cpl_image *spectra, cpl_table *slits)
Local determination of sky.
int dfs_get_parameter_bool(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe boolean parameter value.
int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
Saving table data of given category.
cpl_table * mos_wavelength_align_lss(cpl_image *image, double refwave, double firstLambda, double lastLambda, cpl_table *idscoeff, cpl_vector *skylines, int highres, int order, cpl_image *calibration, int sradius)
Modify the input wavelength solution to match reference sky lines (LSS).
cpl_image * mos_subtract_sky(cpl_image *science, cpl_table *slits, cpl_table *polytraces, double reference, double blue, double red, double dispersion)
Subtract the sky from the scientific CCD exposure.
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_error_code mos_clean_cosmics(cpl_image *image, float gain, float threshold, float ratio)
Remove cosmic rays from sky-subtracted CCD spectral exposure.
cpl_table * mos_build_curv_coeff(cpl_table *global, cpl_table *maskslits, cpl_table *slits)
Build the curvature coefficients table from a global distortions table.
double dfs_get_parameter_double(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe double parameter value.
cpl_table * mos_load_slits_fors_lss(cpl_propertylist *header)
Create slit location table from FITS header of FORS1/2 LSS data.
cpl_table * mos_load_overscans_vimos(const cpl_propertylist *header, int check_consistency)
Get the overscan positions from FITS header of VIMOS data.
cpl_table * mos_build_slit_location(cpl_table *global, cpl_table *maskslits, int ysize)
Build the slit location table from a global distortions table.