FORS Pipeline Reference Manual  5.0.9
fors_extract_objects.c
1 /* $Id: fors_extract_objects.c,v 1.6 2013-04-24 14:14:13 cgarcia 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: cgarcia $
23  * $Date: 2013-04-24 14:14:13 $
24  * $Revision: 1.6 $
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 <cpl.h>
34 #include <moses.h>
35 #include <fors_dfs.h>
36 
37 static int fors_extract_objects_create(cpl_plugin *);
38 static int fors_extract_objects_exec(cpl_plugin *);
39 static int fors_extract_objects_destroy(cpl_plugin *);
40 static int fors_extract_objects(cpl_parameterlist *, cpl_frameset *);
41 
42 static char fors_extract_objects_description[] =
43 "This recipe is used to extract scientific objects spectra on a resampled\n"
44 "image produced with recipe fors_resample, at the positions listed in the\n"
45 "object table produced by recipe fors_detect_objects. Please refer to the\n"
46 "FORS Pipeline User's Manual for more details on object extraction.\n"
47 "\n"
48 "In the table below the MXU acronym can be alternatively read as MOS and\n"
49 "LSS, and SCI as STD.\n\n"
50 "Input files:\n\n"
51 " DO category: Type: Explanation: Required:\n"
52 " MAPPED_SCI_MXU Calib Resampled slit spectra Y\n"
53 " MAPPED_SKY_SCI_MXU Calib Resampled sky spectra Y\n"
54 " OBJECT_TABLE_SCI_MXU Calib Object table Y\n\n"
55 "Output files:\n\n"
56 " DO category: Data type: Explanation:\n"
57 " REDUCED_SCI_MXU FITS image Extracted object spectra\n"
58 " REDUCED_SKY_SCI_MXU FITS image Extracted sky spectra\n"
59 " REDUCED_ERROR_SCI_MXU FITS image Error on extracted spectra\n\n";
60 
61 #define fors_extract_objects_exit(message) \
62 { \
63 if ((const char *)message != NULL) cpl_msg_error(recipe, message); \
64 cpl_image_delete(mapped); \
65 cpl_image_delete(skymapped); \
66 cpl_table_delete(slits); \
67 cpl_propertylist_delete(header); \
68 cpl_msg_indent_less(); \
69 return -1; \
70 }
71 
72 #define fors_extract_objects_exit_memcheck(message) \
73 { \
74 if ((const char *)message != NULL) cpl_msg_info(recipe, message); \
75 printf("free mapped (%p)\n", mapped); \
76 cpl_image_delete(mapped); \
77 printf("free skymapped (%p)\n", skymapped); \
78 cpl_image_delete(skymapped); \
79 printf("free slits (%p)\n", slits); \
80 cpl_table_delete(slits); \
81 printf("free header (%p)\n", header); \
82 cpl_propertylist_delete(header); \
83 cpl_msg_indent_less(); \
84 return 0; \
85 }
86 
87 
99 int cpl_plugin_get_info(cpl_pluginlist *list)
100 {
101  cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
102  cpl_plugin *plugin = &recipe->interface;
103 
104  cpl_plugin_init(plugin,
105  CPL_PLUGIN_API,
106  FORS_BINARY_VERSION,
107  CPL_PLUGIN_TYPE_RECIPE,
108  "fors_extract_objects",
109  "Extract objects in slit spectra",
110  fors_extract_objects_description,
111  "Carlo Izzo",
112  PACKAGE_BUGREPORT,
113  "This file is currently part of the FORS Instrument Pipeline\n"
114  "Copyright (C) 2002-2010 European Southern Observatory\n\n"
115  "This program is free software; you can redistribute it and/or modify\n"
116  "it under the terms of the GNU General Public License as published by\n"
117  "the Free Software Foundation; either version 2 of the License, or\n"
118  "(at your option) any later version.\n\n"
119  "This program is distributed in the hope that it will be useful,\n"
120  "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
121  "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
122  "GNU General Public License for more details.\n\n"
123  "You should have received a copy of the GNU General Public License\n"
124  "along with this program; if not, write to the Free Software Foundation,\n"
125  "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n",
126  fors_extract_objects_create,
127  fors_extract_objects_exec,
128  fors_extract_objects_destroy);
129 
130  cpl_pluginlist_append(list, plugin);
131 
132  return 0;
133 }
134 
135 
146 static int fors_extract_objects_create(cpl_plugin *plugin)
147 {
148  cpl_recipe *recipe;
149  cpl_parameter *p;
150 
151  /*
152  * Check that the plugin is part of a valid recipe
153  */
154 
155  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
156  recipe = (cpl_recipe *)plugin;
157  else
158  return -1;
159 
160  /*
161  * Create the (empty) parameters list in the cpl_recipe object
162  */
163 
164  recipe->parameters = cpl_parameterlist_new();
165 
166  /*
167  * Object extraction method
168  */
169 
170  p = cpl_parameter_new_value("fors.fors_extract_objects.ext_mode",
171  CPL_TYPE_INT,
172  "Object extraction method: 0 = aperture, "
173  "1 = Horne optimal extraction",
174  "fors.fors_extract_objects",
175  1);
176  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ext_mode");
177  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
178  cpl_parameterlist_append(recipe->parameters, p);
179 
180  return 0;
181 }
182 
183 
192 static int fors_extract_objects_exec(cpl_plugin *plugin)
193 {
194  cpl_recipe *recipe;
195 
196  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
197  recipe = (cpl_recipe *)plugin;
198  else
199  return -1;
200 
201  return fors_extract_objects(recipe->parameters, recipe->frames);
202 }
203 
204 
213 static int fors_extract_objects_destroy(cpl_plugin *plugin)
214 {
215  cpl_recipe *recipe;
216 
217  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
218  recipe = (cpl_recipe *)plugin;
219  else
220  return -1;
221 
222  cpl_parameterlist_delete(recipe->parameters);
223 
224  return 0;
225 }
226 
227 
237 static int fors_extract_objects(cpl_parameterlist *parlist,
238  cpl_frameset *frameset)
239 {
240 
241  const char *recipe = "fors_extract_objects";
242 
243 
244  /*
245  * Input parameters
246  */
247 
248  int ext_mode;
249 
250  /*
251  * CPL objects
252  */
253 
254  cpl_image **images;
255  cpl_image *mapped = NULL;
256  cpl_image *skymapped = NULL;
257  cpl_table *slits = NULL;
258  cpl_propertylist *header = NULL;
259 
260  /*
261  * Auxiliary variables
262  */
263 
264  char version[80];
265  const char *object_tag;
266  const char *science_tag;
267  const char *sky_tag;
268  const char *reduced_tag;
269  const char *reduced_sky_tag;
270  const char *reduced_err_tag;
271  int nframes;
272  double gain;
273  double ron;
274  int scimxu;
275  int scimos;
276  int scilss;
277  int stdmxu;
278  int stdmos;
279  int stdlss;
280 
281  char *instrume = NULL;
282 
283 
284  cpl_msg_set_indentation(2);
285 
286 
287  /*
288  * Get configuration parameters
289  */
290 
291  cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
292  cpl_msg_indent_more();
293 
294  ext_mode = dfs_get_parameter_int(parlist,
295  "fors.fors_extract_objects.ext_mode",
296  NULL);
297  if (ext_mode < 0 || ext_mode > 1)
298  fors_extract_objects_exit("Invalid object extraction mode");
299 
300  if (cpl_error_get_code())
301  fors_extract_objects_exit("Failure reading configuration parameters");
302 
303 
304  cpl_msg_indent_less();
305  cpl_msg_info(recipe, "Check input set-of-frames:");
306  cpl_msg_indent_more();
307 
308  nframes = scimxu = cpl_frameset_count_tags(frameset, "MAPPED_SCI_MXU");
309  nframes += scimos = cpl_frameset_count_tags(frameset, "MAPPED_SCI_MOS");
310  nframes += scilss = cpl_frameset_count_tags(frameset, "MAPPED_SCI_LSS");
311  nframes += stdmxu = cpl_frameset_count_tags(frameset, "MAPPED_STD_MXU");
312  nframes += stdmos = cpl_frameset_count_tags(frameset, "MAPPED_STD_MOS");
313  nframes += stdlss = cpl_frameset_count_tags(frameset, "MAPPED_STD_LSS");
314 
315  if (nframes == 0) {
316  fors_extract_objects_exit("Missing input scientific spectra");
317  }
318  if (nframes > 1) {
319  cpl_msg_error(recipe, "Too many input scientific spectra (%d > 1)",
320  nframes);
321  fors_extract_objects_exit(NULL);
322  }
323 
324  if (scimxu) {
325  science_tag = "MAPPED_SCI_MXU";
326  sky_tag = "MAPPED_SKY_SCI_MXU";
327  object_tag = "OBJECT_TABLE_SCI_MXU";
328  reduced_tag = "REDUCED_SCI_MXU";
329  reduced_sky_tag = "REDUCED_SKY_SCI_MXU";
330  reduced_err_tag = "REDUCED_ERROR_SCI_MXU";
331  }
332  else if (scimos) {
333  science_tag = "MAPPED_SCI_MOS";
334  sky_tag = "MAPPED_SKY_SCI_MOS";
335  object_tag = "OBJECT_TABLE_SCI_MOS";
336  reduced_tag = "REDUCED_SCI_MOS";
337  reduced_sky_tag = "REDUCED_SKY_SCI_MOS";
338  reduced_err_tag = "REDUCED_ERROR_SCI_MOS";
339  }
340  else if (scilss) {
341  science_tag = "MAPPED_SCI_LSS";
342  sky_tag = "MAPPED_SKY_SCI_LSS";
343  object_tag = "OBJECT_TABLE_SCI_LSS";
344  reduced_tag = "REDUCED_SCI_LSS";
345  reduced_sky_tag = "REDUCED_SKY_SCI_LSS";
346  reduced_err_tag = "REDUCED_ERROR_SCI_LSS";
347  }
348  else if (stdmxu) {
349  science_tag = "MAPPED_STD_MXU";
350  sky_tag = "MAPPED_SKY_STD_MXU";
351  object_tag = "OBJECT_TABLE_SCI_MXU";
352  reduced_tag = "REDUCED_STD_MXU";
353  reduced_sky_tag = "REDUCED_SKY_STD_MXU";
354  reduced_err_tag = "REDUCED_ERROR_STD_MXU";
355  }
356  else if (stdmos) {
357  science_tag = "MAPPED_STD_MOS";
358  sky_tag = "MAPPED_SKY_STD_MOS";
359  object_tag = "OBJECT_TABLE_SCI_MOS";
360  reduced_tag = "REDUCED_STD_MOS";
361  reduced_sky_tag = "REDUCED_SKY_STD_MOS";
362  reduced_err_tag = "REDUCED_ERROR_STD_MOS";
363  }
364  else if (stdlss) {
365  science_tag = "MAPPED_STD_LSS";
366  sky_tag = "MAPPED_SKY_STD_LSS";
367  object_tag = "OBJECT_TABLE_SCI_LSS";
368  reduced_tag = "REDUCED_STD_LSS";
369  reduced_sky_tag = "REDUCED_SKY_STD_LSS";
370  reduced_err_tag = "REDUCED_ERROR_STD_LSS";
371  }
372 
373  if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
374  fors_extract_objects_exit("Input frames are not from the same grism");
375 
376  if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
377  fors_extract_objects_exit("Input frames are not from the same filter");
378 
379  if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
380  fors_extract_objects_exit("Input frames are not from the same chip");
381 
382  header = dfs_load_header(frameset, science_tag, 0);
383  if (header == NULL)
384  fors_extract_objects_exit("Cannot load scientific frame header");
385 
386  instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
387  if (instrume == NULL)
388  fors_extract_objects_exit("Missing keyword INSTRUME in reference frame "
389  "header");
390 
391  if (instrume[4] == '1')
392  snprintf(version, 80, "%s/%s", "fors1", VERSION);
393  if (instrume[4] == '2')
394  snprintf(version, 80, "%s/%s", "fors2", VERSION);
395 
396  gain = cpl_propertylist_get_double(header, "ESO DET OUT1 CONAD");
397 
398  if (cpl_error_get_code() != CPL_ERROR_NONE)
399  fors_extract_objects_exit("Missing keyword ESO DET OUT1 CONAD in "
400  "scientific frame header");
401 
402  cpl_msg_info(recipe, "The gain factor is: %.2f e-/ADU", gain);
403 
404 
405  ron = cpl_propertylist_get_double(header, "ESO DET OUT1 RON");
406 
407  if (cpl_error_get_code() != CPL_ERROR_NONE)
408  fors_extract_objects_exit("Missing keyword ESO DET OUT1 RON in "
409  "scientific frame header");
410 
411  ron /= gain; /* Convert from electrons to ADU */
412 
413  cpl_msg_info(recipe, "The read-out-noise is: %.2f ADU", ron);
414 
415 
416  cpl_msg_indent_less();
417  cpl_msg_info(recipe, "Load input frames...");
418  cpl_msg_indent_more();
419 
420  mapped = dfs_load_image(frameset, science_tag, CPL_TYPE_FLOAT, 0, 0);
421  if (mapped == NULL)
422  fors_extract_objects_exit("Cannot load input scientific frame");
423 
424  skymapped = dfs_load_image(frameset, sky_tag, CPL_TYPE_FLOAT, 0, 0);
425  if (skymapped == NULL)
426  fors_extract_objects_exit("Cannot load input sky frame");
427 
428  slits = dfs_load_table(frameset, object_tag, 1);
429  if (slits == NULL)
430  fors_extract_objects_exit("Cannot load input object table");
431 
432 
433  cpl_msg_indent_less();
434  cpl_msg_info(recipe, "Object extraction...");
435  cpl_msg_indent_more();
436 
437  //TODO: Add the real propagated variance here (the second argument)
438  //It should be done like in fors_science
439  images = mos_extract_objects(mapped, NULL, skymapped, slits,
440  ext_mode, ron, gain, 1);
441 
442  cpl_image_delete(mapped); mapped = NULL;
443  cpl_image_delete(skymapped); skymapped = NULL;
444  cpl_table_delete(slits); slits = NULL;
445 
446  if (images) {
447 
448  if (dfs_save_image(frameset, images[0], reduced_tag, header,
449  parlist, recipe, version))
450  fors_extract_objects_exit(NULL);
451  cpl_image_delete(images[0]);
452 
453  if (dfs_save_image(frameset, images[1], reduced_sky_tag, header,
454  parlist, recipe, version))
455  fors_extract_objects_exit(NULL);
456  cpl_image_delete(images[1]);
457 
458  if (dfs_save_image(frameset, images[2], reduced_err_tag, header,
459  parlist, recipe, version))
460  fors_extract_objects_exit(NULL);
461  cpl_image_delete(images[2]);
462 
463  cpl_free(images);
464  }
465  else {
466  cpl_msg_warning(recipe, "No objects found: the products "
467  "%s, %s, and %s are not created",
468  reduced_tag, reduced_sky_tag, reduced_err_tag);
469  }
470 
471  cpl_propertylist_delete(header); header = NULL;
472 
473  return 0;
474 }
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
Definition: fors_bias.c:62
cpl_image * dfs_load_image(cpl_frameset *frameset, const char *category, cpl_type type, int ext, int calib)
Loading image data of given category.
Definition: fors_dfs.c:860
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:964
int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
Saving table data of given category.
Definition: fors_dfs.c:1683
int dfs_save_image(cpl_frameset *frameset, const cpl_image *image, const char *category, cpl_propertylist *header, const cpl_parameterlist *parlist, const char *recipename, const char *version)
Saving image data of given category.
Definition: fors_dfs.c:1451
cpl_table * dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
Loading table data of given category.
Definition: fors_dfs.c:916
int dfs_get_parameter_int(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe integer parameter value.
Definition: fors_dfs.c:407
Definition: list.c:74
cpl_image ** mos_extract_objects(cpl_image *science, cpl_image *science_var, cpl_image *sky, cpl_table *objects, int extraction, double ron, double gain, int ncombined)
Extract detected objects from rectified scientific frame.
Definition: moses.c:14295