MUSE Pipeline Reference Manual  0.18.5
muse_scibasic_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-2013 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_scibasic_z.h" /* in turn includes muse.h */
36 
37 /*----------------------------------------------------------------------------*/
66 /*----------------------------------------------------------------------------*/
69 /*----------------------------------------------------------------------------*
70  * Static variables *
71  *----------------------------------------------------------------------------*/
72 static const char *muse_scibasic_help =
73  "Processing handles each raw input image separately: it trims the raw data and records the overscan statistics, subtracts the bias (taking account of the overscan, if --overscan is not &none&), optionally detects cosmic rays (note that by default cosmic ray rejection is handled in the post processing recipes while the data is reformatted into a datacube, so that the default setting is cr=&none& here), converts the images from adu to count, subtracts the dark, divides by the flat-field, and (optionally) propagates the integrated flux value from the sky-flat. The input calibrations geometry table, trace table, and wavelength calibration table are used to assign 3D coordinates to each CCD-based pixel, thereby creating a pixel table for each exposure. If --skylines contains one or more wavelengths for (bright and isolated) sky emission lines, these lines are used to correct the wavelength calibration using an offset. Both the reduced image and the pixel table are saved. For special cases, users can choose to combine all input files at the image level, so that the pixel table is only created once, for the combined data. This is not recommended for science data, where the combination should take place after correcting for atmospheric effects, before the creation of the final cube.";
74 
75 static const char *muse_scibasic_help_esorex =
76  "\n\nInput frames for raw frame tag \"OBJECT\":\n"
77  "\n Frame tag Type Req #Fr Description"
78  "\n -------------------- ---- --- --- ------------"
79  "\n OBJECT raw Y Raw exposure of a science target"
80  "\n MASTER_BIAS calib Y 1 Master bias"
81  "\n MASTER_DARK calib . 1 Master dark"
82  "\n MASTER_FLAT calib Y 1 Master flat"
83  "\n TRACE_TABLE calib Y 1 Tracing table for all slices"
84  "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
85  "\n GEOMETRY_TABLE calib Y 1 Relative positions of the slices in the field of view"
86  "\n MASTER_SKYFLAT calib . 1 Master twilight skyflat"
87  "\n BADPIX_TABLE calib . 1 Known bad pixels"
88  "\n\nProduct frames for raw frame tag \"OBJECT\":\n"
89  "\n Frame tag Level Description"
90  "\n -------------------- -------- ------------"
91  "\n OBJECT_RED intermed Pre-processed CCD-based images (if --saveimage=true)"
92  "\n OBJECT_RESAMPLED intermed Resampled 2D image (if --resample=true)"
93  "\n PIXTABLE_OBJECT intermed Output pixel table" "\n\nInput frames for raw frame tag \"STD\":\n"
94  "\n Frame tag Type Req #Fr Description"
95  "\n -------------------- ---- --- --- ------------"
96  "\n STD raw Y Raw exposure of a standard star field"
97  "\n MASTER_BIAS calib Y 1 Master bias"
98  "\n MASTER_DARK calib . 1 Master dark"
99  "\n MASTER_FLAT calib Y 1 Master flat"
100  "\n TRACE_TABLE calib Y 1 Tracing table for all slices"
101  "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
102  "\n GEOMETRY_TABLE calib Y 1 Relative positions of the slices in the field of view"
103  "\n MASTER_SKYFLAT calib . 1 Master twilight skyflat"
104  "\n BADPIX_TABLE calib . 1 Known bad pixels"
105  "\n\nProduct frames for raw frame tag \"STD\":\n"
106  "\n Frame tag Level Description"
107  "\n -------------------- -------- ------------"
108  "\n STD_RED intermed Pre-processed CCD-based images (if --saveimage=true)"
109  "\n STD_RESAMPLED intermed Resampled 2D image (if --resample=true)"
110  "\n PIXTABLE_STD intermed Output pixel table" "\n\nInput frames for raw frame tag \"SKY\":\n"
111  "\n Frame tag Type Req #Fr Description"
112  "\n -------------------- ---- --- --- ------------"
113  "\n SKY raw Y Raw exposure of an (almost) empty sky field"
114  "\n MASTER_BIAS calib Y 1 Master bias"
115  "\n MASTER_DARK calib . 1 Master dark"
116  "\n MASTER_FLAT calib Y 1 Master flat"
117  "\n TRACE_TABLE calib Y 1 Tracing table for all slices"
118  "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
119  "\n GEOMETRY_TABLE calib Y 1 Relative positions of the slices in the field of view"
120  "\n MASTER_SKYFLAT calib . 1 Master twilight skyflat"
121  "\n BADPIX_TABLE calib . 1 Known bad pixels"
122  "\n\nProduct frames for raw frame tag \"SKY\":\n"
123  "\n Frame tag Level Description"
124  "\n -------------------- -------- ------------"
125  "\n SKY_RED intermed Pre-processed CCD-based images (if --saveimage=true)"
126  "\n SKY_RESAMPLED intermed Resampled 2D image (if --resample=true)"
127  "\n PIXTABLE_SKY intermed Output pixel table" "\n\nInput frames for raw frame tag \"ASTROMETRY\":\n"
128  "\n Frame tag Type Req #Fr Description"
129  "\n -------------------- ---- --- --- ------------"
130  "\n ASTROMETRY raw Y Raw exposure of an astrometric field"
131  "\n MASTER_BIAS calib Y 1 Master bias"
132  "\n MASTER_DARK calib . 1 Master dark"
133  "\n MASTER_FLAT calib Y 1 Master flat"
134  "\n TRACE_TABLE calib Y 1 Tracing table for all slices"
135  "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
136  "\n GEOMETRY_TABLE calib Y 1 Relative positions of the slices in the field of view"
137  "\n MASTER_SKYFLAT calib . 1 Master twilight skyflat"
138  "\n BADPIX_TABLE calib . 1 Known bad pixels"
139  "\n\nProduct frames for raw frame tag \"ASTROMETRY\":\n"
140  "\n Frame tag Level Description"
141  "\n -------------------- -------- ------------"
142  "\n ASTROMETRY_RED intermed Pre-processed CCD-based images (if --saveimage=true)"
143  "\n ASTROMETRY_RESAMPLED intermed Resampled 2D image (if --resample=true)"
144  "\n PIXTABLE_ASTROMETRY intermed Output pixel table" "\n\nInput frames for raw frame tag \"REDUCED\":\n"
145  "\n Frame tag Type Req #Fr Description"
146  "\n -------------------- ---- --- --- ------------"
147  "\n REDUCED raw Y Reduced CCD image"
148  "\n TRACE_TABLE calib Y 1 Tracing table for all slices"
149  "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
150  "\n GEOMETRY_TABLE calib Y 1 Relative positions of the slices in the field of view"
151  "\n\nProduct frames for raw frame tag \"REDUCED\":\n"
152  "\n Frame tag Level Description"
153  "\n -------------------- -------- ------------"
154  "\n REDUCED_RESAMPLED intermed Resampled 2D image (if --resample=true)"
155  "\n PIXTABLE_REDUCED intermed Output pixel table";
156 
157 /*----------------------------------------------------------------------------*/
165 /*----------------------------------------------------------------------------*/
166 static cpl_recipeconfig *
167 muse_scibasic_new_recipeconfig(void)
168 {
169  cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
170  const char *tag;
171 
172  tag = "OBJECT";
173  cpl_recipeconfig_set_tag(recipeconfig, tag, 1, -1);
174  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_BIAS", 1, 1);
175  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_DARK", -1, 1);
176  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_FLAT", 1, 1);
177  cpl_recipeconfig_set_input(recipeconfig, tag, "TRACE_TABLE", 1, 1);
178  cpl_recipeconfig_set_input(recipeconfig, tag, "WAVECAL_TABLE", 1, 1);
179  cpl_recipeconfig_set_input(recipeconfig, tag, "GEOMETRY_TABLE", 1, 1);
180  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_SKYFLAT", -1, 1);
181  cpl_recipeconfig_set_input(recipeconfig, tag, "BADPIX_TABLE", -1, 1);
182  cpl_recipeconfig_set_output(recipeconfig, tag, "OBJECT_RED");
183  cpl_recipeconfig_set_output(recipeconfig, tag, "OBJECT_RESAMPLED");
184  cpl_recipeconfig_set_output(recipeconfig, tag, "PIXTABLE_OBJECT");
185 
186  tag = "STD";
187  cpl_recipeconfig_set_tag(recipeconfig, tag, 1, -1);
188  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_BIAS", 1, 1);
189  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_DARK", -1, 1);
190  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_FLAT", 1, 1);
191  cpl_recipeconfig_set_input(recipeconfig, tag, "TRACE_TABLE", 1, 1);
192  cpl_recipeconfig_set_input(recipeconfig, tag, "WAVECAL_TABLE", 1, 1);
193  cpl_recipeconfig_set_input(recipeconfig, tag, "GEOMETRY_TABLE", 1, 1);
194  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_SKYFLAT", -1, 1);
195  cpl_recipeconfig_set_input(recipeconfig, tag, "BADPIX_TABLE", -1, 1);
196  cpl_recipeconfig_set_output(recipeconfig, tag, "STD_RED");
197  cpl_recipeconfig_set_output(recipeconfig, tag, "STD_RESAMPLED");
198  cpl_recipeconfig_set_output(recipeconfig, tag, "PIXTABLE_STD");
199 
200  tag = "SKY";
201  cpl_recipeconfig_set_tag(recipeconfig, tag, 1, -1);
202  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_BIAS", 1, 1);
203  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_DARK", -1, 1);
204  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_FLAT", 1, 1);
205  cpl_recipeconfig_set_input(recipeconfig, tag, "TRACE_TABLE", 1, 1);
206  cpl_recipeconfig_set_input(recipeconfig, tag, "WAVECAL_TABLE", 1, 1);
207  cpl_recipeconfig_set_input(recipeconfig, tag, "GEOMETRY_TABLE", 1, 1);
208  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_SKYFLAT", -1, 1);
209  cpl_recipeconfig_set_input(recipeconfig, tag, "BADPIX_TABLE", -1, 1);
210  cpl_recipeconfig_set_output(recipeconfig, tag, "SKY_RED");
211  cpl_recipeconfig_set_output(recipeconfig, tag, "SKY_RESAMPLED");
212  cpl_recipeconfig_set_output(recipeconfig, tag, "PIXTABLE_SKY");
213 
214  tag = "ASTROMETRY";
215  cpl_recipeconfig_set_tag(recipeconfig, tag, 1, -1);
216  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_BIAS", 1, 1);
217  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_DARK", -1, 1);
218  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_FLAT", 1, 1);
219  cpl_recipeconfig_set_input(recipeconfig, tag, "TRACE_TABLE", 1, 1);
220  cpl_recipeconfig_set_input(recipeconfig, tag, "WAVECAL_TABLE", 1, 1);
221  cpl_recipeconfig_set_input(recipeconfig, tag, "GEOMETRY_TABLE", 1, 1);
222  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_SKYFLAT", -1, 1);
223  cpl_recipeconfig_set_input(recipeconfig, tag, "BADPIX_TABLE", -1, 1);
224  cpl_recipeconfig_set_output(recipeconfig, tag, "ASTROMETRY_RED");
225  cpl_recipeconfig_set_output(recipeconfig, tag, "ASTROMETRY_RESAMPLED");
226  cpl_recipeconfig_set_output(recipeconfig, tag, "PIXTABLE_ASTROMETRY");
227 
228  tag = "REDUCED";
229  cpl_recipeconfig_set_tag(recipeconfig, tag, 1, -1);
230  cpl_recipeconfig_set_input(recipeconfig, tag, "TRACE_TABLE", 1, 1);
231  cpl_recipeconfig_set_input(recipeconfig, tag, "WAVECAL_TABLE", 1, 1);
232  cpl_recipeconfig_set_input(recipeconfig, tag, "GEOMETRY_TABLE", 1, 1);
233  cpl_recipeconfig_set_output(recipeconfig, tag, "REDUCED_RESAMPLED");
234  cpl_recipeconfig_set_output(recipeconfig, tag, "PIXTABLE_REDUCED");
235 
236  return recipeconfig;
237 } /* muse_scibasic_new_recipeconfig() */
238 
239 /*----------------------------------------------------------------------------*/
249 /*----------------------------------------------------------------------------*/
250 static cpl_error_code
251 muse_scibasic_prepare_header(const char *aFrametag, cpl_propertylist *aHeader)
252 {
253  cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
254  cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
255  if (!strcmp(aFrametag, "OBJECT_RED")) {
256  muse_processing_prepare_property(aHeader, "ESO QC SCIBASIC NSATURATED",
257  CPL_TYPE_INT,
258  "Number of saturated pixels in output data");
259  } else if (!strcmp(aFrametag, "OBJECT_RESAMPLED")) {
260  } else if (!strcmp(aFrametag, "PIXTABLE_OBJECT")) {
261  muse_processing_prepare_property(aHeader, "ESO QC SCIBASIC NSATURATED",
262  CPL_TYPE_INT,
263  "Number of saturated pixels in output data");
264  muse_processing_prepare_property(aHeader, "ESO QC SCIBASIC LAMBDA SHIFT",
265  CPL_TYPE_FLOAT,
266  "[Angstrom] Shift in wavelength applied to the data using sky emission line(s)");
267  } else if (!strcmp(aFrametag, "STD_RED")) {
268  muse_processing_prepare_property(aHeader, "ESO QC SCIBASIC NSATURATED",
269  CPL_TYPE_INT,
270  "Number of saturated pixels in output data");
271  } else if (!strcmp(aFrametag, "STD_RESAMPLED")) {
272  } else if (!strcmp(aFrametag, "PIXTABLE_STD")) {
273  muse_processing_prepare_property(aHeader, "ESO QC SCIBASIC NSATURATED",
274  CPL_TYPE_INT,
275  "Number of saturated pixels in output data");
276  } else if (!strcmp(aFrametag, "SKY_RED")) {
277  muse_processing_prepare_property(aHeader, "ESO QC SCIBASIC NSATURATED",
278  CPL_TYPE_INT,
279  "Number of saturated pixels in output data");
280  } else if (!strcmp(aFrametag, "SKY_RESAMPLED")) {
281  } else if (!strcmp(aFrametag, "PIXTABLE_SKY")) {
282  muse_processing_prepare_property(aHeader, "ESO QC SCIBASIC NSATURATED",
283  CPL_TYPE_INT,
284  "Number of saturated pixels in output data");
285  } else if (!strcmp(aFrametag, "ASTROMETRY_RED")) {
286  muse_processing_prepare_property(aHeader, "ESO QC SCIBASIC NSATURATED",
287  CPL_TYPE_INT,
288  "Number of saturated pixels in output data");
289  } else if (!strcmp(aFrametag, "ASTROMETRY_RESAMPLED")) {
290  } else if (!strcmp(aFrametag, "PIXTABLE_ASTROMETRY")) {
291  muse_processing_prepare_property(aHeader, "ESO QC SCIBASIC NSATURATED",
292  CPL_TYPE_INT,
293  "Number of saturated pixels in output data");
294  } else if (!strcmp(aFrametag, "REDUCED_RESAMPLED")) {
295  } else if (!strcmp(aFrametag, "PIXTABLE_REDUCED")) {
296  } else {
297  cpl_msg_warning(__func__, "Frame tag %s is not defined", aFrametag);
298  return CPL_ERROR_ILLEGAL_INPUT;
299  }
300  return CPL_ERROR_NONE;
301 } /* muse_scibasic_prepare_header() */
302 
303 /*----------------------------------------------------------------------------*/
312 /*----------------------------------------------------------------------------*/
313 static cpl_frame_level
314 muse_scibasic_get_frame_level(const char *aFrametag)
315 {
316  if (!aFrametag) {
317  return CPL_FRAME_LEVEL_NONE;
318  }
319  if (!strcmp(aFrametag, "OBJECT_RED")) {
320  return CPL_FRAME_LEVEL_INTERMEDIATE;
321  }
322  if (!strcmp(aFrametag, "OBJECT_RESAMPLED")) {
323  return CPL_FRAME_LEVEL_INTERMEDIATE;
324  }
325  if (!strcmp(aFrametag, "PIXTABLE_OBJECT")) {
326  return CPL_FRAME_LEVEL_INTERMEDIATE;
327  }
328  if (!strcmp(aFrametag, "STD_RED")) {
329  return CPL_FRAME_LEVEL_INTERMEDIATE;
330  }
331  if (!strcmp(aFrametag, "STD_RESAMPLED")) {
332  return CPL_FRAME_LEVEL_INTERMEDIATE;
333  }
334  if (!strcmp(aFrametag, "PIXTABLE_STD")) {
335  return CPL_FRAME_LEVEL_INTERMEDIATE;
336  }
337  if (!strcmp(aFrametag, "SKY_RED")) {
338  return CPL_FRAME_LEVEL_INTERMEDIATE;
339  }
340  if (!strcmp(aFrametag, "SKY_RESAMPLED")) {
341  return CPL_FRAME_LEVEL_INTERMEDIATE;
342  }
343  if (!strcmp(aFrametag, "PIXTABLE_SKY")) {
344  return CPL_FRAME_LEVEL_INTERMEDIATE;
345  }
346  if (!strcmp(aFrametag, "ASTROMETRY_RED")) {
347  return CPL_FRAME_LEVEL_INTERMEDIATE;
348  }
349  if (!strcmp(aFrametag, "ASTROMETRY_RESAMPLED")) {
350  return CPL_FRAME_LEVEL_INTERMEDIATE;
351  }
352  if (!strcmp(aFrametag, "PIXTABLE_ASTROMETRY")) {
353  return CPL_FRAME_LEVEL_INTERMEDIATE;
354  }
355  if (!strcmp(aFrametag, "REDUCED_RESAMPLED")) {
356  return CPL_FRAME_LEVEL_INTERMEDIATE;
357  }
358  if (!strcmp(aFrametag, "PIXTABLE_REDUCED")) {
359  return CPL_FRAME_LEVEL_INTERMEDIATE;
360  }
361  return CPL_FRAME_LEVEL_NONE;
362 } /* muse_scibasic_get_frame_level() */
363 
364 /*----------------------------------------------------------------------------*/
373 /*----------------------------------------------------------------------------*/
374 static muse_frame_mode
375 muse_scibasic_get_frame_mode(const char *aFrametag)
376 {
377  if (!aFrametag) {
378  return MUSE_FRAME_MODE_ALL;
379  }
380  if (!strcmp(aFrametag, "OBJECT_RED")) {
381  return MUSE_FRAME_MODE_ALL;
382  }
383  if (!strcmp(aFrametag, "OBJECT_RESAMPLED")) {
384  return MUSE_FRAME_MODE_ALL;
385  }
386  if (!strcmp(aFrametag, "PIXTABLE_OBJECT")) {
387  return MUSE_FRAME_MODE_ALL;
388  }
389  if (!strcmp(aFrametag, "STD_RED")) {
390  return MUSE_FRAME_MODE_ALL;
391  }
392  if (!strcmp(aFrametag, "STD_RESAMPLED")) {
393  return MUSE_FRAME_MODE_ALL;
394  }
395  if (!strcmp(aFrametag, "PIXTABLE_STD")) {
396  return MUSE_FRAME_MODE_ALL;
397  }
398  if (!strcmp(aFrametag, "SKY_RED")) {
399  return MUSE_FRAME_MODE_ALL;
400  }
401  if (!strcmp(aFrametag, "SKY_RESAMPLED")) {
402  return MUSE_FRAME_MODE_ALL;
403  }
404  if (!strcmp(aFrametag, "PIXTABLE_SKY")) {
405  return MUSE_FRAME_MODE_ALL;
406  }
407  if (!strcmp(aFrametag, "ASTROMETRY_RED")) {
408  return MUSE_FRAME_MODE_ALL;
409  }
410  if (!strcmp(aFrametag, "ASTROMETRY_RESAMPLED")) {
411  return MUSE_FRAME_MODE_ALL;
412  }
413  if (!strcmp(aFrametag, "PIXTABLE_ASTROMETRY")) {
414  return MUSE_FRAME_MODE_ALL;
415  }
416  if (!strcmp(aFrametag, "REDUCED_RESAMPLED")) {
417  return MUSE_FRAME_MODE_ALL;
418  }
419  if (!strcmp(aFrametag, "PIXTABLE_REDUCED")) {
420  return MUSE_FRAME_MODE_ALL;
421  }
422  return MUSE_FRAME_MODE_ALL;
423 } /* muse_scibasic_get_frame_mode() */
424 
425 /*----------------------------------------------------------------------------*/
435 /*----------------------------------------------------------------------------*/
436 static int
437 muse_scibasic_create(cpl_plugin *aPlugin)
438 {
439  /* Check that the plugin is part of a valid recipe */
440  cpl_recipe *recipe;
441  if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
442  recipe = (cpl_recipe *)aPlugin;
443  } else {
444  return -1;
445  }
446 
447  /* register the extended processing information (new FITS header creation, *
448  * getting of the frame level for a certain tag) */
450  muse_scibasic_new_recipeconfig(),
451  muse_scibasic_prepare_header,
452  muse_scibasic_get_frame_level,
453  muse_scibasic_get_frame_mode);
454 
455  /* XXX initialize timing in messages *
456  * since at least esorex is too stupid to turn it on, we have to do it */
458  cpl_msg_set_time_on();
459  }
460 
461  /* Create the parameter list in the cpl_recipe object */
462  recipe->parameters = cpl_parameterlist_new();
463  /* Fill the parameters list */
464  cpl_parameter *p;
465 
466  /* --nifu: IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in parallel. */
467  p = cpl_parameter_new_range("muse.muse_scibasic.nifu",
468  CPL_TYPE_INT,
469  "IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in parallel.",
470  "muse.muse_scibasic",
471  (int)0,
472  (int)-1,
473  (int)24);
474  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nifu");
475  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nifu");
476 
477  cpl_parameterlist_append(recipe->parameters, p);
478 
479  /* --overscan: If this is "none", stop when detecting discrepant overscan levels (see ovscsigma), for "offset" it assumes that the mean overscan level represents the real offset in the bias levels of the exposures involved, and adjusts the data accordingly; for "vpoly", a polynomial is fit to the vertical overscan and subtracted from the whole quadrant. */
480  p = cpl_parameter_new_value("muse.muse_scibasic.overscan",
481  CPL_TYPE_STRING,
482  "If this is \"none\", stop when detecting discrepant overscan levels (see ovscsigma), for \"offset\" it assumes that the mean overscan level represents the real offset in the bias levels of the exposures involved, and adjusts the data accordingly; for \"vpoly\", a polynomial is fit to the vertical overscan and subtracted from the whole quadrant.",
483  "muse.muse_scibasic",
484  (const char *)"vpoly");
485  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "overscan");
486  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "overscan");
487 
488  cpl_parameterlist_append(recipe->parameters, p);
489 
490  /* --ovscreject: This influences how values are rejected when computing overscan statistics. Either no rejection at all ("none"), rejection using the DCR algorithm ("dcr"), or rejection using an iterative constant fit ("fit"). */
491  p = cpl_parameter_new_value("muse.muse_scibasic.ovscreject",
492  CPL_TYPE_STRING,
493  "This influences how values are rejected when computing overscan statistics. Either no rejection at all (\"none\"), rejection using the DCR algorithm (\"dcr\"), or rejection using an iterative constant fit (\"fit\").",
494  "muse.muse_scibasic",
495  (const char *)"dcr");
496  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscreject");
497  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscreject");
498 
499  cpl_parameterlist_append(recipe->parameters, p);
500 
501  /* --ovscsigma: If the deviation of mean overscan levels between a raw input image and the reference image is higher than |ovscsigma x stdev|, stop the processing. If overscan="vpoly", this is used as sigma rejection level for the iterative polynomial fit. Has no effect for overscan="offset". */
502  p = cpl_parameter_new_value("muse.muse_scibasic.ovscsigma",
503  CPL_TYPE_DOUBLE,
504  "If the deviation of mean overscan levels between a raw input image and the reference image is higher than |ovscsigma x stdev|, stop the processing. If overscan=\"vpoly\", this is used as sigma rejection level for the iterative polynomial fit. Has no effect for overscan=\"offset\".",
505  "muse.muse_scibasic",
506  (double)3.);
507  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscsigma");
508  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscsigma");
509 
510  cpl_parameterlist_append(recipe->parameters, p);
511 
512  /* --ovscignore: The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when computing statistics or fits. */
513  p = cpl_parameter_new_value("muse.muse_scibasic.ovscignore",
514  CPL_TYPE_INT,
515  "The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when computing statistics or fits.",
516  "muse.muse_scibasic",
517  (int)3);
518  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscignore");
519  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscignore");
520 
521  cpl_parameterlist_append(recipe->parameters, p);
522 
523  /* --crop: Automatically crop the output pixel tables in wavelength depending on the expected useful wavelength range of the observation mode used (4750-9350 Angstrom for nominal mode, 4600-9350 Angstrom for extended mode). */
524  p = cpl_parameter_new_value("muse.muse_scibasic.crop",
525  CPL_TYPE_BOOL,
526  "Automatically crop the output pixel tables in wavelength depending on the expected useful wavelength range of the observation mode used (4750-9350 Angstrom for nominal mode, 4600-9350 Angstrom for extended mode).",
527  "muse.muse_scibasic",
528  (int)TRUE);
529  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "crop");
530  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "crop");
531 
532  cpl_parameterlist_append(recipe->parameters, p);
533 
534  /* --cr: Type of cosmic ray cleaning to use (for quick-look data processing). */
535  p = cpl_parameter_new_enum("muse.muse_scibasic.cr",
536  CPL_TYPE_STRING,
537  "Type of cosmic ray cleaning to use (for quick-look data processing).",
538  "muse.muse_scibasic",
539  (const char *)"none",
540  2,
541  (const char *)"none",
542  (const char *)"dcr");
543  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "cr");
544  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "cr");
545 
546  cpl_parameterlist_append(recipe->parameters, p);
547 
548  /* --xbox: Search box size in x. Only used if cr=dcr. */
549  p = cpl_parameter_new_value("muse.muse_scibasic.xbox",
550  CPL_TYPE_INT,
551  "Search box size in x. Only used if cr=dcr.",
552  "muse.muse_scibasic",
553  (int)15);
554  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "xbox");
555  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xbox");
556 
557  cpl_parameterlist_append(recipe->parameters, p);
558 
559  /* --ybox: Search box size in y. Only used if cr=dcr. */
560  p = cpl_parameter_new_value("muse.muse_scibasic.ybox",
561  CPL_TYPE_INT,
562  "Search box size in y. Only used if cr=dcr.",
563  "muse.muse_scibasic",
564  (int)40);
565  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ybox");
566  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ybox");
567 
568  cpl_parameterlist_append(recipe->parameters, p);
569 
570  /* --passes: Maximum number of cleaning passes. Only used if cr=dcr. */
571  p = cpl_parameter_new_value("muse.muse_scibasic.passes",
572  CPL_TYPE_INT,
573  "Maximum number of cleaning passes. Only used if cr=dcr.",
574  "muse.muse_scibasic",
575  (int)2);
576  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "passes");
577  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "passes");
578 
579  cpl_parameterlist_append(recipe->parameters, p);
580 
581  /* --thres: Threshold for detection gap in factors of standard deviation. Only used if cr=dcr. */
582  p = cpl_parameter_new_value("muse.muse_scibasic.thres",
583  CPL_TYPE_DOUBLE,
584  "Threshold for detection gap in factors of standard deviation. Only used if cr=dcr.",
585  "muse.muse_scibasic",
586  (double)5.8);
587  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "thres");
588  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "thres");
589 
590  cpl_parameterlist_append(recipe->parameters, p);
591 
592  /* --combine: Type of combination to use. Note that in most cases, science exposures cannot easily be combined on the CCD level, so this should usually be kept as "none"! */
593  p = cpl_parameter_new_enum("muse.muse_scibasic.combine",
594  CPL_TYPE_STRING,
595  "Type of combination to use. Note that in most cases, science exposures cannot easily be combined on the CCD level, so this should usually be kept as \"none\"!",
596  "muse.muse_scibasic",
597  (const char *)"none",
598  5,
599  (const char *)"none",
600  (const char *)"average",
601  (const char *)"median",
602  (const char *)"minmax",
603  (const char *)"sigclip");
604  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "combine");
605  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "combine");
606 
607  cpl_parameterlist_append(recipe->parameters, p);
608 
609  /* --nlow: Number of minimum pixels to reject with minmax */
610  p = cpl_parameter_new_value("muse.muse_scibasic.nlow",
611  CPL_TYPE_INT,
612  "Number of minimum pixels to reject with minmax",
613  "muse.muse_scibasic",
614  (int)1);
615  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nlow");
616  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nlow");
617 
618  cpl_parameterlist_append(recipe->parameters, p);
619 
620  /* --nhigh: Number of maximum pixels to reject with minmax */
621  p = cpl_parameter_new_value("muse.muse_scibasic.nhigh",
622  CPL_TYPE_INT,
623  "Number of maximum pixels to reject with minmax",
624  "muse.muse_scibasic",
625  (int)1);
626  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nhigh");
627  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nhigh");
628 
629  cpl_parameterlist_append(recipe->parameters, p);
630 
631  /* --nkeep: Number of pixels to keep with minmax */
632  p = cpl_parameter_new_value("muse.muse_scibasic.nkeep",
633  CPL_TYPE_INT,
634  "Number of pixels to keep with minmax",
635  "muse.muse_scibasic",
636  (int)1);
637  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nkeep");
638  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nkeep");
639 
640  cpl_parameterlist_append(recipe->parameters, p);
641 
642  /* --lsigma: Low sigma for pixel rejection with sigclip */
643  p = cpl_parameter_new_value("muse.muse_scibasic.lsigma",
644  CPL_TYPE_DOUBLE,
645  "Low sigma for pixel rejection with sigclip",
646  "muse.muse_scibasic",
647  (double)3);
648  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lsigma");
649  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lsigma");
650 
651  cpl_parameterlist_append(recipe->parameters, p);
652 
653  /* --hsigma: High sigma for pixel rejection with sigclip */
654  p = cpl_parameter_new_value("muse.muse_scibasic.hsigma",
655  CPL_TYPE_DOUBLE,
656  "High sigma for pixel rejection with sigclip",
657  "muse.muse_scibasic",
658  (double)3);
659  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "hsigma");
660  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "hsigma");
661 
662  cpl_parameterlist_append(recipe->parameters, p);
663 
664  /* --scale: Scale the individual images to a common exposure time before combining them. */
665  p = cpl_parameter_new_value("muse.muse_scibasic.scale",
666  CPL_TYPE_BOOL,
667  "Scale the individual images to a common exposure time before combining them.",
668  "muse.muse_scibasic",
669  (int)TRUE);
670  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "scale");
671  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "scale");
672 
673  cpl_parameterlist_append(recipe->parameters, p);
674 
675  /* --saveimage: Save the pre-processed CCD-based image of each input exposure before it is transformed into a pixel table. */
676  p = cpl_parameter_new_value("muse.muse_scibasic.saveimage",
677  CPL_TYPE_BOOL,
678  "Save the pre-processed CCD-based image of each input exposure before it is transformed into a pixel table.",
679  "muse.muse_scibasic",
680  (int)TRUE);
681  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "saveimage");
682  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "saveimage");
683 
684  cpl_parameterlist_append(recipe->parameters, p);
685 
686  /* --skylines: List of wavelengths of sky emission lines (in Angstrom) to use as reference for wavelength offset correction using a Gaussian fit. It can contain multiple (isolated) lines, as comma-separated list, individual shifts are then combined into one weighted average offset. */
687  p = cpl_parameter_new_value("muse.muse_scibasic.skylines",
688  CPL_TYPE_STRING,
689  "List of wavelengths of sky emission lines (in Angstrom) to use as reference for wavelength offset correction using a Gaussian fit. It can contain multiple (isolated) lines, as comma-separated list, individual shifts are then combined into one weighted average offset.",
690  "muse.muse_scibasic",
691  (const char *)"5577.339,6300.304");
692  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "skylines");
693  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "skylines");
694 
695  cpl_parameterlist_append(recipe->parameters, p);
696 
697  /* --skyhalfwidth: Half-width of the extraction box (in Angstrom) around each sky emission line. */
698  p = cpl_parameter_new_value("muse.muse_scibasic.skyhalfwidth",
699  CPL_TYPE_DOUBLE,
700  "Half-width of the extraction box (in Angstrom) around each sky emission line.",
701  "muse.muse_scibasic",
702  (double)5.);
703  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "skyhalfwidth");
704  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "skyhalfwidth");
705 
706  cpl_parameterlist_append(recipe->parameters, p);
707 
708  /* --skybinsize: Size of the bins (in Angstrom per pixel) for the intermediate spectrum to do the Gaussian fit to each sky emission line. */
709  p = cpl_parameter_new_value("muse.muse_scibasic.skybinsize",
710  CPL_TYPE_DOUBLE,
711  "Size of the bins (in Angstrom per pixel) for the intermediate spectrum to do the Gaussian fit to each sky emission line.",
712  "muse.muse_scibasic",
713  (double)0.1);
714  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "skybinsize");
715  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "skybinsize");
716 
717  cpl_parameterlist_append(recipe->parameters, p);
718 
719  /* --resample: Resample the input science data into 2D spectral images using tracing and wavelength calibration solutions for a visual check. Note that the image produced will show small wiggles even when the input calibrations are good and were applied successfully! */
720  p = cpl_parameter_new_value("muse.muse_scibasic.resample",
721  CPL_TYPE_BOOL,
722  "Resample the input science data into 2D spectral images using tracing and wavelength calibration solutions for a visual check. Note that the image produced will show small wiggles even when the input calibrations are good and were applied successfully!",
723  "muse.muse_scibasic",
724  (int)FALSE);
725  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "resample");
726  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "resample");
727 
728  cpl_parameterlist_append(recipe->parameters, p);
729 
730  /* --dlambda: Wavelength step (in Angstrom per pixel) to use for resampling. */
731  p = cpl_parameter_new_value("muse.muse_scibasic.dlambda",
732  CPL_TYPE_DOUBLE,
733  "Wavelength step (in Angstrom per pixel) to use for resampling.",
734  "muse.muse_scibasic",
735  (double)1.25);
736  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "dlambda");
737  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dlambda");
738 
739  cpl_parameterlist_append(recipe->parameters, p);
740 
741  return 0;
742 } /* muse_scibasic_create() */
743 
744 /*----------------------------------------------------------------------------*/
755 /*----------------------------------------------------------------------------*/
756 static int
757 muse_scibasic_params_fill(muse_scibasic_params_t *aParams, cpl_parameterlist *aParameters)
758 {
759  cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
760  cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
761  cpl_parameter *p;
762 
763  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.nifu");
764  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
765  aParams->nifu = cpl_parameter_get_int(p);
766 
767  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.overscan");
768  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
769  aParams->overscan = cpl_parameter_get_string(p);
770 
771  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.ovscreject");
772  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
773  aParams->ovscreject = cpl_parameter_get_string(p);
774 
775  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.ovscsigma");
776  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
777  aParams->ovscsigma = cpl_parameter_get_double(p);
778 
779  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.ovscignore");
780  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
781  aParams->ovscignore = cpl_parameter_get_int(p);
782 
783  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.crop");
784  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
785  aParams->crop = cpl_parameter_get_bool(p);
786 
787  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.cr");
788  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
789  aParams->cr_s = cpl_parameter_get_string(p);
790  aParams->cr =
791  (!strcasecmp(aParams->cr_s, "none")) ? MUSE_SCIBASIC_PARAM_CR_NONE :
792  (!strcasecmp(aParams->cr_s, "dcr")) ? MUSE_SCIBASIC_PARAM_CR_DCR :
793  MUSE_SCIBASIC_PARAM_CR_INVALID_VALUE;
794  cpl_ensure_code(aParams->cr != MUSE_SCIBASIC_PARAM_CR_INVALID_VALUE,
795  CPL_ERROR_ILLEGAL_INPUT);
796 
797  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.xbox");
798  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
799  aParams->xbox = cpl_parameter_get_int(p);
800 
801  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.ybox");
802  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
803  aParams->ybox = cpl_parameter_get_int(p);
804 
805  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.passes");
806  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
807  aParams->passes = cpl_parameter_get_int(p);
808 
809  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.thres");
810  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
811  aParams->thres = cpl_parameter_get_double(p);
812 
813  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.combine");
814  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
815  aParams->combine_s = cpl_parameter_get_string(p);
816  aParams->combine =
817  (!strcasecmp(aParams->combine_s, "none")) ? MUSE_SCIBASIC_PARAM_COMBINE_NONE :
818  (!strcasecmp(aParams->combine_s, "average")) ? MUSE_SCIBASIC_PARAM_COMBINE_AVERAGE :
819  (!strcasecmp(aParams->combine_s, "median")) ? MUSE_SCIBASIC_PARAM_COMBINE_MEDIAN :
820  (!strcasecmp(aParams->combine_s, "minmax")) ? MUSE_SCIBASIC_PARAM_COMBINE_MINMAX :
821  (!strcasecmp(aParams->combine_s, "sigclip")) ? MUSE_SCIBASIC_PARAM_COMBINE_SIGCLIP :
822  MUSE_SCIBASIC_PARAM_COMBINE_INVALID_VALUE;
823  cpl_ensure_code(aParams->combine != MUSE_SCIBASIC_PARAM_COMBINE_INVALID_VALUE,
824  CPL_ERROR_ILLEGAL_INPUT);
825 
826  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.nlow");
827  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
828  aParams->nlow = cpl_parameter_get_int(p);
829 
830  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.nhigh");
831  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
832  aParams->nhigh = cpl_parameter_get_int(p);
833 
834  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.nkeep");
835  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
836  aParams->nkeep = cpl_parameter_get_int(p);
837 
838  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.lsigma");
839  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
840  aParams->lsigma = cpl_parameter_get_double(p);
841 
842  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.hsigma");
843  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
844  aParams->hsigma = cpl_parameter_get_double(p);
845 
846  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.scale");
847  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
848  aParams->scale = cpl_parameter_get_bool(p);
849 
850  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.saveimage");
851  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
852  aParams->saveimage = cpl_parameter_get_bool(p);
853 
854  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.skylines");
855  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
856  aParams->skylines = cpl_parameter_get_string(p);
857 
858  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.skyhalfwidth");
859  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
860  aParams->skyhalfwidth = cpl_parameter_get_double(p);
861 
862  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.skybinsize");
863  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
864  aParams->skybinsize = cpl_parameter_get_double(p);
865 
866  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.resample");
867  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
868  aParams->resample = cpl_parameter_get_bool(p);
869 
870  p = cpl_parameterlist_find(aParameters, "muse.muse_scibasic.dlambda");
871  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
872  aParams->dlambda = cpl_parameter_get_double(p);
873 
874  return 0;
875 } /* muse_scibasic_params_fill() */
876 
877 /*----------------------------------------------------------------------------*/
884 /*----------------------------------------------------------------------------*/
885 static int
886 muse_scibasic_exec(cpl_plugin *aPlugin)
887 {
888  if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
889  return -1;
890  }
891  cpl_recipe *recipe = (cpl_recipe *)aPlugin;
892  cpl_msg_set_threadid_on();
893 
894  cpl_frameset *usedframes = cpl_frameset_new(),
895  *outframes = cpl_frameset_new();
896  muse_scibasic_params_t params;
897  muse_scibasic_params_fill(&params, recipe->parameters);
898 
899  cpl_errorstate prestate = cpl_errorstate_get();
900 
901  if (params.nifu < -1 || params.nifu > kMuseNumIFUs) {
902  cpl_msg_error(__func__, "Please specify a valid IFU number (between 1 and "
903  "%d), 0 (to process all IFUs consecutively), or -1 (to "
904  "process all IFUs in parallel) using --nifu.", kMuseNumIFUs);
905  return -1;
906  } /* if invalid params.nifu */
907 
908  int rc = 0;
909  if (params.nifu > 0) {
910  muse_processing *proc = muse_processing_new("muse_scibasic",
911  recipe);
912  rc = muse_scibasic_compute(proc, &params);
913  cpl_frameset_join(usedframes, proc->usedFrames);
914  cpl_frameset_join(outframes, proc->outputFrames);
916  } else if (params.nifu < 0) { /* parallel processing */
917  int *rcs = cpl_calloc(kMuseNumIFUs, sizeof(int));
918  int nifu;
919  #pragma omp parallel for default(none) \
920  shared(outframes, params, rcs, recipe, usedframes)
921  for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
922  muse_processing *proc = muse_processing_new("muse_scibasic",
923  recipe);
924  muse_scibasic_params_t *pars = cpl_malloc(sizeof(muse_scibasic_params_t));
925  memcpy(pars, &params, sizeof(muse_scibasic_params_t));
926  pars->nifu = nifu;
927  int *rci = rcs + (nifu - 1);
928  *rci = muse_scibasic_compute(proc, pars);
929  if (rci && cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
930  *rci = 0;
931  }
932  cpl_free(pars);
933  #pragma omp critical(muse_processing_used_frames)
934  cpl_frameset_join(usedframes, proc->usedFrames);
935  #pragma omp critical(muse_processing_output_frames)
936  cpl_frameset_join(outframes, proc->outputFrames);
938  } /* for nifu */
939  /* non-parallel loop to propagate the "worst" return code; *
940  * since we only ever return -1, any non-zero code is propagated */
941  for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
942  if (rcs[nifu-1] != 0) {
943  rc = rcs[nifu-1];
944  } /* if */
945  } /* for nifu */
946  cpl_free(rcs);
947  } else { /* serial processing */
948  for (params.nifu = 1; params.nifu <= kMuseNumIFUs && !rc; params.nifu++) {
949  muse_processing *proc = muse_processing_new("muse_scibasic",
950  recipe);
951  rc = muse_scibasic_compute(proc, &params);
952  if (rc && cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
953  rc = 0;
954  }
955  cpl_frameset_join(usedframes, proc->usedFrames);
956  cpl_frameset_join(outframes, proc->outputFrames);
958  } /* for nifu */
959  } /* else */
960 
961  if (!cpl_errorstate_is_equal(prestate)) {
962  /* dump all errors from this recipe in chronological order */
963  cpl_errorstate_dump(prestate, CPL_FALSE, muse_cplerrorstate_dump_some);
964  /* reset message level to not get the same errors displayed again by esorex */
965  cpl_msg_set_level(CPL_MSG_INFO);
966  }
967  /* clean up duplicates in framesets of used and output frames */
970  /* to get esorex to see our classification (frame groups etc.), *
971  * replace the original frameset with the list of used frames *
972  * before appending product output frames */
973  /* keep the same pointer, so just erase all frames, not delete the frameset */
974  muse_cplframeset_erase_all(recipe->frames);
975  cpl_frameset_join(recipe->frames, usedframes);
976  cpl_frameset_join(recipe->frames, outframes);
977  cpl_frameset_delete(usedframes);
978  cpl_frameset_delete(outframes);
979  return rc;
980 } /* muse_scibasic_exec() */
981 
982 /*----------------------------------------------------------------------------*/
989 /*----------------------------------------------------------------------------*/
990 static int
991 muse_scibasic_destroy(cpl_plugin *aPlugin)
992 {
993  /* Get the recipe from the plugin */
994  cpl_recipe *recipe;
995  if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
996  recipe = (cpl_recipe *)aPlugin;
997  } else {
998  return -1;
999  }
1000 
1001  /* Clean up */
1002  cpl_parameterlist_delete(recipe->parameters);
1004  return 0;
1005 } /* muse_scibasic_destroy() */
1006 
1007 /*----------------------------------------------------------------------------*/
1017 /*----------------------------------------------------------------------------*/
1018 int
1019 cpl_plugin_get_info(cpl_pluginlist *aList)
1020 {
1021  cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
1022  cpl_plugin *plugin = &recipe->interface;
1023 
1024  char *helptext;
1026  helptext = cpl_sprintf("%s%s", muse_scibasic_help,
1027  muse_scibasic_help_esorex);
1028  } else {
1029  helptext = cpl_sprintf("%s", muse_scibasic_help);
1030  }
1031 
1032  /* Initialize the CPL plugin stuff for this module */
1033  cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
1034  CPL_PLUGIN_TYPE_RECIPE,
1035  "muse_scibasic",
1036  "Remove the instrumental signature from the data of each CCD and convert them from an image into a pixel table.",
1037  helptext,
1038  "Peter Weilbacher",
1039  "usd-help@eso.org",
1040  muse_get_license(),
1041  muse_scibasic_create,
1042  muse_scibasic_exec,
1043  muse_scibasic_destroy);
1044  cpl_pluginlist_append(aList, plugin);
1045  cpl_free(helptext);
1046 
1047  return 0;
1048 } /* cpl_plugin_get_info() */
1049 
void muse_processing_delete(muse_processing *aProcessing)
Free the muse_processing structure.
int nkeep
Number of pixels to keep with minmax.
double hsigma
High sigma for pixel rejection with sigclip.
muse_cplframework_type muse_cplframework(void)
Return the CPL framework the recipe is run under.
int passes
Maximum number of cleaning passes. Only used if cr=dcr.
double ovscsigma
If the deviation of mean overscan levels between a raw input image and the reference image is higher ...
const char * combine_s
Type of combination to use. Note that in most cases, science exposures cannot easily be combined on t...
double dlambda
Wavelength step (in Angstrom per pixel) to use for resampling.
double lsigma
Low sigma for pixel rejection with sigclip.
int combine
Type of combination to use. Note that in most cases, science exposures cannot easily be combined on t...
int scale
Scale the individual images to a common exposure time before combining them.
int saveimage
Save the pre-processed CCD-based image of each input exposure before it is transformed into a pixel t...
const char * muse_get_license(void)
Get the pipeline copyright and license.
Definition: muse_utils.c:80
const char * overscan
If this is "none", stop when detecting discrepant overscan levels (see ovscsigma), for "offset" it assumes that the mean overscan level represents the real offset in the bias levels of the exposures involved, and adjusts the data accordingly; for "vpoly", a polynomial is fit to the vertical overscan and subtracted from the whole quadrant.
muse_processing * muse_processing_new(const char *aRecipeName, cpl_recipe *aRecipe)
Create a new processing structure.
int cr
Type of cosmic ray cleaning to use (for quick-look data processing).
muse_frame_mode
int resample
Resample the input science data into 2D spectral images using tracing and wavelength calibration solu...
cpl_frameset * outputFrames
int nifu
IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in ...
void muse_cplerrorstate_dump_some(unsigned aCurrent, unsigned aFirst, unsigned aLast)
Dump some CPL errors.
void muse_processinginfo_delete(cpl_recipe *)
Clear all information from the processing info and from the recipe config.
double skyhalfwidth
Half-width of the extraction box (in Angstrom) around each sky emission line.
int crop
Automatically crop the output pixel tables in wavelength depending on the expected useful wavelength ...
const char * ovscreject
This influences how values are rejected when computing overscan statistics. Either no rejection at al...
int xbox
Search box size in x. Only used if cr=dcr.
int nhigh
Number of maximum pixels to reject with minmax.
cpl_error_code muse_cplframeset_erase_duplicate(cpl_frameset *aFrames)
Erase all duplicate frames from a frameset.
int ybox
Search box size in y. Only used if cr=dcr.
double thres
Threshold for detection gap in factors of standard deviation. Only used if cr=dcr.
Structure to hold the parameters of the muse_scibasic recipe.
double skybinsize
Size of the bins (in Angstrom per pixel) for the intermediate spectrum to do the Gaussian fit to each...
cpl_error_code muse_cplframeset_erase_all(cpl_frameset *aFrames)
Erase all frames in a frameset.
const char * cr_s
Type of cosmic ray cleaning to use (for quick-look data processing). (as string)
void muse_processinginfo_register(cpl_recipe *, cpl_recipeconfig *, muse_processing_prepare_header_func *, muse_processing_get_frame_level_func *, muse_processing_get_frame_mode_func *)
Register extended functionalities for MUSE recipes.
const char * skylines
List of wavelengths of sky emission lines (in Angstrom) to use as reference for wavelength offset cor...
cpl_frameset * usedFrames
int ovscignore
The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when com...
int nlow
Number of minimum pixels to reject with minmax.
cpl_error_code muse_processing_prepare_property(cpl_propertylist *, const char *, cpl_type, const char *)
Prepare and check the specified property.