GRAVI Pipeline Reference Manual  0.6.3
gravi_all_flat.c
1 /* $Id: gravi_all_flat.c,v 1.29 2009/02/10 09:16:12 llundin Exp $
2  *
3  * This file is part of the GRAVI Pipeline
4  * Copyright (C) 2002,2003 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: llundin $
23  * $Date: 2009/02/10 09:16:12 $
24  * $Revision: 1.29 $
25  * $Name: $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include <cpl.h>
37 #include <stdio.h>
38 #include <string.h>
39 
40 #include "gravi_calib.h"
41 #include "gravi_utils.h"
42 #include "gravi_pfits.h"
43 #include "gravi_dfs.h"
44 #include <time.h>
45 #include "gravi_data.h"
46 
47 
48 /*-----------------------------------------------------------------------------
49  Private function prototypes
50  -----------------------------------------------------------------------------*/
51 
52 static int gravi_all_flat_create(cpl_plugin *);
53 static int gravi_all_flat_exec(cpl_plugin *);
54 static int gravi_all_flat_destroy(cpl_plugin *);
55 static int gravi_all_flat(cpl_frameset *, const cpl_parameterlist *);
56 
57 /*-----------------------------------------------------------------------------
58  Static variables
59  -----------------------------------------------------------------------------*/
60 
61 static char gravi_all_flat_description[] =
62 "This recipe is used to compute the flat matrix.\n"
63 "The given output FITS file contain a flat table with "
64 "the values of the transmission, phase and coherence extract "
65 "using the flat matrix \n"
66 "The description should include the required FITS-files and\n"
67 "their associated tags, e.g.\n"
68 "Description DO category\n"
69 "Required input :\n"
70 "Raw flat file (There is 4 files per profile map) " GRAVI_FLAT "\n"
71 "Raw dark file " GRAVI_DARK "\n"
72 "or\n"
73 "Master dark " DARK "\n"
74 "Bad pixel map " BAD "\n"
75 "Ouput :\n"
76 "Profile map " FLAT "\n"
77 "Bad pixel map (if there is not bad pixel map in the inputs) " BAD "\n"
78 "\n"
79 "Additionally, it should describe functionality of the expected output."
80 "\n";
81 
82 /*-----------------------------------------------------------------------------
83  Function code
84  -----------------------------------------------------------------------------*/
85 
86 /*----------------------------------------------------------------------------*/
96 /*----------------------------------------------------------------------------*/
97 int cpl_plugin_get_info(cpl_pluginlist * list)
98 {
99  cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
100  cpl_plugin * plugin = &recipe->interface;
101 
102  if (cpl_plugin_init(plugin,
103  CPL_PLUGIN_API,
104  GRAVI_BINARY_VERSION,
105  CPL_PLUGIN_TYPE_RECIPE,
106  "gravi_all_flat",
107  "This recipe is used to compute flat matrix",
108  gravi_all_flat_description,
109  "Firstname Lastname",
110  PACKAGE_BUGREPORT,
111  gravi_get_license(),
112  gravi_all_flat_create,
113  gravi_all_flat_exec,
114  gravi_all_flat_destroy)) {
115  cpl_msg_error(cpl_func, "Plugin initialization failed");
116  (void)cpl_error_set_where(cpl_func);
117  return 1;
118  }
119 
120  if (cpl_pluginlist_append(list, plugin)) {
121  cpl_msg_error(cpl_func, "Error adding plugin to list");
122  (void)cpl_error_set_where(cpl_func);
123  return 1;
124  }
125 
126  return 0;
127 }
128 
129 /*----------------------------------------------------------------------------*/
137 /*----------------------------------------------------------------------------*/
138 static int gravi_all_flat_create(cpl_plugin * plugin)
139 {
140  cpl_recipe * recipe;
141  cpl_parameter * p;
142 
143  /* Do not create the recipe if an error code is already set */
144  if (cpl_error_get_code() != CPL_ERROR_NONE) {
145  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
146  cpl_func, __LINE__, cpl_error_get_where());
147  return (int)cpl_error_get_code();
148  }
149 
150  if (plugin == NULL) {
151  cpl_msg_error(cpl_func, "Null plugin");
152  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
153  }
154 
155  /* Verify plugin type */
156  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
157  cpl_msg_error(cpl_func, "Plugin is not a recipe");
158  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
159  }
160 
161  /* Get the recipe */
162  recipe = (cpl_recipe *)plugin;
163 
164  /* Create the parameters list in the cpl_recipe object */
165  recipe->parameters = cpl_parameterlist_new();
166  if (recipe->parameters == NULL) {
167  cpl_msg_error(cpl_func, "Parameter list allocation failed");
168  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
169  }
170 
171  /* Fill the parameters list */
172  /* -- */
173  p = cpl_parameter_new_value("gravi.gravi_all_flat."
174  "profile_width", CPL_TYPE_INT, "profile width option",
175  "gravi.gravi_all_flat", 5);
176  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "profile_width");
177  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
178  cpl_parameterlist_append(recipe->parameters, p);
179 
180  p = cpl_parameter_new_value("gravi."
181  "flat_param.Bad_dark_threshold", CPL_TYPE_INT, "the rms factor for "
182  "dark bad pixel threshold", "gravi.gravi_all_flat", 5);
183  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "Bad_dark_threshold");
184  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
185  cpl_parameterlist_append(recipe->parameters, p);
186 
187 
188  return 0;
189 }
190 
191 /*----------------------------------------------------------------------------*/
197 /*----------------------------------------------------------------------------*/
198 static int gravi_all_flat_exec(cpl_plugin * plugin)
199 {
200 
201  cpl_recipe * recipe;
202  int recipe_status;
203  cpl_errorstate initial_errorstate = cpl_errorstate_get();
204 
205  /* Return immediately if an error code is already set */
206  if (cpl_error_get_code() != CPL_ERROR_NONE) {
207  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
208  cpl_func, __LINE__, cpl_error_get_where());
209  return (int)cpl_error_get_code();
210  }
211 
212  if (plugin == NULL) {
213  cpl_msg_error(cpl_func, "Null plugin");
214  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
215  }
216 
217  /* Verify plugin type */
218  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
219  cpl_msg_error(cpl_func, "Plugin is not a recipe");
220  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
221  }
222 
223  /* Get the recipe */
224  recipe = (cpl_recipe *)plugin;
225 
226  /* Verify parameter and frame lists */
227  if (recipe->parameters == NULL) {
228  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
229  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
230  }
231  if (recipe->frames == NULL) {
232  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
233  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
234  }
235 
236  /* Invoke the recipe */
237  recipe_status = gravi_all_flat(recipe->frames, recipe->parameters);
238 
239  /* Ensure DFS-compliance of the products */
240  if (cpl_dfs_update_product_header(recipe->frames)) {
241  if (!recipe_status) recipe_status = (int)cpl_error_get_code();
242  }
243 
244  if (!cpl_errorstate_is_equal(initial_errorstate)) {
245  /* Dump the error history since recipe execution start.
246  At this point the recipe cannot recover from the error */
247  cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
248  }
249 
250  return recipe_status;
251 }
252 
253 /*----------------------------------------------------------------------------*/
259 /*----------------------------------------------------------------------------*/
260 static int gravi_all_flat_destroy(cpl_plugin * plugin)
261 {
262  cpl_recipe * recipe;
263 
264  if (plugin == NULL) {
265  cpl_msg_error(cpl_func, "Null plugin");
266  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
267  }
268 
269  /* Verify plugin type */
270  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
271  cpl_msg_error(cpl_func, "Plugin is not a recipe");
272  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
273  }
274 
275  /* Get the recipe */
276  recipe = (cpl_recipe *)plugin;
277 
278  cpl_parameterlist_delete(recipe->parameters);
279 
280  return 0;
281 }
282 
283 
284 /*----------------------------------------------------------------------------*/
291 /*----------------------------------------------------------------------------*/
292 static int gravi_all_flat(cpl_frameset * frameset,
293  const cpl_parameterlist * parlist)
294 {
295  cpl_frameset * flat_frameset, * dark_frameset, * darkcalib_frameset, * badpix_frameset;
296  cpl_propertylist * applist, * primary_hdr, * bad_primary_hdr;
297  cpl_frame * frame, *_frame;
298  const char * filename;
299  gravi_data * profile_map, * dark_file, * dark_map, * bad_map;
300  gravi_data ** flat_data;
301  double gain_ft, gain_sc;
302  int nb_frame, i;
303 
304  /* Identify the RAW and CALIB frames in the input frameset */
305  cpl_ensure_code(gravi_dfs_set_groups(frameset) == CPL_ERROR_NONE,
306  cpl_error_get_code()) ;
307 
308  /* - Extract a set of frame flat */
309 
310  flat_frameset = gravi_frameset_extract_flat(frameset);
311 
312  darkcalib_frameset = gravi_frameset_extract_dark_file(frameset);
313 
314  dark_frameset = gravi_frameset_extract_dark(frameset);
315 
316  badpix_frameset = gravi_frameset_extract_badpix(frameset);
317  if (cpl_frameset_is_empty(flat_frameset) ||
318  ((cpl_frameset_is_empty(dark_frameset)) &&
319  cpl_frameset_is_empty(darkcalib_frameset))) {
320  /* To use this recipe the frameset must contain at least
321  * one flat frame. */
322  cpl_frameset_delete(flat_frameset);
323  cpl_frameset_delete(dark_frameset);
324  cpl_frameset_delete(darkcalib_frameset);
325  cpl_frameset_delete(badpix_frameset);
326  return (int)cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
327  "No dark or flat frame on the inputs frameset") ;
328  }
329 
330  /* Get the number of the flat frame contained in the frameset */
331 
332  nb_frame = cpl_frameset_get_size(flat_frameset);
333  /* Check that the number of flat frames is upper than 4 */
334  if (nb_frame < 4){
335  cpl_frameset_delete(flat_frameset);
336  cpl_frameset_delete(dark_frameset);
337  cpl_frameset_delete(darkcalib_frameset);
338  cpl_frameset_delete(badpix_frameset);
339  return (int)cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
340  "The number of flat frames must be more than 4");
341  }
342 
343  /* Extract the dark map */
344  if (!cpl_frameset_is_empty(dark_frameset)){
345  _frame = cpl_frameset_get_position(dark_frameset, 0);
346  filename = cpl_frame_get_filename(_frame);
347  cpl_msg_info (NULL, "This file %s is a dark file", filename);
348 
349  dark_file = gravi_data_load(filename);
350  dark_map = gravi_compute_dark(dark_file);
351 
352  gravi_data_delete(dark_file);
353  }
354  else if (!cpl_frameset_is_empty(darkcalib_frameset)){
355  _frame = cpl_frameset_get_position(darkcalib_frameset, 0);
356  cpl_frameset_insert (dark_frameset, cpl_frame_duplicate (_frame));
357  filename = cpl_frame_get_filename(_frame);
358 
359  cpl_msg_info (NULL, "This file %s is a dark file already "
360  "computed", filename);
361  dark_map = gravi_data_load(filename);
362  }
363  else {
364  cpl_frameset_delete(flat_frameset);
365  cpl_frameset_delete(dark_frameset);
366  cpl_frameset_delete(darkcalib_frameset);
367  cpl_frameset_delete(badpix_frameset);
368 
369  gravi_data_delete(dark_map);
370  return (int)cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
371  "No dark frames in the frameset");
372  }
373 
374  /* Compute the bad pixel map */
375  if (!cpl_frameset_is_empty(badpix_frameset)){
376  _frame = cpl_frameset_get_position(badpix_frameset, 0);
377  filename = cpl_frame_get_filename(_frame);
378  cpl_msg_info (NULL, "This file %s is a bad pixel map", filename);
379 
380  bad_map = gravi_data_load(filename);
381  }
382 
383  else {
384  bad_map = gravi_compute_badpix(dark_map, parlist);
385 
386  if (cpl_error_get_code()) {
387  gravi_data_delete(dark_map);
388  gravi_data_delete(bad_map);
389 
390  cpl_frameset_delete(flat_frameset);
391  cpl_frameset_delete(dark_frameset);
392  cpl_frameset_delete(darkcalib_frameset);
393  cpl_frameset_delete(badpix_frameset);
394  return (int)cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT,
395  "Error while computing the bad pixel map");
396 
397  }
398  /* Save the pad pixel map */
399  bad_primary_hdr = gravi_data_get_propertylist (bad_map,
400  GRAVI_PRIMARY_HDR_NAME_EXT);
401  applist = gravi_propertylist_get_qc (bad_primary_hdr);
402 
403  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, BAD);
404 
405  frame = cpl_frameset_get_position (dark_frameset, 0);
406 
407  if (gravi_data_save (bad_map, frameset, "gravi_bad_map.fits", parlist,
408  dark_frameset, frame, "gravi_all_flat", applist)
409  != CPL_ERROR_NONE){
410 
411  gravi_data_delete(bad_map);
412 
413  gravi_data_delete(dark_map);
414  cpl_frameset_delete(flat_frameset);
415  cpl_frameset_delete(dark_frameset);
416  cpl_frameset_delete(darkcalib_frameset);
417  cpl_propertylist_delete(applist);
418  cpl_frameset_delete(badpix_frameset);
419  return (int) cpl_error_set_message(cpl_func,
420  CPL_ERROR_ILLEGAL_OUTPUT, "Could not save the bad pixel map");
421  }
422  cpl_propertylist_delete (applist);
423  }
424 
425  /* Extract the gravi datas from the flat frame set and the dark map from
426  * the dark frame set */
427 
428  flat_data = cpl_malloc(nb_frame * sizeof(gravi_data *));
429 
430  for(i = 0; i < nb_frame; i++){
431  frame = cpl_frameset_get_position(flat_frameset, i);
432  filename = cpl_frame_get_filename(frame);
433 
434  flat_data[i] = gravi_data_load(filename);
435  }
436 
437  /* Compute the flat calib data of a set of flat frames */
438 
439  /* Compute the profile map */
440 
441  profile_map = gravi_compute_profile(flat_data, dark_map, bad_map,
442  nb_frame, parlist);
443 
444  if (profile_map == NULL) {
445 
446  gravi_data_delete(dark_map);
447  gravi_data_delete(profile_map);
448  for(i = 0; i < 4; i++){
449  gravi_data_delete(flat_data[i]);
450  }
451  cpl_free(flat_data);
452  cpl_frameset_delete(flat_frameset);
453  cpl_frameset_delete(dark_frameset);
454  cpl_frameset_delete(darkcalib_frameset);
455  cpl_frameset_delete(badpix_frameset);
456  return (int)cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT,
457  "Error while computing the profile map");
458  }
459 
460  /* Compute the gain */
461  clock_t start, end;
462  start = clock();
463  gain_ft = gravi_compute_gain(flat_data, nb_frame, dark_map,
464  GRAVI_IMAGING_DATA_FT_EXT);
465  cpl_msg_info (NULL, "QC_MEANGAIN_FT = %e", gain_ft);
466 
467  gain_sc = gravi_compute_gain(flat_data, nb_frame, dark_map,
468  GRAVI_IMAGING_DATA_SC_EXT);
469  cpl_msg_info (NULL, "QC_MEANGAIN_SC = %e", gain_sc);
470  end = clock();
471  printf ("Temps gravi_compute_gain : %f\n", (end - start) / (double)CLOCKS_PER_SEC);
472 
473  gravi_data_delete(bad_map);
474 
475  for(i = 0; i < nb_frame; i++){
476  gravi_data_delete(flat_data[i]);
477  }
478  cpl_free(flat_data);
479  if (cpl_error_get_code()) {
480  gravi_data_delete(dark_map);
481  gravi_data_delete(profile_map);
482  cpl_frameset_delete(flat_frameset);
483  cpl_frameset_delete(dark_frameset);
484  cpl_frameset_delete(darkcalib_frameset);
485  cpl_frameset_delete(badpix_frameset);
486  return (int)cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT,
487  "Error while computing the gain map");
488  }
489 
490  primary_hdr = gravi_data_get_propertylist(profile_map,
491  GRAVI_PRIMARY_HDR_NAME_EXT);
492 
493 
494  cpl_propertylist_append_double (primary_hdr, QC_MEANGAIN_SC, gain_sc);
495  cpl_propertylist_append_double (primary_hdr, QC_MEANGAIN_FT, gain_ft);
496 
497  /* Create product frame, add DataFlow keywords, save the file, log the
498  * saved file in the input frameset*/
499  applist = gravi_propertylist_get_qc(primary_hdr);
500  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, FLAT);
501 
502 // int tel;
503 // char * shutter_key_name;
504 // for (tel = 0; tel < 4; tel ++){
505 // shutter_key_name = cpl_sprintf(GRAVI_SHUTTER_KEY"%d STATUS", tel + 1);
506 //
507 // /* Get the shutter_key_name from the primary header */
508 // printf("statu %d = %s\n", tel, cpl_propertylist_get_string(primary_hdr, shutter_key_name));
509 // cpl_propertylist_set_string(applist, shutter_key_name, "T");
510 //
511 // printf("statu2 %d = %s\n", tel, cpl_propertylist_get_string(primary_hdr, shutter_key_name));
512 //
513 // cpl_free(shutter_key_name);
514 // shutter_key_name = cpl_sprintf("ZEBIiIIII%d STATUS", tel + 1);
515 // cpl_propertylist_append_string(applist, shutter_key_name, "T");
516 // cpl_free(shutter_key_name);
517 // }
519 
520  frame = cpl_frameset_get_position (flat_frameset, 0);
521 
522  if (gravi_data_save (profile_map, frameset, "gravi_profile_map.fits", parlist,
523  frameset, frame, "gravi_all_flat", applist)
524  != CPL_ERROR_NONE){
525 
526  gravi_data_delete(profile_map);
527  gravi_data_delete(dark_map);
528  cpl_frameset_delete(flat_frameset);
529  cpl_frameset_delete(dark_frameset);
530  cpl_frameset_delete(darkcalib_frameset);
531  cpl_frameset_delete(badpix_frameset);
532  cpl_propertylist_delete(applist);
533  return (int) cpl_error_set_message(cpl_func,
534  CPL_ERROR_ILLEGAL_OUTPUT, "Could not save the profile_map");
535  }
536  cpl_propertylist_delete(applist);
537 
538  /* Deallocation of all variables */
539 
540 
541  gravi_data_delete(profile_map);
542  gravi_data_delete(dark_map);
543  cpl_frameset_delete(flat_frameset);
544  cpl_frameset_delete(badpix_frameset);
545  cpl_frameset_delete(darkcalib_frameset);
546  cpl_frameset_delete(dark_frameset);
547 
548  return (int)cpl_error_get_code();
549 }
550 
551