MUSE Pipeline Reference Manual  0.18.1
muse_qi_mask_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_qi_mask_z.h" /* in turn includes muse.h */
36 
37 /*----------------------------------------------------------------------------*/
57 /*----------------------------------------------------------------------------*/
60 /*----------------------------------------------------------------------------*
61  * Static variables *
62  *----------------------------------------------------------------------------*/
63 static const char *muse_qi_mask_help =
64  "Trace and wavelength calibration tables (24 of them each, one per IFU) are used to build wavelength maps. If the input data is binned, the wavelength maps are binned in the same way (averaging of pixels). The wavelength maps are then thresholded to create masks of the desired wavelength range. Finally, the mask is &untrimmed&, i.e. empty regions for the pre- and overscans are added (in a simple way, assuming quadrants of equal size, and padding of 32 pixels on all quadrant edges). Note: this recipe is not part of the main MUSE pipeline but to be used in the integration phase to create image masks until the system is fully qualified. It therefore does only minimal error checking.";
65 
66 static const char *muse_qi_mask_help_esorex =
67  "\n\nInput frames for raw frame tag \"BIAS\":\n"
68  "\n Frame tag Type Req #Fr Description"
69  "\n -------------------- ---- --- --- ------------"
70  "\n BIAS raw . 1 Raw bias"
71  "\n TRACE_TABLE calib Y 1 Tracing table for all slices"
72  "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
73  "\n\nProduct frames for raw frame tag \"BIAS\":\n"
74  "\n Frame tag Level Description"
75  "\n -------------------- -------- ------------"
76  "\n MASK_IMAGE final Image masks for quick image reconstruction";
77 
78 /*----------------------------------------------------------------------------*/
86 /*----------------------------------------------------------------------------*/
87 static cpl_recipeconfig *
88 muse_qi_mask_new_recipeconfig(void)
89 {
90  cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
91  const char *tag;
92 
93  tag = "BIAS";
94  cpl_recipeconfig_set_tag(recipeconfig, tag, -1, 1);
95  cpl_recipeconfig_set_input(recipeconfig, tag, "TRACE_TABLE", 1, 1);
96  cpl_recipeconfig_set_input(recipeconfig, tag, "WAVECAL_TABLE", 1, 1);
97  cpl_recipeconfig_set_output(recipeconfig, tag, "MASK_IMAGE");
98 
99  return recipeconfig;
100 } /* muse_qi_mask_new_recipeconfig() */
101 
102 /*----------------------------------------------------------------------------*/
112 /*----------------------------------------------------------------------------*/
113 static cpl_error_code
114 muse_qi_mask_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, "MASK_IMAGE")) {
119  } else {
120  cpl_msg_warning(__func__, "Frame tag %s is not defined", aFrametag);
121  return CPL_ERROR_ILLEGAL_INPUT;
122  }
123  return CPL_ERROR_NONE;
124 } /* muse_qi_mask_prepare_header() */
125 
126 /*----------------------------------------------------------------------------*/
135 /*----------------------------------------------------------------------------*/
136 static cpl_frame_level
137 muse_qi_mask_get_frame_level(const char *aFrametag)
138 {
139  if (!aFrametag) {
140  return CPL_FRAME_LEVEL_NONE;
141  }
142  if (!strcmp(aFrametag, "MASK_IMAGE")) {
143  return CPL_FRAME_LEVEL_FINAL;
144  }
145  return CPL_FRAME_LEVEL_NONE;
146 } /* muse_qi_mask_get_frame_level() */
147 
148 /*----------------------------------------------------------------------------*/
157 /*----------------------------------------------------------------------------*/
158 static muse_frame_mode
159 muse_qi_mask_get_frame_mode(const char *aFrametag)
160 {
161  if (!aFrametag) {
162  return MUSE_FRAME_MODE_ALL;
163  }
164  if (!strcmp(aFrametag, "MASK_IMAGE")) {
165  return MUSE_FRAME_MODE_ALL;
166  }
167  return MUSE_FRAME_MODE_ALL;
168 } /* muse_qi_mask_get_frame_mode() */
169 
170 /*----------------------------------------------------------------------------*/
180 /*----------------------------------------------------------------------------*/
181 static int
182 muse_qi_mask_create(cpl_plugin *aPlugin)
183 {
184  /* Check that the plugin is part of a valid recipe */
185  cpl_recipe *recipe;
186  if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
187  recipe = (cpl_recipe *)aPlugin;
188  } else {
189  return -1;
190  }
191 
192  /* register the extended processing information (new FITS header creation, *
193  * getting of the frame level for a certain tag) */
195  muse_qi_mask_new_recipeconfig(),
196  muse_qi_mask_prepare_header,
197  muse_qi_mask_get_frame_level,
198  muse_qi_mask_get_frame_mode);
199 
200  /* XXX initialize timing in messages *
201  * since at least esorex is too stupid to turn it on, we have to do it */
203  cpl_msg_set_time_on();
204  }
205 
206  /* Create the parameter list in the cpl_recipe object */
207  recipe->parameters = cpl_parameterlist_new();
208  /* Fill the parameters list */
209  cpl_parameter *p;
210 
211  /* --wrange: Wavelength range (filter name) of the setup. Set this to "custom" to set up a new wavelength range using the wmin/wmax parameters. */
212  p = cpl_parameter_new_enum("muse.muse_qi_mask.wrange",
213  CPL_TYPE_STRING,
214  "Wavelength range (filter name) of the setup. Set this to \"custom\" to set up a new wavelength range using the wmin/wmax parameters.",
215  "muse.muse_qi_mask",
216  (const char *)"MUSE",
217  6,
218  (const char *)"MUSE",
219  (const char *)"B",
220  (const char *)"V",
221  (const char *)"R",
222  (const char *)"I",
223  (const char *)"custom");
224  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "wrange");
225  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wrange");
226 
227  cpl_parameterlist_append(recipe->parameters, p);
228 
229  /* --wmin: Lower boundary of the wavelength range [Angstrom]. Only used when wrange=custom. */
230  p = cpl_parameter_new_value("muse.muse_qi_mask.wmin",
231  CPL_TYPE_DOUBLE,
232  "Lower boundary of the wavelength range [Angstrom]. Only used when wrange=custom.",
233  "muse.muse_qi_mask",
234  (double)4650.);
235  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "wmin");
236  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wmin");
237 
238  cpl_parameterlist_append(recipe->parameters, p);
239 
240  /* --wmax: Lower boundary of the wavelength range [Angstrom]. Only used when wrange=custom. */
241  p = cpl_parameter_new_value("muse.muse_qi_mask.wmax",
242  CPL_TYPE_DOUBLE,
243  "Lower boundary of the wavelength range [Angstrom]. Only used when wrange=custom.",
244  "muse.muse_qi_mask",
245  (double)9300.);
246  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "wmax");
247  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wmax");
248 
249  cpl_parameterlist_append(recipe->parameters, p);
250 
251  /* --nifu: IFU to handle. If set to 0, all IFUs are processed serially, which is the recommendation for this recipe, since only then all extensions end up in the same output file. */
252  p = cpl_parameter_new_range("muse.muse_qi_mask.nifu",
253  CPL_TYPE_INT,
254  "IFU to handle. If set to 0, all IFUs are processed serially, which is the recommendation for this recipe, since only then all extensions end up in the same output file.",
255  "muse.muse_qi_mask",
256  (int)0,
257  (int)0,
258  (int)24);
259  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nifu");
260  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nifu");
261 
262  cpl_parameterlist_append(recipe->parameters, p);
263 
264  return 0;
265 } /* muse_qi_mask_create() */
266 
267 /*----------------------------------------------------------------------------*/
278 /*----------------------------------------------------------------------------*/
279 static int
280 muse_qi_mask_params_fill(muse_qi_mask_params_t *aParams, cpl_parameterlist *aParameters)
281 {
282  cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
283  cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
284  cpl_parameter *p;
285 
286  p = cpl_parameterlist_find(aParameters, "muse.muse_qi_mask.wrange");
287  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
288  aParams->wrange_s = cpl_parameter_get_string(p);
289  aParams->wrange =
290  (!strcasecmp(aParams->wrange_s, "MUSE")) ? MUSE_QI_MASK_PARAM_WRANGE_MUSE :
291  (!strcasecmp(aParams->wrange_s, "B")) ? MUSE_QI_MASK_PARAM_WRANGE_B :
292  (!strcasecmp(aParams->wrange_s, "V")) ? MUSE_QI_MASK_PARAM_WRANGE_V :
293  (!strcasecmp(aParams->wrange_s, "R")) ? MUSE_QI_MASK_PARAM_WRANGE_R :
294  (!strcasecmp(aParams->wrange_s, "I")) ? MUSE_QI_MASK_PARAM_WRANGE_I :
295  (!strcasecmp(aParams->wrange_s, "custom")) ? MUSE_QI_MASK_PARAM_WRANGE_CUSTOM :
296  MUSE_QI_MASK_PARAM_WRANGE_INVALID_VALUE;
297  cpl_ensure_code(aParams->wrange != MUSE_QI_MASK_PARAM_WRANGE_INVALID_VALUE,
298  CPL_ERROR_ILLEGAL_INPUT);
299 
300  p = cpl_parameterlist_find(aParameters, "muse.muse_qi_mask.wmin");
301  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
302  aParams->wmin = cpl_parameter_get_double(p);
303 
304  p = cpl_parameterlist_find(aParameters, "muse.muse_qi_mask.wmax");
305  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
306  aParams->wmax = cpl_parameter_get_double(p);
307 
308  p = cpl_parameterlist_find(aParameters, "muse.muse_qi_mask.nifu");
309  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
310  aParams->nifu = cpl_parameter_get_int(p);
311 
312  return 0;
313 } /* muse_qi_mask_params_fill() */
314 
315 /*----------------------------------------------------------------------------*/
322 /*----------------------------------------------------------------------------*/
323 static int
324 muse_qi_mask_exec(cpl_plugin *aPlugin)
325 {
326  if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
327  return -1;
328  }
329  cpl_recipe *recipe = (cpl_recipe *)aPlugin;
330  cpl_msg_set_threadid_on();
331 
332  cpl_frameset *usedframes = cpl_frameset_new(),
333  *outframes = cpl_frameset_new();
334  muse_qi_mask_params_t params;
335  muse_qi_mask_params_fill(&params, recipe->parameters);
336 
337  cpl_errorstate prestate = cpl_errorstate_get();
338 
339  muse_processing *proc = muse_processing_new("muse_qi_mask",
340  recipe);
341  int rc = muse_qi_mask_compute(proc, &params);
342  cpl_frameset_join(usedframes, proc->usedFrames);
343  cpl_frameset_join(outframes, proc->outputFrames);
345 
346  if (!cpl_errorstate_is_equal(prestate)) {
347  /* dump all errors from this recipe in chronological order */
348  cpl_errorstate_dump(prestate, CPL_FALSE, muse_cplerrorstate_dump_some);
349  /* reset message level to not get the same errors displayed again by esorex */
350  cpl_msg_set_level(CPL_MSG_INFO);
351  }
352  /* clean up duplicates in framesets of used and output frames */
355  /* to get esorex to see our classification (frame groups etc.), *
356  * replace the original frameset with the list of used frames *
357  * before appending product output frames */
358  /* keep the same pointer, so just erase all frames, not delete the frameset */
359  muse_cplframeset_erase_all(recipe->frames);
360  cpl_frameset_join(recipe->frames, usedframes);
361  cpl_frameset_join(recipe->frames, outframes);
362  cpl_frameset_delete(usedframes);
363  cpl_frameset_delete(outframes);
364  return rc;
365 } /* muse_qi_mask_exec() */
366 
367 /*----------------------------------------------------------------------------*/
374 /*----------------------------------------------------------------------------*/
375 static int
376 muse_qi_mask_destroy(cpl_plugin *aPlugin)
377 {
378  /* Get the recipe from the plugin */
379  cpl_recipe *recipe;
380  if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
381  recipe = (cpl_recipe *)aPlugin;
382  } else {
383  return -1;
384  }
385 
386  /* Clean up */
387  cpl_parameterlist_delete(recipe->parameters);
389  return 0;
390 } /* muse_qi_mask_destroy() */
391 
392 /*----------------------------------------------------------------------------*/
402 /*----------------------------------------------------------------------------*/
403 int
404 cpl_plugin_get_info(cpl_pluginlist *aList)
405 {
406  cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
407  cpl_plugin *plugin = &recipe->interface;
408 
409  char *helptext;
411  helptext = cpl_sprintf("%s%s", muse_qi_mask_help,
412  muse_qi_mask_help_esorex);
413  } else {
414  helptext = cpl_sprintf("%s", muse_qi_mask_help);
415  }
416 
417  /* Initialize the CPL plugin stuff for this module */
418  cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
419  CPL_PLUGIN_TYPE_RECIPE,
420  "muse_qi_mask",
421  "Create image masks for use with the quick image reconstruction.",
422  helptext,
423  "Peter Weilbacher",
424  "usd-help@eso.org",
426  muse_qi_mask_create,
427  muse_qi_mask_exec,
428  muse_qi_mask_destroy);
429  cpl_pluginlist_append(aList, plugin);
430  cpl_free(helptext);
431 
432  return 0;
433 } /* cpl_plugin_get_info() */
434 
void muse_processing_delete(muse_processing *aProcessing)
Free the muse_processing structure.
muse_cplframework_type muse_cplframework(void)
Return the CPL framework the recipe is run under.
const char * muse_get_license(void)
Get the pipeline copyright and license.
Definition: muse_utils.c:80
double wmax
Lower boundary of the wavelength range [Angstrom]. Only used when wrange=custom.
muse_processing * muse_processing_new(const char *aRecipeName, cpl_recipe *aRecipe)
Create a new processing structure.
muse_frame_mode
cpl_frameset * outputFrames
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.
const char * wrange_s
Wavelength range (filter name) of the setup. Set this to "custom" to set up a new wavelength range us...
int wrange
Wavelength range (filter name) of the setup. Set this to "custom" to set up a new wavelength range us...
double wmin
Lower boundary of the wavelength range [Angstrom]. Only used when wrange=custom.
Structure to hold the parameters of the muse_qi_mask 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.
cpl_frameset * usedFrames
int nifu
IFU to handle. If set to 0, all IFUs are processed serially, which is the recommendation for this rec...