34 #include <vimos_science_impl.h>
37 #include <fors_stack.h>
38 #include <fors_tools.h>
42 static int vimos_science_create(cpl_plugin *);
43 static int vimos_science_exec(cpl_plugin *);
44 static int vimos_science_destroy(cpl_plugin *);
45 static int vimos_science(cpl_parameterlist *, cpl_frameset *);
47 static char vimos_science_description[] =
48 "This recipe is used to reduce scientific spectra using the extraction\n"
49 "mask and the products created by the recipe vimos_calib. The spectra are\n"
50 "bias subtracted, flat fielded (if a normalised flat field is specified)\n"
51 "and remapped eliminating the optical distortions. The wavelength calibration\n"
52 "can be optionally upgraded using a number of sky lines: if no sky lines\n"
53 "catalog of wavelengths is specified, an internal one is used instead.\n"
54 "If the alignment to the sky lines is performed, the input dispersion\n"
55 "coefficients table is upgraded and saved to disk, and a new CCD wavelengths\n"
56 "map is created. A grism table (typically depending on the grism used)\n"
57 "may also be specified: this table contains a default recipe parameter\n"
58 "setting to control the way spectra are extracted for a specific instrument\n"
59 "mode, as it is used for automatic run of the pipeline on Paranal and in\n"
60 "Garching. If this table is specified, it will modify the default recipe\n"
61 "parameter setting, with the exception of those parameters which have been\n"
62 "explicitly modifyed on the command line. If a grism table is not specified,\n"
63 "the input recipe parameters values will always be read from the command\n"
64 "line, or from an esorex configuration file if present, or from their\n"
65 "generic default values (that are rarely meaningful).\n"
66 "MOS_SLIT_LOCATION and MOS_CURV_COEFF tables are not (yet) expected for\n"
67 "long-slit-like data.\n"
68 "Only in case of a standard star exposure input, the atmospheric extinction\n"
69 "table and a table with the physical fluxes of the observed standard star\n"
70 "must be specified in input.\n\n"
72 " DO category: Type: Explanation: Required:\n"
73 " MOS_SCIENCE Raw Scientific exposure Y\n"
74 " or MOS_STANDARD Raw Standard star exposure Y\n"
76 " MASTER_BIAS Calib Master bias Y\n"
77 " SKY_LINE_CATALOG Calib Sky lines catalog .\n"
78 " MOS_MASTER_SCREEN_FLAT Calib Normalised flat field .\n"
79 " MOS_DISP_COEFF Calib Inverse dispersion Y\n"
80 " MOS_CURV_COEFF Calib Spectral curvature Y\n"
81 " MOS_SLIT_LOCATION Calib Slits positions table Y\n"
82 " GRISM_TABLE Calib Grism table .\n"
84 " In case MOS_STANDARD is specified in input,\n"
86 " EXTINCT_TABLE Calib Atmospheric extinction Y\n"
87 " STD_FLUX_TABLE Calib Standard star flux Y\n"
90 " DO category: Data type: Explanation:\n"
91 " MOS_SCIENCE_REDUCED FITS image Extracted scientific spectra\n"
92 " or MOS_STANDARD_REDUCED FITS image Extracted standard star spectrum\n"
93 " MOS_SKY_REDUCED FITS image Extracted sky spectra\n"
94 " MOS_ERROR_REDUCED FITS image Errors on extracted spectra\n"
96 " MOS_UNMAPPED_SCIENCE FITS image Sky subtracted scientific spectra\n"
97 " or MOS_UNMAPPED_STANDARD FITS image Sky subtracted standard spectrum\n"
99 " MOS_SCIENCE_EXTRACTED FITS image Rectified scientific spectra\n"
100 " or MOS_STANDARD_EXTRACTED FITS image Rectified standard star spectrum\n"
102 " MOS_SCIENCE_SKY_EXTRACTED FITS image Rectified science spectra with sky\n"
103 "or MOS_STANDARD_SKY_EXTRACTED FITS image Rectified std spectrum with sky\n"
105 " MOS_SCIENCE_SKY FITS image Rectified sky spectra\n"
106 " MOS_UNMAPPED_SKY FITS image Sky on CCD\n"
107 " MOS_GLOBAL_SKY_SPECTRUM FITS table Global sky spectrum\n"
108 " OBJECT_TABLE FITS table Positions of detected objects\n"
110 " Only if the sky-alignment of the wavelength solution is requested:\n"
111 " MOS_SKYLINES_OFFSETS_LONG FITS table Sky lines offsets (LSS-like data)\n"
112 "or MOS_SKYLINES_OFFSETS_SLIT FITS table Sky lines offsets (MOS-like data)\n"
113 " MOS_DISP_COEFF_SKY FITS table Upgraded dispersion coefficients\n"
114 " MOS_WAVELENGTH_MAP_SKY FITS image Upgraded wavelength map\n"
116 " Only if a MOS_STANDARD is specified in input:\n"
117 " MOS_SPECPHOT_TABLE FITS table Efficiency and response curves\n\n";
132 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe );
133 cpl_plugin *plugin = &recipe->interface;
135 cpl_plugin_init(plugin,
138 CPL_PLUGIN_TYPE_RECIPE,
140 "Extraction of scientific spectra",
141 vimos_science_description,
144 "This file is currently part of the FORS Instrument Pipeline\n"
145 "Copyright (C) 2002-2010 European Southern Observatory\n\n"
146 "This program is free software; you can redistribute it and/or modify\n"
147 "it under the terms of the GNU General Public License as published by\n"
148 "the Free Software Foundation; either version 2 of the License, or\n"
149 "(at your option) any later version.\n\n"
150 "This program is distributed in the hope that it will be useful,\n"
151 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
152 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
153 "GNU General Public License for more details.\n\n"
154 "You should have received a copy of the GNU General Public License\n"
155 "along with this program; if not, write to the Free Software Foundation,\n"
156 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n",
157 vimos_science_create,
159 vimos_science_destroy);
161 cpl_pluginlist_append(list, plugin);
177 static int vimos_science_create(cpl_plugin *plugin)
187 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
188 recipe = (cpl_recipe *)plugin;
196 recipe->parameters = cpl_parameterlist_new();
203 p = cpl_parameter_new_value(
"fors.vimos_science.dispersion",
205 "Resampling step (Angstrom/pixel)",
206 "fors.vimos_science",
208 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dispersion");
209 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
210 cpl_parameterlist_append(recipe->parameters, p);
216 p = cpl_parameter_new_value(
"fors.vimos_science.skyalign",
218 "Polynomial order for sky lines alignment, "
219 "or -1 to avoid alignment",
220 "fors.vimos_science",
222 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skyalign");
223 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
224 cpl_parameterlist_append(recipe->parameters, p);
230 p = cpl_parameter_new_value(
"fors.vimos_science.wcolumn",
232 "Name of sky line catalog table column "
234 "fors.vimos_science",
236 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wcolumn");
237 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
238 cpl_parameterlist_append(recipe->parameters, p);
244 p = cpl_parameter_new_value(
"fors.vimos_science.startwavelength",
246 "Start wavelength in spectral extraction",
247 "fors.vimos_science",
249 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"startwavelength");
250 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
251 cpl_parameterlist_append(recipe->parameters, p);
257 p = cpl_parameter_new_value(
"fors.vimos_science.endwavelength",
259 "End wavelength in spectral extraction",
260 "fors.vimos_science",
262 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"endwavelength");
263 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
264 cpl_parameterlist_append(recipe->parameters, p);
270 p = cpl_parameter_new_value(
"fors.vimos_science.reference",
272 "Reference wavelength for calibration",
273 "fors.vimos_science",
275 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"reference");
276 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
277 cpl_parameterlist_append(recipe->parameters, p);
283 p = cpl_parameter_new_value(
"fors.vimos_science.flux",
285 "Apply flux conservation",
286 "fors.vimos_science",
288 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"flux");
289 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
290 cpl_parameterlist_append(recipe->parameters, p);
296 p = cpl_parameter_new_value(
"fors.vimos_science.flatfield",
299 "fors.vimos_science",
301 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"flatfield");
302 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
303 cpl_parameterlist_append(recipe->parameters, p);
309 p = cpl_parameter_new_value(
"fors.vimos_science.skyglobal",
311 "Subtract global sky spectrum from CCD",
312 "fors.vimos_science",
314 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skyglobal");
315 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
316 cpl_parameterlist_append(recipe->parameters, p);
322 p = cpl_parameter_new_value(
"fors.vimos_science.skymedian",
324 "Sky subtraction from extracted slit spectra",
325 "fors.vimos_science",
327 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skymedian");
328 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
329 cpl_parameterlist_append(recipe->parameters, p);
335 p = cpl_parameter_new_value(
"fors.vimos_science.skylocal",
337 "Sky subtraction from CCD slit spectra",
338 "fors.vimos_science",
340 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skylocal");
341 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
342 cpl_parameterlist_append(recipe->parameters, p);
348 p = cpl_parameter_new_value(
"fors.vimos_science.cosmics",
350 "Eliminate cosmic rays hits (only if global "
351 "or local sky subtraction is also requested)",
352 "fors.vimos_science",
354 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"cosmics");
355 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
356 cpl_parameterlist_append(recipe->parameters, p);
362 p = cpl_parameter_new_value(
"fors.vimos_science.slit_margin",
364 "Number of pixels to exclude at each slit "
365 "in object detection and extraction",
366 "fors.vimos_science",
368 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"slit_margin");
369 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
370 cpl_parameterlist_append(recipe->parameters, p);
376 p = cpl_parameter_new_value(
"fors.vimos_science.ext_radius",
378 "Maximum extraction radius for detected "
380 "fors.vimos_science",
382 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ext_radius");
383 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
384 cpl_parameterlist_append(recipe->parameters, p);
390 p = cpl_parameter_new_value(
"fors.vimos_science.cont_radius",
392 "Minimum distance at which two objects "
393 "of equal luminosity do not contaminate "
394 "each other (pixel)",
395 "fors.vimos_science",
397 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"cont_radius");
398 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
399 cpl_parameterlist_append(recipe->parameters, p);
405 p = cpl_parameter_new_value(
"fors.vimos_science.ext_mode",
407 "Object extraction method: 0 = aperture, "
408 "1 = Horne optimal extraction",
409 "fors.vimos_science",
411 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ext_mode");
412 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
413 cpl_parameterlist_append(recipe->parameters, p);
419 p = cpl_parameter_new_value(
"fors.vimos_science.time_normalise",
421 "Normalise output spectra by the exposure time",
422 "fors.vimos_science",
424 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"time_normalise");
425 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
426 cpl_parameterlist_append(recipe->parameters, p);
432 p = cpl_parameter_new_value(
"fors.vimos_science.anyframe",
434 "Look for a standard star in any frame "
435 "classified as MOS_STANDARD",
436 "fors.vimos_science",
438 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"anyframe");
439 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
440 cpl_parameterlist_append(recipe->parameters, p);
447 p = cpl_parameter_new_value(
"fors.vimos_science.response",
449 "Order of polynomial modeling the "
450 "instrument response",
451 "fors.vimos_science",
453 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"response");
454 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
455 cpl_parameterlist_append(recipe->parameters, p);
462 p = cpl_parameter_new_enum(
"fors.vimos_science.alignment",
464 "Type of alignment of dithered frames, "
465 "either to the nearest neighbour pixel "
466 "or to fractions of pixel",
467 "fors.vimos_science",
470 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"alignment");
471 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
472 cpl_parameterlist_append(recipe->parameters, p);
480 "fors.vimos_science",
"average");
487 p = cpl_parameter_new_value(
"fors.vimos_science.fringing",
489 "Apply fringing correction "
490 "(only for dithered observations)",
491 "fors.vimos_science",
493 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"fringing");
494 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
495 cpl_parameterlist_append(recipe->parameters, p);
502 p = cpl_parameter_new_value(
"fors.vimos_science.qc",
504 "Compute QC1 parameters",
505 "fors.vimos_science",
507 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"qc");
508 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
509 cpl_parameterlist_append(recipe->parameters, p);
524 static int vimos_science_exec(cpl_plugin *plugin)
528 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
529 recipe = (cpl_recipe *)plugin;
533 return vimos_science(recipe->parameters, recipe->frames);
545 static int vimos_science_destroy(cpl_plugin *plugin)
549 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
550 recipe = (cpl_recipe *)plugin;
554 cpl_parameterlist_delete(recipe->parameters);
569 static int vimos_science(cpl_parameterlist *parlist, cpl_frameset *frameset)
571 const char *science_tag =
"MOS_SCIENCE";
572 int mos = cpl_frameset_count_tags(frameset, science_tag);
576 const char *curv_coeff_tag =
"MOS_CURV_COEFF";
577 const char *slit_location_tag =
"MOS_SLIT_LOCATION";
578 const char *disp_coeff_tag =
"MOS_DISP_COEFF";
579 const char *unmapped_science_tag =
"MOS_UNMAPPED_SCIENCE";
580 const char *mapped_science_tag =
"MOS_SCIENCE_EXTRACTED";
581 const char *object_table_tag =
"OBJECT_TABLE";
582 const char *unmapped_sky_tag =
"MOS_UNMAPPED_SKY";
583 const char *mapped_sky_tag =
"MOS_SCIENCE_SKY";
584 const char *reduced_science_tag =
"MOS_SCIENCE_REDUCED";
585 const char *reduced_sky_tag =
"MOS_SKY_REDUCED";
586 const char *reduced_error_tag =
"MOS_ERROR_REDUCED";
587 const char *stack_method;
588 const char *alignment;
590 double startwavelength;
591 double endwavelength;
601 int rotate_back = -1;
602 cpl_frameset *work = cpl_frameset_duplicate(frameset);
603 cpl_frame **mos_science = cpl_calloc(mos,
sizeof(cpl_frame*));
604 cpl_parameter *param;
605 cpl_table *reference = NULL;
606 cpl_table *objects = NULL;
607 cpl_image **images = NULL;
608 cpl_image *image = NULL;
609 cpl_image *sky_image = NULL;
610 cpl_imagelist *imagelist = NULL;
611 cpl_image *fringes = NULL;
612 cpl_image *stacked = NULL;
613 cpl_image *mapped = NULL;
614 cpl_image *smapped = NULL;
615 cpl_image *sky_stacked = NULL;
616 cpl_image *sky_mapped = NULL;
617 cpl_image *sky_smapped = NULL;
618 cpl_table *polytraces = NULL;
619 cpl_table *idscoeff = NULL;
620 cpl_table *slits = NULL;
621 cpl_table *grism_table = NULL;
622 cpl_propertylist *header = NULL;
633 int int_alignment = 0;
639 snprintf(version, 80,
"%s-%s", PACKAGE, PACKAGE_VERSION);
646 "fors.vimos_science.cosmics", NULL);
649 "fors.vimos_science.dispersion", grism_table);
652 "fors.vimos_science.reference", grism_table);
655 "fors.vimos_science.startwavelength", grism_table);
658 "fors.vimos_science.endwavelength", grism_table);
661 "fors.vimos_science.alignment", NULL);
663 if (strcmp(alignment,
"integer") == 0) {
668 "fors.vimos_science.stack_method", NULL);
670 if (strcmp(stack_method,
"minmax") == 0) {
672 "fors.vimos_science.minrejection", NULL);
673 if (min_reject < 0) {
674 cpl_msg_error(
"vimos_science",
675 "Invalid number of lower rejections");
680 "fors.vimos_science.maxrejection", NULL);
682 if (max_reject < 0) {
683 cpl_msg_error(
"vimos_science",
684 "Invalid number of upper rejections");
689 if (strcmp(stack_method,
"ksigma") == 0) {
691 "fors.vimos_science.klow", NULL);
693 cpl_msg_error(
"vimos_science",
694 "Invalid lower K-sigma");
699 "fors.vimos_science.khigh", NULL);
701 cpl_msg_error(
"vimos_science",
702 "Invalid lower K-sigma");
707 "fors.vimos_science.kiter", NULL);
709 cpl_msg_error(
"vimos_science",
710 "Invalid number of iterations");
716 "fors.vimos_science.slit_margin",
719 "fors.vimos_science.ext_radius",
722 "fors.vimos_science.cont_radius",
725 "fors.vimos_science.ext_mode",
729 "fors.vimos_science.fringing", NULL);
731 cpl_table_delete(grism_table); grism_table = NULL;
738 param = cpl_parameterlist_find(parlist,
739 "fors.vimos_science.time_normalise");
740 time_normal = cpl_parameter_get_bool(param);
741 cpl_parameter_set_bool(param, 0);
748 mos_science[0] = cpl_frameset_find(frameset, science_tag);
749 for (i = 1; i < mos; i++) {
750 mos_science[i] = cpl_frameset_find(frameset, NULL);
758 for (i = 0; i < mos; i++) {
759 cpl_frameset_erase(work, science_tag);
760 cpl_frameset_insert(work, cpl_frame_duplicate(mos_science[i]));
761 vimos_science_impl(work, parlist);
769 cpl_frameset_erase(work,
"MOS_SKYLINES_OFFSETS_SLIT");
770 cpl_frameset_erase(work,
"MOS_SCIENCE_SKY_EXTRACTED");
771 cpl_frameset_erase(work,
"MOS_UNMAPPED_SKY");
772 cpl_frameset_erase(work,
"MOS_UNMAPPED_SCIENCE");
773 cpl_frameset_erase(work,
"MOS_WAVELENGTH_MAP_SKY");
774 cpl_frameset_erase(work,
"MOS_SCIENCE_SKY");
775 cpl_frameset_erase(work,
"OBJECT_TABLE");
776 cpl_frameset_erase(work,
"MOS_SCIENCE_REDUCED");
777 cpl_frameset_erase(work,
"MOS_SKY_REDUCED");
778 cpl_frameset_erase(work,
"MOS_ERROR_REDUCED");
779 cpl_frameset_erase(work,
"MOS_DISP_COEFF_SKY");
780 cpl_frameset_erase(work,
"MOS_SCIENCE_EXTRACTED");
788 name = cpl_sprintf(
"object_table_%d.fits", i);
789 status = rename(
"object_table.fits", name);
791 name = cpl_sprintf(
"mos_unmapped_sky_%d.fits", i);
792 status |= rename(
"mos_unmapped_sky.fits", name);
794 name = cpl_sprintf(
"mos_unmapped_science_%d.fits", i);
795 status |= rename(
"mos_unmapped_science.fits", name);
799 cpl_msg_error(
"vimos_science",
"Cannot rename product.");
800 cpl_free(mos_science);
801 cpl_frameset_delete(work);
806 cpl_free(mos_science);
807 cpl_frameset_delete(work);
815 imagelist = cpl_imagelist_new();
817 for (i = 0; i < mos; i++) {
818 name = cpl_sprintf(
"mos_unmapped_science_%d.fits", i);
819 image = cpl_image_load(name, CPL_TYPE_FLOAT, 0, 0);
820 cpl_imagelist_set(imagelist, image,
821 cpl_imagelist_get_size(imagelist));
824 fringes = cpl_imagelist_collapse_median_create(imagelist);
825 cpl_imagelist_delete(imagelist);
826 cpl_image_save(fringes,
"fringes.fits",
827 CPL_BPP_IEEE_FLOAT, NULL, CPL_IO_DEFAULT);
836 reference = cpl_table_load(
"object_table_0.fits", 1, 1);
837 stacked = cpl_image_load(
"mos_unmapped_science_0.fits",
838 CPL_TYPE_FLOAT, 0, 0);
839 sky_stacked = cpl_image_load(
"mos_unmapped_sky_0.fits",
840 CPL_TYPE_FLOAT, 0, 0);
842 cpl_image_subtract(stacked, fringes);
843 cpl_image_add(sky_stacked, fringes);
847 cpl_image_save(stacked,
"mos_unmapped_science_0.fits",
848 CPL_BPP_IEEE_FLOAT, NULL, CPL_IO_DEFAULT);
851 for (i = 1; i < mos; i++) {
852 name = cpl_sprintf(
"object_table_%d.fits", i);
853 objects = cpl_table_load(name, 1, 1);
856 cpl_msg_error(
"vimos_science",
"Cannot compute offset.");
857 cpl_table_delete(objects);
860 cpl_table_delete(objects);
861 name = cpl_sprintf(
"mos_unmapped_science_%d.fits", i);
862 image = cpl_image_load(name, CPL_TYPE_FLOAT, 0, 0);
865 cpl_image_subtract(image, fringes);
868 cpl_msg_info(
"vimos_science",
869 "Frame %d offset relative "
870 "to frame 1: %.2f pix\n", i + 1, offset);
873 offset = floor(offset + 0.5);
874 cpl_msg_info(
"vimos_science",
875 "Nearest neighbour offset applied is "
876 "%.0f pix\n", offset);
880 cpl_image_save(image, name, CPL_BPP_IEEE_FLOAT,
881 NULL, CPL_IO_DEFAULT);
888 name = cpl_sprintf(
"mos_unmapped_sky_%d.fits", i);
889 sky_image = cpl_image_load(name, CPL_TYPE_FLOAT, 0, 0);
892 cpl_image_add(sky_image, fringes);
897 cpl_image_add(sky_stacked, sky_image);
898 cpl_image_delete(sky_image);
900 if (strcmp(stack_method,
"average") == 0) {
901 cpl_image_add(stacked, image);
902 cpl_image_delete(image);
906 imagelist = cpl_imagelist_new();
907 cpl_imagelist_set(imagelist, stacked,
908 cpl_imagelist_get_size(imagelist));
910 cpl_imagelist_set(imagelist, image,
911 cpl_imagelist_get_size(imagelist));
914 cpl_table_delete(reference);
916 cpl_image_divide_scalar(sky_stacked, mos);
919 cpl_image_delete(fringes);
922 if (strcmp(stack_method,
"average") == 0) {
923 cpl_image_divide_scalar(stacked, mos);
926 if (strcmp(stack_method,
"median") == 0) {
927 stacked = cpl_imagelist_collapse_median_create(imagelist);
928 cpl_imagelist_delete(imagelist);
931 if (strcmp(stack_method,
"minmax") == 0) {
932 stacked = cpl_imagelist_collapse_minmax_create(imagelist,
935 cpl_imagelist_delete(imagelist);
938 if (strcmp(stack_method,
"ksigma") == 0) {
940 cpl_imagelist_delete(imagelist);
945 gain = cpl_propertylist_get_double(header,
"ESO DET OUT1 CONAD");
946 ron = cpl_propertylist_get_double(header,
"ESO DET OUT1 RON");
950 header, parlist,
"vimos_science", version)) {
951 cpl_image_delete(stacked);
952 cpl_image_delete(sky_stacked);
953 cpl_propertylist_delete(header);
954 cpl_table_delete(slits);
959 header, parlist,
"vimos_science", version)) {
960 cpl_image_delete(stacked);
961 cpl_image_delete(sky_stacked);
962 cpl_propertylist_delete(header);
963 cpl_table_delete(slits);
967 cpl_parameter_set_bool(param, time_normal);
969 cpl_image_turn(stacked, rotate);
970 cpl_image_turn(sky_stacked, rotate);
972 nx = cpl_image_get_size_x(stacked);
973 ny = cpl_image_get_size_y(stacked);
983 cpl_msg_indent_less();
984 cpl_msg_info(
"vimos_science",
985 "Processing stacked scientific spectra...");
986 cpl_msg_indent_more();
989 startwavelength, endwavelength,
990 dispersion, flux, NULL);
992 cpl_image_delete(stacked);
995 refwave, startwavelength,
996 endwavelength, dispersion,
999 cpl_image_delete(sky_stacked);
1000 cpl_table_delete(polytraces);
1003 startwavelength, endwavelength,
1004 dispersion, idscoeff, flux);
1006 cpl_image_delete(smapped);
1009 startwavelength, endwavelength,
1010 dispersion, idscoeff, flux);
1011 cpl_table_delete(idscoeff);
1013 cpl_propertylist_update_double(header,
"CRPIX1", 1.0);
1014 cpl_propertylist_update_double(header,
"CRPIX2", 1.0);
1015 cpl_propertylist_update_double(header,
"CRVAL1",
1016 startwavelength + dispersion/2);
1017 cpl_propertylist_update_double(header,
"CRVAL2", 1.0);
1018 cpl_propertylist_update_double(header,
"CD1_1", dispersion);
1019 cpl_propertylist_update_double(header,
"CD1_2", 0.0);
1020 cpl_propertylist_update_double(header,
"CD2_1", 0.0);
1021 cpl_propertylist_update_double(header,
"CD2_2", 1.0);
1022 cpl_propertylist_update_string(header,
"CTYPE1",
"LINEAR");
1023 cpl_propertylist_update_string(header,
"CTYPE2",
"PIXEL");
1036 header, parlist,
"vimos_science", version)) {
1037 cpl_propertylist_delete(header);
1038 cpl_image_delete(mapped);
1039 cpl_image_delete(sky_mapped);
1040 cpl_table_delete(slits);
1045 header, parlist,
"vimos_science", version)) {
1046 cpl_propertylist_delete(header);
1047 cpl_image_delete(mapped);
1048 cpl_image_delete(sky_mapped);
1049 cpl_table_delete(slits);
1054 cpl_msg_indent_less();
1055 cpl_msg_info(
"vimos_science",
"Final object detection...");
1056 cpl_msg_indent_more();
1058 if (cosmics || strcmp(stack_method,
"average")) {
1063 cpl_image *mapped_cleaned = cpl_image_duplicate(mapped);
1066 ext_radius, cont_radius);
1068 cpl_image_delete(mapped_cleaned);
1071 cpl_image_delete(image);
1074 if (
dfs_save_table(frameset, slits, object_table_tag, NULL, parlist,
1075 "vimos_science", version)) {
1076 cpl_propertylist_delete(header);
1077 cpl_image_delete(mapped);
1078 cpl_image_delete(sky_mapped);
1079 cpl_table_delete(slits);
1083 cpl_msg_indent_less();
1084 cpl_msg_info(
"vimos_science",
"Final object extraction...");
1085 cpl_msg_indent_more();
1088 ext_mode, ron, gain, mos);
1090 cpl_image_delete(mapped);
1091 cpl_image_delete(sky_mapped);
1092 cpl_table_delete(slits);
1099 header, parlist,
"vimos_science", version)) {
1100 cpl_image_delete(images[0]);
1101 cpl_image_delete(images[1]);
1102 cpl_image_delete(images[2]);
1104 cpl_propertylist_delete(header);
1108 cpl_image_delete(images[0]);
1114 parlist,
"vimos_science", version)) {
1115 cpl_image_delete(images[1]);
1116 cpl_image_delete(images[2]);
1118 cpl_propertylist_delete(header);
1122 cpl_image_delete(images[1]);
1127 if (
dfs_save_image(frameset, images[2], reduced_error_tag, header,
1128 parlist,
"vimos_science", version)) {
1129 cpl_image_delete(images[2]);
1131 cpl_propertylist_delete(header);
1135 cpl_image_delete(images[2]);
1140 cpl_msg_warning(
"vimos_science",
"No objects found: the products "
1141 "%s, %s, and %s are not created",
1142 reduced_science_tag, reduced_sky_tag,
1146 cpl_propertylist_delete(header);
1151 return vimos_science_impl(frameset, parlist);
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.
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
const char * dfs_get_parameter_string(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe string parameter value.
cpl_propertylist * dfs_load_header(cpl_frameset *frameset, const char *category, int ext)
Loading header associated to data of given category.
cpl_error_code mos_rotate_slits(cpl_table *slits, int rotation, int nx, int ny)
Rotate a slit location table.
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_image * mos_detect_objects(cpl_image *image, cpl_table *slits, int margin, int maxradius, int conradius)
Detect objects in rectified scientific frame.
int dfs_get_parameter_bool(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe boolean parameter value.
cpl_error_code mos_image_shift(cpl_image *image, double dx, double dy)
Shift values in an image.
void fors_stack_define_parameters(cpl_parameterlist *parameters, const char *context, const char *default_method)
Define recipe parameters.
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_image * mos_ksigma_stack(cpl_imagelist *imlist, double klow, double khigh, int kiter, cpl_image **good)
Stack images using k-sigma clipping.
cpl_image ** mos_extract_objects(cpl_image *science, cpl_image *science_var, cpl_image *sky, cpl_table *objects, int extraction, double ron, double gain, int ncombined)
Extract detected objects from rectified scientific frame.
cpl_error_code mos_clean_cosmics(cpl_image *image, float gain, float threshold, float ratio)
Remove cosmic rays from sky-subtracted CCD spectral exposure.
double dfs_get_parameter_double(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe double parameter value.
int mos_compute_offset(cpl_table *reference, cpl_table *objects, double *offset)
Estimate offset between two object tables.