UVES Pipeline Reference Manual  5.5.5b2
uves_mdark_impl.c
1 /* *
2  * This file is part of the ESO UVES Pipeline *
3  * Copyright (C) 2004,2005 European Southern Observatory *
4  * *
5  * This library is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the Free Software *
17  * Foundation, 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA *
18  */
19 
20 /*
21  * $Author: amodigli $
22  * $Date: 2011-01-03 08:39:09 $
23  * $Revision: 1.53 $
24  * $Name: not supported by cvs2svn $
25  *
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31 
32 /*----------------------------------------------------------------------------*/
39 /*----------------------------------------------------------------------------*/
40 
41 /*-----------------------------------------------------------------------------
42  Includes
43  -----------------------------------------------------------------------------*/
44 #include <uves_mdark_impl.h>
45 
46 #include <uves_parameters.h>
47 #include <uves_utils.h>
48 #include <uves.h>
49 #include <uves_dfs.h>
50 #include <uves_pfits.h>
51 #include <uves_qclog.h>
52 #include <uves_recipe.h>
53 #include <uves_utils_wrappers.h>
54 #include <uves_error.h>
55 #include <uves_globals.h>
56 
57 #include <cpl.h>
58 #include <float.h>
59 #include <string.h>
60 /*-----------------------------------------------------------------------------
61  Functions prototypes
62  -----------------------------------------------------------------------------*/
63 /*
64 static int
65 uves_qcdark_define_parameters_body(cpl_parameterlist *parameters,
66  const char *recipe_id);
67 */
68 static int
69 uves_mdark_define_parameters(cpl_parameterlist *parameters);
70 
71 static void uves_mdark_region_qc(cpl_image* img,
72  const cpl_parameterlist* p,
73  const cpl_imagelist* raw_images,
74  const char* recipe_id,
75  cpl_table* qclog);
76 static cpl_image *
77 uves_mdark_process_chip(const cpl_imagelist *raw_images,
78  uves_propertylist **raw_headers,
79  const cpl_image *master_bias,
80  uves_propertylist *mdark_header,
81  const cpl_parameterlist *parameters,
82  const char* recipe_id,
83  cpl_table* qclog, const int do_qc);
84 
85 
86 /*-----------------------------------------------------------------------------
87  Recipe standard code
88  -----------------------------------------------------------------------------*/
89 #define cpl_plugin_get_info uves_mdark_get_info
90 UVES_RECIPE_DEFINE(
91  UVES_MDARK_ID, UVES_MDARK_DOM,
92  /* Warning: if more parameters are added to this recipe, they
93  need to be propagated to uves_cal_mkmaster! */
94  uves_mdark_define_parameters,
95  "Jonas M. Larsen", "cpl@eso.org",
96  "Creates the master dark frame",
97  "This recipe creates a master dark frame by taking the median of all\n"
98  "input frames which should have identical exposure times. Symbolically,\n"
99  " masterdark = median( dark_i ) - masterbias\n"
100  "\n"
101  "The input dark frames must have same tag and size and must be either\n"
102  "(P)DARK_BLUE or (P)DARK_RED. Also, a master bias (MASTER_BIAS_xxxx) must\n"
103  "be provided for each chip (xxxx = BLUE, REDL, REDU).\n"
104  "\n"
105  "On blue input the recipe computes one master dark frame; on red input the\n"
106  "recipe produces a master dark frame for each chip (MASTER_(P)DARK_xxxx).\n");
107 
109 /*-----------------------------------------------------------------------------
110  Functions code
111  -----------------------------------------------------------------------------*/
112 
113 
114 
115 /*----------------------------------------------------------------------------*/
121 /*----------------------------------------------------------------------------*/
122 static cpl_error_code
123 uves_extract_basic_parameters_for_qc(const cpl_parameterlist* p,
124  const char* recipe_id,
125  int * pr_num_x,
126  int* pr_num_y,
127  int* pr_box_sx,
128  int* pr_box_sy)
129 {
130 
131  char name[MAX_NAME_SIZE];
132  char pname[MAX_NAME_SIZE];
133 
134  sprintf(name,"reg.num_x");
135  sprintf(pname,"%s.%s", UVES_QCDARK_ID, name);
136  uves_msg("pname=%s",pname);
137  check(uves_get_parameter(p,NULL,recipe_id,pname,CPL_TYPE_INT,pr_num_x),
138  "Could not read parameter");
139 
140  sprintf(name,"reg.num_y");
141  sprintf(pname,"%s.%s", UVES_QCDARK_ID, name);
142  check(uves_get_parameter(p,NULL,recipe_id,pname,CPL_TYPE_INT,pr_num_y),
143  "Could not read parameter");
144 
145  sprintf(name,"reg.box_sx");
146  sprintf(pname,"%s.%s", UVES_QCDARK_ID, name);
147  check(uves_get_parameter(p,NULL,recipe_id,pname,CPL_TYPE_INT,pr_box_sx),
148  "Could not read parameter");
149 
150  sprintf(name,"reg.box_sy");
151  sprintf(pname,"%s.%s", UVES_QCDARK_ID, name);
152  check(uves_get_parameter(p,NULL,recipe_id,pname,CPL_TYPE_INT,pr_box_sy),
153  "Could not read parameter");
154 
155  cleanup:
156  return cpl_error_get_code();
157 
158 }
159 
160 
161 
162 
163 
164 
165 /*----------------------------------------------------------------------------*/
171 /*----------------------------------------------------------------------------*/
172 static int
173 uves_mdark_define_parameters(cpl_parameterlist *parameters)
174 {
175  if (uves_master_stack_define_parameters(parameters,
176  make_str(UVES_MDARK_ID))
177  != CPL_ERROR_NONE)
178  {
179  return -1;
180  }
181 
182  return uves_qcdark_define_parameters_body(parameters,
183  make_str(UVES_MDARK_ID));
184 }
185 
186 /*----------------------------------------------------------------------------*/
193 /*----------------------------------------------------------------------------*/
194 int
195 uves_qcdark_define_parameters_body(cpl_parameterlist *parameters,
196  const char *recipe_id)
197 {
198  /*****************
199  * General *
200  *****************/
201  if (uves_define_global_parameters(parameters) != CPL_ERROR_NONE)
202  {
203  return -1;
204  }
205 
206  if (uves_master_stack_define_parameters(parameters,recipe_id)
207  != CPL_ERROR_NONE)
208  {
209  return -1;
210  }
211 
212 
213  /****************************
214  * Spline back.sub. *
215  ****************************/
216 
217  if (uves_propagate_parameters_step(UVES_QCDARK_ID, parameters,
218  recipe_id, NULL) != 0)
219  {
220  return -1;
221  }
222 
223  return (cpl_error_get_code() != CPL_ERROR_NONE);
224 }
225 
226 
227 
228 /*----------------------------------------------------------------------------*/
237 /*----------------------------------------------------------------------------*/
238 cpl_error_code
239 uves_mdark_define_qc_parameters(cpl_parameterlist* parameters)
240 {
241 
242 
243 
244 
245 
246  {
247 
248  const char* name = "reg.num_x";
249  char* full_name = uves_sprintf("%s.%s", UVES_QCDARK_ID, name);
250  cpl_parameter *p = NULL;
251  uves_parameter_new_range(p, full_name,
252  CPL_TYPE_INT,
253  "Number of regions along the X axis "
254  "(where mean/med/rms are computed). ",
255  UVES_QCDARK_ID,
256  4,0,INT_MAX);
257 
258  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name );
259  cpl_parameterlist_append(parameters, p);
260  cpl_free(full_name);
261 
262 
263 
264  name = "reg.num_y";
265  full_name = uves_sprintf("%s.%s", UVES_QCDARK_ID,name);
266  uves_parameter_new_range(p, full_name,
267  CPL_TYPE_INT,
268  "Number of regions along the Y axis"
269  "(where mean/med/rms are computed). ",
270  UVES_QCDARK_ID,
271  4,0,INT_MAX);
272 
273  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
274  cpl_parameterlist_append(parameters, p);
275  cpl_free(full_name);
276 
277 
278 
279  name = "reg.box_sx";
280  full_name = uves_sprintf("%s.%s", UVES_QCDARK_ID,name);
281  uves_parameter_new_range(p, full_name,
282  CPL_TYPE_INT,
283  "Region X size [pix]",
284  UVES_QCDARK_ID,
285  100,0,INT_MAX);
286  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
287  cpl_parameterlist_append(parameters, p);
288  cpl_free(full_name);
289 
290 
291  name = "reg.box_sy";
292  full_name = uves_sprintf("%s.%s", UVES_QCDARK_ID,name);
293  uves_parameter_new_range(p, full_name,
294  CPL_TYPE_INT,
295  "Region Y size [pix]",
296  UVES_QCDARK_ID,
297  100,0,INT_MAX);
298  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
299  cpl_parameterlist_append(parameters, p);
300  cpl_free(full_name);
301 
302  name = "reg.border_x";
303  full_name = uves_sprintf("%s.%s", UVES_QCDARK_ID,name);
304  uves_parameter_new_range(p, full_name,
305  CPL_TYPE_INT,
306  "X distance between the left hand side "
307  "of the detector and the left hand side "
308  "of the region [pix]",
309  UVES_QCDARK_ID,
310  100,0,INT_MAX);
311  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
312  cpl_parameterlist_append(parameters, p);
313  cpl_free(full_name);
314 
315 
316  name = "reg.border_y";
317  full_name = uves_sprintf("%s.%s", UVES_QCDARK_ID,name);
318  uves_parameter_new_range(p, full_name,
319  CPL_TYPE_INT,
320  "X distance between the left hand side "
321  "of the detector and the left hand side "
322  "of the region [pix]",
323  UVES_QCDARK_ID,
324  100,0,INT_MAX);
325  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
326  cpl_parameterlist_append(parameters, p);
327  cpl_free(full_name);
328 
329 
330 
331  name = "reg.when";
332  full_name = uves_sprintf("%s.%s", UVES_QCDARK_ID,name);
333  uves_parameter_new_enum(p, full_name,
334  CPL_TYPE_INT,
335  "When QC analysis is performed. "
336  "0: on each raw frame or "
337  "1: on the master frame",
338  UVES_QCDARK_ID,
339  0,2,0,1);
340  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
341  cpl_parameterlist_append(parameters, p);
342  cpl_free(full_name);
343 
344 
345  }
346 
347  if (cpl_error_get_code() != CPL_ERROR_NONE)
348  {
349  cpl_msg_error(__func__, "Creation of mdark parameters failed: '%s'",
350  cpl_error_get_where());
351  cpl_parameterlist_delete(parameters);
352  }
353  return cpl_error_get_code();
354 }
355 
356 
357 /*----------------------------------------------------------------------------*/
365 /*----------------------------------------------------------------------------*/
366 cpl_parameterlist *
367 uves_qcdark_define_parameters(void)
368 {
369 
370  cpl_parameterlist *parameters = NULL;
371 
372  parameters = cpl_parameterlist_new();
373 
374  check(uves_mdark_define_qc_parameters(parameters),
375  "Error defining mdark qc parameters");
376 
377 
378  cleanup:
379  if (cpl_error_get_code() != CPL_ERROR_NONE)
380  {
381  cpl_msg_error(__func__, "Creation of mdark parameters failed: '%s'",
382  cpl_error_get_where());
383  cpl_parameterlist_delete(parameters);
384  return NULL;
385  } else {
386  return parameters;
387  }
388 }
389 
390 
391 
392 
393 
394 /*----------------------------------------------------------------------------*/
414 /*----------------------------------------------------------------------------*/
415 static cpl_image *
416 uves_mdark_process_chip(const cpl_imagelist *raw_images,
417  uves_propertylist **raw_headers,
418  const cpl_image *master_bias,
419  uves_propertylist *mdark_header,
420  const cpl_parameterlist *parameters,
421  const char* recipe_id,
422  cpl_table* qclog,const int do_qc)
423 {
424  cpl_image *master_dark = NULL; /* Result */
425  cpl_image *current_dark = NULL;
426  cpl_imagelist *preproc_images = NULL;
427  double min_exptime = 0;
428  double max_exptime = 0;
429  int i;
430  //char name[MAX_NAME_SIZE];
431  //char pname[MAX_NAME_SIZE];
432 
433  int pr_num_x=4;
434  int pr_num_y=4;
435  int pr_box_sx=100;
436  int pr_box_sy=100;
437  const char* STACK_METHOD=NULL;
438  double STACK_KLOW=0;
439  double STACK_KHIGH=0;
440  int STACK_NITER=0;
441 
442 /* check critical QC parameters to see if QC need to be computed or not */
443 
444  check_nomsg(uves_extract_basic_parameters_for_qc(parameters,recipe_id,
445  &pr_num_x,&pr_num_y,
446  &pr_box_sx,&pr_box_sy));
447 
448 /* parameters for stacking */
449  check( uves_get_parameter(parameters, NULL, recipe_id, "stack_method", CPL_TYPE_STRING, &STACK_METHOD),
450  "Could not read parameter");
451 
452  uves_string_toupper((char*)STACK_METHOD);
453 
454  check( uves_get_parameter(parameters, NULL, recipe_id, "klow", CPL_TYPE_DOUBLE, &STACK_KLOW),
455  "Could not read parameter");
456  check( uves_get_parameter(parameters, NULL, recipe_id, "khigh", CPL_TYPE_DOUBLE, &STACK_KHIGH),
457  "Could not read parameter");
458  check( uves_get_parameter(parameters, NULL, recipe_id, "niter", CPL_TYPE_INT, &STACK_NITER),
459  "Could not read parameter");
460 
461 
462 
463  /* First process each input image and store the results in a
464  new image list */
465 
466  preproc_images = cpl_imagelist_new();
467  for (i = 0; i < cpl_imagelist_get_size(raw_images); i++)
468  {
469  double exposure_time = 0.0;
470  const uves_propertylist *current_header;
471 
472  current_dark = cpl_image_duplicate(cpl_imagelist_get_const(raw_images, i));
473  current_header = raw_headers[i];
474 
475  /* Subtract master bias */
476  if (master_bias != NULL)
477  {
478  uves_msg("Subtracting master bias");
479  check( uves_subtract_bias(current_dark, master_bias),
480  "Error subtracting master bias");
481 
482  if (false) {
483  uves_msg_debug("Thresholding to non-negative values");
484  check( cpl_image_threshold(current_dark,
485  0, DBL_MAX, /* Interval */
486  0, DBL_MAX), /* New values */
487  "Error thresholding image");
488  }
489  }
490  else
491  {
492  uves_msg("Skipping bias subtraction");
493  }
494 
495  check( exposure_time = uves_pfits_get_exptime(current_header),
496  "Error reading exposure time");
497 
498  if(pr_num_x != 0 && pr_num_y != 0 && pr_box_sx != 0 && pr_box_sy !=0 ) {
499  if(do_qc == 0) {
500  uves_msg("Calculating QC parameters on raw dark frame %d",i);
501  uves_mdark_region_qc(current_dark,parameters,raw_images,recipe_id,qclog);
502  }
503 
504  }
505  /* Initialize/update min/max exposure time*/
506  if (i == 0 || exposure_time < min_exptime)
507  {
508  min_exptime = exposure_time;
509  }
510  if (i == 0 || exposure_time > max_exptime)
511  {
512  max_exptime = exposure_time;
513  }
514 
515  /* Do not normalize to unit exposure time */
516 /* If this is uncommented, then remember to also calculate the
517  correct master dark exposure time below.
518  uves_msg("Normalizing from %f s to unit exposure time", exposure_time);
519  check( cpl_image_divide_scalar(current_dark, exposure_time),
520  "Error normalizing dark frame"); */
521 
522  /* Append to imagelist */
523  check( cpl_imagelist_set(preproc_images,
524  current_dark,
525  i), /* Position (number_of_images=>append) */
526  "Could not insert image into image list");
527 
528  /* Don't deallocate the image. It will be deallocated when
529  the image list is deallocated */
530  current_dark = NULL;
531  }
532 
533  /* Check exposure times */
534  uves_msg("Exposure times range from %e s to %e s (%e %% variation)",
535  min_exptime,
536  max_exptime,
537  100 * (max_exptime - min_exptime) / min_exptime);
538 
539  if ((max_exptime - min_exptime) / min_exptime > .001)
540  {
541  uves_msg_warning("Exposure times differ by %e %%",
542  100 * (max_exptime - min_exptime) / min_exptime);
543  }
544 
545  /* Get median stack of input darks */
546  if(strcmp(STACK_METHOD,"MEDIAN")==0) {
547  uves_msg("Calculating stack median");
548  check( master_dark = cpl_imagelist_collapse_median_create(preproc_images),
549  "Error computing median");
550  } else {
551  uves_msg("Calculating stack mean");
552  check( master_dark = uves_ksigma_stack(preproc_images,STACK_KLOW,
553  STACK_KHIGH,STACK_NITER),
554  "Error computing master dark");
555 
556  }
557  check( uves_pfits_set_exptime(mdark_header, (max_exptime + min_exptime)/2),
558  "Error setting master dark exposure time");
559  uves_pfits_set_extname(mdark_header,"Master dark");
560 
561  cleanup:
562  uves_free_image(&current_dark);
563  uves_free_imagelist(&preproc_images);
564  if (cpl_error_get_code() != CPL_ERROR_NONE)
565  {
566  uves_free_image(&master_dark);
567  }
568 
569  return master_dark;
570 }
571 
572 
573 /*----------------------------------------------------------------------------*/
580 /*----------------------------------------------------------------------------*/
581 static void
582 UVES_CONCAT2X(UVES_MDARK_ID,exe)(cpl_frameset *frames,
583  const cpl_parameterlist *parameters,
584  const char *starttime)
585 {
586  uves_mdark_exe_body(frames, parameters, starttime, make_str(UVES_MDARK_ID));
587  return;
588 }
589 
590 /*----------------------------------------------------------------------------*/
602 /*----------------------------------------------------------------------------*/
603 void
604 uves_mdark_exe_body(cpl_frameset *frames,
605  const cpl_parameterlist *parameters,
606  const char *starttime,
607  const char *recipe_id)
608 {
609  /* Function id */
610  /*
611  * Variables that will contain the values of the recipe parameters
612  */
613  /* None */
614 
615  /* CPL objects */
616  /* Input */
617  cpl_imagelist *raw_images[2] = {NULL, NULL};
618  uves_propertylist **raw_headers[2] = {NULL, NULL}; /* Two arrays of pointers */
619 
620  /* Master bias */
621  cpl_image *master_bias = NULL;
622  uves_propertylist *master_bias_header = NULL;
623 
624  /* Output */
625  cpl_table* qclog[2] = {NULL, NULL};
626  cpl_image *master_dark = NULL;
627  uves_propertylist *product_header[2] = {NULL, NULL};
628 
629  /* Local variables */
630  char *product_filename = NULL;
631  const char *product_tag[2] = {NULL, NULL};
632  bool blue;
633  enum uves_chip chip;
634 
635  const char* pname=NULL;
636 
637 
638  int pr_when=0;
639  const char* PROCESS_CHIP=NULL;
640  int pr_num_x=0;
641  int pr_num_y=0;
642  int pr_box_sx=0;
643  int pr_box_sy=0;
644  bool dump_qc=true;
645 
646  /* Load and check raw dark images and headers, identify arm (blue/red) */
647  /* On success, 'raw_headers' will be an array with the same size as 'raw_images' */
648  if (cpl_frameset_find(frames, UVES_DARK(true )) != NULL ||
649  cpl_frameset_find(frames, UVES_DARK(false)) != NULL)
650  {
651  check( uves_load_raw_imagelist(frames,
652  false, /* FLAMES format? */
653  UVES_DARK(true), UVES_DARK(false),
654  CPL_TYPE_DOUBLE,
655  raw_images, raw_headers, product_header,
656  &blue), "Error loading raw dark frames");
657 
658  for (chip = uves_chip_get_first(blue);
659  chip != UVES_CHIP_INVALID;
660  chip = uves_chip_get_next(chip))
661  {
662  product_tag[uves_chip_get_index(chip)] = UVES_MASTER_DARK(chip);
663  }
664  }
665  else if (cpl_frameset_find(frames, UVES_PDARK(true )) != NULL ||
666  cpl_frameset_find(frames, UVES_PDARK(false)) != NULL)
667  {
668  check( uves_load_raw_imagelist(frames,
669  false, /* FLAMES format? */
670  UVES_PDARK(true), UVES_PDARK(false),
671  CPL_TYPE_DOUBLE,
672  raw_images, raw_headers, product_header,
673  &blue), "Error loading raw dark frames");
674 
675  for (chip = uves_chip_get_first(blue);
676  chip != UVES_CHIP_INVALID;
677  chip = uves_chip_get_next(chip))
678  {
679  product_tag[uves_chip_get_index(chip)] = UVES_MASTER_PDARK(chip);
680  }
681  }
682  else
683  {
684  assure(false, CPL_ERROR_DATA_NOT_FOUND,
685  "Missing input dark frame: %s, %s, %s or %s expected",
686  UVES_DARK(true) , UVES_DARK(false),
687  UVES_PDARK(true), UVES_PDARK(false));
688  }
689 
690 
691 
692  check_nomsg(uves_extract_basic_parameters_for_qc(parameters,recipe_id,
693  &pr_num_x,&pr_num_y,
694  &pr_box_sx,&pr_box_sy));
695 
696  if(pr_num_x <=0 || pr_num_y <= 0 || pr_box_sx <=0 || pr_box_sy <= 0) {
697  dump_qc=false;
698  }
699  pname = uves_sprintf("%s.%s", UVES_QCDARK_ID, "reg.when");
700  check(uves_get_parameter(parameters,NULL,recipe_id,pname,CPL_TYPE_INT,&pr_when),
701  "Could not read parameter");
702 
703  check( uves_get_parameter(parameters, NULL, "uves", "process_chip", CPL_TYPE_STRING, &PROCESS_CHIP),
704  "Could not read parameter");
705  uves_string_toupper((char*)PROCESS_CHIP);
706 
707 
708  /* Loop over one or two chips */
709  for (chip = uves_chip_get_first(blue);
710  chip != UVES_CHIP_INVALID;
711  chip = uves_chip_get_next(chip))
712  {
713 
714  if(strcmp(PROCESS_CHIP,"REDU") == 0) {
715  chip = uves_chip_get_next(chip);
716  }
717 
718  const char *master_bias_filename = "";
719  const char *chip_name = "";
720 
721  int raw_index = uves_chip_get_index(chip);
722 
723  uves_msg("Processing %s chip",
725 
726  /* Get chip name of first input frame */
727  check_nomsg( chip_name = uves_pfits_get_chipid(raw_headers[raw_index][0], chip));
728 
729  /* Load master bias, set pointer to NULL if not present */
730  uves_free_image(&master_bias);
731  uves_free_propertylist(&master_bias_header);
732  if (cpl_frameset_find(frames, UVES_MASTER_BIAS(chip)) != NULL)
733  {
734  check( uves_load_mbias(frames, chip_name,
735  &master_bias_filename, &master_bias,
736  &master_bias_header, chip),
737  "Error loading master bias");
738 
739  uves_msg_low("Using master bias in '%s'", master_bias_filename);
740  }
741  else
742  {
743  uves_msg_low("No master bias in SOF. Bias subtraction not done");
744  }
745 
746  /* Process chip */
747 
748 
749 
750  uves_free_image(&master_dark);
751  uves_qclog_delete(&qclog[0]);
752  qclog[0] = uves_qclog_init(raw_headers[raw_index][0], chip);
753  check( master_dark = uves_mdark_process_chip(raw_images[raw_index],
754  raw_headers[raw_index],
755  master_bias,
756  product_header[raw_index],
757  parameters,recipe_id,
758  qclog[0],pr_when),
759  "Error processing chip");
760 
761 
762  /* Finished. Save */
763  /* Finished. Calculate QC parameters and save */
764  if(pr_when==1) {
765  uves_msg("Calculating QC parameters on master dark frame");
766  uves_mdark_region_qc(master_dark,parameters,
767  raw_images[raw_index],recipe_id,qclog[0]);
768 
769  }
770 
771  /* Insert into frame set */
772  uves_msg("Saving product");
773 
774  cpl_free(product_filename);
775  check( product_filename = uves_masterdark_filename(chip), "Error getting filename");
776 
777 
778  check( uves_frameset_insert(frames,
779  master_dark,
780  CPL_FRAME_GROUP_PRODUCT,
781  CPL_FRAME_TYPE_IMAGE,
782  CPL_FRAME_LEVEL_INTERMEDIATE,
783  product_filename,
784  product_tag[raw_index],
785  raw_headers[raw_index][0],
786  product_header[raw_index],
787  NULL,
788  parameters,
789  recipe_id,
790  PACKAGE "/" PACKAGE_VERSION,qclog,
791  starttime, dump_qc,
792  UVES_ALL_STATS),
793  "Could not add master dark %s to frameset", product_filename);
794  uves_msg("Master dark %s added to frameset", product_filename);
795  uves_qclog_delete(&qclog[0]);
796 
797  if(strcmp(PROCESS_CHIP,"REDL") == 0) {
798  chip = uves_chip_get_next(chip);
799  }
800 
801 
802  }/* For each chip */
803 
804  cleanup:
805  /* Input */
806  if (raw_images[0] != NULL)
807  {
808  int i;
809  for (i = 0; i < cpl_imagelist_get_size(raw_images[0]); i++)
810  {
811  if (raw_headers[0] != NULL) uves_free_propertylist(&raw_headers[0][i]);
812  if (raw_headers[1] != NULL) uves_free_propertylist(&raw_headers[1][i]);
813  }
814 
815  cpl_free(raw_headers[0]); raw_headers[0] = NULL;
816  cpl_free(raw_headers[1]); raw_headers[1] = NULL;
817  }
818 
819  uves_free_imagelist(&raw_images[0]);
820  uves_free_imagelist(&raw_images[1]);
821 
822  /* Master bias */
823  uves_free_image(&master_bias);
824  uves_free_propertylist(&master_bias_header);
825 
826  /* Output */
827  uves_qclog_delete(&qclog[0]);
828  uves_free_image(&master_dark);
829  uves_free_propertylist(&product_header[0]);
830  uves_free_propertylist(&product_header[1]);
831  cpl_free(product_filename);
832  uves_free(pname);
833  return;
834 }
835 
836 
837 static void
838 uves_mdark_region_qc(cpl_image* img,
839  const cpl_parameterlist* p,
840  const cpl_imagelist* raw_images,
841  const char* recipe_id,
842  cpl_table* qclog)
843 {
844 
845  int pr_num_x=4;
846  int pr_num_y=4;
847  int pr_box_sx=100;
848  int pr_box_sy=100;
849  int pr_border_x=100;
850  int pr_border_y=100;
851 
852 
853  int i=0;
854  int j=0;
855  int llx=0;
856  int lly=0;
857  int urx=0;
858  int ury=0;
859  int space_x=0;
860  int space_y=0;
861  int sx=0;
862  int sy=0;
863  int nraw=0;
864  int raw=0;
865  char name[MAX_NAME_SIZE];
866  char pname[MAX_NAME_SIZE];
867  char qc_key[MAX_NAME_SIZE];
868  char qc_com[MAX_NAME_SIZE];
869  double qc_avg=0;
870  double qc_med=0;
871  double qc_rms=0;
872  double qc_min=0;
873  double qc_max=0;
874  cpl_table* qc_sto=NULL;
875 
876  check_nomsg(uves_extract_basic_parameters_for_qc(p,recipe_id,
877  &pr_num_x,&pr_num_y,
878  &pr_box_sx,&pr_box_sy));
879 
880  uves_msg("pr_num_x=%d pr_num_y=%d pr_box_sx=%d pr_box_sy=%d",
881  pr_num_x,pr_num_y,pr_box_sx,pr_box_sy);
882 
883  if(pr_num_x <= 0 || pr_num_y <= 0 || pr_box_sx <= 0 || pr_box_sy <= 0) {
884  return;
885  }
886 
887  sprintf(name,"reg.border_x");
888  sprintf(pname,"%s.%s", UVES_QCDARK_ID, name);
889  check(uves_get_parameter(p,NULL,recipe_id,pname,CPL_TYPE_INT,&pr_border_x),
890  "Could not read parameter");
891 
892  sprintf(name,"reg.border_y");
893  sprintf(pname,"%s.%s", UVES_QCDARK_ID, name);
894  check(uves_get_parameter(p,NULL,recipe_id,pname,CPL_TYPE_INT,&pr_border_y),
895  "Could not read parameter");
896 
897 
898  check_nomsg(nraw=cpl_imagelist_get_size(raw_images));
900  "PRO DATANCOM",
901  nraw,
902  "Number of frames combined",
903  "%d"));
904 
905  sx=cpl_image_get_size_x(img);
906  sy=cpl_image_get_size_y(img);
907  space_x=(int)((sx-2*pr_border_x)/pr_num_x);
908  space_y=(int)((sy-2*pr_border_y)/pr_num_y);
909  qc_sto=cpl_table_new(pr_num_x*pr_num_y);
910  cpl_table_new_column(qc_sto,"MIN",CPL_TYPE_DOUBLE);
911  cpl_table_new_column(qc_sto,"MAX",CPL_TYPE_DOUBLE);
912  cpl_table_new_column(qc_sto,"AVG",CPL_TYPE_DOUBLE);
913  cpl_table_new_column(qc_sto,"MED",CPL_TYPE_DOUBLE);
914  cpl_table_new_column(qc_sto,"RMS",CPL_TYPE_DOUBLE);
915 
916  for(i=0;i<pr_num_x;i++) {
917  llx=pr_border_x+i*space_x;
918  urx=llx+pr_box_sx;
919 
920  llx=(llx>0) ? llx:1;
921  urx=(urx<=sx) ? urx:sx;
922 
923  for(j=0;j<pr_num_y;j++) {
924  lly=pr_border_y+j*space_y;
925  ury=lly+pr_box_sy;
926 
927  lly=(lly>0) ? lly:1;
928  ury=(ury<=sy) ? ury:sy;
929 
930  raw=i*pr_num_y+j;
931  check_nomsg(qc_min=cpl_image_get_min_window(img,llx,lly,urx,ury));
932  qc_max=cpl_image_get_min_window(img,llx,lly,urx,ury);
933  qc_avg=cpl_image_get_mean_window(img,llx,lly,urx,ury);
934  qc_med=cpl_image_get_median_window(img,llx,lly,urx,ury);
935  qc_rms=cpl_image_get_stdev_window(img,llx,lly,urx,ury);
936  uves_msg_debug("QC on area [%d,%d:%d,%d]. Min %g Max %g Avg %g Med %g Rms %g",
937  llx,lly,urx,ury,qc_min,qc_max,qc_avg,qc_med,qc_rms);
938 
939  sprintf(qc_key,"%s%d%d%s","QC REG",i,j," MIN");
940  sprintf(qc_com,"%s%d%d","Min of region [%d,%d]",i,j);
941  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_min,qc_com,"%g"));
942  check_nomsg(cpl_table_set_double(qc_sto,"MIN",raw,qc_min));
943 
944  sprintf(qc_key,"%s%d%d%s","QC REG",i,j," MAX");
945  sprintf(qc_com,"%s%d%d","Max of region [%d,%d]",i,j);
946  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_max,qc_com,"%g"));
947  check_nomsg(cpl_table_set_double(qc_sto,"MAX",raw,qc_max));
948 
949  sprintf(qc_key,"%s%d%d%s","QC REG",i,j," AVG");
950  sprintf(qc_com,"%s%d%d","Mean of region [%d,%d]",i,j);
951  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_avg,qc_com,"%g"));
952  check_nomsg(cpl_table_set_double(qc_sto,"AVG",raw,qc_avg));
953 
954  sprintf(qc_key,"%s%d%d%s","QC REG",i,j," MED");
955  sprintf(qc_com,"%s%d%d","Median of region [%d,%d]",i,j);
956  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_med,qc_com,"%g"));
957  check_nomsg(cpl_table_set_double(qc_sto,"MED",raw,qc_med));
958 
959  sprintf(qc_key,"%s%d%d%s","QC REG",i,j," RMS");
960  sprintf(qc_com,"%s%d%d","Rms of region [%d,%d]",i,j);
961  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_rms,qc_com,"%g"));
962  check_nomsg(cpl_table_set_double(qc_sto,"RMS",raw,qc_rms));
963 
964 
965  }
966  }
967 
968 
969  check_nomsg(qc_min=cpl_table_get_column_min(qc_sto,"MIN"));
970  check_nomsg(qc_max=cpl_table_get_column_max(qc_sto,"MIN"));
971  check_nomsg(qc_avg=cpl_table_get_column_mean(qc_sto,"MIN"));
972  check_nomsg(qc_med=cpl_table_get_column_median(qc_sto,"MIN"));
973  check_nomsg(qc_rms=cpl_table_get_column_stdev(qc_sto,"MIN"));
974 
975  sprintf(qc_key,"%s","QC REG MIN MIN");
976  sprintf(qc_com,"%s","Min of all Mins");
977  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_min,qc_com,"%g"));
978 
979  sprintf(qc_key,"%s","QC REG MIN MAX");
980  sprintf(qc_com,"%s","Max of all Mins");
981  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_max,qc_com,"%g"));
982 
983  sprintf(qc_key,"%s","QC REG MIN AVG");
984  sprintf(qc_com,"%s","Mean of all Mins");
985  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_avg,qc_com,"%g"));
986 
987  sprintf(qc_key,"%s","QC REG MIN MED");
988  sprintf(qc_com,"%s","Median of all Mins");
989  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_med,qc_com,"%g"));
990 
991  sprintf(qc_key,"%s","QC REG MIN RMS");
992  sprintf(qc_com,"%s","Rms of all Mins");
993  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_rms,qc_com,"%g"));
994 
995 
996 
997  check_nomsg(qc_min=cpl_table_get_column_min(qc_sto,"MAX"));
998  check_nomsg(qc_max=cpl_table_get_column_max(qc_sto,"MAX"));
999  check_nomsg(qc_avg=cpl_table_get_column_mean(qc_sto,"MAX"));
1000  check_nomsg(qc_med=cpl_table_get_column_median(qc_sto,"MAX"));
1001  check_nomsg(qc_rms=cpl_table_get_column_stdev(qc_sto,"MAX"));
1002 
1003  sprintf(qc_key,"%s","QC REG MAX MIN");
1004  sprintf(qc_com,"%s","Min of all Maxs");
1005  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_min,qc_com,"%g"));
1006 
1007  sprintf(qc_key,"%s","QC REG MAX MAX");
1008  sprintf(qc_com,"%s","Max of all Maxs");
1009  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_max,qc_com,"%g"));
1010 
1011  sprintf(qc_key,"%s","QC REG MAX AVG");
1012  sprintf(qc_com,"%s","Mean of all Maxs");
1013  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_avg,qc_com,"%g"));
1014 
1015  sprintf(qc_key,"%s","QC REG MAX MED");
1016  sprintf(qc_com,"%s","Median of all Maxs");
1017  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_med,qc_com,"%g"));
1018 
1019  sprintf(qc_key,"%s","QC REG MAX RMS");
1020  sprintf(qc_com,"%s","Rms of all Maxs");
1021  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_rms,qc_com,"%g"));
1022 
1023 
1024  check_nomsg(qc_min=cpl_table_get_column_min(qc_sto,"AVG"));
1025  check_nomsg(qc_max=cpl_table_get_column_max(qc_sto,"AVG"));
1026  check_nomsg(qc_avg=cpl_table_get_column_mean(qc_sto,"AVG"));
1027  check_nomsg(qc_med=cpl_table_get_column_median(qc_sto,"AVG"));
1028  check_nomsg(qc_rms=cpl_table_get_column_stdev(qc_sto,"AVG"));
1029 
1030  sprintf(qc_key,"%s","QC REG AVG MIN");
1031  sprintf(qc_com,"%s","Min of all Means");
1032  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_min,qc_com,"%g"));
1033 
1034  sprintf(qc_key,"%s","QC REG AVG MAX");
1035  sprintf(qc_com,"%s","Max of all Means");
1036  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_max,qc_com,"%g"));
1037 
1038  sprintf(qc_key,"%s","QC REG AVG AVG");
1039  sprintf(qc_com,"%s","Mean of all Means");
1040  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_avg,qc_com,"%g"));
1041 
1042  sprintf(qc_key,"%s","QC REG AVG MED");
1043  sprintf(qc_com,"%s","Median of all Means");
1044  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_med,qc_com,"%g"));
1045 
1046  sprintf(qc_key,"%s","QC REG AVG RMS");
1047  sprintf(qc_com,"%s","Rms of all Means");
1048  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_rms,qc_com,"%g"));
1049 
1050 
1051  check_nomsg(qc_min=cpl_table_get_column_min(qc_sto,"MED"));
1052  check_nomsg(qc_max=cpl_table_get_column_max(qc_sto,"MED"));
1053  check_nomsg(qc_avg=cpl_table_get_column_mean(qc_sto,"MED"));
1054  check_nomsg(qc_med=cpl_table_get_column_median(qc_sto,"MED"));
1055  check_nomsg(qc_rms=cpl_table_get_column_stdev(qc_sto,"MED"));
1056 
1057  sprintf(qc_key,"%s","QC REG MED MIN");
1058  sprintf(qc_com,"%s","Min of all Medians");
1059  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_min,qc_com,"%g"));
1060 
1061  sprintf(qc_key,"%s","QC REG MED MAX");
1062  sprintf(qc_com,"%s","Max of all Medians");
1063  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_max,qc_com,"%g"));
1064 
1065  sprintf(qc_key,"%s","QC REG MED AVG");
1066  sprintf(qc_com,"%s","Mean of all Medians");
1067  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_avg,qc_com,"%g"));
1068 
1069  sprintf(qc_key,"%s","QC REG MED MED");
1070  sprintf(qc_com,"%s","Median of all Medians");
1071  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_med,qc_com,"%g"));
1072 
1073  sprintf(qc_key,"%s","QC REG MED RMS");
1074  sprintf(qc_com,"%s","Rms of all Medians");
1075  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_rms,qc_com,"%g"));
1076 
1077 
1078  check_nomsg(qc_min=cpl_table_get_column_min(qc_sto,"RMS"));
1079  check_nomsg(qc_max=cpl_table_get_column_max(qc_sto,"RMS"));
1080  check_nomsg(qc_avg=cpl_table_get_column_mean(qc_sto,"RMS"));
1081  check_nomsg(qc_med=cpl_table_get_column_median(qc_sto,"RMS"));
1082  check_nomsg(qc_rms=cpl_table_get_column_stdev(qc_sto,"RMS"));
1083 
1084 
1085  sprintf(qc_key,"%s","QC REG RMS MIN");
1086  sprintf(qc_com,"%s","Min of all Rms");
1087  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_min,qc_com,"%g"));
1088 
1089  sprintf(qc_key,"%s","QC REG RMS MAX");
1090  sprintf(qc_com,"%s","Max of all Rms");
1091  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_max,qc_com,"%g"));
1092 
1093  sprintf(qc_key,"%s","QC REG RMS AVG");
1094  sprintf(qc_com,"%s","Mean of all Rms");
1095  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_avg,qc_com,"%g"));
1096 
1097  sprintf(qc_key,"%s","QC REG RMS MED");
1098  sprintf(qc_com,"%s","Median of all Rms");
1099  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_med,qc_com,"%g"));
1100 
1101  sprintf(qc_key,"%s","QC REG RMS RMS");
1102  sprintf(qc_com,"%s","Rms of all Rms");
1103  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_rms,qc_com,"%g"));
1104 
1105 
1106 
1107 
1108  cleanup:
1109  uves_free_table(&qc_sto);
1110 
1111  return;
1112 
1113 }
1114 
1115 
#define uves_msg_warning(...)
Print an warning message.
Definition: uves_msg.h:87
#define check_nomsg(CMD)
Definition: uves_error.h:204
cpl_error_code uves_subtract_bias(cpl_image *image, const cpl_image *master_bias)
Subtract bias.
Definition: uves_utils.c:2394
int uves_qclog_delete(cpl_table **table)
delete QC-LOG table
Definition: uves_qclog.c:716
int uves_qclog_add_double(cpl_table *table, const char *key_name, const double value, const char *key_help, const char *format)
Add double key to QC-LOG table.
Definition: uves_qclog.c:641
int uves_qclog_add_int(cpl_table *table, const char *key_name, const int value, const char *key_help, const char *format)
Add integer key to QC-LOG table.
Definition: uves_qclog.c:521
#define uves_msg(...)
Print a message on 'info' or 'debug' level.
Definition: uves_msg.h:119
double uves_pfits_get_exptime(const uves_propertylist *plist)
Find out the exposure time in seconds.
Definition: uves_pfits.c:922
int uves_chip_get_index(enum uves_chip chip)
Convert to integer.
Definition: uves_chip.c:124
enum uves_chip uves_chip_get_first(bool blue)
Get first chip for blue or red arm.
Definition: uves_chip.c:92
cpl_error_code uves_pfits_set_extname(uves_propertylist *plist, const char *extname)
Write the EXTNAME keyword.
Definition: uves_pfits.c:2736
cpl_error_code uves_pfits_set_exptime(uves_propertylist *plist, double exptime)
Write the exposure time.
Definition: uves_pfits.c:944
cpl_image * uves_ksigma_stack(const cpl_imagelist *imlist, double klow, double khigh, int kiter)
Stack images using k-sigma clipping.
Definition: uves_utils.c:356
#define uves_msg_low(...)
Print a message on a lower message level.
Definition: uves_msg.h:105
enum uves_chip uves_chip_get_next(enum uves_chip chip)
Get next chip.
Definition: uves_chip.c:108
#define uves_msg_debug(...)
Print a debug message.
Definition: uves_msg.h:97
const char * uves_chip_tostring_upper(enum uves_chip chip)
Convert to string.
Definition: uves_chip.c:156
const char * uves_string_toupper(char *s)
Convert all lowercase characters in a string into uppercase characters.
Definition: uves_utils.c:1493
#define check(CMD,...)
Definition: uves_error.h:198
cpl_table * uves_qclog_init(const uves_propertylist *raw_header, enum uves_chip chip)
Init QC-LOG table.
Definition: uves_qclog.c:410
const char * uves_pfits_get_chipid(const uves_propertylist *plist, enum uves_chip chip)
Find out the chip ID.
Definition: uves_pfits.c:619