MUSE Pipeline Reference Manual  2.1.1
muse_standard_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_standard_z.h" /* in turn includes muse.h */
36 
37 /*----------------------------------------------------------------------------*/
66 /*----------------------------------------------------------------------------*/
69 /*----------------------------------------------------------------------------*
70  * Static variables *
71  *----------------------------------------------------------------------------*/
72 static const char *muse_standard_help =
73  "Merge pixel tables from all IFUs and correct for differential atmospheric refraction. To derive the flux response curve, integrate the flux of all objects detected within the field of view using the given profile. Select one object as the standard star (either the brightest or the one nearest one, depending on --select) and compare its measured fluxes to tabulated fluxes to derive the sensitivity over wavelength. Postprocess this sensitivity curve to mark wavelength ranges affected by telluric absorption. Interpolate over the telluric regions and derive a telluric correction spectrum for them. The final response cuve is then linearly extrapolated to the largest possible MUSE wavelength range and smoothed (with the method given by --smooth). The derivation of the telluric correction spectrum assumes that the star has a smooth spectrum within the telluric regions. If there are more than one exposure given in the input data, the derivation of the flux response and telluric corrections are done separately for each exposure. For each exposure, an image containing the extracted stellar spectra and the datacube used for flux integration are saved, together with collapsed images for each given filter.";
74 
75 static const char *muse_standard_help_esorex =
76  "\n\nInput frames for raw frame tag \"PIXTABLE_STD\":\n"
77  "\n Frame tag Type Req #Fr Description"
78  "\n -------------------- ---- --- --- ------------"
79  "\n PIXTABLE_STD raw Y Pixel table of a standard star field"
80  "\n EXTINCT_TABLE calib Y 1 Atmospheric extinction table"
81  "\n STD_FLUX_TABLE calib Y Flux reference table for standard stars"
82  "\n TELLURIC_REGIONS calib . 1 Definition of telluric regions"
83  "\n FILTER_LIST calib . 1 File to be used to create field-of-view images."
84  "\n\nProduct frames for raw frame tag \"PIXTABLE_STD\":\n"
85  "\n Frame tag Level Description"
86  "\n -------------------- -------- ------------"
87  "\n DATACUBE_STD final Reduced standard star field exposure"
88  "\n STD_FLUXES final The integrated flux per wavelength of all detected sources"
89  "\n STD_RESPONSE final Response curve as derived from standard star(s)"
90  "\n STD_TELLURIC final Telluric absorption as derived from standard star(s)";
91 
92 /*----------------------------------------------------------------------------*/
100 /*----------------------------------------------------------------------------*/
101 static cpl_recipeconfig *
102 muse_standard_new_recipeconfig(void)
103 {
104  cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
105 
106  cpl_recipeconfig_set_tag(recipeconfig, "PIXTABLE_STD", 1, -1);
107  cpl_recipeconfig_set_input(recipeconfig, "PIXTABLE_STD", "EXTINCT_TABLE", 1, 1);
108  cpl_recipeconfig_set_input(recipeconfig, "PIXTABLE_STD", "STD_FLUX_TABLE", 1, -1);
109  cpl_recipeconfig_set_input(recipeconfig, "PIXTABLE_STD", "TELLURIC_REGIONS", -1, 1);
110  cpl_recipeconfig_set_input(recipeconfig, "PIXTABLE_STD", "FILTER_LIST", -1, 1);
111  cpl_recipeconfig_set_output(recipeconfig, "PIXTABLE_STD", "DATACUBE_STD");
112  cpl_recipeconfig_set_output(recipeconfig, "PIXTABLE_STD", "STD_FLUXES");
113  cpl_recipeconfig_set_output(recipeconfig, "PIXTABLE_STD", "STD_RESPONSE");
114  cpl_recipeconfig_set_output(recipeconfig, "PIXTABLE_STD", "STD_TELLURIC");
115 
116  return recipeconfig;
117 } /* muse_standard_new_recipeconfig() */
118 
119 /*----------------------------------------------------------------------------*/
129 /*----------------------------------------------------------------------------*/
130 static cpl_error_code
131 muse_standard_prepare_header(const char *aFrametag, cpl_propertylist *aHeader)
132 {
133  cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
134  cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
135  if (!strcmp(aFrametag, "DATACUBE_STD")) {
136  muse_processing_prepare_property(aHeader, "ESO QC STANDARD NDET",
137  CPL_TYPE_INT,
138  "Number of detected sources in output cube.");
139  muse_processing_prepare_property(aHeader, "ESO QC STANDARD LAMBDA",
140  CPL_TYPE_FLOAT,
141  "[Angstrom] Wavelength of plane in combined cube that was used for object detection.");
142  muse_processing_prepare_property(aHeader, "ESO QC STANDARD POS[0-9]+ X",
143  CPL_TYPE_FLOAT,
144  "[pix] Position of source k in x-direction in output cube. If the FWHM measurement fails, this value will be -1.");
145  muse_processing_prepare_property(aHeader, "ESO QC STANDARD POS[0-9]+ Y",
146  CPL_TYPE_FLOAT,
147  "[pix] Position of source k in y-direction in output cube. If the FWHM measurement fails, this value will be -1.");
148  muse_processing_prepare_property(aHeader, "ESO QC STANDARD FWHM[0-9]+ X",
149  CPL_TYPE_FLOAT,
150  "[arcsec] FWHM of source k in x-direction in output cube. If the FWHM measurement fails, this value will be -1.");
151  muse_processing_prepare_property(aHeader, "ESO QC STANDARD FWHM[0-9]+ Y",
152  CPL_TYPE_FLOAT,
153  "[arcsec] FWHM of source k in y-direction in output cube. If the FWHM measurement fails, this value will be -1.");
154  muse_processing_prepare_property(aHeader, "ESO QC STANDARD FWHM NVALID",
155  CPL_TYPE_INT,
156  "Number of detected sources with valid FWHM in output cube.");
157  muse_processing_prepare_property(aHeader, "ESO QC STANDARD FWHM MEDIAN",
158  CPL_TYPE_FLOAT,
159  "[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.");
160  muse_processing_prepare_property(aHeader, "ESO QC STANDARD FWHM MAD",
161  CPL_TYPE_FLOAT,
162  "[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.");
163  } else if (!strcmp(aFrametag, "STD_FLUXES")) {
164  } else if (!strcmp(aFrametag, "STD_RESPONSE")) {
165  muse_processing_prepare_property(aHeader, "ESO QC STANDARD STARNAME",
166  CPL_TYPE_STRING,
167  "Name of the standard star used for the throughput / zeropoint calculation.");
168  muse_processing_prepare_property(aHeader, "ESO QC STANDARD THRU5000",
169  CPL_TYPE_FLOAT,
170  "Throughput computed at 5000 +/- 100 Angstrom.");
171  muse_processing_prepare_property(aHeader, "ESO QC STANDARD THRU6000",
172  CPL_TYPE_FLOAT,
173  "Throughput computed at 6000 +/- 100 Angstrom.");
174  muse_processing_prepare_property(aHeader, "ESO QC STANDARD THRU7000",
175  CPL_TYPE_FLOAT,
176  "Throughput computed at 7000 +/- 100 Angstrom.");
177  muse_processing_prepare_property(aHeader, "ESO QC STANDARD THRU8000",
178  CPL_TYPE_FLOAT,
179  "Throughput computed at 8000 +/- 100 Angstrom.");
180  muse_processing_prepare_property(aHeader, "ESO QC STANDARD THRU9000",
181  CPL_TYPE_FLOAT,
182  "Throughput computed at 9000 +/- 100 Angstrom.");
183  muse_processing_prepare_property(aHeader, "ESO QC STANDARD ZP V",
184  CPL_TYPE_FLOAT,
185  "[mag] Zeropoint in Johnson V filter. zp = -2.5 log10(fobs_V / fref_V), where fobs_V was integrated over the filter curve and converted to f_lambda using the known effective VLT area. (optional) Only computed if FILTER_LIST and corresponding --filter is given.");
186  muse_processing_prepare_property(aHeader, "ESO QC STANDARD ZP R",
187  CPL_TYPE_FLOAT,
188  "[mag] Zeropoint in Cousins R filter. zp = -2.5 log10(fobs_R / fref_R), where fobs_R was integrated over the filter curve and converted to f_lambda using the known effective VLT area. (optional) Only computed if FILTER_LIST and corresponding --filter is given.");
189  muse_processing_prepare_property(aHeader, "ESO QC STANDARD ZP I",
190  CPL_TYPE_FLOAT,
191  "[mag] Zeropoint in Cousins I filter. zp = -2.5 log10(fobs_I / fref_I), where fobs_I was integrated over the filter curve and converted to f_lambda using the known effective VLT area. (optional) Only computed if FILTER_LIST and corresponding --filter is given.");
192  } else if (!strcmp(aFrametag, "STD_TELLURIC")) {
193  } else {
194  cpl_msg_warning(__func__, "Frame tag %s is not defined", aFrametag);
195  return CPL_ERROR_ILLEGAL_INPUT;
196  }
197  return CPL_ERROR_NONE;
198 } /* muse_standard_prepare_header() */
199 
200 /*----------------------------------------------------------------------------*/
209 /*----------------------------------------------------------------------------*/
210 static cpl_frame_level
211 muse_standard_get_frame_level(const char *aFrametag)
212 {
213  if (!aFrametag) {
214  return CPL_FRAME_LEVEL_NONE;
215  }
216  if (!strcmp(aFrametag, "DATACUBE_STD")) {
217  return CPL_FRAME_LEVEL_FINAL;
218  }
219  if (!strcmp(aFrametag, "STD_FLUXES")) {
220  return CPL_FRAME_LEVEL_FINAL;
221  }
222  if (!strcmp(aFrametag, "STD_RESPONSE")) {
223  return CPL_FRAME_LEVEL_FINAL;
224  }
225  if (!strcmp(aFrametag, "STD_TELLURIC")) {
226  return CPL_FRAME_LEVEL_FINAL;
227  }
228  return CPL_FRAME_LEVEL_NONE;
229 } /* muse_standard_get_frame_level() */
230 
231 /*----------------------------------------------------------------------------*/
240 /*----------------------------------------------------------------------------*/
241 static muse_frame_mode
242 muse_standard_get_frame_mode(const char *aFrametag)
243 {
244  if (!aFrametag) {
245  return MUSE_FRAME_MODE_ALL;
246  }
247  if (!strcmp(aFrametag, "DATACUBE_STD")) {
249  }
250  if (!strcmp(aFrametag, "STD_FLUXES")) {
252  }
253  if (!strcmp(aFrametag, "STD_RESPONSE")) {
255  }
256  if (!strcmp(aFrametag, "STD_TELLURIC")) {
258  }
259  return MUSE_FRAME_MODE_ALL;
260 } /* muse_standard_get_frame_mode() */
261 
262 /*----------------------------------------------------------------------------*/
272 /*----------------------------------------------------------------------------*/
273 static int
274 muse_standard_create(cpl_plugin *aPlugin)
275 {
276  /* Check that the plugin is part of a valid recipe */
277  cpl_recipe *recipe;
278  if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
279  recipe = (cpl_recipe *)aPlugin;
280  } else {
281  return -1;
282  }
283 
284  /* register the extended processing information (new FITS header creation, *
285  * getting of the frame level for a certain tag) */
287  muse_standard_new_recipeconfig(),
288  muse_standard_prepare_header,
289  muse_standard_get_frame_level,
290  muse_standard_get_frame_mode);
291 
292  /* XXX initialize timing in messages *
293  * since at least esorex is too stupid to turn it on, we have to do it */
295  cpl_msg_set_time_on();
296  }
297 
298  /* Create the parameter list in the cpl_recipe object */
299  recipe->parameters = cpl_parameterlist_new();
300  /* Fill the parameters list */
301  cpl_parameter *p;
302 
303  /* --profile: Type of flux integration to use. "gaussian" and "moffat" use 2D profile fitting, circle and square are non-optimal flux integrators. */
304  p = cpl_parameter_new_enum("muse.muse_standard.profile",
305  CPL_TYPE_STRING,
306  "Type of flux integration to use. \"gaussian\" and \"moffat\" use 2D profile fitting, circle and square are non-optimal flux integrators.",
307  "muse.muse_standard",
308  (const char *)"moffat",
309  4,
310  (const char *)"gaussian",
311  (const char *)"moffat",
312  (const char *)"circle",
313  (const char *)"square");
314  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "profile");
315  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "profile");
316 
317  cpl_parameterlist_append(recipe->parameters, p);
318 
319  /* --select: How to select the star for flux integration, "flux" uses the brightest star in the field, "distance" uses the detection nearest to the approximate coordinates of the reference source. */
320  p = cpl_parameter_new_enum("muse.muse_standard.select",
321  CPL_TYPE_STRING,
322  "How to select the star for flux integration, \"flux\" uses the brightest star in the field, \"distance\" uses the detection nearest to the approximate coordinates of the reference source.",
323  "muse.muse_standard",
324  (const char *)"distance",
325  2,
326  (const char *)"flux",
327  (const char *)"distance");
328  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "select");
329  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "select");
330 
331  cpl_parameterlist_append(recipe->parameters, p);
332 
333  /* --smooth: How to smooth the response curve before writing it to disk. "none" does not do any kind of smoothing (such a response curve is only useful, if smoothed externally; "median" does a median-filter of 15 Angstrom half-width; "ppoly" fits piecewise cubic polynomials (each one across 2x150 Angstrom width) postprocessed by a sliding average filter of 15 Angstrom half-width. */
334  p = cpl_parameter_new_enum("muse.muse_standard.smooth",
335  CPL_TYPE_STRING,
336  "How to smooth the response curve before writing it to disk. \"none\" does not do any kind of smoothing (such a response curve is only useful, if smoothed externally; \"median\" does a median-filter of 15 Angstrom half-width; \"ppoly\" fits piecewise cubic polynomials (each one across 2x150 Angstrom width) postprocessed by a sliding average filter of 15 Angstrom half-width.",
337  "muse.muse_standard",
338  (const char *)"ppoly",
339  3,
340  (const char *)"none",
341  (const char *)"median",
342  (const char *)"ppoly");
343  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "smooth");
344  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "smooth");
345 
346  cpl_parameterlist_append(recipe->parameters, p);
347 
348  /* --lambdamin: Cut off the data below this wavelength after loading the pixel table(s). */
349  p = cpl_parameter_new_value("muse.muse_standard.lambdamin",
350  CPL_TYPE_DOUBLE,
351  "Cut off the data below this wavelength after loading the pixel table(s).",
352  "muse.muse_standard",
353  (double)4000.);
354  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdamin");
355  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdamin");
356 
357  cpl_parameterlist_append(recipe->parameters, p);
358 
359  /* --lambdamax: Cut off the data above this wavelength after loading the pixel table(s). */
360  p = cpl_parameter_new_value("muse.muse_standard.lambdamax",
361  CPL_TYPE_DOUBLE,
362  "Cut off the data above this wavelength after loading the pixel table(s).",
363  "muse.muse_standard",
364  (double)10000.);
365  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdamax");
366  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdamax");
367 
368  cpl_parameterlist_append(recipe->parameters, p);
369 
370  /* --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. */
371  p = cpl_parameter_new_value("muse.muse_standard.lambdaref",
372  CPL_TYPE_DOUBLE,
373  "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.",
374  "muse.muse_standard",
375  (double)7000.);
376  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdaref");
377  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdaref");
378 
379  cpl_parameterlist_append(recipe->parameters, p);
380 
381  /* --darcheck: Carry out a check of the theoretical DAR correction using source centroiding. If "correct" it will also apply an empirical correction. */
382  p = cpl_parameter_new_enum("muse.muse_standard.darcheck",
383  CPL_TYPE_STRING,
384  "Carry out a check of the theoretical DAR correction using source centroiding. If \"correct\" it will also apply an empirical correction.",
385  "muse.muse_standard",
386  (const char *)"none",
387  3,
388  (const char *)"none",
389  (const char *)"check",
390  (const char *)"correct");
391  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "darcheck");
392  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "darcheck");
393 
394  cpl_parameterlist_append(recipe->parameters, p);
395 
396  /* --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. If the zeropoint QC parameters are wanted, make sure to add "Johnson_V,Cousins_R,Cousins_I". */
397  p = cpl_parameter_new_value("muse.muse_standard.filter",
398  CPL_TYPE_STRING,
399  "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. If the zeropoint QC parameters are wanted, make sure to add \"Johnson_V,Cousins_R,Cousins_I\".",
400  "muse.muse_standard",
401  (const char *)"white");
402  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "filter");
403  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "filter");
404 
405  cpl_parameterlist_append(recipe->parameters, p);
406 
407  return 0;
408 } /* muse_standard_create() */
409 
410 /*----------------------------------------------------------------------------*/
421 /*----------------------------------------------------------------------------*/
422 static int
423 muse_standard_params_fill(muse_standard_params_t *aParams, cpl_parameterlist *aParameters)
424 {
425  cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
426  cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
427  cpl_parameter *p;
428 
429  p = cpl_parameterlist_find(aParameters, "muse.muse_standard.profile");
430  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
431  aParams->profile_s = cpl_parameter_get_string(p);
432  aParams->profile =
433  (!strcasecmp(aParams->profile_s, "gaussian")) ? MUSE_STANDARD_PARAM_PROFILE_GAUSSIAN :
434  (!strcasecmp(aParams->profile_s, "moffat")) ? MUSE_STANDARD_PARAM_PROFILE_MOFFAT :
435  (!strcasecmp(aParams->profile_s, "circle")) ? MUSE_STANDARD_PARAM_PROFILE_CIRCLE :
436  (!strcasecmp(aParams->profile_s, "square")) ? MUSE_STANDARD_PARAM_PROFILE_SQUARE :
437  MUSE_STANDARD_PARAM_PROFILE_INVALID_VALUE;
438  cpl_ensure_code(aParams->profile != MUSE_STANDARD_PARAM_PROFILE_INVALID_VALUE,
439  CPL_ERROR_ILLEGAL_INPUT);
440 
441  p = cpl_parameterlist_find(aParameters, "muse.muse_standard.select");
442  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
443  aParams->select_s = cpl_parameter_get_string(p);
444  aParams->select =
445  (!strcasecmp(aParams->select_s, "flux")) ? MUSE_STANDARD_PARAM_SELECT_FLUX :
446  (!strcasecmp(aParams->select_s, "distance")) ? MUSE_STANDARD_PARAM_SELECT_DISTANCE :
447  MUSE_STANDARD_PARAM_SELECT_INVALID_VALUE;
448  cpl_ensure_code(aParams->select != MUSE_STANDARD_PARAM_SELECT_INVALID_VALUE,
449  CPL_ERROR_ILLEGAL_INPUT);
450 
451  p = cpl_parameterlist_find(aParameters, "muse.muse_standard.smooth");
452  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
453  aParams->smooth_s = cpl_parameter_get_string(p);
454  aParams->smooth =
455  (!strcasecmp(aParams->smooth_s, "none")) ? MUSE_STANDARD_PARAM_SMOOTH_NONE :
456  (!strcasecmp(aParams->smooth_s, "median")) ? MUSE_STANDARD_PARAM_SMOOTH_MEDIAN :
457  (!strcasecmp(aParams->smooth_s, "ppoly")) ? MUSE_STANDARD_PARAM_SMOOTH_PPOLY :
458  MUSE_STANDARD_PARAM_SMOOTH_INVALID_VALUE;
459  cpl_ensure_code(aParams->smooth != MUSE_STANDARD_PARAM_SMOOTH_INVALID_VALUE,
460  CPL_ERROR_ILLEGAL_INPUT);
461 
462  p = cpl_parameterlist_find(aParameters, "muse.muse_standard.lambdamin");
463  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
464  aParams->lambdamin = cpl_parameter_get_double(p);
465 
466  p = cpl_parameterlist_find(aParameters, "muse.muse_standard.lambdamax");
467  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
468  aParams->lambdamax = cpl_parameter_get_double(p);
469 
470  p = cpl_parameterlist_find(aParameters, "muse.muse_standard.lambdaref");
471  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
472  aParams->lambdaref = cpl_parameter_get_double(p);
473 
474  p = cpl_parameterlist_find(aParameters, "muse.muse_standard.darcheck");
475  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
476  aParams->darcheck_s = cpl_parameter_get_string(p);
477  aParams->darcheck =
478  (!strcasecmp(aParams->darcheck_s, "none")) ? MUSE_STANDARD_PARAM_DARCHECK_NONE :
479  (!strcasecmp(aParams->darcheck_s, "check")) ? MUSE_STANDARD_PARAM_DARCHECK_CHECK :
480  (!strcasecmp(aParams->darcheck_s, "correct")) ? MUSE_STANDARD_PARAM_DARCHECK_CORRECT :
481  MUSE_STANDARD_PARAM_DARCHECK_INVALID_VALUE;
482  cpl_ensure_code(aParams->darcheck != MUSE_STANDARD_PARAM_DARCHECK_INVALID_VALUE,
483  CPL_ERROR_ILLEGAL_INPUT);
484 
485  p = cpl_parameterlist_find(aParameters, "muse.muse_standard.filter");
486  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
487  aParams->filter = cpl_parameter_get_string(p);
488 
489  return 0;
490 } /* muse_standard_params_fill() */
491 
492 /*----------------------------------------------------------------------------*/
499 /*----------------------------------------------------------------------------*/
500 static int
501 muse_standard_exec(cpl_plugin *aPlugin)
502 {
503  if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
504  return -1;
505  }
507  cpl_recipe *recipe = (cpl_recipe *)aPlugin;
508  cpl_msg_set_threadid_on();
509 
510  cpl_frameset *usedframes = cpl_frameset_new(),
511  *outframes = cpl_frameset_new();
512  muse_standard_params_t params;
513  muse_standard_params_fill(&params, recipe->parameters);
514 
515  cpl_errorstate prestate = cpl_errorstate_get();
516 
517  muse_processing *proc = muse_processing_new("muse_standard",
518  recipe);
519  int rc = muse_standard_compute(proc, &params);
520  cpl_frameset_join(usedframes, proc->usedframes);
521  cpl_frameset_join(outframes, proc->outframes);
523 
524  if (!cpl_errorstate_is_equal(prestate)) {
525  /* dump all errors from this recipe in chronological order */
526  cpl_errorstate_dump(prestate, CPL_FALSE, muse_cplerrorstate_dump_some);
527  /* reset message level to not get the same errors displayed again by esorex */
528  cpl_msg_set_level(CPL_MSG_INFO);
529  }
530  /* clean up duplicates in framesets of used and output frames */
533 
534  /* to get esorex to see our classification (frame groups etc.), *
535  * replace the original frameset with the list of used frames *
536  * before appending product output frames */
537  /* keep the same pointer, so just erase all frames, not delete the frameset */
538  muse_cplframeset_erase_all(recipe->frames);
539  cpl_frameset_join(recipe->frames, usedframes);
540  cpl_frameset_join(recipe->frames, outframes);
541  cpl_frameset_delete(usedframes);
542  cpl_frameset_delete(outframes);
543  return rc;
544 } /* muse_standard_exec() */
545 
546 /*----------------------------------------------------------------------------*/
553 /*----------------------------------------------------------------------------*/
554 static int
555 muse_standard_destroy(cpl_plugin *aPlugin)
556 {
557  /* Get the recipe from the plugin */
558  cpl_recipe *recipe;
559  if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
560  recipe = (cpl_recipe *)aPlugin;
561  } else {
562  return -1;
563  }
564 
565  /* Clean up */
566  cpl_parameterlist_delete(recipe->parameters);
568  return 0;
569 } /* muse_standard_destroy() */
570 
571 /*----------------------------------------------------------------------------*/
581 /*----------------------------------------------------------------------------*/
582 int
583 cpl_plugin_get_info(cpl_pluginlist *aList)
584 {
585  cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
586  cpl_plugin *plugin = &recipe->interface;
587 
588  char *helptext;
590  helptext = cpl_sprintf("%s%s", muse_standard_help,
591  muse_standard_help_esorex);
592  } else {
593  helptext = cpl_sprintf("%s", muse_standard_help);
594  }
595 
596  /* Initialize the CPL plugin stuff for this module */
597  cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
598  CPL_PLUGIN_TYPE_RECIPE,
599  "muse_standard",
600  "Create a flux response curve from a standard star exposure.",
601  helptext,
602  "Peter Weilbacher",
603  "usd-help@eso.org",
605  muse_standard_create,
606  muse_standard_exec,
607  muse_standard_destroy);
608  cpl_pluginlist_append(aList, plugin);
609  cpl_free(helptext);
610 
611  return 0;
612 } /* cpl_plugin_get_info() */
613 
void muse_processing_delete(muse_processing *aProcessing)
Free the muse_processing structure.
int profile
Type of flux integration to use. "gaussian" and "moffat" use 2D profile fitting, circle and square ar...
muse_cplframework_type muse_cplframework(void)
Return the CPL framework the recipe is run under.
int select
How to select the star for flux integration, "flux" uses the brightest star in the field...
int smooth
How to smooth the response curve before writing it to disk. "none" does not do any kind of smoothing ...
const char * profile_s
Type of flux integration to use. "gaussian" and "moffat" use 2D profile fitting, circle and square ar...
const char * select_s
How to select the star for flux integration, "flux" uses the brightest star in the field...
const char * darcheck_s
Carry out a check of the theoretical DAR correction using source centroiding. If "correct" it will al...
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:83
muse_frame_mode
cpl_frameset * outframes
double lambdamin
Cut off the data below this wavelength after loading the pixel table(s).
void muse_cplerrorstate_dump_some(unsigned aCurrent, unsigned aFirst, unsigned aLast)
Dump some CPL errors.
double lambdaref
Reference wavelength used for correction of differential atmospheric refraction. The R-band (peak wav...
void muse_processinginfo_delete(cpl_recipe *)
Clear all information from the processing info and from the recipe config.
double lambdamax
Cut off the data above this wavelength after loading the pixel table(s).
Structure to hold the parameters of the muse_standard recipe.
cpl_error_code muse_cplframeset_erase_duplicate(cpl_frameset *aFrames)
Erase all duplicate frames from a frameset.
cpl_error_code muse_cplframeset_erase_all(cpl_frameset *aFrames)
Erase all frames in a frameset.
void muse_processinginfo_register(cpl_recipe *, cpl_recipeconfig *, muse_processing_prepare_header_func *, muse_processing_get_frame_level_func *, muse_processing_get_frame_mode_func *)
Register extended functionalities for MUSE recipes.
int darcheck
Carry out a check of the theoretical DAR correction using source centroiding. If "correct" it will al...
void muse_processing_recipeinfo(cpl_plugin *)
Output main pipeline configuration, inputs, and parameters.
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...
const char * smooth_s
How to smooth the response curve before writing it to disk. "none" does not do any kind of smoothing ...
cpl_error_code muse_processing_prepare_property(cpl_propertylist *, const char *, cpl_type, const char *)
Prepare and check the specified property.