OMEGA Pipeline Reference Manual  1.0.5
omega_qcheck.c
1 /* $Id: omega_qcheck.c,v 1.2 2012-01-12 12:05:09 agabasch Exp $
2  *
3  * This file is part of the OMEGA 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: agabasch $
23  * $Date: 2012-01-12 12:05:09 $
24  * $Revision: 1.2 $
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 "omega_recipe.h"
37 
38 /*----------------------------------------------------------------------------*/
59 /*----------------------------------------------------------------------------*/
62 /*-----------------------------------------------------------------------------
63  Functions prototypes
64  -----------------------------------------------------------------------------*/
65 
66 static int omega_qcheck_create(cpl_plugin *) ;
67 static int omega_qcheck_exec(cpl_plugin *) ;
68 static int omega_qcheck_destroy(cpl_plugin *) ;
69 static int omega_qcheck_old(cpl_frameset *,cpl_parameterlist *) ;
70 static int omega_qcheck(cpl_frameset *,cpl_parameterlist *) ;
71 
72 /*-----------------------------------------------------------------------------
73  Private Functions
74  -----------------------------------------------------------------------------*/
75 static void omega_qcheck_init(void);
76 static void omega_qcheck_tidy(void);
77 
78 /* Parameters and QC structure*/
79 static struct {
80  /* Inputs. Parameters */
81  float rejt;
82  int extnum;
83  int niter;
84  int oc;
85  int paf;
86 
87  /* QC parameters */
88  double mean;
89  double median;
90  double stdev;
91 
92 }omega_qcheck_config;
93 
94 /* Input and Output */
95 static struct {
96  cpl_size *labels;
97  cpl_stats *stats;
98  cpl_frameset *domelist;
99  omega_fits *domefits1;
100  cpl_propertylist *eh;
101 
102  /*Products*/
103  char *proname;
104  cpl_table *result;
105 } ps;
106 
107 /* Static variables */
108 
109 /* Static variables */
110 #define RECIPE "omega_qcheck"
111 
112 /*----------------------------------------------------------------------------*/
120 /*----------------------------------------------------------------------------*/
121 int cpl_plugin_get_info(cpl_pluginlist * list)
122 {
123  cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe)) ;
124  cpl_plugin * plugin = &recipe->interface ;
125 
126  cpl_plugin_init(plugin,
127  CPL_PLUGIN_API,
128  OMEGA_BINARY_VERSION,
129  CPL_PLUGIN_TYPE_RECIPE,
130  "omega_qcheck",
131  "OMEGA - Generates a quick check on the detector responsivity for each chip.",
132  "The recipe takes as input exactly one raw domeflat frame, and \n"
133  "a master bias. Optionally, an overscan correction mode can be set. \n"
134  "The default is to apply no overscan correction.",
135  "Sandra Castro",
136  "scastro@eso.org",
138  omega_qcheck_create,
139  omega_qcheck_exec,
140  omega_qcheck_destroy) ;
141 
142  cpl_pluginlist_append(list, plugin) ;
143 
144  return 0;
145 }
146 
147 /*----------------------------------------------------------------------------*/
156 /*----------------------------------------------------------------------------*/
157 static int omega_qcheck_create(cpl_plugin * plugin)
158 {
159  cpl_recipe * recipe;
160  cpl_parameter * p ;
161 
162  /* Do not create the recipe if an error code is already set */
163  if (cpl_error_get_code() != CPL_ERROR_NONE) {
164  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
165  cpl_func, __LINE__, cpl_error_get_where());
166  return (int)cpl_error_get_code();
167  }
168 
169  if (plugin == NULL) {
170  cpl_msg_error(cpl_func, "Null plugin");
171  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
172  }
173 
174  /* Verify plugin type */
175  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
176  cpl_msg_error(cpl_func, "Plugin is not a recipe");
177  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
178  }
179 
180  /* Get the recipe */
181  recipe = (cpl_recipe *)plugin;
182 
183  /* Create the parameters list in the cpl_recipe object */
184  recipe->parameters = cpl_parameterlist_new() ;
185 
186  /* Fill the parameters list */
187  p = cpl_parameter_new_value("omega.omega_qcheck.ExtensionNumber",
188  CPL_TYPE_INT,
189  "FITS extension number to load (1 to 32). (-1 == all)",
190  "omega_qcheck",
191  -1) ;
192 
193  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"ext") ;
194  cpl_parameterlist_append(recipe->parameters, p) ;
195 
196 
197  p = cpl_parameter_new_range("omega.omega_qcheck.OverscanMethod",
198  CPL_TYPE_INT,
199  "Overscan Correction Method (0 to 6):\n"
200  "0 = no overscan correction;\n"
201  "1 = use median of prescan in X;\n"
202  "2 = use median of overscan in X;\n"
203  "3 = use median on prescan in Y;\n"
204  "4 = use median of overscan in Y;\n"
205  "5 = per-row subtraction of the median of row in prescan regions of X;\n"
206  "6 = per-row subtraction of the median of row in overscan regions of X\n",
207  "omega_qcheck",
208  0, 0, 6);
209 
210  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"oc-meth") ;
211  cpl_parameterlist_append(recipe->parameters, p) ;
212 
213  p = cpl_parameter_new_value("omega.omega_qcheck.PAF",
214  CPL_TYPE_BOOL,
215  "Boolean value to create PAF files. 1(Yes), 0(No)",
216  "omega_qcheck",
217  1) ;
218 
219  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "paf") ;
220  cpl_parameterlist_append(recipe->parameters, p) ;
221 
222  p = cpl_parameter_new_value("omega.omega_qcheck.rej_threshold",
223  CPL_TYPE_DOUBLE,
224  "The rejection threshold for outlying pixels",
225  "omega_qcheck",
226  5.0) ;
227 
228  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"rej-thre") ;
229  cpl_parameterlist_append(recipe->parameters, p) ;
230 
231  p = cpl_parameter_new_value("omega.omega_qcheck.NumberIter",
232  CPL_TYPE_INT,
233  "The maximum number of iterations",
234  "omega_qcheck",
235  5) ;
236 
237  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"niter") ;
238  cpl_parameterlist_append(recipe->parameters, p) ;
239 
240 
241 
242  return 0;
243 }
244 
245 /*----------------------------------------------------------------------------*/
251 /*----------------------------------------------------------------------------*/
252 static int omega_qcheck_exec(cpl_plugin * plugin)
253 {
254  cpl_recipe * recipe;
255  int recipe_status;
256 
257  /* Return immediately if an error code is already set */
258  if (cpl_error_get_code() != CPL_ERROR_NONE) {
259  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
260  cpl_func, __LINE__, cpl_error_get_where());
261  return (int)cpl_error_get_code();
262  }
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  /* Verify parameter and frame lists */
279  if (recipe->parameters == NULL) {
280  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
281  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
282  }
283  if (recipe->frames == NULL) {
284  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
285  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
286  }
287 
288  /* Invoke the recipe */
289  recipe_status = omega_qcheck(recipe->frames, recipe->parameters);
290 
291  /* Ensure DFS-compliance of the products */
292  if (cpl_dfs_update_product_header(recipe->frames)) {
293  if (!recipe_status) recipe_status = (int)cpl_error_get_code();
294  }
295 
296 
297  return recipe_status;
298 }
299 
300 /*----------------------------------------------------------------------------*/
306 /*----------------------------------------------------------------------------*/
307 static int omega_qcheck_destroy(cpl_plugin * plugin)
308 {
309  cpl_recipe * recipe = (cpl_recipe *)plugin ;
310 
311  if (plugin == NULL) {
312  cpl_msg_error(cpl_func, "Null plugin");
313  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
314  }
315 
316  /* Verify plugin type */
317  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
318  cpl_msg_error(cpl_func, "Plugin is not a recipe");
319  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
320  }
321 
322  /* Get the recipe */
323  recipe = (cpl_recipe *)plugin;
324 
325  cpl_parameterlist_delete(recipe->parameters);
326 
327  return 0 ;
328 }
329 
330 /*----------------------------------------------------------------------------*/
338 /*----------------------------------------------------------------------------*/
339 static int omega_qcheck_old(cpl_frameset *set, cpl_parameterlist *pars)
340 {
341 
342  int j,jst,jfn,live,oscan1,isfirst;
343  cpl_size nlab;
344  const char *_id = "omega_qcheck";
345  char *outfile = NULL;
346 
347  cpl_frame *mbias_frame;
348  const cpl_frame *frame1;
349  const cpl_frame *frame2;
350  cpl_frame *product_frame;
351  cpl_image *mbias_image;
352  cpl_image *trim_raw1;
353  cpl_image *trim_raw2;
354  cpl_parameter *par;
355  cpl_propertylist *plist,*qclist;
356 
357 
358  /*Start the recipe */
359 
360  if (!pars) {
361  cpl_msg_error (_id, "Parameters list not found");
362  return -1;
363  }
364 
365  if (cpl_frameset_is_empty(set) == 1) {
366  cpl_msg_error (_id, "Frameset not found");
367  return -1;
368  }
369 
370  /* Initialise a few things */
371  omega_qcheck_init();
372 
373  /* Retrieve input parameters */
374  par = cpl_parameterlist_find(pars, "omega.omega_qcheck.ExtensionNumber") ;
375  omega_qcheck_config.extnum = cpl_parameter_get_int(par) ;
376 
377  par = cpl_parameterlist_find(pars, "omega.omega_qcheck.OverscanMethod") ;
378  omega_qcheck_config.oc = cpl_parameter_get_int(par) ;
379 
380  par = cpl_parameterlist_find(pars, "omega.omega_qcheck.NumberIter") ;
381  omega_qcheck_config.niter = cpl_parameter_get_int(par) ;
382 
383  par = cpl_parameterlist_find(pars, "omega.omega_qcheck.rej_threshold") ;
384  omega_qcheck_config.rejt = cpl_parameter_get_double(par) ;
385 
386  par = cpl_parameterlist_find(pars, "omega.omega_qcheck.PAF") ;
387  omega_qcheck_config.paf = cpl_parameter_get_bool(par) ;
388 
389  /* Identify the RAW and CALIB frames in the input frameset */
390  if (oc_dfs_set_groups(set)) {
391  cpl_msg_error(_id, "Cannot identify RAW and CALIB frames") ;
392  omega_qcheck_tidy();
393  return -1 ;
394  }
395 
396 
397  /* Verify the frameset contents. */
398  /*Make sure there are exactly 2 lifetest frames */
399  if ((ps.labels = cpl_frameset_labelise(set,omega_compare_tags,
400  &nlab)) == NULL) {
401  cpl_msg_error(_id,"Cannot labelise the input frameset");
402  omega_qcheck_tidy();
403  return -1;
404  }
405  if ((ps.domelist = omega_frameset_subgroup(set,ps.labels,nlab,
406  LIFETEST_RAW)) == NULL) {
407  cpl_msg_error(_id,"Cannot find dome frames in input frameset");
408  omega_qcheck_tidy();
409  return -1;
410  }
411  if (cpl_frameset_get_size(ps.domelist) < 2) {
412  cpl_msg_error(_id,"Need exactly 2 (%s) frames to run this recipe",LIFETEST_RAW);
413  omega_qcheck_tidy();
414  return -1;
415  }
416 
417  /* Set up some convenience variables */
418  frame1 = cpl_frameset_get_frame_const(ps.domelist,0);
419  frame2 = cpl_frameset_get_frame_const(ps.domelist,1);
420  cpl_msg_info (_id,"Using %s frames: %s and %s",LIFETEST_RAW,cpl_frame_get_filename(frame1),
421  cpl_frame_get_filename(frame2));
422 
423  mbias_frame = cpl_frameset_find(set, OMEGA_CALIB_BIAS);
424  if (mbias_frame == NULL) {
425  cpl_msg_error (_id,"No Master Bias is present in frame set");
426  omega_qcheck_tidy();
427  return -1;
428  }
429 
430  cpl_msg_info(_id,"Using %s %s",OMEGA_CALIB_BIAS, cpl_frame_get_filename(mbias_frame));
431 
432  /* Loop for each of the image extensions */
433  omega_exten_range(omega_qcheck_config.extnum,&jst,&jfn);
434  if(omega_qcheck_config.extnum == 0){
435  cpl_msg_error(cpl_func,"Unsupported extension request, %d",omega_qcheck_config.extnum);
436  omega_qcheck_tidy();
437  return -1;
438  }
439 
440  /* Check which instrument */
441  if(omega_pfits_check_instrume(cpl_frameset_get_first_const(set)) == 1 &&
442  omega_qcheck_config.extnum == 0 && jfn == 32)
443  jfn = 8;
444 
445  for (j = jst; j <= jfn; j++) {
446  cpl_msg_info(_id,"Beginning work on extension %d",j);
447  isfirst = (j == jst);
448  omega_qcheck_config.mean = 0.0;
449  omega_qcheck_config.median = 0.0;
450  omega_qcheck_config.stdev = 0.0;
451 
452 
453  /* Check that this detector is live*/
454  plist = cpl_propertylist_load(cpl_frame_get_filename(frame1),j);
455  omega_pfits_get_detlive(plist,&live);
456  if (! live) {
457  cpl_msg_warning(_id,"First dome image detector not live");
458  /*save dummy extension*/
459  freeplist(plist);
460  continue;
461  }
462  freeplist(plist);
463 
464  plist = cpl_propertylist_load(cpl_frame_get_filename(frame2),j);
465  omega_pfits_get_detlive(plist,&live);
466  if (! live) {
467  cpl_msg_warning(_id,"Second dome image detector not live");
468  /*save dummy extension*/
469  freeplist(plist);
470  continue;
471  }
472  freeplist(plist);
473 
474  /* Check overscan correction method consistency */
475  oscan1 = omega_pfits_get_overscan(mbias_frame, j);
476  if(oscan1 != omega_qcheck_config.oc) {
477  cpl_msg_warning (_id, "Overscan correction mode for Master Bias (oc = %d) differs from "
478  "the one used here (oc = %d)", oscan1, omega_qcheck_config.oc);
479  }
480 
481  /* Load master bias*/
482  mbias_image = cpl_image_load(cpl_frame_get_filename(mbias_frame), CPL_TYPE_FLOAT, 0, j);
483  if (mbias_image == NULL) {
484  cpl_msg_error(_id,"Cannot load MASTER BIAS");
485  omega_qcheck_tidy();
486  return -1;
487  }
488 
489  cpl_msg_info (_id,"Doing trim and overscan correction on images");
490 
491  trim_raw1 = TrimOscanCorrect(frame1, omega_qcheck_config.oc, j);
492  if(trim_raw1 == NULL){
493  cpl_msg_error(_id,"Cannot trim first image");
494  freeimage(mbias_image);
495  omega_qcheck_tidy();
496  return -1;
497  }
498 
499  cpl_image_subtract(trim_raw1, mbias_image);
500 
501  trim_raw2 = TrimOscanCorrect(frame2, omega_qcheck_config.oc, j);
502  if(trim_raw2 == NULL){
503  cpl_msg_error(_id,"Cannot trim second image");
504  freeimage(mbias_image);
505  omega_qcheck_tidy();
506  return -1;
507  }
508 
509  cpl_image_subtract(trim_raw2, mbias_image);
510  freeimage(mbias_image);
511 
512  cpl_image_divide(trim_raw1, trim_raw2);
513  if(trim_raw1 == NULL){
514  cpl_msg_error(_id,"Error in image division");
515  omega_qcheck_tidy();
516  return -1;
517  }
518 
519  freeimage(trim_raw2);
520 
521  /*Calculate statistics iteratively*/
522  ps.stats = omega_iter_stat_opts(trim_raw1,NULL,omega_qcheck_config.rejt,omega_qcheck_config.niter);
523  if(ps.stats != NULL){
524  omega_qcheck_config.mean = cpl_stats_get_mean(ps.stats);
525  omega_qcheck_config.median = cpl_stats_get_median(ps.stats);
526  omega_qcheck_config.stdev = cpl_stats_get_stdev(ps.stats);
527  }
528  else{
529  cpl_msg_warning(_id,"Cannot calculate statistics iteratively");
530  }
531 
532  freestats(ps.stats);
533  freeimage(trim_raw1);
534 
535  /* Save the product */
536  ps.result = cpl_table_new(1);
537  cpl_table_new_column(ps.result, "MEAN", CPL_TYPE_DOUBLE);
538  cpl_table_new_column(ps.result, "MEDIAN", CPL_TYPE_DOUBLE);
539  cpl_table_new_column(ps.result, "STDEV", CPL_TYPE_DOUBLE);
540  cpl_table_set_double(ps.result, "MEAN", 0, omega_qcheck_config.mean);
541  cpl_table_set_double(ps.result, "MEDIAN", 0, omega_qcheck_config.median);
542  cpl_table_set_double(ps.result, "STDEV", 0, omega_qcheck_config.stdev);
543 
544 /*
545  ps.domefits1 = omega_fits_load(frame1,CPL_TYPE_FLOAT,j);
546  ps.eh = omega_fits_get_ehu(ps.domefits1);
547 */
548 
549  /* Create QC list */
550  qclist = cpl_propertylist_new();
551  cpl_propertylist_append_double(qclist, "ESO QC QUICK CHECK MEAN",
552  omega_qcheck_config.mean) ;
553  cpl_propertylist_set_comment(qclist,"ESO QC QUICK CHECK MEAN","Mean of difference");
554 
555  cpl_propertylist_append_double(qclist, "ESO QC QUICK CHECK MEDIAN",
556  omega_qcheck_config.median) ;
557  cpl_propertylist_set_comment(qclist,"ESO QC QUICK CHECK MEDIAN","Median of difference");
558 
559  cpl_propertylist_append_double(qclist, "ESO QC QUICK CHECK STDEV",
560  omega_qcheck_config.stdev) ;
561  cpl_propertylist_set_comment(qclist,"ESO QC QUICK CHECK STDEV","Standard deviation of difference");
562 
563  if(isfirst){
564  ps.proname = cpl_sprintf("%s_%s.fits", INSTRUME,LTEST_PROCATG);
565  product_frame = omega_product_frame(ps.proname, LTEST_PROCATG, CPL_FRAME_TYPE_TABLE);
566  }
567 
568  if(omega_save_table(ps.result,set,pars,NULL,qclist,ps.proname,RECIPE,product_frame,
569  NULL,isfirst) == -1){
570  cpl_msg_error(cpl_func, "Cannot save the product");
571  freeplist(qclist);
572  omega_qcheck_tidy();
573  return -1 ;
574  }
575 
576 /*
577  if (omega_qcheck_save(set,pars) == -1) {
578  cpl_msg_error(_id, "Cannot save the product");
579  omega_qcheck_tidy();
580  return -1 ;
581  }
582 */
583 
584  freetable(ps.result);
585  freeplist(qclist);
586 // freefits(ps.domefits1);
587 // ps.domefits1 = NULL;
588 
589  } /* go back and do next extension */
590 
591 
592  /*Clean up */
593  omega_qcheck_tidy();
594 
595  return 0;
596 
597 }
598 
599 /*----------------------------------------------------------------------------*/
612 /*----------------------------------------------------------------------------*/
613 
614 static int omega_qcheck(cpl_frameset *set, cpl_parameterlist *pars)
615 {
616 
617  int j,jst,jfn,oscan1,isfirst;
618  cpl_size nlab;
619  cpl_frame *mbias_frame;
620  const cpl_frame *frame1;
621  cpl_image *mbias_image;
622  cpl_image *trim_raw1;
623  cpl_frame *product_frame;
624  cpl_parameter *par;
625  cpl_propertylist *qclist,*alist;
626 
627 
628  /*Start the recipe */
629 
630  if (!pars) {
631  cpl_msg_error (cpl_func, "Parameters list not found");
632  return -1;
633  }
634 
635  if (cpl_frameset_is_empty(set) == 1) {
636  cpl_msg_error (cpl_func, "Frameset not found");
637  return -1;
638  }
639 
640  /* Initialise a few things */
641  omega_qcheck_init();
642 
643  /* Retrieve input parameters */
644  par = cpl_parameterlist_find(pars, "omega.omega_qcheck.ExtensionNumber") ;
645  omega_qcheck_config.extnum = cpl_parameter_get_int(par) ;
646 
647  par = cpl_parameterlist_find(pars, "omega.omega_qcheck.OverscanMethod") ;
648  omega_qcheck_config.oc = cpl_parameter_get_int(par) ;
649 
650  par = cpl_parameterlist_find(pars, "omega.omega_qcheck.NumberIter") ;
651  omega_qcheck_config.niter = cpl_parameter_get_int(par) ;
652 
653  par = cpl_parameterlist_find(pars, "omega.omega_qcheck.rej_threshold") ;
654  omega_qcheck_config.rejt = cpl_parameter_get_double(par) ;
655 
656  par = cpl_parameterlist_find(pars, "omega.omega_qcheck.PAF") ;
657  omega_qcheck_config.paf = cpl_parameter_get_bool(par) ;
658 
659  /* Identify the RAW and CALIB frames in the input frameset */
660  if (oc_dfs_set_groups(set)) {
661  cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames") ;
662  omega_qcheck_tidy();
663  return -1 ;
664  }
665 
666 
667  /* Verify the frameset contents. */
668  /*Make sure there is exactly 1 lifetest frames */
669  if ((ps.labels = cpl_frameset_labelise(set,omega_compare_tags,
670  &nlab)) == NULL) {
671  cpl_msg_error(cpl_func,"Cannot labelise the input frameset");
672  omega_qcheck_tidy();
673  return -1;
674  }
675  if ((ps.domelist = omega_frameset_subgroup(set,ps.labels,nlab,
676  LIFETEST_RAW)) == NULL) {
677  cpl_msg_error(cpl_func,"Cannot find dome frame in input frameset");
678  omega_qcheck_tidy();
679  return -1;
680  }
681  if (cpl_frameset_get_size(ps.domelist) < 1) {
682  cpl_msg_error(cpl_func,"Need exactly 1 (%s) frame to run this recipe",LIFETEST_RAW);
683  omega_qcheck_tidy();
684  return -1;
685  }
686 
687  /* Set up some convenience variables */
688  frame1 = cpl_frameset_get_frame_const(ps.domelist,0);
689  cpl_msg_info (cpl_func,"Using %s frame: %s",LIFETEST_RAW,cpl_frame_get_filename(frame1));
690 
691  mbias_frame = cpl_frameset_find(set, OMEGA_CALIB_BIAS);
692  if (mbias_frame == NULL) {
693  cpl_msg_error (cpl_func,"No Master Bias is present in frame set");
694  omega_qcheck_tidy();
695  return -1;
696  }
697 
698  cpl_msg_info(cpl_func,"Using %s %s",OMEGA_CALIB_BIAS, cpl_frame_get_filename(mbias_frame));
699 
700  /* Loop for each of the image extensions */
701  omega_extensions(frame1,omega_qcheck_config.extnum,&jst,&jfn);
702  if(omega_qcheck_config.extnum == 0){
703  cpl_msg_error(cpl_func,"Unsupported extension request, %d",omega_qcheck_config.extnum);
704  omega_qcheck_tidy();
705  return -1;
706  }
707 
708  for (j = jst; j <= jfn; j++) {
709  cpl_msg_info(cpl_func,"Working on extension %d",j);
710  isfirst = (j == jst);
711  omega_qcheck_config.mean = 0.0;
712  omega_qcheck_config.median = 0.0;
713  omega_qcheck_config.stdev = 0.0;
714 
715 
716  /* Check that this detector is live*/
717  /*
718  plist = cpl_propertylist_load(cpl_frame_get_filename(frame1),j);
719  omega_pfits_get_detlive(plist,&live);
720  if (! live) {
721  cpl_msg_warning(cpl_func,"First dome image detector not live");
722  save dummy extension
723  freeplist(plist);
724  continue;
725  }
726  freeplist(plist);
727  */
728 
729  /* Check overscan correction method consistency */
730  oscan1 = omega_pfits_get_overscan(mbias_frame, j);
731  if(oscan1 != omega_qcheck_config.oc) {
732  cpl_msg_warning (cpl_func, "Overscan correction mode for Master Bias (oc = %d) differs from "
733  "the one used here (oc = %d)", oscan1, omega_qcheck_config.oc);
734  }
735 
736  /* Load master bias*/
737  mbias_image = cpl_image_load(cpl_frame_get_filename(mbias_frame), CPL_TYPE_FLOAT, 0, j);
738  if (mbias_image == NULL) {
739  cpl_msg_error(cpl_func,"Cannot load MASTER BIAS");
740  omega_qcheck_tidy();
741  return -1;
742  }
743 
744  ps.domefits1 = omega_fits_load(frame1,CPL_TYPE_FLOAT,j);
745 
746  trim_raw1 = omega_trim_oscan_correct(ps.domefits1, omega_qcheck_config.oc);
747  if(trim_raw1 == NULL){
748  cpl_msg_error(cpl_func,"Cannot trim input image");
749  freeimage(mbias_image);
750  omega_qcheck_tidy();
751  return -1;
752  }
753 
754  cpl_image_subtract(trim_raw1, mbias_image);
755  freeimage(mbias_image);
756 
757  /*Calculate statistics iteratively*/
758  ps.stats = omega_iter_stat_opts(trim_raw1,NULL,omega_qcheck_config.rejt,omega_qcheck_config.niter);
759  if(ps.stats != NULL){
760  omega_qcheck_config.mean = cpl_stats_get_mean(ps.stats);
761  omega_qcheck_config.median = cpl_stats_get_median(ps.stats);
762  omega_qcheck_config.stdev = cpl_stats_get_stdev(ps.stats);
763  }
764  else{
765  cpl_msg_warning(cpl_func,"Cannot calculate statistics iteratively");
766  }
767 
768  freestats(ps.stats);
769  freeimage(trim_raw1);
770 
771  /* FIXME: include comparison with REFERENCE frame */
772  /* Save the product */
773  ps.result = cpl_table_new(1);
774  cpl_table_new_column(ps.result, "MEAN", CPL_TYPE_DOUBLE);
775  cpl_table_new_column(ps.result, "MEDIAN", CPL_TYPE_DOUBLE);
776  cpl_table_new_column(ps.result, "STDEV", CPL_TYPE_DOUBLE);
777  cpl_table_set_double(ps.result, "MEAN", 0, omega_qcheck_config.mean);
778  cpl_table_set_double(ps.result, "MEDIAN", 0, omega_qcheck_config.median);
779  cpl_table_set_double(ps.result, "STDEV", 0, omega_qcheck_config.stdev);
780 
781  /* Create QC list */
782  qclist = cpl_propertylist_new();
783  cpl_propertylist_append_double(qclist, "ESO QC QUICK CHECK MEAN",
784  omega_qcheck_config.mean) ;
785  cpl_propertylist_set_comment(qclist,"ESO QC QUICK CHECK MEAN","Mean of difference");
786 
787  cpl_propertylist_append_double(qclist, "ESO QC QUICK CHECK MEDIAN",
788  omega_qcheck_config.median) ;
789  cpl_propertylist_set_comment(qclist,"ESO QC QUICK CHECK MEDIAN","Median of difference");
790 
791  cpl_propertylist_append_double(qclist, "ESO QC QUICK CHECK STDEV",
792  omega_qcheck_config.stdev) ;
793  cpl_propertylist_set_comment(qclist,"ESO QC QUICK CHECK STDEV","Standard deviation of difference");
794 
795  if(isfirst){
796  ps.proname = cpl_sprintf("%s_%s.fits", INSTRUME,LTEST_PROCATG);
797  product_frame = omega_product_frame(ps.proname, LTEST_PROCATG, CPL_FRAME_TYPE_TABLE);
798  }
799 
800 
801  alist=cpl_propertylist_load_regexp(cpl_frame_get_filename(frame1),j,"EXTNAME",0);
802  if(omega_save_table(ps.result,set,pars,alist,qclist,ps.proname,RECIPE,product_frame,
803  NULL,isfirst) == -1){
804  cpl_msg_error(cpl_func, "Cannot save the product");
805  cpl_propertylist_delete(alist);
806  freeplist(qclist);
807  omega_qcheck_tidy();
808  return -1 ;
809  }
810  cpl_propertylist_delete(alist);
811 /*
812  if (omega_qcheck_save(set,pars) == -1) {
813  cpl_msg_error(cpl_func, "Cannot save the product");
814  omega_qcheck_tidy();
815  return -1 ;
816  }
817 */
818 
819  freetable(ps.result);
820  freeplist(qclist);
821  freefits(ps.domefits1);
822  ps.domefits1 = NULL;
823  } /* go back and do next extension */
824 
825 
826  /*Clean up */
827  omega_qcheck_tidy();
828 
829  return 0;
830 
831 }
832 
833 
834 /* Initialize the pointers */
835 static void omega_qcheck_init(void) {
836  ps.labels = NULL;
837  ps.domelist = NULL;
838  ps.domefits1 = NULL;
839  ps.stats = NULL;
840  ps.eh = NULL;
841  ps.proname = NULL;
842  ps.result = NULL;
843 }
844 
845 /* Free any allocated memory */
846 static void omega_qcheck_tidy(void) {
847  freespace(ps.labels);
848  freeframeset(ps.domelist);
849  freefits(ps.domefits1);
850  freestats(ps.stats);
851  freespace(ps.proname);
852  freetable(ps.result);
853 }
854