FORS Pipeline Reference Manual  4.12.5
vimos_calib.c
1 /* $Id: vimos_calib.c,v 1.21 2010-09-14 07:38:16 cizzo Exp $
2  *
3  * This file is part of the FORS Data Reduction Pipeline
4  * Copyright (C) 2002-2010 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /*
22  * $Author: cizzo $
23  * $Date: 2010-09-14 07:38:16 $
24  * $Revision: 1.21 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 #include <math.h>
33 #include <vimos_calib_impl.h>
34 #include <cpl.h>
35 #include <moses.h>
36 #include <fors_dfs.h>
37 #include <fors_qc.h>
38 
39 static int vimos_calib_create(cpl_plugin *);
40 static int vimos_calib_exec(cpl_plugin *);
41 static int vimos_calib_destroy(cpl_plugin *);
42 static int vimos_calib(cpl_parameterlist *, cpl_frameset *);
43 
44 static char vimos_calib_description[] =
45 "This recipe is used to identify reference lines on MOS arc lamp\n"
46 "exposures, and trace the spectral edges on the corresponding flat field\n"
47 "exposures. This information is used to determine the spectral extraction\n"
48 "mask to be applied in the scientific data reduction, performed with the\n"
49 "recipe vimos_science. The input arc lamp and flat field exposures are\n"
50 "assumed to be obtained quasi-simultaneously, so that they would be\n"
51 "described by exactly the same instrument distortions.\n"
52 "A line catalog must be specified, containing the wavelengths of the\n"
53 "reference arc lamp lines used for the wavelength calibration. A grism\n"
54 "table (typically depending on the instrument mode, and in particular on\n"
55 "the grism used) may also be specified: this table contains a default\n"
56 "recipe parameter setting to control the way spectra are extracted for\n"
57 "a specific instrument mode, as it is used for automatic run of the\n"
58 "pipeline on Paranal and in Garching. If this table is specified, it\n"
59 "will modify the default recipe parameter setting, with the exception of\n"
60 "those parameters which have been explicitly modifyed on the command line.\n"
61 "If a grism table is not specified, the input recipe parameters values\n"
62 "will always be read from the command line, or from an esorex configuration\n"
63 "file if present, or from their generic default values (that are rarely\n"
64 "meaningful). Finally a master bias frame must be input to this recipe.\n"
65 "In the table below the MOS_CURV_COEFF, MOS_CURV_TRACES, MOS_SPATIAL_MAP\n"
66 "MOS_ARC_SPECTRUM_EXTRACTED, MOS_SPECTRA_DETECTION, MOS_SLIT_MAP, and\n"
67 "MOS_SLIT_LOCATION, are never created in case of long-slit-like data.\n"
68 "The products MOS_SPECTRA_DETECTION, MOS_SLIT_MAP, and MOS_DISP_RESIDUALS,\n"
69 "are just created if the --check parameter is set to true. The product\n"
70 "GLOBAL_DISTORTION_TABLE is just created if more than 12 separate spectra\n"
71 "are found in the CCD.\n\n"
72 "Input files:\n\n"
73 " DO category: Type: Explanation: Required:\n"
74 " MOS_SCREEN_FLAT Raw Flat field exposures Y\n"
75 " MOS_ARC_SPECTRUM Raw Arc lamp exposure Y\n"
76 " MASTER_BIAS or BIAS Calib Bias frame Y\n"
77 " LINE_CATALOG Calib Line catalog Y\n"
78 " GRISM_TABLE Calib Grism table .\n\n"
79 "Output files:\n\n"
80 " DO category: Data type: Explanation:\n"
81 " MOS_COMBINED_SCREEN_FLAT FITS image Combined (sum) flat field\n"
82 " MOS_MASTER_SCREEN_FLAT FITS image Normalised flat field\n"
83 " MOS_ARC_SPECTRUM_EXTRACTED FITS image Wavelength calibrated arc spectrum\n"
84 " MOS_DISP_COEFF FITS table Inverse dispersion coefficients\n"
85 " MOS_DISP_RESIDUALS FITS image Residuals in wavelength calibration\n"
86 " MOS_DISP_RESIDUALS_TABLE FITS table Residuals in wavelength calibration\n"
87 " MOS_DELTA_IMAGE FITS image Offset vs linear wavelength calib\n"
88 " MOS_WAVELENGTH_MAP FITS image Wavelength for each pixel on CCD\n"
89 " MOS_SPECTRA_DETECTION FITS image Check for preliminary detection\n"
90 " MOS_SLIT_MAP FITS image Map of central wavelength on CCD\n"
91 " MOS_CURV_TRACES FITS table Spectral curvature traces\n"
92 " MOS_CURV_COEFF FITS table Spectral curvature coefficients\n"
93 " MOS_SPATIAL_MAP FITS image Spatial position along slit on CCD\n"
94 " MOS_SPECTRAL_RESOLUTION FITS table Resolution at reference arc lines\n"
95 " MOS_SLIT_LOCATION FITS table Slits on product frames and CCD\n"
96 " GLOBAL_DISTORTION_TABLE FITS table Global distortions table\n\n";
97 
109 int cpl_plugin_get_info(cpl_pluginlist *list)
110 {
111  cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
112  cpl_plugin *plugin = &recipe->interface;
113 
114  cpl_plugin_init(plugin,
115  CPL_PLUGIN_API,
116  FORS_BINARY_VERSION,
117  CPL_PLUGIN_TYPE_RECIPE,
118  "vimos_calib",
119  "Determination of the extraction mask",
120  vimos_calib_description,
121  "Carlo Izzo",
122  PACKAGE_BUGREPORT,
123  "This file is currently part of the FORS Instrument Pipeline\n"
124  "Copyright (C) 2002-2010 European Southern Observatory\n\n"
125  "This program is free software; you can redistribute it and/or modify\n"
126  "it under the terms of the GNU General Public License as published by\n"
127  "the Free Software Foundation; either version 2 of the License, or\n"
128  "(at your option) any later version.\n\n"
129  "This program is distributed in the hope that it will be useful,\n"
130  "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
131  "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
132  "GNU General Public License for more details.\n\n"
133  "You should have received a copy of the GNU General Public License\n"
134  "along with this program; if not, write to the Free Software Foundation,\n"
135  "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n",
136  vimos_calib_create,
137  vimos_calib_exec,
138  vimos_calib_destroy);
139 
140  cpl_pluginlist_append(list, plugin);
141 
142  return 0;
143 }
144 
145 
156 static int vimos_calib_create(cpl_plugin *plugin)
157 {
158  cpl_recipe *recipe;
159  cpl_parameter *p;
160 
161 
162  /*
163  * Check that the plugin is part of a valid recipe
164  */
165 
166  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
167  recipe = (cpl_recipe *)plugin;
168  else
169  return -1;
170 
171  /*
172  * Create the parameters list in the cpl_recipe object
173  */
174 
175  recipe->parameters = cpl_parameterlist_new();
176 
177 
178  /*
179  * Dispersion
180  */
181 
182  p = cpl_parameter_new_value("fors.vimos_calib.dispersion",
183  CPL_TYPE_DOUBLE,
184  "Expected spectral dispersion (Angstrom/pixel)",
185  "fors.vimos_calib",
186  0.0);
187  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dispersion");
188  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
189  cpl_parameterlist_append(recipe->parameters, p);
190 
191  /*
192  * Peak detection level
193  */
194 
195  p = cpl_parameter_new_value("fors.vimos_calib.peakdetection",
196  CPL_TYPE_DOUBLE,
197  "Initial peak detection threshold (ADU)",
198  "fors.vimos_calib",
199  0.0);
200  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "peakdetection");
201  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
202  cpl_parameterlist_append(recipe->parameters, p);
203 
204  /*
205  * Degree of wavelength calibration polynomial
206  */
207 
208  p = cpl_parameter_new_value("fors.vimos_calib.wdegree",
209  CPL_TYPE_INT,
210  "Degree of wavelength calibration polynomial",
211  "fors.vimos_calib",
212  0);
213  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wdegree");
214  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
215  cpl_parameterlist_append(recipe->parameters, p);
216 
217  /*
218  * Reference lines search radius
219  */
220 
221  p = cpl_parameter_new_value("fors.vimos_calib.wradius",
222  CPL_TYPE_INT,
223  "Search radius if iterating pattern-matching "
224  "with first-guess method",
225  "fors.vimos_calib",
226  4);
227  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wradius");
228  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
229  cpl_parameterlist_append(recipe->parameters, p);
230 
231  /*
232  * Rejection threshold in dispersion relation polynomial fitting
233  */
234 
235  p = cpl_parameter_new_value("fors.vimos_calib.wreject",
236  CPL_TYPE_DOUBLE,
237  "Rejection threshold in dispersion "
238  "relation fit (pixel)",
239  "fors.vimos_calib",
240  0.7);
241  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wreject");
242  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
243  cpl_parameterlist_append(recipe->parameters, p);
244 
245  /*
246  * Wavelength solution interpolation (for LSS data)
247  */
248 
249  p = cpl_parameter_new_value("fors.vimos_calib.wmode",
250  CPL_TYPE_INT,
251  "Interpolation mode of wavelength solution "
252  "applicable to LSS-like data (0 = no "
253  "interpolation, 1 = fill gaps, 2 = global "
254  "model)",
255  "fors.vimos_calib",
256  2);
257  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wmode");
258  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
259  cpl_parameterlist_append(recipe->parameters, p);
260 
261  /*
262  * Line catalog table column containing the reference wavelengths
263  */
264 
265  p = cpl_parameter_new_value("fors.vimos_calib.wcolumn",
266  CPL_TYPE_STRING,
267  "Name of line catalog table column "
268  "with wavelengths",
269  "fors.vimos_calib",
270  "WLEN");
271  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wcolumn");
272  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
273  cpl_parameterlist_append(recipe->parameters, p);
274 
275  /*
276  * Degree of spectral curvature polynomial
277  */
278 
279  p = cpl_parameter_new_value("fors.vimos_calib.cdegree",
280  CPL_TYPE_INT,
281  "Degree of spectral curvature polynomial",
282  "fors.vimos_calib",
283  0);
284  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "cdegree");
285  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
286  cpl_parameterlist_append(recipe->parameters, p);
287 
288  /*
289  * Curvature solution interpolation (for MOS-like data)
290  */
291 
292  p = cpl_parameter_new_value("fors.vimos_calib.cmode",
293  CPL_TYPE_INT,
294  "Interpolation mode of curvature solution "
295  "applicable to MOS-like data (0 = no "
296  "interpolation, 1 = fill gaps, 2 = global "
297  "model)",
298  "fors.vimos_calib",
299  1);
300  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "cmode");
301  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
302  cpl_parameterlist_append(recipe->parameters, p);
303 
304  /*
305  * Start wavelength for spectral extraction
306  */
307 
308  p = cpl_parameter_new_value("fors.vimos_calib.startwavelength",
309  CPL_TYPE_DOUBLE,
310  "Start wavelength in spectral extraction",
311  "fors.vimos_calib",
312  0.0);
313  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startwavelength");
314  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
315  cpl_parameterlist_append(recipe->parameters, p);
316 
317  /*
318  * End wavelength for spectral extraction
319  */
320 
321  p = cpl_parameter_new_value("fors.vimos_calib.endwavelength",
322  CPL_TYPE_DOUBLE,
323  "End wavelength in spectral extraction",
324  "fors.vimos_calib",
325  0.0);
326  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "endwavelength");
327  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
328  cpl_parameterlist_append(recipe->parameters, p);
329 
330  /*
331  * Reference wavelength for wavelength calibration
332  */
333 
334  p = cpl_parameter_new_value("fors.vimos_calib.reference",
335  CPL_TYPE_DOUBLE,
336  "Reference wavelength for calibration",
337  "fors.vimos_calib",
338  0.0);
339  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "reference");
340  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
341  cpl_parameterlist_append(recipe->parameters, p);
342 
343  /*
344  * Try slit identification
345  */
346 
347  p = cpl_parameter_new_value("fors.vimos_calib.slit_ident",
348  CPL_TYPE_BOOL,
349  "Attempt slit identification",
350  "fors.vimos_calib",
351  TRUE);
352  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slit_ident");
353  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
354  cpl_parameterlist_append(recipe->parameters, p);
355 
356  /*
357  * Degree of flat field fitting polynomial along spatial direction
358  * (used for LSS data)
359  */
360 
361  p = cpl_parameter_new_value("fors.vimos_calib.sdegree",
362  CPL_TYPE_INT,
363  "Degree of flat field fitting polynomial "
364  "along spatial direction (used for LSS-like "
365  "data only)",
366  "fors.vimos_calib",
367  -1);
368  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sdegree");
369  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
370  cpl_parameterlist_append(recipe->parameters, p);
371 
372  /*
373  * Degree of flat field fitting polynomial along dispersion direction
374  * (used for MOS data)
375  */
376 
377  p = cpl_parameter_new_value("fors.vimos_calib.ddegree",
378  CPL_TYPE_INT,
379  "Degree of flat field fitting polynomial "
380  "along dispersion direction (not used for "
381  "long-slit-like data)",
382  "fors.vimos_calib",
383  -1);
384  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ddegree");
385  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
386  cpl_parameterlist_append(recipe->parameters, p);
387 
388  /*
389  * Smooth box radius for flat field along dispersion direction
390  */
391 
392  p = cpl_parameter_new_value("fors.vimos_calib.dradius",
393  CPL_TYPE_INT,
394  "Smooth box radius for flat field along "
395  "dispersion direction",
396  "fors.vimos_calib",
397  10);
398  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dradius");
399  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
400  cpl_parameterlist_append(recipe->parameters, p);
401 
402  /*
403  * Smooth box radius for flat field along spatial direction
404  * (used for LSS data only)
405  */
406 
407  p = cpl_parameter_new_value("fors.vimos_calib.sradius",
408  CPL_TYPE_INT,
409  "Smooth box radius for flat field along "
410  "spatial direction",
411  "fors.vimos_calib",
412  10);
413  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sradius");
414  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
415  cpl_parameterlist_append(recipe->parameters, p);
416 
417  /*
418  * Computation of QC1 parameters
419  */
420 
421  p = cpl_parameter_new_value("fors.vimos_calib.qc",
422  CPL_TYPE_BOOL,
423  "Compute QC1 parameters",
424  "fors.vimos_calib",
425  TRUE);
426  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "qc");
427  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
428  cpl_parameterlist_append(recipe->parameters, p);
429 
430  /*
431  * Create check products
432  */
433 
434  p = cpl_parameter_new_value("fors.vimos_calib.check",
435  CPL_TYPE_BOOL,
436  "Create intermediate products",
437  "fors.vimos_calib",
438  FALSE);
439  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "check");
440  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
441  cpl_parameterlist_append(recipe->parameters, p);
442 
443  return 0;
444 }
445 
446 
455 static int vimos_calib_exec(cpl_plugin *plugin)
456 {
457  cpl_recipe *recipe;
458 
459  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
460  recipe = (cpl_recipe *)plugin;
461  else
462  return -1;
463 
464  return vimos_calib(recipe->parameters, recipe->frames);
465 }
466 
467 
476 static int vimos_calib_destroy(cpl_plugin *plugin)
477 {
478  cpl_recipe *recipe;
479 
480  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
481  recipe = (cpl_recipe *)plugin;
482  else
483  return -1;
484 
485  cpl_parameterlist_delete(recipe->parameters);
486 
487  return 0;
488 }
489 
490 
500 static int vimos_calib(cpl_parameterlist *parlist, cpl_frameset *frameset)
501 {
502  cpl_table *maskslits;
503  cpl_propertylist *header;
504  int mos;
505  int multiplex;
506 
507  /*
508  * Check whether there is spectral multiplexing here
509  */
510 
511  mos = cpl_frameset_count_tags(frameset, "MOS_ARC_SPECTRUM");
512 
513  if (mos == 0) {
514  cpl_msg_error("vimos_calib", "Missing input arc lamp frame");
515  return -1;
516  }
517 
518  if (mos > 1) {
519  cpl_msg_error("vimos_calib",
520  "Just one input arc lamp frame is allowed");
521  return -1;
522  }
523 
524  header = dfs_load_header(frameset, "MOS_ARC_SPECTRUM", 0);
525 
526  if (header == NULL) {
527  cpl_msg_error("vimos_calib", "Cannot load arc lamp header");
528  return -1;
529  }
530 
531  maskslits = mos_load_slits_vimos(header);
532  cpl_propertylist_delete(header);
533  multiplex = mos_check_multiplex(maskslits);
534 
535  if (multiplex == 1)
536  return vimos_calib_impl(frameset, parlist);
537 
538  cpl_msg_info("vimos_calib", "Spectral multiplexing: %d", multiplex);
539  cpl_msg_error("vimos_calib", "Cannot handle such data");
540  return -1;
541 }
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
Definition: fors_bias.c:62
cpl_propertylist * dfs_load_header(cpl_frameset *frameset, const char *category, int ext)
Loading header associated to data of given category.
Definition: fors_dfs.c:951
int mos_check_multiplex(cpl_table *slits)
Determining whether a VIMOS mask has spectral multplexing or not.
Definition: moses.c:15327
Definition: list.c:74
cpl_table * mos_load_slits_vimos(cpl_propertylist *header)
Create slit location table from FITS header of VIMOS data.
Definition: moses.c:15216
int vimos_calib_impl(cpl_frameset *frameset, cpl_parameterlist *parlist)
Interpret the command line options and execute the data processing.