OMEGA Pipeline Reference Manual  1.0.6
omega_darkcurrent.c
1 /* $Id: omega_darkcurrent.c,v 1.5 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.5 $
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_darkcurrent_create(cpl_plugin *) ;
67 static int omega_darkcurrent_exec(cpl_plugin *) ;
68 static int omega_darkcurrent_destroy(cpl_plugin *) ;
69 static int omega_darkcurrent(cpl_frameset *set,cpl_parameterlist *pars) ;
70 
71 /*-----------------------------------------------------------------------------
72  Private Functions
73  -----------------------------------------------------------------------------*/
74 int omega_darkcurrent_combine(cpl_parameterlist *pars, int xn);
75 int omega_darkcurrent_save(cpl_image *image, cpl_frameset *set, cpl_parameterlist *parlist,
76  cpl_propertylist *qclist, cpl_type_bpp bitpix,
77  const char *outfile, cpl_frame *product_frame);
78 static void omega_darkcurrent_init(void);
79 static void omega_darkcurrent_tidy(void);
80 
81 /*-----------------------------------------------------------------------------
82  Static structures
83  -----------------------------------------------------------------------------*/
84 
85 static struct {
86  /* Inputs. Parameters */
87 /* double rej_sig;*/
88  int extnum;
89  int oc;
90  int paf;
91 
92  /* Outputs. QC parameters */
93  double dark_current;
94  double rate;
95 
96 }omega_darkcurrent_config;
97 
98 /* Input and Output */
99 static struct {
100  cpl_size *labels;
101  const cpl_frame *mbframe;
102  cpl_frameset *darklist;
103  omega_fits *firstdark;
104  cpl_propertylist *eh;
105 
106  /* Products */
107  cpl_image *mdark;
108 
109 } ps;
110 
111 
112 /* Static variables */
113 #define RECIPE "omega_darkcurrent"
114 
115 static int isfirst;
116 
117 
118 /*----------------------------------------------------------------------------*/
126 /*----------------------------------------------------------------------------*/
127 int cpl_plugin_get_info(cpl_pluginlist * list)
128 {
129  cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe)) ;
130  cpl_plugin * plugin = &recipe->interface ;
131 
132  cpl_plugin_init(plugin,
133  CPL_PLUGIN_API,
134  OMEGA_BINARY_VERSION,
135  CPL_PLUGIN_TYPE_RECIPE,
136  "omega_darkcurrent",
137  "OMEGA - Measure the dark current and the particle event rate.(Calfile 531).",
138  "The raw dark frames are trimmed, overscan-corrected and"
139  "debiased. The dark current is calculated by median averaging"
140  "three reduced dark frames and iteratively rejecting outliers"
141  "from the result, and computing the mean of the remaining pixels.",
142  "Sandra Castro",
143  "scastro@eso.org",
145  omega_darkcurrent_create,
146  omega_darkcurrent_exec,
147  omega_darkcurrent_destroy) ;
148 
149  cpl_pluginlist_append(list, plugin) ;
150 
151  return 0;
152 }
153 
154 
155 /*----------------------------------------------------------------------------*/
164 /*----------------------------------------------------------------------------*/
165 static int omega_darkcurrent_create(cpl_plugin * plugin)
166 {
167  cpl_recipe * recipe;
168  cpl_parameter * p ;
169  char *path = NULL;
170 
171  /* Do not create the recipe if an error code is already set */
172  if (cpl_error_get_code() != CPL_ERROR_NONE) {
173  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
174  cpl_func, __LINE__, cpl_error_get_where());
175  return (int)cpl_error_get_code();
176  }
177 
178  if (plugin == NULL) {
179  cpl_msg_error(cpl_func, "Null plugin");
180  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
181  }
182 
183  /* Verify plugin type */
184  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
185  cpl_msg_error(cpl_func, "Plugin is not a recipe");
186  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
187  }
188 
189  /* Get the recipe */
190  recipe = (cpl_recipe *)plugin;
191 
192  /* Create the parameters list in the cpl_recipe object */
193  recipe->parameters = cpl_parameterlist_new() ;
194  if (recipe->parameters == NULL) {
195  cpl_msg_error(cpl_func, "Parameter list allocation failed");
196  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
197  }
198 
199  /* Fill the parameters list */
200  p = cpl_parameter_new_value("omega.omega_darkcurrent.ExtensionNumber",
201  CPL_TYPE_INT,
202  "FITS extension number to load (1 to 32). (-1 = all)",
203  "omega_darkcurrent",
204  -1) ;
205 
206  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"ext") ;
207  cpl_parameterlist_append(recipe->parameters, p) ;
208 
209 
210  p = cpl_parameter_new_range("omega.omega_darkcurrent.OverscanMethod",
211  CPL_TYPE_INT,
212  "Overscan Correction Method",
213  "omega_darkcurrent",
214  6, 0, 6);
215  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"oc-meth") ;
216  cpl_parameterlist_append(recipe->parameters, p) ;
217 
218  p = cpl_parameter_new_value("omega.omega_darkcurrent.PAF",
219  CPL_TYPE_BOOL,
220  "Boolean value to create PAF files. 1(Yes), 0(No)",
221  "omega_darkcurrent",
222  1) ;
223 
224  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "paf") ;
225  cpl_parameterlist_append(recipe->parameters, p) ;
226 
227  p = cpl_parameter_new_value("omega.omega_darkcurrent.RejThre",
228  CPL_TYPE_DOUBLE,
229  "The threshold rejecting outlying pixels",
230  "omega_darkcurrent",
231  5.0) ;
232 
233  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"rej-thre") ;
234  cpl_parameterlist_append(recipe->parameters, p) ;
235 
236  p = cpl_parameter_new_value("omega.omega_darkcurrent.DetThre",
237  CPL_TYPE_DOUBLE,
238  "The detection threshold for cosmic ray event ",
239  "omega_darkcurrent",
240  6.0) ;
241 
242  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"det-thre") ;
243  cpl_parameterlist_append(recipe->parameters, p) ;
244 
245 
246  p = cpl_parameter_new_value("omega.omega_darkcurrent.MaxIter",
247  CPL_TYPE_INT,
248  "The maximum number of iterations",
249  "omega_darkcurrent",
250  3) ;
251 
252  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"niter") ;
253  cpl_parameterlist_append(recipe->parameters, p) ;
254 
255  p = cpl_parameter_new_value("omega.omega_darkcurrent.MaxCurrent",
256  CPL_TYPE_DOUBLE,
257  "The maximum dark current in ADU/pixel/hour",
258  "omega_darkcurrent",
259  5.0) ;
260 
261  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "maxcur") ;
262  cpl_parameterlist_append(recipe->parameters, p) ;
263 
264 
265  p = cpl_parameter_new_value("omega.omega_darkcurrent.MaxDiffCurrent",
266  CPL_TYPE_DOUBLE,
267  "The maximum difference of dark current between previous ??",
268  "omega_darkcurrent",
269  0.2) ;
270 
271  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "maxdifcur") ;
272  cpl_parameterlist_append(recipe->parameters, p) ;
273 
274 /* ------------------ Sextractor parameters ------------------------- */
275  path = cpl_sprintf("%s", OMEGA_BIN_PATH);
276  p = cpl_parameter_new_value("omega.omega_darkcurrent.BinPath",
277  CPL_TYPE_STRING,
278  "Path to any external executable program.",
279  "omega.BinPath",
280  path);
281 
282  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "bin-path");
283  cpl_parameterlist_append(recipe->parameters, p);
284  cpl_free(path);
285 
286  path = cpl_sprintf("%s/omega.cosmic.sex", OMEGA_CONFIG_PATH);
287  p = cpl_parameter_new_value("omega.omega_darkcurrent.SexCosmic",
288  CPL_TYPE_STRING,
289  "Path to Sextractor cosmic detection mode config file.",
290  "omega.Sextractor",
291  path);
292 
293  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "sex-cosmic");
294  cpl_parameterlist_append(recipe->parameters, p);
295  cpl_free(path);
296 
297  path = cpl_sprintf("%s/omega.conv", OMEGA_CONFIG_PATH);
298  p = cpl_parameter_new_value("omega.omega_darkcurrent.SexConv",
299  CPL_TYPE_STRING,
300  "Path to Sextractor convolution mask file.",
301  "omega.Sextractor",
302  path);
303 
304  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "sex-conv");
305  cpl_parameterlist_append(recipe->parameters, p);
306  cpl_free(path);
307 
308  path = cpl_sprintf("%s/omega.param", OMEGA_CONFIG_PATH);
309  p = cpl_parameter_new_value("omega.omega_darkcurrent.SexParam",
310  CPL_TYPE_STRING,
311  "Path to Sextractor parameters file.",
312  "omega.Sextractor",
313  path);
314 
315  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"sex-param");
316  cpl_parameterlist_append(recipe->parameters, p);
317  cpl_free(path);
318 
319  path = cpl_sprintf("%s/omega.nnw", OMEGA_CONFIG_PATH);
320  p = cpl_parameter_new_value("omega.omega_darkcurrent.SexNnw",
321  CPL_TYPE_STRING,
322  "Path to Sextractor neural network config file.",
323  "omega.Sextractor",
324  path);
325 
326  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI, "sex-nnw");
327  cpl_parameterlist_append(recipe->parameters, p);
328  cpl_free(path);
329 
330 
331  /* Return */
332  return 0;
333 }
334 
335 /*----------------------------------------------------------------------------*/
341 /*----------------------------------------------------------------------------*/
342 static int omega_darkcurrent_exec(cpl_plugin * plugin)
343 {
344 
345  cpl_recipe * recipe;
346  int recipe_status;
347 
348  /* Return immediately if an error code is already set */
349  if (cpl_error_get_code() != CPL_ERROR_NONE) {
350  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
351  cpl_func, __LINE__, cpl_error_get_where());
352  return (int)cpl_error_get_code();
353  }
354 
355  if (plugin == NULL) {
356  cpl_msg_error(cpl_func, "Null plugin");
357  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
358  }
359 
360  /* Verify plugin type */
361  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
362  cpl_msg_error(cpl_func, "Plugin is not a recipe");
363  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
364  }
365 
366  /* Get the recipe */
367  recipe = (cpl_recipe *)plugin;
368 
369  /* Verify parameter and frame lists */
370  if (recipe->parameters == NULL) {
371  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
372  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
373  }
374  if (recipe->frames == NULL) {
375  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
376  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
377  }
378 
379  /* Invoke the recipe */
380  recipe_status = omega_darkcurrent(recipe->frames, recipe->parameters);
381 
382  /* Ensure DFS-compliance of the products */
383  if (cpl_dfs_update_product_header(recipe->frames)) {
384  if (!recipe_status) recipe_status = (int)cpl_error_get_code();
385  }
386 
387 
388  return recipe_status;
389 }
390 
391 /*----------------------------------------------------------------------------*/
397 /*----------------------------------------------------------------------------*/
398 static int omega_darkcurrent_destroy(cpl_plugin * plugin)
399 {
400  cpl_recipe * recipe;
401 
402  if (plugin == NULL) {
403  cpl_msg_error(cpl_func, "Null plugin");
404  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
405  }
406 
407  /* Verify plugin type */
408  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
409  cpl_msg_error(cpl_func, "Plugin is not a recipe");
410  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
411  }
412 
413  /* Get the recipe */
414  recipe = (cpl_recipe *)plugin;
415 
416  cpl_parameterlist_delete(recipe->parameters);
417 
418  return 0 ;
419 }
420 
421 
422 /*----------------------------------------------------------------------------*/
429 /*----------------------------------------------------------------------------*/
430 static int omega_darkcurrent(cpl_frameset *set, cpl_parameterlist *pars)
431 {
432 
433  int j,jst,jfn;
434  cpl_size nlab;
435  int ndark = 0;
436  int oscan1 = 0;
437  int status = 0;
438  float bias = BIAS;
439  char *outmdark = NULL;
440  const char *_id = "omega_darkcurrent";
441 
442  cpl_parameter *par = NULL;
443  cpl_frame *firstframe = NULL;
444  cpl_frame *prframe_mdark = NULL;
445  cpl_propertylist *qclist = NULL;
446  cpl_propertylist *alist = NULL;
447 
448 
449 
450  /*Start the recipe */
451 
452  if (pars == NULL) {
453  cpl_msg_error (_id, "Parameters list not found");
454  return -1;
455  }
456 
457  if (cpl_frameset_is_empty(set) == 1) {
458  cpl_msg_error (_id, "Frameset not found");
459  return -1;
460  }
461 
462 /* Retrieve input parameters */
463  par = cpl_parameterlist_find(pars, "omega.omega_darkcurrent.ExtensionNumber") ;
464  omega_darkcurrent_config.extnum = cpl_parameter_get_int(par) ;
465 
466  par = cpl_parameterlist_find(pars, "omega.omega_darkcurrent.OverscanMethod") ;
467  omega_darkcurrent_config.oc = cpl_parameter_get_int(par) ;
468 
469  par = cpl_parameterlist_find(pars, "omega.omega_darkcurrent.PAF");
470  omega_darkcurrent_config.paf = cpl_parameter_get_bool(par);
471 
472 
473 
474 /* Identify the RAW and CALIB frames in the input frameset */
475  if (oc_dfs_set_groups(set)) {
476  cpl_msg_error(_id, "Cannot identify RAW and CALIB frames") ;
477  return -1 ;
478  }
479 
480  /*Initialized things*/
481  omega_darkcurrent_init();
482 
483 /* Verify the frameset contents */
484  if ((ps.labels = cpl_frameset_labelise(set,omega_compare_tags,
485  &nlab)) == NULL) {
486  cpl_msg_error(_id,"Cannot labelise the input frameset");
487  omega_darkcurrent_tidy();
488  return -1;
489  }
490  if ((ps.darklist = omega_frameset_subgroup(set,ps.labels,nlab,
491  DARK_RAW)) == NULL) {
492  cpl_msg_error(_id,"Cannot find bias frames in input frameset");
493  omega_darkcurrent_tidy();
494  return -1;
495  }
496 
497  ndark = cpl_frameset_count_tags (set, DARK_RAW);
498  if (ndark < 3) {
499  cpl_msg_error (_id, "Need at least 3 (%s) frames to run this recipe", DARK_RAW);
500  omega_darkcurrent_tidy();
501  return -1;
502  }
503 
504  cpl_msg_info (_id,"There are %d %s frames in frame set",ndark, DARK_RAW);
505 
506  /* Get first frame from frame set */
507  firstframe = cpl_frameset_get_position(ps.darklist, 0) ;
508 
509 
510  /* Check for calibration frames */
511  /* Master Bias */
512  ps.mbframe = cpl_frameset_find_const(set, OMEGA_CALIB_BIAS);
513  if (ps.mbframe == NULL) {
514  cpl_msg_info(_id,"A Master Bias is not present in frame set. Using default value %f", bias);
515  }
516  else{
517  cpl_msg_info(_id,"Using %s %s",OMEGA_CALIB_BIAS, cpl_frame_get_filename(ps.mbframe));
518  }
519 
520  /* Loop for each of the image extensions */
521  omega_exten_range(omega_darkcurrent_config.extnum,&jst,&jfn);
522  if(omega_darkcurrent_config.extnum == 0){
523  cpl_msg_error(cpl_func,"Unsupported extension request, %d",omega_darkcurrent_config.extnum);
524  omega_darkcurrent_tidy();
525  return -1;
526  }
527 
528  /* Create output names for the products */
529  for (j = jst; j <= jfn; j++) {
530 
531  isfirst = (j == jst);
532  cpl_msg_info(_id,"Beginning work on extension %d",j);
533  omega_darkcurrent_config.dark_current = 0.0;
534  omega_darkcurrent_config.rate = 0;
535 
536  /* Check overscan correction method consistency if oc mode == 0*/
537 
538  if(omega_darkcurrent_config.oc==0){
539  if(ps.mbframe != NULL){
540  oscan1 = omega_pfits_get_overscan(ps.mbframe, j);
541  if(oscan1 != omega_darkcurrent_config.oc) {
542  cpl_msg_warning (_id, "Overscan correction mode for Master Bias (oc = %d) differs from "
543  "the one used here (oc = %d)", oscan1, omega_darkcurrent_config.oc);
544  }
545  }
546  }
547 
548  ps.firstdark = omega_fits_load(firstframe,CPL_TYPE_FLOAT,j);
549  ps.eh = omega_fits_get_ehu(ps.firstdark);
550 
551  /* Call the combining routine */
552  status = omega_darkcurrent_combine(pars, j);
553  if(status == 1){
554  cpl_msg_warning(_id, "Image detector is not live");
555  /* Save dummy product */
556  freefits(ps.firstdark);
557  ps.eh = NULL;
558  continue;
559  }
560  else if(status == -1){
561  cpl_msg_error(_id,"Cannot combine images");
562  freespace(outmdark);
563  omega_darkcurrent_tidy();
564  return -1;
565  }
566 
567  status = 0;
568 
569  /* Save the products */
570  /* Save the MEAN DARK product */
571  qclist = cpl_propertylist_new();
572  cpl_propertylist_append_double(qclist, "ESO QC DARK CURRENT",
573  omega_darkcurrent_config.dark_current) ;
574  cpl_propertylist_set_comment(qclist, "ESO QC DARK CURRENT",
575  "Dark current") ;
576  cpl_propertylist_append_double(qclist, "ESO QC PARTICLE RATE",
577  omega_darkcurrent_config.rate) ;
578  cpl_propertylist_set_comment(qclist, "ESO QC PARTICLE RATE",
579  "Value of particle rate" ) ;
580 
581  if(isfirst){
582  outmdark = cpl_sprintf("%s_%s.fits", INSTRUME,DARK_PROCATG);
583  prframe_mdark = omega_product_frame(outmdark, DARK_PROCATG, CPL_FRAME_TYPE_IMAGE);
584  }
585 
586  alist = cpl_propertylist_new();
587  cpl_propertylist_append_string(alist, "EXTNAME",
588  cpl_propertylist_get_string(ps.eh, "EXTNAME"));
589  cpl_propertylist_set_comment(alist,"EXTNAME", "Extension name");
590 
591  cpl_propertylist_copy_property_regexp(alist, ps.eh, WCS_KEYS, 0);
592 
593  if(omega_save_image(ps.mdark,set,pars,alist,qclist,CPL_BPP_IEEE_FLOAT,outmdark,
594  RECIPE,prframe_mdark,NULL,isfirst) == -1){
595  cpl_msg_error(_id,"Cannot save product %s", DARK_PROCATG);
596  freeplist(qclist);
597  freeplist(alist);
598  freespace(outmdark);
599  omega_darkcurrent_tidy();
600  return -1;;
601  }
602 
603  freeplist(qclist);
604  freeplist(alist);
605  freeimage(ps.mdark);
606  freefits(ps.firstdark);
607  ps.firstdark = NULL;
608  ps.eh = NULL;
609 
610  } /* work on next extension */
611 
612 
613  freespace(outmdark);
614  omega_darkcurrent_tidy();
615 
616 
617  return 0;
618 }
619 
620 /*----------------------------------------------------------------------------*/
629 /*----------------------------------------------------------------------------*/
630 int omega_darkcurrent_combine(cpl_parameterlist *pars, int xn)
631 {
632 
633  int count = 0;
634  int i = 0;
635  int maxiter = 0;
636  int ndark = 0;
637  int live = 0;
638  float bias = BIAS;
639  double dethres = 3.0;
640  double exptime = 0.0;
641  double rate = 0.0;
642  double rejt = 5.0;
643  double detector_size_x=1.;
644  double detector_size_y=1.;
645  double detector_size=1.;
646 
647  const char *cmd = NULL;
648  const char *cosmiccat = "OMEGA_cosmicrays.fits";
649  const char *cosmic_conf = NULL;
650  const char *_id = "";
651  const char *path = NULL;
652  const char *sex_conv = NULL;
653  const char *sex_nnw = NULL;
654  const char *sex_par = NULL;
655  const char *temp1739 = "OMEGA_temp001739.fits";
656 
657  const cpl_frame *darkfr = NULL;
658  cpl_image *mbias = NULL, *trim_raw = NULL;
659  cpl_imagelist *ilist = NULL;
660  cpl_stats *stats = NULL;
661  cpl_parameter *par = NULL;
662  cpl_propertylist *mplist = NULL, *xplist = NULL;
663 
664 
665  par = cpl_parameterlist_find(pars, "omega.omega_darkcurrent.MaxIter") ;
666  maxiter = cpl_parameter_get_int(par) ;
667 
668  par = cpl_parameterlist_find(pars, "omega.omega_darkcurrent.RejThre") ;
669  rejt = cpl_parameter_get_double(par) ;
670 
671  par = cpl_parameterlist_find(pars, "omega.omega_darkcurrent.DetThre") ;
672  dethres = cpl_parameter_get_double(par) ;
673 
674  par = cpl_parameterlist_find(pars, "omega.omega_darkcurrent.BinPath");
675  path = cpl_parameter_get_string(par) ;
676 
677  par = cpl_parameterlist_find(pars,"omega.omega_darkcurrent.SexCosmic" );
678  cosmic_conf = cpl_parameter_get_string(par) ;
679 
680  par = cpl_parameterlist_find(pars,"omega.omega_darkcurrent.SexConv" );
681  sex_conv = cpl_parameter_get_string(par) ;
682 
683  par = cpl_parameterlist_find(pars,"omega.omega_darkcurrent.SexParam" );
684  sex_par = cpl_parameter_get_string(par) ;
685 
686  par = cpl_parameterlist_find(pars,"omega.omega_darkcurrent.SexNnw" );
687  sex_nnw = cpl_parameter_get_string(par) ;
688 
689 
690  /* Check that this detector is live*/
691  omega_pfits_get_detlive(ps.eh,&live);
692  if (! live) {
693  return 1;
694  }
695 
696  /* Load master bias image */
697  if(ps.mbframe != NULL){
698  mbias = cpl_image_load(cpl_frame_get_filename(ps.mbframe), CPL_TYPE_FLOAT,0,xn);
699  if (mbias == NULL) {
700  cpl_msg_warning(_id,"Cannot load image %s", OMEGA_CALIB_BIAS);
701  }
702  }
703 
704  ilist = cpl_imagelist_new();
705  cpl_msg_info (_id,"Doing trim and overscan correction on images");
706 
707  /* Loop through all images in frame list */
708  /* Loop through raw dark list and trim each image*/
709 
710  ndark = cpl_frameset_get_size(ps.darklist);
711 
712  for (i=0; i< ndark; i++)
713  {
714  darkfr = cpl_frameset_get_position(ps.darklist, i);
715  if (darkfr == NULL)
716  break;
717  trim_raw = TrimOscanCorrect(darkfr, omega_darkcurrent_config.oc, xn);
718  if(trim_raw == NULL){
719  cpl_msg_error(_id,"Cannot trim image");
720  freeilist(ilist);
721  return -1;
722  }
723 
724  if(omega_darkcurrent_config.oc==0){
725  if (mbias != NULL){
726  cpl_msg_info(cpl_func,"Subtracting bias frame");
727  cpl_image_subtract(trim_raw, mbias);
728  }
729  else
730  cpl_image_subtract_scalar(trim_raw, bias);
731  }
732 
733  cpl_imagelist_set(ilist, trim_raw, i);
734  }
735 
736  freeimage(mbias);
737  if (ilist == NULL) {
738  cpl_msg_error(_id,"Error in image list <%s>",cpl_error_get_message());
739  freeimage(trim_raw);
740  return -1;
741  }
742 
743  cpl_msg_info (_id,"Computing the median of all images...");
744  ps.mdark = cpl_imagelist_collapse_median_create(ilist);
745 
746  if (ps.mdark == NULL) {
747  cpl_msg_error (_id,"Cannot take median of list <%s>",cpl_error_get_message());
748  freeilist(ilist);
749  return -1;
750  }
751 
752  cpl_msg_info(_id,"Estimating the RMS using %d maximum iterations",maxiter);
753  cpl_msg_info(_id,"Rejection threshold is %g (sigma)",rejt);
754 
755 
756  /*Calculate statistics iteratively*/
757  stats = omega_iter_stat(ps.mdark,rejt,maxiter);
758  if(stats == NULL){
759  cpl_msg_warning(_id,"Cannot calculate statistics iteratively");
760  }
761 
762  darkfr = cpl_frameset_get_position(ps.darklist, 0) ;
763  mplist = cpl_propertylist_load_regexp(cpl_frame_get_filename(darkfr), 0, "EXPTIME", 0);
764  xplist = cpl_propertylist_load_regexp(cpl_frame_get_filename(darkfr), xn, "EXPTIME", 0);
765  exptime = omega_pfits_get_exptime(xplist);
766  if (exptime == 0.0){
767  exptime = omega_pfits_get_exptime(mplist);
768  }
769 
770  omega_darkcurrent_config.dark_current = cpl_stats_get_mean(stats) / exptime*3600.0;
771  freeplist(mplist);
772  freeplist(xplist);
773 
774  freestats(stats);
775 
776  /*Calculate the particle event rate*/
777  rate = 0.0;
778  for(i=0; i < ndark; i++){
779 
780  cpl_image_save(cpl_imagelist_get(ilist, i),temp1739,BITPIX,NULL,CPL_IO_DEFAULT);
781 
782  /*
783  * Run Sextractor on a cosmic detection mode
784  */
785 
786  cmd = cpl_sprintf("%s/sex %s -c %s -PARAMETERS_NAME %s -FILTER_NAME %s -STARNNW_NAME %s "
787  "-DETECT_THRESH %g "
788  "-CHECKIMAGE_NAME chkimage.fits "
789  "-CATALOG_TYPE FITS_1.0 "
790  "-CATALOG_NAME %s",
791  path,
792  temp1739,
793  cosmic_conf,
794  sex_par,
795  sex_conv,
796  sex_nnw,
797  dethres,
798  cosmiccat);
799 
800  if (system(cmd) != 0) {
801  cpl_free((char *)cmd);
802  freeilist(ilist);
803  cpl_msg_error("","%s Failed to run Sextractor", _id);
804  return -1;
805  }
806 
807  cpl_free((char *)cmd);
808 
809  mplist = cpl_propertylist_load_regexp(cosmiccat, 1, "NAXIS2", 0);
810  if(mplist == NULL){
811  cpl_msg_error(_id,"Cannot load header for %s",cosmiccat);
812  freeilist(ilist);
813  return -1;
814  }
815 
816  count = cpl_propertylist_get_int(mplist,"NAXIS2");
817  /* cpl_msg_info(_id,"Detected %d cosmic ray events",count);*/
818 
819  rate += count;
820  freeplist(mplist);
821  }
822  /*Detector size in cm^2 assuming 15mue/pixel */
823 
824  detector_size_x=cpl_image_get_size_x(cpl_imagelist_get(ilist,0));
825  detector_size_y=cpl_image_get_size_y(cpl_imagelist_get(ilist,0));
826  detector_size=detector_size_x * detector_size_y * 0.0015 * 0.0015;
827 
828  rate = rate/ndark;
829  rate = rate/exptime*3600.0;
830  if(detector_size>0){
831  rate = rate/detector_size;
832  }
833  omega_darkcurrent_config.rate = rate;
834 
835  freeilist(ilist);
836 
837 
838  return 0;
839 }
840 
854 /*----------------------------------------------------------------------------*/
869 int omega_darkcurrent_save(cpl_image *image, cpl_frameset *set, cpl_parameterlist *parlist,
870  cpl_propertylist *qclist, cpl_type_bpp bitpix,
871  const char *outfile, cpl_frame *product_frame)
872 
873 {
874 
875  const char *fctid = "omega_darkcurrent_save";
876  cpl_propertylist *plist = NULL;
877 
878  /* If it is the first time, setup initial frame */
879  if (isfirst) {
880 
881  /* Create a new product frame object and define some tags */
882  plist = cpl_propertylist_new();
883 
884  /* Add DataFlow keywords in primary header */
885  if (cpl_dfs_setup_product_header(plist, product_frame, set, parlist,
886  RECIPE,PIPEID,DICID,NULL) != CPL_ERROR_NONE) {
887 
888  cpl_msg_warning(fctid, "Problem in the main header of product DFS-compliance") ;
889  }
890 
891  /* Once CPL recalculates these values, the following
892  * line should be removed
893  */
894  cpl_propertylist_erase_regexp(plist,REM_PRIM_KEYS,0);
895 
896  /* Save the empty primary unit */
897  if (cpl_propertylist_save(plist,outfile,CPL_IO_DEFAULT) != CPL_ERROR_NONE){
898  cpl_msg_error(fctid,"Cannot save product PHU");
899  freeplist(plist);
900  return 1;
901  }
902 
903  freeplist(plist);
904  cpl_frameset_insert(set,product_frame);
905  }
906 
907  /* Setup the extension */
908  plist = cpl_propertylist_duplicate(ps.eh);
909 
910 
911  /* Add DRS keywords */
912  cpl_propertylist_append_int(plist, "ESO DRS OVERSCAN METHOD", omega_darkcurrent_config.oc);
913  cpl_propertylist_set_comment(plist, "ESO DRS OVERSCAN METHOD", "overscan correction method");
914 
915  /* Add DataFlow keywords in extension header */
916  if (cpl_dfs_setup_product_header(plist, product_frame, set, parlist,
917  RECIPE,PIPEID,DICID,NULL) != CPL_ERROR_NONE) {
918 
919  cpl_msg_warning(fctid, "Problem in the extension header of product DFS-compliance") ;
920  }
921 
922  /*Remove undesired keywords from extension header*/
923  cpl_propertylist_erase_regexp(plist, REM_EXT_KEYS, 0);
924 
925 
926  /* Append QC list to the extension header */
927  cpl_propertylist_append(plist, qclist);
928 
929  /* Save the product */
930  if (cpl_image_save(image,outfile,bitpix,plist,
931  CPL_IO_EXTEND) != CPL_ERROR_NONE) {
932  cpl_msg_error(fctid,"Cannot save product. %s", cpl_error_get_message());
933  freeplist(plist);
934  return -1;
935  }
936 
937 
938  /* Save the paf file */
939  if(omega_darkcurrent_config.paf){
940  int xtnum = omega_fits_get_extnum(ps.firstdark);
941  char *prefix = omega_get_root_name(outfile);
942  char *outpaf = cpl_sprintf("%s_%d.paf",prefix,xtnum);
943  const char pafcopy[] = "^(DATE-OBS|ARCFILE|ESO TPL ID|ESO DET WIN1 DIT1|MJD-OBS|EXTNAME|ESO PRO CATG)$";
944  cpl_frame *fframe = cpl_frameset_get_position(set, 0) ;
945  cpl_propertylist *mlist = cpl_propertylist_load_regexp(cpl_frame_get_filename(fframe),0,pafcopy, 0);
946  cpl_propertylist_copy_property_regexp(qclist, mlist, pafcopy, 0);
947  if (cpl_propertylist_copy_property_regexp(qclist, plist,
948  pafcopy, 0) != CPL_ERROR_NONE){
949 
950  cpl_msg_warning(fctid,"Some mandatory keywords are missing in PAF file");
951  }
952 
953  cpl_dfs_save_paf(INSTRUME, RECIPE, qclist, outpaf);
954  cpl_free(outpaf);
955  freeplist(mlist);
956  }
957 
958  freeplist(plist);
959 
960  return 0;
961 }
962 
963 /* Initialize the pointers */
964 static void omega_darkcurrent_init(void) {
965  ps.labels = NULL;
966  ps.darklist = NULL;
967  ps.mdark = NULL;
968  ps.mbframe = NULL;
969  ps.eh = NULL;
970  ps.firstdark = NULL;
971 }
972 
973 /* Free any allocated memory */
974 static void omega_darkcurrent_tidy(void) {
975  freespace(ps.labels);
976  freeframeset(ps.darklist);
977  freeimage(ps.mdark);
978  freefits(ps.firstdark);
979 }
980 
int omega_pfits_get_overscan(const cpl_frame *frame, int xn)
Get the DRS keyword of the overscan method used to reduce the image.
Definition: omega_pfits.c:912
double omega_pfits_get_exptime(const cpl_propertylist *plist)
Get the EXPTIME value.
Definition: omega_pfits.c:193
cpl_stats * omega_iter_stat(cpl_image *img, double threshold, int iter)
Compute statistics of an image iteratively.
Definition: omega_stats.c:83
int omega_pfits_get_detlive(const cpl_propertylist *plist, int *detlive)
Get the value of DET_LIVE.
Definition: omega_pfits.c:214
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
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_darkcurrent_combine(cpl_parameterlist *pars, int xn)
Trim and combine input images.
int omega_compare_tags(const cpl_frame *frame1, const cpl_frame *frame2)
Definition: omega_utils.c:206
omega_fits * omega_fits_load(const cpl_frame *inframe, cpl_type type, int extnum)
Definition: omega_fits.c:84
int omega_fits_get_extnum(omega_fits *p)
Definition: omega_fits.c:414
const char * omega_get_license(void)
Get the pipeline copyright and license.
Definition: omega_utils.c:67
void omega_exten_range(int inexten, int *out1, int *out2)
Definition: omega_utils.c:305
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
char * omega_get_root_name(const char *filename)
Find out the root part of a basename (name without extension).
Definition: omega_utils.c:158
cpl_propertylist * omega_fits_get_ehu(omega_fits *p)
Definition: omega_fits.c:489
cpl_frameset * omega_frameset_subgroup(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
Definition: omega_utils.c:257
int omega_darkcurrent_save(cpl_image *image, cpl_frameset *set, cpl_parameterlist *parlist, cpl_propertylist *qclist, cpl_type_bpp bitpix, const char *outfile, cpl_frame *product_frame)
Save the omega_darkcurrent recipe products on disk.
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