UVES Pipeline Reference Manual  5.4.0
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  check( uves_pfits_set_exptime(mbias_header, exposure_time),
422  "Error setting master bias exposure time");
423  if(CLEAN_TRAPS) {
424  check( badpixels_cleaned =
425  uves_correct_badpix_all(master_bias, mbias_header,
426  chip, binx, biny, false,red_ccd_is_new),
427  "Error replacing bad pixels");
428 
429  uves_msg("%d bad pixels replaced", badpixels_cleaned);
430  }
431 
432  cleanup:
433  if (cpl_error_get_code() != CPL_ERROR_NONE)
434  {
435  uves_free_image(&master_bias);
436  }
437 
438  return master_bias;
439 }
440 
441 /*----------------------------------------------------------------------------*/
448 /*----------------------------------------------------------------------------*/
449 static void
450 UVES_CONCAT2X(UVES_MBIAS_ID,exe)(cpl_frameset *frames,
451  const cpl_parameterlist *parameters,
452  const char *starttime)
453 {
454  uves_mbias_exe_body(frames, parameters, starttime, make_str(UVES_MBIAS_ID));
455  return;
456 }
457 
458 /*----------------------------------------------------------------------------*/
469 /*----------------------------------------------------------------------------*/
470 void
471 uves_mbias_exe_body(cpl_frameset *frames,
472  const cpl_parameterlist *parameters,
473  const char *starttime,
474  const char *recipe_id)
475 {
476  /* Input */
477  cpl_imagelist *raw_images[2] = {NULL, NULL};
478  uves_propertylist **raw_headers[2] = {NULL, NULL}; /* Two arrays of pointers */
479 
480  cpl_table* qclog[2] = {NULL, NULL};
481 
482  /* Output */
483  uves_propertylist *product_header[2] = {NULL, NULL};
484  cpl_image *master_bias = NULL;
485  cpl_stats *mbias_stats = NULL;
486 
487  /* Local variables */
488  char *product_filename = NULL;
489  bool blue;
490  enum uves_chip chip;
491  int binx, biny;
492  const char* PROCESS_CHIP=NULL;
493  bool CLEAN_TRAPS;
494  int raw_index = 0;
495  int i=0;
496 
497  const char* STACK_METHOD=NULL;
498  double STACK_KLOW=0;
499  double STACK_KHIGH=0;
500  int STACK_NITER=0;
501 
502  /* Load and check raw bias images and headers, identify arm (blue/red) */
503  /* On success, 'raw_headers' will be arrays with the same length as 'raw_images' */
504  check( uves_load_raw_imagelist(frames,
505  false, /* FLAMES format? (no) */
506  UVES_BIAS(true), UVES_BIAS(false),
507  CPL_TYPE_DOUBLE,
508  raw_images, raw_headers, product_header,
509  &blue), "Error loading raw frames");
510 
511  /* Get binning from first header (i.e. BLUE or REDL chip, first raw frame) */
512  check( binx = uves_pfits_get_binx(raw_headers[0][0]),
513  "Could not get raw frame x-binning");
514  check( biny = uves_pfits_get_biny(raw_headers[0][0]),
515  "Could not get raw frame y-binning");
516  check( uves_get_parameter(parameters, NULL, "uves", "process_chip", CPL_TYPE_STRING, &PROCESS_CHIP),
517  "Could not read parameter");
518  uves_string_toupper((char*)PROCESS_CHIP);
519 
520  check( uves_get_parameter(parameters, NULL, recipe_id, "clean_traps", CPL_TYPE_BOOL, &CLEAN_TRAPS),
521  "Could not read parameter");
522 
523  check( uves_get_parameter(parameters, NULL, recipe_id, "stack_method", CPL_TYPE_STRING, &STACK_METHOD),
524  "Could not read parameter");
525  uves_string_toupper((char*)STACK_METHOD);
526 
527  check( uves_get_parameter(parameters, NULL, recipe_id, "klow", CPL_TYPE_DOUBLE, &STACK_KLOW),
528  "Could not read parameter");
529  check( uves_get_parameter(parameters, NULL, recipe_id, "khigh", CPL_TYPE_DOUBLE, &STACK_KHIGH),
530  "Could not read parameter");
531  check( uves_get_parameter(parameters, NULL, recipe_id, "niter", CPL_TYPE_INT, &STACK_NITER),
532  "Could not read parameter");
533 
534  /* Loop over one or two chips */
535  for (chip = uves_chip_get_first(blue);
536  chip != UVES_CHIP_INVALID;
537  chip = uves_chip_get_next(chip))
538  {
539  if(strcmp(PROCESS_CHIP,"REDU") == 0) {
540  chip = uves_chip_get_next(chip);
541  }
542  raw_index = uves_chip_get_index(chip);
543 
544  uves_msg("Processing %s chip",
546 
547  uves_msg_debug("Binning = %dx%d", binx, biny);
548 
549  /* Process chip */
550  uves_free_image(&master_bias);
551  check( master_bias = uves_mbias_process_chip(raw_images[raw_index],
552  raw_headers[raw_index],
553  product_header[raw_index],
554  binx, biny,
555  chip,CLEAN_TRAPS,
556  STACK_METHOD,
557  STACK_KLOW,
558  STACK_KHIGH,
559  STACK_NITER),
560  "Error processing chip");
561 
562 
563  cpl_free(product_filename);
564  check( product_filename = uves_masterbias_filename(chip),
565  "Error getting filename");
566 
567  /* Finished. Calculate QC parameters and save */
568  uves_msg("Calculating QC parameters");
569  uves_qclog_delete(&qclog[0]);
570  qclog[0] = uves_qclog_init(raw_headers[raw_index][0], chip);
571  check(uves_mbias_qclog(raw_images[raw_index],
572  raw_headers[raw_index],
573  chip,
574  master_bias,
575  /* binx,biny, */
576  qclog[0]),"error computing qclog");
577 
578  /* Insert into frame set */
579  uves_msg("Saving product...");
580 
581  check( uves_frameset_insert(frames,
582  master_bias,
583  CPL_FRAME_GROUP_PRODUCT,
584  CPL_FRAME_TYPE_IMAGE,
585  CPL_FRAME_LEVEL_INTERMEDIATE,
586  product_filename,
587  UVES_MASTER_BIAS(chip),
588  raw_headers[raw_index][0], /* First frame */
589  product_header[raw_index],
590  NULL,
591  parameters,
592  recipe_id,
593  PACKAGE "/" PACKAGE_VERSION,qclog,
594  starttime, true,
595  UVES_ALL_STATS),
596  "Could not add master bias %s to frameset", product_filename);
597  uves_qclog_delete(&qclog[0]);
598  uves_msg("Master bias '%s' added to frameset", product_filename);
599 
600  if(strcmp(PROCESS_CHIP,"REDL") == 0) {
601  chip = uves_chip_get_next(chip);
602  }
603 
604 
605  } /* For each chip */
606 
607  cleanup:
608  /* Input */
609  if (raw_images[0] != NULL)
610  {
611 
612  for (i = 0; i < cpl_imagelist_get_size(raw_images[0]); i++)
613  {
614  if (raw_headers[0] != NULL) uves_free_propertylist(&raw_headers[0][i]);
615  if (raw_headers[1] != NULL) uves_free_propertylist(&raw_headers[1][i]);
616  }
617  cpl_free(raw_headers[0]); raw_headers[0] = NULL;
618  cpl_free(raw_headers[1]); raw_headers[1] = NULL;
619  }
620  uves_free_imagelist(&raw_images[0]);
621  uves_free_imagelist(&raw_images[1]);
622  /* Output */
623 
624  uves_qclog_delete(&qclog[0]);
625  uves_free_image(&master_bias);
626  uves_free_propertylist(&product_header[0]);
627  uves_free_propertylist(&product_header[1]);
628  cpl_free(product_filename);
629  uves_free_stats(&mbias_stats);
630 
631  return;
632 }
633 
634 
635 
636 static int
637 count_good(const cpl_image *image)
638 {
639  return
640  cpl_image_get_size_x(image) * cpl_image_get_size_y(image) -
641  cpl_image_count_rejected(image);
642 }
643 /*----------------------------------------------------------------------------*/
650 /*----------------------------------------------------------------------------*/
651 static void
652 reject_lo_hi(cpl_image *image, double min, double max)
653 {
654  cpl_mask *mask_lo = NULL;
655  cpl_mask *mask_hi = NULL;
656 
657  mask_lo = cpl_mask_threshold_image_create(image, -DBL_MAX, min);
658  mask_hi = cpl_mask_threshold_image_create(image, max, DBL_MAX);
659  assure_mem( mask_lo );
660  assure_mem( mask_hi );
661 
662  cpl_mask_or(mask_lo, mask_hi);
663 
664  cpl_image_reject_from_mask(image, mask_lo);
665 
666  cleanup:
667  uves_free_mask(&mask_lo);
668  uves_free_mask(&mask_hi);
669  return;
670 }
671 
682 static void uves_mbias_qclog(const cpl_imagelist* raw_imgs,
683  uves_propertylist **raw_headers,
684  enum uves_chip chip,
685  const cpl_image* mbia,
686  /* int sx_pix, Size of X bin in pix
687  int sy_pix, Size of Y bin in pix */
688  cpl_table* qclog
689  )
690 {
691  int nx_pix= 0; /* No of X pix */
692  int ny_pix= 0; /* No of Y pix */
693 
694  int sample_x= 100; /* X size of sampling window in pix */
695  int sample_y= 100; /* Y size of sampling window in pix */
696  int x_cent_s= 0; /* X sampling window starting point */
697  int x_cent_e= 0; /* X sampling window ending point */
698  int y_cent_s= 0; /* Y sampling window starting point */
699  int y_cent_e= 0; /* Y sampling window ending point */
700 
701 
702 
703 
704 
705  double upp_threshold= 0.0;
706  double low_threshold= 0.0;
707  double extra=0.1;
708  double qc_ron_master= 0.0;
709 
710  double master_median=0.0;
711  int pn= 0;
712 
713 
714  double min=0.0;
715  double max=0.0;
716  double struct_col=0.0;
717  double struct_row=0.0;
718 
719  double time_s=+9999999.0;
720  double time_e=-9999999.0;
721  int nraw=0;
722  double qc_duty_cycle=0.;
723  double exposure_time=0;
724  int i=0;
725  char key_name[80];
726 
727  const cpl_image* rbia=NULL;
728  cpl_image* tima=NULL;
729  cpl_image* avg_col=NULL;
730  cpl_image* avg_row=NULL;
731 
732  uves_qclog_add_string(qclog,
733  "QC TEST1 ID",
734  "Test-on-Master-Bias",
735  "Name of QC test",
736  "%s");
737 
738  uves_msg("Computing duty cycle...");
739 
740  /* Set mbias exposure time to average of inputs */
741  exposure_time = 0;
742  nraw = cpl_imagelist_get_size(raw_imgs);
744  "PRO DATANCOM",
745  nraw,
746  "Number of frames combined",
747  "%d"));
748 
749 
750  for (i = 0; i < nraw; i++)
751  {
752  check( exposure_time = uves_pfits_get_mjdobs(raw_headers[i]),
753  "Error reading exposure time");
754  if(exposure_time >= time_e) time_e = exposure_time;
755  if(exposure_time <= time_s) time_s = exposure_time;
756  }
757  if(nraw > 1) {
758  qc_duty_cycle = (time_e-time_s)/ (nraw-1);
759  }
760  else
761  {
762  qc_duty_cycle = 0;
763  }
764 
766  "QC DUTYCYCL",
767  qc_duty_cycle,
768  "Time to store a frame",
769  "%.5e"));
770 
771  /* The following is not really used in MIDAS so we comment
772  strcpy(date,uves_pfits_get_tpl_start(plist));
773  */
774 
775 
776  /* CONVERT FROM MIDAS
777  nx_pix = m$value({mbia},NPIX(1));
778  ny_pix = m$value({mbia},NPIX(2));
779  */
780 
781  nx_pix = cpl_image_get_size_x(mbia);
782  ny_pix = cpl_image_get_size_y(mbia);
783 
784 
785  x_cent_s = (nx_pix - sample_x)/2;
786  x_cent_e = (nx_pix + sample_x)/2;
787  y_cent_s = (ny_pix - sample_y)/2;
788  y_cent_e = (ny_pix + sample_y)/2;
789 
790 
791  check_nomsg(upp_threshold =
792  cpl_image_get_median_window(mbia,
793  x_cent_s,
794  y_cent_s,
795  x_cent_e,
796  y_cent_e)*(1 + extra));
797  check_nomsg(low_threshold =
798  cpl_image_get_median_window(mbia,
799  x_cent_s,
800  y_cent_s,
801  x_cent_e,
802  y_cent_e)*(1 - extra));
803 
804  /* convert from MIDAS
805  pn = {uves_portid({PATHID})};
806  */
807  check_nomsg(pn = PORT_ID(chip));
808  uves_msg_debug("Port number = %d", pn);
809 
810  rbia = cpl_imagelist_get_const(raw_imgs,0);
811  check_nomsg(uves_mbias_qc_ron_raw(rbia, chip,
812  x_cent_s,x_cent_e,y_cent_s,y_cent_e,qclog));
813 
814 
815  /* convert from MIDAS
816  stat/ima {mbia} + bins=1 exc={low_threshold},{upp_threshold};
817  */
818  check_nomsg(tima=cpl_image_duplicate(mbia));
819 
820  check_nomsg( reject_lo_hi(tima, low_threshold, upp_threshold) );
821  if (count_good(tima) >= 2)
822  {
823  check_nomsg(master_median = cpl_image_get_median(tima));
824  check_nomsg(qc_ron_master = cpl_image_get_stdev(tima));
825  }
826  else
827  {
828  master_median = -1;
829  qc_ron_master = -1;
830  uves_msg_warning("Only %d good pixels in image. Setting QC parameters to -1",
831  count_good(tima));
832  }
833  uves_free_image(&tima);
834 
836  "PRO DATAMED",
837  master_median,
838  "Median of pixel values",
839  "%7.3f"));
840 
841  sprintf(key_name, "QC OUT%d RON MASTER", pn);
843  key_name,
844  qc_ron_master,
845  "Read noise frame in ADU",
846  "%8.4f"));
847 
848  /* ==========================
849  * Calculates Bias struct
850  * ==========================
851  */
852 
853 
854  /*
855  * in case of RED frame cuts out values greater than 300.
856  * as the frame can be affected by this local operation we
857  * do the calculation on a copy of the original frame
858  */
859 
860 
861  check_nomsg(tima=cpl_image_duplicate(mbia));
862  if (chip != UVES_CHIP_BLUE) {
863  /*
864  replace/ima {mbia} {tmpfrm} 300,>=300.;
865  */
866  check_nomsg(cpl_image_threshold(tima,
867  -DBL_MAX,300,
868  -DBL_MAX,300));
869  }
870 
871 
872  check_nomsg(avg_col = cpl_image_collapse_create(tima,1));
873  check_nomsg(cpl_image_divide_scalar(avg_col,cpl_image_get_size_x(tima)));
874 
875  /* restricts statistics to +/- 2 ADU around mean */
876  min = cpl_image_get_mean(avg_col) - 2;
877  max = cpl_image_get_mean(avg_col) + 2;
878 
879  /* replace with MIDAS
880  stat/ima avg_col + exc={min},{max};
881  */
882  check_nomsg( reject_lo_hi(avg_col, min, max) );
883  if (count_good(avg_col) >= 2)
884  {
885  check_nomsg(struct_col = cpl_image_get_stdev(avg_col));
886  }
887  else
888  {
889  struct_col = -1;
890  uves_msg_warning("Only %d good pixels in image. Setting QC parameter to -1",
891  count_good(avg_col));
892  }
893 
894  sprintf(key_name,"%s%d%s","QC OUT",pn," STRUCTY");
896  key_name,
897  struct_col,
898  "structure in Y (bias slope)",
899  "%8.4f"));
900 
901 
902 
903  check_nomsg(avg_row = cpl_image_collapse_create(tima,0));
904  check_nomsg(cpl_image_divide_scalar(avg_row,cpl_image_get_size_y(tima)));
905 
906  /* restricts statistics to +/- 2 ADU around mean */
907  min = cpl_image_get_mean(avg_row) - 2;
908  max = cpl_image_get_mean(avg_row) + 2;
909 
910  /* replace with MIDAS
911  stat/ima avg_row + exc={min},{max};
912  */
913  check_nomsg( reject_lo_hi(avg_row, min, max) );
914  if (count_good(avg_row) >= 2)
915  {
916  check_nomsg(struct_row = cpl_image_get_stdev(avg_row));
917  }
918  else
919  {
920  struct_row = -1;
921  uves_msg_warning("Only %d good pixels in image. Setting QC parameter to -1",
922  count_good(avg_row));
923  }
924 
925 
926  sprintf(key_name,"%s%d%s","QC OUT",pn," STRUCTX");
928  key_name,
929  struct_row,
930  "structure in X (bias slope)",
931  "%8.4f"));
932 
933 
934 
935 
936  cleanup:
937  uves_free_image(&avg_col);
938  uves_free_image(&avg_row);
939  uves_free_image(&tima);
940 
941  return;
942 
943 }
957 static void
958 uves_mbias_qc_ron_raw(const cpl_image* rbia,
959  enum uves_chip chip,
960  const int x_cent_s,
961  const int x_cent_e,
962  const int y_cent_s,
963  const int y_cent_e,
964  cpl_table* qclog)
965 {
966 
967  double qc_ron_raw=0.0;
968  double upp_threshold=0.0;
969  double low_threshold=0.0;
970  double extra=0.1;
971  char key_name[80];
972  int pn=0;
973  cpl_image* tima=NULL;
974 
975  /* replace with MIDAS
976  date = "{{mbia},ESO.TPL.START}";
977  store/frame infrm {incat} 1;
978  */
979  check_nomsg(upp_threshold =
980  cpl_image_get_median_window(rbia,
981  x_cent_s,
982  y_cent_s,
983  x_cent_e,
984  y_cent_e)*(1 + extra));
985 
986  check_nomsg(low_threshold =
987  cpl_image_get_median_window(rbia,
988  x_cent_s,
989  y_cent_s,
990  x_cent_e,
991  y_cent_e)*(1 - extra));
992 
993 
994 
995  /* replace from MIDAS
996  stat/ima {rbia} + bins=1 exc={low_treshold},{upp_treshold};
997  */
998  check_nomsg(tima=cpl_image_duplicate(rbia));
999 
1000  check_nomsg( reject_lo_hi(tima, low_threshold, upp_threshold) );
1001  if (count_good(tima) >= 2)
1002  {
1003  check_nomsg(qc_ron_raw = cpl_image_get_stdev(tima));
1004  }
1005  else
1006  {
1007  qc_ron_raw = -1;
1008  uves_msg_warning("Only %d good pixels in image. Setting QC parameter to -1",
1009  count_good(tima));
1010  }
1011 
1012 
1013  /* replace from MIDAS
1014  pn = {uves_portid({PATHID})};
1015  */
1016  check_nomsg(pn = PORT_ID(chip));
1017 
1018 
1019  sprintf(key_name,"%s%d%s","QC OUT",pn," RON RAW");
1021  key_name,
1022  qc_ron_raw,
1023  "Read noise frame in ADU",
1024  "%8.4f"));
1025 
1026  cleanup:
1027  uves_free_image(&tima);
1028  return;
1029 }
1030