35 #include "muse_scipost_z.h" 87 static const char *muse_scipost_help =
88 "Sort input pixel tables into lists of files per exposure, merge pixel tables from all IFUs of each exposure. Correct each exposure for differential atmospheric refraction (unless --lambdaref is far outside the MUSE wavelength range). Then the flux calibration is carried out, if a response curve was given in the input; it includes a correction of telluric absorption, if a telluric absorption correction file was given. Then the sky subtraction is carried out (unless --skymethod=\"none\"), either directly subtracting an input sky continuum and an input sky emission lines (for --skymethod=\"subtract-model\"), or (--skymethod=\"model\") create a sky spectrum from the darkest fraction (--skymodel_fraction, after ignoring the lowest --skymodel_ignore as artifacts) of the field of view, then fitting and subtracting sky emission lines using an initial estimate of the input sky lines; then the continuum (residuals after subtracting the sky lines from the sky spectrum) is subtracted as well. If --save contains \"skymodel\", all sky-related products are saved for each exposure. Afterwards the data is corrected for the radial velocity of the observer (--rvcorr), before the input (or a default) astrometric solution is applied. Now each individual exposure is fully reduced; the pixel tables at this stage can be saved by setting \"individual\" in --save. If multiple exposures were given, they are then combined. If --save contains \"combined\", this final merged pixel table is saved. Finally (if --save contains \"cube\"), the data is resampled into a datacube, using all parameters given to the recipe. The extent and orientation of the cube is normally computed from the data itself, but this can be overridden by passing a file with the output world coordinate system (OUTPUT_WCS), for example a MUSE cube. This can also be used to sample the wavelength axis logarithmically (in that file set \"CTYPE3='AWAV-LOG'\"). As a last step, the computed cube is integrated over all filter functions given (--filter) that are also present in the input filter list table.";
90 static const char *muse_scipost_help_esorex =
91 "\n\nInput frames for raw frame tag \"PIXTABLE_OBJECT\":\n" 92 "\n Frame tag Type Req #Fr Description" 93 "\n -------------------- ---- --- --- ------------" 94 "\n PIXTABLE_OBJECT raw Y Pixel table of a science object" 95 "\n EXTINCT_TABLE calib Y 1 Atmospheric extinction table" 96 "\n STD_RESPONSE calib Y 1 Response curve as derived from standard star(s)" 97 "\n STD_TELLURIC calib . 1 Telluric absorption correction as derived from standard star(s)" 98 "\n ASTROMETRY_WCS calib . 1 Astrometric solution derived from astrometric science frame" 99 "\n OFFSET_LIST calib . 1 List of coordinate offsets (and optional flux scale factors)" 100 "\n FILTER_LIST calib . 1 File to be used to create field-of-view images." 101 "\n OUTPUT_WCS calib . 1 WCS to override output cube location / dimensions" 102 "\n SKY_LINES calib . 1 List of OH transitions and other sky lines" 103 "\n SKY_CONTINUUM calib . 1 Sky continuum to use" 104 "\n LSF_PROFILE calib . Slice specific LSF parameters." 105 "\n SKY_MASK calib . 1 Sky mask to use" 106 "\n\nProduct frames for raw frame tag \"PIXTABLE_OBJECT\":\n" 107 "\n Frame tag Level Description" 108 "\n -------------------- -------- ------------" 109 "\n DATACUBE_FINAL final Output datacube" 110 "\n IMAGE_FOV final Field-of-view images corresponding to the \"filter\" parameter." 111 "\n OBJECT_RESAMPLED final Stacked image (if --save contains \"stacked\")" 112 "\n PIXTABLE_REDUCED intermed Fully reduced pixel tables for each exposure (if --save contains \"individual\")" 113 "\n PIXTABLE_POSITIONED intermed Fully reduced and positioned pixel table for each individual exposure (if --save contains \"positioned\")" 114 "\n PIXTABLE_COMBINED intermed Fully reduced and combined pixel table for the full set of exposures (if --save contains \"combined\")" 115 "\n SKY_MASK intermed Created sky mask (if --skymethod=model and --save contains \"skymodel\")" 116 "\n SKY_SPECTRUM intermed Sky spectrum within the sky mask (if --skymethod=model and --save contains \"skymodel\")" 117 "\n SKY_LINES final Estimated sky line flux table (if --skymethod=model and --save contains \"skymodel\")" 118 "\n SKY_CONTINUUM final Estimated continuum flux spectrum (if --skymethod=model and --save contains \"skymodel\")";
129 static cpl_recipeconfig *
130 muse_scipost_new_recipeconfig(
void)
132 cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
134 cpl_recipeconfig_set_tag(recipeconfig,
"PIXTABLE_OBJECT", 1, -1);
135 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_OBJECT",
"EXTINCT_TABLE", 1, 1);
136 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_OBJECT",
"STD_RESPONSE", 1, 1);
137 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_OBJECT",
"STD_TELLURIC", -1, 1);
138 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_OBJECT",
"ASTROMETRY_WCS", -1, 1);
139 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_OBJECT",
"OFFSET_LIST", -1, 1);
140 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_OBJECT",
"FILTER_LIST", -1, 1);
141 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_OBJECT",
"OUTPUT_WCS", -1, 1);
142 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_OBJECT",
"SKY_LINES", 0, 1);
143 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_OBJECT",
"SKY_CONTINUUM", 0, 1);
144 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_OBJECT",
"LSF_PROFILE", 0, -1);
145 cpl_recipeconfig_set_input(recipeconfig,
"PIXTABLE_OBJECT",
"SKY_MASK", 0, 1);
146 cpl_recipeconfig_set_output(recipeconfig,
"PIXTABLE_OBJECT",
"SKY_MASK");
147 cpl_recipeconfig_set_output(recipeconfig,
"PIXTABLE_OBJECT",
"SKY_SPECTRUM");
148 cpl_recipeconfig_set_output(recipeconfig,
"PIXTABLE_OBJECT",
"SKY_LINES");
149 cpl_recipeconfig_set_output(recipeconfig,
"PIXTABLE_OBJECT",
"SKY_CONTINUUM");
165 static cpl_error_code
166 muse_scipost_prepare_header(
const char *aFrametag, cpl_propertylist *aHeader)
168 cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
169 cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
170 if (!strcmp(aFrametag,
"DATACUBE_FINAL")) {
173 "Number of detected sources in output cube.");
176 "[Angstrom] Wavelength of plane in combined cube that was used for object detection.");
179 "[pix] Position of source k in x-direction in output cube. If the FWHM measurement fails, this value will be -1.");
182 "[pix] Position of source k in y-direction in output cube. If the FWHM measurement fails, this value will be -1.");
185 "[arcsec] FWHM of source k in x-direction in output cube. If the FWHM measurement fails, this value will be -1.");
188 "[arcsec] FWHM of source k in y-direction in output cube. If the FWHM measurement fails, this value will be -1.");
191 "Number of detected sources with valid FWHM in output cube.");
194 "[arcsec] Median FWHM of all sources with valid FWHM measurement (in x- and y-direction) in output cube. If less than three sources with valid FWHM are detected, this value is zero.");
197 "[arcsec] Median absolute deviation of the FWHM of all sources with valid FWHM measurement (in x- and y-direction) in output cube. If less than three sources with valid FWHM are detected, this value is zero.");
198 }
else if (!strcmp(aFrametag,
"IMAGE_FOV")) {
201 "[pix] Position of source k in x-direction in combined frame");
204 "[pix] Position of source k in y-direction in combined frame");
207 "[arcsec] FWHM of source k in x-direction in combined frame");
210 "[arcsec] FWHM of source k in y-direction in combined frame");
211 }
else if (!strcmp(aFrametag,
"OBJECT_RESAMPLED")) {
212 }
else if (!strcmp(aFrametag,
"PIXTABLE_REDUCED")) {
213 }
else if (!strcmp(aFrametag,
"PIXTABLE_POSITIONED")) {
214 }
else if (!strcmp(aFrametag,
"PIXTABLE_COMBINED")) {
215 }
else if (!strcmp(aFrametag,
"SKY_MASK")) {
218 "Threshold in the white light considered as sky, used to create this mask");
219 }
else if (!strcmp(aFrametag,
"SKY_SPECTRUM")) {
220 }
else if (!strcmp(aFrametag,
"SKY_LINES")) {
223 "Name of the strongest line in group l");
226 "[Angstrom] Wavelength (air) of the strongest line of group l");
229 "[erg/(s cm2 arcsec2)] Flux of the strongest line of group l");
230 }
else if (!strcmp(aFrametag,
"SKY_CONTINUUM")) {
233 "[erg/(s cm2 arcsec2)] Total flux of the continuum");
236 "[erg/(s cm2 arcsec2 Angstrom)] Maximum (absolute value) of the derivative of the continuum spectrum");
238 cpl_msg_warning(__func__,
"Frame tag %s is not defined", aFrametag);
239 return CPL_ERROR_ILLEGAL_INPUT;
241 return CPL_ERROR_NONE;
254 static cpl_frame_level
255 muse_scipost_get_frame_level(
const char *aFrametag)
258 return CPL_FRAME_LEVEL_NONE;
260 if (!strcmp(aFrametag,
"DATACUBE_FINAL")) {
261 return CPL_FRAME_LEVEL_FINAL;
263 if (!strcmp(aFrametag,
"IMAGE_FOV")) {
264 return CPL_FRAME_LEVEL_FINAL;
266 if (!strcmp(aFrametag,
"OBJECT_RESAMPLED")) {
267 return CPL_FRAME_LEVEL_FINAL;
269 if (!strcmp(aFrametag,
"PIXTABLE_REDUCED")) {
270 return CPL_FRAME_LEVEL_INTERMEDIATE;
272 if (!strcmp(aFrametag,
"PIXTABLE_POSITIONED")) {
273 return CPL_FRAME_LEVEL_INTERMEDIATE;
275 if (!strcmp(aFrametag,
"PIXTABLE_COMBINED")) {
276 return CPL_FRAME_LEVEL_INTERMEDIATE;
278 if (!strcmp(aFrametag,
"SKY_MASK")) {
279 return CPL_FRAME_LEVEL_INTERMEDIATE;
281 if (!strcmp(aFrametag,
"SKY_SPECTRUM")) {
282 return CPL_FRAME_LEVEL_INTERMEDIATE;
284 if (!strcmp(aFrametag,
"SKY_LINES")) {
285 return CPL_FRAME_LEVEL_FINAL;
287 if (!strcmp(aFrametag,
"SKY_CONTINUUM")) {
288 return CPL_FRAME_LEVEL_FINAL;
290 return CPL_FRAME_LEVEL_NONE;
304 muse_scipost_get_frame_mode(
const char *aFrametag)
309 if (!strcmp(aFrametag,
"DATACUBE_FINAL")) {
312 if (!strcmp(aFrametag,
"IMAGE_FOV")) {
315 if (!strcmp(aFrametag,
"OBJECT_RESAMPLED")) {
318 if (!strcmp(aFrametag,
"PIXTABLE_REDUCED")) {
321 if (!strcmp(aFrametag,
"PIXTABLE_POSITIONED")) {
324 if (!strcmp(aFrametag,
"PIXTABLE_COMBINED")) {
327 if (!strcmp(aFrametag,
"SKY_MASK")) {
330 if (!strcmp(aFrametag,
"SKY_SPECTRUM")) {
333 if (!strcmp(aFrametag,
"SKY_LINES")) {
336 if (!strcmp(aFrametag,
"SKY_CONTINUUM")) {
354 muse_scipost_create(cpl_plugin *aPlugin)
358 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
359 recipe = (cpl_recipe *)aPlugin;
367 muse_scipost_new_recipeconfig(),
368 muse_scipost_prepare_header,
369 muse_scipost_get_frame_level,
370 muse_scipost_get_frame_mode);
375 cpl_msg_set_time_on();
379 recipe->parameters = cpl_parameterlist_new();
391 p = cpl_parameter_new_value(
"muse.muse_scipost.save",
393 "Select output product(s) to save. Can contain one or more of \"cube\", \"skymodel\", \"individual\", \"positioned\", \"combined\", and \"stacked\". If several options are given, they have to be comma-separated. (\"cube\": output cube and associated images, if this is not given, no final resampling is done at all -- \"skymodel\": up to four additional output products about the effectively used sky that was subtracted with the \"model\" method -- \"individual\": fully reduced pixel table for each individual exposure -- \"positioned\": fully reduced and positioned pixel table for each individual exposure, the difference to \"individual\" is that here, the output pixel tables have coordinates in RA and DEC; this is only useful, if both the relative exposure weighting and the final resampling are to be done externally -- \"combined\": fully reduced and combined pixel table for the full set of exposures, the difference to \"positioned\" is that all pixel tables are combined into one, with an added weight column; this is useful, if only the final resampling step is to be done separately -- \"stacked\": an additional output file in form of a 2D column-stacked image, i.e. x direction is pseudo-spatial, y direction is wavelength.)",
395 (
const char *)
"cube,skymodel");
396 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"save");
397 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"save");
399 cpl_parameterlist_append(recipe->parameters, p);
402 p = cpl_parameter_new_enum(
"muse.muse_scipost.resample",
404 "The resampling technique to use for the final output cube.",
406 (
const char *)
"drizzle",
408 (
const char *)
"nearest",
409 (
const char *)
"linear",
410 (
const char *)
"quadratic",
411 (
const char *)
"renka",
412 (
const char *)
"drizzle",
413 (
const char *)
"lanczos");
414 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"resample");
415 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"resample");
417 cpl_parameterlist_append(recipe->parameters, p);
420 p = cpl_parameter_new_value(
"muse.muse_scipost.dx",
422 "Horizontal step size for resampling (in arcsec or pixel). The following defaults are taken when this value is set to 0.0: 0.2'' for WFM, 0.075'' for NFM, 1.0 if data is in pixel units.",
425 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"dx");
426 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dx");
428 cpl_parameterlist_append(recipe->parameters, p);
431 p = cpl_parameter_new_value(
"muse.muse_scipost.dy",
433 "Vertical step size for resampling (in arcsec or pixel). The following defaults are taken when this value is set to 0.0: 0.2'' for WFM, 0.075'' for NFM, 1.0 if data is in pixel units.",
436 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"dy");
437 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dy");
439 cpl_parameterlist_append(recipe->parameters, p);
442 p = cpl_parameter_new_value(
"muse.muse_scipost.dlambda",
444 "Wavelength step size (in Angstrom). Natural instrument sampling is used, if this is 0.0",
447 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"dlambda");
448 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dlambda");
450 cpl_parameterlist_append(recipe->parameters, p);
453 p = cpl_parameter_new_enum(
"muse.muse_scipost.crtype",
455 "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.",
457 (
const char *)
"median",
459 (
const char *)
"iraf",
460 (
const char *)
"mean",
461 (
const char *)
"median");
462 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"crtype");
463 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"crtype");
465 cpl_parameterlist_append(recipe->parameters, p);
468 p = cpl_parameter_new_value(
"muse.muse_scipost.crsigma",
470 "Sigma rejection factor to use for cosmic ray rejection during final resampling. A zero or negative value switches cosmic ray rejection off.",
473 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"crsigma");
474 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"crsigma");
476 cpl_parameterlist_append(recipe->parameters, p);
479 p = cpl_parameter_new_value(
"muse.muse_scipost.rc",
481 "Critical radius for the \"renka\" resampling method.",
484 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"rc");
485 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rc");
487 cpl_parameterlist_append(recipe->parameters, p);
490 p = cpl_parameter_new_value(
"muse.muse_scipost.pixfrac",
492 "Pixel down-scaling factor for the \"drizzle\" resampling method. Up to three, comma-separated, floating-point values can be given. If only one value is given, it applies to all dimensions, two values are interpreted as spatial and spectral direction, respectively, while three are taken as horizontal, vertical, and spectral.",
494 (
const char *)
"0.8,0.8");
495 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"pixfrac");
496 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"pixfrac");
498 cpl_parameterlist_append(recipe->parameters, p);
501 p = cpl_parameter_new_value(
"muse.muse_scipost.ld",
503 "Number of adjacent pixels to take into account during resampling in all three directions (loop distance); this affects all resampling methods except \"nearest\".",
506 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"ld");
507 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ld");
509 cpl_parameterlist_append(recipe->parameters, p);
512 p = cpl_parameter_new_enum(
"muse.muse_scipost.format",
514 "Type of output file format, \"Cube\" is a standard FITS cube with NAXIS=3 and multiple extensions (for data and variance). The extended \"x\" formats include the reconstructed image(s) in FITS image extensions within the same file. \"sdpCube\" does some extra calculations to create FITS keywords for the ESO Science Data Products.",
516 (
const char *)
"Cube",
518 (
const char *)
"Cube",
519 (
const char *)
"Euro3D",
520 (
const char *)
"xCube",
521 (
const char *)
"xEuro3D",
522 (
const char *)
"sdpCube");
523 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"format");
524 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"format");
526 cpl_parameterlist_append(recipe->parameters, p);
529 p = cpl_parameter_new_enum(
"muse.muse_scipost.weight",
531 "Type of weighting scheme to use when combining multiple exposures. \"exptime\" just uses the exposure time to weight the exposures, \"fwhm\" uses the best available seeing information from the headers as well, \"none\" preserves an existing weight column in the input pixel tables without changes.",
533 (
const char *)
"exptime",
535 (
const char *)
"exptime",
536 (
const char *)
"fwhm",
537 (
const char *)
"none");
538 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"weight");
539 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"weight");
541 cpl_parameterlist_append(recipe->parameters, p);
544 p = cpl_parameter_new_value(
"muse.muse_scipost.filter",
546 "The filter name(s) to be used for the output field-of-view image. Each name has to correspond to an EXTNAME in an extension of the FILTER_LIST file. If an unsupported filter name is given, creation of the respective image is omitted. If multiple filter names are given, they have to be comma separated.",
548 (
const char *)
"white");
549 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"filter");
550 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"filter");
552 cpl_parameterlist_append(recipe->parameters, p);
562 p = cpl_parameter_new_enum(
"muse.muse_scipost.skymethod",
564 "The method used to subtract the sky background (spectrum). Option \"model\" should work in all kinds of science fields: it uses a global sky spectrum model with a local LSF. \"model\" uses fluxes indicated in the SKY_LINES file as starting estimates, but re-fits them on the global sky spectrum created from the science exposure. If SKY_CONTINUUM is given, it is directly subtracted, otherwise it is created from the sky region of the science exposure. Option \"subtract-model\" uses the input SKY_LINES and SKY_CONTINUUM, subtracting them directly without re-fitting the fluxes, but still makes use of the local LSF, hence LSF_PROFILE is required. The inputs LSF_PROFILE and SKY_LINES are necessary for these two model-based methods; SKY_CONTINUUM is required for \"subtract-model\" and optional for \"model\"; SKY_MASK is optional for \"model\". Finally, option \"simple\" creates a sky spectrum from the science data, and directly subtracts it, without taking the LSF into account (LSF_PROFILE and input SKY files are ignored). It works on data that was not flux calibrated.",
566 (
const char *)
"model",
568 (
const char *)
"none",
569 (
const char *)
"subtract-model",
570 (
const char *)
"model",
571 (
const char *)
"simple");
572 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"skymethod");
573 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skymethod");
575 cpl_parameterlist_append(recipe->parameters, p);
578 p = cpl_parameter_new_value(
"muse.muse_scipost.lambdamin",
580 "Cut off the data below this wavelength after loading the pixel table(s).",
583 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"lambdamin");
584 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lambdamin");
586 cpl_parameterlist_append(recipe->parameters, p);
589 p = cpl_parameter_new_value(
"muse.muse_scipost.lambdamax",
591 "Cut off the data above this wavelength after loading the pixel table(s).",
594 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"lambdamax");
595 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lambdamax");
597 cpl_parameterlist_append(recipe->parameters, p);
600 p = cpl_parameter_new_value(
"muse.muse_scipost.lambdaref",
602 "Reference wavelength used for correction of differential atmospheric refraction. The R-band (peak wavelength ~7000 Angstrom) that is usually used for guiding, is close to the central wavelength of MUSE, so a value of 7000.0 Angstrom should be used if nothing else is known. A value less than zero switches DAR correction off.",
605 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"lambdaref");
606 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lambdaref");
608 cpl_parameterlist_append(recipe->parameters, p);
611 p = cpl_parameter_new_enum(
"muse.muse_scipost.darcheck",
613 "Carry out a check of the theoretical DAR correction using source centroiding. If \"correct\" it will also apply an empirical correction.",
615 (
const char *)
"none",
617 (
const char *)
"none",
618 (
const char *)
"check",
619 (
const char *)
"correct");
620 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"darcheck");
621 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"darcheck");
623 cpl_parameterlist_append(recipe->parameters, p);
626 p = cpl_parameter_new_value(
"muse.muse_scipost.skymodel_fraction",
628 "Fraction of the image (without the ignored part) to be considered as sky. If an input sky mask is provided, the fraction is applied to the regions within the mask. If the whole sky mask should be used, set this parameter to 1.",
631 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"skymodel_fraction");
632 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skymodel_fraction");
634 cpl_parameterlist_append(recipe->parameters, p);
637 p = cpl_parameter_new_value(
"muse.muse_scipost.skymodel_ignore",
639 "Fraction of the image to be ignored. If an input sky mask is provided, the fraction is applied to the regions within the mask. If the whole sky mask should be used, set this parameter to 0.",
642 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"skymodel_ignore");
643 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skymodel_ignore");
645 cpl_parameterlist_append(recipe->parameters, p);
648 p = cpl_parameter_new_value(
"muse.muse_scipost.skymodel_sampling",
650 "Spectral sampling of the sky spectrum [Angstrom].",
653 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"skymodel_sampling");
654 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skymodel_sampling");
655 if (!getenv(
"MUSE_EXPERT_USER")) {
656 cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
659 cpl_parameterlist_append(recipe->parameters, p);
662 p = cpl_parameter_new_value(
"muse.muse_scipost.skymodel_csampling",
664 "Spectral sampling of the continuum spectrum [Angstrom].",
667 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"skymodel_csampling");
668 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"skymodel_csampling");
669 if (!getenv(
"MUSE_EXPERT_USER")) {
670 cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
673 cpl_parameterlist_append(recipe->parameters, p);
676 p = cpl_parameter_new_value(
"muse.muse_scipost.sky_crsigma",
678 "Sigma level clipping for cube-based and spectrum-based CR rejection when creating the sky spectrum. This has to be a string of two comma-separated floating-point numbers. The first value gives the sigma-level rejection for cube-based CR rejection (using \"median\"), the second value the sigma-level for spectrum-based CR cleaning. Both can be switched off, by passing zero or a negative value; by default, the spectrum-based rejection is switched off.",
680 (
const char *)
"15.,15.");
681 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"sky_crsigma");
682 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky_crsigma");
683 if (!getenv(
"MUSE_EXPERT_USER")) {
684 cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
687 cpl_parameterlist_append(recipe->parameters, p);
690 p = cpl_parameter_new_enum(
"muse.muse_scipost.rvcorr",
692 "Correct the radial velocity of the telescope with reference to either the barycenter of the Solar System (bary), the center of the Sun (helio), or to the center of the Earth (geo).",
694 (
const char *)
"bary",
696 (
const char *)
"bary",
697 (
const char *)
"helio",
699 (
const char *)
"none");
700 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"rvcorr");
701 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rvcorr");
703 cpl_parameterlist_append(recipe->parameters, p);
706 p = cpl_parameter_new_value(
"muse.muse_scipost.astrometry",
708 "If false, skip any astrometric calibration, even if one was passed in the input set of files. This causes creation of an output cube with a linear WCS and may result in errors. If you want to use a sensible default, leave this true but do not pass an ASTROMETRY_WCS.",
711 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG,
"astrometry");
712 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"astrometry");
714 cpl_parameterlist_append(recipe->parameters, p);
734 cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
735 cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
738 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.save");
739 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
740 aParams->
save = cpl_parameter_get_string(p);
742 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.resample");
743 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
744 aParams->
resample_s = cpl_parameter_get_string(p);
746 (!strcasecmp(aParams->
resample_s,
"nearest")) ? MUSE_SCIPOST_PARAM_RESAMPLE_NEAREST :
747 (!strcasecmp(aParams->
resample_s,
"linear")) ? MUSE_SCIPOST_PARAM_RESAMPLE_LINEAR :
748 (!strcasecmp(aParams->
resample_s,
"quadratic")) ? MUSE_SCIPOST_PARAM_RESAMPLE_QUADRATIC :
749 (!strcasecmp(aParams->
resample_s,
"renka")) ? MUSE_SCIPOST_PARAM_RESAMPLE_RENKA :
750 (!strcasecmp(aParams->
resample_s,
"drizzle")) ? MUSE_SCIPOST_PARAM_RESAMPLE_DRIZZLE :
751 (!strcasecmp(aParams->
resample_s,
"lanczos")) ? MUSE_SCIPOST_PARAM_RESAMPLE_LANCZOS :
752 MUSE_SCIPOST_PARAM_RESAMPLE_INVALID_VALUE;
753 cpl_ensure_code(aParams->
resample != MUSE_SCIPOST_PARAM_RESAMPLE_INVALID_VALUE,
754 CPL_ERROR_ILLEGAL_INPUT);
756 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.dx");
757 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
758 aParams->
dx = cpl_parameter_get_double(p);
760 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.dy");
761 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
762 aParams->
dy = cpl_parameter_get_double(p);
764 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.dlambda");
765 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
766 aParams->
dlambda = cpl_parameter_get_double(p);
768 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.crtype");
769 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
770 aParams->
crtype_s = cpl_parameter_get_string(p);
772 (!strcasecmp(aParams->
crtype_s,
"iraf")) ? MUSE_SCIPOST_PARAM_CRTYPE_IRAF :
773 (!strcasecmp(aParams->
crtype_s,
"mean")) ? MUSE_SCIPOST_PARAM_CRTYPE_MEAN :
774 (!strcasecmp(aParams->
crtype_s,
"median")) ? MUSE_SCIPOST_PARAM_CRTYPE_MEDIAN :
775 MUSE_SCIPOST_PARAM_CRTYPE_INVALID_VALUE;
776 cpl_ensure_code(aParams->
crtype != MUSE_SCIPOST_PARAM_CRTYPE_INVALID_VALUE,
777 CPL_ERROR_ILLEGAL_INPUT);
779 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.crsigma");
780 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
781 aParams->
crsigma = cpl_parameter_get_double(p);
783 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.rc");
784 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
785 aParams->
rc = cpl_parameter_get_double(p);
787 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.pixfrac");
788 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
789 aParams->
pixfrac = cpl_parameter_get_string(p);
791 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.ld");
792 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
793 aParams->
ld = cpl_parameter_get_int(p);
795 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.format");
796 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
797 aParams->
format_s = cpl_parameter_get_string(p);
799 (!strcasecmp(aParams->
format_s,
"Cube")) ? MUSE_SCIPOST_PARAM_FORMAT_CUBE :
800 (!strcasecmp(aParams->
format_s,
"Euro3D")) ? MUSE_SCIPOST_PARAM_FORMAT_EURO3D :
801 (!strcasecmp(aParams->
format_s,
"xCube")) ? MUSE_SCIPOST_PARAM_FORMAT_XCUBE :
802 (!strcasecmp(aParams->
format_s,
"xEuro3D")) ? MUSE_SCIPOST_PARAM_FORMAT_XEURO3D :
803 (!strcasecmp(aParams->
format_s,
"sdpCube")) ? MUSE_SCIPOST_PARAM_FORMAT_SDPCUBE :
804 MUSE_SCIPOST_PARAM_FORMAT_INVALID_VALUE;
805 cpl_ensure_code(aParams->
format != MUSE_SCIPOST_PARAM_FORMAT_INVALID_VALUE,
806 CPL_ERROR_ILLEGAL_INPUT);
808 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.weight");
809 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
810 aParams->
weight_s = cpl_parameter_get_string(p);
812 (!strcasecmp(aParams->
weight_s,
"exptime")) ? MUSE_SCIPOST_PARAM_WEIGHT_EXPTIME :
813 (!strcasecmp(aParams->
weight_s,
"fwhm")) ? MUSE_SCIPOST_PARAM_WEIGHT_FWHM :
814 (!strcasecmp(aParams->
weight_s,
"none")) ? MUSE_SCIPOST_PARAM_WEIGHT_NONE :
815 MUSE_SCIPOST_PARAM_WEIGHT_INVALID_VALUE;
816 cpl_ensure_code(aParams->
weight != MUSE_SCIPOST_PARAM_WEIGHT_INVALID_VALUE,
817 CPL_ERROR_ILLEGAL_INPUT);
819 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.filter");
820 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
821 aParams->
filter = cpl_parameter_get_string(p);
823 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.skymethod");
824 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
825 aParams->
skymethod_s = cpl_parameter_get_string(p);
827 (!strcasecmp(aParams->
skymethod_s,
"none")) ? MUSE_SCIPOST_PARAM_SKYMETHOD_NONE :
828 (!strcasecmp(aParams->
skymethod_s,
"subtract-model")) ? MUSE_SCIPOST_PARAM_SKYMETHOD_SUBTRACT_MODEL :
829 (!strcasecmp(aParams->
skymethod_s,
"model")) ? MUSE_SCIPOST_PARAM_SKYMETHOD_MODEL :
830 (!strcasecmp(aParams->
skymethod_s,
"simple")) ? MUSE_SCIPOST_PARAM_SKYMETHOD_SIMPLE :
831 MUSE_SCIPOST_PARAM_SKYMETHOD_INVALID_VALUE;
832 cpl_ensure_code(aParams->
skymethod != MUSE_SCIPOST_PARAM_SKYMETHOD_INVALID_VALUE,
833 CPL_ERROR_ILLEGAL_INPUT);
835 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.lambdamin");
836 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
837 aParams->
lambdamin = cpl_parameter_get_double(p);
839 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.lambdamax");
840 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
841 aParams->
lambdamax = cpl_parameter_get_double(p);
843 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.lambdaref");
844 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
845 aParams->
lambdaref = cpl_parameter_get_double(p);
847 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.darcheck");
848 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
849 aParams->
darcheck_s = cpl_parameter_get_string(p);
851 (!strcasecmp(aParams->
darcheck_s,
"none")) ? MUSE_SCIPOST_PARAM_DARCHECK_NONE :
852 (!strcasecmp(aParams->
darcheck_s,
"check")) ? MUSE_SCIPOST_PARAM_DARCHECK_CHECK :
853 (!strcasecmp(aParams->
darcheck_s,
"correct")) ? MUSE_SCIPOST_PARAM_DARCHECK_CORRECT :
854 MUSE_SCIPOST_PARAM_DARCHECK_INVALID_VALUE;
855 cpl_ensure_code(aParams->
darcheck != MUSE_SCIPOST_PARAM_DARCHECK_INVALID_VALUE,
856 CPL_ERROR_ILLEGAL_INPUT);
858 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.skymodel_fraction");
859 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
862 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.skymodel_ignore");
863 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
866 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.skymodel_sampling");
867 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
870 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.skymodel_csampling");
871 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
874 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.sky_crsigma");
875 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
876 aParams->
sky_crsigma = cpl_parameter_get_string(p);
878 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.rvcorr");
879 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
880 aParams->
rvcorr_s = cpl_parameter_get_string(p);
882 (!strcasecmp(aParams->
rvcorr_s,
"bary")) ? MUSE_SCIPOST_PARAM_RVCORR_BARY :
883 (!strcasecmp(aParams->
rvcorr_s,
"helio")) ? MUSE_SCIPOST_PARAM_RVCORR_HELIO :
884 (!strcasecmp(aParams->
rvcorr_s,
"geo")) ? MUSE_SCIPOST_PARAM_RVCORR_GEO :
885 (!strcasecmp(aParams->
rvcorr_s,
"none")) ? MUSE_SCIPOST_PARAM_RVCORR_NONE :
886 MUSE_SCIPOST_PARAM_RVCORR_INVALID_VALUE;
887 cpl_ensure_code(aParams->
rvcorr != MUSE_SCIPOST_PARAM_RVCORR_INVALID_VALUE,
888 CPL_ERROR_ILLEGAL_INPUT);
890 p = cpl_parameterlist_find(aParameters,
"muse.muse_scipost.astrometry");
891 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
892 aParams->
astrometry = cpl_parameter_get_bool(p);
906 muse_scipost_exec(cpl_plugin *aPlugin)
908 if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
912 cpl_recipe *recipe = (cpl_recipe *)aPlugin;
913 cpl_msg_set_threadid_on();
915 cpl_frameset *usedframes = cpl_frameset_new(),
916 *outframes = cpl_frameset_new();
918 muse_scipost_params_fill(¶ms, recipe->parameters);
920 cpl_errorstate prestate = cpl_errorstate_get();
924 int rc = muse_scipost_compute(proc, ¶ms);
925 cpl_frameset_join(usedframes, proc->
usedframes);
926 cpl_frameset_join(outframes, proc->
outframes);
929 if (!cpl_errorstate_is_equal(prestate)) {
933 cpl_msg_set_level(CPL_MSG_INFO);
944 cpl_frameset_join(recipe->frames, usedframes);
945 cpl_frameset_join(recipe->frames, outframes);
946 cpl_frameset_delete(usedframes);
947 cpl_frameset_delete(outframes);
960 muse_scipost_destroy(cpl_plugin *aPlugin)
964 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
965 recipe = (cpl_recipe *)aPlugin;
971 cpl_parameterlist_delete(recipe->parameters);
988 cpl_plugin_get_info(cpl_pluginlist *aList)
990 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe);
991 cpl_plugin *plugin = &recipe->interface;
995 helptext = cpl_sprintf(
"%s%s", muse_scipost_help,
996 muse_scipost_help_esorex);
998 helptext = cpl_sprintf(
"%s", muse_scipost_help);
1002 cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
1003 CPL_PLUGIN_TYPE_RECIPE,
1005 "Prepare reduced and combined science products.",
1010 muse_scipost_create,
1012 muse_scipost_destroy);
1013 cpl_pluginlist_append(aList, plugin);
void muse_processing_delete(muse_processing *aProcessing)
Free the muse_processing structure.
int rvcorr
Correct the radial velocity of the telescope with reference to either the barycenter of the Solar Sys...
double lambdamin
Cut off the data below this wavelength after loading the pixel table(s).
const char * skymethod_s
The method used to subtract the sky background (spectrum). Option "model" should work in all kinds of...
const char * darcheck_s
Carry out a check of the theoretical DAR correction using source centroiding. If "correct" it will al...
double skymodel_ignore
Fraction of the image to be ignored. If an input sky mask is provided, the fraction is applied to the...
muse_cplframework_type muse_cplframework(void)
Return the CPL framework the recipe is run under.
int ld
Number of adjacent pixels to take into account during resampling in all three directions (loop distan...
const char * rvcorr_s
Correct the radial velocity of the telescope with reference to either the barycenter of the Solar Sys...
const char * pixfrac
Pixel down-scaling factor for the "drizzle" resampling method. Up to three, comma-separated, floating-point values can be given. If only one value is given, it applies to all dimensions, two values are interpreted as spatial and spectral direction, respectively, while three are taken as horizontal, vertical, and spectral.
const char * sky_crsigma
Sigma level clipping for cube-based and spectrum-based CR rejection when creating the sky spectrum...
const char * filter
The filter name(s) to be used for the output field-of-view image. Each name has to correspond to an E...
cpl_frameset * usedframes
muse_processing * muse_processing_new(const char *aName, cpl_recipe *aRecipe)
Create a new processing structure.
const char * weight_s
Type of weighting scheme to use when combining multiple exposures. "exptime" just uses the exposure t...
const char * muse_get_license(void)
Get the pipeline copyright and license.
double dy
Vertical step size for resampling (in arcsec or pixel). The following defaults are taken when this va...
double lambdaref
Reference wavelength used for correction of differential atmospheric refraction. The R-band (peak wav...
double rc
Critical radius for the "renka" resampling method.
double skymodel_fraction
Fraction of the image (without the ignored part) to be considered as sky. If an input sky mask is pro...
void muse_cplerrorstate_dump_some(unsigned aCurrent, unsigned aFirst, unsigned aLast)
Dump some CPL errors.
const char * crtype_s
Type of statistics used for detection of cosmic rays during final resampling. "iraf" uses the varianc...
void muse_processinginfo_delete(cpl_recipe *)
Clear all information from the processing info and from the recipe config.
int darcheck
Carry out a check of the theoretical DAR correction using source centroiding. If "correct" it will al...
double skymodel_sampling
Spectral sampling of the sky spectrum [Angstrom].
int astrometry
If false, skip any astrometric calibration, even if one was passed in the input set of files...
double skymodel_csampling
Spectral sampling of the continuum spectrum [Angstrom].
int weight
Type of weighting scheme to use when combining multiple exposures. "exptime" just uses the exposure t...
const char * format_s
Type of output file format, "Cube" is a standard FITS cube with NAXIS=3 and multiple extensions (for ...
double lambdamax
Cut off the data above this wavelength after loading the pixel table(s).
cpl_error_code muse_cplframeset_erase_duplicate(cpl_frameset *aFrames)
Erase all duplicate frames from a frameset.
double dx
Horizontal step size for resampling (in arcsec or pixel). The following defaults are taken when this ...
cpl_error_code muse_cplframeset_erase_all(cpl_frameset *aFrames)
Erase all frames in a frameset.
int skymethod
The method used to subtract the sky background (spectrum). Option "model" should work in all kinds of...
Structure to hold the parameters of the muse_scipost recipe.
double crsigma
Sigma rejection factor to use for cosmic ray rejection during final resampling. A zero or negative va...
int resample
The resampling technique to use for the final output cube.
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.
void muse_processing_recipeinfo(cpl_plugin *)
Output main pipeline configuration, inputs, and parameters.
double dlambda
Wavelength step size (in Angstrom). Natural instrument sampling is used, if this is 0...
int format
Type of output file format, "Cube" is a standard FITS cube with NAXIS=3 and multiple extensions (for ...
const char * resample_s
The resampling technique to use for the final output cube. (as string)
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 * save
Select output product(s) to save. Can contain one or more of "cube", "skymodel", "individual", "positioned", "combined", and "stacked". If several options are given, they have to be comma-separated. ("cube": output cube and associated images, if this is not given, no final resampling is done at all – "skymodel": up to four additional output products about the effectively used sky that was subtracted with the "model" method – "individual": fully reduced pixel table for each individual exposure – "positioned": fully reduced and positioned pixel table for each individual exposure, the difference to "individual" is that here, the output pixel tables have coordinates in RA and DEC; this is only useful, if both the relative exposure weighting and the final resampling are to be done externally – "combined": fully reduced and combined pixel table for the full set of exposures, the difference to "positioned" is that all pixel tables are combined into one, with an added weight column; this is useful, if only the final resampling step is to be done separately – "stacked": an additional output file in form of a 2D column-stacked image, i.e. x direction is pseudo-spatial, y direction is wavelength.)