UVES Pipeline Reference Manual  5.4.6
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  * $Log: not supported by cvs2svn $
26  * Revision 1.52 2010/12/16 16:57:40 amodigli
27  * fixed compiler warnings
28  *
29  * Revision 1.51 2010/09/27 06:32:41 amodigli
30  * fixed mem leaks
31  *
32  * Revision 1.50 2010/09/24 09:32:03 amodigli
33  * put back QFITS dependency to fix problem spot by NRI on FIBER mode (with MIDAS calibs) data
34  *
35  * Revision 1.48 2010/06/11 11:40:00 amodigli
36  * add uves_qcdark_define_parameters_body(), uves_mdark_define_qc_parameters()
37  *
38  * Revision 1.47 2010/06/08 13:51:55 amodigli
39  * cleaned output
40  *
41  * Revision 1.46 2010/05/14 12:47:40 amodigli
42  * set range on several params that control QC
43  *
44  * Revision 1.45 2010/05/11 05:49:02 amodigli
45  * clarified recipe help
46  *
47  * Revision 1.44 2010/03/24 14:56:30 amodigli
48  * fixed compiler warning
49  *
50  * Revision 1.43 2010/03/22 15:57:43 amodigli
51  * added params and possibility to compute master as mean stack
52  *
53  * Revision 1.42 2010/03/01 18:00:22 amodigli
54  * fixed several bugs in computing QC parameters
55  *
56  * Revision 1.41 2008/11/06 14:36:27 amodigli
57  * fixed mem leaks
58  *
59  * Revision 1.40 2008/09/29 06:57:03 amodigli
60  * add #include <string.h>
61  *
62  * Revision 1.39 2008/03/28 08:53:50 amodigli
63  * IRPLIB_CONCAT2X-->UVES_CONCAT2X
64  *
65  * Revision 1.38 2008/02/15 12:43:49 amodigli
66  * allow lower/upper chip for parameter process_chip
67  *
68  * Revision 1.37 2007/10/05 16:01:45 amodigli
69  * using proces_chip parameter to process or not a given RED chip
70  *
71  * Revision 1.36 2007/08/31 06:27:02 amodigli
72  * include uves_globals.h
73  *
74  * Revision 1.35 2007/08/24 08:28:36 amodigli
75  * clearer parm doc
76  *
77  * Revision 1.34 2007/08/24 06:55:36 amodigli
78  * fixed parameter io for qc
79  *
80  * Revision 1.33 2007/08/21 13:08:26 jmlarsen
81  * Removed irplib_access module, largely deprecated by CPL-4
82  *
83  * Revision 1.32 2007/08/17 10:07:02 amodigli
84  * added QC params asked by DFS04195
85  *
86  * Revision 1.31 2007/06/11 13:28:26 jmlarsen
87  * Changed recipe contact address to cpl at eso.org
88  *
89  * Revision 1.30 2007/06/08 13:06:16 jmlarsen
90  * Send bug reports to Andrea
91  *
92  * Revision 1.29 2007/06/06 08:17:33 amodigli
93  * replace tab with 4 spaces
94  *
95  * Revision 1.28 2007/05/16 09:50:40 jmlarsen
96  * Do not threshold to zero after bias subtraction
97  *
98  * Revision 1.27 2007/04/24 12:50:29 jmlarsen
99  * Replaced cpl_propertylist -> uves_propertylist which is much faster
100  *
101  * Revision 1.26 2007/02/09 13:37:47 jmlarsen
102  * Enable calling from uves_cal_mkmaster
103  *
104  * Revision 1.25 2007/02/09 08:57:44 jmlarsen
105  * Include <float.h>
106  *
107  * Revision 1.24 2007/02/09 08:14:16 jmlarsen
108  * Do not use CPL_PIXEL_MAXVAL which works only for integer images
109  *
110  * Revision 1.23 2006/12/07 08:23:23 jmlarsen
111  * uves_load_raw_imagelist: support FLAMES
112  *
113  * Revision 1.22 2006/11/15 15:02:14 jmlarsen
114  * Implemented const safe workarounds for CPL functions
115  *
116  * Revision 1.20 2006/11/15 14:04:08 jmlarsen
117  * Removed non-const version of parameterlist_get_first/last/next which is
118  * already in CPL, added const-safe wrapper, unwrapper and deallocator functions
119  *
120  * Revision 1.19 2006/11/06 15:19:41 jmlarsen
121  * Removed unused include directives
122  *
123  * Revision 1.18 2006/10/17 12:33:02 jmlarsen
124  * Added semicolon at UVES_RECIPE_DEFINE invocation
125  *
126  * Revision 1.17 2006/10/09 13:01:13 jmlarsen
127  * Use macro to define recipe interface functions
128  *
129  * Revision 1.16 2006/09/19 14:31:17 jmlarsen
130  * uves_insert_frame(): use bitmap to specify which image statistics keywords must be computed
131  *
132  * Revision 1.15 2006/09/19 06:55:55 jmlarsen
133  * Changed interface of uves_frameset to optionally write image statistics kewwords
134  *
135  * Revision 1.14 2006/08/24 11:36:37 jmlarsen
136  * Write recipe start/stop time to header
137  *
138  * Revision 1.13 2006/08/17 13:56:53 jmlarsen
139  * Reduced max line length
140  *
141  * Revision 1.12 2006/08/11 14:56:05 amodigli
142  * removed Doxygen warnings
143  *
144  * Revision 1.11 2006/07/14 12:19:28 jmlarsen
145  * Support multiple QC tests per product
146  *
147  * Revision 1.10 2006/07/03 13:02:18 jmlarsen
148  * Threshold to zero after bias subtraction
149  *
150  * Revision 1.9 2006/06/28 13:29:06 amodigli
151  * removed TEST ID from QC log
152  *
153  * Revision 1.8 2006/06/16 08:25:45 jmlarsen
154  * Manually propagate ESO.DET. keywords from 1st/2nd input header
155  *
156  * Revision 1.7 2006/06/13 11:57:02 jmlarsen
157  * Check that calibration frames are from the same chip ID
158  *
159  * Revision 1.6 2006/06/01 14:43:17 jmlarsen
160  * Added missing documentation
161  *
162  * Revision 1.5 2006/05/09 07:42:18 amodigli
163  * added QC-LOG
164  *
165  * Revision 1.4 2006/04/06 12:57:22 jmlarsen
166  * Added support for PDARK, MASTER_PDARK frames
167  *
168  * Revision 1.3 2006/04/06 09:48:15 amodigli
169  * changed uves_frameset_insert interface to have QC log
170  *
171  * Revision 1.2 2006/04/06 08:37:33 jmlarsen
172  * Removed memory leak
173  *
174  * Revision 1.1 2006/02/03 07:46:30 jmlarsen
175  * Moved recipe implementations to ./uves directory
176  *
177  * Revision 1.27 2006/01/19 08:47:24 jmlarsen
178  * Insertedv missing doxygen end tag
179  *
180  * Revision 1.26 2005/12/19 16:17:55 jmlarsen
181  * Replaced bool -> int
182  *
183  */
184 
185 #ifdef HAVE_CONFIG_H
186 # include <config.h>
187 #endif
188 
189 /*----------------------------------------------------------------------------*/
196 /*----------------------------------------------------------------------------*/
197 
198 /*-----------------------------------------------------------------------------
199  Includes
200  -----------------------------------------------------------------------------*/
201 #include <uves_mdark_impl.h>
202 
203 #include <uves_parameters.h>
204 #include <uves_utils.h>
205 #include <uves.h>
206 #include <uves_dfs.h>
207 #include <uves_pfits.h>
208 #include <uves_qclog.h>
209 #include <uves_recipe.h>
210 #include <uves_utils_wrappers.h>
211 #include <uves_error.h>
212 #include <uves_globals.h>
213 
214 #include <cpl.h>
215 #include <float.h>
216 #include <string.h>
217 /*-----------------------------------------------------------------------------
218  Functions prototypes
219  -----------------------------------------------------------------------------*/
220 /*
221 static int
222 uves_qcdark_define_parameters_body(cpl_parameterlist *parameters,
223  const char *recipe_id);
224 */
225 static int
226 uves_mdark_define_parameters(cpl_parameterlist *parameters);
227 
228 static void uves_mdark_region_qc(cpl_image* img,
229  const cpl_parameterlist* p,
230  const cpl_imagelist* raw_images,
231  const char* recipe_id,
232  cpl_table* qclog);
233 static cpl_image *
234 uves_mdark_process_chip(const cpl_imagelist *raw_images,
235  uves_propertylist **raw_headers,
236  const cpl_image *master_bias,
237  uves_propertylist *mdark_header,
238  const cpl_parameterlist *parameters,
239  const char* recipe_id,
240  cpl_table* qclog, const int do_qc);
241 
242 
243 /*-----------------------------------------------------------------------------
244  Recipe standard code
245  -----------------------------------------------------------------------------*/
246 #define cpl_plugin_get_info uves_mdark_get_info
247 UVES_RECIPE_DEFINE(
248  UVES_MDARK_ID, UVES_MDARK_DOM,
249  /* Warning: if more parameters are added to this recipe, they
250  need to be propagated to uves_cal_mkmaster! */
251  uves_mdark_define_parameters,
252  "Jonas M. Larsen", "cpl@eso.org",
253  "Creates the master dark frame",
254  "This recipe creates a master dark frame by taking the median of all\n"
255  "input frames which should have identical exposure times. Symbolically,\n"
256  " masterdark = median( dark_i ) - masterbias\n"
257  "\n"
258  "The input dark frames must have same tag and size and must be either\n"
259  "(P)DARK_BLUE or (P)DARK_RED. Also, a master bias (MASTER_BIAS_xxxx) must\n"
260  "be provided for each chip (xxxx = BLUE, REDL, REDU).\n"
261  "\n"
262  "On blue input the recipe computes one master dark frame; on red input the\n"
263  "recipe produces a master dark frame for each chip (MASTER_(P)DARK_xxxx).\n");
264 
266 /*-----------------------------------------------------------------------------
267  Functions code
268  -----------------------------------------------------------------------------*/
269 
270 
271 
272 /*----------------------------------------------------------------------------*/
278 /*----------------------------------------------------------------------------*/
279 static cpl_error_code
280 uves_extract_basic_parameters_for_qc(const cpl_parameterlist* p,
281  const char* recipe_id,
282  int * pr_num_x,
283  int* pr_num_y,
284  int* pr_box_sx,
285  int* pr_box_sy)
286 {
287 
288  char name[MAX_NAME_SIZE];
289  char pname[MAX_NAME_SIZE];
290 
291  sprintf(name,"reg.num_x");
292  sprintf(pname,"%s.%s", UVES_QCDARK_ID, name);
293  uves_msg("pname=%s",pname);
294  check(uves_get_parameter(p,NULL,recipe_id,pname,CPL_TYPE_INT,pr_num_x),
295  "Could not read parameter");
296 
297  sprintf(name,"reg.num_y");
298  sprintf(pname,"%s.%s", UVES_QCDARK_ID, name);
299  check(uves_get_parameter(p,NULL,recipe_id,pname,CPL_TYPE_INT,pr_num_y),
300  "Could not read parameter");
301 
302  sprintf(name,"reg.box_sx");
303  sprintf(pname,"%s.%s", UVES_QCDARK_ID, name);
304  check(uves_get_parameter(p,NULL,recipe_id,pname,CPL_TYPE_INT,pr_box_sx),
305  "Could not read parameter");
306 
307  sprintf(name,"reg.box_sy");
308  sprintf(pname,"%s.%s", UVES_QCDARK_ID, name);
309  check(uves_get_parameter(p,NULL,recipe_id,pname,CPL_TYPE_INT,pr_box_sy),
310  "Could not read parameter");
311 
312  cleanup:
313  return cpl_error_get_code();
314 
315 }
316 
317 
318 
319 
320 
321 
322 /*----------------------------------------------------------------------------*/
328 /*----------------------------------------------------------------------------*/
329 static int
330 uves_mdark_define_parameters(cpl_parameterlist *parameters)
331 {
332  if (uves_master_stack_define_parameters(parameters,
333  make_str(UVES_MDARK_ID))
334  != CPL_ERROR_NONE)
335  {
336  return -1;
337  }
338 
339  return uves_qcdark_define_parameters_body(parameters,
340  make_str(UVES_MDARK_ID));
341 }
342 
343 /*----------------------------------------------------------------------------*/
350 /*----------------------------------------------------------------------------*/
351 int
352 uves_qcdark_define_parameters_body(cpl_parameterlist *parameters,
353  const char *recipe_id)
354 {
355  /*****************
356  * General *
357  *****************/
358  if (uves_define_global_parameters(parameters) != CPL_ERROR_NONE)
359  {
360  return -1;
361  }
362 
363  if (uves_master_stack_define_parameters(parameters,recipe_id)
364  != CPL_ERROR_NONE)
365  {
366  return -1;
367  }
368 
369 
370  /****************************
371  * Spline back.sub. *
372  ****************************/
373 
374  if (uves_propagate_parameters_step(UVES_QCDARK_ID, parameters,
375  recipe_id, NULL) != 0)
376  {
377  return -1;
378  }
379 
380  return (cpl_error_get_code() != CPL_ERROR_NONE);
381 }
382 
383 
384 
385 /*----------------------------------------------------------------------------*/
394 /*----------------------------------------------------------------------------*/
395 cpl_error_code
396 uves_mdark_define_qc_parameters(cpl_parameterlist* parameters)
397 {
398 
399  const char *name = "";
400  char *full_name = NULL;
401  cpl_parameter *p = NULL;
402 
403  {
404 
405  name = "reg.num_x";
406  full_name = uves_sprintf("%s.%s", UVES_QCDARK_ID, name);
407  uves_parameter_new_range(p, full_name,
408  CPL_TYPE_INT,
409  "Number of regions along the X axis "
410  "(where mean/med/rms are computed). ",
411  UVES_QCDARK_ID,
412  4,0,INT_MAX);
413 
414  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name );
415  cpl_parameterlist_append(parameters, p);
416  cpl_free(full_name);
417 
418 
419 
420  name = "reg.num_y";
421  full_name = uves_sprintf("%s.%s", UVES_QCDARK_ID,name);
422  uves_parameter_new_range(p, full_name,
423  CPL_TYPE_INT,
424  "Number of regions along the Y axis"
425  "(where mean/med/rms are computed). ",
426  UVES_QCDARK_ID,
427  4,0,INT_MAX);
428 
429  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
430  cpl_parameterlist_append(parameters, p);
431  cpl_free(full_name);
432 
433 
434 
435  name = "reg.box_sx";
436  full_name = uves_sprintf("%s.%s", UVES_QCDARK_ID,name);
437  uves_parameter_new_range(p, full_name,
438  CPL_TYPE_INT,
439  "Region X size [pix]",
440  UVES_QCDARK_ID,
441  100,0,INT_MAX);
442  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
443  cpl_parameterlist_append(parameters, p);
444  cpl_free(full_name);
445 
446 
447  name = "reg.box_sy";
448  full_name = uves_sprintf("%s.%s", UVES_QCDARK_ID,name);
449  uves_parameter_new_range(p, full_name,
450  CPL_TYPE_INT,
451  "Region Y size [pix]",
452  UVES_QCDARK_ID,
453  100,0,INT_MAX);
454  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
455  cpl_parameterlist_append(parameters, p);
456  cpl_free(full_name);
457 
458  name = "reg.border_x";
459  full_name = uves_sprintf("%s.%s", UVES_QCDARK_ID,name);
460  uves_parameter_new_range(p, full_name,
461  CPL_TYPE_INT,
462  "X distance between the left hand side "
463  "of the detector and the left hand side "
464  "of the region [pix]",
465  UVES_QCDARK_ID,
466  100,0,INT_MAX);
467  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
468  cpl_parameterlist_append(parameters, p);
469  cpl_free(full_name);
470 
471 
472  name = "reg.border_y";
473  full_name = uves_sprintf("%s.%s", UVES_QCDARK_ID,name);
474  uves_parameter_new_range(p, full_name,
475  CPL_TYPE_INT,
476  "X distance between the left hand side "
477  "of the detector and the left hand side "
478  "of the region [pix]",
479  UVES_QCDARK_ID,
480  100,0,INT_MAX);
481  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
482  cpl_parameterlist_append(parameters, p);
483  cpl_free(full_name);
484 
485 
486 
487  name = "reg.when";
488  full_name = uves_sprintf("%s.%s", UVES_QCDARK_ID,name);
489  uves_parameter_new_enum(p, full_name,
490  CPL_TYPE_INT,
491  "When QC analysis is performed. "
492  "0: on each raw frame or "
493  "1: on the master frame",
494  UVES_QCDARK_ID,
495  0,2,0,1);
496  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
497  cpl_parameterlist_append(parameters, p);
498  cpl_free(full_name);
499 
500 
501  }
502 
503  if (cpl_error_get_code() != CPL_ERROR_NONE)
504  {
505  cpl_msg_error(__func__, "Creation of mdark parameters failed: '%s'",
506  cpl_error_get_where());
507  cpl_parameterlist_delete(parameters);
508  }
509  return cpl_error_get_code();
510 }
511 
512 
513 /*----------------------------------------------------------------------------*/
521 /*----------------------------------------------------------------------------*/
522 cpl_parameterlist *
523 uves_qcdark_define_parameters(void)
524 {
525 
526  cpl_parameterlist *parameters = NULL;
527 
528  parameters = cpl_parameterlist_new();
529 
530  check(uves_mdark_define_qc_parameters(parameters),
531  "Error defining mdark qc parameters");
532 
533 
534  cleanup:
535  if (cpl_error_get_code() != CPL_ERROR_NONE)
536  {
537  cpl_msg_error(__func__, "Creation of mdark parameters failed: '%s'",
538  cpl_error_get_where());
539  cpl_parameterlist_delete(parameters);
540  return NULL;
541  } else {
542  return parameters;
543  }
544 }
545 
546 
547 
548 
549 
550 /*----------------------------------------------------------------------------*/
570 /*----------------------------------------------------------------------------*/
571 static cpl_image *
572 uves_mdark_process_chip(const cpl_imagelist *raw_images,
573  uves_propertylist **raw_headers,
574  const cpl_image *master_bias,
575  uves_propertylist *mdark_header,
576  const cpl_parameterlist *parameters,
577  const char* recipe_id,
578  cpl_table* qclog,const int do_qc)
579 {
580  cpl_image *master_dark = NULL; /* Result */
581  cpl_image *current_dark = NULL;
582  cpl_imagelist *preproc_images = NULL;
583  double min_exptime = 0;
584  double max_exptime = 0;
585  int i;
586  //char name[MAX_NAME_SIZE];
587  //char pname[MAX_NAME_SIZE];
588 
589  int pr_num_x=4;
590  int pr_num_y=4;
591  int pr_box_sx=100;
592  int pr_box_sy=100;
593  const char* STACK_METHOD=NULL;
594  double STACK_KLOW=0;
595  double STACK_KHIGH=0;
596  int STACK_NITER=0;
597 
598 /* check critical QC parameters to see if QC need to be computed or not */
599 
600  check_nomsg(uves_extract_basic_parameters_for_qc(parameters,recipe_id,
601  &pr_num_x,&pr_num_y,
602  &pr_box_sx,&pr_box_sy));
603 
604 /* parameters for stacking */
605  check( uves_get_parameter(parameters, NULL, recipe_id, "stack_method", CPL_TYPE_STRING, &STACK_METHOD),
606  "Could not read parameter");
607 
608  uves_string_toupper((char*)STACK_METHOD);
609 
610  check( uves_get_parameter(parameters, NULL, recipe_id, "klow", CPL_TYPE_DOUBLE, &STACK_KLOW),
611  "Could not read parameter");
612  check( uves_get_parameter(parameters, NULL, recipe_id, "khigh", CPL_TYPE_DOUBLE, &STACK_KHIGH),
613  "Could not read parameter");
614  check( uves_get_parameter(parameters, NULL, recipe_id, "niter", CPL_TYPE_INT, &STACK_NITER),
615  "Could not read parameter");
616 
617 
618 
619  /* First process each input image and store the results in a
620  new image list */
621 
622  preproc_images = cpl_imagelist_new();
623  for (i = 0; i < cpl_imagelist_get_size(raw_images); i++)
624  {
625  double exposure_time = 0.0;
626  const uves_propertylist *current_header;
627 
628  current_dark = cpl_image_duplicate(cpl_imagelist_get_const(raw_images, i));
629  current_header = raw_headers[i];
630 
631  /* Subtract master bias */
632  if (master_bias != NULL)
633  {
634  uves_msg("Subtracting master bias");
635  check( uves_subtract_bias(current_dark, master_bias),
636  "Error subtracting master bias");
637 
638  if (false) {
639  uves_msg_debug("Thresholding to non-negative values");
640  check( cpl_image_threshold(current_dark,
641  0, DBL_MAX, /* Interval */
642  0, DBL_MAX), /* New values */
643  "Error thresholding image");
644  }
645  }
646  else
647  {
648  uves_msg("Skipping bias subtraction");
649  }
650 
651  check( exposure_time = uves_pfits_get_exptime(current_header),
652  "Error reading exposure time");
653 
654  if(pr_num_x != 0 && pr_num_y != 0 && pr_box_sx != 0 && pr_box_sy !=0 ) {
655  if(do_qc == 0) {
656  uves_msg("Calculating QC parameters on raw dark frame %d",i);
657  uves_mdark_region_qc(current_dark,parameters,raw_images,recipe_id,qclog);
658  }
659 
660  }
661  /* Initialize/update min/max exposure time*/
662  if (i == 0 || exposure_time < min_exptime)
663  {
664  min_exptime = exposure_time;
665  }
666  if (i == 0 || exposure_time > max_exptime)
667  {
668  max_exptime = exposure_time;
669  }
670 
671  /* Do not normalize to unit exposure time */
672 /* If this is uncommented, then remember to also calculate the
673  correct master dark exposure time below.
674  uves_msg("Normalizing from %f s to unit exposure time", exposure_time);
675  check( cpl_image_divide_scalar(current_dark, exposure_time),
676  "Error normalizing dark frame"); */
677 
678  /* Append to imagelist */
679  check( cpl_imagelist_set(preproc_images,
680  current_dark,
681  i), /* Position (number_of_images=>append) */
682  "Could not insert image into image list");
683 
684  /* Don't deallocate the image. It will be deallocated when
685  the image list is deallocated */
686  current_dark = NULL;
687  }
688 
689  /* Check exposure times */
690  uves_msg("Exposure times range from %e s to %e s (%e %% variation)",
691  min_exptime,
692  max_exptime,
693  100 * (max_exptime - min_exptime) / min_exptime);
694 
695  if ((max_exptime - min_exptime) / min_exptime > .001)
696  {
697  uves_msg_warning("Exposure times differ by %e %%",
698  100 * (max_exptime - min_exptime) / min_exptime);
699  }
700 
701  /* Get median stack of input darks */
702  if(strcmp(STACK_METHOD,"MEDIAN")==0) {
703  uves_msg("Calculating stack median");
704  check( master_dark = cpl_imagelist_collapse_median_create(preproc_images),
705  "Error computing median");
706  } else {
707  uves_msg("Calculating stack mean");
708  check( master_dark = uves_ksigma_stack(preproc_images,STACK_KLOW,
709  STACK_KHIGH,STACK_NITER),
710  "Error computing master dark");
711 
712  }
713  check( uves_pfits_set_exptime(mdark_header, (max_exptime + min_exptime)/2),
714  "Error setting master dark exposure time");
715  uves_pfits_set_extname(mdark_header,"Master dark");
716 
717  cleanup:
718  uves_free_image(&current_dark);
719  uves_free_imagelist(&preproc_images);
720  if (cpl_error_get_code() != CPL_ERROR_NONE)
721  {
722  uves_free_image(&master_dark);
723  }
724 
725  return master_dark;
726 }
727 
728 
729 /*----------------------------------------------------------------------------*/
736 /*----------------------------------------------------------------------------*/
737 static void
738 UVES_CONCAT2X(UVES_MDARK_ID,exe)(cpl_frameset *frames,
739  const cpl_parameterlist *parameters,
740  const char *starttime)
741 {
742  uves_mdark_exe_body(frames, parameters, starttime, make_str(UVES_MDARK_ID));
743  return;
744 }
745 
746 /*----------------------------------------------------------------------------*/
758 /*----------------------------------------------------------------------------*/
759 void
760 uves_mdark_exe_body(cpl_frameset *frames,
761  const cpl_parameterlist *parameters,
762  const char *starttime,
763  const char *recipe_id)
764 {
765  /* Function id */
766  /*
767  * Variables that will contain the values of the recipe parameters
768  */
769  /* None */
770 
771  /* CPL objects */
772  /* Input */
773  cpl_imagelist *raw_images[2] = {NULL, NULL};
774  uves_propertylist **raw_headers[2] = {NULL, NULL}; /* Two arrays of pointers */
775 
776  /* Master bias */
777  cpl_image *master_bias = NULL;
778  uves_propertylist *master_bias_header = NULL;
779 
780  /* Output */
781  cpl_table* qclog[2] = {NULL, NULL};
782  cpl_image *master_dark = NULL;
783  uves_propertylist *product_header[2] = {NULL, NULL};
784 
785  /* Local variables */
786  char *product_filename = NULL;
787  const char *product_tag[2] = {NULL, NULL};
788  bool blue;
789  enum uves_chip chip;
790 
791  const char* pname=NULL;
792 
793 
794  int pr_when=0;
795  const char* PROCESS_CHIP=NULL;
796  int pr_num_x=0;
797  int pr_num_y=0;
798  int pr_box_sx=0;
799  int pr_box_sy=0;
800  bool dump_qc=true;
801 
802  /* Load and check raw dark images and headers, identify arm (blue/red) */
803  /* On success, 'raw_headers' will be an array with the same size as 'raw_images' */
804  if (cpl_frameset_find(frames, UVES_DARK(true )) != NULL ||
805  cpl_frameset_find(frames, UVES_DARK(false)) != NULL)
806  {
807  check( uves_load_raw_imagelist(frames,
808  false, /* FLAMES format? */
809  UVES_DARK(true), UVES_DARK(false),
810  CPL_TYPE_DOUBLE,
811  raw_images, raw_headers, product_header,
812  &blue), "Error loading raw dark frames");
813 
814  for (chip = uves_chip_get_first(blue);
815  chip != UVES_CHIP_INVALID;
816  chip = uves_chip_get_next(chip))
817  {
818  product_tag[uves_chip_get_index(chip)] = UVES_MASTER_DARK(chip);
819  }
820  }
821  else if (cpl_frameset_find(frames, UVES_PDARK(true )) != NULL ||
822  cpl_frameset_find(frames, UVES_PDARK(false)) != NULL)
823  {
824  check( uves_load_raw_imagelist(frames,
825  false, /* FLAMES format? */
826  UVES_PDARK(true), UVES_PDARK(false),
827  CPL_TYPE_DOUBLE,
828  raw_images, raw_headers, product_header,
829  &blue), "Error loading raw dark frames");
830 
831  for (chip = uves_chip_get_first(blue);
832  chip != UVES_CHIP_INVALID;
833  chip = uves_chip_get_next(chip))
834  {
835  product_tag[uves_chip_get_index(chip)] = UVES_MASTER_PDARK(chip);
836  }
837  }
838  else
839  {
840  assure(false, CPL_ERROR_DATA_NOT_FOUND,
841  "Missing input dark frame: %s, %s, %s or %s expected",
842  UVES_DARK(true) , UVES_DARK(false),
843  UVES_PDARK(true), UVES_PDARK(false));
844  }
845 
846 
847 
848  check_nomsg(uves_extract_basic_parameters_for_qc(parameters,recipe_id,
849  &pr_num_x,&pr_num_y,
850  &pr_box_sx,&pr_box_sy));
851 
852  if(pr_num_x <=0 || pr_num_y <= 0 || pr_box_sx <=0 || pr_box_sy <= 0) {
853  dump_qc=false;
854  }
855  pname = uves_sprintf("%s.%s", UVES_QCDARK_ID, "reg.when");
856  check(uves_get_parameter(parameters,NULL,recipe_id,pname,CPL_TYPE_INT,&pr_when),
857  "Could not read parameter");
858 
859  check( uves_get_parameter(parameters, NULL, "uves", "process_chip", CPL_TYPE_STRING, &PROCESS_CHIP),
860  "Could not read parameter");
861  uves_string_toupper((char*)PROCESS_CHIP);
862 
863 
864  /* Loop over one or two chips */
865  for (chip = uves_chip_get_first(blue);
866  chip != UVES_CHIP_INVALID;
867  chip = uves_chip_get_next(chip))
868  {
869 
870  if(strcmp(PROCESS_CHIP,"REDU") == 0) {
871  chip = uves_chip_get_next(chip);
872  }
873 
874  const char *master_bias_filename = "";
875  const char *chip_name = "";
876 
877  int raw_index = uves_chip_get_index(chip);
878 
879  uves_msg("Processing %s chip",
881 
882  /* Get chip name of first input frame */
883  check_nomsg( chip_name = uves_pfits_get_chipid(raw_headers[raw_index][0], chip));
884 
885  /* Load master bias, set pointer to NULL if not present */
886  uves_free_image(&master_bias);
887  uves_free_propertylist(&master_bias_header);
888  if (cpl_frameset_find(frames, UVES_MASTER_BIAS(chip)) != NULL)
889  {
890  check( uves_load_mbias(frames, chip_name,
891  &master_bias_filename, &master_bias,
892  &master_bias_header, chip),
893  "Error loading master bias");
894 
895  uves_msg_low("Using master bias in '%s'", master_bias_filename);
896  }
897  else
898  {
899  uves_msg_low("No master bias in SOF. Bias subtraction not done");
900  }
901 
902  /* Process chip */
903 
904 
905 
906  uves_free_image(&master_dark);
907  uves_qclog_delete(&qclog[0]);
908  qclog[0] = uves_qclog_init(raw_headers[raw_index][0], chip);
909  check( master_dark = uves_mdark_process_chip(raw_images[raw_index],
910  raw_headers[raw_index],
911  master_bias,
912  product_header[raw_index],
913  parameters,recipe_id,
914  qclog[0],pr_when),
915  "Error processing chip");
916 
917 
918  /* Finished. Save */
919  /* Finished. Calculate QC parameters and save */
920  if(pr_when==1) {
921  uves_msg("Calculating QC parameters on master dark frame");
922  uves_mdark_region_qc(master_dark,parameters,
923  raw_images[raw_index],recipe_id,qclog[0]);
924 
925  }
926 
927  /* Insert into frame set */
928  uves_msg("Saving product");
929 
930  cpl_free(product_filename);
931  check( product_filename = uves_masterdark_filename(chip), "Error getting filename");
932 
933 
934  check( uves_frameset_insert(frames,
935  master_dark,
936  CPL_FRAME_GROUP_PRODUCT,
937  CPL_FRAME_TYPE_IMAGE,
938  CPL_FRAME_LEVEL_INTERMEDIATE,
939  product_filename,
940  product_tag[raw_index],
941  raw_headers[raw_index][0],
942  product_header[raw_index],
943  NULL,
944  parameters,
945  recipe_id,
946  PACKAGE "/" PACKAGE_VERSION,qclog,
947  starttime, dump_qc,
948  UVES_ALL_STATS),
949  "Could not add master dark %s to frameset", product_filename);
950  uves_msg("Master dark %s added to frameset", product_filename);
951  uves_qclog_delete(&qclog[0]);
952 
953  if(strcmp(PROCESS_CHIP,"REDL") == 0) {
954  chip = uves_chip_get_next(chip);
955  }
956 
957 
958  }/* For each chip */
959 
960  cleanup:
961  /* Input */
962  if (raw_images[0] != NULL)
963  {
964  int i;
965  for (i = 0; i < cpl_imagelist_get_size(raw_images[0]); i++)
966  {
967  if (raw_headers[0] != NULL) uves_free_propertylist(&raw_headers[0][i]);
968  if (raw_headers[1] != NULL) uves_free_propertylist(&raw_headers[1][i]);
969  }
970 
971  cpl_free(raw_headers[0]); raw_headers[0] = NULL;
972  cpl_free(raw_headers[1]); raw_headers[1] = NULL;
973  }
974 
975  uves_free_imagelist(&raw_images[0]);
976  uves_free_imagelist(&raw_images[1]);
977 
978  /* Master bias */
979  uves_free_image(&master_bias);
980  uves_free_propertylist(&master_bias_header);
981 
982  /* Output */
983  uves_qclog_delete(&qclog[0]);
984  uves_free_image(&master_dark);
985  uves_free_propertylist(&product_header[0]);
986  uves_free_propertylist(&product_header[1]);
987  cpl_free(product_filename);
988  uves_free(pname);
989  return;
990 }
991 
992 
993 static void
994 uves_mdark_region_qc(cpl_image* img,
995  const cpl_parameterlist* p,
996  const cpl_imagelist* raw_images,
997  const char* recipe_id,
998  cpl_table* qclog)
999 {
1000 
1001  int pr_num_x=4;
1002  int pr_num_y=4;
1003  int pr_box_sx=100;
1004  int pr_box_sy=100;
1005  int pr_border_x=100;
1006  int pr_border_y=100;
1007 
1008 
1009  int i=0;
1010  int j=0;
1011  int llx=0;
1012  int lly=0;
1013  int urx=0;
1014  int ury=0;
1015  int space_x=0;
1016  int space_y=0;
1017  int sx=0;
1018  int sy=0;
1019  int nraw=0;
1020  int raw=0;
1021  char name[MAX_NAME_SIZE];
1022  char pname[MAX_NAME_SIZE];
1023  char qc_key[MAX_NAME_SIZE];
1024  char qc_com[MAX_NAME_SIZE];
1025  double qc_avg=0;
1026  double qc_med=0;
1027  double qc_rms=0;
1028  double qc_min=0;
1029  double qc_max=0;
1030  cpl_table* qc_sto=NULL;
1031 
1032  check_nomsg(uves_extract_basic_parameters_for_qc(p,recipe_id,
1033  &pr_num_x,&pr_num_y,
1034  &pr_box_sx,&pr_box_sy));
1035 
1036  uves_msg("pr_num_x=%d pr_num_y=%d pr_box_sx=%d pr_box_sy=%d",
1037  pr_num_x,pr_num_y,pr_box_sx,pr_box_sy);
1038 
1039  if(pr_num_x <= 0 || pr_num_y <= 0 || pr_box_sx <= 0 || pr_box_sy <= 0) {
1040  return;
1041  }
1042 
1043  sprintf(name,"reg.border_x");
1044  sprintf(pname,"%s.%s", UVES_QCDARK_ID, name);
1045  check(uves_get_parameter(p,NULL,recipe_id,pname,CPL_TYPE_INT,&pr_border_x),
1046  "Could not read parameter");
1047 
1048  sprintf(name,"reg.border_y");
1049  sprintf(pname,"%s.%s", UVES_QCDARK_ID, name);
1050  check(uves_get_parameter(p,NULL,recipe_id,pname,CPL_TYPE_INT,&pr_border_y),
1051  "Could not read parameter");
1052 
1053 
1054  check_nomsg(nraw=cpl_imagelist_get_size(raw_images));
1056  "PRO DATANCOM",
1057  nraw,
1058  "Number of frames combined",
1059  "%d"));
1060 
1061  sx=cpl_image_get_size_x(img);
1062  sy=cpl_image_get_size_y(img);
1063  space_x=(int)((sx-2*pr_border_x)/pr_num_x);
1064  space_y=(int)((sy-2*pr_border_y)/pr_num_y);
1065  qc_sto=cpl_table_new(pr_num_x*pr_num_y);
1066  cpl_table_new_column(qc_sto,"MIN",CPL_TYPE_DOUBLE);
1067  cpl_table_new_column(qc_sto,"MAX",CPL_TYPE_DOUBLE);
1068  cpl_table_new_column(qc_sto,"AVG",CPL_TYPE_DOUBLE);
1069  cpl_table_new_column(qc_sto,"MED",CPL_TYPE_DOUBLE);
1070  cpl_table_new_column(qc_sto,"RMS",CPL_TYPE_DOUBLE);
1071 
1072  for(i=0;i<pr_num_x;i++) {
1073  llx=pr_border_x+i*space_x;
1074  urx=llx+pr_box_sx;
1075 
1076  llx=(llx>0) ? llx:1;
1077  urx=(urx<=sx) ? urx:sx;
1078 
1079  for(j=0;j<pr_num_y;j++) {
1080  lly=pr_border_y+j*space_y;
1081  ury=lly+pr_box_sy;
1082 
1083  lly=(lly>0) ? lly:1;
1084  ury=(ury<=sy) ? ury:sy;
1085 
1086  raw=i*pr_num_y+j;
1087  check_nomsg(qc_min=cpl_image_get_min_window(img,llx,lly,urx,ury));
1088  qc_max=cpl_image_get_min_window(img,llx,lly,urx,ury);
1089  qc_avg=cpl_image_get_mean_window(img,llx,lly,urx,ury);
1090  qc_med=cpl_image_get_median_window(img,llx,lly,urx,ury);
1091  qc_rms=cpl_image_get_stdev_window(img,llx,lly,urx,ury);
1092  uves_msg_debug("QC on area [%d,%d:%d,%d]. Min %g Max %g Avg %g Med %g Rms %g",
1093  llx,lly,urx,ury,qc_min,qc_max,qc_avg,qc_med,qc_rms);
1094 
1095  sprintf(qc_key,"%s%d%d%s","QC REG",i,j," MIN");
1096  sprintf(qc_com,"%s%d%d","Min of region [%d,%d]",i,j);
1097  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_min,qc_com,"%g"));
1098  check_nomsg(cpl_table_set_double(qc_sto,"MIN",raw,qc_min));
1099 
1100  sprintf(qc_key,"%s%d%d%s","QC REG",i,j," MAX");
1101  sprintf(qc_com,"%s%d%d","Max of region [%d,%d]",i,j);
1102  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_max,qc_com,"%g"));
1103  check_nomsg(cpl_table_set_double(qc_sto,"MAX",raw,qc_max));
1104 
1105  sprintf(qc_key,"%s%d%d%s","QC REG",i,j," AVG");
1106  sprintf(qc_com,"%s%d%d","Mean of region [%d,%d]",i,j);
1107  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_avg,qc_com,"%g"));
1108  check_nomsg(cpl_table_set_double(qc_sto,"AVG",raw,qc_avg));
1109 
1110  sprintf(qc_key,"%s%d%d%s","QC REG",i,j," MED");
1111  sprintf(qc_com,"%s%d%d","Median of region [%d,%d]",i,j);
1112  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_med,qc_com,"%g"));
1113  check_nomsg(cpl_table_set_double(qc_sto,"MED",raw,qc_med));
1114 
1115  sprintf(qc_key,"%s%d%d%s","QC REG",i,j," RMS");
1116  sprintf(qc_com,"%s%d%d","Rms of region [%d,%d]",i,j);
1117  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_rms,qc_com,"%g"));
1118  check_nomsg(cpl_table_set_double(qc_sto,"RMS",raw,qc_rms));
1119 
1120 
1121  }
1122  }
1123 
1124 
1125  check_nomsg(qc_min=cpl_table_get_column_min(qc_sto,"MIN"));
1126  check_nomsg(qc_max=cpl_table_get_column_max(qc_sto,"MIN"));
1127  check_nomsg(qc_avg=cpl_table_get_column_mean(qc_sto,"MIN"));
1128  check_nomsg(qc_med=cpl_table_get_column_median(qc_sto,"MIN"));
1129  check_nomsg(qc_rms=cpl_table_get_column_stdev(qc_sto,"MIN"));
1130 
1131  sprintf(qc_key,"%s","QC REG MIN MIN");
1132  sprintf(qc_com,"%s","Min of all Mins");
1133  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_min,qc_com,"%g"));
1134 
1135  sprintf(qc_key,"%s","QC REG MIN MAX");
1136  sprintf(qc_com,"%s","Max of all Mins");
1137  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_max,qc_com,"%g"));
1138 
1139  sprintf(qc_key,"%s","QC REG MIN AVG");
1140  sprintf(qc_com,"%s","Mean of all Mins");
1141  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_avg,qc_com,"%g"));
1142 
1143  sprintf(qc_key,"%s","QC REG MIN MED");
1144  sprintf(qc_com,"%s","Median of all Mins");
1145  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_med,qc_com,"%g"));
1146 
1147  sprintf(qc_key,"%s","QC REG MIN RMS");
1148  sprintf(qc_com,"%s","Rms of all Mins");
1149  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_rms,qc_com,"%g"));
1150 
1151 
1152 
1153  check_nomsg(qc_min=cpl_table_get_column_min(qc_sto,"MAX"));
1154  check_nomsg(qc_max=cpl_table_get_column_max(qc_sto,"MAX"));
1155  check_nomsg(qc_avg=cpl_table_get_column_mean(qc_sto,"MAX"));
1156  check_nomsg(qc_med=cpl_table_get_column_median(qc_sto,"MAX"));
1157  check_nomsg(qc_rms=cpl_table_get_column_stdev(qc_sto,"MAX"));
1158 
1159  sprintf(qc_key,"%s","QC REG MAX MIN");
1160  sprintf(qc_com,"%s","Min of all Maxs");
1161  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_min,qc_com,"%g"));
1162 
1163  sprintf(qc_key,"%s","QC REG MAX MAX");
1164  sprintf(qc_com,"%s","Max of all Maxs");
1165  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_max,qc_com,"%g"));
1166 
1167  sprintf(qc_key,"%s","QC REG MAX AVG");
1168  sprintf(qc_com,"%s","Mean of all Maxs");
1169  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_avg,qc_com,"%g"));
1170 
1171  sprintf(qc_key,"%s","QC REG MAX MED");
1172  sprintf(qc_com,"%s","Median of all Maxs");
1173  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_med,qc_com,"%g"));
1174 
1175  sprintf(qc_key,"%s","QC REG MAX RMS");
1176  sprintf(qc_com,"%s","Rms of all Maxs");
1177  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_rms,qc_com,"%g"));
1178 
1179 
1180  check_nomsg(qc_min=cpl_table_get_column_min(qc_sto,"AVG"));
1181  check_nomsg(qc_max=cpl_table_get_column_max(qc_sto,"AVG"));
1182  check_nomsg(qc_avg=cpl_table_get_column_mean(qc_sto,"AVG"));
1183  check_nomsg(qc_med=cpl_table_get_column_median(qc_sto,"AVG"));
1184  check_nomsg(qc_rms=cpl_table_get_column_stdev(qc_sto,"AVG"));
1185 
1186  sprintf(qc_key,"%s","QC REG AVG MIN");
1187  sprintf(qc_com,"%s","Min of all Means");
1188  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_min,qc_com,"%g"));
1189 
1190  sprintf(qc_key,"%s","QC REG AVG MAX");
1191  sprintf(qc_com,"%s","Max of all Means");
1192  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_max,qc_com,"%g"));
1193 
1194  sprintf(qc_key,"%s","QC REG AVG AVG");
1195  sprintf(qc_com,"%s","Mean of all Means");
1196  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_avg,qc_com,"%g"));
1197 
1198  sprintf(qc_key,"%s","QC REG AVG MED");
1199  sprintf(qc_com,"%s","Median of all Means");
1200  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_med,qc_com,"%g"));
1201 
1202  sprintf(qc_key,"%s","QC REG AVG RMS");
1203  sprintf(qc_com,"%s","Rms of all Means");
1204  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_rms,qc_com,"%g"));
1205 
1206 
1207  check_nomsg(qc_min=cpl_table_get_column_min(qc_sto,"MED"));
1208  check_nomsg(qc_max=cpl_table_get_column_max(qc_sto,"MED"));
1209  check_nomsg(qc_avg=cpl_table_get_column_mean(qc_sto,"MED"));
1210  check_nomsg(qc_med=cpl_table_get_column_median(qc_sto,"MED"));
1211  check_nomsg(qc_rms=cpl_table_get_column_stdev(qc_sto,"MED"));
1212 
1213  sprintf(qc_key,"%s","QC REG MED MIN");
1214  sprintf(qc_com,"%s","Min of all Medians");
1215  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_min,qc_com,"%g"));
1216 
1217  sprintf(qc_key,"%s","QC REG MED MAX");
1218  sprintf(qc_com,"%s","Max of all Medians");
1219  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_max,qc_com,"%g"));
1220 
1221  sprintf(qc_key,"%s","QC REG MED AVG");
1222  sprintf(qc_com,"%s","Mean of all Medians");
1223  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_avg,qc_com,"%g"));
1224 
1225  sprintf(qc_key,"%s","QC REG MED MED");
1226  sprintf(qc_com,"%s","Median of all Medians");
1227  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_med,qc_com,"%g"));
1228 
1229  sprintf(qc_key,"%s","QC REG MED RMS");
1230  sprintf(qc_com,"%s","Rms of all Medians");
1231  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_rms,qc_com,"%g"));
1232 
1233 
1234  check_nomsg(qc_min=cpl_table_get_column_min(qc_sto,"RMS"));
1235  check_nomsg(qc_max=cpl_table_get_column_max(qc_sto,"RMS"));
1236  check_nomsg(qc_avg=cpl_table_get_column_mean(qc_sto,"RMS"));
1237  check_nomsg(qc_med=cpl_table_get_column_median(qc_sto,"RMS"));
1238  check_nomsg(qc_rms=cpl_table_get_column_stdev(qc_sto,"RMS"));
1239 
1240 
1241  sprintf(qc_key,"%s","QC REG RMS MIN");
1242  sprintf(qc_com,"%s","Min of all Rms");
1243  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_min,qc_com,"%g"));
1244 
1245  sprintf(qc_key,"%s","QC REG RMS MAX");
1246  sprintf(qc_com,"%s","Max of all Rms");
1247  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_max,qc_com,"%g"));
1248 
1249  sprintf(qc_key,"%s","QC REG RMS AVG");
1250  sprintf(qc_com,"%s","Mean of all Rms");
1251  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_avg,qc_com,"%g"));
1252 
1253  sprintf(qc_key,"%s","QC REG RMS MED");
1254  sprintf(qc_com,"%s","Median of all Rms");
1255  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_med,qc_com,"%g"));
1256 
1257  sprintf(qc_key,"%s","QC REG RMS RMS");
1258  sprintf(qc_com,"%s","Rms of all Rms");
1259  check_nomsg(uves_qclog_add_double(qclog,qc_key,qc_rms,qc_com,"%g"));
1260 
1261 
1262 
1263 
1264  cleanup:
1265  uves_free_table(&qc_sto);
1266 
1267  return;
1268 
1269 }
1270 
1271 
#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