OMEGA Pipeline Reference Manual  1.0.6
omega_mbias.c
1 /* $Id: omega_mbias.c,v 1.3 2012-08-30 07:46:52 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-08-30 07:46:52 $
24  * $Revision: 1.3 $
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 
59 /*-----------------------------------------------------------------------------
60  Functions prototypes
61  -----------------------------------------------------------------------------*/
62 
63 static int omega_mbias_create(cpl_plugin *) ;
64 static int omega_mbias_exec(cpl_plugin *) ;
65 static int omega_mbias_destroy(cpl_plugin *) ;
66 static int omega_mbias(cpl_frameset *,cpl_parameterlist *) ;
67 
68 /*-----------------------------------------------------------------------------
69  Private Functions
70  -----------------------------------------------------------------------------*/
71 int omega_mbias_combine(int xn);
72 static void omega_mbias_init(void);
73 static void omega_mbias_tidy(void);
74 
75 /*-----------------------------------------------------------------------------
76  Static structures
77  -----------------------------------------------------------------------------*/
78 
79 static struct {
80  /* Inputs. Parameters */
81  float rejsig;
82  double sigma;
83  int extnum;
84  int oc;
85  int paf;
86 
87  /* Outputs. QC parameters */
88  int CountHotPixels;
89  double Mean;
90  double Median;
91  double Stdev;
92 
93 }omega_mbias_config;
94 
95 
96 /* Input and Output */
97 static struct {
98  cpl_size *labels;
99  const cpl_frame *rnframe;
100  cpl_frameset *biaslist;
101  cpl_stats *stats;
102  omega_fits *firstbias;
103  cpl_propertylist *ph;
104  cpl_propertylist *eh;
105 
106  /* Products */
107  cpl_image *mbias;
108  cpl_image *hpixels;
109 
110 } ps;
111 
112 /*-----------------------------------------------------------------------------
113  Static variables
114  -----------------------------------------------------------------------------*/
115 
116 /* Static variables */
117 #define RECIPE "omega_mbias"
118 
119 static int isfirst;
120 
121 
122 
123 
134 int cpl_plugin_get_info(cpl_pluginlist * list)
135 {
136  cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe)) ;
137  cpl_plugin * plugin = &recipe->interface ;
138 
139  cpl_plugin_init(plugin,
140  CPL_PLUGIN_API,
141  OMEGA_BINARY_VERSION,
142  CPL_PLUGIN_TYPE_RECIPE,
143  "omega_mbias",
144  "OMEGA - Create Master Bias for each chip.",
145  "Trims and applies overscan correction to the raw input bias \n"
146  "frames. Averages these frames to derive the master bias frame. \n"
147  "Calculates the image statistics on the resulting frame. Creates \n"
148  "the FITS header and saves it together with the FITS image.",
149  "Sandra Castro",
150  "scastro@eso.org",
152  omega_mbias_create,
153  omega_mbias_exec,
154  omega_mbias_destroy) ;
155 
156  cpl_pluginlist_append(list, plugin) ;
157 
158  return 0;
159 }
160 
161 /*----------------------------------------------------------------------------*/
170 /*----------------------------------------------------------------------------*/
171 static int omega_mbias_create(cpl_plugin * plugin)
172 {
173  cpl_recipe * recipe;
174  cpl_parameter * p ;
175 
176  /* Do not create the recipe if an error code is already set */
177  if (cpl_error_get_code() != CPL_ERROR_NONE) {
178  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
179  cpl_func, __LINE__, cpl_error_get_where());
180  return (int)cpl_error_get_code();
181  }
182 
183  if (plugin == NULL) {
184  cpl_msg_error(cpl_func, "Null plugin");
185  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
186  }
187 
188  /* Verify plugin type */
189  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
190  cpl_msg_error(cpl_func, "Plugin is not a recipe");
191  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
192  }
193 
194  /* Get the recipe */
195  recipe = (cpl_recipe *)plugin;
196 
197  /* Create the parameters list in the cpl_recipe object */
198  recipe->parameters = cpl_parameterlist_new() ;
199  if (recipe->parameters == NULL) {
200  cpl_msg_error(cpl_func, "Parameter list allocation failed");
201  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
202  }
203 
204  /* Fill the parameters list */
205  p = cpl_parameter_new_value("omega.omega_mbias.ExtensionNumber",
206  CPL_TYPE_INT,
207  "FITS extension number to load (1 to 32). (-1 = all)",
208  "omega_mbias",
209  -1) ;
210 
211  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"ext") ;
212  cpl_parameterlist_append(recipe->parameters, p) ;
213 
214 
215  p = cpl_parameter_new_range("omega.omega_mbias.OverscanMethod",
216  CPL_TYPE_INT,
217  "Overscan Correction Method",
218  "omega_mbias",
219  0, 0, 6);
220  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"oc-meth") ;
221  cpl_parameterlist_append(recipe->parameters, p) ;
222 
223  p = cpl_parameter_new_value("omega.omega_mbias.PAF",
224  CPL_TYPE_BOOL,
225  "Boolean value to create PAF files. 1(Yes), 0(No)",
226  "omega_mbias",
227  1) ;
228 
229  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "paf") ;
230  cpl_parameterlist_append(recipe->parameters, p) ;
231 
232  p = cpl_parameter_new_value("omega.omega_mbias.SigmaClip",
233  CPL_TYPE_DOUBLE,
234  "Sigma Clipping Threshold for image",
235  "omega_mbias",
236  3.0) ;
237 
238  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"sig-clip") ;
239  cpl_parameterlist_append(recipe->parameters, p) ;
240 
241  p = cpl_parameter_new_range("omega.omega_mbias.RejSigma",
242  CPL_TYPE_DOUBLE,
243  "Rejection threshold for outlying pixels in Hot Pixels Map",
244  "omega_mbias",
245  5.0, 1.0, 10.0) ;
246 
247  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "rej-sigma") ;
248  cpl_parameterlist_append(recipe->parameters, p) ;
249 
250 
251  /* Return */
252  return 0;
253 }
254 
255 /*----------------------------------------------------------------------------*/
261 /*----------------------------------------------------------------------------*/
262 static int omega_mbias_exec(cpl_plugin * plugin)
263 {
264  cpl_recipe * recipe;
265  int recipe_status;
266 /* cpl_errorstate initial_errorstate = cpl_errorstate_get();*/
267 
268  /* Return immediately if an error code is already set */
269  if (cpl_error_get_code() != CPL_ERROR_NONE) {
270  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
271  cpl_func, __LINE__, cpl_error_get_where());
272  return (int)cpl_error_get_code();
273  }
274 
275  if (plugin == NULL) {
276  cpl_msg_error(cpl_func, "Null plugin");
277  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
278  }
279 
280  /* Verify plugin type */
281  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
282  cpl_msg_error(cpl_func, "Plugin is not a recipe");
283  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
284  }
285 
286  /* Get the recipe */
287  recipe = (cpl_recipe *)plugin;
288 
289  /* Verify parameter and frame lists */
290  if (recipe->parameters == NULL) {
291  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
292  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
293  }
294  if (recipe->frames == NULL) {
295  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
296  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
297  }
298 
299  /* Invoke the recipe */
300  recipe_status = omega_mbias(recipe->frames, recipe->parameters);
301 
302  /* Ensure DFS-compliance of the products */
303  if (cpl_dfs_update_product_header(recipe->frames)) {
304  if (!recipe_status) recipe_status = (int)cpl_error_get_code();
305  }
306 
307 
308  return recipe_status;
309 }
310 
311 /*----------------------------------------------------------------------------*/
317 /*----------------------------------------------------------------------------*/
318 static int omega_mbias_destroy(cpl_plugin * plugin)
319 {
320  cpl_recipe * recipe;
321 
322  if (plugin == NULL) {
323  cpl_msg_error(cpl_func, "Null plugin");
324  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
325  }
326 
327  /* Verify plugin type */
328  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
329  cpl_msg_error(cpl_func, "Plugin is not a recipe");
330  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
331  }
332 
333  /* Get the recipe */
334  recipe = (cpl_recipe *)plugin;
335 
336  cpl_parameterlist_delete(recipe->parameters);
337 
338  return 0 ;
339 }
340 
341 /*----------------------------------------------------------------------------*/
348 /*----------------------------------------------------------------------------*/
349 static int omega_mbias(cpl_frameset *set, cpl_parameterlist *pars)
350 {
351 
352  int j,jst,jfn,status;
353  cpl_size nlab;
354  int nbias = 0;
355  char *outhpm = NULL;
356  char *outmbias = NULL;
357 
358  const char *_id = "omega_mbias";
359 
360  cpl_parameter *par;
361  cpl_frame *firstframe;
362  cpl_frame *prframe_mbias = NULL;
363  cpl_frame *prframe_hpm = NULL;
364  const cpl_frame *refframe = NULL;
365  cpl_propertylist *qclist;
366  cpl_propertylist *alist;
367  cpl_stats *diffstats = NULL;
368 
369 
370  /*Start the recipe */
371 
372  if (!pars) {
373  cpl_msg_error (_id, "Parameters list not found");
374  return -1;
375  }
376 
377  if (cpl_frameset_is_empty(set) == 1) {
378  cpl_msg_error (_id, "Frameset not found");
379  return -1;
380  }
381 
382 
383 /* Retrieve input parameters */
384  par = cpl_parameterlist_find(pars, "omega.omega_mbias.ExtensionNumber") ;
385  omega_mbias_config.extnum = cpl_parameter_get_int(par) ;
386 
387  par = cpl_parameterlist_find(pars, "omega.omega_mbias.OverscanMethod") ;
388  omega_mbias_config.oc = cpl_parameter_get_int(par) ;
389 
390  par = cpl_parameterlist_find(pars, "omega.omega_mbias.SigmaClip") ;
391  omega_mbias_config.sigma = cpl_parameter_get_double(par) ;
392 
393  par = cpl_parameterlist_find(pars, "omega.omega_mbias.RejSigma") ;
394  omega_mbias_config.rejsig = cpl_parameter_get_double(par) ;
395 
396  par = cpl_parameterlist_find(pars, "omega.omega_mbias.PAF");
397  omega_mbias_config.paf = cpl_parameter_get_bool(par);
398 
399 
400 
401 /* Identify the RAW and CALIB frames in the input frameset */
402  if (oc_dfs_set_groups(set)) {
403  cpl_msg_error(_id, "Cannot identify RAW and CALIB frames") ;
404  return -1 ;
405  }
406 
407 
408  /*Initialized things*/
409  omega_mbias_init();
410 
411 
412  /* Verify the frameset contents. */
413  if ((ps.labels = cpl_frameset_labelise(set,omega_compare_tags,
414  &nlab)) == NULL) {
415  cpl_msg_error(_id,"Cannot labelise the input frameset");
416  omega_mbias_tidy();
417  return -1;
418  }
419  if ((ps.biaslist = omega_frameset_subgroup(set,ps.labels,nlab,
420  MBIAS_RAW)) == NULL) {
421  cpl_msg_error(_id,"Cannot find bias frames in input frameset");
422  omega_mbias_tidy();
423  return -1;
424  }
425 
426  nbias = cpl_frameset_get_size(ps.biaslist);
427  if (nbias < 2) {
428  cpl_msg_error(_id,"Need at least 2 (%s) frames to run this recipe",MBIAS_RAW);
429  omega_mbias_tidy();
430  return -1;
431  }
432 
433  cpl_msg_info (_id,"There are %d %s in frame set",nbias, MBIAS_RAW);
434 
435  /* Check for calibration frame */
436  /* Readnoise table */
437  ps.rnframe = cpl_frameset_find_const(set, OMEGA_CALIB_RDNOISE);
438  if (ps.rnframe == NULL) {
439  cpl_msg_info(_id,"A Readnoise table is not present in frame set. Using header values");
440  }
441  else{
442  cpl_msg_info(_id,"Using %s %s",OMEGA_CALIB_RDNOISE, cpl_frame_get_filename(ps.rnframe));
443  }
444 
445  /* Get first frame from frame set */
446  firstframe = cpl_frameset_get_position(ps.biaslist, 0) ;
447 
448  /* Optional reference master bias frame */
449  refframe = cpl_frameset_find_const(set, REFBIAS);
450  if (refframe != NULL)
451  cpl_msg_info(cpl_func,"Using %s for comparison",cpl_frame_get_filename(refframe));
452 
453  /* Loop for each of the image extensions */
454  omega_extensions(firstframe,omega_mbias_config.extnum,&jst,&jfn);
455 
456  if(omega_mbias_config.extnum == 0){
457  cpl_msg_error(cpl_func,"Unsupported extension request, %d",omega_mbias_config.extnum);
458  omega_mbias_tidy();
459  return -1;
460  }
461 
462 
463  /* Check which instrument */
464  if (omega_pfits_check_instrume(firstframe) == 1)
465  sprintf(INSTRUME,"wfi");
466 
467  if(omega_pfits_check_instrume(firstframe) == 1 &&
468  omega_mbias_config.extnum == 0 && jfn == 32){
469  jfn = 8;
470  }
471 
472  for (j = jst; j <= jfn; j++) {
473 
474  isfirst = (j == jst);
475  cpl_msg_info(_id,"Beginning work on extension %d",j);
476  omega_mbias_config.CountHotPixels = 0;
477  omega_mbias_config.Mean = 0.0;
478  omega_mbias_config.Median = 0.0;
479  omega_mbias_config.Stdev = 0.0;
480 
481  ps.firstbias = omega_fits_load(firstframe,CPL_TYPE_FLOAT,j);
482  ps.eh = omega_fits_get_ehu(ps.firstbias);
483 
484  /* Call the combining routine */
485  status = omega_mbias_combine(j);
486  if(status == 1){
487  cpl_msg_warning(_id, "Image detector is not live");
488  /* Save dummy product */
489  freefits(ps.firstbias);
490  ps.eh = NULL;
491  continue;
492  }
493  else if(status == -1){
494  cpl_msg_error(_id,"Cannot combine images");
495  freespace(outhpm);
496  freespace(outmbias);
497  omega_mbias_tidy();
498  return -1;
499  }
500 
501  status = 0;
502 
503  qclist = cpl_propertylist_new();
504 
505  /* Compare with reference frame */
506  if(refframe != NULL){
507  if(omega_compare_reference(ps.mbias,refframe,j,&diffstats) == -1){
508  cpl_msg_warning(cpl_func,"Cannot compare with reference frame");
509  }
510  else{
511  cpl_propertylist_append_double(qclist,"ESO QC DIFF REFBIAS MEAN",
512  cpl_stats_get_mean(diffstats));
513  cpl_propertylist_set_comment(qclist,"ESO QC DIFF REFBIAS MEAN",
514  "Mean of difference with reference");
515  cpl_propertylist_append_double(qclist,"ESO QC DIFF REFBIAS MEDIAN",
516  cpl_stats_get_median(diffstats));
517  cpl_propertylist_set_comment(qclist,"ESO QC DIFF REFBIAS MEDIAN",
518  "Median of difference with reference");
519  cpl_propertylist_append_double(qclist,"ESO QC DIFF REFBIAS STDEV",
520  cpl_stats_get_stdev(diffstats));
521  cpl_propertylist_set_comment(qclist,"ESO QC DIFF REFBIAS STDEV",
522  "Stdev of difference with reference");
523 
524  freestats(diffstats);
525  }
526  }
527 
528  /* Save the products */
529  /* Save the MASTER BIAS product */
530  cpl_propertylist_append_double(qclist, "ESO QC MASTER BIAS MEAN",
531  omega_mbias_config.Mean) ;
532  cpl_propertylist_set_comment (qclist, "ESO QC MASTER BIAS MEAN",
533  "Mean value of master bias");
534 
535  cpl_propertylist_append_double(qclist, "ESO QC MASTER BIAS MEDIAN",
536  omega_mbias_config.Median) ;
537  cpl_propertylist_set_comment (qclist, "ESO QC MASTER BIAS MEDIAN",
538  "Median value of master bias");
539 
540  cpl_propertylist_append_double(qclist, "ESO QC MASTER BIAS STDEV",
541  omega_mbias_config.Stdev) ;
542  cpl_propertylist_set_comment (qclist, "ESO QC MASTER BIAS STDEV",
543  "Standard Deviation of master bias");
544 
545  if(isfirst){
546  outmbias = cpl_sprintf("%s_%s.fits", INSTRUME,MBIAS_PROCATG);
547  prframe_mbias = omega_product_frame(outmbias, MBIAS_PROCATG, CPL_FRAME_TYPE_IMAGE);
548  }
549 
550  alist = cpl_propertylist_new();
551  cpl_propertylist_append_string(alist, "EXTNAME",
552  cpl_propertylist_get_string(ps.eh, "EXTNAME"));
553  cpl_propertylist_set_comment(alist,"EXTNAME", "Extension name");
554 
555  /* Add DRS keywords */
556  cpl_propertylist_update_int(alist, "ESO DRS OVERSCAN METHOD", omega_mbias_config.oc);
557  cpl_propertylist_set_comment(alist, "ESO DRS OVERSCAN METHOD", "overscan correction method");
558 
559  cpl_propertylist_copy_property_regexp(alist, ps.eh, WCS_KEYS, 0);
560 
561 
562  if(omega_save_image(ps.mbias,set,pars,alist,qclist,CPL_BPP_IEEE_FLOAT,outmbias,
563  RECIPE,prframe_mbias,NULL,isfirst) == -1){
564  cpl_msg_error(_id,"Cannot save product %s", MBIAS_PROCATG);
565  freeplist(qclist);
566  freeplist(alist);
567  freespace(outhpm);
568  freespace(outmbias);
569  omega_mbias_tidy();
570  return -1;;
571  }
572 
573  freeplist(qclist);
574  freeimage(ps.mbias);
575 
576  /* Save the HOT PIXELS MAP product */
577  qclist = cpl_propertylist_new();
578  cpl_propertylist_append_int(qclist,"ESO QC NUMBER HOT PIXELS",
579  omega_mbias_config.CountHotPixels);
580  cpl_propertylist_set_comment(qclist,"ESO QC NUMBER HOT PIXELS",
581  "Number of hot pixels");
582  if(isfirst){
583  outhpm = cpl_sprintf("%s_%s.fits", INSTRUME,HPM_PROCATG);
584  prframe_hpm = omega_product_frame(outhpm, HPM_PROCATG, CPL_FRAME_TYPE_IMAGE);
585  }
586 
587  if(omega_save_image(ps.hpixels,set,pars,alist,qclist,CPL_BPP_16_SIGNED,outhpm,
588  RECIPE,prframe_hpm,NULL,isfirst) == -1){
589  cpl_msg_error(_id,"Cannot save product %s", HPM_PROCATG);
590  freeplist(qclist);
591  freeplist(alist);
592  freespace(outhpm);
593  freespace(outmbias);
594  omega_mbias_tidy();
595  return -1;;
596  }
597 
598  freeplist(qclist);
599  freeplist(alist);
600  freeimage(ps.hpixels);
601  status = 0;
602 
603  freefits(ps.firstbias);
604  ps.firstbias = NULL;
605  ps.eh = NULL;
606 
607 
608  } /* work on next extension */
609 
610  freespace(outhpm);
611  freespace(outmbias);
612  omega_mbias_tidy();
613 
614  return 0;
615 }
616 
626 {
627 
628  int i, nbias, live, naxis1, naxis2;
629  double read_noise, threshold;
630  double cutoff = 200.0; /*FIXME: arbitrary initial value*/
631  const char *_id = "omega_mbias_combine";
632 
633  const cpl_frame *biasfr;
634  cpl_image *trim_raw,*median_all,*dev,*good_int,*good_float;
635  cpl_image *sum_data,*sum_good,*image;
636  cpl_imagelist *ilist;
637  cpl_mask *good,*pixelmap;
638  cpl_table *rntable;
639 
640 
641 
642 
643  /* Check that this detector is live*/
644  omega_pfits_get_detlive(ps.eh,&live);
645  if (! live) {
646  return 1;
647  }
648 
649  cpl_msg_info (_id,"Doing trim and overscan correction on images");
650 
651  nbias = cpl_frameset_get_size(ps.biaslist);
652  for (i=0; i< nbias; i++){
653  biasfr = cpl_frameset_get_position(ps.biaslist, i) ;
654  if (biasfr == NULL)
655  break;
656  trim_raw = TrimOscanCorrect(biasfr, omega_mbias_config.oc, xn);
657  if(trim_raw == NULL){
658  return -1;
659  }
660 
661  if (i == 0) {
662  naxis1 = cpl_image_get_size_x (trim_raw);
663  naxis2 = cpl_image_get_size_y (trim_raw);
664  ilist = cpl_imagelist_new ();
665  }
666 
667  cpl_imagelist_set (ilist, trim_raw, i);
668  }
669 
670  if (ilist == NULL) {
671  cpl_msg_error(_id,"Error in imagelist <%s>",cpl_error_get_message());
672  freeimage(trim_raw);
673  return -1;
674 
675  }
676 
677  /*
678  * If READNOISE_ADU table doesn't exist, try to
679  * get readnoise value from header of first image
680  */
681  if(ps.rnframe != NULL){
682  rntable = cpl_table_load(cpl_frame_get_filename(ps.rnframe), xn, 0);
683  if(rntable != NULL){
684  read_noise = cpl_table_get_double(rntable, "READNOISE",0, NULL);
685  freetable(rntable);
686  }
687  else{
688  omega_pfits_get_readnoise(ps.eh, &read_noise);
689  cpl_msg_warning(cpl_func,"Cannot load READNOISE_ADU table. %s",cpl_error_get_message());
690  }
691  }
692  else {
693  omega_pfits_get_readnoise(ps.eh, &read_noise);
694  }
695 
696  if (read_noise == 0.0){
697  cpl_msg_info(_id,"Using default value for read noise");
698  read_noise = 2.5;
699  }
700  else {
701  cpl_msg_info(_id,"Using read noise = %g", read_noise);
702  }
703 
704 
705  threshold = read_noise * omega_mbias_config.sigma;
706  cpl_msg_info (_id,"Discarding outliers using threshold %g", threshold);
707 
708 /* Calculate the median of all raw bias */
709 
710  cpl_msg_info (_id,"Computing the median of all images...");
711  median_all = cpl_imagelist_collapse_median_create (ilist);
712 
713  if (median_all == NULL) {
714  cpl_msg_error (_id,"Cannot take median of imagelist <%s>",cpl_error_get_message());
715  freeilist(ilist);
716  return -1;
717  }
718 
719 /* Clip the outliers from the first image*/
720  trim_raw = cpl_imagelist_get (ilist, 0);
721  dev = cpl_image_subtract_create(median_all, trim_raw);
722 
723  good = cpl_mask_threshold_image_create(dev, -threshold, threshold);
724  freeimage(dev);
725 
726  good_int = cpl_image_new_from_mask(good) ;
727  freemask(good) ;
728  good_float = cpl_image_cast(good_int, CPL_TYPE_FLOAT);
729  freeimage(good_int);
730 
731  sum_data = cpl_image_multiply_create(trim_raw, good_float);
732  sum_good = cpl_image_duplicate(good_float);
733 
734  freeimage(good_float);
735 
736 /* Clip the outliers from the remaining images*/
737  for (i=1; i< nbias; i++){
738 
739  trim_raw = cpl_imagelist_get(ilist, i);
740 /* if (trim_raw == NULL)
741  cpl_msg_error("","Image is NULL <%s>",cpl_error_get_message());
742 */
743  dev = cpl_image_subtract_create(median_all, trim_raw);
744 
745  if (dev == NULL) {
746  cpl_msg_error(_id,"Error in subtraction <%s>",cpl_error_get_function());
747  freeilist(ilist);
748  freeimage(median_all);
749  freeimage(sum_data);
750  freeimage(sum_good);
751  return -1;
752  }
753 
754  good = cpl_mask_threshold_image_create (dev, -threshold, threshold);
755 
756  freeimage(dev);
757 
758  good_int = cpl_image_new_from_mask(good) ;
759  freemask(good) ;
760  good_float = cpl_image_cast(good_int, CPL_TYPE_FLOAT);
761  freeimage(good_int);
762 
763  image = cpl_image_multiply_create(trim_raw, good_float);
764  cpl_image_add(sum_data, image);
765 
766  cpl_image_add(sum_good, good_float);
767 
768  freeimage(image);
769  freeimage(good_float);
770  }
771 
772  freeimage(median_all);
773  freeilist(ilist);
774 
775  cpl_image_threshold(sum_good, FLT_EPSILON, FLT_MAX, FLT_EPSILON, FLT_MAX);
776  ps.mbias = cpl_image_divide_create(sum_data, sum_good);
777 
778  if (ps.mbias == NULL) {
779  cpl_msg_error(_id,"Cannot create product. Error in division");
780  freeimage(sum_data);
781  freeimage(sum_good);
782  return -1;
783  }
784 
785  freeimage(sum_data);
786  freeimage(sum_good);
787 
788  /* Compute statistics on the master bias image */
789  ps.stats = cpl_stats_new_from_image(ps.mbias, CPL_STATS_ALL);
790  if(ps.stats != NULL) {
791  omega_mbias_config.Mean = cpl_stats_get_mean(ps.stats);
792  omega_mbias_config.Median = cpl_stats_get_median(ps.stats);
793  omega_mbias_config.Stdev = cpl_stats_get_stdev(ps.stats);
794  cutoff = omega_mbias_config.Mean + omega_mbias_config.rejsig * omega_mbias_config.Stdev;
795  cpl_msg_info(_id,"Using cutoff %g for Hot Pixels Map creation", cutoff);
796  }
797 
798  freestats(ps.stats);
799 
800  /* Create a hot pixels map */
801  pixelmap = cpl_mask_threshold_image_create(ps.mbias, -1e20, cutoff);
802 
803  /*Do an inverse to count the number of CPL_BINARY_1*/
804  cpl_mask_not(pixelmap);
805  omega_mbias_config.CountHotPixels = cpl_mask_count(pixelmap);
806 
807  /*Invert back*/
808  /* cpl_mask_not(pixelmap);*/
809 
810  /* Convert image to INT to save it */
811 
812  ps.hpixels = cpl_image_new_from_mask(pixelmap);
813  freemask(pixelmap);
814 
815  return 0;
816 }
817 
818 /* Initialize the pointers */
819 static void omega_mbias_init(void) {
820  ps.labels = NULL;
821  ps.rnframe = NULL;
822  ps.biaslist = NULL;
823  ps.mbias = NULL;
824  ps.hpixels = NULL;
825  ps.ph = NULL;
826  ps.eh = NULL;
827  ps.stats = NULL;
828  ps.firstbias = NULL;
829 }
830 
831 /* Free any allocated memory */
832 static void omega_mbias_tidy(void) {
833  freespace(ps.labels);
834  freeframeset(ps.biaslist);
835  freeimage(ps.mbias);
836  freeimage(ps.hpixels);
837  freestats(ps.stats);
838  freefits(ps.firstbias);
839 }
840 
int omega_mbias_combine(int xn)
Process the BIAS frames.
Definition: omega_mbias.c:625
int omega_pfits_get_detlive(const cpl_propertylist *plist, int *detlive)
Get the value of DET_LIVE.
Definition: omega_pfits.c:214
void omega_pfits_get_readnoise(cpl_propertylist *plist, double *rn)
Get the read noise value from a header.
Definition: omega_pfits.c:870
void omega_extensions(const cpl_frame *frame, int inexten, int *out1, int *out2)
Definition: omega_utils.c:348
cpl_image * TrimOscanCorrect(const cpl_frame *frame, int oscan, int extn)
This method loads a raw image, trims it and (optionally) performs an overscan correction, using the statistics of the pre and overscan regions. This can be done with a single value for the whole image or on a per-row basis.
Definition: omega_trim.c:87
int omega_compare_tags(const cpl_frame *frame1, const cpl_frame *frame2)
Definition: omega_utils.c:206
int omega_pfits_check_instrume(const cpl_frame *fr)
Check if INSTRUME is WFI or OMEGA.
Definition: omega_pfits.c:785
omega_fits * omega_fits_load(const cpl_frame *inframe, cpl_type type, int extnum)
Definition: omega_fits.c:84
const char * omega_get_license(void)
Get the pipeline copyright and license.
Definition: omega_utils.c:67
cpl_frame * omega_product_frame(const char *filename, const char *tag, cpl_frame_type type)
Setup a frame to save a product.
Definition: omega_utils.c:499
int omega_compare_reference(const cpl_image *master, const cpl_frame *refframe, int ext, cpl_stats **diffstats)
Definition: omega_utils.c:404
cpl_propertylist * omega_fits_get_ehu(omega_fits *p)
Definition: omega_fits.c:489
int cpl_plugin_get_info(cpl_pluginlist *list)
Definition: omega_mbias.c:134
cpl_frameset * omega_frameset_subgroup(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
Definition: omega_utils.c:257
int omega_save_image(const cpl_image *img, cpl_frameset *set, const cpl_parameterlist *pars, cpl_propertylist *alist, const cpl_propertylist *qclist, cpl_type_bpp bpp, const char *name, const char *recipe, cpl_frame *frame, const cpl_frame *inherit, int isfirst)
Save an image as a DFS compliant product.
Definition: omega_utils.c:916