MUSE Pipeline Reference Manual  2.1.1
muse_astrometry_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_astrometry_z.h" /* in turn includes muse.h */
36 
37 /*----------------------------------------------------------------------------*/
59 /*----------------------------------------------------------------------------*/
62 /*----------------------------------------------------------------------------*
63  * Static variables *
64  *----------------------------------------------------------------------------*/
65 static const char *muse_astrometry_help =
66  "Merge pixel tables from all IFUs, apply correction for differential atmospheric refraction, optionally apply flux calibration and telluric correction (if the necessary input data was given), and resample the data from all exposures into a datacube. Use the cube to detect objects which are then matched to their reference positions from which a two-dimensional WCS solution is computed. The main output is the ASTROMETRY_WCS file which is a bare FITS header containing the world coordinate solution. The secondary product is DATACUBE_ASTROMETRY, it is not needed for further processing but can be used for verification and debugging. It contains the reconstructed cube and two images created from it in further FITS extensions: a white-light image and the special image created from the central planes of the cube used to detect and centroid the stars (as well as its variance).";
67 
68 static const char *muse_astrometry_help_esorex =
69  "\n\nInput frames for raw frame tag \"PIXTABLE_ASTROMETRY\":\n"
70  "\n Frame tag Type Req #Fr Description"
71  "\n -------------------- ---- --- --- ------------"
72  "\n PIXTABLE_ASTROMETRY raw Y Pixel table of an astrometric field"
73  "\n ASTROMETRY_REFERENCE calib Y 1 Reference table of known objects for astrometry"
74  "\n EXTINCT_TABLE calib . 1 Atmospheric extinction table"
75  "\n STD_RESPONSE calib . 1 Response curve as derived from standard star(s)"
76  "\n STD_TELLURIC calib . 1 Telluric absorption as derived from standard star(s)"
77  "\n\nProduct frames for raw frame tag \"PIXTABLE_ASTROMETRY\":\n"
78  "\n Frame tag Level Description"
79  "\n -------------------- -------- ------------"
80  "\n DATACUBE_ASTROMETRY final Reduced astrometry field exposure"
81  "\n ASTROMETRY_WCS final Astrometric solution";
82 
83 /*----------------------------------------------------------------------------*/
91 /*----------------------------------------------------------------------------*/
92 static cpl_recipeconfig *
93 muse_astrometry_new_recipeconfig(void)
94 {
95  cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
96 
97  cpl_recipeconfig_set_tag(recipeconfig, "PIXTABLE_ASTROMETRY", 1, -1);
98  cpl_recipeconfig_set_input(recipeconfig, "PIXTABLE_ASTROMETRY", "ASTROMETRY_REFERENCE", 1, 1);
99  cpl_recipeconfig_set_input(recipeconfig, "PIXTABLE_ASTROMETRY", "EXTINCT_TABLE", -1, 1);
100  cpl_recipeconfig_set_input(recipeconfig, "PIXTABLE_ASTROMETRY", "STD_RESPONSE", -1, 1);
101  cpl_recipeconfig_set_input(recipeconfig, "PIXTABLE_ASTROMETRY", "STD_TELLURIC", -1, 1);
102  cpl_recipeconfig_set_output(recipeconfig, "PIXTABLE_ASTROMETRY", "DATACUBE_ASTROMETRY");
103  cpl_recipeconfig_set_output(recipeconfig, "PIXTABLE_ASTROMETRY", "ASTROMETRY_WCS");
104 
105  return recipeconfig;
106 } /* muse_astrometry_new_recipeconfig() */
107 
108 /*----------------------------------------------------------------------------*/
118 /*----------------------------------------------------------------------------*/
119 static cpl_error_code
120 muse_astrometry_prepare_header(const char *aFrametag, cpl_propertylist *aHeader)
121 {
122  cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
123  cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
124  if (!strcmp(aFrametag, "DATACUBE_ASTROMETRY")) {
125  muse_processing_prepare_property(aHeader, "ESO QC ASTRO NDET",
126  CPL_TYPE_INT,
127  "Number of detected sources in output cube.");
128  muse_processing_prepare_property(aHeader, "ESO QC ASTRO LAMBDA",
129  CPL_TYPE_FLOAT,
130  "[Angstrom] Wavelength of plane in combined cube that was used for object detection.");
131  muse_processing_prepare_property(aHeader, "ESO QC ASTRO POS[0-9]+ X",
132  CPL_TYPE_FLOAT,
133  "[pix] Position of source k in x-direction in output cube. If the FWHM measurement fails, this value will be -1.");
134  muse_processing_prepare_property(aHeader, "ESO QC ASTRO POS[0-9]+ Y",
135  CPL_TYPE_FLOAT,
136  "[pix] Position of source k in y-direction in output cube. If the FWHM measurement fails, this value will be -1.");
137  muse_processing_prepare_property(aHeader, "ESO QC ASTRO FWHM[0-9]+ X",
138  CPL_TYPE_FLOAT,
139  "[arcsec] FWHM of source k in x-direction in output cube. If the FWHM measurement fails, this value will be -1.");
140  muse_processing_prepare_property(aHeader, "ESO QC ASTRO FWHM[0-9]+ Y",
141  CPL_TYPE_FLOAT,
142  "[arcsec] FWHM of source k in y-direction in output cube. If the FWHM measurement fails, this value will be -1.");
143  muse_processing_prepare_property(aHeader, "ESO QC ASTRO FWHM NVALID",
144  CPL_TYPE_INT,
145  "Number of detected sources with valid FWHM in output cube.");
146  muse_processing_prepare_property(aHeader, "ESO QC ASTRO FWHM MEDIAN",
147  CPL_TYPE_FLOAT,
148  "[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.");
149  muse_processing_prepare_property(aHeader, "ESO QC ASTRO FWHM MAD",
150  CPL_TYPE_FLOAT,
151  "[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.");
152  } else if (!strcmp(aFrametag, "ASTROMETRY_WCS")) {
153  muse_processing_prepare_property(aHeader, "ESO QC ASTRO NSTARS",
154  CPL_TYPE_INT,
155  "Number of stars identified for the astrometric solution");
156  muse_processing_prepare_property(aHeader, "ESO QC ASTRO SCALE X",
157  CPL_TYPE_FLOAT,
158  "[arcsec] Computed scale in x-direction");
159  muse_processing_prepare_property(aHeader, "ESO QC ASTRO SCALE Y",
160  CPL_TYPE_FLOAT,
161  "[arcsec] Computed scale in y-direction");
162  muse_processing_prepare_property(aHeader, "ESO QC ASTRO ANGLE X",
163  CPL_TYPE_FLOAT,
164  "[deg] Computed angle in x-direction");
165  muse_processing_prepare_property(aHeader, "ESO QC ASTRO ANGLE Y",
166  CPL_TYPE_FLOAT,
167  "[deg] Computed angle in y-direction");
168  muse_processing_prepare_property(aHeader, "ESO QC ASTRO MEDRES X",
169  CPL_TYPE_FLOAT,
170  "[arcsec] Median residuals of astrometric fit in x-direction");
171  muse_processing_prepare_property(aHeader, "ESO QC ASTRO MEDRES Y",
172  CPL_TYPE_FLOAT,
173  "[arcsec] Median residuals of astrometric fit in y-direction");
174  } else {
175  cpl_msg_warning(__func__, "Frame tag %s is not defined", aFrametag);
176  return CPL_ERROR_ILLEGAL_INPUT;
177  }
178  return CPL_ERROR_NONE;
179 } /* muse_astrometry_prepare_header() */
180 
181 /*----------------------------------------------------------------------------*/
190 /*----------------------------------------------------------------------------*/
191 static cpl_frame_level
192 muse_astrometry_get_frame_level(const char *aFrametag)
193 {
194  if (!aFrametag) {
195  return CPL_FRAME_LEVEL_NONE;
196  }
197  if (!strcmp(aFrametag, "DATACUBE_ASTROMETRY")) {
198  return CPL_FRAME_LEVEL_FINAL;
199  }
200  if (!strcmp(aFrametag, "ASTROMETRY_WCS")) {
201  return CPL_FRAME_LEVEL_FINAL;
202  }
203  return CPL_FRAME_LEVEL_NONE;
204 } /* muse_astrometry_get_frame_level() */
205 
206 /*----------------------------------------------------------------------------*/
215 /*----------------------------------------------------------------------------*/
216 static muse_frame_mode
217 muse_astrometry_get_frame_mode(const char *aFrametag)
218 {
219  if (!aFrametag) {
220  return MUSE_FRAME_MODE_ALL;
221  }
222  if (!strcmp(aFrametag, "DATACUBE_ASTROMETRY")) {
224  }
225  if (!strcmp(aFrametag, "ASTROMETRY_WCS")) {
227  }
228  return MUSE_FRAME_MODE_ALL;
229 } /* muse_astrometry_get_frame_mode() */
230 
231 /*----------------------------------------------------------------------------*/
241 /*----------------------------------------------------------------------------*/
242 static int
243 muse_astrometry_create(cpl_plugin *aPlugin)
244 {
245  /* Check that the plugin is part of a valid recipe */
246  cpl_recipe *recipe;
247  if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
248  recipe = (cpl_recipe *)aPlugin;
249  } else {
250  return -1;
251  }
252 
253  /* register the extended processing information (new FITS header creation, *
254  * getting of the frame level for a certain tag) */
256  muse_astrometry_new_recipeconfig(),
257  muse_astrometry_prepare_header,
258  muse_astrometry_get_frame_level,
259  muse_astrometry_get_frame_mode);
260 
261  /* XXX initialize timing in messages *
262  * since at least esorex is too stupid to turn it on, we have to do it */
264  cpl_msg_set_time_on();
265  }
266 
267  /* Create the parameter list in the cpl_recipe object */
268  recipe->parameters = cpl_parameterlist_new();
269  /* Fill the parameters list */
270  cpl_parameter *p;
271 
272  /* --centroid: Centroiding method to use for objects in the field of view. "gaussian" and "moffat" use 2D fits to derive the centroid, "box" is a simple centroid in a square box. */
273  p = cpl_parameter_new_enum("muse.muse_astrometry.centroid",
274  CPL_TYPE_STRING,
275  "Centroiding method to use for objects in the field of view. \"gaussian\" and \"moffat\" use 2D fits to derive the centroid, \"box\" is a simple centroid in a square box.",
276  "muse.muse_astrometry",
277  (const char *)"moffat",
278  3,
279  (const char *)"gaussian",
280  (const char *)"moffat",
281  (const char *)"box");
282  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "centroid");
283  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "centroid");
284 
285  cpl_parameterlist_append(recipe->parameters, p);
286 
287  /* --detsigma: Source detection sigma level to use. If this is negative, values between its absolute and 1.0 are tested with a stepsize of 0.1, to find an optimal solution. */
288  p = cpl_parameter_new_value("muse.muse_astrometry.detsigma",
289  CPL_TYPE_DOUBLE,
290  "Source detection sigma level to use. If this is negative, values between its absolute and 1.0 are tested with a stepsize of 0.1, to find an optimal solution.",
291  "muse.muse_astrometry",
292  (double)-3.0);
293  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "detsigma");
294  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "detsigma");
295 
296  cpl_parameterlist_append(recipe->parameters, p);
297 
298  /* --radius: Initial radius in pixels for pattern matching identification in the astrometric field. */
299  p = cpl_parameter_new_value("muse.muse_astrometry.radius",
300  CPL_TYPE_DOUBLE,
301  "Initial radius in pixels for pattern matching identification in the astrometric field.",
302  "muse.muse_astrometry",
303  (double)5.);
304  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "radius");
305  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "radius");
306 
307  cpl_parameterlist_append(recipe->parameters, p);
308 
309  /* --faccuracy: Factor of initial accuracy relative to mean positional accuracy of the measured positions to use for pattern matching. */
310  p = cpl_parameter_new_value("muse.muse_astrometry.faccuracy",
311  CPL_TYPE_DOUBLE,
312  "Factor of initial accuracy relative to mean positional accuracy of the measured positions to use for pattern matching.",
313  "muse.muse_astrometry",
314  (double)5.);
315  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "faccuracy");
316  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "faccuracy");
317 
318  cpl_parameterlist_append(recipe->parameters, p);
319 
320  /* --niter: Number of iterations of the astrometric fit. */
321  p = cpl_parameter_new_value("muse.muse_astrometry.niter",
322  CPL_TYPE_INT,
323  "Number of iterations of the astrometric fit.",
324  "muse.muse_astrometry",
325  (int)2);
326  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "niter");
327  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "niter");
328 
329  cpl_parameterlist_append(recipe->parameters, p);
330 
331  /* --rejsigma: Rejection sigma level of the astrometric fit. */
332  p = cpl_parameter_new_value("muse.muse_astrometry.rejsigma",
333  CPL_TYPE_DOUBLE,
334  "Rejection sigma level of the astrometric fit.",
335  "muse.muse_astrometry",
336  (double)3.);
337  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "rejsigma");
338  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "rejsigma");
339 
340  cpl_parameterlist_append(recipe->parameters, p);
341 
342  /* --rotcenter: Center of rotation of the instrument, given as two comma-separated floating point values in pixels. */
343  p = cpl_parameter_new_value("muse.muse_astrometry.rotcenter",
344  CPL_TYPE_STRING,
345  "Center of rotation of the instrument, given as two comma-separated floating point values in pixels.",
346  "muse.muse_astrometry",
347  (const char *)"-0.01,-1.20");
348  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "rotcenter");
349  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "rotcenter");
350 
351  cpl_parameterlist_append(recipe->parameters, p);
352 
353  /* --lambdamin: Cut off the data below this wavelength after loading the pixel table(s). */
354  p = cpl_parameter_new_value("muse.muse_astrometry.lambdamin",
355  CPL_TYPE_DOUBLE,
356  "Cut off the data below this wavelength after loading the pixel table(s).",
357  "muse.muse_astrometry",
358  (double)4000.);
359  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdamin");
360  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdamin");
361 
362  cpl_parameterlist_append(recipe->parameters, p);
363 
364  /* --lambdamax: Cut off the data above this wavelength after loading the pixel table(s). */
365  p = cpl_parameter_new_value("muse.muse_astrometry.lambdamax",
366  CPL_TYPE_DOUBLE,
367  "Cut off the data above this wavelength after loading the pixel table(s).",
368  "muse.muse_astrometry",
369  (double)10000.);
370  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdamax");
371  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdamax");
372 
373  cpl_parameterlist_append(recipe->parameters, p);
374 
375  /* --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. */
376  p = cpl_parameter_new_value("muse.muse_astrometry.lambdaref",
377  CPL_TYPE_DOUBLE,
378  "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.",
379  "muse.muse_astrometry",
380  (double)7000.);
381  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "lambdaref");
382  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambdaref");
383 
384  cpl_parameterlist_append(recipe->parameters, p);
385 
386  /* --darcheck: Carry out a check of the theoretical DAR correction using source centroiding. If "correct" it will also apply an empirical correction. */
387  p = cpl_parameter_new_enum("muse.muse_astrometry.darcheck",
388  CPL_TYPE_STRING,
389  "Carry out a check of the theoretical DAR correction using source centroiding. If \"correct\" it will also apply an empirical correction.",
390  "muse.muse_astrometry",
391  (const char *)"none",
392  3,
393  (const char *)"none",
394  (const char *)"check",
395  (const char *)"correct");
396  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "darcheck");
397  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "darcheck");
398 
399  cpl_parameterlist_append(recipe->parameters, p);
400 
401  return 0;
402 } /* muse_astrometry_create() */
403 
404 /*----------------------------------------------------------------------------*/
415 /*----------------------------------------------------------------------------*/
416 static int
417 muse_astrometry_params_fill(muse_astrometry_params_t *aParams, cpl_parameterlist *aParameters)
418 {
419  cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
420  cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
421  cpl_parameter *p;
422 
423  p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.centroid");
424  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
425  aParams->centroid_s = cpl_parameter_get_string(p);
426  aParams->centroid =
427  (!strcasecmp(aParams->centroid_s, "gaussian")) ? MUSE_ASTROMETRY_PARAM_CENTROID_GAUSSIAN :
428  (!strcasecmp(aParams->centroid_s, "moffat")) ? MUSE_ASTROMETRY_PARAM_CENTROID_MOFFAT :
429  (!strcasecmp(aParams->centroid_s, "box")) ? MUSE_ASTROMETRY_PARAM_CENTROID_BOX :
430  MUSE_ASTROMETRY_PARAM_CENTROID_INVALID_VALUE;
431  cpl_ensure_code(aParams->centroid != MUSE_ASTROMETRY_PARAM_CENTROID_INVALID_VALUE,
432  CPL_ERROR_ILLEGAL_INPUT);
433 
434  p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.detsigma");
435  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
436  aParams->detsigma = cpl_parameter_get_double(p);
437 
438  p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.radius");
439  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
440  aParams->radius = cpl_parameter_get_double(p);
441 
442  p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.faccuracy");
443  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
444  aParams->faccuracy = cpl_parameter_get_double(p);
445 
446  p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.niter");
447  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
448  aParams->niter = cpl_parameter_get_int(p);
449 
450  p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.rejsigma");
451  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
452  aParams->rejsigma = cpl_parameter_get_double(p);
453 
454  p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.rotcenter");
455  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
456  aParams->rotcenter = cpl_parameter_get_string(p);
457 
458  p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.lambdamin");
459  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
460  aParams->lambdamin = cpl_parameter_get_double(p);
461 
462  p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.lambdamax");
463  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
464  aParams->lambdamax = cpl_parameter_get_double(p);
465 
466  p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.lambdaref");
467  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
468  aParams->lambdaref = cpl_parameter_get_double(p);
469 
470  p = cpl_parameterlist_find(aParameters, "muse.muse_astrometry.darcheck");
471  cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
472  aParams->darcheck_s = cpl_parameter_get_string(p);
473  aParams->darcheck =
474  (!strcasecmp(aParams->darcheck_s, "none")) ? MUSE_ASTROMETRY_PARAM_DARCHECK_NONE :
475  (!strcasecmp(aParams->darcheck_s, "check")) ? MUSE_ASTROMETRY_PARAM_DARCHECK_CHECK :
476  (!strcasecmp(aParams->darcheck_s, "correct")) ? MUSE_ASTROMETRY_PARAM_DARCHECK_CORRECT :
477  MUSE_ASTROMETRY_PARAM_DARCHECK_INVALID_VALUE;
478  cpl_ensure_code(aParams->darcheck != MUSE_ASTROMETRY_PARAM_DARCHECK_INVALID_VALUE,
479  CPL_ERROR_ILLEGAL_INPUT);
480 
481  return 0;
482 } /* muse_astrometry_params_fill() */
483 
484 /*----------------------------------------------------------------------------*/
491 /*----------------------------------------------------------------------------*/
492 static int
493 muse_astrometry_exec(cpl_plugin *aPlugin)
494 {
495  if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
496  return -1;
497  }
499  cpl_recipe *recipe = (cpl_recipe *)aPlugin;
500  cpl_msg_set_threadid_on();
501 
502  cpl_frameset *usedframes = cpl_frameset_new(),
503  *outframes = cpl_frameset_new();
505  muse_astrometry_params_fill(&params, recipe->parameters);
506 
507  cpl_errorstate prestate = cpl_errorstate_get();
508 
509  muse_processing *proc = muse_processing_new("muse_astrometry",
510  recipe);
511  int rc = muse_astrometry_compute(proc, &params);
512  cpl_frameset_join(usedframes, proc->usedframes);
513  cpl_frameset_join(outframes, proc->outframes);
515 
516  if (!cpl_errorstate_is_equal(prestate)) {
517  /* dump all errors from this recipe in chronological order */
518  cpl_errorstate_dump(prestate, CPL_FALSE, muse_cplerrorstate_dump_some);
519  /* reset message level to not get the same errors displayed again by esorex */
520  cpl_msg_set_level(CPL_MSG_INFO);
521  }
522  /* clean up duplicates in framesets of used and output frames */
525 
526  /* to get esorex to see our classification (frame groups etc.), *
527  * replace the original frameset with the list of used frames *
528  * before appending product output frames */
529  /* keep the same pointer, so just erase all frames, not delete the frameset */
530  muse_cplframeset_erase_all(recipe->frames);
531  cpl_frameset_join(recipe->frames, usedframes);
532  cpl_frameset_join(recipe->frames, outframes);
533  cpl_frameset_delete(usedframes);
534  cpl_frameset_delete(outframes);
535  return rc;
536 } /* muse_astrometry_exec() */
537 
538 /*----------------------------------------------------------------------------*/
545 /*----------------------------------------------------------------------------*/
546 static int
547 muse_astrometry_destroy(cpl_plugin *aPlugin)
548 {
549  /* Get the recipe from the plugin */
550  cpl_recipe *recipe;
551  if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
552  recipe = (cpl_recipe *)aPlugin;
553  } else {
554  return -1;
555  }
556 
557  /* Clean up */
558  cpl_parameterlist_delete(recipe->parameters);
560  return 0;
561 } /* muse_astrometry_destroy() */
562 
563 /*----------------------------------------------------------------------------*/
573 /*----------------------------------------------------------------------------*/
574 int
575 cpl_plugin_get_info(cpl_pluginlist *aList)
576 {
577  cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
578  cpl_plugin *plugin = &recipe->interface;
579 
580  char *helptext;
582  helptext = cpl_sprintf("%s%s", muse_astrometry_help,
583  muse_astrometry_help_esorex);
584  } else {
585  helptext = cpl_sprintf("%s", muse_astrometry_help);
586  }
587 
588  /* Initialize the CPL plugin stuff for this module */
589  cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
590  CPL_PLUGIN_TYPE_RECIPE,
591  "muse_astrometry",
592  "Compute an astrometric solution.",
593  helptext,
594  "Peter Weilbacher",
595  "usd-help@eso.org",
597  muse_astrometry_create,
598  muse_astrometry_exec,
599  muse_astrometry_destroy);
600  cpl_pluginlist_append(aList, plugin);
601  cpl_free(helptext);
602 
603  return 0;
604 } /* cpl_plugin_get_info() */
605 
void muse_processing_delete(muse_processing *aProcessing)
Free the muse_processing structure.
double rejsigma
Rejection sigma level of the astrometric fit.
double lambdaref
Reference wavelength used for correction of differential atmospheric refraction. The R-band (peak wav...
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
double radius
Initial radius in pixels for pattern matching identification in the astrometric field.
muse_frame_mode
double lambdamin
Cut off the data below this wavelength after loading the pixel table(s).
cpl_frameset * outframes
int centroid
Centroiding method to use for objects in the field of view. "gaussian" and "moffat" use 2D fits to de...
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 * centroid_s
Centroiding method to use for objects in the field of view. "gaussian" and "moffat" use 2D fits to de...
int niter
Number of iterations of the astrometric fit.
const char * darcheck_s
Carry out a check of the theoretical DAR correction using source centroiding. If "correct" it will al...
double detsigma
Source detection sigma level to use. If this is negative, values between its absolute and 1...
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.
const char * rotcenter
Center of rotation of the instrument, given as two comma-separated floating point values in pixels...
Structure to hold the parameters of the muse_astrometry recipe.
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.
double lambdamax
Cut off the data above this wavelength after loading the pixel table(s).
void muse_processing_recipeinfo(cpl_plugin *)
Output main pipeline configuration, inputs, and parameters.
double faccuracy
Factor of initial accuracy relative to mean positional accuracy of the measured positions to use for ...
int darcheck
Carry out a check of the theoretical DAR correction using source centroiding. If "correct" it will al...
cpl_error_code muse_processing_prepare_property(cpl_propertylist *, const char *, cpl_type, const char *)
Prepare and check the specified property.