35 #include "muse_twilight_z.h"
88 static const char *muse_twilight_help =
89 "Processing first 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&), converts the images from adu to count, subtracts the dark, divides by the flat-field and combines all the exposures using input parameters. 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 from the master sky-flat. These pixel tables are then cut in wavelength using the --lambdamin and --lambdamax parameters. The integrated flux in each IFU is computed as the sum of the data in the pixel table, and saved in the header, to be used later as estimate for the relative throughput of each IFU. The pixel tables of all IFUs are then merged, using the integrated fluxes as inverse scaling factors, and a cube is reconstructed from the merged dataset, using given parameters. A white-light image is created from the cube. This skyflat cube is then saved to disk, with the white-light image as one extension. To construct a smooth 3D illumination correction, the cube is post-processed in the following way: the white-light image is used to create a mask of the illuminated area. From this area, the optional vignetting mask is removed. The smoothing is then computed for each plane of the cube: the illuminated area is smoothed (by a 5x7 median filter), normalized, fit with a 2D polynomial (of given polynomial orders), and normalized again. A smooth white image is then created by collapsing the smooth cube. If a vignetting mask was given, the corner area given by the mask is used to compute a 2D correction for the vignetted area: the original unsmoothed white-light image is corrected for large scale gradients by dividing it with the smooth white image. The residuals in the corner area then smoothed using input parameters. This smoothed vignetting correction is the multiplied onto each plane of the smooth cube, normalizing each plane again. This twilight cube is then saved to disk.";
91 static const char *muse_twilight_help_esorex =
92 "\n\nInput frames for raw frame tag \"SKYFLAT\":\n"
93 "\n Frame tag Type Req #Fr Description"
94 "\n -------------------- ---- --- --- ------------"
95 "\n SKYFLAT raw Y >=3 Raw twilight skyflat"
96 "\n MASTER_BIAS calib Y 1 Master bias"
97 "\n MASTER_DARK calib . 1 Master dark"
98 "\n MASTER_FLAT calib Y 1 Master flat"
99 "\n BADPIX_TABLE calib . 1 Known bad pixels"
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 VIGNETTING_MASK calib . 1 Mask to mark vignetted regions in the MUSE field of view"
104 "\n\nProduct frames for raw frame tag \"SKYFLAT\":\n"
105 "\n Frame tag Level Description"
106 "\n -------------------- -------- ------------"
107 "\n DATACUBE_SKYFLAT final Cube of combined twilight skyflat exposures"
108 "\n TWILIGHT_CUBE final Smoothed cube of twilight sky";
119 static cpl_recipeconfig *
120 muse_twilight_new_recipeconfig(
void)
122 cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
126 cpl_recipeconfig_set_tag(recipeconfig, tag, 3, -1);
127 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_BIAS", 1, 1);
128 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_DARK", -1, 1);
129 cpl_recipeconfig_set_input(recipeconfig, tag,
"MASTER_FLAT", 1, 1);
130 cpl_recipeconfig_set_input(recipeconfig, tag,
"BADPIX_TABLE", -1, 1);
131 cpl_recipeconfig_set_input(recipeconfig, tag,
"TRACE_TABLE", 1, 1);
132 cpl_recipeconfig_set_input(recipeconfig, tag,
"WAVECAL_TABLE", 1, 1);
133 cpl_recipeconfig_set_input(recipeconfig, tag,
"GEOMETRY_TABLE", 1, 1);
134 cpl_recipeconfig_set_input(recipeconfig, tag,
"VIGNETTING_MASK", -1, 1);
135 cpl_recipeconfig_set_output(recipeconfig, tag,
"DATACUBE_SKYFLAT");
136 cpl_recipeconfig_set_output(recipeconfig, tag,
"TWILIGHT_CUBE");
152 static cpl_error_code
153 muse_twilight_prepare_header(
const char *aFrametag, cpl_propertylist *aHeader)
155 cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
156 cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
157 if (!strcmp(aFrametag,
"DATACUBE_SKYFLAT")) {
160 "Median value of raw exposure i of IFU m in input list");
163 "Mean value of raw exposure i of IFU m in input list");
166 "Standard deviation of raw exposure i of IFU m in input list");
169 "Minimum value of raw exposure i of IFU m in input list");
172 "Maximum value of raw exposure i of IFU m in input list");
175 "Number of saturated pixels in raw exposure i of IFU m in input list");
178 "Median value of the combined exposures in IFU m");
181 "Mean value of the combined exposures in IFU m");
184 "Standard deviation of the combined exposures in IFU m");
187 "Minimum value of the combined exposures in IFU m");
190 "Maximum value of the combined exposures in IFU m");
193 "Flux integrated over the whole CCD of the combined exposures of IFU m");
196 "Flux integrated over all slices of IFU m. Computed using the pixel table of the exposure.");
197 }
else if (!strcmp(aFrametag,
"TWILIGHT_CUBE")) {
199 cpl_msg_warning(__func__,
"Frame tag %s is not defined", aFrametag);
200 return CPL_ERROR_ILLEGAL_INPUT;
202 return CPL_ERROR_NONE;
215 static cpl_frame_level
216 muse_twilight_get_frame_level(
const char *aFrametag)
219 return CPL_FRAME_LEVEL_NONE;
221 if (!strcmp(aFrametag,
"DATACUBE_SKYFLAT")) {
222 return CPL_FRAME_LEVEL_FINAL;
224 if (!strcmp(aFrametag,
"TWILIGHT_CUBE")) {
225 return CPL_FRAME_LEVEL_FINAL;
227 return CPL_FRAME_LEVEL_NONE;
241 muse_twilight_get_frame_mode(
const char *aFrametag)
246 if (!strcmp(aFrametag,
"DATACUBE_SKYFLAT")) {
249 if (!strcmp(aFrametag,
"TWILIGHT_CUBE")) {
267 muse_twilight_create(cpl_plugin *aPlugin)
271 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
272 recipe = (cpl_recipe *)aPlugin;
280 muse_twilight_new_recipeconfig(),
281 muse_twilight_prepare_header,
282 muse_twilight_get_frame_level,
283 muse_twilight_get_frame_mode);
288 cpl_msg_set_time_on();
292 recipe->parameters = cpl_parameterlist_new();
297 p = cpl_parameter_new_value(
"muse.muse_twilight.overscan",
299 "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.",
300 "muse.muse_twilight",
301 (
const char *)
"vpoly");
302 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"overscan");
303 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"overscan");
305 cpl_parameterlist_append(recipe->parameters, p);
308 p = cpl_parameter_new_value(
"muse.muse_twilight.ovscreject",
310 "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\").",
311 "muse.muse_twilight",
312 (
const char *)
"dcr");
313 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"ovscreject");
314 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ovscreject");
316 cpl_parameterlist_append(recipe->parameters, p);
319 p = cpl_parameter_new_value(
"muse.muse_twilight.ovscsigma",
321 "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 (the level comparison is then done afterwards with |100 x stdev| to guard against incompatible settings). Has no effect for overscan=\"offset\".",
322 "muse.muse_twilight",
324 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"ovscsigma");
325 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ovscsigma");
327 cpl_parameterlist_append(recipe->parameters, p);
330 p = cpl_parameter_new_value(
"muse.muse_twilight.ovscignore",
332 "The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when computing statistics or fits.",
333 "muse.muse_twilight",
335 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"ovscignore");
336 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ovscignore");
338 cpl_parameterlist_append(recipe->parameters, p);
341 p = cpl_parameter_new_enum(
"muse.muse_twilight.combine",
343 "Type of combination to use",
344 "muse.muse_twilight",
345 (
const char *)
"sigclip",
347 (
const char *)
"average",
348 (
const char *)
"median",
349 (
const char *)
"minmax",
350 (
const char *)
"sigclip");
351 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"combine");
352 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"combine");
354 cpl_parameterlist_append(recipe->parameters, p);
357 p = cpl_parameter_new_value(
"muse.muse_twilight.nlow",
359 "Number of minimum pixels to reject with minmax",
360 "muse.muse_twilight",
362 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nlow");
363 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nlow");
365 cpl_parameterlist_append(recipe->parameters, p);
368 p = cpl_parameter_new_value(
"muse.muse_twilight.nhigh",
370 "Number of maximum pixels to reject with minmax",
371 "muse.muse_twilight",
373 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nhigh");
374 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nhigh");
376 cpl_parameterlist_append(recipe->parameters, p);
379 p = cpl_parameter_new_value(
"muse.muse_twilight.nkeep",
381 "Number of pixels to keep with minmax",
382 "muse.muse_twilight",
384 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"nkeep");
385 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nkeep");
387 cpl_parameterlist_append(recipe->parameters, p);
390 p = cpl_parameter_new_value(
"muse.muse_twilight.lsigma",
392 "Low sigma for pixel rejection with sigclip",
393 "muse.muse_twilight",
395 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"lsigma");
396 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lsigma");
398 cpl_parameterlist_append(recipe->parameters, p);
401 p = cpl_parameter_new_value(
"muse.muse_twilight.hsigma",
403 "High sigma for pixel rejection with sigclip",
404 "muse.muse_twilight",
406 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"hsigma");
407 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"hsigma");
409 cpl_parameterlist_append(recipe->parameters, p);
412 p = cpl_parameter_new_value(
"muse.muse_twilight.scale",
414 "Scale the individual images to a common exposure time before combining them.",
415 "muse.muse_twilight",
417 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"scale");
418 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"scale");
420 cpl_parameterlist_append(recipe->parameters, p);
423 p = cpl_parameter_new_enum(
"muse.muse_twilight.resample",
425 "The resampling technique to use for the final output cube.",
426 "muse.muse_twilight",
427 (
const char *)
"drizzle",
429 (
const char *)
"nearest",
430 (
const char *)
"linear",
431 (
const char *)
"quadratic",
432 (
const char *)
"renka",
433 (
const char *)
"drizzle",
434 (
const char *)
"lanczos");
435 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"resample");
436 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"resample");
438 cpl_parameterlist_append(recipe->parameters, p);
441 p = cpl_parameter_new_enum(
"muse.muse_twilight.crtype",
443 "Type of statistics used for detection of cosmic rays during final resampling. \"iraf\" uses the variance information, \"mean\" uses standard (mean/stdev) statistics, \"median\" uses median and the median median of the absolute median deviation.",
444 "muse.muse_twilight",
445 (
const char *)
"median",
447 (
const char *)
"iraf",
448 (
const char *)
"mean",
449 (
const char *)
"median");
450 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"crtype");
451 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"crtype");
453 cpl_parameterlist_append(recipe->parameters, p);
456 p = cpl_parameter_new_value(
"muse.muse_twilight.crsigma",
458 "Sigma rejection factor to use for cosmic ray rejection during final resampling. A zero or negative value switches cosmic ray rejection off.",
459 "muse.muse_twilight",
461 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"crsigma");
462 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"crsigma");
464 cpl_parameterlist_append(recipe->parameters, p);
467 p = cpl_parameter_new_value(
"muse.muse_twilight.lambdamin",
469 "Minimum wavelength for twilight reconstruction.",
470 "muse.muse_twilight",
472 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"lambdamin");
473 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lambdamin");
475 cpl_parameterlist_append(recipe->parameters, p);
478 p = cpl_parameter_new_value(
"muse.muse_twilight.lambdamax",
480 "Maximum wavelength for twilight reconstruction.",
481 "muse.muse_twilight",
483 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"lambdamax");
484 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lambdamax");
486 cpl_parameterlist_append(recipe->parameters, p);
489 p = cpl_parameter_new_value(
"muse.muse_twilight.dlambda",
491 "Sampling for twilight reconstruction, this should result in planes of equal wavelength coverage.",
492 "muse.muse_twilight",
494 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"dlambda");
495 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dlambda");
497 cpl_parameterlist_append(recipe->parameters, p);
500 p = cpl_parameter_new_value(
"muse.muse_twilight.xorder",
502 "Polynomial order to use in x direction to fit the full field of view.",
503 "muse.muse_twilight",
505 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"xorder");
506 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"xorder");
508 cpl_parameterlist_append(recipe->parameters, p);
511 p = cpl_parameter_new_value(
"muse.muse_twilight.yorder",
513 "Polynomial order to use in y direction to fit the full field of view.",
514 "muse.muse_twilight",
516 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"yorder");
517 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"yorder");
519 cpl_parameterlist_append(recipe->parameters, p);
522 p = cpl_parameter_new_value(
"muse.muse_twilight.vignmaskedges",
524 "Pixels on edges stronger than this fraction in the normalized image are excluded from the fit to the vignetted area. Set to non-positive number to include them in the fit.",
525 "muse.muse_twilight",
527 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"vignmaskedges");
528 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"vignmaskedges");
530 cpl_parameterlist_append(recipe->parameters, p);
533 p = cpl_parameter_new_enum(
"muse.muse_twilight.vignsmooth",
535 "Type of smoothing to use for the vignetted region given by the VIGNETTING_MASK; gaussian uses (vignxpar + vignypar)/2 as FWHM.",
536 "muse.muse_twilight",
537 (
const char *)
"polyfit",
539 (
const char *)
"polyfit",
540 (
const char *)
"gaussian",
541 (
const char *)
"median");
542 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"vignsmooth");
543 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"vignsmooth");
545 cpl_parameterlist_append(recipe->parameters, p);
548 p = cpl_parameter_new_value(
"muse.muse_twilight.vignxpar",
550 "Parameter used by the vignetting smoothing: x order for polyfit (default, recommended 4), parameter that influences the FWHM for the gaussian (recommended: 10), or x dimension of median filter (recommended 5).",
551 "muse.muse_twilight",
553 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"vignxpar");
554 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"vignxpar");
556 cpl_parameterlist_append(recipe->parameters, p);
559 p = cpl_parameter_new_value(
"muse.muse_twilight.vignypar",
561 "Parameter used by the vignetting smoothing: y order for polyfit (default, recommended 4), parameter that influences the FWHM for the gaussian (recommended: 10), or y dimension of median filter (recommended 5).",
562 "muse.muse_twilight",
564 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"vignypar");
565 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"vignypar");
567 cpl_parameterlist_append(recipe->parameters, p);
587 cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
588 cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
591 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.overscan");
592 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
593 aParams->
overscan = cpl_parameter_get_string(p);
595 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.ovscreject");
596 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
597 aParams->
ovscreject = cpl_parameter_get_string(p);
599 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.ovscsigma");
600 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
601 aParams->
ovscsigma = cpl_parameter_get_double(p);
603 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.ovscignore");
604 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
605 aParams->
ovscignore = cpl_parameter_get_int(p);
607 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.combine");
608 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
609 aParams->
combine_s = cpl_parameter_get_string(p);
611 (!strcasecmp(aParams->
combine_s,
"average")) ? MUSE_TWILIGHT_PARAM_COMBINE_AVERAGE :
612 (!strcasecmp(aParams->
combine_s,
"median")) ? MUSE_TWILIGHT_PARAM_COMBINE_MEDIAN :
613 (!strcasecmp(aParams->
combine_s,
"minmax")) ? MUSE_TWILIGHT_PARAM_COMBINE_MINMAX :
614 (!strcasecmp(aParams->
combine_s,
"sigclip")) ? MUSE_TWILIGHT_PARAM_COMBINE_SIGCLIP :
615 MUSE_TWILIGHT_PARAM_COMBINE_INVALID_VALUE;
616 cpl_ensure_code(aParams->
combine != MUSE_TWILIGHT_PARAM_COMBINE_INVALID_VALUE,
617 CPL_ERROR_ILLEGAL_INPUT);
619 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.nlow");
620 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
621 aParams->
nlow = cpl_parameter_get_int(p);
623 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.nhigh");
624 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
625 aParams->
nhigh = cpl_parameter_get_int(p);
627 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.nkeep");
628 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
629 aParams->
nkeep = cpl_parameter_get_int(p);
631 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.lsigma");
632 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
633 aParams->
lsigma = cpl_parameter_get_double(p);
635 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.hsigma");
636 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
637 aParams->
hsigma = cpl_parameter_get_double(p);
639 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.scale");
640 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
641 aParams->
scale = cpl_parameter_get_bool(p);
643 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.resample");
644 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
645 aParams->
resample_s = cpl_parameter_get_string(p);
647 (!strcasecmp(aParams->
resample_s,
"nearest")) ? MUSE_TWILIGHT_PARAM_RESAMPLE_NEAREST :
648 (!strcasecmp(aParams->
resample_s,
"linear")) ? MUSE_TWILIGHT_PARAM_RESAMPLE_LINEAR :
649 (!strcasecmp(aParams->
resample_s,
"quadratic")) ? MUSE_TWILIGHT_PARAM_RESAMPLE_QUADRATIC :
650 (!strcasecmp(aParams->
resample_s,
"renka")) ? MUSE_TWILIGHT_PARAM_RESAMPLE_RENKA :
651 (!strcasecmp(aParams->
resample_s,
"drizzle")) ? MUSE_TWILIGHT_PARAM_RESAMPLE_DRIZZLE :
652 (!strcasecmp(aParams->
resample_s,
"lanczos")) ? MUSE_TWILIGHT_PARAM_RESAMPLE_LANCZOS :
653 MUSE_TWILIGHT_PARAM_RESAMPLE_INVALID_VALUE;
654 cpl_ensure_code(aParams->
resample != MUSE_TWILIGHT_PARAM_RESAMPLE_INVALID_VALUE,
655 CPL_ERROR_ILLEGAL_INPUT);
657 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.crtype");
658 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
659 aParams->
crtype_s = cpl_parameter_get_string(p);
661 (!strcasecmp(aParams->
crtype_s,
"iraf")) ? MUSE_TWILIGHT_PARAM_CRTYPE_IRAF :
662 (!strcasecmp(aParams->
crtype_s,
"mean")) ? MUSE_TWILIGHT_PARAM_CRTYPE_MEAN :
663 (!strcasecmp(aParams->
crtype_s,
"median")) ? MUSE_TWILIGHT_PARAM_CRTYPE_MEDIAN :
664 MUSE_TWILIGHT_PARAM_CRTYPE_INVALID_VALUE;
665 cpl_ensure_code(aParams->
crtype != MUSE_TWILIGHT_PARAM_CRTYPE_INVALID_VALUE,
666 CPL_ERROR_ILLEGAL_INPUT);
668 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.crsigma");
669 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
670 aParams->
crsigma = cpl_parameter_get_double(p);
672 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.lambdamin");
673 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
674 aParams->
lambdamin = cpl_parameter_get_double(p);
676 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.lambdamax");
677 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
678 aParams->
lambdamax = cpl_parameter_get_double(p);
680 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.dlambda");
681 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
682 aParams->
dlambda = cpl_parameter_get_double(p);
684 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.xorder");
685 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
686 aParams->
xorder = cpl_parameter_get_int(p);
688 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.yorder");
689 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
690 aParams->
yorder = cpl_parameter_get_int(p);
692 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.vignmaskedges");
693 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
696 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.vignsmooth");
697 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
700 (!strcasecmp(aParams->
vignsmooth_s,
"polyfit")) ? MUSE_TWILIGHT_PARAM_VIGNSMOOTH_POLYFIT :
701 (!strcasecmp(aParams->
vignsmooth_s,
"gaussian")) ? MUSE_TWILIGHT_PARAM_VIGNSMOOTH_GAUSSIAN :
702 (!strcasecmp(aParams->
vignsmooth_s,
"median")) ? MUSE_TWILIGHT_PARAM_VIGNSMOOTH_MEDIAN :
703 MUSE_TWILIGHT_PARAM_VIGNSMOOTH_INVALID_VALUE;
704 cpl_ensure_code(aParams->
vignsmooth != MUSE_TWILIGHT_PARAM_VIGNSMOOTH_INVALID_VALUE,
705 CPL_ERROR_ILLEGAL_INPUT);
707 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.vignxpar");
708 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
709 aParams->
vignxpar = cpl_parameter_get_int(p);
711 p = cpl_parameterlist_find(aParameters,
"muse.muse_twilight.vignypar");
712 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
713 aParams->
vignypar = cpl_parameter_get_int(p);
727 muse_twilight_exec(cpl_plugin *aPlugin)
729 if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
732 cpl_recipe *recipe = (cpl_recipe *)aPlugin;
733 cpl_msg_set_threadid_on();
735 cpl_frameset *usedframes = cpl_frameset_new(),
736 *outframes = cpl_frameset_new();
738 muse_twilight_params_fill(¶ms, recipe->parameters);
740 cpl_errorstate prestate = cpl_errorstate_get();
744 int rc = muse_twilight_compute(proc, ¶ms);
745 cpl_frameset_join(usedframes, proc->
usedframes);
746 cpl_frameset_join(outframes, proc->
outframes);
749 if (!cpl_errorstate_is_equal(prestate)) {
753 cpl_msg_set_level(CPL_MSG_INFO);
764 cpl_frameset_join(recipe->frames, usedframes);
765 cpl_frameset_join(recipe->frames, outframes);
766 cpl_frameset_delete(usedframes);
767 cpl_frameset_delete(outframes);
780 muse_twilight_destroy(cpl_plugin *aPlugin)
784 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
785 recipe = (cpl_recipe *)aPlugin;
791 cpl_parameterlist_delete(recipe->parameters);
808 cpl_plugin_get_info(cpl_pluginlist *aList)
810 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe);
811 cpl_plugin *plugin = &recipe->interface;
815 helptext = cpl_sprintf(
"%s%s", muse_twilight_help,
816 muse_twilight_help_esorex);
818 helptext = cpl_sprintf(
"%s", muse_twilight_help);
822 cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
823 CPL_PLUGIN_TYPE_RECIPE,
825 "Combine several twilight skyflats into one cube, compute correction factors for each IFU, and create a smooth 3D illumination correction.",
830 muse_twilight_create,
832 muse_twilight_destroy);
833 cpl_pluginlist_append(aList, plugin);
double crsigma
Sigma rejection factor to use for cosmic ray rejection during final resampling. A zero or negative va...
void muse_processing_delete(muse_processing *aProcessing)
Free the muse_processing structure.
const char * vignsmooth_s
Type of smoothing to use for the vignetted region given by the VIGNETTING_MASK; gaussian uses (vignxp...
int scale
Scale the individual images to a common exposure time before combining them.
double lsigma
Low sigma for pixel rejection with sigclip.
int nkeep
Number of pixels to keep with minmax.
muse_cplframework_type muse_cplframework(void)
Return the CPL framework the recipe is run under.
double ovscsigma
If the deviation of mean overscan levels between a raw input image and the reference image is higher ...
const char * crtype_s
Type of statistics used for detection of cosmic rays during final resampling. "iraf" uses the varianc...
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.
cpl_frameset * usedframes
muse_processing * muse_processing_new(const char *aName, cpl_recipe *aRecipe)
Create a new processing structure.
int nhigh
Number of maximum pixels to reject with minmax.
const char * muse_get_license(void)
Get the pipeline copyright and license.
int vignxpar
Parameter used by the vignetting smoothing: x order for polyfit (default, recommended 4)...
double vignmaskedges
Pixels on edges stronger than this fraction in the normalized image are excluded from the fit to the ...
int vignypar
Parameter used by the vignetting smoothing: y order for polyfit (default, recommended 4)...
const char * combine_s
Type of combination to use (as string)
Structure to hold the parameters of the muse_twilight recipe.
double dlambda
Sampling for twilight reconstruction, this should result in planes of equal wavelength coverage...
int vignsmooth
Type of smoothing to use for the vignetted region given by the VIGNETTING_MASK; gaussian uses (vignxp...
int resample
The resampling technique to use for the final output cube.
void muse_cplerrorstate_dump_some(unsigned aCurrent, unsigned aFirst, unsigned aLast)
Dump some CPL errors.
double lambdamin
Minimum wavelength for twilight reconstruction.
void muse_processinginfo_delete(cpl_recipe *)
Clear all information from the processing info and from the recipe config.
int combine
Type of combination to use.
double hsigma
High sigma for pixel rejection with sigclip.
int yorder
Polynomial order to use in y direction to fit the full field of view.
int xorder
Polynomial order to use in x direction to fit the full field of view.
const char * ovscreject
This influences how values are rejected when computing overscan statistics. Either no rejection at al...
cpl_error_code muse_cplframeset_erase_duplicate(cpl_frameset *aFrames)
Erase all duplicate frames from a frameset.
cpl_error_code muse_cplframeset_erase_all(cpl_frameset *aFrames)
Erase all frames in a frameset.
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.
int ovscignore
The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when com...
double lambdamax
Maximum wavelength for twilight reconstruction.
int nlow
Number of minimum pixels to reject with minmax.
int crtype
Type of statistics used for detection of cosmic rays during final resampling. "iraf" uses the varianc...
cpl_error_code muse_processing_prepare_property(cpl_propertylist *, const char *, cpl_type, const char *)
Prepare and check the specified property.
const char * resample_s
The resampling technique to use for the final output cube. (as string)