UVES Pipeline Reference Manual  5.4.4
uves_mbias_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-11-02 15:43:23 $
23  * $Revision: 1.62 $
24  * $Name: not supported by cvs2svn $
25  * $Log: not supported by cvs2svn $
26  * Revision 1.61 2011/09/09 09:56:21 amodigli
27  * using irplib_mkmaster() functionality
28  *
29  * Revision 1.60 2010/09/24 09:49:18 amodigli
30  * added info on mean master bias level as asked by Daniel
31  *
32  * Revision 1.59 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.57 2010/08/30 14:16:08 amodigli
36  * fixed problem computing QC.RON.OUTi.RAW (DFS09268)
37  *
38  * Revision 1.56 2010/06/11 11:40:46 amodigli
39  * rename method to stack_method
40  *
41  * Revision 1.55 2010/06/02 09:20:44 amodigli
42  * added correction of bias level before computation of median stack-then put back mean of levels on master bias
43  *
44  * Revision 1.54 2010/03/31 10:09:59 amodigli
45  * added description
46  *
47  * Revision 1.53 2010/03/22 15:58:02 amodigli
48  * added params and possibility to compute master as mean stack
49  *
50  * Revision 1.52 2009/10/29 17:16:29 amodigli
51  * added param to specify if red cdd is new/old in call to uves_get_badpix
52  *
53  * Revision 1.51 2008/09/29 06:56:48 amodigli
54  * add #include <string.h>
55  *
56  * Revision 1.50 2008/05/01 09:51:03 amodigli
57  * fixed compiler warnings
58  *
59  * Revision 1.49 2008/04/02 14:02:02 amodigli
60  * fixed compilation warnings
61  *
62  * Revision 1.48 2008/03/28 08:53:43 amodigli
63  * IRPLIB_CONCAT2X-->UVES_CONCAT2X
64  *
65  * Revision 1.47 2008/03/04 15:20:59 amodigli
66  * fixed redchain problem with clean_traps parameter
67  *
68  * Revision 1.46 2008/03/03 16:34:03 amodigli
69  * added parameter to control trap column correction
70  *
71  * Revision 1.45 2008/02/15 12:43:49 amodigli
72  * allow lower/upper chip for parameter process_chip
73  *
74  * Revision 1.44 2007/10/05 16:01:44 amodigli
75  * using proces_chip parameter to process or not a given RED chip
76  *
77  * Revision 1.43 2007/08/21 13:08:26 jmlarsen
78  * Removed irplib_access module, largely deprecated by CPL-4
79  *
80  * Revision 1.42 2007/06/11 13:28:26 jmlarsen
81  * Changed recipe contact address to cpl at eso.org
82  *
83  * Revision 1.41 2007/06/08 13:06:16 jmlarsen
84  * Send bug reports to Andrea
85  *
86  * Revision 1.40 2007/06/06 08:17:33 amodigli
87  * replace tab with 4 spaces
88  *
89  * Revision 1.39 2007/05/22 11:31:35 jmlarsen
90  * Removed image plotting functionality
91  *
92  * Revision 1.38 2007/04/24 12:50:29 jmlarsen
93  * Replaced cpl_propertylist -> uves_propertylist which is much faster
94  *
95  * Revision 1.37 2007/02/27 07:42:21 jmlarsen
96  * Fixed bug when counting non-rejected pixels
97  *
98  * Revision 1.36 2007/02/26 10:15:56 jmlarsen
99  * Be robust against the unlikely case that there are no good pixels to compute QC stats
100  *
101  * Revision 1.35 2007/02/23 13:32:43 jmlarsen
102  * Change QC computation to exactly match MIDAS' STAT/IMAGE
103  *
104  * Revision 1.34 2007/02/09 13:37:43 jmlarsen
105  * Enable calling from uves_cal_mkmaster
106  *
107  * Revision 1.33 2007/02/09 08:57:29 jmlarsen
108  * Do not use CPL_PIXEL_MAXVAL which works only for integer images
109  *
110  * Revision 1.32 2007/02/09 08:14:16 jmlarsen
111  * Do not use CPL_PIXEL_MAXVAL which works only for integer images
112  *
113  * Revision 1.31 2007/01/10 12:37:39 jmlarsen
114  * Removed obsolete comments
115  *
116  * Revision 1.30 2006/12/07 08:23:23 jmlarsen
117  * uves_load_raw_imagelist: support FLAMES
118  *
119  * Revision 1.29 2006/11/15 15:02:14 jmlarsen
120  * Implemented const safe workarounds for CPL functions
121  *
122  * Revision 1.27 2006/11/15 14:04:08 jmlarsen
123  * Removed non-const version of parameterlist_get_first/last/next which is
124  * already in CPL, added const-safe wrapper, unwrapper and deallocator functions
125  *
126  * Revision 1.26 2006/11/06 15:19:41 jmlarsen
127  * Removed unused include directives
128  *
129  * Revision 1.25 2006/10/17 12:33:02 jmlarsen
130  * Added semicolon at UVES_RECIPE_DEFINE invocation
131  *
132  * Revision 1.24 2006/10/09 13:01:13 jmlarsen
133  * Use macro to define recipe interface functions
134  *
135  * Revision 1.23 2006/09/19 14:31:10 jmlarsen
136  * uves_insert_frame(): use bitmap to specify which image statistics keywords must
137  * be computed
138  *
139  * Revision 1.22 2006/09/19 06:55:52 jmlarsen
140  * Changed interface of uves_frameset to optionally write image statistics kewwords
141  *
142  * Revision 1.21 2006/08/24 11:36:37 jmlarsen
143  * Write recipe start/stop time to header
144  *
145  * Revision 1.20 2006/08/18 13:35:42 jmlarsen
146  * Fixed/changed QC parameter formats
147  *
148  * Revision 1.19 2006/08/17 13:56:53 jmlarsen
149  * Reduced max line length
150  *
151  * Revision 1.18 2006/08/11 14:56:05 amodigli
152  * removed Doxygen warnings
153  *
154  * Revision 1.17 2006/08/10 10:52:11 jmlarsen
155  * Bugfix in comparison of chip id
156  *
157  * Revision 1.16 2006/07/14 12:19:28 jmlarsen
158  * Support multiple QC tests per product
159  *
160  * Revision 1.15 2006/07/03 13:09:24 amodigli
161  * adjusted description display layout
162  *
163  * Revision 1.14 2006/07/03 12:58:34 jmlarsen
164  * Support flagging instead of interpolating bad pixels
165  *
166  * Revision 1.13 2006/06/22 08:58:33 jmlarsen
167  * Use correct port number for QC
168  *
169  * Revision 1.12 2006/06/16 08:25:45 jmlarsen
170  * Manually propagate ESO.DET. keywords from 1st/2nd input header
171  *
172  * Revision 1.11 2006/06/07 09:01:28 amodigli
173  * added some doc
174  *
175  * Revision 1.10 2006/06/06 08:40:50 jmlarsen
176  * Changed order of messages
177  *
178  * Revision 1.9 2006/05/12 15:40:08 jmlarsen
179  * Fixed mixed code declarations
180  *
181  * Revision 1.8 2006/05/09 15:42:00 amodigli
182  * added QC log
183  *
184  * Revision 1.7 2006/05/08 16:47:15 amodigli
185  * added QC
186  *
187  * Revision 1.6 2006/05/08 15:38:46 amodigli
188  * made changes to have port-id
189  *
190  * Revision 1.5 2006/05/05 14:33:22 jmlarsen
191  * Removed debugging message
192  *
193  * Revision 1.4 2006/05/05 13:54:52 jmlarsen
194  * Removed warnings about unused variables
195  *
196  * Revision 1.3 2006/04/20 10:47:39 amodigli
197  * added qclog
198  *
199  * Revision 1.2 2006/04/06 09:48:15 amodigli
200  * changed uves_frameset_insert interface to have QC log
201  *
202  * Revision 1.1 2006/02/03 07:46:30 jmlarsen
203  * Moved recipe implementations to ./uves directory
204  *
205  * Revision 1.42 2006/01/19 08:47:24 jmlarsen
206  * Inserted missing doxygen end tag
207  *
208  * Revision 1.41 2005/12/19 16:17:55 jmlarsen
209  * Replaced bool -> int
210  *
211  */
212 
213 #ifdef HAVE_CONFIG_H
214 # include <config.h>
215 #endif
216 
217 /*----------------------------------------------------------------------------*/
224 /*----------------------------------------------------------------------------*/
225 
226 /*-----------------------------------------------------------------------------
227  Includes
228  -----------------------------------------------------------------------------*/
229 #include <uves_mbias_impl.h>
230 
231 #include <uves_utils.h>
232 #include <uves_corrbadpix.h>
233 #include <uves_parameters.h>
234 #include <uves.h>
235 #include <uves_dfs.h>
236 #include <uves_pfits.h>
237 #include <uves_qclog.h>
238 #include <uves_recipe.h>
239 #include <uves_utils_wrappers.h>
240 #include <uves_error.h>
241 #include <irplib_mkmaster.h>
242 #include <uves_msg.h>
243 
244 /* Library */
245 #include <cpl.h>
246 #include <float.h>
247 #include <ctype.h>
248 #include <string.h>
249 /*-----------------------------------------------------------------------------
250  Functions prototypes
251  -----------------------------------------------------------------------------*/
252 
253 static void uves_mbias_qclog(const cpl_imagelist* raw_imgs,
254  uves_propertylist **raw_headers,
255  enum uves_chip chip,
256  const cpl_image* mbia,
257  /* int sx_pix, Size of X bin in pix
258  int sy_pix, Size of Y bin in pix */
259  cpl_table* qclog
260  );
261 
262 static void
263 uves_mbias_qc_ron_raw(const cpl_image* rbia,
264  enum uves_chip chip,
265  const int x_cent_s,
266  const int x_cent_e,
267  const int y_cent_s,
268  const int y_cent_e,
269  cpl_table* qclog);
270 
271 static int
272 uves_mbias_define_parameters(cpl_parameterlist *parameters);
273 
274 /*-----------------------------------------------------------------------------
275  Recipe standard code
276  -----------------------------------------------------------------------------*/
277 #define cpl_plugin_get_info uves_mbias_get_info
278 UVES_RECIPE_DEFINE(
279  UVES_MBIAS_ID, UVES_MBIAS_DOM,
280  /* Warning: if more parameters are added to this recipe, they
281  need to be propagated to uves_cal_mkmaster! */
282  uves_mbias_define_parameters,
283  "Jonas M. Larsen", "cpl@eso.org",
284  "Creates the master bias frame",
285  "This recipe creates a master bias frame by computing the median of all input\n"
286  "bias frames. All input frames must have same tag and size and must be either\n"
287  "BIAS_BLUE or BIAS_RED.\n"
288  "On blue input the recipe computes one master bias frame; on red input a \n"
289  "master bias frame for each chip is produced. The average, standard deviation\n"
290  "and median of the master bias image(s) are written to the FITS header(s)");
291 
292 
293 /*-----------------------------------------------------------------------------
294  Functions code
295  -----------------------------------------------------------------------------*/
298 /*----------------------------------------------------------------------------*/
305 /*----------------------------------------------------------------------------*/
306 int uves_mbias_define_parameters_body(cpl_parameterlist *parameters,
307  const char *recipe_id)
308 {
309 
310  /*****************
311  * General *
312  *****************/
313  if (uves_define_global_parameters(parameters) != CPL_ERROR_NONE)
314  {
315  return -1;
316  }
317 
318  /**************************************
319  * detector's trap correction *
320  **************************************/
321 
322  if (uves_corr_traps_define_parameters(parameters,recipe_id)
323  != CPL_ERROR_NONE)
324  {
325  return -1;
326  }
327 
328  /**************************************
329  * Master stack generation *
330  **************************************/
331 
332  if (uves_master_stack_define_parameters(parameters,recipe_id)
333  != CPL_ERROR_NONE)
334  {
335  return -1;
336  }
337 
338  return (cpl_error_get_code() != CPL_ERROR_NONE);
339 }
340 
341 
342 
343 /*----------------------------------------------------------------------------*/
349 /*----------------------------------------------------------------------------*/
350 static int
351 uves_mbias_define_parameters(cpl_parameterlist *parameters)
352 {
353  return uves_mbias_define_parameters_body(parameters, make_str(UVES_MBIAS_ID));
354 }
355 
356 
357 
358 
359 
360 /*----------------------------------------------------------------------------*/
377 /*----------------------------------------------------------------------------*/
378 static cpl_image *
379 uves_mbias_process_chip(const cpl_imagelist *raw_images,
380  uves_propertylist **raw_headers,
381  uves_propertylist *mbias_header,
382  int binx, int biny,
383  enum uves_chip chip,
384  bool CLEAN_TRAPS,
385  const char* STACK_METHOD,
386  const double STACK_KLOW,
387  const double STACK_KHIGH,
388  const int STACK_NITER)
389 {
390  cpl_image *master_bias = NULL; /* Result */
391  double exposure_time = 0;
392  int badpixels_cleaned;
393  int i;
394  int nraw=0;
395  bool red_ccd_is_new=false;
396  cpl_vector* bias_levels=NULL;
397  double bias_mean=0;
398 
399  uves_msg("Calculating master bias...");
400 
401  check_nomsg(red_ccd_is_new=uves_ccd_is_new(raw_headers[0]));
402  /* Get the median at each pixel */
403  if(strcmp(STACK_METHOD,"MEDIAN")==0) {
404  uves_msg("method median");
405  master_bias=irplib_mkmaster_median(raw_images,5.,5,1.e-5);
406  } else {
407  uves_msg("method mean");
408  master_bias=irplib_mkmaster_mean(raw_images,5.,5,1.e-5,STACK_KLOW,STACK_KHIGH,STACK_NITER);
409  }
410 
411  /* Set mbias exposure time to average of inputs */
412  exposure_time = 0;
413  nraw=cpl_imagelist_get_size(raw_images);
414  for (i = 0; i < nraw; i++)
415  {
416  check( exposure_time += uves_pfits_get_exptime(raw_headers[i]),
417  "Error reading exposure time");
418  }
419  exposure_time /= nraw;
420 
421  uves_pfits_set_extname(mbias_header,"Master bias");
422 
423  check( uves_pfits_set_exptime(mbias_header, exposure_time),
424  "Error setting master bias exposure time");
425  if(CLEAN_TRAPS) {
426  check( badpixels_cleaned =
427  uves_correct_badpix_all(master_bias, mbias_header,
428  chip, binx, biny, false,red_ccd_is_new),
429  "Error replacing bad pixels");
430 
431  uves_msg("%d bad pixels replaced", badpixels_cleaned);
432  }
433 
434  cleanup:
435  if (cpl_error_get_code() != CPL_ERROR_NONE)
436  {
437  uves_free_image(&master_bias);
438  }
439 
440  return master_bias;
441 }
442 
443 /*----------------------------------------------------------------------------*/
450 /*----------------------------------------------------------------------------*/
451 static void
452 UVES_CONCAT2X(UVES_MBIAS_ID,exe)(cpl_frameset *frames,
453  const cpl_parameterlist *parameters,
454  const char *starttime)
455 {
456  uves_mbias_exe_body(frames, parameters, starttime, make_str(UVES_MBIAS_ID));
457  return;
458 }
459 
460 /*----------------------------------------------------------------------------*/
471 /*----------------------------------------------------------------------------*/
472 void
473 uves_mbias_exe_body(cpl_frameset *frames,
474  const cpl_parameterlist *parameters,
475  const char *starttime,
476  const char *recipe_id)
477 {
478  /* Input */
479  cpl_imagelist *raw_images[2] = {NULL, NULL};
480  uves_propertylist **raw_headers[2] = {NULL, NULL}; /* Two arrays of pointers */
481 
482  cpl_table* qclog[2] = {NULL, NULL};
483 
484  /* Output */
485  uves_propertylist *product_header[2] = {NULL, NULL};
486  cpl_image *master_bias = NULL;
487  cpl_stats *mbias_stats = NULL;
488 
489  /* Local variables */
490  char *product_filename = NULL;
491  bool blue;
492  enum uves_chip chip;
493  int binx, biny;
494  const char* PROCESS_CHIP=NULL;
495  bool CLEAN_TRAPS;
496  int raw_index = 0;
497  int i=0;
498 
499  const char* STACK_METHOD=NULL;
500  double STACK_KLOW=0;
501  double STACK_KHIGH=0;
502  int STACK_NITER=0;
503 
504  /* Load and check raw bias images and headers, identify arm (blue/red) */
505  /* On success, 'raw_headers' will be arrays with the same length as 'raw_images' */
506  check( uves_load_raw_imagelist(frames,
507  false, /* FLAMES format? (no) */
508  UVES_BIAS(true), UVES_BIAS(false),
509  CPL_TYPE_DOUBLE,
510  raw_images, raw_headers, product_header,
511  &blue), "Error loading raw frames");
512 
513  /* Get binning from first header (i.e. BLUE or REDL chip, first raw frame) */
514  check( binx = uves_pfits_get_binx(raw_headers[0][0]),
515  "Could not get raw frame x-binning");
516  check( biny = uves_pfits_get_biny(raw_headers[0][0]),
517  "Could not get raw frame y-binning");
518  check( uves_get_parameter(parameters, NULL, "uves", "process_chip", CPL_TYPE_STRING, &PROCESS_CHIP),
519  "Could not read parameter");
520  uves_string_toupper((char*)PROCESS_CHIP);
521 
522  check( uves_get_parameter(parameters, NULL, recipe_id, "clean_traps", CPL_TYPE_BOOL, &CLEAN_TRAPS),
523  "Could not read parameter");
524 
525  check( uves_get_parameter(parameters, NULL, recipe_id, "stack_method", CPL_TYPE_STRING, &STACK_METHOD),
526  "Could not read parameter");
527  uves_string_toupper((char*)STACK_METHOD);
528 
529  check( uves_get_parameter(parameters, NULL, recipe_id, "klow", CPL_TYPE_DOUBLE, &STACK_KLOW),
530  "Could not read parameter");
531  check( uves_get_parameter(parameters, NULL, recipe_id, "khigh", CPL_TYPE_DOUBLE, &STACK_KHIGH),
532  "Could not read parameter");
533  check( uves_get_parameter(parameters, NULL, recipe_id, "niter", CPL_TYPE_INT, &STACK_NITER),
534  "Could not read parameter");
535 
536  /* Loop over one or two chips */
537  for (chip = uves_chip_get_first(blue);
538  chip != UVES_CHIP_INVALID;
539  chip = uves_chip_get_next(chip))
540  {
541  if(strcmp(PROCESS_CHIP,"REDU") == 0) {
542  chip = uves_chip_get_next(chip);
543  }
544  raw_index = uves_chip_get_index(chip);
545 
546  uves_msg("Processing %s chip",
548 
549  uves_msg_debug("Binning = %dx%d", binx, biny);
550 
551  /* Process chip */
552  uves_free_image(&master_bias);
553  check( master_bias = uves_mbias_process_chip(raw_images[raw_index],
554  raw_headers[raw_index],
555  product_header[raw_index],
556  binx, biny,
557  chip,CLEAN_TRAPS,
558  STACK_METHOD,
559  STACK_KLOW,
560  STACK_KHIGH,
561  STACK_NITER),
562  "Error processing chip");
563 
564 
565  cpl_free(product_filename);
566  check( product_filename = uves_masterbias_filename(chip),
567  "Error getting filename");
568 
569  /* Finished. Calculate QC parameters and save */
570  uves_msg("Calculating QC parameters");
571  uves_qclog_delete(&qclog[0]);
572  qclog[0] = uves_qclog_init(raw_headers[raw_index][0], chip);
573  check(uves_mbias_qclog(raw_images[raw_index],
574  raw_headers[raw_index],
575  chip,
576  master_bias,
577  /* binx,biny, */
578  qclog[0]),"error computing qclog");
579 
580  /* Insert into frame set */
581  uves_msg("Saving product...");
582 
583  check( uves_frameset_insert(frames,
584  master_bias,
585  CPL_FRAME_GROUP_PRODUCT,
586  CPL_FRAME_TYPE_IMAGE,
587  CPL_FRAME_LEVEL_INTERMEDIATE,
588  product_filename,
589  UVES_MASTER_BIAS(chip),
590  raw_headers[raw_index][0], /* First frame */
591  product_header[raw_index],
592  NULL,
593  parameters,
594  recipe_id,
595  PACKAGE "/" PACKAGE_VERSION,qclog,
596  starttime, true,
597  UVES_ALL_STATS),
598  "Could not add master bias %s to frameset", product_filename);
599  uves_qclog_delete(&qclog[0]);
600  uves_msg("Master bias '%s' added to frameset", product_filename);
601 
602  if(strcmp(PROCESS_CHIP,"REDL") == 0) {
603  chip = uves_chip_get_next(chip);
604  }
605 
606 
607  } /* For each chip */
608 
609  cleanup:
610  /* Input */
611  if (raw_images[0] != NULL)
612  {
613 
614  for (i = 0; i < cpl_imagelist_get_size(raw_images[0]); i++)
615  {
616  if (raw_headers[0] != NULL) uves_free_propertylist(&raw_headers[0][i]);
617  if (raw_headers[1] != NULL) uves_free_propertylist(&raw_headers[1][i]);
618  }
619  cpl_free(raw_headers[0]); raw_headers[0] = NULL;
620  cpl_free(raw_headers[1]); raw_headers[1] = NULL;
621  }
622  uves_free_imagelist(&raw_images[0]);
623  uves_free_imagelist(&raw_images[1]);
624  /* Output */
625 
626  uves_qclog_delete(&qclog[0]);
627  uves_free_image(&master_bias);
628  uves_free_propertylist(&product_header[0]);
629  uves_free_propertylist(&product_header[1]);
630  cpl_free(product_filename);
631  uves_free_stats(&mbias_stats);
632 
633  return;
634 }
635 
636 
637 
638 static int
639 count_good(const cpl_image *image)
640 {
641  return
642  cpl_image_get_size_x(image) * cpl_image_get_size_y(image) -
643  cpl_image_count_rejected(image);
644 }
645 /*----------------------------------------------------------------------------*/
652 /*----------------------------------------------------------------------------*/
653 static void
654 reject_lo_hi(cpl_image *image, double min, double max)
655 {
656  cpl_mask *mask_lo = NULL;
657  cpl_mask *mask_hi = NULL;
658 
659  mask_lo = cpl_mask_threshold_image_create(image, -DBL_MAX, min);
660  mask_hi = cpl_mask_threshold_image_create(image, max, DBL_MAX);
661  assure_mem( mask_lo );
662  assure_mem( mask_hi );
663 
664  cpl_mask_or(mask_lo, mask_hi);
665 
666  cpl_image_reject_from_mask(image, mask_lo);
667 
668  cleanup:
669  uves_free_mask(&mask_lo);
670  uves_free_mask(&mask_hi);
671  return;
672 }
673 
684 static void uves_mbias_qclog(const cpl_imagelist* raw_imgs,
685  uves_propertylist **raw_headers,
686  enum uves_chip chip,
687  const cpl_image* mbia,
688  /* int sx_pix, Size of X bin in pix
689  int sy_pix, Size of Y bin in pix */
690  cpl_table* qclog
691  )
692 {
693  int nx_pix= 0; /* No of X pix */
694  int ny_pix= 0; /* No of Y pix */
695 
696  int sample_x= 100; /* X size of sampling window in pix */
697  int sample_y= 100; /* Y size of sampling window in pix */
698  int x_cent_s= 0; /* X sampling window starting point */
699  int x_cent_e= 0; /* X sampling window ending point */
700  int y_cent_s= 0; /* Y sampling window starting point */
701  int y_cent_e= 0; /* Y sampling window ending point */
702 
703 
704 
705 
706 
707  double upp_threshold= 0.0;
708  double low_threshold= 0.0;
709  double extra=0.1;
710  double qc_ron_master= 0.0;
711 
712  double master_median=0.0;
713  int pn= 0;
714 
715 
716  double min=0.0;
717  double max=0.0;
718  double struct_col=0.0;
719  double struct_row=0.0;
720 
721  double time_s=+9999999.0;
722  double time_e=-9999999.0;
723  int nraw=0;
724  double qc_duty_cycle=0.;
725  double exposure_time=0;
726  int i=0;
727  char key_name[80];
728 
729  const cpl_image* rbia=NULL;
730  cpl_image* tima=NULL;
731  cpl_image* avg_col=NULL;
732  cpl_image* avg_row=NULL;
733 
734  uves_qclog_add_string(qclog,
735  "QC TEST1 ID",
736  "Test-on-Master-Bias",
737  "Name of QC test",
738  "%s");
739 
740  uves_msg("Computing duty cycle...");
741 
742  /* Set mbias exposure time to average of inputs */
743  exposure_time = 0;
744  nraw = cpl_imagelist_get_size(raw_imgs);
746  "PRO DATANCOM",
747  nraw,
748  "Number of frames combined",
749  "%d"));
750 
751 
752  for (i = 0; i < nraw; i++)
753  {
754  check( exposure_time = uves_pfits_get_mjdobs(raw_headers[i]),
755  "Error reading exposure time");
756  if(exposure_time >= time_e) time_e = exposure_time;
757  if(exposure_time <= time_s) time_s = exposure_time;
758  }
759  if(nraw > 1) {
760  qc_duty_cycle = (time_e-time_s)/ (nraw-1);
761  }
762  else
763  {
764  qc_duty_cycle = 0;
765  }
766 
768  "QC DUTYCYCL",
769  qc_duty_cycle,
770  "Time to store a frame",
771  "%.5e"));
772 
773  /* The following is not really used in MIDAS so we comment
774  strcpy(date,uves_pfits_get_tpl_start(plist));
775  */
776 
777 
778  /* CONVERT FROM MIDAS
779  nx_pix = m$value({mbia},NPIX(1));
780  ny_pix = m$value({mbia},NPIX(2));
781  */
782 
783  nx_pix = cpl_image_get_size_x(mbia);
784  ny_pix = cpl_image_get_size_y(mbia);
785 
786 
787  x_cent_s = (nx_pix - sample_x)/2;
788  x_cent_e = (nx_pix + sample_x)/2;
789  y_cent_s = (ny_pix - sample_y)/2;
790  y_cent_e = (ny_pix + sample_y)/2;
791 
792 
793  check_nomsg(upp_threshold =
794  cpl_image_get_median_window(mbia,
795  x_cent_s,
796  y_cent_s,
797  x_cent_e,
798  y_cent_e)*(1 + extra));
799  check_nomsg(low_threshold =
800  cpl_image_get_median_window(mbia,
801  x_cent_s,
802  y_cent_s,
803  x_cent_e,
804  y_cent_e)*(1 - extra));
805 
806  /* convert from MIDAS
807  pn = {uves_portid({PATHID})};
808  */
809  check_nomsg(pn = PORT_ID(chip));
810  uves_msg_debug("Port number = %d", pn);
811 
812  rbia = cpl_imagelist_get_const(raw_imgs,0);
813  check_nomsg(uves_mbias_qc_ron_raw(rbia, chip,
814  x_cent_s,x_cent_e,y_cent_s,y_cent_e,qclog));
815 
816 
817  /* convert from MIDAS
818  stat/ima {mbia} + bins=1 exc={low_threshold},{upp_threshold};
819  */
820  check_nomsg(tima=cpl_image_duplicate(mbia));
821 
822  check_nomsg( reject_lo_hi(tima, low_threshold, upp_threshold) );
823  if (count_good(tima) >= 2)
824  {
825  check_nomsg(master_median = cpl_image_get_median(tima));
826  check_nomsg(qc_ron_master = cpl_image_get_stdev(tima));
827  }
828  else
829  {
830  master_median = -1;
831  qc_ron_master = -1;
832  uves_msg_warning("Only %d good pixels in image. Setting QC parameters to -1",
833  count_good(tima));
834  }
835  uves_free_image(&tima);
836 
838  "PRO DATAMED",
839  master_median,
840  "Median of pixel values",
841  "%7.3f"));
842 
843  sprintf(key_name, "QC OUT%d RON MASTER", pn);
845  key_name,
846  qc_ron_master,
847  "Read noise frame in ADU",
848  "%8.4f"));
849 
850  /* ==========================
851  * Calculates Bias struct
852  * ==========================
853  */
854 
855 
856  /*
857  * in case of RED frame cuts out values greater than 300.
858  * as the frame can be affected by this local operation we
859  * do the calculation on a copy of the original frame
860  */
861 
862 
863  check_nomsg(tima=cpl_image_duplicate(mbia));
864  if (chip != UVES_CHIP_BLUE) {
865  /*
866  replace/ima {mbia} {tmpfrm} 300,>=300.;
867  */
868  check_nomsg(cpl_image_threshold(tima,
869  -DBL_MAX,300,
870  -DBL_MAX,300));
871  }
872 
873 
874  check_nomsg(avg_col = cpl_image_collapse_create(tima,1));
875  check_nomsg(cpl_image_divide_scalar(avg_col,cpl_image_get_size_x(tima)));
876 
877  /* restricts statistics to +/- 2 ADU around mean */
878  min = cpl_image_get_mean(avg_col) - 2;
879  max = cpl_image_get_mean(avg_col) + 2;
880 
881  /* replace with MIDAS
882  stat/ima avg_col + exc={min},{max};
883  */
884  check_nomsg( reject_lo_hi(avg_col, min, max) );
885  if (count_good(avg_col) >= 2)
886  {
887  check_nomsg(struct_col = cpl_image_get_stdev(avg_col));
888  }
889  else
890  {
891  struct_col = -1;
892  uves_msg_warning("Only %d good pixels in image. Setting QC parameter to -1",
893  count_good(avg_col));
894  }
895 
896  sprintf(key_name,"%s%d%s","QC OUT",pn," STRUCTY");
898  key_name,
899  struct_col,
900  "structure in Y (bias slope)",
901  "%8.4f"));
902 
903 
904 
905  check_nomsg(avg_row = cpl_image_collapse_create(tima,0));
906  check_nomsg(cpl_image_divide_scalar(avg_row,cpl_image_get_size_y(tima)));
907 
908  /* restricts statistics to +/- 2 ADU around mean */
909  min = cpl_image_get_mean(avg_row) - 2;
910  max = cpl_image_get_mean(avg_row) + 2;
911 
912  /* replace with MIDAS
913  stat/ima avg_row + exc={min},{max};
914  */
915  check_nomsg( reject_lo_hi(avg_row, min, max) );
916  if (count_good(avg_row) >= 2)
917  {
918  check_nomsg(struct_row = cpl_image_get_stdev(avg_row));
919  }
920  else
921  {
922  struct_row = -1;
923  uves_msg_warning("Only %d good pixels in image. Setting QC parameter to -1",
924  count_good(avg_row));
925  }
926 
927 
928  sprintf(key_name,"%s%d%s","QC OUT",pn," STRUCTX");
930  key_name,
931  struct_row,
932  "structure in X (bias slope)",
933  "%8.4f"));
934 
935 
936 
937 
938  cleanup:
939  uves_free_image(&avg_col);
940  uves_free_image(&avg_row);
941  uves_free_image(&tima);
942 
943  return;
944 
945 }
959 static void
960 uves_mbias_qc_ron_raw(const cpl_image* rbia,
961  enum uves_chip chip,
962  const int x_cent_s,
963  const int x_cent_e,
964  const int y_cent_s,
965  const int y_cent_e,
966  cpl_table* qclog)
967 {
968 
969  double qc_ron_raw=0.0;
970  double upp_threshold=0.0;
971  double low_threshold=0.0;
972  double extra=0.1;
973  char key_name[80];
974  int pn=0;
975  cpl_image* tima=NULL;
976 
977  /* replace with MIDAS
978  date = "{{mbia},ESO.TPL.START}";
979  store/frame infrm {incat} 1;
980  */
981  check_nomsg(upp_threshold =
982  cpl_image_get_median_window(rbia,
983  x_cent_s,
984  y_cent_s,
985  x_cent_e,
986  y_cent_e)*(1 + extra));
987 
988  check_nomsg(low_threshold =
989  cpl_image_get_median_window(rbia,
990  x_cent_s,
991  y_cent_s,
992  x_cent_e,
993  y_cent_e)*(1 - extra));
994 
995 
996 
997  /* replace from MIDAS
998  stat/ima {rbia} + bins=1 exc={low_treshold},{upp_treshold};
999  */
1000  check_nomsg(tima=cpl_image_duplicate(rbia));
1001 
1002  check_nomsg( reject_lo_hi(tima, low_threshold, upp_threshold) );
1003  if (count_good(tima) >= 2)
1004  {
1005  check_nomsg(qc_ron_raw = cpl_image_get_stdev(tima));
1006  }
1007  else
1008  {
1009  qc_ron_raw = -1;
1010  uves_msg_warning("Only %d good pixels in image. Setting QC parameter to -1",
1011  count_good(tima));
1012  }
1013 
1014 
1015  /* replace from MIDAS
1016  pn = {uves_portid({PATHID})};
1017  */
1018  check_nomsg(pn = PORT_ID(chip));
1019 
1020 
1021  sprintf(key_name,"%s%d%s","QC OUT",pn," RON RAW");
1023  key_name,
1024  qc_ron_raw,
1025  "Read noise frame in ADU",
1026  "%8.4f"));
1027 
1028  cleanup:
1029  uves_free_image(&tima);
1030  return;
1031 }
1032 
#define uves_msg_warning(...)
Print an warning message.
Definition: uves_msg.h:87
int uves_qclog_add_string(cpl_table *table, const char *key_name, const char *value, const char *key_help, const char *format)
Add string key to QC-LOG table.
Definition: uves_qclog.c:683
#define check_nomsg(CMD)
Definition: uves_error.h:204
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
int uves_pfits_get_binx(const uves_propertylist *plist)
Find out the x binning factor.
Definition: uves_pfits.c:1176
#define uves_msg(...)
Print a message on 'info' or 'debug' level.
Definition: uves_msg.h:119
double uves_pfits_get_mjdobs(const uves_propertylist *plist)
Find out the modified julian observation date.
Definition: uves_pfits.c:1086
int uves_pfits_get_biny(const uves_propertylist *plist)
Find out the y binning factor.
Definition: uves_pfits.c:1194
bool uves_ccd_is_new(const uves_propertylist *plist)
Find out if CCD header is new.
Definition: uves_pfits.c:553
double uves_pfits_get_exptime(const uves_propertylist *plist)
Find out the exposure time in seconds.
Definition: uves_pfits.c:922
#define assure_mem(PTR)
Definition: uves_error.h:181
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
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
int uves_correct_badpix_all(cpl_image *master_bias, uves_propertylist *mbias_header, enum uves_chip chip, int binx, int biny, int mark_bad, bool red_ccd_new)
Correct all bad pixels on a chip.
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
cpl_image * irplib_mkmaster_median(cpl_imagelist *images, const double kappa, const int nclip, const double tolerance)
Computes master frame by clean stack median of the input imagelist.
cpl_image * irplib_mkmaster_mean(cpl_imagelist *images, const double kappa, const int nclip, const double tolerance, const double klow, const double khigh, const int niter)
Computes master frame by clean stack mean of the input imagelist.