IIINSTRUMENT Pipeline Reference Manual  6.2.2
isaac_img_detlin.c
1 /* $Id: isaac_img_detlin.c,v 1.31 2013-03-12 08:06:48 llundin Exp $
2  *
3  * This file is part of the ISAAC 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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: llundin $
23  * $Date: 2013-03-12 08:06:48 $
24  * $Revision: 1.31 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include <math.h>
37 #include <cpl.h>
38 
39 #include "irplib_utils.h"
40 
41 #include "isaac_utils.h"
42 #include "isaac_pfits.h"
43 #include "isaac_dfs.h"
44 #include "isaac_fit.h"
45 
46 /*-----------------------------------------------------------------------------
47  Functions prototypes
48  -----------------------------------------------------------------------------*/
49 
50 static int isaac_img_detlin_create(cpl_plugin *);
51 static int isaac_img_detlin_exec(cpl_plugin *);
52 static int isaac_img_detlin_destroy(cpl_plugin *);
53 static int isaac_img_detlin(cpl_parameterlist *, cpl_frameset *);
54 
55 static cpl_imagelist * isaac_img_detlin_load(cpl_frameset *, cpl_frameset *,
56  double **);
57 static int isaac_img_detlin_save(cpl_imagelist *, cpl_parameterlist *,
58  cpl_frameset *);
59 
60 /*-----------------------------------------------------------------------------
61  Static variables
62  -----------------------------------------------------------------------------*/
63 
64 static struct {
65  /* Inputs */
66  int force_flag;
67 
68  /* Outputs */
69  double lamp_stability;
70 } isaac_img_detlin_config;
71 
72 static char isaac_img_detlin_description[] =
73 "isaac_img_detlin -- ISAAC imaging detector linearity recipe.\n"
74 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
75 "raw-file.fits "ISAAC_IMG_DETLIN_LAMP_RAW" or\n"
76 "raw-file.fits "ISAAC_IMG_DETLIN_DARK_RAW"\n";
77 
78 /*-----------------------------------------------------------------------------
79  Functions code
80  -----------------------------------------------------------------------------*/
81 
82 /*----------------------------------------------------------------------------*/
90 /*----------------------------------------------------------------------------*/
91 int cpl_plugin_get_info(cpl_pluginlist * list)
92 {
93  cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe));
94  cpl_plugin * plugin = &recipe->interface;
95 
96  cpl_plugin_init(plugin,
97  CPL_PLUGIN_API,
98  ISAAC_BINARY_VERSION,
99  CPL_PLUGIN_TYPE_RECIPE,
100  "isaac_img_detlin",
101  "Detector linearity recipe",
102  isaac_img_detlin_description,
103  "Lars Lundin",
104  PACKAGE_BUGREPORT,
106  isaac_img_detlin_create,
107  isaac_img_detlin_exec,
108  isaac_img_detlin_destroy);
109 
110  cpl_pluginlist_append(list, plugin);
111 
112  return 0;
113 }
114 
115 /*----------------------------------------------------------------------------*/
124 /*----------------------------------------------------------------------------*/
125 static int isaac_img_detlin_create(cpl_plugin * plugin)
126 {
127  cpl_recipe * recipe;
128  cpl_parameter * p;
129 
130  /* Get the recipe out of the plugin */
131  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
132  recipe = (cpl_recipe *)plugin;
133  else return CPL_ERROR_UNSPECIFIED;
134 
135  /* Create the parameters list in the cpl_recipe object */
136  recipe->parameters = cpl_parameterlist_new();
137 
138  /* Fill the parameters list */
139  /* --force */
140  p = cpl_parameter_new_value("isaac.isaac_img_detlin.force", CPL_TYPE_BOOL,
141  "flag to force th computation", "isaac.isaac_img_detlin",
142  FALSE);
143  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "force");
144  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
145  cpl_parameterlist_append(recipe->parameters, p);
146 
147  /* Return */
148  return 0;
149 }
150 
151 /*----------------------------------------------------------------------------*/
157 /*----------------------------------------------------------------------------*/
158 static int isaac_img_detlin_exec(cpl_plugin * plugin)
159 {
160  cpl_recipe * recipe;
161 
162  /* Get the recipe out of the plugin */
163  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
164  recipe = (cpl_recipe *)plugin;
165  else return CPL_ERROR_UNSPECIFIED;
166 
167  return isaac_img_detlin(recipe->parameters, recipe->frames);
168 }
169 
170 /*----------------------------------------------------------------------------*/
176 /*----------------------------------------------------------------------------*/
177 static int isaac_img_detlin_destroy(cpl_plugin * plugin)
178 {
179  cpl_recipe * recipe;
180 
181  /* Get the recipe out of the plugin */
182  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
183  recipe = (cpl_recipe *)plugin;
184  else return CPL_ERROR_UNSPECIFIED;
185 
186  cpl_parameterlist_delete(recipe->parameters);
187  return 0;
188 }
189 
190 /*----------------------------------------------------------------------------*/
197 /*----------------------------------------------------------------------------*/
198 static int isaac_img_detlin(
199  cpl_parameterlist * parlist,
200  cpl_frameset * framelist)
201 {
202  cpl_parameter * par;
203  cpl_frameset * darkframes;
204  cpl_frameset * lampframes;
205  cpl_imagelist * iset;
206  double * ditval;
207  cpl_imagelist * fitres;
208 
209  /* Initialise */
210  par = NULL;
211 
212  /* Retrieve input parameters */
213  /* Force flag */
214  par = cpl_parameterlist_find(parlist, "isaac.isaac_img_detlin.force");
215  isaac_img_detlin_config.force_flag = cpl_parameter_get_bool(par);
216 
217  /* Identify the RAW and CALIB frames in the input frameset */
218  if (isaac_dfs_set_groups(framelist)) {
219  cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
220  return CPL_ERROR_UNSPECIFIED;
221  }
222 
223  /* Retrieve raw frames */
224  if ((lampframes = isaac_extract_frameset(framelist,
225  ISAAC_IMG_DETLIN_LAMP_RAW)) == NULL) {
226  cpl_msg_error(cpl_func, "Cannot find any lamp frame in input");
227  return CPL_ERROR_UNSPECIFIED;
228  }
229  if ((darkframes = isaac_extract_frameset(framelist,
230  ISAAC_IMG_DETLIN_DARK_RAW)) == NULL) {
231  cpl_msg_error(cpl_func, "Cannot find any dark frame in input");
232  cpl_frameset_delete(lampframes);
233  return CPL_ERROR_UNSPECIFIED;
234  }
235 
236  /* Load the data and check the DIT consistency */
237  cpl_msg_info(cpl_func, "Load the data");
238  cpl_msg_indent_more();
239  if ((iset = isaac_img_detlin_load(lampframes, darkframes, &ditval))==NULL) {
240  cpl_msg_error(cpl_func, "Cannot load the data");
241  cpl_frameset_delete(lampframes);
242  cpl_frameset_delete(darkframes);
243  cpl_msg_indent_less();
244  return CPL_ERROR_UNSPECIFIED;
245  }
246  cpl_frameset_delete(lampframes);
247  cpl_frameset_delete(darkframes);
248  cpl_msg_indent_less();
249 
250  /* Compute the linearity coefficients */
251  cpl_msg_info(cpl_func, "Compute the linearity coefficients");
252  cpl_msg_indent_more();
253  if ((fitres = isaac_imagelist_fit_polynomial(iset, ditval, 3)) == NULL) {
254  cpl_msg_error(cpl_func, "Cannot compute the linearity coefficients");
255  cpl_imagelist_delete(iset);
256  cpl_free(ditval);
257  cpl_msg_indent_less();
258  return CPL_ERROR_UNSPECIFIED;
259  }
260  cpl_msg_indent_less();
261  cpl_free(ditval);
262  cpl_imagelist_delete(iset);
263 
264  /* Save the products */
265  cpl_msg_info(cpl_func, "Save the products");
266  cpl_msg_indent_more();
267  if (isaac_img_detlin_save(fitres, parlist, framelist)==-1) {
268  cpl_msg_error(cpl_func, "Cannot save the products");
269  cpl_imagelist_delete(fitres);
270  cpl_msg_indent_less();
271  return CPL_ERROR_UNSPECIFIED;
272  }
273  cpl_msg_indent_less();
274 
275  /* Free and return */
276  cpl_imagelist_delete(fitres);
277  return 0;
278 }
279 
280 /*----------------------------------------------------------------------------*/
288 /*----------------------------------------------------------------------------*/
289 static cpl_imagelist * isaac_img_detlin_load(
290  cpl_frameset * lamps,
291  cpl_frameset * darks,
292  double ** ditvals)
293 {
294  int nb_lamps;
295  cpl_vector * selection;
296  cpl_frame * frame;
297  cpl_propertylist * propertylist;
298  double dit_lamp, dit_dark;
299  int dit_stab;
300  cpl_imagelist * lamps_data;
301  cpl_imagelist * darks_data;
302  double * stab_levels;
303  double * dit_purged;
304  int i, j;
305 
306  /* Check that there are as many lamp as darks */
307  if ((nb_lamps = cpl_frameset_get_size(lamps)) < 3) return NULL;
308  if (cpl_frameset_get_size(darks) != nb_lamps) return NULL;
309 
310  /* Check out that they have consistent integration times */
311  cpl_msg_info(cpl_func, "Checking DIT consistency");
312  selection = cpl_vector_new(nb_lamps);
313  *ditvals = cpl_malloc(nb_lamps * sizeof(double));
314  dit_stab = 0;
315  for (i=0; i<nb_lamps; i++) {
316  /* Check if ok */
317  if (cpl_error_get_code()) {
318  cpl_vector_delete(selection);
319  cpl_free(*ditvals);
320  return NULL;
321  }
322  /* DIT from LAMP */
323  frame = cpl_frameset_get_position(lamps, i);
324  propertylist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
325  dit_lamp = (double)isaac_pfits_get_dit(propertylist);
326  cpl_propertylist_delete(propertylist);
327  if (cpl_error_get_code()) {
328  cpl_msg_error(cpl_func, "Cannot get DIT");
329  cpl_vector_delete(selection);
330  cpl_free(*ditvals);
331  return NULL;
332  }
333  /* DIT from DARK */
334  frame = cpl_frameset_get_position(darks, i);
335  propertylist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
336  dit_dark = (double)isaac_pfits_get_dit(propertylist);
337  cpl_propertylist_delete(propertylist);
338  if (cpl_error_get_code()) {
339  cpl_msg_error(cpl_func, "Cannot get DIT");
340  cpl_vector_delete(selection);
341  cpl_free(*ditvals);
342  return NULL;
343  }
344  /* Check consistency */
345  if (fabs(dit_dark-dit_lamp) > 1e-3) {
346  cpl_msg_error(cpl_func, "DIT not consistent between LAMP and DARK");
347  cpl_vector_delete(selection);
348  cpl_free(*ditvals);
349  return NULL;
350  }
351  (*ditvals)[i] = dit_lamp;
352  /* Set selection */
353  if (i==0) {
354  cpl_vector_set(selection, i, -1.0);
355  dit_stab ++;
356  } else {
357  if (fabs(dit_lamp - (*ditvals)[0]) < 1e-5) {
358  cpl_vector_set(selection, i, -1.0);
359  dit_stab ++;
360  } else {
361  cpl_vector_set(selection, i, 1.0);
362  }
363  }
364  }
365 
366  /* Check if there are enough DITs for stability check */
367  if (dit_stab < 2) {
368  cpl_msg_error(cpl_func, "Not enough frames for stability check");
369  cpl_vector_delete(selection);
370  cpl_free(*ditvals);
371  return NULL;
372  }
373 
374  /* Load the data and compute lamp-dark */
375  cpl_msg_info(cpl_func, "Compute the differences lamp - dark");
376  lamps_data = cpl_imagelist_load_frameset(lamps, CPL_TYPE_FLOAT, 1, 0);
377  darks_data = cpl_imagelist_load_frameset(darks, CPL_TYPE_FLOAT, 1, 0);
378  if (cpl_imagelist_subtract(lamps_data,darks_data) != CPL_ERROR_NONE) {
379  cpl_msg_error(cpl_func, "Cannot subtract the 2 image lists");
380  cpl_vector_delete(selection);
381  cpl_free(*ditvals);
382  if (lamps_data) cpl_imagelist_delete(lamps_data);
383  if (darks_data) cpl_imagelist_delete(darks_data);
384  return NULL;
385  }
386  cpl_imagelist_delete(darks_data);
387 
388  /* Check the lamp stability */
389  cpl_msg_info(cpl_func, "Check the lamp stability");
390  stab_levels = cpl_malloc(dit_stab * sizeof(double));
391  j = 0;
392  for (i=0; i<nb_lamps; i++) {
393  if (cpl_vector_get(selection, i) < 0) {
394  stab_levels[j] =
395  cpl_image_get_mean(cpl_imagelist_get(lamps_data, i));
396  j++;
397  }
398  }
399 
400  /* Compute the lamp stability */
401  isaac_img_detlin_config.lamp_stability = 0.0;
402  for (i=1; i<dit_stab; i++) {
403  if ((fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0]) >
404  isaac_img_detlin_config.lamp_stability)
405  isaac_img_detlin_config.lamp_stability =
406  fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0];
407  }
408  cpl_free(stab_levels);
409 
410  /* Check the lamp stability */
411  if (isaac_img_detlin_config.lamp_stability > 0.01) {
412  if (isaac_img_detlin_config.force_flag == 1) {
413  cpl_msg_warning(cpl_func,
414  "level difference #%d too high - proceed anyway",i+1);
415  } else {
416  cpl_msg_error(cpl_func, "level difference #%d too high", i+1);
417  cpl_vector_delete(selection);
418  cpl_free(*ditvals);
419  cpl_imagelist_delete(lamps_data);
420  return NULL;
421  }
422  }
423 
424  /* Purge the stability check data and DITs */
425  if (cpl_imagelist_erase(lamps_data, selection) != CPL_ERROR_NONE) {
426  cpl_msg_error(cpl_func, "cannot discard stability frames");
427  cpl_vector_delete(selection);
428  cpl_free(*ditvals);
429  cpl_imagelist_delete(lamps_data);
430  return NULL;
431  }
432  dit_purged = cpl_malloc(cpl_imagelist_get_size(lamps_data)*sizeof(double));
433  j = 0;
434  for (i=0; i<nb_lamps; i++) {
435  if (cpl_vector_get(selection, i) > 0) {
436  dit_purged[j] = (*ditvals)[i];
437  j++;
438  }
439  }
440  cpl_free(*ditvals);
441  *ditvals = dit_purged;
442 
443  /* Free and eturn */
444  cpl_vector_delete(selection);
445  return lamps_data;
446 }
447 
448 /*----------------------------------------------------------------------------*/
456 /*----------------------------------------------------------------------------*/
457 static int isaac_img_detlin_save(
458  cpl_imagelist * fitres,
459  cpl_parameterlist * parlist,
460  cpl_frameset * set)
461 {
462  const cpl_frame * ref_frame;
463  cpl_propertylist * plist;
464  cpl_propertylist * qclist;
465  cpl_propertylist * paflist;
466  double qc_meda, qc_medb, qc_medc, qc_medq;
467 
468  /* Compute the QC params */
469  qc_meda = cpl_image_get_median(cpl_imagelist_get(fitres, 0));
470  qc_medb = cpl_image_get_median(cpl_imagelist_get(fitres, 1));
471  qc_medc = cpl_image_get_median(cpl_imagelist_get(fitres, 2));
472  qc_medq = cpl_image_get_median(cpl_imagelist_get(fitres, 3));
473 
474  /* Get the QC params in qclist */
475  qclist = cpl_propertylist_new();
476  cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDA", qc_meda);
477  cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDB", qc_medb);
478  cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDC", qc_medc);
479  cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDQ", qc_medq);
480  cpl_propertylist_append_double(qclist, "ESO QC DETLIN LAMP",
481  isaac_img_detlin_config.lamp_stability );
482 
483  /* Write the _A FITS FILE */
484  irplib_dfs_save_image(set,
485  parlist,
486  set,
487  cpl_imagelist_get(fitres, 0),
488  CPL_BPP_IEEE_FLOAT,
489  "isaac_img_detlin",
490  ISAAC_IMG_DETLIN_A,
491  qclist,
492  NULL,
493  PACKAGE "/" PACKAGE_VERSION,
494  "isaac_img_detlin_A.fits");
495 
496  /* Write the _B FITS FILE */
497  irplib_dfs_save_image(set,
498  parlist,
499  set,
500  cpl_imagelist_get(fitres, 1),
501  CPL_BPP_IEEE_FLOAT,
502  "isaac_img_detlin",
503  ISAAC_IMG_DETLIN_B,
504  qclist,
505  NULL,
506  PACKAGE "/" PACKAGE_VERSION,
507  "isaac_img_detlin_B.fits");
508 
509  /* Write the _C FITS FILE */
510  irplib_dfs_save_image(set,
511  parlist,
512  set,
513  cpl_imagelist_get(fitres, 2),
514  CPL_BPP_IEEE_FLOAT,
515  "isaac_img_detlin",
516  ISAAC_IMG_DETLIN_C,
517  qclist,
518  NULL,
519  PACKAGE "/" PACKAGE_VERSION,
520  "isaac_img_detlin_C.fits");
521 
522  /* Write the _Q FITS FILE */
523  irplib_dfs_save_image(set,
524  parlist,
525  set,
526  cpl_imagelist_get(fitres, 3),
527  CPL_BPP_IEEE_FLOAT,
528  "isaac_img_detlin",
529  ISAAC_IMG_DETLIN_Q,
530  qclist,
531  NULL,
532  PACKAGE "/" PACKAGE_VERSION,
533  "isaac_img_detlin_Q.fits");
534 
535  /* Get the reference frame */
536  ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
537 
538  /* Get FITS header from reference file */
539  if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
540  0)) == NULL) {
541  cpl_msg_error(cpl_func, "getting header from reference frame");
542  cpl_propertylist_delete(qclist);
543  return CPL_ERROR_UNSPECIFIED;
544  }
545 
546  /* Get the keywords for the paf file */
547  paflist = cpl_propertylist_new();
548  cpl_propertylist_copy_property_regexp(paflist, plist,
549  "^(ARCFILE|MJD-OBS|ESO TPL ID|DATE-OBS|ESO DET DIT|"
550  "ESO DET NDIT|ESO DET NCORRS|ESO DET MODE NAME)$", 0);
551  cpl_propertylist_delete(plist);
552 
553  /* Copy the QC in paflist */
554  cpl_propertylist_copy_property_regexp(paflist, qclist, ".", 0);
555  cpl_propertylist_delete(qclist);
556 
557  /* PRO.CATG */
558  cpl_propertylist_update_string(paflist, CPL_DFS_PRO_CATG,
559  ISAAC_IMG_DETLIN_A);
560 
561  /* Save the PAF file */
562  cpl_dfs_save_paf("ISAAC",
563  "isaac_img_detlin",
564  paflist,
565  "isaac_img_detlin_QC.paf");
566  cpl_propertylist_delete(paflist);
567  return 0;
568 }
569 
int isaac_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: isaac_dfs.c:60
cpl_imagelist * isaac_imagelist_fit_polynomial(const cpl_imagelist *ilist, const double *dit, int deg)
Compute the non linearity of the detector.
Definition: isaac_fit.c:78
double isaac_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
Definition: isaac_pfits.c:305
cpl_frameset * isaac_extract_frameset(const cpl_frameset *self, const char *tag)
Extract the frames with the given tag from a frameset.
Definition: isaac_utils.c:356
const char * isaac_get_license(void)
Get the pipeline copyright and license.
Definition: isaac_utils.c:62