35 #include "muse_scibasic_z.h"
72 static const char *muse_scibasic_help =
73 "Processing handles each raw input image separately: it trims the raw data and records the overscan statistics, subtracts the bias (taking account of the overscan, if --overscan is not &none&), optionally detects cosmic rays (note that by default cosmic ray rejection is handled in the post processing recipes while the data is reformatted into a datacube, so that the default setting is cr=&none& here), converts the images from adu to count, subtracts the dark, divides by the flat-field, and (optionally) propagates the integrated flux value from the sky-flat. The input calibrations geometry table, trace table, and wavelength calibration table are used to assign 3D coordinates to each CCD-based pixel, thereby creating a pixel table for each exposure. If --skylines contains one or more wavelengths for (bright and isolated) sky emission lines, these lines are used to correct the wavelength calibration using an offset. Both the reduced image and the pixel table are saved. For special cases, users can choose to combine all input files at the image level, so that the pixel table is only created once, for the combined data. This is not recommended for science data, where the combination should take place after correcting for atmospheric effects, before the creation of the final cube.";
75 static const char *muse_scibasic_help_esorex =
76 "\n\nInput frames for raw frame tag \"OBJECT\":\n"
77 "\n Frame tag Type Req #Fr Description"
78 "\n -------------------- ---- --- --- ------------"
79 "\n OBJECT raw Y Raw exposure of a science target"
80 "\n MASTER_BIAS calib Y 1 Master bias"
81 "\n MASTER_DARK calib . 1 Master dark"
82 "\n MASTER_FLAT calib Y 1 Master flat"
83 "\n TRACE_TABLE calib Y 1 Tracing table for all slices"
84 "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
85 "\n GEOMETRY_TABLE calib Y 1 Relative positions of the slices in the field of view"
86 "\n MASTER_SKYFLAT calib . 1 Master twilight skyflat"
87 "\n BADPIX_TABLE calib . 1 Known bad pixels"
88 "\n\nProduct frames for raw frame tag \"OBJECT\":\n"
89 "\n Frame tag Level Description"
90 "\n -------------------- -------- ------------"
91 "\n OBJECT_RED intermed Pre-processed CCD-based images (if --saveimage=true)"
92 "\n OBJECT_RESAMPLED intermed Resampled 2D image (if --resample=true)"
93 "\n PIXTABLE_OBJECT intermed Output pixel table" "\n\nInput frames for raw frame tag \"STD\":\n"
94 "\n Frame tag Type Req #Fr Description"
95 "\n -------------------- ---- --- --- ------------"
96 "\n STD raw Y Raw exposure of a standard star field"
97 "\n MASTER_BIAS calib Y 1 Master bias"
98 "\n MASTER_DARK calib . 1 Master dark"
99 "\n MASTER_FLAT calib Y 1 Master flat"
100 "\n TRACE_TABLE calib Y 1 Tracing table for all slices"
101 "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
102 "\n GEOMETRY_TABLE calib Y 1 Relative positions of the slices in the field of view"
103 "\n MASTER_SKYFLAT calib . 1 Master twilight skyflat"
104 "\n BADPIX_TABLE calib . 1 Known bad pixels"
105 "\n\nProduct frames for raw frame tag \"STD\":\n"
106 "\n Frame tag Level Description"
107 "\n -------------------- -------- ------------"
108 "\n STD_RED intermed Pre-processed CCD-based images (if --saveimage=true)"
109 "\n STD_RESAMPLED intermed Resampled 2D image (if --resample=true)"
110 "\n PIXTABLE_STD intermed Output pixel table" "\n\nInput frames for raw frame tag \"SKY\":\n"
111 "\n Frame tag Type Req #Fr Description"
112 "\n -------------------- ---- --- --- ------------"
113 "\n SKY raw Y Raw exposure of an (almost) empty sky field"
114 "\n MASTER_BIAS calib Y 1 Master bias"
115 "\n MASTER_DARK calib . 1 Master dark"
116 "\n MASTER_FLAT calib Y 1 Master flat"
117 "\n TRACE_TABLE calib Y 1 Tracing table for all slices"
118 "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
119 "\n GEOMETRY_TABLE calib Y 1 Relative positions of the slices in the field of view"
120 "\n MASTER_SKYFLAT calib . 1 Master twilight skyflat"
121 "\n BADPIX_TABLE calib . 1 Known bad pixels"
122 "\n\nProduct frames for raw frame tag \"SKY\":\n"
123 "\n Frame tag Level Description"
124 "\n -------------------- -------- ------------"
125 "\n SKY_RED intermed Pre-processed CCD-based images (if --saveimage=true)"
126 "\n SKY_RESAMPLED intermed Resampled 2D image (if --resample=true)"
127 "\n PIXTABLE_SKY intermed Output pixel table" "\n\nInput frames for raw frame tag \"ASTROMETRY\":\n"
128 "\n Frame tag Type Req #Fr Description"
129 "\n -------------------- ---- --- --- ------------"
130 "\n ASTROMETRY raw Y Raw exposure of an astrometric field"
131 "\n MASTER_BIAS calib Y 1 Master bias"
132 "\n MASTER_DARK calib . 1 Master dark"
133 "\n MASTER_FLAT calib Y 1 Master flat"
134 "\n TRACE_TABLE calib Y 1 Tracing table for all slices"
135 "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
136 "\n GEOMETRY_TABLE calib Y 1 Relative positions of the slices in the field of view"
137 "\n MASTER_SKYFLAT calib . 1 Master twilight skyflat"
138 "\n BADPIX_TABLE calib . 1 Known bad pixels"
139 "\n\nProduct frames for raw frame tag \"ASTROMETRY\":\n"
140 "\n Frame tag Level Description"
141 "\n -------------------- -------- ------------"
142 "\n ASTROMETRY_RED intermed Pre-processed CCD-based images (if --saveimage=true)"
143 "\n ASTROMETRY_RESAMPLED intermed Resampled 2D image (if --resample=true)"
144 "\n PIXTABLE_ASTROMETRY intermed Output pixel table" "\n\nInput frames for raw frame tag \"REDUCED\":\n"
145 "\n Frame tag Type Req #Fr Description"
146 "\n -------------------- ---- --- --- ------------"
147 "\n REDUCED raw Y Reduced CCD image"
148 "\n TRACE_TABLE calib Y 1 Tracing table for all slices"
149 "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
150 "\n GEOMETRY_TABLE calib Y 1 Relative positions of the slices in the field of view"
151 "\n\nProduct frames for raw frame tag \"REDUCED\":\n"
152 "\n Frame tag Level Description"
153 "\n -------------------- -------- ------------"
154 "\n REDUCED_RESAMPLED intermed Resampled 2D image (if --resample=true)"
155 "\n PIXTABLE_REDUCED intermed Output pixel table";
166 static cpl_recipeconfig *
167 muse_scibasic_new_recipeconfig(
void)
169 cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
173 cpl_recipeconfig_set_tag(recipeconfig, tag, 1, -1);
174 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_BIAS", 1, 1);
175 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_DARK", -1, 1);
176 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_FLAT", 1, 1);
177 cpl_recipeconfig_set_input(recipeconfig, tag,
"TRACE_TABLE", 1, 1);
178 cpl_recipeconfig_set_input(recipeconfig, tag,
"WAVECAL_TABLE", 1, 1);
179 cpl_recipeconfig_set_input(recipeconfig, tag,
"GEOMETRY_TABLE", 1, 1);
180 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_SKYFLAT", -1, 1);
181 cpl_recipeconfig_set_input(recipeconfig, tag,
"BADPIX_TABLE", -1, 1);
182 cpl_recipeconfig_set_output(recipeconfig, tag,
"OBJECT_RED");
183 cpl_recipeconfig_set_output(recipeconfig, tag,
"OBJECT_RESAMPLED");
184 cpl_recipeconfig_set_output(recipeconfig, tag,
"PIXTABLE_OBJECT");
187 cpl_recipeconfig_set_tag(recipeconfig, tag, 1, -1);
188 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_BIAS", 1, 1);
189 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_DARK", -1, 1);
190 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_FLAT", 1, 1);
191 cpl_recipeconfig_set_input(recipeconfig, tag,
"TRACE_TABLE", 1, 1);
192 cpl_recipeconfig_set_input(recipeconfig, tag,
"WAVECAL_TABLE", 1, 1);
193 cpl_recipeconfig_set_input(recipeconfig, tag,
"GEOMETRY_TABLE", 1, 1);
194 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_SKYFLAT", -1, 1);
195 cpl_recipeconfig_set_input(recipeconfig, tag,
"BADPIX_TABLE", -1, 1);
196 cpl_recipeconfig_set_output(recipeconfig, tag,
"STD_RED");
197 cpl_recipeconfig_set_output(recipeconfig, tag,
"STD_RESAMPLED");
198 cpl_recipeconfig_set_output(recipeconfig, tag,
"PIXTABLE_STD");
201 cpl_recipeconfig_set_tag(recipeconfig, tag, 1, -1);
202 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_BIAS", 1, 1);
203 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_DARK", -1, 1);
204 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_FLAT", 1, 1);
205 cpl_recipeconfig_set_input(recipeconfig, tag,
"TRACE_TABLE", 1, 1);
206 cpl_recipeconfig_set_input(recipeconfig, tag,
"WAVECAL_TABLE", 1, 1);
207 cpl_recipeconfig_set_input(recipeconfig, tag,
"GEOMETRY_TABLE", 1, 1);
208 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_SKYFLAT", -1, 1);
209 cpl_recipeconfig_set_input(recipeconfig, tag,
"BADPIX_TABLE", -1, 1);
210 cpl_recipeconfig_set_output(recipeconfig, tag,
"SKY_RED");
211 cpl_recipeconfig_set_output(recipeconfig, tag,
"SKY_RESAMPLED");
212 cpl_recipeconfig_set_output(recipeconfig, tag,
"PIXTABLE_SKY");
215 cpl_recipeconfig_set_tag(recipeconfig, tag, 1, -1);
216 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_BIAS", 1, 1);
217 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_DARK", -1, 1);
218 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_FLAT", 1, 1);
219 cpl_recipeconfig_set_input(recipeconfig, tag,
"TRACE_TABLE", 1, 1);
220 cpl_recipeconfig_set_input(recipeconfig, tag,
"WAVECAL_TABLE", 1, 1);
221 cpl_recipeconfig_set_input(recipeconfig, tag,
"GEOMETRY_TABLE", 1, 1);
222 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_SKYFLAT", -1, 1);
223 cpl_recipeconfig_set_input(recipeconfig, tag,
"BADPIX_TABLE", -1, 1);
224 cpl_recipeconfig_set_output(recipeconfig, tag,
"ASTROMETRY_RED");
225 cpl_recipeconfig_set_output(recipeconfig, tag,
"ASTROMETRY_RESAMPLED");
226 cpl_recipeconfig_set_output(recipeconfig, tag,
"PIXTABLE_ASTROMETRY");
229 cpl_recipeconfig_set_tag(recipeconfig, tag, 1, -1);
230 cpl_recipeconfig_set_input(recipeconfig, tag,
"TRACE_TABLE", 1, 1);
231 cpl_recipeconfig_set_input(recipeconfig, tag,
"WAVECAL_TABLE", 1, 1);
232 cpl_recipeconfig_set_input(recipeconfig, tag,
"GEOMETRY_TABLE", 1, 1);
233 cpl_recipeconfig_set_output(recipeconfig, tag,
"REDUCED_RESAMPLED");
234 cpl_recipeconfig_set_output(recipeconfig, tag,
"PIXTABLE_REDUCED");
250 static cpl_error_code
251 muse_scibasic_prepare_header(
const char *aFrametag, cpl_propertylist *aHeader)
253 cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
254 cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
255 if (!strcmp(aFrametag,
"OBJECT_RED")) {
258 "Number of saturated pixels in output data");
259 }
else if (!strcmp(aFrametag,
"OBJECT_RESAMPLED")) {
260 }
else if (!strcmp(aFrametag,
"PIXTABLE_OBJECT")) {
263 "Number of saturated pixels in output data");
266 "[Angstrom] Shift in wavelength applied to the data using sky emission line(s)");
267 }
else if (!strcmp(aFrametag,
"STD_RED")) {
270 "Number of saturated pixels in output data");
271 }
else if (!strcmp(aFrametag,
"STD_RESAMPLED")) {
272 }
else if (!strcmp(aFrametag,
"PIXTABLE_STD")) {
275 "Number of saturated pixels in output data");
276 }
else if (!strcmp(aFrametag,
"SKY_RED")) {
279 "Number of saturated pixels in output data");
280 }
else if (!strcmp(aFrametag,
"SKY_RESAMPLED")) {
281 }
else if (!strcmp(aFrametag,
"PIXTABLE_SKY")) {
284 "Number of saturated pixels in output data");
285 }
else if (!strcmp(aFrametag,
"ASTROMETRY_RED")) {
288 "Number of saturated pixels in output data");
289 }
else if (!strcmp(aFrametag,
"ASTROMETRY_RESAMPLED")) {
290 }
else if (!strcmp(aFrametag,
"PIXTABLE_ASTROMETRY")) {
293 "Number of saturated pixels in output data");
294 }
else if (!strcmp(aFrametag,
"REDUCED_RESAMPLED")) {
295 }
else if (!strcmp(aFrametag,
"PIXTABLE_REDUCED")) {
297 cpl_msg_warning(__func__,
"Frame tag %s is not defined", aFrametag);
298 return CPL_ERROR_ILLEGAL_INPUT;
300 return CPL_ERROR_NONE;
313 static cpl_frame_level
314 muse_scibasic_get_frame_level(
const char *aFrametag)
317 return CPL_FRAME_LEVEL_NONE;
319 if (!strcmp(aFrametag,
"OBJECT_RED")) {
320 return CPL_FRAME_LEVEL_INTERMEDIATE;
322 if (!strcmp(aFrametag,
"OBJECT_RESAMPLED")) {
323 return CPL_FRAME_LEVEL_INTERMEDIATE;
325 if (!strcmp(aFrametag,
"PIXTABLE_OBJECT")) {
326 return CPL_FRAME_LEVEL_INTERMEDIATE;
328 if (!strcmp(aFrametag,
"STD_RED")) {
329 return CPL_FRAME_LEVEL_INTERMEDIATE;
331 if (!strcmp(aFrametag,
"STD_RESAMPLED")) {
332 return CPL_FRAME_LEVEL_INTERMEDIATE;
334 if (!strcmp(aFrametag,
"PIXTABLE_STD")) {
335 return CPL_FRAME_LEVEL_INTERMEDIATE;
337 if (!strcmp(aFrametag,
"SKY_RED")) {
338 return CPL_FRAME_LEVEL_INTERMEDIATE;
340 if (!strcmp(aFrametag,
"SKY_RESAMPLED")) {
341 return CPL_FRAME_LEVEL_INTERMEDIATE;
343 if (!strcmp(aFrametag,
"PIXTABLE_SKY")) {
344 return CPL_FRAME_LEVEL_INTERMEDIATE;
346 if (!strcmp(aFrametag,
"ASTROMETRY_RED")) {
347 return CPL_FRAME_LEVEL_INTERMEDIATE;
349 if (!strcmp(aFrametag,
"ASTROMETRY_RESAMPLED")) {
350 return CPL_FRAME_LEVEL_INTERMEDIATE;
352 if (!strcmp(aFrametag,
"PIXTABLE_ASTROMETRY")) {
353 return CPL_FRAME_LEVEL_INTERMEDIATE;
355 if (!strcmp(aFrametag,
"REDUCED_RESAMPLED")) {
356 return CPL_FRAME_LEVEL_INTERMEDIATE;
358 if (!strcmp(aFrametag,
"PIXTABLE_REDUCED")) {
359 return CPL_FRAME_LEVEL_INTERMEDIATE;
361 return CPL_FRAME_LEVEL_NONE;
375 muse_scibasic_get_frame_mode(
const char *aFrametag)
380 if (!strcmp(aFrametag,
"OBJECT_RED")) {
383 if (!strcmp(aFrametag,
"OBJECT_RESAMPLED")) {
386 if (!strcmp(aFrametag,
"PIXTABLE_OBJECT")) {
389 if (!strcmp(aFrametag,
"STD_RED")) {
392 if (!strcmp(aFrametag,
"STD_RESAMPLED")) {
395 if (!strcmp(aFrametag,
"PIXTABLE_STD")) {
398 if (!strcmp(aFrametag,
"SKY_RED")) {
401 if (!strcmp(aFrametag,
"SKY_RESAMPLED")) {
404 if (!strcmp(aFrametag,
"PIXTABLE_SKY")) {
407 if (!strcmp(aFrametag,
"ASTROMETRY_RED")) {
410 if (!strcmp(aFrametag,
"ASTROMETRY_RESAMPLED")) {
413 if (!strcmp(aFrametag,
"PIXTABLE_ASTROMETRY")) {
416 if (!strcmp(aFrametag,
"REDUCED_RESAMPLED")) {
419 if (!strcmp(aFrametag,
"PIXTABLE_REDUCED")) {
437 muse_scibasic_create(cpl_plugin *aPlugin)
441 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
442 recipe = (cpl_recipe *)aPlugin;
450 muse_scibasic_new_recipeconfig(),
451 muse_scibasic_prepare_header,
452 muse_scibasic_get_frame_level,
453 muse_scibasic_get_frame_mode);
458 cpl_msg_set_time_on();
462 recipe->parameters = cpl_parameterlist_new();
467 p = cpl_parameter_new_range(
"muse.muse_scibasic.nifu",
469 "IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in parallel.",
470 "muse.muse_scibasic",
474 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nifu");
475 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nifu");
477 cpl_parameterlist_append(recipe->parameters, p);
480 p = cpl_parameter_new_value(
"muse.muse_scibasic.overscan",
482 "If this is \"none\", stop when detecting discrepant overscan levels (see ovscsigma), for \"offset\" it assumes that the mean overscan level represents the real offset in the bias levels of the exposures involved, and adjusts the data accordingly; for \"vpoly\", a polynomial is fit to the vertical overscan and subtracted from the whole quadrant.",
483 "muse.muse_scibasic",
484 (
const char *)
"vpoly");
485 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"overscan");
486 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"overscan");
488 cpl_parameterlist_append(recipe->parameters, p);
491 p = cpl_parameter_new_value(
"muse.muse_scibasic.ovscreject",
493 "This influences how values are rejected when computing overscan statistics. Either no rejection at all (\"none\"), rejection using the DCR algorithm (\"dcr\"), or rejection using an iterative constant fit (\"fit\").",
494 "muse.muse_scibasic",
495 (
const char *)
"dcr");
496 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"ovscreject");
497 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ovscreject");
499 cpl_parameterlist_append(recipe->parameters, p);
502 p = cpl_parameter_new_value(
"muse.muse_scibasic.ovscsigma",
504 "If the deviation of mean overscan levels between a raw input image and the reference image is higher than |ovscsigma x stdev|, stop the processing. If overscan=\"vpoly\", this is used as sigma rejection level for the iterative polynomial fit. Has no effect for overscan=\"offset\".",
505 "muse.muse_scibasic",
507 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"ovscsigma");
508 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ovscsigma");
510 cpl_parameterlist_append(recipe->parameters, p);
513 p = cpl_parameter_new_value(
"muse.muse_scibasic.ovscignore",
515 "The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when computing statistics or fits.",
516 "muse.muse_scibasic",
518 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"ovscignore");
519 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ovscignore");
521 cpl_parameterlist_append(recipe->parameters, p);
524 p = cpl_parameter_new_value(
"muse.muse_scibasic.crop",
526 "Automatically crop the output pixel tables in wavelength depending on the expected useful wavelength range of the observation mode used (4750-9350 Angstrom for nominal mode, 4600-9350 Angstrom for extended mode).",
527 "muse.muse_scibasic",
529 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"crop");
530 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"crop");
532 cpl_parameterlist_append(recipe->parameters, p);
535 p = cpl_parameter_new_enum(
"muse.muse_scibasic.cr",
537 "Type of cosmic ray cleaning to use (for quick-look data processing).",
538 "muse.muse_scibasic",
539 (
const char *)
"none",
541 (
const char *)
"none",
542 (
const char *)
"dcr");
543 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"cr");
544 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"cr");
546 cpl_parameterlist_append(recipe->parameters, p);
549 p = cpl_parameter_new_value(
"muse.muse_scibasic.xbox",
551 "Search box size in x. Only used if cr=dcr.",
552 "muse.muse_scibasic",
554 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"xbox");
555 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"xbox");
557 cpl_parameterlist_append(recipe->parameters, p);
560 p = cpl_parameter_new_value(
"muse.muse_scibasic.ybox",
562 "Search box size in y. Only used if cr=dcr.",
563 "muse.muse_scibasic",
565 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"ybox");
566 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ybox");
568 cpl_parameterlist_append(recipe->parameters, p);
571 p = cpl_parameter_new_value(
"muse.muse_scibasic.passes",
573 "Maximum number of cleaning passes. Only used if cr=dcr.",
574 "muse.muse_scibasic",
576 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"passes");
577 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"passes");
579 cpl_parameterlist_append(recipe->parameters, p);
582 p = cpl_parameter_new_value(
"muse.muse_scibasic.thres",
584 "Threshold for detection gap in factors of standard deviation. Only used if cr=dcr.",
585 "muse.muse_scibasic",
587 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"thres");
588 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"thres");
590 cpl_parameterlist_append(recipe->parameters, p);
593 p = cpl_parameter_new_enum(
"muse.muse_scibasic.combine",
595 "Type of combination to use. Note that in most cases, science exposures cannot easily be combined on the CCD level, so this should usually be kept as \"none\"!",
596 "muse.muse_scibasic",
597 (
const char *)
"none",
599 (
const char *)
"none",
600 (
const char *)
"average",
601 (
const char *)
"median",
602 (
const char *)
"minmax",
603 (
const char *)
"sigclip");
604 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"combine");
605 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"combine");
607 cpl_parameterlist_append(recipe->parameters, p);
610 p = cpl_parameter_new_value(
"muse.muse_scibasic.nlow",
612 "Number of minimum pixels to reject with minmax",
613 "muse.muse_scibasic",
615 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nlow");
616 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nlow");
618 cpl_parameterlist_append(recipe->parameters, p);
621 p = cpl_parameter_new_value(
"muse.muse_scibasic.nhigh",
623 "Number of maximum pixels to reject with minmax",
624 "muse.muse_scibasic",
626 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nhigh");
627 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nhigh");
629 cpl_parameterlist_append(recipe->parameters, p);
632 p = cpl_parameter_new_value(
"muse.muse_scibasic.nkeep",
634 "Number of pixels to keep with minmax",
635 "muse.muse_scibasic",
637 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nkeep");
638 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nkeep");
640 cpl_parameterlist_append(recipe->parameters, p);
643 p = cpl_parameter_new_value(
"muse.muse_scibasic.lsigma",
645 "Low sigma for pixel rejection with sigclip",
646 "muse.muse_scibasic",
648 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"lsigma");
649 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lsigma");
651 cpl_parameterlist_append(recipe->parameters, p);
654 p = cpl_parameter_new_value(
"muse.muse_scibasic.hsigma",
656 "High sigma for pixel rejection with sigclip",
657 "muse.muse_scibasic",
659 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"hsigma");
660 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"hsigma");
662 cpl_parameterlist_append(recipe->parameters, p);
665 p = cpl_parameter_new_value(
"muse.muse_scibasic.scale",
667 "Scale the individual images to a common exposure time before combining them.",
668 "muse.muse_scibasic",
670 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"scale");
671 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"scale");
673 cpl_parameterlist_append(recipe->parameters, p);
676 p = cpl_parameter_new_value(
"muse.muse_scibasic.saveimage",
678 "Save the pre-processed CCD-based image of each input exposure before it is transformed into a pixel table.",
679 "muse.muse_scibasic",
681 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"saveimage");
682 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"saveimage");
684 cpl_parameterlist_append(recipe->parameters, p);
687 p = cpl_parameter_new_value(
"muse.muse_scibasic.skylines",
689 "List of wavelengths of sky emission lines (in Angstrom) to use as reference for wavelength offset correction using a Gaussian fit. It can contain multiple (isolated) lines, as comma-separated list, individual shifts are then combined into one weighted average offset.",
690 "muse.muse_scibasic",
691 (
const char *)
"5577.339,6300.304");
692 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"skylines");
693 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skylines");
695 cpl_parameterlist_append(recipe->parameters, p);
698 p = cpl_parameter_new_value(
"muse.muse_scibasic.skyhalfwidth",
700 "Half-width of the extraction box (in Angstrom) around each sky emission line.",
701 "muse.muse_scibasic",
703 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"skyhalfwidth");
704 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skyhalfwidth");
706 cpl_parameterlist_append(recipe->parameters, p);
709 p = cpl_parameter_new_value(
"muse.muse_scibasic.skybinsize",
711 "Size of the bins (in Angstrom per pixel) for the intermediate spectrum to do the Gaussian fit to each sky emission line.",
712 "muse.muse_scibasic",
714 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"skybinsize");
715 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skybinsize");
717 cpl_parameterlist_append(recipe->parameters, p);
720 p = cpl_parameter_new_value(
"muse.muse_scibasic.resample",
722 "Resample the input science data into 2D spectral images using tracing and wavelength calibration solutions for a visual check. Note that the image produced will show small wiggles even when the input calibrations are good and were applied successfully!",
723 "muse.muse_scibasic",
725 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"resample");
726 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"resample");
728 cpl_parameterlist_append(recipe->parameters, p);
731 p = cpl_parameter_new_value(
"muse.muse_scibasic.dlambda",
733 "Wavelength step (in Angstrom per pixel) to use for resampling.",
734 "muse.muse_scibasic",
736 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"dlambda");
737 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dlambda");
739 cpl_parameterlist_append(recipe->parameters, p);
759 cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
760 cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
763 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.nifu");
764 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
765 aParams->
nifu = cpl_parameter_get_int(p);
767 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.overscan");
768 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
769 aParams->
overscan = cpl_parameter_get_string(p);
771 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.ovscreject");
772 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
773 aParams->
ovscreject = cpl_parameter_get_string(p);
775 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.ovscsigma");
776 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
777 aParams->
ovscsigma = cpl_parameter_get_double(p);
779 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.ovscignore");
780 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
781 aParams->
ovscignore = cpl_parameter_get_int(p);
783 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.crop");
784 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
785 aParams->
crop = cpl_parameter_get_bool(p);
787 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.cr");
788 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
789 aParams->
cr_s = cpl_parameter_get_string(p);
791 (!strcasecmp(aParams->
cr_s,
"none")) ? MUSE_SCIBASIC_PARAM_CR_NONE :
792 (!strcasecmp(aParams->
cr_s,
"dcr")) ? MUSE_SCIBASIC_PARAM_CR_DCR :
793 MUSE_SCIBASIC_PARAM_CR_INVALID_VALUE;
794 cpl_ensure_code(aParams->
cr != MUSE_SCIBASIC_PARAM_CR_INVALID_VALUE,
795 CPL_ERROR_ILLEGAL_INPUT);
797 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.xbox");
798 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
799 aParams->
xbox = cpl_parameter_get_int(p);
801 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.ybox");
802 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
803 aParams->
ybox = cpl_parameter_get_int(p);
805 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.passes");
806 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
807 aParams->
passes = cpl_parameter_get_int(p);
809 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.thres");
810 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
811 aParams->
thres = cpl_parameter_get_double(p);
813 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.combine");
814 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
815 aParams->
combine_s = cpl_parameter_get_string(p);
817 (!strcasecmp(aParams->
combine_s,
"none")) ? MUSE_SCIBASIC_PARAM_COMBINE_NONE :
818 (!strcasecmp(aParams->
combine_s,
"average")) ? MUSE_SCIBASIC_PARAM_COMBINE_AVERAGE :
819 (!strcasecmp(aParams->
combine_s,
"median")) ? MUSE_SCIBASIC_PARAM_COMBINE_MEDIAN :
820 (!strcasecmp(aParams->
combine_s,
"minmax")) ? MUSE_SCIBASIC_PARAM_COMBINE_MINMAX :
821 (!strcasecmp(aParams->
combine_s,
"sigclip")) ? MUSE_SCIBASIC_PARAM_COMBINE_SIGCLIP :
822 MUSE_SCIBASIC_PARAM_COMBINE_INVALID_VALUE;
823 cpl_ensure_code(aParams->
combine != MUSE_SCIBASIC_PARAM_COMBINE_INVALID_VALUE,
824 CPL_ERROR_ILLEGAL_INPUT);
826 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.nlow");
827 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
828 aParams->
nlow = cpl_parameter_get_int(p);
830 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.nhigh");
831 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
832 aParams->
nhigh = cpl_parameter_get_int(p);
834 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.nkeep");
835 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
836 aParams->
nkeep = cpl_parameter_get_int(p);
838 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.lsigma");
839 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
840 aParams->
lsigma = cpl_parameter_get_double(p);
842 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.hsigma");
843 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
844 aParams->
hsigma = cpl_parameter_get_double(p);
846 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.scale");
847 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
848 aParams->
scale = cpl_parameter_get_bool(p);
850 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.saveimage");
851 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
852 aParams->
saveimage = cpl_parameter_get_bool(p);
854 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.skylines");
855 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
856 aParams->
skylines = cpl_parameter_get_string(p);
858 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.skyhalfwidth");
859 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
862 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.skybinsize");
863 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
864 aParams->
skybinsize = cpl_parameter_get_double(p);
866 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.resample");
867 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
868 aParams->
resample = cpl_parameter_get_bool(p);
870 p = cpl_parameterlist_find(aParameters,
"muse.muse_scibasic.dlambda");
871 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
872 aParams->
dlambda = cpl_parameter_get_double(p);
886 muse_scibasic_exec(cpl_plugin *aPlugin)
888 if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
891 cpl_recipe *recipe = (cpl_recipe *)aPlugin;
892 cpl_msg_set_threadid_on();
894 cpl_frameset *usedframes = cpl_frameset_new(),
895 *outframes = cpl_frameset_new();
897 muse_scibasic_params_fill(¶ms, recipe->parameters);
899 cpl_errorstate prestate = cpl_errorstate_get();
901 if (params.
nifu < -1 || params.
nifu > kMuseNumIFUs) {
902 cpl_msg_error(__func__,
"Please specify a valid IFU number (between 1 and "
903 "%d), 0 (to process all IFUs consecutively), or -1 (to "
904 "process all IFUs in parallel) using --nifu.", kMuseNumIFUs);
909 if (params.
nifu > 0) {
912 rc = muse_scibasic_compute(proc, ¶ms);
913 cpl_frameset_join(usedframes, proc->
usedFrames);
916 }
else if (params.
nifu < 0) {
917 int *rcs = cpl_calloc(kMuseNumIFUs,
sizeof(
int));
919 #pragma omp parallel for default(none) \
920 shared(outframes, params, rcs, recipe, usedframes)
921 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
927 int *rci = rcs + (nifu - 1);
928 *rci = muse_scibasic_compute(proc, pars);
929 if (rci && cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
933 #pragma omp critical(muse_processing_used_frames)
934 cpl_frameset_join(usedframes, proc->
usedFrames);
935 #pragma omp critical(muse_processing_output_frames)
941 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
942 if (rcs[nifu-1] != 0) {
948 for (params.
nifu = 1; params.
nifu <= kMuseNumIFUs && !rc; params.
nifu++) {
951 rc = muse_scibasic_compute(proc, ¶ms);
952 if (rc && cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
955 cpl_frameset_join(usedframes, proc->
usedFrames);
961 if (!cpl_errorstate_is_equal(prestate)) {
965 cpl_msg_set_level(CPL_MSG_INFO);
975 cpl_frameset_join(recipe->frames, usedframes);
976 cpl_frameset_join(recipe->frames, outframes);
977 cpl_frameset_delete(usedframes);
978 cpl_frameset_delete(outframes);
991 muse_scibasic_destroy(cpl_plugin *aPlugin)
995 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
996 recipe = (cpl_recipe *)aPlugin;
1002 cpl_parameterlist_delete(recipe->parameters);
1019 cpl_plugin_get_info(cpl_pluginlist *aList)
1021 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe);
1022 cpl_plugin *plugin = &recipe->interface;
1026 helptext = cpl_sprintf(
"%s%s", muse_scibasic_help,
1027 muse_scibasic_help_esorex);
1029 helptext = cpl_sprintf(
"%s", muse_scibasic_help);
1033 cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
1034 CPL_PLUGIN_TYPE_RECIPE,
1036 "Remove the instrumental signature from the data of each CCD and convert them from an image into a pixel table.",
1041 muse_scibasic_create,
1043 muse_scibasic_destroy);
1044 cpl_pluginlist_append(aList, plugin);
void muse_processing_delete(muse_processing *aProcessing)
Free the muse_processing structure.
int nkeep
Number of pixels to keep with minmax.
double hsigma
High sigma for pixel rejection with sigclip.
muse_cplframework_type muse_cplframework(void)
Return the CPL framework the recipe is run under.
int passes
Maximum number of cleaning passes. Only used if cr=dcr.
double ovscsigma
If the deviation of mean overscan levels between a raw input image and the reference image is higher ...
const char * combine_s
Type of combination to use. Note that in most cases, science exposures cannot easily be combined on t...
double dlambda
Wavelength step (in Angstrom per pixel) to use for resampling.
double lsigma
Low sigma for pixel rejection with sigclip.
int combine
Type of combination to use. Note that in most cases, science exposures cannot easily be combined on t...
int scale
Scale the individual images to a common exposure time before combining them.
int saveimage
Save the pre-processed CCD-based image of each input exposure before it is transformed into a pixel t...
const char * muse_get_license(void)
Get the pipeline copyright and license.
const char * overscan
If this is "none", stop when detecting discrepant overscan levels (see ovscsigma), for "offset" it assumes that the mean overscan level represents the real offset in the bias levels of the exposures involved, and adjusts the data accordingly; for "vpoly", a polynomial is fit to the vertical overscan and subtracted from the whole quadrant.
muse_processing * muse_processing_new(const char *aRecipeName, cpl_recipe *aRecipe)
Create a new processing structure.
int cr
Type of cosmic ray cleaning to use (for quick-look data processing).
int resample
Resample the input science data into 2D spectral images using tracing and wavelength calibration solu...
cpl_frameset * outputFrames
int nifu
IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in ...
void muse_cplerrorstate_dump_some(unsigned aCurrent, unsigned aFirst, unsigned aLast)
Dump some CPL errors.
void muse_processinginfo_delete(cpl_recipe *)
Clear all information from the processing info and from the recipe config.
double skyhalfwidth
Half-width of the extraction box (in Angstrom) around each sky emission line.
int crop
Automatically crop the output pixel tables in wavelength depending on the expected useful wavelength ...
const char * ovscreject
This influences how values are rejected when computing overscan statistics. Either no rejection at al...
int xbox
Search box size in x. Only used if cr=dcr.
int nhigh
Number of maximum pixels to reject with minmax.
cpl_error_code muse_cplframeset_erase_duplicate(cpl_frameset *aFrames)
Erase all duplicate frames from a frameset.
int ybox
Search box size in y. Only used if cr=dcr.
double thres
Threshold for detection gap in factors of standard deviation. Only used if cr=dcr.
Structure to hold the parameters of the muse_scibasic recipe.
double skybinsize
Size of the bins (in Angstrom per pixel) for the intermediate spectrum to do the Gaussian fit to each...
cpl_error_code muse_cplframeset_erase_all(cpl_frameset *aFrames)
Erase all frames in a frameset.
const char * cr_s
Type of cosmic ray cleaning to use (for quick-look data processing). (as string)
void muse_processinginfo_register(cpl_recipe *, cpl_recipeconfig *, muse_processing_prepare_header_func *, muse_processing_get_frame_level_func *, muse_processing_get_frame_mode_func *)
Register extended functionalities for MUSE recipes.
const char * skylines
List of wavelengths of sky emission lines (in Angstrom) to use as reference for wavelength offset cor...
cpl_frameset * usedFrames
int ovscignore
The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when com...
int nlow
Number of minimum pixels to reject with minmax.
cpl_error_code muse_processing_prepare_property(cpl_propertylist *, const char *, cpl_type, const char *)
Prepare and check the specified property.