MUSE Pipeline Reference Manual  2.1.1
muse_scipost_z.c
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set sw=2 sts=2 et cin: */
3 /*
4  * This file is part of the MUSE Instrument Pipeline
5  * Copyright (C) 2005-2015 European Southern Observatory
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21 
22 /* This file was automatically generated */
23 
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 
28 /*----------------------------------------------------------------------------*
29  * Includes *
30  *----------------------------------------------------------------------------*/
31 #include <string.h> /* strcmp(), strstr() */
32 #include <strings.h> /* strcasecmp() */
33 #include <cpl.h>
34 
35 #include "muse_scipost_z.h" /* in turn includes muse.h */
36 
37 /*----------------------------------------------------------------------------*/
81 /*----------------------------------------------------------------------------*/
84 /*----------------------------------------------------------------------------*
85  * Static variables *
86  *----------------------------------------------------------------------------*/
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.";
89 
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\")";
119 
120 /*----------------------------------------------------------------------------*/
128 /*----------------------------------------------------------------------------*/
129 static cpl_recipeconfig *
130 muse_scipost_new_recipeconfig(void)
131 {
132  cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
133 
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");
150 
151  return recipeconfig;
152 } /* muse_scipost_new_recipeconfig() */
153 
154 /*----------------------------------------------------------------------------*/
164 /*----------------------------------------------------------------------------*/
165 static cpl_error_code
166 muse_scipost_prepare_header(const char *aFrametag, cpl_propertylist *aHeader)
167 {
168  cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
169  cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
170  if (!strcmp(aFrametag, "DATACUBE_FINAL")) {
171  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST NDET",
172  CPL_TYPE_INT,
173  "Number of detected sources in output cube.");
174  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST LAMBDA",
175  CPL_TYPE_FLOAT,
176  "[Angstrom] Wavelength of plane in combined cube that was used for object detection.");
177  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST POS[0-9]+ X",
178  CPL_TYPE_FLOAT,
179  "[pix] Position of source k in x-direction in output cube. If the FWHM measurement fails, this value will be -1.");
180  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST POS[0-9]+ Y",
181  CPL_TYPE_FLOAT,
182  "[pix] Position of source k in y-direction in output cube. If the FWHM measurement fails, this value will be -1.");
183  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST FWHM[0-9]+ X",
184  CPL_TYPE_FLOAT,
185  "[arcsec] FWHM of source k in x-direction in output cube. If the FWHM measurement fails, this value will be -1.");
186  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST FWHM[0-9]+ Y",
187  CPL_TYPE_FLOAT,
188  "[arcsec] FWHM of source k in y-direction in output cube. If the FWHM measurement fails, this value will be -1.");
189  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST FWHM NVALID",
190  CPL_TYPE_INT,
191  "Number of detected sources with valid FWHM in output cube.");
192  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST FWHM MEDIAN",
193  CPL_TYPE_FLOAT,
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.");
195  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST FWHM MAD",
196  CPL_TYPE_FLOAT,
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")) {
199  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST POS[0-9]+ X",
200  CPL_TYPE_FLOAT,
201  "[pix] Position of source k in x-direction in combined frame");
202  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST POS[0-9]+ Y",
203  CPL_TYPE_FLOAT,
204  "[pix] Position of source k in y-direction in combined frame");
205  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST FWHM[0-9]+ X",
206  CPL_TYPE_FLOAT,
207  "[arcsec] FWHM of source k in x-direction in combined frame");
208  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST FWHM[0-9]+ Y",
209  CPL_TYPE_FLOAT,
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")) {
216  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST THRESHOLD",
217  CPL_TYPE_DOUBLE,
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")) {
221  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST LINE[0-9]+ NAME",
222  CPL_TYPE_STRING,
223  "Name of the strongest line in group l");
224  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST LINE[0-9]+ AWAV",
225  CPL_TYPE_DOUBLE,
226  "[Angstrom] Wavelength (air) of the strongest line of group l");
227  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST LINE[0-9]+ FLUX",
228  CPL_TYPE_DOUBLE,
229  "[erg/(s cm2 arcsec2)] Flux of the strongest line of group l");
230  } else if (!strcmp(aFrametag, "SKY_CONTINUUM")) {
231  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST CONT FLUX",
232  CPL_TYPE_DOUBLE,
233  "[erg/(s cm2 arcsec2)] Total flux of the continuum");
234  muse_processing_prepare_property(aHeader, "ESO QC SCIPOST CONT MAXDEV",
235  CPL_TYPE_DOUBLE,
236  "[erg/(s cm2 arcsec2 Angstrom)] Maximum (absolute value) of the derivative of the continuum spectrum");
237  } else {
238  cpl_msg_warning(__func__, "Frame tag %s is not defined", aFrametag);
239  return CPL_ERROR_ILLEGAL_INPUT;
240  }
241  return CPL_ERROR_NONE;
242 } /* muse_scipost_prepare_header() */
243 
244 /*----------------------------------------------------------------------------*/
253 /*----------------------------------------------------------------------------*/
254 static cpl_frame_level
255 muse_scipost_get_frame_level(const char *aFrametag)
256 {
257  if (!aFrametag) {
258  return CPL_FRAME_LEVEL_NONE;
259  }
260  if (!strcmp(aFrametag, "DATACUBE_FINAL")) {
261  return CPL_FRAME_LEVEL_FINAL;
262  }
263  if (!strcmp(aFrametag, "IMAGE_FOV")) {
264  return CPL_FRAME_LEVEL_FINAL;
265  }
266  if (!strcmp(aFrametag, "OBJECT_RESAMPLED")) {
267  return CPL_FRAME_LEVEL_FINAL;
268  }
269  if (!strcmp(aFrametag, "PIXTABLE_REDUCED")) {
270  return CPL_FRAME_LEVEL_INTERMEDIATE;
271  }
272  if (!strcmp(aFrametag, "PIXTABLE_POSITIONED")) {
273  return CPL_FRAME_LEVEL_INTERMEDIATE;
274  }
275  if (!strcmp(aFrametag, "PIXTABLE_COMBINED")) {
276  return CPL_FRAME_LEVEL_INTERMEDIATE;
277  }
278  if (!strcmp(aFrametag, "SKY_MASK")) {
279  return CPL_FRAME_LEVEL_INTERMEDIATE;
280  }
281  if (!strcmp(aFrametag, "SKY_SPECTRUM")) {
282  return CPL_FRAME_LEVEL_INTERMEDIATE;
283  }
284  if (!strcmp(aFrametag, "SKY_LINES")) {
285  return CPL_FRAME_LEVEL_FINAL;
286  }
287  if (!strcmp(aFrametag, "SKY_CONTINUUM")) {
288  return CPL_FRAME_LEVEL_FINAL;
289  }
290  return CPL_FRAME_LEVEL_NONE;
291 } /* muse_scipost_get_frame_level() */
292 
293 /*----------------------------------------------------------------------------*/
302 /*----------------------------------------------------------------------------*/
303 static muse_frame_mode
304 muse_scipost_get_frame_mode(const char *aFrametag)
305 {
306  if (!aFrametag) {
307  return MUSE_FRAME_MODE_ALL;
308  }
309  if (!strcmp(aFrametag, "DATACUBE_FINAL")) {
310  return MUSE_FRAME_MODE_MASTER;
311  }
312  if (!strcmp(aFrametag, "IMAGE_FOV")) {
314  }
315  if (!strcmp(aFrametag, "OBJECT_RESAMPLED")) {
316  return MUSE_FRAME_MODE_MASTER;
317  }
318  if (!strcmp(aFrametag, "PIXTABLE_REDUCED")) {
320  }
321  if (!strcmp(aFrametag, "PIXTABLE_POSITIONED")) {
323  }
324  if (!strcmp(aFrametag, "PIXTABLE_COMBINED")) {
325  return MUSE_FRAME_MODE_MASTER;
326  }
327  if (!strcmp(aFrametag, "SKY_MASK")) {
329  }
330  if (!strcmp(aFrametag, "SKY_SPECTRUM")) {
332  }
333  if (!strcmp(aFrametag, "SKY_LINES")) {
335  }
336  if (!strcmp(aFrametag, "SKY_CONTINUUM")) {
338  }
339  return MUSE_FRAME_MODE_ALL;
340 } /* muse_scipost_get_frame_mode() */
341 
342 /*----------------------------------------------------------------------------*/
352 /*----------------------------------------------------------------------------*/
353 static int
354 muse_scipost_create(cpl_plugin *aPlugin)
355 {
356  /* Check that the plugin is part of a valid recipe */
357  cpl_recipe *recipe;
358  if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
359  recipe = (cpl_recipe *)aPlugin;
360  } else {
361  return -1;
362  }
363 
364  /* register the extended processing information (new FITS header creation, *
365  * getting of the frame level for a certain tag) */
367  muse_scipost_new_recipeconfig(),
368  muse_scipost_prepare_header,
369  muse_scipost_get_frame_level,
370  muse_scipost_get_frame_mode);
371 
372  /* XXX initialize timing in messages *
373  * since at least esorex is too stupid to turn it on, we have to do it */
375  cpl_msg_set_time_on();
376  }
377 
378  /* Create the parameter list in the cpl_recipe object */
379  recipe->parameters = cpl_parameterlist_new();
380  /* Fill the parameters list */
381  cpl_parameter *p;
382 
383  /* --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.
384  ("cube": output cube and associated images, if this is not given, no final resampling is done at all --
385  "skymodel": up to four additional output products about the effectively used sky that was subtracted with the "model" method --
386  "individual": fully reduced pixel table for each individual exposure --
387  "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 --
388  "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 --
389  "stacked": an additional output file in form of a 2D column-stacked image, i.e. x direction is pseudo-spatial, y direction is wavelength.)
390  */
391  p = cpl_parameter_new_value("muse.muse_scipost.save",
392  CPL_TYPE_STRING,
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.)",
394  "muse.muse_scipost",
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");
398 
399  cpl_parameterlist_append(recipe->parameters, p);
400 
401  /* --resample: The resampling technique to use for the final output cube. */
402  p = cpl_parameter_new_enum("muse.muse_scipost.resample",
403  CPL_TYPE_STRING,
404  "The resampling technique to use for the final output cube.",
405  "muse.muse_scipost",
406  (const char *)"drizzle",
407  6,
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");
416 
417  cpl_parameterlist_append(recipe->parameters, p);
418 
419  /* --dx: 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. */
420  p = cpl_parameter_new_value("muse.muse_scipost.dx",
421  CPL_TYPE_DOUBLE,
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.",
423  "muse.muse_scipost",
424  (double)0.0);
425  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "dx");
426  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dx");
427 
428  cpl_parameterlist_append(recipe->parameters, p);
429 
430  /* --dy: 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. */
431  p = cpl_parameter_new_value("muse.muse_scipost.dy",
432  CPL_TYPE_DOUBLE,
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.",
434  "muse.muse_scipost",
435  (double)0.0);
436  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "dy");
437  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dy");
438 
439  cpl_parameterlist_append(recipe->parameters, p);
440 
441  /* --dlambda: Wavelength step size (in Angstrom). Natural instrument sampling is used, if this is 0.0 */
442  p = cpl_parameter_new_value("muse.muse_scipost.dlambda",
443  CPL_TYPE_DOUBLE,
444  "Wavelength step size (in Angstrom). Natural instrument sampling is used, if this is 0.0",
445  "muse.muse_scipost",
446  (double)0.0);
447  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "dlambda");
448  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dlambda");
449 
450  cpl_parameterlist_append(recipe->parameters, p);
451 
452  /* --crtype: 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. */
453  p = cpl_parameter_new_enum("muse.muse_scipost.crtype",
454  CPL_TYPE_STRING,
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.",
456  "muse.muse_scipost",
457  (const char *)"median",
458  3,
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");
464 
465  cpl_parameterlist_append(recipe->parameters, p);
466 
467  /* --crsigma: Sigma rejection factor to use for cosmic ray rejection during final resampling. A zero or negative value switches cosmic ray rejection off. */
468  p = cpl_parameter_new_value("muse.muse_scipost.crsigma",
469  CPL_TYPE_DOUBLE,
470  "Sigma rejection factor to use for cosmic ray rejection during final resampling. A zero or negative value switches cosmic ray rejection off.",
471  "muse.muse_scipost",
472  (double)15.);
473  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "crsigma");
474  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "crsigma");
475 
476  cpl_parameterlist_append(recipe->parameters, p);
477 
478  /* --rc: Critical radius for the "renka" resampling method. */
479  p = cpl_parameter_new_value("muse.muse_scipost.rc",
480  CPL_TYPE_DOUBLE,
481  "Critical radius for the \"renka\" resampling method.",
482  "muse.muse_scipost",
483  (double)1.25);
484  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "rc");
485  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "rc");
486 
487  cpl_parameterlist_append(recipe->parameters, p);
488 
489  /* --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. */
490  p = cpl_parameter_new_value("muse.muse_scipost.pixfrac",
491  CPL_TYPE_STRING,
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.",
493  "muse.muse_scipost",
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");
497 
498  cpl_parameterlist_append(recipe->parameters, p);
499 
500  /* --ld: Number of adjacent pixels to take into account during resampling in all three directions (loop distance); this affects all resampling methods except "nearest". */
501  p = cpl_parameter_new_value("muse.muse_scipost.ld",
502  CPL_TYPE_INT,
503  "Number of adjacent pixels to take into account during resampling in all three directions (loop distance); this affects all resampling methods except \"nearest\".",
504  "muse.muse_scipost",
505  (int)1);
506  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ld");
507  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ld");
508 
509  cpl_parameterlist_append(recipe->parameters, p);
510 
511  /* --format: 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. */
512  p = cpl_parameter_new_enum("muse.muse_scipost.format",
513  CPL_TYPE_STRING,
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.",
515  "muse.muse_scipost",
516  (const char *)"Cube",
517  5,
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");
525 
526  cpl_parameterlist_append(recipe->parameters, p);
527 
528  /* --weight: 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. */
529  p = cpl_parameter_new_enum("muse.muse_scipost.weight",
530  CPL_TYPE_STRING,
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.",
532  "muse.muse_scipost",
533  (const char *)"exptime",
534  3,
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");
540 
541  cpl_parameterlist_append(recipe->parameters, p);
542 
543  /* --filter: 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. */
544  p = cpl_parameter_new_value("muse.muse_scipost.filter",
545  CPL_TYPE_STRING,
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.",
547  "muse.muse_scipost",
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");
551 
552  cpl_parameterlist_append(recipe->parameters, p);
553 
554  /* --skymethod: The method used to subtract the sky background (spectrum).
555  Option "model" should work in all kinds of science fields: it uses a global sky spectrum model with a local LSF.
556  "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.
557  If SKY_CONTINUUM is given, it is directly subtracted, otherwise it is created from the sky region of the science exposure.
558  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.
559  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".
560  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.
561  */
562  p = cpl_parameter_new_enum("muse.muse_scipost.skymethod",
563  CPL_TYPE_STRING,
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.",
565  "muse.muse_scipost",
566  (const char *)"model",
567  4,
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");
574 
575  cpl_parameterlist_append(recipe->parameters, p);
576 
577  /* --lambdamin: Cut off the data below this wavelength after loading the pixel table(s). */
578  p = cpl_parameter_new_value("muse.muse_scipost.lambdamin",
579  CPL_TYPE_DOUBLE,
580  "Cut off the data below this wavelength after loading the pixel table(s).",
581  "muse.muse_scipost",
582  (double)4000.);
583  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdamin");
584  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdamin");
585 
586  cpl_parameterlist_append(recipe->parameters, p);
587 
588  /* --lambdamax: Cut off the data above this wavelength after loading the pixel table(s). */
589  p = cpl_parameter_new_value("muse.muse_scipost.lambdamax",
590  CPL_TYPE_DOUBLE,
591  "Cut off the data above this wavelength after loading the pixel table(s).",
592  "muse.muse_scipost",
593  (double)10000.);
594  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdamax");
595  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdamax");
596 
597  cpl_parameterlist_append(recipe->parameters, p);
598 
599  /* --lambdaref: 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. */
600  p = cpl_parameter_new_value("muse.muse_scipost.lambdaref",
601  CPL_TYPE_DOUBLE,
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.",
603  "muse.muse_scipost",
604  (double)7000.);
605  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdaref");
606  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdaref");
607 
608  cpl_parameterlist_append(recipe->parameters, p);
609 
610  /* --darcheck: Carry out a check of the theoretical DAR correction using source centroiding. If "correct" it will also apply an empirical correction. */
611  p = cpl_parameter_new_enum("muse.muse_scipost.darcheck",
612  CPL_TYPE_STRING,
613  "Carry out a check of the theoretical DAR correction using source centroiding. If \"correct\" it will also apply an empirical correction.",
614  "muse.muse_scipost",
615  (const char *)"none",
616  3,
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");
622 
623  cpl_parameterlist_append(recipe->parameters, p);
624 
625  /* --skymodel_fraction: 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. */
626  p = cpl_parameter_new_value("muse.muse_scipost.skymodel_fraction",
627  CPL_TYPE_DOUBLE,
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.",
629  "muse.muse_scipost",
630  (double)0.10);
631  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "skymodel_fraction");
632  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "skymodel_fraction");
633 
634  cpl_parameterlist_append(recipe->parameters, p);
635 
636  /* --skymodel_ignore: 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. */
637  p = cpl_parameter_new_value("muse.muse_scipost.skymodel_ignore",
638  CPL_TYPE_DOUBLE,
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.",
640  "muse.muse_scipost",
641  (double)0.05);
642  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "skymodel_ignore");
643  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "skymodel_ignore");
644 
645  cpl_parameterlist_append(recipe->parameters, p);
646 
647  /* --skymodel_sampling: Spectral sampling of the sky spectrum [Angstrom]. */
648  p = cpl_parameter_new_value("muse.muse_scipost.skymodel_sampling",
649  CPL_TYPE_DOUBLE,
650  "Spectral sampling of the sky spectrum [Angstrom].",
651  "muse.muse_scipost",
652  (double)0.3125);
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);
657  }
658 
659  cpl_parameterlist_append(recipe->parameters, p);
660 
661  /* --skymodel_csampling: Spectral sampling of the continuum spectrum [Angstrom]. */
662  p = cpl_parameter_new_value("muse.muse_scipost.skymodel_csampling",
663  CPL_TYPE_DOUBLE,
664  "Spectral sampling of the continuum spectrum [Angstrom].",
665  "muse.muse_scipost",
666  (double)0.3125);
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);
671  }
672 
673  cpl_parameterlist_append(recipe->parameters, p);
674 
675  /* --sky_crsigma: 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. */
676  p = cpl_parameter_new_value("muse.muse_scipost.sky_crsigma",
677  CPL_TYPE_STRING,
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.",
679  "muse.muse_scipost",
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);
685  }
686 
687  cpl_parameterlist_append(recipe->parameters, p);
688 
689  /* --rvcorr: 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). */
690  p = cpl_parameter_new_enum("muse.muse_scipost.rvcorr",
691  CPL_TYPE_STRING,
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).",
693  "muse.muse_scipost",
694  (const char *)"bary",
695  4,
696  (const char *)"bary",
697  (const char *)"helio",
698  (const char *)"geo",
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");
702 
703  cpl_parameterlist_append(recipe->parameters, p);
704 
705  /* --astrometry: 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. */
706  p = cpl_parameter_new_value("muse.muse_scipost.astrometry",
707  CPL_TYPE_BOOL,
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.",
709  "muse.muse_scipost",
710  (int)TRUE);
711  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "astrometry");
712  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "astrometry");
713 
714  cpl_parameterlist_append(recipe->parameters, p);
715 
716  return 0;
717 } /* muse_scipost_create() */
718 
719 /*----------------------------------------------------------------------------*/
730 /*----------------------------------------------------------------------------*/
731 static int
732 muse_scipost_params_fill(muse_scipost_params_t *aParams, cpl_parameterlist *aParameters)
733 {
734  cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
735  cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
736  cpl_parameter *p;
737 
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);
741 
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);
745  aParams->resample =
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);
755 
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);
759 
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);
763 
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);
767 
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);
771  aParams->crtype =
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);
778 
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);
782 
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);
786 
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);
790 
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);
794 
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);
798  aParams->format =
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);
807 
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);
811  aParams->weight =
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);
818 
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);
822 
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);
826  aParams->skymethod =
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);
834 
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);
838 
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);
842 
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);
846 
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);
850  aParams->darcheck =
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);
857 
858  p = cpl_parameterlist_find(aParameters, "muse.muse_scipost.skymodel_fraction");
859  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
860  aParams->skymodel_fraction = cpl_parameter_get_double(p);
861 
862  p = cpl_parameterlist_find(aParameters, "muse.muse_scipost.skymodel_ignore");
863  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
864  aParams->skymodel_ignore = cpl_parameter_get_double(p);
865 
866  p = cpl_parameterlist_find(aParameters, "muse.muse_scipost.skymodel_sampling");
867  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
868  aParams->skymodel_sampling = cpl_parameter_get_double(p);
869 
870  p = cpl_parameterlist_find(aParameters, "muse.muse_scipost.skymodel_csampling");
871  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
872  aParams->skymodel_csampling = cpl_parameter_get_double(p);
873 
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);
877 
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);
881  aParams->rvcorr =
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);
889 
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);
893 
894  return 0;
895 } /* muse_scipost_params_fill() */
896 
897 /*----------------------------------------------------------------------------*/
904 /*----------------------------------------------------------------------------*/
905 static int
906 muse_scipost_exec(cpl_plugin *aPlugin)
907 {
908  if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
909  return -1;
910  }
912  cpl_recipe *recipe = (cpl_recipe *)aPlugin;
913  cpl_msg_set_threadid_on();
914 
915  cpl_frameset *usedframes = cpl_frameset_new(),
916  *outframes = cpl_frameset_new();
917  muse_scipost_params_t params;
918  muse_scipost_params_fill(&params, recipe->parameters);
919 
920  cpl_errorstate prestate = cpl_errorstate_get();
921 
922  muse_processing *proc = muse_processing_new("muse_scipost",
923  recipe);
924  int rc = muse_scipost_compute(proc, &params);
925  cpl_frameset_join(usedframes, proc->usedframes);
926  cpl_frameset_join(outframes, proc->outframes);
928 
929  if (!cpl_errorstate_is_equal(prestate)) {
930  /* dump all errors from this recipe in chronological order */
931  cpl_errorstate_dump(prestate, CPL_FALSE, muse_cplerrorstate_dump_some);
932  /* reset message level to not get the same errors displayed again by esorex */
933  cpl_msg_set_level(CPL_MSG_INFO);
934  }
935  /* clean up duplicates in framesets of used and output frames */
938 
939  /* to get esorex to see our classification (frame groups etc.), *
940  * replace the original frameset with the list of used frames *
941  * before appending product output frames */
942  /* keep the same pointer, so just erase all frames, not delete the frameset */
943  muse_cplframeset_erase_all(recipe->frames);
944  cpl_frameset_join(recipe->frames, usedframes);
945  cpl_frameset_join(recipe->frames, outframes);
946  cpl_frameset_delete(usedframes);
947  cpl_frameset_delete(outframes);
948  return rc;
949 } /* muse_scipost_exec() */
950 
951 /*----------------------------------------------------------------------------*/
958 /*----------------------------------------------------------------------------*/
959 static int
960 muse_scipost_destroy(cpl_plugin *aPlugin)
961 {
962  /* Get the recipe from the plugin */
963  cpl_recipe *recipe;
964  if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
965  recipe = (cpl_recipe *)aPlugin;
966  } else {
967  return -1;
968  }
969 
970  /* Clean up */
971  cpl_parameterlist_delete(recipe->parameters);
973  return 0;
974 } /* muse_scipost_destroy() */
975 
976 /*----------------------------------------------------------------------------*/
986 /*----------------------------------------------------------------------------*/
987 int
988 cpl_plugin_get_info(cpl_pluginlist *aList)
989 {
990  cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
991  cpl_plugin *plugin = &recipe->interface;
992 
993  char *helptext;
995  helptext = cpl_sprintf("%s%s", muse_scipost_help,
996  muse_scipost_help_esorex);
997  } else {
998  helptext = cpl_sprintf("%s", muse_scipost_help);
999  }
1000 
1001  /* Initialize the CPL plugin stuff for this module */
1002  cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
1003  CPL_PLUGIN_TYPE_RECIPE,
1004  "muse_scipost",
1005  "Prepare reduced and combined science products.",
1006  helptext,
1007  "Peter Weilbacher",
1008  "usd-help@eso.org",
1009  muse_get_license(),
1010  muse_scipost_create,
1011  muse_scipost_exec,
1012  muse_scipost_destroy);
1013  cpl_pluginlist_append(aList, plugin);
1014  cpl_free(helptext);
1015 
1016  return 0;
1017 } /* cpl_plugin_get_info() */
1018 
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.
Definition: muse_utils.c:83
muse_frame_mode
double dy
Vertical step size for resampling (in arcsec or pixel). The following defaults are taken when this va...
cpl_frameset * outframes
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.)