MUSE Pipeline Reference Manual  2.1.1
muse_geometry_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_geometry_z.h" /* in turn includes muse.h */
36 
37 /*----------------------------------------------------------------------------*/
71 /*----------------------------------------------------------------------------*/
74 /*----------------------------------------------------------------------------*
75  * Static variables *
76  *----------------------------------------------------------------------------*/
77 static const char *muse_geometry_help =
78  "Processing first works separately on each IFU of the raw input data (in parallel): it trims the raw data and records the overscan statistics, subtracts the bias and converts them from adu to count. Optionally, the dark can be subtracted and the data can be divided by the flat-field. The data of all input mask exposures is then averaged. The averaged image together with the trace table and wavelength calibration as well as the line catalog are used to detect spots. The detection windows are used to measure the spots on all images of the sequence, the result is saved, with information on the measured PSF, in the spots tables. Then properties of all slices are computed, first separately on each IFU to determine the peak position of the mask for each slice and its angle, subsequently the width and horizontal position. Then, the result of all IFUs is analyzed together to produce a refined horizontal position, applying global shifts to each IFU as needed. The vertical position is then determined using the known slice ordering on the sky; the relative peak positions are put into sequence, taking into account the vertical offsets of the pinholes in the mask. The table is then cleaned up from intermediate debug data. If the --smooth parameter is set to a positive value, it is used to do a sigma-clipped smoothing within each slicer stack, for a more regular appearance of the output table. The table is then saved. As a last optional step, additional raw input data is reduced using the newly geometry to produce an image of the field of view. If these exposures contain smooth features, they can be used as a visual check of the quality of the geometrical calibration.";
79 
80 static const char *muse_geometry_help_esorex =
81  "\n\nInput frames for raw frame tag \"MASK\":\n"
82  "\n Frame tag Type Req #Fr Description"
83  "\n -------------------- ---- --- --- ------------"
84  "\n MASK raw Y >=50 The full exposure sequence of raw multi-pinhole mask images"
85  "\n MASTER_BIAS calib Y 1 Master bias"
86  "\n MASTER_DARK calib . 1 Master dark"
87  "\n MASTER_FLAT calib . 1 Master flat"
88  "\n TRACE_TABLE calib Y 1 Trace table"
89  "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
90  "\n LINE_CATALOG calib Y 1 List of arc lines"
91  "\n BADPIX_TABLE calib . Known bad pixels"
92  "\n MASK_CHECK calib . Some other optional raw frame, ideally a trace mask exposure or something else with smooth features."
93  "\n\nProduct frames for raw frame tag \"MASK\":\n"
94  "\n Frame tag Level Description"
95  "\n -------------------- -------- ------------"
96  "\n MASK_REDUCED final Reduced pinhole mask images"
97  "\n MASK_COMBINED final Combined pinhole mask image"
98  "\n SPOTS_TABLE final Measurements of all detected spots on all input images."
99  "\n GEOMETRY_UNSMOOTHED final Relative positions of the slices in the field of view (unsmoothed)"
100  "\n GEOMETRY_TABLE final Relative positions of the slices in the field of view"
101  "\n GEOMETRY_CUBE final Cube of the field of view to check the geometry calibration. It is restricted to the wavelength range given in the parameters and contains an integrated image (\"white\") over this range."
102  "\n GEOMETRY_CHECK final Optional field of view image to check the geometry calibration, integrated over the wavelength range given in the parameters.";
103 
104 /*----------------------------------------------------------------------------*/
112 /*----------------------------------------------------------------------------*/
113 static cpl_recipeconfig *
114 muse_geometry_new_recipeconfig(void)
115 {
116  cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
117 
118  cpl_recipeconfig_set_tag(recipeconfig, "MASK", 50, -1);
119  cpl_recipeconfig_set_input(recipeconfig, "MASK", "MASTER_BIAS", 1, 1);
120  cpl_recipeconfig_set_input(recipeconfig, "MASK", "MASTER_DARK", -1, 1);
121  cpl_recipeconfig_set_input(recipeconfig, "MASK", "MASTER_FLAT", -1, 1);
122  cpl_recipeconfig_set_input(recipeconfig, "MASK", "TRACE_TABLE", 1, 1);
123  cpl_recipeconfig_set_input(recipeconfig, "MASK", "WAVECAL_TABLE", 1, 1);
124  cpl_recipeconfig_set_input(recipeconfig, "MASK", "LINE_CATALOG", 1, 1);
125  cpl_recipeconfig_set_input(recipeconfig, "MASK", "BADPIX_TABLE", -1, -1);
126  cpl_recipeconfig_set_input(recipeconfig, "MASK", "MASK_CHECK", -1, -1);
127  cpl_recipeconfig_set_output(recipeconfig, "MASK", "MASK_REDUCED");
128  cpl_recipeconfig_set_output(recipeconfig, "MASK", "MASK_COMBINED");
129  cpl_recipeconfig_set_output(recipeconfig, "MASK", "SPOTS_TABLE");
130  cpl_recipeconfig_set_output(recipeconfig, "MASK", "GEOMETRY_UNSMOOTHED");
131  cpl_recipeconfig_set_output(recipeconfig, "MASK", "GEOMETRY_TABLE");
132  cpl_recipeconfig_set_output(recipeconfig, "MASK", "GEOMETRY_CUBE");
133 
134  return recipeconfig;
135 } /* muse_geometry_new_recipeconfig() */
136 
137 /*----------------------------------------------------------------------------*/
147 /*----------------------------------------------------------------------------*/
148 static cpl_error_code
149 muse_geometry_prepare_header(const char *aFrametag, cpl_propertylist *aHeader)
150 {
151  cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
152  cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
153  if (!strcmp(aFrametag, "MASK_REDUCED")) {
154  } else if (!strcmp(aFrametag, "MASK_COMBINED")) {
155  } else if (!strcmp(aFrametag, "SPOTS_TABLE")) {
156  muse_processing_prepare_property(aHeader, "ESO QC GEO EXP[0-9]+ FWHM MEAN",
157  CPL_TYPE_FLOAT,
158  "[pix] Average FWHM of all bright spots in exposure k.");
159  muse_processing_prepare_property(aHeader, "ESO QC GEO EXP[0-9]+ FWHM MEDIAN",
160  CPL_TYPE_FLOAT,
161  "[pix] Median FWHM of all bright spots in exposure k.");
162  muse_processing_prepare_property(aHeader, "ESO QC GEO EXP[0-9]+ FWHM STDEV",
163  CPL_TYPE_FLOAT,
164  "[pix] Standard deviation of FWHM of all bright spots in exposure k.");
165  muse_processing_prepare_property(aHeader, "ESO QC GEO FWHM MEAN",
166  CPL_TYPE_FLOAT,
167  "[pix] Average of the average FWHM of all bright spots in all exposures.");
168  muse_processing_prepare_property(aHeader, "ESO QC GEO FWHM STDEV",
169  CPL_TYPE_FLOAT,
170  "[pix] Standard deviation of the average FWHM of all bright spots in all exposures.");
171  } else if (!strcmp(aFrametag, "GEOMETRY_UNSMOOTHED")) {
172  } else if (!strcmp(aFrametag, "GEOMETRY_TABLE")) {
173  muse_processing_prepare_property(aHeader, "ESO QC GEO IFU[0-9]+ ANGLE",
174  CPL_TYPE_FLOAT,
175  "[deg] Angle of the mask with respect to the slicer system, computed as median angle of all slices of this IFU for which the measurement could be made.");
176  muse_processing_prepare_property(aHeader, "ESO QC GEO IFU[0-9]+ WLEN[0-9]+",
177  CPL_TYPE_FLOAT,
178  "[Angstrom] Nominal wavelength of arc line l.");
179  muse_processing_prepare_property(aHeader, "ESO QC GEO IFU[0-9]+ WLEN[0-9]+ FLUX MEAN",
180  CPL_TYPE_FLOAT,
181  "Average integrated flux in all spots at reference wavelength l.");
182  muse_processing_prepare_property(aHeader, "ESO QC GEO IFU[0-9]+ WLEN[0-9]+ FLUX MEDIAN",
183  CPL_TYPE_FLOAT,
184  "Median integrated flux in all spots at reference wavelength l.");
185  muse_processing_prepare_property(aHeader, "ESO QC GEO IFU[0-9]+ WLEN[0-9]+ FLUX STDEV",
186  CPL_TYPE_FLOAT,
187  "Standard deviation of integrated flux in all spots at reference wavelength l.");
188  muse_processing_prepare_property(aHeader, "ESO QC GEO IFU[0-9]+ GAPPOS MEAN",
189  CPL_TYPE_FLOAT,
190  "[pix] Average position of the central gap between the 12 slices of IFU m.");
191  muse_processing_prepare_property(aHeader, "ESO QC GEO MASK ANGLE",
192  CPL_TYPE_FLOAT,
193  "[deg] Angle of the mask with respect to the slicer system, computed as median angle of all slices of all IFUs for which the measurement could be made.");
194  muse_processing_prepare_property(aHeader, "ESO QC GEO GAPPOS MEAN",
195  CPL_TYPE_FLOAT,
196  "[pix] Average of all mean central gap positions of all IFUs for which the measurement could be made.");
197  muse_processing_prepare_property(aHeader, "ESO QC GEO GAPPOS STDEV",
198  CPL_TYPE_FLOAT,
199  "[pix] Standard deviation of all mean central gap positions of all IFUs for which the measurement could be made.");
200  muse_processing_prepare_property(aHeader, "ESO QC GEO SMOOTH NX",
201  CPL_TYPE_INT,
202  "Number of slices that were changed with respect to x position by smoothing. Gets set to -1 if smoothing is inactive.");
203  muse_processing_prepare_property(aHeader, "ESO QC GEO SMOOTH NY",
204  CPL_TYPE_INT,
205  "Number of slices that were changed with respect to y position by smoothing. Gets set to -1 if smoothing is inactive.");
206  muse_processing_prepare_property(aHeader, "ESO QC GEO SMOOTH NANGLE",
207  CPL_TYPE_INT,
208  "Number of slices that were changed with respect to angle by smoothing. Gets set to -1 if smoothing is inactive.");
209  muse_processing_prepare_property(aHeader, "ESO QC GEO SMOOTH NWIDTH",
210  CPL_TYPE_INT,
211  "Number of slices that were changed with respect to width by smoothing. Gets set to -1 if smoothing is inactive.");
212  } else if (!strcmp(aFrametag, "GEOMETRY_CUBE")) {
213  } else if (!strcmp(aFrametag, "GEOMETRY_CHECK")) {
214  } else {
215  cpl_msg_warning(__func__, "Frame tag %s is not defined", aFrametag);
216  return CPL_ERROR_ILLEGAL_INPUT;
217  }
218  return CPL_ERROR_NONE;
219 } /* muse_geometry_prepare_header() */
220 
221 /*----------------------------------------------------------------------------*/
230 /*----------------------------------------------------------------------------*/
231 static cpl_frame_level
232 muse_geometry_get_frame_level(const char *aFrametag)
233 {
234  if (!aFrametag) {
235  return CPL_FRAME_LEVEL_NONE;
236  }
237  if (!strcmp(aFrametag, "MASK_REDUCED")) {
238  return CPL_FRAME_LEVEL_FINAL;
239  }
240  if (!strcmp(aFrametag, "MASK_COMBINED")) {
241  return CPL_FRAME_LEVEL_FINAL;
242  }
243  if (!strcmp(aFrametag, "SPOTS_TABLE")) {
244  return CPL_FRAME_LEVEL_FINAL;
245  }
246  if (!strcmp(aFrametag, "GEOMETRY_UNSMOOTHED")) {
247  return CPL_FRAME_LEVEL_FINAL;
248  }
249  if (!strcmp(aFrametag, "GEOMETRY_TABLE")) {
250  return CPL_FRAME_LEVEL_FINAL;
251  }
252  if (!strcmp(aFrametag, "GEOMETRY_CUBE")) {
253  return CPL_FRAME_LEVEL_FINAL;
254  }
255  if (!strcmp(aFrametag, "GEOMETRY_CHECK")) {
256  return CPL_FRAME_LEVEL_FINAL;
257  }
258  return CPL_FRAME_LEVEL_NONE;
259 } /* muse_geometry_get_frame_level() */
260 
261 /*----------------------------------------------------------------------------*/
270 /*----------------------------------------------------------------------------*/
271 static muse_frame_mode
272 muse_geometry_get_frame_mode(const char *aFrametag)
273 {
274  if (!aFrametag) {
275  return MUSE_FRAME_MODE_ALL;
276  }
277  if (!strcmp(aFrametag, "MASK_REDUCED")) {
278  return MUSE_FRAME_MODE_ALL;
279  }
280  if (!strcmp(aFrametag, "MASK_COMBINED")) {
281  return MUSE_FRAME_MODE_MASTER;
282  }
283  if (!strcmp(aFrametag, "SPOTS_TABLE")) {
284  return MUSE_FRAME_MODE_MASTER;
285  }
286  if (!strcmp(aFrametag, "GEOMETRY_UNSMOOTHED")) {
287  return MUSE_FRAME_MODE_MASTER;
288  }
289  if (!strcmp(aFrametag, "GEOMETRY_TABLE")) {
290  return MUSE_FRAME_MODE_MASTER;
291  }
292  if (!strcmp(aFrametag, "GEOMETRY_CUBE")) {
293  return MUSE_FRAME_MODE_MASTER;
294  }
295  if (!strcmp(aFrametag, "GEOMETRY_CHECK")) {
296  return MUSE_FRAME_MODE_ALL;
297  }
298  return MUSE_FRAME_MODE_ALL;
299 } /* muse_geometry_get_frame_mode() */
300 
301 /*----------------------------------------------------------------------------*/
311 /*----------------------------------------------------------------------------*/
312 static int
313 muse_geometry_create(cpl_plugin *aPlugin)
314 {
315  /* Check that the plugin is part of a valid recipe */
316  cpl_recipe *recipe;
317  if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
318  recipe = (cpl_recipe *)aPlugin;
319  } else {
320  return -1;
321  }
322 
323  /* register the extended processing information (new FITS header creation, *
324  * getting of the frame level for a certain tag) */
326  muse_geometry_new_recipeconfig(),
327  muse_geometry_prepare_header,
328  muse_geometry_get_frame_level,
329  muse_geometry_get_frame_mode);
330 
331  /* XXX initialize timing in messages *
332  * since at least esorex is too stupid to turn it on, we have to do it */
334  cpl_msg_set_time_on();
335  }
336 
337  /* Create the parameter list in the cpl_recipe object */
338  recipe->parameters = cpl_parameterlist_new();
339  /* Fill the parameters list */
340  cpl_parameter *p;
341 
342  /* --ifu1: First IFU to analyze. */
343  p = cpl_parameter_new_range("muse.muse_geometry.ifu1",
344  CPL_TYPE_INT,
345  "First IFU to analyze.",
346  "muse.muse_geometry",
347  (int)1,
348  (int)1,
349  (int)24);
350  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ifu1");
351  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ifu1");
352  if (!getenv("MUSE_EXPERT_USER")) {
353  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
354  }
355 
356  cpl_parameterlist_append(recipe->parameters, p);
357 
358  /* --ifu2: Last IFU to analyze. */
359  p = cpl_parameter_new_range("muse.muse_geometry.ifu2",
360  CPL_TYPE_INT,
361  "Last IFU to analyze.",
362  "muse.muse_geometry",
363  (int)24,
364  (int)1,
365  (int)24);
366  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "ifu2");
367  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ifu2");
368  if (!getenv("MUSE_EXPERT_USER")) {
369  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
370  }
371 
372  cpl_parameterlist_append(recipe->parameters, p);
373 
374  /* --sigma: Sigma detection level for spot detection, in terms of median deviation above the median. */
375  p = cpl_parameter_new_value("muse.muse_geometry.sigma",
376  CPL_TYPE_DOUBLE,
377  "Sigma detection level for spot detection, in terms of median deviation above the median.",
378  "muse.muse_geometry",
379  (double)2.2);
380  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "sigma");
381  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sigma");
382 
383  cpl_parameterlist_append(recipe->parameters, p);
384 
385  /* --centroid: Type of centroiding and FWHM determination to use for all spot measurements: simple barycenter method or using a Gaussian fit. */
386  p = cpl_parameter_new_enum("muse.muse_geometry.centroid",
387  CPL_TYPE_STRING,
388  "Type of centroiding and FWHM determination to use for all spot measurements: simple barycenter method or using a Gaussian fit.",
389  "muse.muse_geometry",
390  (const char *)"gaussian",
391  2,
392  (const char *)"barycenter",
393  (const char *)"gaussian");
394  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "centroid");
395  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "centroid");
396 
397  cpl_parameterlist_append(recipe->parameters, p);
398 
399  /* --smooth: Use this sigma-level cut for smoothing of the output table within each slicer stack. Set to non-positive value to deactivate smoothing. */
400  p = cpl_parameter_new_value("muse.muse_geometry.smooth",
401  CPL_TYPE_DOUBLE,
402  "Use this sigma-level cut for smoothing of the output table within each slicer stack. Set to non-positive value to deactivate smoothing.",
403  "muse.muse_geometry",
404  (double)1.5);
405  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "smooth");
406  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "smooth");
407 
408  cpl_parameterlist_append(recipe->parameters, p);
409 
410  /* --lambdamin: When passing any MASK_CHECK frames in the input, use this lower wavelength cut before reconstructing the image. */
411  p = cpl_parameter_new_value("muse.muse_geometry.lambdamin",
412  CPL_TYPE_DOUBLE,
413  "When passing any MASK_CHECK frames in the input, use this lower wavelength cut before reconstructing the image.",
414  "muse.muse_geometry",
415  (double)6800.);
416  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdamin");
417  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdamin");
418  if (!getenv("MUSE_EXPERT_USER")) {
419  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
420  }
421 
422  cpl_parameterlist_append(recipe->parameters, p);
423 
424  /* --lambdamax: When passing any MASK_CHECK frames in the input, use this upper wavelength cut before reconstructing the image. */
425  p = cpl_parameter_new_value("muse.muse_geometry.lambdamax",
426  CPL_TYPE_DOUBLE,
427  "When passing any MASK_CHECK frames in the input, use this upper wavelength cut before reconstructing the image.",
428  "muse.muse_geometry",
429  (double)7200.);
430  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdamax");
431  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdamax");
432  if (!getenv("MUSE_EXPERT_USER")) {
433  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
434  }
435 
436  cpl_parameterlist_append(recipe->parameters, p);
437 
438  return 0;
439 } /* muse_geometry_create() */
440 
441 /*----------------------------------------------------------------------------*/
452 /*----------------------------------------------------------------------------*/
453 static int
454 muse_geometry_params_fill(muse_geometry_params_t *aParams, cpl_parameterlist *aParameters)
455 {
456  cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
457  cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
458  cpl_parameter *p;
459 
460  p = cpl_parameterlist_find(aParameters, "muse.muse_geometry.ifu1");
461  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
462  aParams->ifu1 = cpl_parameter_get_int(p);
463 
464  p = cpl_parameterlist_find(aParameters, "muse.muse_geometry.ifu2");
465  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
466  aParams->ifu2 = cpl_parameter_get_int(p);
467 
468  p = cpl_parameterlist_find(aParameters, "muse.muse_geometry.sigma");
469  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
470  aParams->sigma = cpl_parameter_get_double(p);
471 
472  p = cpl_parameterlist_find(aParameters, "muse.muse_geometry.centroid");
473  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
474  aParams->centroid_s = cpl_parameter_get_string(p);
475  aParams->centroid =
476  (!strcasecmp(aParams->centroid_s, "barycenter")) ? MUSE_GEOMETRY_PARAM_CENTROID_BARYCENTER :
477  (!strcasecmp(aParams->centroid_s, "gaussian")) ? MUSE_GEOMETRY_PARAM_CENTROID_GAUSSIAN :
478  MUSE_GEOMETRY_PARAM_CENTROID_INVALID_VALUE;
479  cpl_ensure_code(aParams->centroid != MUSE_GEOMETRY_PARAM_CENTROID_INVALID_VALUE,
480  CPL_ERROR_ILLEGAL_INPUT);
481 
482  p = cpl_parameterlist_find(aParameters, "muse.muse_geometry.smooth");
483  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
484  aParams->smooth = cpl_parameter_get_double(p);
485 
486  p = cpl_parameterlist_find(aParameters, "muse.muse_geometry.lambdamin");
487  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
488  aParams->lambdamin = cpl_parameter_get_double(p);
489 
490  p = cpl_parameterlist_find(aParameters, "muse.muse_geometry.lambdamax");
491  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
492  aParams->lambdamax = cpl_parameter_get_double(p);
493 
494  return 0;
495 } /* muse_geometry_params_fill() */
496 
497 /*----------------------------------------------------------------------------*/
504 /*----------------------------------------------------------------------------*/
505 static int
506 muse_geometry_exec(cpl_plugin *aPlugin)
507 {
508  if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
509  return -1;
510  }
512  cpl_recipe *recipe = (cpl_recipe *)aPlugin;
513  cpl_msg_set_threadid_on();
514 
515  cpl_frameset *usedframes = cpl_frameset_new(),
516  *outframes = cpl_frameset_new();
517  muse_geometry_params_t params;
518  muse_geometry_params_fill(&params, recipe->parameters);
519 
520  cpl_errorstate prestate = cpl_errorstate_get();
521 
522  muse_processing *proc = muse_processing_new("muse_geometry",
523  recipe);
524  int rc = muse_geometry_compute(proc, &params);
525  cpl_frameset_join(usedframes, proc->usedframes);
526  cpl_frameset_join(outframes, proc->outframes);
528 
529  if (!cpl_errorstate_is_equal(prestate)) {
530  /* dump all errors from this recipe in chronological order */
531  cpl_errorstate_dump(prestate, CPL_FALSE, muse_cplerrorstate_dump_some);
532  /* reset message level to not get the same errors displayed again by esorex */
533  cpl_msg_set_level(CPL_MSG_INFO);
534  }
535  /* clean up duplicates in framesets of used and output frames */
538 
539  /* to get esorex to see our classification (frame groups etc.), *
540  * replace the original frameset with the list of used frames *
541  * before appending product output frames */
542  /* keep the same pointer, so just erase all frames, not delete the frameset */
543  muse_cplframeset_erase_all(recipe->frames);
544  cpl_frameset_join(recipe->frames, usedframes);
545  cpl_frameset_join(recipe->frames, outframes);
546  cpl_frameset_delete(usedframes);
547  cpl_frameset_delete(outframes);
548  return rc;
549 } /* muse_geometry_exec() */
550 
551 /*----------------------------------------------------------------------------*/
558 /*----------------------------------------------------------------------------*/
559 static int
560 muse_geometry_destroy(cpl_plugin *aPlugin)
561 {
562  /* Get the recipe from the plugin */
563  cpl_recipe *recipe;
564  if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
565  recipe = (cpl_recipe *)aPlugin;
566  } else {
567  return -1;
568  }
569 
570  /* Clean up */
571  cpl_parameterlist_delete(recipe->parameters);
573  return 0;
574 } /* muse_geometry_destroy() */
575 
576 /*----------------------------------------------------------------------------*/
586 /*----------------------------------------------------------------------------*/
587 int
588 cpl_plugin_get_info(cpl_pluginlist *aList)
589 {
590  cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
591  cpl_plugin *plugin = &recipe->interface;
592 
593  char *helptext;
595  helptext = cpl_sprintf("%s%s", muse_geometry_help,
596  muse_geometry_help_esorex);
597  } else {
598  helptext = cpl_sprintf("%s", muse_geometry_help);
599  }
600 
601  /* Initialize the CPL plugin stuff for this module */
602  cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
603  CPL_PLUGIN_TYPE_RECIPE,
604  "muse_geometry",
605  "Compute relative location of the slices within the field of view and measure the instrumental PSF on the detectors.",
606  helptext,
607  "Peter Weilbacher",
608  "usd-help@eso.org",
610  muse_geometry_create,
611  muse_geometry_exec,
612  muse_geometry_destroy);
613  cpl_pluginlist_append(aList, plugin);
614  cpl_free(helptext);
615 
616  return 0;
617 } /* cpl_plugin_get_info() */
618 
void muse_processing_delete(muse_processing *aProcessing)
Free the muse_processing structure.
const char * centroid_s
Type of centroiding and FWHM determination to use for all spot measurements: simple barycenter method...
double sigma
Sigma detection level for spot detection, in terms of median deviation above the median.
double lambdamax
When passing any MASK_CHECK frames in the input, use this upper wavelength cut before reconstructing ...
muse_cplframework_type muse_cplframework(void)
Return the CPL framework the recipe is run under.
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
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 centroid
Type of centroiding and FWHM determination to use for all spot measurements: simple barycenter method...
double smooth
Use this sigma-level cut for smoothing of the output table within each slicer stack. Set to non-positive value to deactivate smoothing.
cpl_error_code muse_cplframeset_erase_duplicate(cpl_frameset *aFrames)
Erase all duplicate frames from a frameset.
int ifu2
Last IFU to analyze.
cpl_error_code muse_cplframeset_erase_all(cpl_frameset *aFrames)
Erase all frames in a frameset.
int ifu1
First IFU to analyze.
double lambdamin
When passing any MASK_CHECK frames in the input, use this lower wavelength cut before reconstructing ...
void muse_processinginfo_register(cpl_recipe *, cpl_recipeconfig *, muse_processing_prepare_header_func *, muse_processing_get_frame_level_func *, muse_processing_get_frame_mode_func *)
Register extended functionalities for MUSE recipes.
void muse_processing_recipeinfo(cpl_plugin *)
Output main pipeline configuration, inputs, and parameters.
cpl_error_code muse_processing_prepare_property(cpl_propertylist *, const char *, cpl_type, const char *)
Prepare and check the specified property.
Structure to hold the parameters of the muse_geometry recipe.