FORS Pipeline Reference Manual  5.0.9
fors_detect_objects.c
1 /* $Id: fors_detect_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_detect_objects_create(cpl_plugin *);
38 static int fors_detect_objects_exec(cpl_plugin *);
39 static int fors_detect_objects_destroy(cpl_plugin *);
40 static int fors_detect_objects(cpl_parameterlist *, cpl_frameset *);
41 
42 static char fors_detect_objects_description[] =
43 "This recipe is used to detect scientific objects spectra on a resampled\n"
44 "image produced with recipe fors_resample. Please refer to the FORS\n"
45 "Pipeline User's Manual for more details on object detection.\n"
46 "\n"
47 "In the table below the MXU acronym can be alternatively read as MOS and\n"
48 "LSS, and SCI as STD.\n\n"
49 "Input files:\n\n"
50 " DO category: Type: Explanation: Required:\n"
51 " MAPPED_SCI_MXU Calib Resampled slit spectra Y\n"
52 " SLIT_LOCATION_MXU Calib Slit location on image Y\n"
53 "Output files:\n\n"
54 " DO category: Data type: Explanation:\n"
55 " OBJECT_TABLE_SCI_MXU FITS table Object positions in slit spectra\n\n";
56 
57 #define fors_detect_objects_exit(message) \
58 { \
59 if ((const char *)message != NULL) cpl_msg_error(recipe, message); \
60 cpl_image_delete(dummy); \
61 cpl_image_delete(mapped); \
62 cpl_table_delete(slits); \
63 cpl_propertylist_delete(header); \
64 cpl_msg_indent_less(); \
65 return -1; \
66 }
67 
68 #define fors_detect_objects_exit_memcheck(message) \
69 { \
70 if ((const char *)message != NULL) cpl_msg_info(recipe, message); \
71 printf("free dummy (%p)\n", dummy); \
72 cpl_image_delete(dummy); \
73 printf("free mapped (%p)\n", mapped); \
74 cpl_image_delete(mapped); \
75 printf("free slits (%p)\n", slits); \
76 cpl_table_delete(slits); \
77 printf("free header (%p)\n", header); \
78 cpl_propertylist_delete(header); \
79 cpl_msg_indent_less(); \
80 return 0; \
81 }
82 
83 
95 int cpl_plugin_get_info(cpl_pluginlist *list)
96 {
97  cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
98  cpl_plugin *plugin = &recipe->interface;
99 
100  cpl_plugin_init(plugin,
101  CPL_PLUGIN_API,
102  FORS_BINARY_VERSION,
103  CPL_PLUGIN_TYPE_RECIPE,
104  "fors_detect_objects",
105  "Detect objects in slit spectra",
106  fors_detect_objects_description,
107  "Carlo Izzo",
108  PACKAGE_BUGREPORT,
109  "This file is currently part of the FORS Instrument Pipeline\n"
110  "Copyright (C) 2002-2010 European Southern Observatory\n\n"
111  "This program is free software; you can redistribute it and/or modify\n"
112  "it under the terms of the GNU General Public License as published by\n"
113  "the Free Software Foundation; either version 2 of the License, or\n"
114  "(at your option) any later version.\n\n"
115  "This program is distributed in the hope that it will be useful,\n"
116  "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
117  "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
118  "GNU General Public License for more details.\n\n"
119  "You should have received a copy of the GNU General Public License\n"
120  "along with this program; if not, write to the Free Software Foundation,\n"
121  "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n",
122  fors_detect_objects_create,
123  fors_detect_objects_exec,
124  fors_detect_objects_destroy);
125 
126  cpl_pluginlist_append(list, plugin);
127 
128  return 0;
129 }
130 
131 
142 static int fors_detect_objects_create(cpl_plugin *plugin)
143 {
144  cpl_recipe *recipe;
145  cpl_parameter *p;
146 
147  /*
148  * Check that the plugin is part of a valid recipe
149  */
150 
151  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
152  recipe = (cpl_recipe *)plugin;
153  else
154  return -1;
155 
156  /*
157  * Create the (empty) parameters list in the cpl_recipe object
158  */
159 
160  recipe->parameters = cpl_parameterlist_new();
161 
162  /*
163  * Slit margin
164  */
165 
166  p = cpl_parameter_new_value("fors.fors_detect_objects.slit_margin",
167  CPL_TYPE_INT,
168  "Number of pixels to exclude at each slit "
169  "in object detection and extraction",
170  "fors.fors_detect_objects",
171  3);
172  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slit_margin");
173  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
174  cpl_parameterlist_append(recipe->parameters, p);
175 
176  /*
177  * Extraction radius
178  */
179 
180  p = cpl_parameter_new_value("fors.fors_detect_objects.ext_radius",
181  CPL_TYPE_INT,
182  "Maximum extraction radius for detected "
183  "objects (pixel)",
184  "fors.fors_detect_objects",
185  6);
186  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ext_radius");
187  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
188  cpl_parameterlist_append(recipe->parameters, p);
189 
190  /*
191  * Contamination radius
192  */
193 
194  p = cpl_parameter_new_value("fors.fors_detect_objects.cont_radius",
195  CPL_TYPE_INT,
196  "Minimum distance at which two objects "
197  "of equal luminosity do not contaminate "
198  "each other (pixel)",
199  "fors.fors_detect_objects",
200  0);
201  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "cont_radius");
202  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
203  cpl_parameterlist_append(recipe->parameters, p);
204 
205  return 0;
206 }
207 
208 
217 static int fors_detect_objects_exec(cpl_plugin *plugin)
218 {
219  cpl_recipe *recipe;
220 
221  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
222  recipe = (cpl_recipe *)plugin;
223  else
224  return -1;
225 
226  return fors_detect_objects(recipe->parameters, recipe->frames);
227 }
228 
229 
238 static int fors_detect_objects_destroy(cpl_plugin *plugin)
239 {
240  cpl_recipe *recipe;
241 
242  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
243  recipe = (cpl_recipe *)plugin;
244  else
245  return -1;
246 
247  cpl_parameterlist_delete(recipe->parameters);
248 
249  return 0;
250 }
251 
252 
262 static int fors_detect_objects(cpl_parameterlist *parlist,
263  cpl_frameset *frameset)
264 {
265 
266  const char *recipe = "fors_detect_objects";
267 
268 
269  /*
270  * Input parameters
271  */
272 
273  int slit_margin;
274  int ext_radius;
275  int cont_radius;
276 
277  /*
278  * CPL objects
279  */
280 
281  cpl_image *mapped = NULL;
282  cpl_image *dummy = NULL;
283  cpl_table *slits = NULL;
284  cpl_propertylist *header = NULL;
285 
286  /*
287  * Auxiliary variables
288  */
289 
290  char version[80];
291  const char *slit_location_tag;
292  const char *input_tag;
293  const char *outpt_tag;
294  int nframes;
295  double gain;
296  int scimxu;
297  int scimos;
298  int scilss;
299  int stdmxu;
300  int stdmos;
301  int stdlss;
302 
303  char *instrume = NULL;
304 
305 
306  cpl_msg_set_indentation(2);
307 
308 
309  /*
310  * Get configuration parameters
311  */
312 
313  cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
314  cpl_msg_indent_more();
315 
316  slit_margin = dfs_get_parameter_int(parlist,
317  "fors.fors_detect_objects.slit_margin",
318  NULL);
319  if (slit_margin < 0)
320  fors_detect_objects_exit("Value must be zero or positive");
321 
322  ext_radius = dfs_get_parameter_int(parlist,
323  "fors.fors_detect_objects.ext_radius",
324  NULL);
325  if (ext_radius < 0)
326  fors_detect_objects_exit("Value must be zero or positive");
327 
328  cont_radius = dfs_get_parameter_int(parlist,
329  "fors.fors_detect_objects.cont_radius",
330  NULL);
331  if (cont_radius < 0)
332  fors_detect_objects_exit("Value must be zero or positive");
333 
334  if (cpl_error_get_code())
335  fors_detect_objects_exit("Failure reading configuration parameters");
336 
337 
338  cpl_msg_indent_less();
339  cpl_msg_info(recipe, "Check input set-of-frames:");
340  cpl_msg_indent_more();
341 
342  nframes = scimxu = cpl_frameset_count_tags(frameset, "MAPPED_SCI_MXU");
343  nframes += scimos = cpl_frameset_count_tags(frameset, "MAPPED_SCI_MOS");
344  nframes += scilss = cpl_frameset_count_tags(frameset, "MAPPED_SCI_LSS");
345  nframes += stdmxu = cpl_frameset_count_tags(frameset, "MAPPED_STD_MXU");
346  nframes += stdmos = cpl_frameset_count_tags(frameset, "MAPPED_STD_MOS");
347  nframes += stdlss = cpl_frameset_count_tags(frameset, "MAPPED_STD_LSS");
348 
349  if (nframes == 0) {
350  fors_detect_objects_exit("Missing input scientific spectra");
351  }
352  if (nframes > 1) {
353  cpl_msg_error(recipe, "Too many input scientific spectra (%d > 1)",
354  nframes);
355  fors_detect_objects_exit(NULL);
356  }
357 
358  if (scimxu) {
359  input_tag = "MAPPED_SCI_MXU";
360  outpt_tag = "OBJECT_TABLE_SCI_MXU";
361  slit_location_tag = "SLIT_LOCATION_MXU";
362  }
363  else if (scimos) {
364  input_tag = "MAPPED_SCI_MOS";
365  outpt_tag = "OBJECT_TABLE_SCI_MOS";
366  slit_location_tag = "SLIT_LOCATION_MOS";
367  }
368  else if (scilss) {
369  input_tag = "MAPPED_SCI_LSS";
370  outpt_tag = "OBJECT_TABLE_SCI_LSS";
371  slit_location_tag = "SLIT_LOCATION_LSS";
372  }
373  else if (stdmxu) {
374  input_tag = "MAPPED_STD_MXU";
375  outpt_tag = "OBJECT_TABLE_SCI_MXU";
376  slit_location_tag = "SLIT_LOCATION_MXU";
377  }
378  else if (stdmos) {
379  input_tag = "MAPPED_STD_MOS";
380  outpt_tag = "OBJECT_TABLE_SCI_MOS";
381  slit_location_tag = "SLIT_LOCATION_MOS";
382  }
383  else if (stdlss) {
384  input_tag = "MAPPED_STD_LSS";
385  outpt_tag = "OBJECT_TABLE_SCI_LSS";
386  slit_location_tag = "SLIT_LOCATION_LSS";
387  }
388 
389  if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
390  cpl_msg_warning(cpl_func,"Input frames are not from the same grism");
391 
392  if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
393  cpl_msg_warning(cpl_func,"Input frames are not from the same filter");
394 
395  if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
396  cpl_msg_warning(cpl_func,"Input frames are not from the same chip");
397 
398  header = dfs_load_header(frameset, input_tag, 0);
399  if (header == NULL)
400  fors_detect_objects_exit("Cannot load scientific frame header");
401 
402  instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
403  if (instrume == NULL)
404  fors_detect_objects_exit("Missing keyword INSTRUME in reference frame "
405  "header");
406 
407  if (instrume[4] == '1')
408  snprintf(version, 80, "%s/%s", "fors1", VERSION);
409  if (instrume[4] == '2')
410  snprintf(version, 80, "%s/%s", "fors2", VERSION);
411 
412  gain = cpl_propertylist_get_double(header, "ESO DET OUT1 CONAD");
413 
414  cpl_propertylist_delete(header); header = NULL;
415 
416  if (cpl_error_get_code() != CPL_ERROR_NONE)
417  fors_detect_objects_exit("Missing keyword ESO DET OUT1 CONAD in "
418  "scientific frame header");
419 
420  cpl_msg_info(recipe, "The gain factor is: %.2f e-/ADU", gain);
421 
422 
423  cpl_msg_indent_less();
424  cpl_msg_info(recipe, "Load input frames...");
425  cpl_msg_indent_more();
426 
427  mapped = dfs_load_image(frameset, input_tag, CPL_TYPE_FLOAT, 0, 0);
428  if (mapped == NULL)
429  fors_detect_objects_exit("Cannot load input scientific frame");
430 
431  slits = dfs_load_table(frameset, slit_location_tag, 1);
432  if (slits == NULL)
433  fors_detect_objects_exit("Cannot load slits location table");
434 
435  cpl_msg_indent_less();
436  cpl_msg_info(recipe, "Object detection...");
437  cpl_msg_indent_more();
438 
439  mos_clean_cosmics(mapped, gain, -1., -1.);
440  dummy = mos_detect_objects(mapped, slits, slit_margin,
441  ext_radius, cont_radius);
442 
443  cpl_image_delete(mapped); mapped = NULL;
444  cpl_image_delete(dummy); dummy = NULL;
445 
446  if (dfs_save_table(frameset, slits, outpt_tag, NULL, parlist,
447  recipe, version))
448  fors_detect_objects_exit(NULL);
449 
450  cpl_table_delete(slits); slits = NULL;
451 
452  return 0;
453 }
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
cpl_image * mos_detect_objects(cpl_image *image, cpl_table *slits, int margin, int maxradius, int conradius)
Detect objects in rectified scientific frame.
Definition: moses.c:13944
int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
Saving table data of given category.
Definition: fors_dfs.c:1683
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
int dfs_save_table(cpl_frameset *frameset, const cpl_table *table, const char *category, cpl_propertylist *header, const cpl_parameterlist *parlist, const char *recipename, const char *version)
Saving table data of given category.
Definition: fors_dfs.c:1575
Definition: list.c:74
cpl_error_code mos_clean_cosmics(cpl_image *image, float gain, float threshold, float ratio)
Remove cosmic rays from sky-subtracted CCD spectral exposure.
Definition: moses.c:13174