NACO Pipeline Reference Manual  4.4.0
naco_img_dark.c
1 /* $Id: naco_img_dark.c,v 1.75 2011-12-22 11:12:38 llundin Exp $
2  *
3  * This file is part of the NACO 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: 2011-12-22 11:12:38 $
24  * $Revision: 1.75 $
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 "naco_recipe.h"
37 
38 /*-----------------------------------------------------------------------------
39  Defines
40  -----------------------------------------------------------------------------*/
41 
42 #define RECIPE_STRING "naco_img_dark"
43 
44 /*-----------------------------------------------------------------------------
45  Private Functions prototypes
46  -----------------------------------------------------------------------------*/
47 
48 static cpl_error_code naco_img_dark_reduce(cpl_propertylist *,
49  const irplib_framelist *,
50  cpl_image **, cpl_mask **,
51  cpl_mask **, cpl_mask **);
52 
53 static cpl_error_code naco_img_dark_qc(cpl_propertylist *,
54  cpl_propertylist *,
55  const irplib_framelist *);
56 
57 static cpl_error_code naco_img_dark_save(cpl_frameset *,
58  const cpl_parameterlist *,
59  const cpl_propertylist *,
60  const cpl_propertylist *,
61  const cpl_image *, const cpl_mask *,
62  const cpl_mask *, const cpl_mask *,
63  int, const irplib_framelist *);
64 
65 static char * naco_img_dark_make_tag(const cpl_frame*,
66  const cpl_propertylist *, int);
67 
68 NACO_RECIPE_DEFINE(naco_img_dark,
69  NACO_PARAM_REJBORD |
70  NACO_PARAM_HOT_LIM |
71  NACO_PARAM_COLD_LIM |
72  NACO_PARAM_DEV_LIM |
73  NACO_PARAM_NSAMPLES |
74  NACO_PARAM_HALFSIZE,
75  "Dark recipe",
76  "naco_img_dark -- NACO imaging dark recipe.\n"
77  "The files listed in the Set Of Frames (sof-file) "
78  "must be tagged:\n"
79  "NACO-raw-file.fits " NACO_IMG_DARK_RAW "\n");
80 
81 /*-----------------------------------------------------------------------------
82  Static variables
83  -----------------------------------------------------------------------------*/
84 
85 static struct {
86  /* Inputs */
87  int rej_left;
88  int rej_right;
89  int rej_bottom;
90  int rej_top;
91  double hot_thresh;
92  double cold_thresh;
93  double dev_thresh;
94  int hsize;
95  int nsamples;
96 } naco_img_dark_config;
97 
98 /*----------------------------------------------------------------------------*/
102 /*----------------------------------------------------------------------------*/
103 
104 /*-----------------------------------------------------------------------------
105  Functions code
106  -----------------------------------------------------------------------------*/
107 
108 
109 /*----------------------------------------------------------------------------*/
116 /*----------------------------------------------------------------------------*/
117 static int naco_img_dark(cpl_frameset * framelist,
118  const cpl_parameterlist * parlist)
119 {
120  irplib_framelist* allframes = NULL;
121  irplib_framelist* rawframes = NULL;
122  const char ** taglist = NULL;
123  const char * rej_bord;
124  irplib_framelist* f_one = NULL;
125  cpl_imagelist * i_one = NULL;
126  cpl_image * avg = NULL;
127  cpl_mask * hot = NULL;
128  cpl_mask * cold = NULL;
129  cpl_mask * dev = NULL;
130  cpl_propertylist * qclist = cpl_propertylist_new();
131  cpl_propertylist * paflist = cpl_propertylist_new();
132  int nsets;
133  int i;
134  int nb_good = 0;
135 
136 
137  /* Retrieve input parameters */
138  rej_bord = naco_parameterlist_get_string(parlist, RECIPE_STRING, NACO_PARAM_REJBORD);
139  skip_if (0);
140  skip_if (sscanf(rej_bord, "%d %d %d %d",
141  &naco_img_dark_config.rej_left,
142  &naco_img_dark_config.rej_right,
143  &naco_img_dark_config.rej_bottom,
144  &naco_img_dark_config.rej_top) != 4);
145 
146  naco_img_dark_config.hot_thresh =
147  naco_parameterlist_get_double(parlist, RECIPE_STRING, NACO_PARAM_HOT_LIM);
148  naco_img_dark_config.dev_thresh =
149  naco_parameterlist_get_double(parlist, RECIPE_STRING, NACO_PARAM_DEV_LIM);
150  naco_img_dark_config.cold_thresh =
151  naco_parameterlist_get_double(parlist, RECIPE_STRING, NACO_PARAM_COLD_LIM);
152  naco_img_dark_config.hsize =
153  naco_parameterlist_get_int(parlist, RECIPE_STRING, NACO_PARAM_HALFSIZE);
154  naco_img_dark_config.nsamples =
155  naco_parameterlist_get_int(parlist, RECIPE_STRING, NACO_PARAM_NSAMPLES);
156 
157  skip_if (0);
158 
159  /* Identify the RAW and CALIB frames in the input frameset */
160  skip_if (naco_dfs_set_groups(framelist));
161 
162  allframes = irplib_framelist_cast(framelist);
163  skip_if(allframes == NULL);
164 
165  rawframes = irplib_framelist_extract(allframes, NACO_IMG_DARK_RAW);
166  skip_if(rawframes == NULL);
167  irplib_framelist_empty(allframes);
168 
169  skip_if(irplib_framelist_load_propertylist_all(rawframes, 0, "^("
170  IRPLIB_PFITS_REGEXP_RECAL "|"
171  NACO_PFITS_REGEXP_DARK "|"
172  NACO_PFITS_REGEXP_DARK_PAF
173  ")$", CPL_FALSE));
174 
175  taglist = naco_framelist_set_tag(rawframes, naco_img_dark_make_tag, &nsets);
176  skip_if(taglist == NULL);
177 
178  cpl_msg_info(cpl_func, "Identified %d setting(s) in %d frames",
179  nsets, irplib_framelist_get_size(rawframes));
180 
181  /* Extract settings and reduce each of them */
182  for (i=0 ; i < nsets ; i++) {
183 
184  /* Reduce data set nb i */
185  f_one = irplib_framelist_extract(rawframes, taglist[i]);
186 
187  /* Reset the tag */
188  skip_if(irplib_framelist_set_tag_all(f_one, NACO_IMG_DARK_RAW));
189 
190  cpl_msg_info(cpl_func, "Reducing frame set %d of %d (size=%d) with "
191  "setting: %s", i+1, nsets,
192  irplib_framelist_get_size(f_one), taglist[i]);
193 
194  skip_if (f_one == NULL);
195 
196  /* At least 2 frames required */
197  if (irplib_framelist_get_size(f_one) < 2) {
198  cpl_msg_warning(cpl_func, "Setting %d skipped (Need at least 2 "
199  "frames)", i+1);
201  f_one = NULL;
202  continue;
203  }
204 
205  skip_if(naco_img_dark_reduce(qclist, f_one, &avg, &hot, &cold, &dev));
206 
207  skip_if(naco_img_dark_qc(qclist, paflist, f_one));
208 
209  /* Save the products */
210  skip_if (naco_img_dark_save(framelist, parlist, qclist, paflist,
211  avg, hot, cold, dev, i+1, f_one));
212 
213  nb_good++;
214 
215  cpl_image_delete(avg);
216  cpl_mask_delete(hot);
217  cpl_mask_delete(cold);
218  cpl_mask_delete(dev);
220  cpl_propertylist_empty(qclist);
221  cpl_propertylist_empty(paflist);
222  avg = NULL;
223  cold = NULL;
224  hot = NULL;
225  dev = NULL;
226  f_one = NULL;
227  }
228 
229  skip_if (nb_good == 0);
230 
231  end_skip;
232 
233  cpl_imagelist_delete(i_one);
234  cpl_free(taglist);
235  cpl_image_delete(avg);
236  cpl_mask_delete(hot);
237  cpl_mask_delete(cold);
238  cpl_mask_delete(dev);
240  irplib_framelist_delete(allframes);
241  irplib_framelist_delete(rawframes);
242  cpl_propertylist_delete(qclist);
243  cpl_propertylist_delete(paflist);
244 
245  return cpl_error_get_code();
246 }
247 
248 /*----------------------------------------------------------------------------*/
261 /*----------------------------------------------------------------------------*/
262 static cpl_error_code naco_img_dark_reduce(cpl_propertylist * qclist,
263  const irplib_framelist * f_one,
264  cpl_image ** pavg, cpl_mask ** phot,
265  cpl_mask ** pcold, cpl_mask ** pdev)
266 {
267 
268  cpl_image * dark = NULL;
269  cpl_image * diff = NULL;
270  char * ron_key = NULL;
271  double rms;
272  double lower, upper;
273  double dark_med;
274  double mean;
275  int ndevpix;
276  cpl_size zone[4];
277  int coldpix_nb;
278  int hotpix_nb;
279  int nfiles;
280  int i;
281 
282  skip_if (f_one == NULL);
283 
284  nfiles = irplib_framelist_get_size(f_one);
285 
286  skip_if (nfiles < 2);
287 
288  skip_if (irplib_framelist_contains(f_one, "NAXIS1",
289  CPL_TYPE_INT, CPL_TRUE, 0.0));
290 
291  skip_if (irplib_framelist_contains(f_one, "NAXIS2",
292  CPL_TYPE_INT, CPL_TRUE, 0.0));
293 
294  for (i=0 ; i < nfiles ; i++) {
295  const cpl_frame * frame = irplib_framelist_get_const(f_one, i);
296  const char * name = cpl_frame_get_filename(frame);
297 
298  cpl_image_delete(diff);
299  diff = dark;
300  irplib_check(dark = cpl_image_load(name, CPL_TYPE_FLOAT, 0, 0),
301  "Could not load FITS-image from %s", name);
302 
303  if (i == 0) {
304  const int nx = cpl_image_get_size_x(dark);
305  const int ny = cpl_image_get_size_y(dark);
306 
307  zone[0] = naco_img_dark_config.rej_left+1;
308  zone[1] = nx - naco_img_dark_config.rej_right;
309  zone[2] = naco_img_dark_config.rej_bottom+1;
310  zone[3] = ny - naco_img_dark_config.rej_top;
311 
312  *pavg = cpl_image_duplicate(dark);
313  skip_if(*pavg == NULL);
314  } else {
315  const cpl_propertylist * plist
317  const int ndit = naco_pfits_get_ndit(plist);
318  const char ron_format[] = "ESO QC RON%d";
319  double ron;
320 
321  skip_if(0);
322 
323  irplib_ensure(ndit > 0, CPL_ERROR_ILLEGAL_INPUT,
324  NACO_PFITS_INT_NDIT " must be positive, not %d",
325  ndit);
326 
327  skip_if(cpl_image_subtract(diff, dark));
328 
329  /* Compute the read-out noise */
330  irplib_check(cpl_flux_get_noise_window(diff, zone,
331  naco_img_dark_config.hsize,
332  naco_img_dark_config.nsamples,
333  &rms, NULL),
334  "Cannot compute the RON for difference between images "
335  "%d and %d", i, i+1);
336 
337  /* Normalise the RON with NDIT */
338  ron = rms * sqrt(ndit/2.0);
339 
340  /* Add QC parameters */
341  cpl_free(ron_key);
342  ron_key = cpl_sprintf(ron_format, i);
343 
344  bug_if(ron_key == NULL);
345 
346  skip_if(cpl_propertylist_append_double(qclist, ron_key, ron));
347 
348  /* Sum up the darks */
349  skip_if(cpl_image_add(*pavg, dark));
350 
351  }
352 
353  }
354  cpl_image_delete(dark);
355  dark = NULL;
356 
357  mean = cpl_image_get_mean(diff);
358 
359  /* Use the rms of the difference of the last two images to
360  create the deviant pixel map */
361  lower = mean - rms * naco_img_dark_config.dev_thresh;
362  upper = mean + rms * naco_img_dark_config.dev_thresh;
363  cpl_mask_delete(*pdev);
364  irplib_check(*pdev = cpl_mask_threshold_image_create(diff, lower, upper),
365  "Cannot compute the deviant pixel map");
366  cpl_image_delete(diff);
367  diff = NULL;
368 
369  skip_if (cpl_mask_not(*pdev));
370  ndevpix = cpl_mask_count(*pdev);
371  skip_if (0);
372 
373  /* Average it to the master dark */
374  skip_if(cpl_image_divide_scalar(*pavg, (double)nfiles));
375 
376  /* Compute median-rms of the central part of the dark */
377  dark_med = cpl_image_get_median_window(*pavg, zone[0], zone[2], zone[1],
378  zone[3]);
379 
380  irplib_check (cpl_flux_get_noise_window(*pavg, zone,
381  naco_img_dark_config.hsize,
382  naco_img_dark_config.nsamples,
383  &rms, NULL),
384  "Cannot compute the RON of the master dark");
385 
386  lower = dark_med - rms * naco_img_dark_config.cold_thresh;
387  upper = dark_med + rms * naco_img_dark_config.hot_thresh;
388 
389  /* Create the cold pixel map */
390  cpl_mask_delete(*pcold);
391  irplib_check(*pcold = cpl_mask_threshold_image_create(*pavg, -FLT_MAX,
392  lower),
393  "Cannot compute the cold pixel map");
394  coldpix_nb = cpl_mask_count(*pcold);
395  skip_if (0);
396 
397  /* Create the hot pixel map */
398  cpl_mask_delete(*phot);
399  irplib_check(*phot = cpl_mask_threshold_image_create(*pavg, upper, DBL_MAX),
400  "Cannot compute the hot pixel map");
401  hotpix_nb = cpl_mask_count(*phot);
402  skip_if (0);
403 
404  /* Add QC parameters */
405 
406  skip_if(cpl_propertylist_append_double(qclist, "ESO QC DARKMED", dark_med));
407  skip_if(cpl_propertylist_append_int(qclist, "ESO QC NBCOLPIX", coldpix_nb));
408  skip_if(cpl_propertylist_append_int(qclist, "ESO QC NBHOTPIX", hotpix_nb));
409  skip_if(cpl_propertylist_append_int(qclist, "ESO QC NBDEVPIX", ndevpix));
410 
411  end_skip;
412 
413  cpl_image_delete(dark);
414  cpl_image_delete(diff);
415  cpl_free(ron_key);
416 
417  return cpl_error_get_code();
418 }
419 
420 
421 /*----------------------------------------------------------------------------*/
429 /*----------------------------------------------------------------------------*/
430 static cpl_error_code naco_img_dark_qc(cpl_propertylist * qclist,
431  cpl_propertylist * paflist,
432  const irplib_framelist * rawframes)
433 {
434 
435  const cpl_propertylist * reflist
437  const char pafcopy[] = "^(" NACO_PFITS_REGEXP_DARK_PAF ")$";
438 
439 
440  bug_if (0);
441 
442  bug_if (cpl_propertylist_copy_property_regexp(paflist, reflist, pafcopy,
443  0));
444  bug_if (cpl_propertylist_append(paflist, qclist));
445 
446  bug_if (cpl_propertylist_copy_property_regexp(qclist, reflist, "^("
447  IRPLIB_PFITS_REGEXP_RECAL
448  ")$", 0));
449 
450  bug_if (irplib_pfits_set_airmass(qclist, rawframes));
451 
452  end_skip;
453 
454  return cpl_error_get_code();
455 }
456 
457 /*----------------------------------------------------------------------------*/
472 /*----------------------------------------------------------------------------*/
473 static cpl_error_code naco_img_dark_save(cpl_frameset * set_tot,
474  const cpl_parameterlist * parlist,
475  const cpl_propertylist * qclist,
476  const cpl_propertylist * paflist,
477  const cpl_image * avg,
478  const cpl_mask * hot,
479  const cpl_mask * cold,
480  const cpl_mask * dev,
481  int set_nb,
482  const irplib_framelist * f_one)
483 {
484  cpl_frameset * set_one = irplib_frameset_cast(f_one);
485  cpl_image * image = NULL;
486  char * filename = NULL;
487 
488 
489  bug_if (0);
490 
491  /* Write the average image */
492  filename = cpl_sprintf(RECIPE_STRING "_set%02d_avg" CPL_DFS_FITS,
493  set_nb);
494  skip_if (irplib_dfs_save_image(set_tot, parlist, set_one, avg,
495  CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
496  NACO_IMG_DARK_AVG, qclist, NULL, naco_pipe_id,
497  filename));
498 
499  /* Write the hotpixel map */
500  image = cpl_image_new_from_mask(hot);
501  bug_if(0);
502 
503  cpl_free(filename);
504  filename = cpl_sprintf(RECIPE_STRING "_set%02d_hotpix" CPL_DFS_FITS,
505  set_nb);
506  skip_if (irplib_dfs_save_image(set_tot, parlist, set_one, image,
507  CPL_BPP_8_UNSIGNED, RECIPE_STRING, NACO_IMG_DARK_HOT,
508  qclist, NULL, naco_pipe_id, filename));
509 
510  /* Write the coldpixel map */
511  cpl_image_delete(image);
512  image = cpl_image_new_from_mask(cold);
513  bug_if(0);
514 
515  cpl_free(filename);
516  filename = cpl_sprintf(RECIPE_STRING "_set%02d_coldpix" CPL_DFS_FITS,
517  set_nb);
518  skip_if (irplib_dfs_save_image(set_tot, parlist, set_one, image,
519  CPL_BPP_8_UNSIGNED, RECIPE_STRING,
520  NACO_IMG_DARK_COLD, qclist, NULL, naco_pipe_id,
521  filename));
522 
523  /* Write the deviant pixel map */
524  cpl_image_delete(image);
525  image = cpl_image_new_from_mask(dev);
526  bug_if(0);
527 
528  cpl_free(filename);
529  filename = cpl_sprintf(RECIPE_STRING "_set%02d_devpix" CPL_DFS_FITS,
530  set_nb);
531  skip_if (irplib_dfs_save_image(set_tot, parlist, set_one, image,
532  CPL_BPP_8_UNSIGNED, RECIPE_STRING, NACO_IMG_DARK_DEV,
533  qclist, NULL, naco_pipe_id, filename));
534  cpl_image_delete(image);
535  image = NULL;
536 
537 #ifdef NACO_SAVE_PAF
538  /* THE PAF FILE FOR QC PARAMETERS */
539 
540  /* PRO.CATG */
541  bug_if(cpl_propertylist_append_string(paflist, CPL_DFS_PRO_CATG,
542  NACO_IMG_DARK_AVG));
543 
544  cpl_free(filename);
545  filename = cpl_sprintf(RECIPE_STRING "_set%02d" CPL_DFS_PAF, set_nb);
546  skip_if (cpl_dfs_save_paf("NACO", RECIPE_STRING, paflist, filename));
547 #else
548  bug_if(paflist == NULL);
549 #endif
550 
551  end_skip;
552 
553  cpl_image_delete(image);
554  cpl_frameset_delete(set_one);
555  cpl_free(filename);
556 
557  return cpl_error_get_code();
558 }
559 
560 
561 /*----------------------------------------------------------------------------*/
571 /*----------------------------------------------------------------------------*/
572 static char * naco_img_dark_make_tag(const cpl_frame* self,
573  const cpl_propertylist * plist, int dummy)
574 {
575 
576  char * tag = NULL;
577  const char * mode;
578  const char * name;
579  double etime;
580  int irom;
581 
582 
583  skip_if (cpl_error_get_code());
584 
585  skip_if(self == NULL);
586  skip_if(plist == NULL);
587  skip_if(dummy < 0); /* Avoid warning of unused variable */
588 
589  /* exposure time */
590  etime = naco_pfits_get_exptime(plist);
591  skip_if(cpl_error_get_code());
592 
593  /* readout mode */
594  irom = naco_pfits_get_rom(plist);
595  skip_if(cpl_error_get_code());
596 
597 
598  /* detector mode */
599  mode = naco_pfits_get_mode(plist);
600  skip_if(cpl_error_get_code());
601 
602  /* Compare the camera */
603  name = naco_pfits_get_opti7_name(plist);
604  skip_if(cpl_error_get_code());
605 
606  tag = cpl_sprintf("%s:%s:%d:%.5f", name, mode, irom,
607  etime);
608  bug_if(tag == NULL);
609 
610  end_skip;
611 
612  if (cpl_error_get_code()) {
613  cpl_free(tag);
614  tag = NULL;
615  }
616 
617  return tag;
618 
619 }
cpl_frameset * irplib_frameset_cast(const irplib_framelist *self)
Create a CPL frameset from an irplib_framelist.
cpl_error_code irplib_framelist_set_tag_all(irplib_framelist *self, const char *tag)
Set the tag of all frames in the list.
int naco_pfits_get_rom(const cpl_propertylist *self)
find out the read out mode
Definition: naco_pfits.c:377
int naco_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: naco_dfs.c:62
cpl_error_code irplib_pfits_set_airmass(cpl_propertylist *self, const irplib_framelist *rawframes)
Update/Set the AIRMASS property.
Definition: irplib_pfits.c:373
int naco_pfits_get_ndit(const cpl_propertylist *self)
find out the NDIT keyword
Definition: naco_pfits.c:292
int naco_parameterlist_get_int(const cpl_parameterlist *self, const char *recipe, naco_parameter bitmask)
Retrieve the value of a NACO integer parameter.
const char * naco_pfits_get_opti7_name(const cpl_propertylist *self)
find out the OPTI7.NAME key
Definition: naco_pfits.c:329
const cpl_propertylist * irplib_framelist_get_propertylist_const(const irplib_framelist *self, int pos)
Get the propertylist of the specified frame in the framelist.
void irplib_framelist_empty(irplib_framelist *self)
Erase all frames from a framelist.
cpl_error_code irplib_dfs_save_image(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_image *image, cpl_type_bpp bpp, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save an image as a DFS-compliant pipeline product.
Definition: irplib_utils.c:208
cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist *self, int ind, const char *regexp, cpl_boolean invert)
Load the propertylists of all frames in the framelist.
double naco_parameterlist_get_double(const cpl_parameterlist *self, const char *recipe, naco_parameter bitmask)
Retrieve the value of a NACO parameter of type double.
irplib_framelist * irplib_framelist_extract(const irplib_framelist *self, const char *tag)
Extract the frames with the given tag from a framelist.
const cpl_frame * irplib_framelist_get_const(const irplib_framelist *self, int pos)
Get the specified frame from the framelist.
const char ** naco_framelist_set_tag(irplib_framelist *self, char *(*pftag)(const cpl_frame *, const cpl_propertylist *, int), int *pntags)
Retag a framelist according to the given tagging function.
Definition: naco_utils.c:176
void irplib_framelist_delete(irplib_framelist *self)
Deallocate an irplib_framelist with its frames and properties.
cpl_error_code irplib_framelist_contains(const irplib_framelist *self, const char *key, cpl_type type, cpl_boolean is_equal, double fp_tol)
Verify that a property is present for all frames.
const char * naco_pfits_get_mode(const cpl_propertylist *self)
find out the mode name
Definition: naco_pfits.c:268
irplib_framelist * irplib_framelist_cast(const cpl_frameset *frameset)
Create an irplib_framelist from a cpl_framelist.
const char * naco_parameterlist_get_string(const cpl_parameterlist *self, const char *recipe, naco_parameter bitmask)
Retrieve the value of a NACO string parameter.
int irplib_framelist_get_size(const irplib_framelist *self)
Get the size of a framelist.
double naco_pfits_get_exptime(const cpl_propertylist *self)
find out the exposure time
Definition: naco_pfits.c:155