IIINSTRUMENT Pipeline Reference Manual  1.5.13
sofi_img_dark.c
1 /* $Id: sofi_img_dark.c,v 1.27 2013-03-12 08:04:53 llundin Exp $
2  *
3  * This file is part of the SOFI 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:04:53 $
24  * $Revision: 1.27 $
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 <cpl.h>
37 #include <math.h>
38 
39 #include "irplib_utils.h"
40 
41 #include "sofi_utils.h"
42 #include "sofi_pfits.h"
43 #include "sofi_dfs.h"
44 
45 /*-----------------------------------------------------------------------------
46  Functions prototypes
47  -----------------------------------------------------------------------------*/
48 
49 static int sofi_img_dark_create(cpl_plugin *);
50 static int sofi_img_dark_exec(cpl_plugin *);
51 static int sofi_img_dark_destroy(cpl_plugin *);
52 static int sofi_img_dark(cpl_parameterlist *, cpl_frameset *);
53 
54 static int sofi_img_dark_avg_reduce(cpl_frameset *, cpl_image **);
55 static cpl_matrix * sofi_img_dark_ron_reduce(cpl_frameset *);
56 static int sofi_img_dark_compare(const cpl_frame *, const cpl_frame *);
57 static int sofi_img_dark_save(cpl_image *, cpl_matrix *, int, cpl_frameset *,
58  cpl_parameterlist *, cpl_frameset *);
59 
60 /*-----------------------------------------------------------------------------
61  Static variables
62  -----------------------------------------------------------------------------*/
63 
64 static struct {
65  /* Inputs */
66  int hsize;
67  int nsamples;
68  /* Outputs */
69  double dark_med;
70  double dark_stdev;
71 } sofi_img_dark_config;
72 
73 static char sofi_img_dark_description[] =
74 "sofi_img_dark -- SOFI imaging dark recipe.\n"
75 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
76 "raw-file.fits "SOFI_IMG_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  SOFI_BINARY_VERSION,
99  CPL_PLUGIN_TYPE_RECIPE,
100  "sofi_img_dark",
101  "Dark recipe",
102  sofi_img_dark_description,
103  "Yves Jung",
104  "yjung@eso.org",
106  sofi_img_dark_create,
107  sofi_img_dark_exec,
108  sofi_img_dark_destroy);
109 
110  cpl_pluginlist_append(list, plugin);
111 
112  return 0;
113 }
114 
115 /*----------------------------------------------------------------------------*/
124 /*----------------------------------------------------------------------------*/
125 static int sofi_img_dark_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  /* --nsamples */
140  p = cpl_parameter_new_value("sofi.sofi_img_dark.nsamples",
141  CPL_TYPE_INT, "number of samples for RON computation",
142  "sofi.sofi_img_dark", 100);
143  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nsamples");
144  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
145  cpl_parameterlist_append(recipe->parameters, p);
146  /* --hsize */
147  p = cpl_parameter_new_value("sofi.sofi_img_dark.hsize",
148  CPL_TYPE_INT, "half size of the window for RON computation",
149  "sofi.sofi_img_dark", 6);
150  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "hsize");
151  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
152  cpl_parameterlist_append(recipe->parameters, p);
153 
154  /* Return */
155  return 0;
156 }
157 
158 /*----------------------------------------------------------------------------*/
164 /*----------------------------------------------------------------------------*/
165 static int sofi_img_dark_exec(cpl_plugin * plugin)
166 {
167  cpl_recipe * recipe;
168 
169  /* Get the recipe out of the plugin */
170  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
171  recipe = (cpl_recipe *)plugin;
172  else return CPL_ERROR_UNSPECIFIED;
173 
174  return sofi_img_dark(recipe->parameters, recipe->frames);
175 }
176 
177 /*----------------------------------------------------------------------------*/
183 /*----------------------------------------------------------------------------*/
184 static int sofi_img_dark_destroy(cpl_plugin * plugin)
185 {
186  cpl_recipe * recipe;
187 
188  /* Get the recipe out of the plugin */
189  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
190  recipe = (cpl_recipe *)plugin;
191  else return CPL_ERROR_UNSPECIFIED;
192 
193  cpl_parameterlist_delete(recipe->parameters);
194  return 0;
195 }
196 
197 /*----------------------------------------------------------------------------*/
204 /*----------------------------------------------------------------------------*/
205 static int sofi_img_dark(
206  cpl_parameterlist * parlist,
207  cpl_frameset * framelist)
208 {
209  cpl_parameter * par;
210  cpl_size nsets;
211  cpl_size * selection;
212  cpl_frameset * f_one;
213  cpl_image * avg;
214  cpl_matrix * rons;
215  int i;
216 
217  /* Retrieve input parameters */
218  par = cpl_parameterlist_find(parlist, "sofi.sofi_img_dark.hsize");
219  sofi_img_dark_config.hsize = cpl_parameter_get_int(par);
220  par = cpl_parameterlist_find(parlist, "sofi.sofi_img_dark.nsamples");
221  sofi_img_dark_config.nsamples = cpl_parameter_get_int(par);
222 
223  /* Identify the RAW and CALIB frames in the input frameset */
224  if (sofi_dfs_set_groups(framelist)) {
225  cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
226  return CPL_ERROR_UNSPECIFIED;
227  }
228 
229  /* Labelize all input frames */
230  cpl_msg_info(cpl_func, "Identify the different settings");
231  selection=cpl_frameset_labelise(framelist, sofi_img_dark_compare, &nsets);
232  if (selection == NULL) {
233  cpl_msg_error(cpl_func, "Cannot labelise input frames");
234  return CPL_ERROR_UNSPECIFIED;
235  }
236 
237  /* Extract settings and reduce each of them */
238  for (i=0; i<nsets; i++) {
239  /* Initialise */
240  sofi_img_dark_config.dark_med = -1.0;
241  sofi_img_dark_config.dark_stdev = -1.0;
242  avg = NULL;
243 
244  /* Reduce data set nb i */
245  cpl_msg_info(cpl_func, "Reduce data set no %d out of %d", i+1,
246  (int)nsets);
247  cpl_msg_indent_more();
248  f_one = cpl_frameset_extract(framelist, selection, i);
249 
250  /* At least 2 frames required */
251  if (cpl_frameset_get_size(f_one) < 2) {
252  cpl_msg_warning(cpl_func, "Setting %d skipped (not enough frames)",
253  i+1);
254  cpl_frameset_delete(f_one);
255  return CPL_ERROR_UNSPECIFIED;
256  } else {
257  /* AVG part */
258  cpl_msg_info(cpl_func, "Compute the master dark");
259  cpl_msg_indent_more();
260  if (sofi_img_dark_avg_reduce(f_one, &avg)) {
261  cpl_msg_warning(cpl_func, "Cannot reduce set number %d", i+1);
262  }
263  cpl_msg_indent_less();
264  /* RON part */
265  cpl_msg_info(cpl_func, "Compute the read-out noise");
266  cpl_msg_indent_more();
267  if ((rons = sofi_img_dark_ron_reduce(f_one)) == NULL) {
268  cpl_msg_warning(cpl_func, "Cannot reduce set number %d", i+1);
269  }
270  cpl_msg_indent_less();
271  /* Save the products */
272  if (sofi_img_dark_save(avg, rons, i+1, f_one, parlist,
273  framelist) !=0 ){
274  cpl_msg_error(cpl_func, "Cannot save the products");
275  if (avg) cpl_image_delete(avg);
276  if (rons) cpl_matrix_delete(rons);
277  cpl_frameset_delete(f_one);
278  return CPL_ERROR_UNSPECIFIED;
279  }
280  if (rons) cpl_matrix_delete(rons);
281  }
282  if (avg) cpl_image_delete(avg);
283  cpl_frameset_delete(f_one);
284  cpl_msg_indent_less();
285  }
286 
287  /* Free and return */
288  cpl_free(selection);
289  return 0;
290 }
291 
292 /*----------------------------------------------------------------------------*/
299 /*----------------------------------------------------------------------------*/
300 static int sofi_img_dark_avg_reduce(
301  cpl_frameset * framelist,
302  cpl_image ** avg)
303 {
304  cpl_imagelist * iset;
305  cpl_vector * medians;
306  cpl_image * image;
307  int i;
308 
309  /* Test entries */
310  if (framelist == NULL) return CPL_ERROR_UNSPECIFIED;
311 
312  /* Load the image set */
313  if ((iset = cpl_imagelist_load_frameset(framelist, CPL_TYPE_FLOAT, 1,
314  0)) == NULL) {
315  cpl_msg_error(cpl_func, "Cannot load the data");
316  return CPL_ERROR_UNSPECIFIED;
317  }
318 
319  /* Average it to the master dark */
320  if ((*avg = cpl_imagelist_collapse_create(iset)) == NULL) {
321  cpl_msg_error(cpl_func, "Cannot average the data set");
322  cpl_imagelist_delete(iset);
323  return CPL_ERROR_UNSPECIFIED;
324  }
325 
326  /* Compute mean-rms of the median values */
327  medians = cpl_vector_new(cpl_imagelist_get_size(iset));
328  for (i=0; i<cpl_imagelist_get_size(iset); i++) {
329  image = cpl_imagelist_get(iset, i);
330  cpl_vector_set(medians, i, cpl_image_get_median(image));
331  }
332  cpl_imagelist_delete(iset);
333  sofi_img_dark_config.dark_med = cpl_vector_get_mean(medians);
334  sofi_img_dark_config.dark_stdev = cpl_vector_get_stdev(medians);
335 
336  /* Free and Return */
337  cpl_vector_delete(medians);
338  return 0;
339 }
340 
341 /*----------------------------------------------------------------------------*/
352 /*----------------------------------------------------------------------------*/
353 static cpl_matrix * sofi_img_dark_ron_reduce(cpl_frameset * framelist)
354 {
355  cpl_frame * cur_frame;
356  cpl_propertylist * plist;
357  cpl_imagelist * iset;
358  cpl_matrix * rons;
359  cpl_image * tmp_im;
360  double rms;
361  double norm;
362  int ndit;
363  cpl_size zone_def[4];
364  int i;
365 
366  /* Test entries */
367  if (framelist == NULL) return NULL;
368 
369  /* Load the current set */
370  if ((iset = cpl_imagelist_load_frameset(framelist, CPL_TYPE_FLOAT, 1,
371  0)) == NULL) {
372  cpl_msg_error(cpl_func, "Cannot load the data");
373  return NULL;
374  }
375 
376  /* Create the matrix */
377  rons = cpl_matrix_new(cpl_imagelist_get_size(iset)-1, 4);
378 
379  /* Loop on all pairs */
380  for (i=0; i<cpl_imagelist_get_size(iset)-1; i++) {
381  cpl_msg_info(cpl_func, "Pair number %d", i+1);
382  /* Get the norm factor */
383  if (cpl_error_get_code()) {
384  cpl_matrix_delete(rons);
385  cpl_imagelist_delete(iset);
386  return NULL;
387  }
388  cur_frame = cpl_frameset_get_position(framelist, i);
389  plist = cpl_propertylist_load(cpl_frame_get_filename(cur_frame),
390  0);
391  ndit = sofi_pfits_get_ndit(plist);
392  cpl_propertylist_delete(plist);
393  if (cpl_error_get_code()) {
394  cpl_msg_error(cpl_func, "Cannot get the NDIT");
395  cpl_matrix_delete(rons);
396  cpl_imagelist_delete(iset);
397  return NULL;
398  }
399  norm = 0.5 * ndit;
400  norm = sqrt(norm);
401 
402  /* Compute the current subtracted image */
403  if ((tmp_im = cpl_image_subtract_create(
404  cpl_imagelist_get(iset, i),
405  cpl_imagelist_get(iset, i+1))) == NULL) {
406  cpl_msg_error(cpl_func, "Cannot subtract the images");
407  cpl_imagelist_delete(iset);
408  cpl_matrix_delete(rons);
409  return NULL;
410  }
411 
412  /* Get measurement for lower-left quadrant */
413  zone_def[0] = 1;
414  zone_def[1] = cpl_image_get_size_x(tmp_im)/2;
415  zone_def[2] = 1;
416  zone_def[3] = cpl_image_get_size_y(tmp_im)/2;
417  cpl_flux_get_noise_window(tmp_im, zone_def,
418  sofi_img_dark_config.hsize,
419  sofi_img_dark_config.nsamples, &rms, NULL);
420  cpl_matrix_set(rons, i, 0, rms * norm);
421  cpl_msg_info(cpl_func, "RON in LL quadrant: %g", rms * norm);
422 
423  /* Get measurement for lower-right quadrant */
424  zone_def[0] = cpl_image_get_size_x(tmp_im)/2 + 1;
425  zone_def[1] = cpl_image_get_size_x(tmp_im);
426  zone_def[2] = 1;
427  zone_def[3] = cpl_image_get_size_y(tmp_im)/2;
428  cpl_flux_get_noise_window(tmp_im, zone_def,
429  sofi_img_dark_config.hsize,
430  sofi_img_dark_config.nsamples, &rms, NULL);
431  cpl_matrix_set(rons, i, 1, rms * norm);
432  cpl_msg_info(cpl_func, "RON in LR quadrant: %g", rms * norm);
433 
434  /* Get measurement for upper-left quadrant */
435  zone_def[0] = 1;
436  zone_def[1] = cpl_image_get_size_x(tmp_im)/2;
437  zone_def[2] = cpl_image_get_size_y(tmp_im)/2 + 1;
438  zone_def[3] = cpl_image_get_size_y(tmp_im);
439  cpl_flux_get_noise_window(tmp_im, zone_def,
440  sofi_img_dark_config.hsize,
441  sofi_img_dark_config.nsamples, &rms, NULL);
442  cpl_matrix_set(rons, i, 2, rms * norm);
443  cpl_msg_info(cpl_func, "RON in UL quadrant: %g", rms * norm);
444 
445  /* Get measurement for upper-right quadrant */
446  zone_def[0] = cpl_image_get_size_x(tmp_im)/2 + 1;
447  zone_def[1] = cpl_image_get_size_x(tmp_im);
448  zone_def[2] = cpl_image_get_size_y(tmp_im)/2 + 1;
449  zone_def[3] = cpl_image_get_size_y(tmp_im);
450  cpl_flux_get_noise_window(tmp_im, zone_def,
451  sofi_img_dark_config.hsize,
452  sofi_img_dark_config.nsamples, &rms, NULL);
453  cpl_matrix_set(rons, i, 3, rms * norm);
454  cpl_msg_info(cpl_func, "RON in UR quadrant: %g", rms * norm);
455  cpl_image_delete(tmp_im);
456  }
457 
458  /* Free and return */
459  cpl_imagelist_delete(iset);
460  return rons;
461 }
462 
463 /*----------------------------------------------------------------------------*/
474 /*----------------------------------------------------------------------------*/
475 static int sofi_img_dark_save(
476  cpl_image * avg,
477  cpl_matrix * rons,
478  int set_nb,
479  cpl_frameset * set,
480  cpl_parameterlist * parlist,
481  cpl_frameset * set_tot)
482 {
483  cpl_propertylist * plist;
484  cpl_propertylist * qclist;
485  cpl_propertylist * paflist;
486  const cpl_frame * ref_frame;
487  char qc_str[128];
488  char * filename;
489  int i;
490 
491  /* Get the QC params in qclist */
492  qclist = cpl_propertylist_new();
493  cpl_propertylist_append_double(qclist, "ESO QC DARKMED",
494  sofi_img_dark_config.dark_med);
495  cpl_propertylist_append_double(qclist, "ESO QC DARKSTDEV",
496  sofi_img_dark_config.dark_stdev);
497  if (rons != NULL) {
498  for (i=0; i<cpl_matrix_get_nrow(rons); i++) {
499  sprintf(qc_str, "ESO QC LL RON%d", i+1);
500  cpl_propertylist_append_double(qclist, qc_str,
501  cpl_matrix_get(rons, i, 0));
502  sprintf(qc_str, "ESO QC LR RON%d", i+1);
503  cpl_propertylist_append_double(qclist, qc_str,
504  cpl_matrix_get(rons, i, 1));
505  sprintf(qc_str, "ESO QC UL RON%d", i+1);
506  cpl_propertylist_append_double(qclist, qc_str,
507  cpl_matrix_get(rons, i, 2));
508  sprintf(qc_str, "ESO QC UR RON%d", i+1);
509  cpl_propertylist_append_double(qclist, qc_str,
510  cpl_matrix_get(rons, i, 3));
511  }
512  }
513 
514  /* Write the average image */
515  filename = cpl_sprintf("sofi_img_dark_set%02d_avg.fits", set_nb);
516  irplib_dfs_save_image(set_tot,
517  parlist,
518  set,
519  avg,
520  CPL_BPP_IEEE_FLOAT,
521  "sofi_img_dark",
522  SOFI_IMG_DARK_AVG,
523  qclist,
524  NULL,
525  PACKAGE "/" PACKAGE_VERSION,
526  filename);
527  cpl_free(filename);
528 
529  /* Get the reference frame */
530  ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
531 
532  /* Get FITS header from reference file */
533  if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
534  0)) == NULL) {
535  cpl_msg_error(cpl_func, "getting header from reference frame");
536  cpl_propertylist_delete(qclist);
537  return CPL_ERROR_UNSPECIFIED;
538  }
539 
540  /* Get the keywords for the paf file */
541  paflist = cpl_propertylist_new();
542  cpl_propertylist_copy_property_regexp(paflist, plist,
543  "^(ARCFILE|MJD-OBS|ESO TPL ID|ESO DPR TECH|DATE-OBS|ESO DET DIT|"
544  "ESO DET NDIT|ESO DET NCORRS|ESO DET NDSAMPLES|ESO DET MODE NAME)$", 0);
545  cpl_propertylist_delete(plist);
546 
547  /* Copy the QC in paflist */
548  cpl_propertylist_copy_property_regexp(paflist, qclist, ".", 0);
549  cpl_propertylist_delete(qclist);
550 
551  /* Save the PAF file */
552  filename = cpl_sprintf("sofi_img_dark_set%02d.paf", set_nb);
553  cpl_dfs_save_paf("SOFI",
554  "sofi_img_dark",
555  paflist,
556  filename);
557  cpl_free(filename);
558  cpl_propertylist_delete(paflist);
559  return 0;
560 }
561 
562 /*----------------------------------------------------------------------------*/
569 /*----------------------------------------------------------------------------*/
570 static int sofi_img_dark_compare(
571  const cpl_frame * frame1,
572  const cpl_frame * frame2)
573 {
574  int comparison;
575  cpl_propertylist * plist1;
576  cpl_propertylist * plist2;
577  double dval1, dval2;
578  int ival1, ival2;
579 
580  /* Test entries */
581  if (frame1==NULL || frame2==NULL) return CPL_ERROR_UNSPECIFIED;
582 
583  /* Get property lists */
584  if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),
585  0)) == NULL) {
586  cpl_msg_error(cpl_func, "getting header from reference frame");
587  return CPL_ERROR_UNSPECIFIED;
588  }
589  if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),
590  0)) == NULL) {
591  cpl_msg_error(cpl_func, "getting header from reference frame");
592  cpl_propertylist_delete(plist1);
593  return CPL_ERROR_UNSPECIFIED;
594  }
595 
596  /* Test status */
597  if (cpl_error_get_code()) {
598  cpl_propertylist_delete(plist1);
599  cpl_propertylist_delete(plist2);
600  return CPL_ERROR_UNSPECIFIED;
601  }
602 
603  /* Compare exposure time */
604  comparison = 1;
605  dval1 = sofi_pfits_get_dit(plist1);
606  dval2 = sofi_pfits_get_dit(plist2);
607  if (cpl_error_get_code()) {
608  cpl_msg_error(cpl_func, "cannot get exposure time");
609  cpl_propertylist_delete(plist1);
610  cpl_propertylist_delete(plist2);
611  return CPL_ERROR_UNSPECIFIED;
612  }
613  if (fabs(dval1-dval2) > 1e-5) comparison = 0;
614 
615  /* Compare NDIT */
616  ival1 = sofi_pfits_get_ndit(plist1);
617  ival2 = sofi_pfits_get_ndit(plist2);
618  if (cpl_error_get_code()) {
619  cpl_msg_error(cpl_func, "cannot get NDIT");
620  cpl_propertylist_delete(plist1);
621  cpl_propertylist_delete(plist2);
622  return CPL_ERROR_UNSPECIFIED;
623  }
624  if (ival1 != ival2) comparison = 0;
625 
626  /* Compare the readout mode */
627  ival1 = sofi_pfits_get_rom(plist1);
628  ival2 = sofi_pfits_get_rom(plist2);
629  if (cpl_error_get_code()) {
630  cpl_msg_error(cpl_func, "cannot get read-out mode");
631  cpl_propertylist_delete(plist1);
632  cpl_propertylist_delete(plist2);
633  return CPL_ERROR_UNSPECIFIED;
634  }
635  if (ival1 != ival2) comparison = 0;
636 
637  /* Free and return */
638  cpl_propertylist_delete(plist1);
639  cpl_propertylist_delete(plist2);
640  return comparison;
641 }
642 
sofi_pfits_get_ndit
int sofi_pfits_get_ndit(const cpl_propertylist *plist)
find out the NDIT keyword
Definition: sofi_pfits.c:375
sofi_pfits_get_dit
double sofi_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
Definition: sofi_pfits.c:195
sofi_dfs_set_groups
int sofi_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: sofi_dfs.c:60
sofi_get_license
const char * sofi_get_license(void)
Get the pipeline copyright and license.
Definition: sofi_utils.c:60
sofi_pfits_get_rom
int sofi_pfits_get_rom(const cpl_propertylist *plist)
find out the read out mode
Definition: sofi_pfits.c:486