MUSE Pipeline Reference Manual  1.0.2
muse_lsf_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-2014 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_lsf_z.h" /* in turn includes muse.h */
36 
37 /*----------------------------------------------------------------------------*/
45 /*----------------------------------------------------------------------------*/
48 /*----------------------------------------------------------------------------*
49  * Static variables *
50  *----------------------------------------------------------------------------*/
51 static const char *muse_lsf_help =
52  "Compute the slice and wavelength dependent LSF from a lines spectrum (ARC lamp).";
53 
54 static const char *muse_lsf_help_esorex =
55  "\n\nInput frames for raw frame tag \"ARC\":\n"
56  "\n Frame tag Type Req #Fr Description"
57  "\n -------------------- ---- --- --- ------------"
58  "\n ARC raw Y Raw arc lamp exposures"
59  "\n MASTER_BIAS calib Y 1 Master bias"
60  "\n MASTER_DARK calib . 1 Master dark"
61  "\n MASTER_FLAT calib . 1 Master flat"
62  "\n TRACE_TABLE calib Y 1 Trace table"
63  "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
64  "\n BADPIX_TABLE calib . 1 Known bad pixels"
65  "\n LINE_CATALOG calib Y 1 Arc line catalog"
66  "\n\nProduct frames for raw frame tag \"ARC\":\n"
67  "\n Frame tag Level Description"
68  "\n -------------------- -------- ------------"
69  "\n LSF_PROFILE final Slice specific LSF parameters (if --lsf=true)"
70  "\n PIXTABLE_SUBTRACTED final Subtracted pixel table (if --save_subtracted=true), for debugging.";
71 
72 /*----------------------------------------------------------------------------*/
80 /*----------------------------------------------------------------------------*/
81 static cpl_recipeconfig *
82 muse_lsf_new_recipeconfig(void)
83 {
84  cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
85  const char *tag;
86 
87  tag = "ARC";
88  cpl_recipeconfig_set_tag(recipeconfig, tag, 1, -1);
89  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_BIAS", 1, 1);
90  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_DARK", -1, 1);
91  cpl_recipeconfig_set_input(recipeconfig, tag, "MASTER_FLAT", -1, 1);
92  cpl_recipeconfig_set_input(recipeconfig, tag, "TRACE_TABLE", 1, 1);
93  cpl_recipeconfig_set_input(recipeconfig, tag, "WAVECAL_TABLE", 1, 1);
94  cpl_recipeconfig_set_input(recipeconfig, tag, "BADPIX_TABLE", -1, 1);
95  cpl_recipeconfig_set_input(recipeconfig, tag, "LINE_CATALOG", 1, 1);
96  cpl_recipeconfig_set_output(recipeconfig, tag, "LSF_PROFILE");
97  cpl_recipeconfig_set_output(recipeconfig, tag, "PIXTABLE_SUBTRACTED");
98 
99  return recipeconfig;
100 } /* muse_lsf_new_recipeconfig() */
101 
102 /*----------------------------------------------------------------------------*/
112 /*----------------------------------------------------------------------------*/
113 static cpl_error_code
114 muse_lsf_prepare_header(const char *aFrametag, cpl_propertylist *aHeader)
115 {
116  cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
117  cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
118  if (!strcmp(aFrametag, "LSF_PROFILE")) {
119  muse_processing_prepare_property(aHeader, "ESO QC LSF IFU[0-9]+ SLICE[0-9]+ FWHM MEAN",
120  CPL_TYPE_FLOAT,
121  "Mean FWHM of the LSF slice j");
122  muse_processing_prepare_property(aHeader, "ESO QC LSF IFU[0-9]+ SLICE[0-9]+ FWHM STDEV",
123  CPL_TYPE_FLOAT,
124  "Standard deviation of the LSF in slice j");
125  muse_processing_prepare_property(aHeader, "ESO QC LSF IFU[0-9]+ SLICE[0-9]+ FWHM MIN",
126  CPL_TYPE_FLOAT,
127  "Minimum FWHM of the LSF in slice j");
128  muse_processing_prepare_property(aHeader, "ESO QC LSF IFU[0-9]+ SLICE[0-9]+ FWHM MAX",
129  CPL_TYPE_FLOAT,
130  "Maximum FWHM of the LSF in slice j");
131  } else if (!strcmp(aFrametag, "PIXTABLE_SUBTRACTED")) {
132  } else {
133  cpl_msg_warning(__func__, "Frame tag %s is not defined", aFrametag);
134  return CPL_ERROR_ILLEGAL_INPUT;
135  }
136  return CPL_ERROR_NONE;
137 } /* muse_lsf_prepare_header() */
138 
139 /*----------------------------------------------------------------------------*/
148 /*----------------------------------------------------------------------------*/
149 static cpl_frame_level
150 muse_lsf_get_frame_level(const char *aFrametag)
151 {
152  if (!aFrametag) {
153  return CPL_FRAME_LEVEL_NONE;
154  }
155  if (!strcmp(aFrametag, "LSF_PROFILE")) {
156  return CPL_FRAME_LEVEL_FINAL;
157  }
158  if (!strcmp(aFrametag, "PIXTABLE_SUBTRACTED")) {
159  return CPL_FRAME_LEVEL_FINAL;
160  }
161  return CPL_FRAME_LEVEL_NONE;
162 } /* muse_lsf_get_frame_level() */
163 
164 /*----------------------------------------------------------------------------*/
173 /*----------------------------------------------------------------------------*/
174 static muse_frame_mode
175 muse_lsf_get_frame_mode(const char *aFrametag)
176 {
177  if (!aFrametag) {
178  return MUSE_FRAME_MODE_ALL;
179  }
180  if (!strcmp(aFrametag, "LSF_PROFILE")) {
181  return MUSE_FRAME_MODE_MASTER;
182  }
183  if (!strcmp(aFrametag, "PIXTABLE_SUBTRACTED")) {
184  return MUSE_FRAME_MODE_MASTER;
185  }
186  return MUSE_FRAME_MODE_ALL;
187 } /* muse_lsf_get_frame_mode() */
188 
189 /*----------------------------------------------------------------------------*/
199 /*----------------------------------------------------------------------------*/
200 static int
201 muse_lsf_create(cpl_plugin *aPlugin)
202 {
203  /* Check that the plugin is part of a valid recipe */
204  cpl_recipe *recipe;
205  if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
206  recipe = (cpl_recipe *)aPlugin;
207  } else {
208  return -1;
209  }
210 
211  /* register the extended processing information (new FITS header creation, *
212  * getting of the frame level for a certain tag) */
214  muse_lsf_new_recipeconfig(),
215  muse_lsf_prepare_header,
216  muse_lsf_get_frame_level,
217  muse_lsf_get_frame_mode);
218 
219  /* XXX initialize timing in messages *
220  * since at least esorex is too stupid to turn it on, we have to do it */
222  cpl_msg_set_time_on();
223  }
224 
225  /* Create the parameter list in the cpl_recipe object */
226  recipe->parameters = cpl_parameterlist_new();
227  /* Fill the parameters list */
228  cpl_parameter *p;
229 
230  /* --nifu: IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in parallel. */
231  p = cpl_parameter_new_range("muse.muse_lsf.nifu",
232  CPL_TYPE_INT,
233  "IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in parallel.",
234  "muse.muse_lsf",
235  (int)0,
236  (int)-1,
237  (int)24);
238  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nifu");
239  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nifu");
240 
241  cpl_parameterlist_append(recipe->parameters, p);
242 
243  /* --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. */
244  p = cpl_parameter_new_value("muse.muse_lsf.overscan",
245  CPL_TYPE_STRING,
246  "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.",
247  "muse.muse_lsf",
248  (const char *)"vpoly");
249  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "overscan");
250  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "overscan");
251 
252  cpl_parameterlist_append(recipe->parameters, p);
253 
254  /* --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"). */
255  p = cpl_parameter_new_value("muse.muse_lsf.ovscreject",
256  CPL_TYPE_STRING,
257  "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\").",
258  "muse.muse_lsf",
259  (const char *)"dcr");
260  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscreject");
261  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscreject");
262 
263  cpl_parameterlist_append(recipe->parameters, p);
264 
265  /* --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 (the level comparison is then done afterwards with |100 x stdev| to guard against incompatible settings). Has no effect for overscan="offset". */
266  p = cpl_parameter_new_value("muse.muse_lsf.ovscsigma",
267  CPL_TYPE_DOUBLE,
268  "If the deviation of mean overscan levels between a raw input image and the reference image is higher than |ovscsigma x stdev|, stop the processing. If overscan=\"vpoly\", this is used as sigma rejection level for the iterative polynomial fit (the level comparison is then done afterwards with |100 x stdev| to guard against incompatible settings). Has no effect for overscan=\"offset\".",
269  "muse.muse_lsf",
270  (double)30.);
271  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscsigma");
272  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscsigma");
273 
274  cpl_parameterlist_append(recipe->parameters, p);
275 
276  /* --ovscignore: The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when computing statistics or fits. */
277  p = cpl_parameter_new_value("muse.muse_lsf.ovscignore",
278  CPL_TYPE_INT,
279  "The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when computing statistics or fits.",
280  "muse.muse_lsf",
281  (int)3);
282  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ovscignore");
283  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ovscignore");
284 
285  cpl_parameterlist_append(recipe->parameters, p);
286 
287  /* --combine: Type of lampwise image combination to use. */
288  p = cpl_parameter_new_enum("muse.muse_lsf.combine",
289  CPL_TYPE_STRING,
290  "Type of lampwise image combination to use.",
291  "muse.muse_lsf",
292  (const char *)"sigclip",
293  4,
294  (const char *)"average",
295  (const char *)"median",
296  (const char *)"minmax",
297  (const char *)"sigclip");
298  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "combine");
299  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "combine");
300 
301  cpl_parameterlist_append(recipe->parameters, p);
302 
303  /* --save_subtracted: Save the pixel table after the LSF subtraction. */
304  p = cpl_parameter_new_value("muse.muse_lsf.save_subtracted",
305  CPL_TYPE_BOOL,
306  "Save the pixel table after the LSF subtraction.",
307  "muse.muse_lsf",
308  (int)FALSE);
309  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "save_subtracted");
310  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "save_subtracted");
311 
312  cpl_parameterlist_append(recipe->parameters, p);
313 
314  /* --line_quality: Minimal quality flag in line catalog for selection */
315  p = cpl_parameter_new_value("muse.muse_lsf.line_quality",
316  CPL_TYPE_INT,
317  "Minimal quality flag in line catalog for selection",
318  "muse.muse_lsf",
319  (int)3);
320  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "line_quality");
321  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "line_quality");
322 
323  cpl_parameterlist_append(recipe->parameters, p);
324 
325  /* --merge: Merge output products from different IFUs into a common file. */
326  p = cpl_parameter_new_value("muse.muse_lsf.merge",
327  CPL_TYPE_BOOL,
328  "Merge output products from different IFUs into a common file.",
329  "muse.muse_lsf",
330  (int)FALSE);
331  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "merge");
332  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "merge");
333 
334  cpl_parameterlist_append(recipe->parameters, p);
335 
336  return 0;
337 } /* muse_lsf_create() */
338 
339 /*----------------------------------------------------------------------------*/
350 /*----------------------------------------------------------------------------*/
351 static int
352 muse_lsf_params_fill(muse_lsf_params_t *aParams, cpl_parameterlist *aParameters)
353 {
354  cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
355  cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
356  cpl_parameter *p;
357 
358  p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.nifu");
359  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
360  aParams->nifu = cpl_parameter_get_int(p);
361 
362  p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.overscan");
363  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
364  aParams->overscan = cpl_parameter_get_string(p);
365 
366  p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.ovscreject");
367  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
368  aParams->ovscreject = cpl_parameter_get_string(p);
369 
370  p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.ovscsigma");
371  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
372  aParams->ovscsigma = cpl_parameter_get_double(p);
373 
374  p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.ovscignore");
375  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
376  aParams->ovscignore = cpl_parameter_get_int(p);
377 
378  p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.combine");
379  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
380  aParams->combine_s = cpl_parameter_get_string(p);
381  aParams->combine =
382  (!strcasecmp(aParams->combine_s, "average")) ? MUSE_LSF_PARAM_COMBINE_AVERAGE :
383  (!strcasecmp(aParams->combine_s, "median")) ? MUSE_LSF_PARAM_COMBINE_MEDIAN :
384  (!strcasecmp(aParams->combine_s, "minmax")) ? MUSE_LSF_PARAM_COMBINE_MINMAX :
385  (!strcasecmp(aParams->combine_s, "sigclip")) ? MUSE_LSF_PARAM_COMBINE_SIGCLIP :
386  MUSE_LSF_PARAM_COMBINE_INVALID_VALUE;
387  cpl_ensure_code(aParams->combine != MUSE_LSF_PARAM_COMBINE_INVALID_VALUE,
388  CPL_ERROR_ILLEGAL_INPUT);
389 
390  p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.save_subtracted");
391  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
392  aParams->save_subtracted = cpl_parameter_get_bool(p);
393 
394  p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.line_quality");
395  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
396  aParams->line_quality = cpl_parameter_get_int(p);
397 
398  p = cpl_parameterlist_find(aParameters, "muse.muse_lsf.merge");
399  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
400  aParams->merge = cpl_parameter_get_bool(p);
401 
402  return 0;
403 } /* muse_lsf_params_fill() */
404 
405 /*----------------------------------------------------------------------------*/
412 /*----------------------------------------------------------------------------*/
413 static int
414 muse_lsf_exec(cpl_plugin *aPlugin)
415 {
416  if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
417  return -1;
418  }
419  cpl_recipe *recipe = (cpl_recipe *)aPlugin;
420  cpl_msg_set_threadid_on();
421 
422  cpl_frameset *usedframes = cpl_frameset_new(),
423  *outframes = cpl_frameset_new();
424  muse_lsf_params_t params;
425  muse_lsf_params_fill(&params, recipe->parameters);
426 
427  cpl_errorstate prestate = cpl_errorstate_get();
428 
429  if (params.nifu < -1 || params.nifu > kMuseNumIFUs) {
430  cpl_msg_error(__func__, "Please specify a valid IFU number (between 1 and "
431  "%d), 0 (to process all IFUs consecutively), or -1 (to "
432  "process all IFUs in parallel) using --nifu.", kMuseNumIFUs);
433  return -1;
434  } /* if invalid params.nifu */
435 
436  cpl_boolean donotmerge = CPL_FALSE; /* depending on nifu we may not merge */
437  int rc = 0;
438  if (params.nifu > 0) {
439  muse_processing *proc = muse_processing_new("muse_lsf",
440  recipe);
441  rc = muse_lsf_compute(proc, &params);
442  cpl_frameset_join(usedframes, proc->usedframes);
443  cpl_frameset_join(outframes, proc->outframes);
445  donotmerge = CPL_TRUE; /* after processing one IFU, merging cannot work */
446  } else if (params.nifu < 0) { /* parallel processing */
447  int *rcs = cpl_calloc(kMuseNumIFUs, sizeof(int));
448  int nifu;
449  #pragma omp parallel for default(none) \
450  shared(outframes, params, rcs, recipe, usedframes)
451  for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
452  muse_processing *proc = muse_processing_new("muse_lsf",
453  recipe);
454  muse_lsf_params_t *pars = cpl_malloc(sizeof(muse_lsf_params_t));
455  memcpy(pars, &params, sizeof(muse_lsf_params_t));
456  pars->nifu = nifu;
457  int *rci = rcs + (nifu - 1);
458  *rci = muse_lsf_compute(proc, pars);
459  if (rci && cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
460  *rci = 0;
461  }
462  cpl_free(pars);
463  #pragma omp critical(muse_processing_used_frames)
464  cpl_frameset_join(usedframes, proc->usedframes);
465  #pragma omp critical(muse_processing_output_frames)
466  cpl_frameset_join(outframes, proc->outframes);
468  } /* for nifu */
469  /* non-parallel loop to propagate the "worst" return code; *
470  * since we only ever return -1, any non-zero code is propagated */
471  for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
472  if (rcs[nifu-1] != 0) {
473  rc = rcs[nifu-1];
474  } /* if */
475  } /* for nifu */
476  cpl_free(rcs);
477  } else { /* serial processing */
478  for (params.nifu = 1; params.nifu <= kMuseNumIFUs && !rc; params.nifu++) {
479  muse_processing *proc = muse_processing_new("muse_lsf",
480  recipe);
481  rc = muse_lsf_compute(proc, &params);
482  if (rc && cpl_error_get_code() == MUSE_ERROR_CHIP_NOT_LIVE) {
483  rc = 0;
484  }
485  cpl_frameset_join(usedframes, proc->usedframes);
486  cpl_frameset_join(outframes, proc->outframes);
488  } /* for nifu */
489  } /* else */
490  UNUSED_ARGUMENT(donotmerge); /* maybe this is not going to be used below */
491 
492  if (!cpl_errorstate_is_equal(prestate)) {
493  /* dump all errors from this recipe in chronological order */
494  cpl_errorstate_dump(prestate, CPL_FALSE, muse_cplerrorstate_dump_some);
495  /* reset message level to not get the same errors displayed again by esorex */
496  cpl_msg_set_level(CPL_MSG_INFO);
497  }
498  /* clean up duplicates in framesets of used and output frames */
501 
502  /* merge output products from the up to 24 IFUs */
503  if (params.merge && !donotmerge) {
504  muse_utils_frameset_merge_frames(outframes);
505  }
506 
507  /* to get esorex to see our classification (frame groups etc.), *
508  * replace the original frameset with the list of used frames *
509  * before appending product output frames */
510  /* keep the same pointer, so just erase all frames, not delete the frameset */
511  muse_cplframeset_erase_all(recipe->frames);
512  cpl_frameset_join(recipe->frames, usedframes);
513  cpl_frameset_join(recipe->frames, outframes);
514  cpl_frameset_delete(usedframes);
515  cpl_frameset_delete(outframes);
516  return rc;
517 } /* muse_lsf_exec() */
518 
519 /*----------------------------------------------------------------------------*/
526 /*----------------------------------------------------------------------------*/
527 static int
528 muse_lsf_destroy(cpl_plugin *aPlugin)
529 {
530  /* Get the recipe from the plugin */
531  cpl_recipe *recipe;
532  if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
533  recipe = (cpl_recipe *)aPlugin;
534  } else {
535  return -1;
536  }
537 
538  /* Clean up */
539  cpl_parameterlist_delete(recipe->parameters);
541  return 0;
542 } /* muse_lsf_destroy() */
543 
544 /*----------------------------------------------------------------------------*/
554 /*----------------------------------------------------------------------------*/
555 int
556 cpl_plugin_get_info(cpl_pluginlist *aList)
557 {
558  cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
559  cpl_plugin *plugin = &recipe->interface;
560 
561  char *helptext;
563  helptext = cpl_sprintf("%s%s", muse_lsf_help,
564  muse_lsf_help_esorex);
565  } else {
566  helptext = cpl_sprintf("%s", muse_lsf_help);
567  }
568 
569  /* Initialize the CPL plugin stuff for this module */
570  cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
571  CPL_PLUGIN_TYPE_RECIPE,
572  "muse_lsf",
573  "Compute the LSF",
574  helptext,
575  "Ole Streicher",
576  "usd-help@eso.org",
578  muse_lsf_create,
579  muse_lsf_exec,
580  muse_lsf_destroy);
581  cpl_pluginlist_append(aList, plugin);
582  cpl_free(helptext);
583 
584  return 0;
585 } /* cpl_plugin_get_info() */
586 
void muse_processing_delete(muse_processing *aProcessing)
Free the muse_processing structure.
double ovscsigma
If the deviation of mean overscan levels between a raw input image and the reference image is higher ...
Definition: muse_lsf_z.h:59
muse_cplframework_type muse_cplframework(void)
Return the CPL framework the recipe is run under.
const char * ovscreject
This influences how values are rejected when computing overscan statistics. Either no rejection at al...
Definition: muse_lsf_z.h:56
int nifu
IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in ...
Definition: muse_lsf_z.h:50
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.
Definition: muse_lsf_z.h:53
int save_subtracted
Save the pixel table after the LSF subtraction.
Definition: muse_lsf_z.h:70
int merge
Merge output products from different IFUs into a common file.
Definition: muse_lsf_z.h:76
int ovscignore
The number of pixels of the overscan adjacent to the data region of the CCD that are ignored when com...
Definition: muse_lsf_z.h:62
cpl_frameset * usedframes
muse_processing * muse_processing_new(const char *aName, cpl_recipe *aRecipe)
Create a new processing structure.
const char * muse_get_license(void)
Get the pipeline copyright and license.
Definition: muse_utils.c:84
const char * combine_s
Type of lampwise image combination to use. (as string)
Definition: muse_lsf_z.h:67
muse_frame_mode
Structure to hold the parameters of the muse_lsf recipe.
Definition: muse_lsf_z.h:48
cpl_frameset * outframes
int line_quality
Minimal quality flag in line catalog for selection.
Definition: muse_lsf_z.h:73
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.
int combine
Type of lampwise image combination to use.
Definition: muse_lsf_z.h:65
cpl_error_code muse_cplframeset_erase_duplicate(cpl_frameset *aFrames)
Erase all duplicate frames from a frameset.
cpl_error_code muse_cplframeset_erase_all(cpl_frameset *aFrames)
Erase all frames in a frameset.
void muse_processinginfo_register(cpl_recipe *, cpl_recipeconfig *, muse_processing_prepare_header_func *, muse_processing_get_frame_level_func *, muse_processing_get_frame_mode_func *)
Register extended functionalities for MUSE recipes.
cpl_error_code muse_processing_prepare_property(cpl_propertylist *, const char *, cpl_type, const char *)
Prepare and check the specified property.