UVES Pipeline Reference Manual  5.4.6
uves_reduce_mflat.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 02111-1307 USA *
18  * */
19 
20 /*
21  * $Author: amodigli $
22  * $Date: 2013-08-08 13:36:46 $
23  * $Revision: 1.53 $
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 /*----------------------------------------------------------------------------*/
35 /*----------------------------------------------------------------------------*/
40 /*-----------------------------------------------------------------------------
41  Includes
42  -----------------------------------------------------------------------------*/
43 #include <uves_reduce_mflat.h>
44 
45 #include <uves.h>
46 #include <uves_backsub.h>
47 #include <uves_chip.h>
48 #include <uves_dfs.h>
49 #include <uves_pfits.h>
50 #include <uves_parameters.h>
51 #include <uves_utils.h>
52 #include <uves_utils_wrappers.h>
53 #include <uves_qclog.h>
54 #include <uves_error.h>
55 #include <uves_msg.h>
56 
57 #include <cpl.h>
58 #include <float.h>
59 #include <string.h>
60 /*-----------------------------------------------------------------------------
61  Functions prototypes
62  -----------------------------------------------------------------------------*/
63 
64 static void uves_mflat_qclog(const cpl_imagelist* raw_images,
65  cpl_table* qclog);
66 
67 static cpl_error_code uves_msflats(cpl_frameset * set, const cpl_parameterlist *parameters,
68  const char *recipe_id,
69  const char *starttime);
70 static void uves_mflat_one(cpl_frameset *frames,
71  const cpl_parameterlist *parameters,
72  bool flames,
73  const char *recipe_id,
74  const char *starttime,
75  const char* prefix);
76 
77 static cpl_error_code
78 uves_mflat_at_ypos(cpl_frameset* set,
79  const cpl_parameterlist* parameters,
80  const char *recipe_id,
81  const char *starttime,
82  const cpl_frameset* raw,
83  const cpl_frameset* cdb,
84  const int ref_x1enc,
85  const int ref_x2enc,
86  const int set_no);
87 
88 static void uves_reduce_mflat(cpl_frameset *frames, const cpl_parameterlist *parameters,
89  bool flames,
90  const char *recipe_id,
91  const char *starttime,
92  const char *prefix);
93 
94 /*-----------------------------------------------------------------------------
95  Implementation
96  -----------------------------------------------------------------------------*/
97 const char * const uves_mflat_desc =
98 "This recipe creates a master flat frame by 1) subtracting the master bias\n"
99 "frame from each flat field frame, 2) dividing each flat field frame by the\n"
100 " exposure time for that frame, 3) taking the median of all bias subtracted,\n"
101 " normalized raw\n flat frames, 4) optionally subtracting the master dark \n"
102 "frame, and 5) subtracting\n the background to get the bias subtracted, \n"
103 "optionally dark subtracted, normalized, background subtracted master \n"
104 "flat-field frame. Symbolically,\n"
105 " masterflat = median( (flat_i - masterbias)/exptime_i ) - masterdark/exptime\n"
106 " - background.\n"
107 "\n"
108 "The input flat field frames must have same tag which must match\n"
109 "(I|D|S|T|SCREEN|)FLAT_(BLUE|RED), for example TFLAT_BLUE or FLAT_RED. Also, a\n"
110 "master bias (MASTER_BIAS_xxxx) and ordertable (ORDER_TABLE_xxxx) must be\n"
111 "provided for each chip (xxxx = BLUE, REDL, REDU). A master dark frame\n"
112 "(MASTER_(P)DARK_xxxx) may optionally be provided. On blue input the recipe\n"
113 "computes one master flat field frame; on red input the recipe produces a\n"
114 "master flat field frame for each chip (MASTER_FLAT_xxxx, MASTER_IFLAT_xxxx,\n"
115 "MASTER_DFLAT_xxxx, MASTER_TFLAT_xxxx or MASTER_SCREEN_FLAT_xxxx).";
116 
117 /*----------------------------------------------------------------------------*/
124 /*----------------------------------------------------------------------------*/
125 int
126 uves_mflat_define_parameters_body(cpl_parameterlist *parameters,
127  const char *recipe_id)
128 {
129 
130  cpl_parameter* p=NULL;
131  /*****************
132  * General *
133  *****************/
134  if (uves_define_global_parameters(parameters) != CPL_ERROR_NONE)
135  {
136  return -1;
137  }
138  if (uves_corr_traps_define_parameters(parameters,recipe_id)
139  != CPL_ERROR_NONE)
140  {
141  return -1;
142  }
143 
144  /**************************************
145  * Master stack generation *
146  **************************************/
147  if (uves_master_flat_define_parameters(parameters,recipe_id)
148  != CPL_ERROR_NONE)
149  {
150  return -1;
151  }
152 
153  if(strcmp(recipe_id,"flames_cal_mkmaster") ==0) {
154  check_nomsg(p=cpl_parameterlist_find(parameters,"flames_cal_mkmaster.norm_method"));
155  cpl_parameter_set_string(p,"exptime");
156  }
157  cleanup:
158 /*
159  if (uves_master_stack_define_parameters(parameters,recipe_id)
160  != CPL_ERROR_NONE)
161  {
162  return -1;
163  }
164 */
165 
166  /****************************
167  * Spline back.sub. *
168  ****************************/
169 
170  if (uves_propagate_parameters_step(UVES_BACKSUB_ID, parameters,
171  recipe_id, NULL) != 0)
172  {
173  return -1;
174  }
175 
176 
177 
178  return (cpl_error_get_code() != CPL_ERROR_NONE);
179 }
180 
181 /*----------------------------------------------------------------------------*/
219 /*----------------------------------------------------------------------------*/
220 static cpl_image *
221 uves_mflat_process_chip(const cpl_imagelist *raw_images,
222  uves_propertylist **raw_headers,
223  uves_propertylist *master_flat_header,
224  const cpl_image *master_bias,
225  const cpl_image *master_dark,
226  const uves_propertylist *mdark_header,
227  const cpl_table *ordertable,
228  const polynomial *order_locations,
229  bool flames,
230  const cpl_parameterlist *parameters,
231  enum uves_chip chip,
232  const char *recipe_id,
233  bool debug_mode,
234  cpl_image **background)
235 
236 {
237  cpl_image *master_flat = NULL; /* Result */
238  cpl_image *master_flat_tmp = NULL; /* Result */
239 
240  cpl_image *current_flat = NULL;
241 
242  int i;
243  const char* FLAT_METHOD=NULL;
244  cpl_vector* exptimes=NULL;
245  cpl_vector* gain_vals=NULL;
246  double mdark_exposure=0;
247  cpl_image* mdark_scaled=NULL;
248  double fnoise=0;
249  double gain=0;
250  cpl_imagelist *raw_images_local=NULL;
251 
252  /* First process each input image and store the results in a new image list */
253  /* Get recipe parameters */
254  check( uves_get_parameter(parameters, NULL, recipe_id, "norm_method",
255  CPL_TYPE_STRING, &FLAT_METHOD),
256  "Could not read parameter");
257  uves_string_toupper((char*)FLAT_METHOD);
258 
259  raw_images_local=(cpl_imagelist*) raw_images;
260  exptimes=cpl_vector_new(cpl_imagelist_get_size(raw_images));
261  gain_vals=cpl_vector_new(cpl_imagelist_get_size(raw_images));
262  /* to remove compiler warnings */
263  for (i = 0; i < cpl_imagelist_get_size(raw_images); i++)
264  {
265  double exposure_time = 0.0;
266 
267  const uves_propertylist *current_header = NULL;
268 
269  current_flat = cpl_image_duplicate(cpl_imagelist_get_const(raw_images, i));
270  current_header = raw_headers[i];
271 
272  /* Subtract master bias */
273  if (master_bias != NULL)
274  {
275  uves_msg("Subtracting master bias");
276  check( uves_subtract_bias(current_flat, master_bias),
277  "Error subtracting master bias");
278  }
279  else
280  {
281  uves_msg("Skipping bias subtraction");
282  }
283 
284  /* Normalize to unit exposure time */
285  check( exposure_time = uves_pfits_get_exptime(current_header),
286  "Error reading exposure time");
287  check( gain = uves_pfits_get_gain(current_header,chip),
288  "Error reading gain value");
289 
290  uves_msg("Normalizing flat from %f s to unit exposure time", exposure_time);
291  check( cpl_image_divide_scalar(current_flat, exposure_time),
292  "Error normalizing flat field");
293  check( uves_pfits_set_exptime(master_flat_header, 1.0),
294  "Error writing master frame exposure time");
295  cpl_vector_set(exptimes,i,exposure_time);
296  cpl_vector_set(gain_vals,i,gain);
297 
298  /* Append to imagelist */
299  check( cpl_imagelist_set(raw_images_local, /* Image list */
300  current_flat, /* Image to insert */
301  i), /* Position (number_of_images=>append) */
302  "Could not insert image into image list");
303 
304  /* Don't deallocate the image. It will be deallocated when
305  the image list is deallocated */
306  current_flat = NULL;
307  }
308 
309  /* subtract master dark if present */
310  if (master_dark != NULL)
311  {
312  uves_msg("Subtracting master dark");
313  check_nomsg( mdark_exposure = uves_pfits_get_exptime(mdark_header));
314  mdark_scaled=cpl_image_duplicate(master_dark);
315  cpl_image_divide_scalar(mdark_scaled,mdark_exposure);
316  check( cpl_imagelist_subtract_image(raw_images_local,mdark_scaled),
317  "Error subtracting master dark");
318  uves_free_image(&mdark_scaled);
319  }
320  else
321  {
322  uves_msg("Skipping dark subtraction");
323  }
324 
325 
326  /* Take median of all input flats */
327  if(strcmp(FLAT_METHOD,"EXPTIME")==0) {
328  uves_msg("Calculating stack median");
329  check(master_flat=cpl_imagelist_collapse_median_create(raw_images_local),
330  "Error computing median");
331  } else {
332  uves_msg("Calculating stack normalized master");
333  check( master_flat_tmp = uves_flat_create_normalized_master(raw_images_local,
334  ordertable,
335  order_locations,gain_vals,&fnoise),
336  "Error computing master flat with normalization");
337 
338  check( master_flat = uves_flat_create_normalized_master2(raw_images_local,
339  ordertable,
340  order_locations,
341  master_flat_tmp),
342  "Error computing master flat with normalization");
343  uves_free_image(&master_flat_tmp);
344  uves_propertylist_append_c_double(master_flat_header,UVES_FNOISE,fnoise,
345  "Master flat RMS on frame");
346 
347  }
348  /*clean mem and reset local pointers to null */
349  raw_images_local=NULL;
350  uves_free_vector(&exptimes);
351  uves_free_vector(&gain_vals);
352 
353  if (debug_mode && !flames)
354  {
355  check( uves_save_image_local("Pre-background subtracted master flat", "pre",
356  master_flat, chip, -1, -1, master_flat_header, true),
357  "Error saving image");
358  }
359 
360  /* Subtract background from master flat */
361  if (!flames)
362  {
363  uves_msg("Subtracting background");
364 
365  check( uves_backsub_spline(master_flat,
366  /* Info about chip (wavelength, ...) is
367  stored in any raw header,
368  so just pass the first one */
369  raw_headers[0],
370  ordertable, order_locations,
371  parameters, recipe_id,
372  chip,
373  true, /* Use flat-field parameters? */
374  background),
375  "Error subtracting background from master flat");
376  }
377  else
378  {
379  uves_msg("Skipping background subtraction");
380  }
381  uves_pfits_set_extname(master_flat_header,"Master flat");
382  cleanup:
383 
384 
385  uves_free_image(&current_flat);
386  if (cpl_error_get_code() != CPL_ERROR_NONE)
387  {
388  uves_free_image(&master_flat);
389  }
390 
391  return master_flat;
392 }
393 
394 /*----------------------------------------------------------------------------*/
406 /*----------------------------------------------------------------------------*/
407 void
408 uves_mflat_exe_body(cpl_frameset *frames,
409  const cpl_parameterlist *parameters,
410  const char *starttime,
411  const char *recipe_id)
412 {
413  /* Do FLAMES reduction if SFLAT frame is given */
414  if (cpl_frameset_find(frames, UVES_SFLAT(false)) != NULL) {
415 
416  check(uves_msflats(frames, parameters, recipe_id, starttime),
417  "find same sflats failed");
418  }
419  else {
420  bool flames = false;
421  check(uves_mflat_one(frames, parameters, flames, recipe_id,
422  starttime, ""),
423  "Master flat one failed");
424  }
425 
426  cleanup:
427  return;
428 }
429 
430 /*----------------------------------------------------------------------------*/
436 /*----------------------------------------------------------------------------*/
437 static cpl_error_code
438 uves_msflats(cpl_frameset * set, const cpl_parameterlist *parameters,
439  const char *recipe_id,
440  const char *starttime)
441 {
442  /* Pseudocode:
443  extract raw frames from set
444  extract cdb frames from set
445  identifies how many different Y position we have
446  for each Y pos:
447  extract from the raw_set the raw frames corresponding to each Y pos
448  merge in a new wrk_set the cdb_set
449  computes the corresponding master flat
450  put the products in the final set
451  endfor
452  */
453  cpl_frameset* raw=NULL;
454  cpl_frameset* cdb=NULL;
455  cpl_frameset* pro=NULL;
456  int status=0;
457  int x1enc=0;
458  int x2enc=0;
459 
460  cpl_table* encoder_tbl=NULL;
461  int nset=0;
462  int i=0;
463 
464  //Extracts SFLAT raw frames
465  check(raw=uves_frameset_extract(set,UVES_SFLAT(false)),
466  "Extract %s frames failed",
467  UVES_SFLAT(false));
468 
469  check(uves_extract_frames_group_type(set,&cdb,CPL_FRAME_GROUP_CALIB),
470  "Extract cdb frames failed");
471  check(uves_sflats_get_encoder_steps(raw,&encoder_tbl,&nset),
472  "Get encoder steps failed");
473  uves_msg("Check Slit Flat Field Y nominal positions within each set");
474  for(i=0;i<nset;i++) {
475 
476  uves_msg("Slit Flat field set %d: x1enc = %d x2enc = %d",
477  i+1,
478  cpl_table_get_int(encoder_tbl,"x1enc",i,&status),
479  cpl_table_get_int(encoder_tbl,"x2enc",i,&status));
480 
481  }
482 
483  for(i=0;i<nset;i++) {
484  x1enc=cpl_table_get_int(encoder_tbl,"x1enc",i,&status);
485  x2enc=cpl_table_get_int(encoder_tbl,"x2enc",i,&status);
486 
487  uves_msg("Processing set %d", i+1);
488 
489  check(uves_mflat_at_ypos(set,parameters,recipe_id,starttime,raw,cdb,x1enc,x2enc,i+1),
490  "Master flat one failed");
491  }
492 
493  cleanup:
494  uves_free_table(&encoder_tbl);
495  uves_free_frameset(&raw);
496  uves_free_frameset(&cdb);
497  uves_free_frameset(&pro);
498 
499  return cpl_error_get_code();
500 }
501 
502 
503 /*----------------------------------------------------------------------------*/
509 /*----------------------------------------------------------------------------*/
510 static cpl_error_code
511 uves_mflat_at_ypos(cpl_frameset* set,
512  const cpl_parameterlist* parameters,
513  const char *recipe_id,
514  const char *starttime,
515  const cpl_frameset* raw,
516  const cpl_frameset* cdb,
517  const int ref_x1enc,
518  const int ref_x2enc,
519  const int set_no)
520 {
521 
522  const cpl_frame* frm_tmp=NULL;
523  char* file=NULL;
524  uves_propertylist* plist=NULL;
525  cpl_size i=0;
526  const int threshold = 5;
527  cpl_frame* frm_dup=NULL;
528  cpl_frameset* tmp=NULL;
529  cpl_frameset* pro=NULL;
530  int x1enc=0;
531  int x2enc=0;
532  char prefix[255];
533  bool flames = true;
534 
535  check_nomsg(tmp=cpl_frameset_new());
536  for(i=0;i<cpl_frameset_get_size(raw);i++)
537  {
538  check_nomsg(frm_tmp=cpl_frameset_get_frame_const(raw,i));
539  check_nomsg(file=cpl_strdup(cpl_frame_get_filename(frm_tmp)));
540  check_nomsg(plist=uves_propertylist_load(file,0));
543 
544  if( (fabs(x1enc - ref_x1enc) <= threshold) &&
545  (fabs(x2enc - ref_x2enc) <= threshold) ) {
546  uves_msg_debug("file=%s x1enc=%d x2enc=%d",file,x1enc,x2enc);
547  check(frm_dup = cpl_frame_duplicate(frm_tmp),"duplicate");
548  check(cpl_frameset_insert(tmp,frm_dup),"insert");
549  }
550  cpl_free(file);
551  uves_free_propertylist(&plist);
552  }
553  check_nomsg(uves_frameset_merge(tmp,cdb));
554  sprintf(prefix,"%s%d%s","set",set_no,"_");
555  check(uves_mflat_one(tmp,parameters, flames, recipe_id, starttime,prefix),"Master flat one failed");
556  check_nomsg(uves_extract_frames_group_type(tmp,&pro,CPL_FRAME_GROUP_PRODUCT));
557  check_nomsg(uves_frameset_merge(set,pro));
558 
559  cleanup:
560  uves_free_frameset(&tmp);
561  uves_free_frameset(&pro);
562  uves_free_propertylist(&plist);
563 
564  return cpl_error_get_code();
565 }
566 /*----------------------------------------------------------------------------*/
579 /*----------------------------------------------------------------------------*/
580 static void
581 uves_mflat_one(cpl_frameset *frames,
582  const cpl_parameterlist *parameters,
583  bool flames,
584  const char *recipe_id,
585  const char *starttime,
586  const char* prefix)
587 {
588  /* Do flat-fielding */
589  check_nomsg( uves_reduce_mflat(frames, parameters,
590  flames, recipe_id,
591  starttime, prefix) );
592 
593  cleanup:
594  return;
595 }
596 
597 /*----------------------------------------------------------------------------*/
608 /*----------------------------------------------------------------------------*/
609 static void
610 uves_reduce_mflat(cpl_frameset *frames, const cpl_parameterlist *parameters,
611  bool flames,
612  const char *recipe_id,
613  const char *starttime,
614  const char *prefix)
615 {
616  bool debug_mode;
617 
618  /* Input */
619  cpl_imagelist *raw_images[2] = {NULL, NULL}; /* An image list for both chips */
620  uves_propertylist **raw_headers[2] = {NULL, NULL}; /* Two arrays of pointers */
621 
622  /* Master bias */
623  cpl_image *master_bias = NULL;
624  uves_propertylist *master_bias_header = NULL;
625 
626  /* Master dark */
627  cpl_image *master_dark = NULL;
628  uves_propertylist *master_dark_header = NULL;
629 
630  /* Order table */
631  cpl_table *ordertable = NULL;
632  uves_propertylist *ordertable_header = NULL;
633  polynomial *order_locations = NULL;
634  cpl_table *traces = NULL;
635 
636  /* Reference master flat */
637  cpl_image *ref_flat = NULL;
638  uves_propertylist *ref_flat_header = NULL;
639 
640  /* Output */
641  cpl_table *qclog[] = {NULL, NULL};
642  cpl_image *master_flat = NULL;
643  cpl_image *background = NULL;
644  uves_propertylist *product_header[] = {NULL, NULL};
645  cpl_image *ratio = NULL;
646 
647  /* Local variables */
648  char *product_filename = NULL;
649  char pro_filename[255];
650  const char *product_tag[2] = {NULL, NULL};
651  bool blue;
652  enum uves_chip chip;
653  const char* PROCESS_CHIP=NULL;
654 
655 
656 
657 
658  const char *ordertable_filename = "";
659  const char *master_bias_filename = "";
660  const char *master_dark_filename = "";
661  const char *chip_name = "";
662  int raw_index = 0;
663  const char *ref_flat_filename;
664 
665  /* Read recipe parameters */
666  {
667  /* General */
668  check( uves_get_parameter(parameters, NULL, "uves", "debug", CPL_TYPE_BOOL , &debug_mode ),
669  "Could not read parameter");
670  }
671  check( uves_get_parameter(parameters, NULL, "uves", "process_chip", CPL_TYPE_STRING, &PROCESS_CHIP), "Could not read parameter");
672 
673  uves_string_toupper((char*)PROCESS_CHIP);
674 
675  /* Load and check raw flat images and headers, identify arm (blue/red) */
676  /* On success, 'raw_headers' will be an array with the same size as 'raw_images' */
677  /* Set product tags to match input tag */
678 
679  if (cpl_frameset_find(frames, UVES_FLAT(true )) != NULL ||
680  cpl_frameset_find(frames, UVES_FLAT(false)) != NULL)
681  {
682  check( uves_load_raw_imagelist(frames,
683  flames,
684  UVES_FLAT(true), UVES_FLAT(false),
685  CPL_TYPE_DOUBLE,
686  raw_images, raw_headers, product_header,
687  &blue), "Error loading raw flat frames");
688 
689  for (chip = uves_chip_get_first(blue); chip != UVES_CHIP_INVALID;
690  chip = uves_chip_get_next(chip))
691  {
692  product_tag[uves_chip_get_index(chip)] = UVES_MASTER_FLAT(chip);
693  }
694  }
695  else if (cpl_frameset_find(frames, UVES_DFLAT(true )) != NULL ||
696  cpl_frameset_find(frames, UVES_DFLAT(false)) != NULL)
697  {
698  check( uves_load_raw_imagelist(frames,
699  flames,
700  UVES_DFLAT(true), UVES_DFLAT(false),
701  CPL_TYPE_DOUBLE,
702  raw_images, raw_headers, product_header,
703  &blue), "Error loading raw flat frames");
704  for (chip = uves_chip_get_first(blue);
705  chip != UVES_CHIP_INVALID;
706  chip = uves_chip_get_next(chip))
707  {
708  product_tag[uves_chip_get_index(chip)] = UVES_MASTER_DFLAT(chip);
709  }
710  }
711  else if (cpl_frameset_find(frames, UVES_IFLAT(true )) != NULL ||
712  cpl_frameset_find(frames, UVES_IFLAT(false)) != NULL)
713  {
714  check( uves_load_raw_imagelist(frames,
715  flames,
716  UVES_IFLAT(true), UVES_IFLAT(false),
717  CPL_TYPE_DOUBLE,
718  raw_images, raw_headers, product_header,
719  &blue), "Error loading raw flat frames");
720  for (chip = uves_chip_get_first(blue);
721  chip != UVES_CHIP_INVALID;
722  chip = uves_chip_get_next(chip))
723  {
724  product_tag[uves_chip_get_index(chip)] = UVES_MASTER_IFLAT(chip);
725  }
726  }
727  else if (cpl_frameset_find(frames, UVES_TFLAT(true )) != NULL ||
728  cpl_frameset_find(frames, UVES_TFLAT(false)) != NULL)
729  {
730  check( uves_load_raw_imagelist(frames,
731  flames,
732  UVES_TFLAT(true), UVES_TFLAT(false),
733  CPL_TYPE_DOUBLE,
734  raw_images, raw_headers, product_header,
735  &blue), "Error loading raw flat frames");
736  for (chip = uves_chip_get_first(blue);
737  chip != UVES_CHIP_INVALID;
738  chip = uves_chip_get_next(chip))
739  {
740  product_tag[uves_chip_get_index(chip)] = UVES_MASTER_TFLAT(chip);
741  }
742  }
743  else if (cpl_frameset_find(frames, UVES_SCREEN_FLAT(true )) != NULL ||
744  cpl_frameset_find(frames, UVES_SCREEN_FLAT(false)) != NULL)
745  {
746  check( uves_load_raw_imagelist(frames,
747  flames,
748  UVES_SCREEN_FLAT(true), UVES_SCREEN_FLAT(false),
749  CPL_TYPE_DOUBLE,
750  raw_images, raw_headers, product_header,
751  &blue), "Error loading raw flat frames");
752  for (chip = uves_chip_get_first(blue);
753  chip != UVES_CHIP_INVALID;
754  chip = uves_chip_get_next(chip))
755  {
756  product_tag[uves_chip_get_index(chip)] = UVES_MASTER_SCREEN_FLAT(chip);
757  }
758  }
759  else if (cpl_frameset_find(frames, UVES_SFLAT(true )) != NULL ||
760  cpl_frameset_find(frames, UVES_SFLAT(false)) != NULL)
761  {
762  check( uves_load_raw_imagelist(frames,
763  flames,
764  UVES_SFLAT(true), UVES_SFLAT(false),
765  CPL_TYPE_DOUBLE,
766  raw_images, raw_headers, product_header,
767  &blue), "Error loading raw flat frames");
768  for (chip = uves_chip_get_first(blue);
769  chip != UVES_CHIP_INVALID;
770  chip = uves_chip_get_next(chip))
771  {
772  product_tag[uves_chip_get_index(chip)] = UVES_MASTER_SFLAT(chip);
773  }
774  }
775  else
776  {
777  assure(false, CPL_ERROR_DATA_NOT_FOUND,
778  "Missing input flat frame: "
779  "%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s or %s expected",
780  UVES_FLAT(true) , UVES_FLAT(false),
781  UVES_DFLAT(true), UVES_DFLAT(false),
782  UVES_IFLAT(true), UVES_IFLAT(false),
783  UVES_TFLAT(true), UVES_TFLAT(false),
784  UVES_SCREEN_FLAT(true), UVES_SCREEN_FLAT(false),
785  UVES_SFLAT(true), UVES_SFLAT(false));
786  }
787 
788  /* Loop over one or two chips */
789  for (chip = uves_chip_get_first(blue);
790  chip != UVES_CHIP_INVALID;
791  chip = uves_chip_get_next(chip))
792  {
793 
794  if(strcmp(PROCESS_CHIP,"REDU") == 0) {
795  chip = uves_chip_get_next(chip);
796  }
797 
798  raw_index = uves_chip_get_index(chip);
799 
800  uves_msg("Processing %s chip", uves_chip_tostring_upper(chip));
801 
802  /* Chip name of first input frame */
803  check_nomsg( chip_name = uves_pfits_get_chipid(raw_headers[raw_index][0], chip));
804 
805  /* Load master bias, set pointer to NULL if not present */
806  uves_free_image(&master_bias);
807  uves_free_propertylist(&master_bias_header);
808  if (cpl_frameset_find(frames, UVES_MASTER_BIAS(chip)) != NULL)
809  {
810  uves_free_image(&master_bias);
811  uves_free_propertylist(&master_bias_header);
812  check( uves_load_mbias(frames,
813  chip_name,
814  &master_bias_filename, &master_bias,
815  &master_bias_header, chip),
816  "Error loading master bias");
817 
818  uves_msg_low("Using master bias in '%s'", master_bias_filename);
819  }
820  else
821  {
822  uves_msg_low("No master bias in SOF. Bias subtraction not done");
823  }
824 
825  /* Load master dark, set pointer to NULL if not present */
826  uves_free_image(&master_dark);
827  uves_free_propertylist(&master_dark_header);
828  if (cpl_frameset_find(frames, UVES_MASTER_DARK(chip)) != NULL ||
829  cpl_frameset_find(frames, UVES_MASTER_PDARK(chip)) != NULL)
830  {
831  uves_free_image(&master_dark);
832  uves_free_propertylist(&master_dark_header);
833  check( uves_load_mdark(frames, chip_name,
834  &master_dark_filename, &master_dark,
835  &master_dark_header, chip),
836  "Error loading master dark");
837 
838  uves_msg_low("Using master dark in '%s'", master_dark_filename);
839  }
840  else
841  {
842  uves_msg_low("No master dark in SOF. Dark subtraction not done");
843  }
844 
845  /* Load the order table for this chip */
846  if (flames)
847  /* FLAMES does not do background subtraction (here)
848  and therefore does not need an ordertable */
849  {
850  if (cpl_frameset_find(frames, UVES_ORDER_TABLE(flames, chip)) != NULL)
851  {
852  uves_msg_warning("Order table (%s) is not used in FLAMES reduction",
853  UVES_ORDER_TABLE(flames, chip));
854  }
855  }
856  else
857  {
858  uves_free_table (&ordertable);
859  uves_free_propertylist(&ordertable_header);
860  uves_polynomial_delete(&order_locations);
861  uves_free_table (&traces);
862 
863  check( uves_load_ordertable(frames,
864  flames,
865  chip_name,
866  &ordertable_filename,
867  &ordertable,
868  &ordertable_header,
869  NULL,
870  &order_locations,
871  &traces, NULL, NULL,
872  NULL, NULL, /* fibre_pos,fibre_mask */
873  chip,
874  false),
875  "Could not load order table");
876  uves_msg("Using order table in '%s'", ordertable_filename);
877  }
878 
879  /* Compute QC parameters and save */
880  uves_msg("Computing QC parameters");
881  uves_qclog_delete(&qclog[0]);
882  qclog[0] = uves_qclog_init(raw_headers[raw_index][0], chip);
883 
884  check(uves_mflat_qclog(raw_images[raw_index],
885  qclog[0]),"error computing qclog");
886 
887 
888 
889  /* Process chip */
890  uves_free_image(&master_flat);
891  uves_free_image(&background);
892  check( master_flat = uves_mflat_process_chip(
893  raw_images[raw_index], raw_headers[raw_index],
894  product_header[raw_index],
895  master_bias,
896  master_dark, master_dark_header,
897  ordertable, order_locations,
898  flames,
899  parameters,
900  chip,
901  recipe_id,
902  debug_mode,
903  &background),
904  "Error processing chip");
905 
906  /* Finished. Save */
907  uves_msg("Saving products");
908 
909  cpl_free(product_filename);
910  check( product_filename = uves_masterflat_filename(chip),
911  "Error getting filename");
912  strcpy(pro_filename,prefix);
913  strcat(pro_filename,product_filename);
914  check( uves_frameset_insert(
915  frames,
916  master_flat,
917  CPL_FRAME_GROUP_PRODUCT,
918  CPL_FRAME_TYPE_IMAGE,
919  CPL_FRAME_LEVEL_INTERMEDIATE,
920  pro_filename,
921  product_tag[raw_index],
922  raw_headers[raw_index][0],
923  product_header[raw_index],
924  NULL,
925  parameters,
926  recipe_id,
927  PACKAGE "/" PACKAGE_VERSION, qclog,
928  starttime, true, UVES_ALL_STATS),
929  "Could not add master flat %s %s to frameset",
930  product_filename, product_tag[raw_index]);
931  uves_msg("Master flat %s %s added to frameset",
932  pro_filename, product_tag[raw_index]);
933 
934  /* Save background image */
935  if (!flames)
936  {
937  cpl_free(product_filename);
938  check( product_filename = uves_masterflat_bkg_filename(chip),
939  "Error getting filename");
940  strcpy(pro_filename,prefix);
941  strcat(pro_filename,product_filename);
942  uves_pfits_set_extname(product_header[raw_index],
943  "Inter-order background");
944  check( uves_frameset_insert(frames,
945  background,
946  CPL_FRAME_GROUP_PRODUCT,
947  CPL_FRAME_TYPE_IMAGE,
948  CPL_FRAME_LEVEL_INTERMEDIATE,
949  pro_filename,
950  UVES_BKG_FLAT(chip),
951  raw_headers[raw_index][0],
952  product_header[raw_index],
953  NULL,
954  parameters,
955  recipe_id,
956  PACKAGE "/" PACKAGE_VERSION, NULL,
957  starttime, false,
958  CPL_STATS_MIN | CPL_STATS_MAX),
959  "Could not add background image '%s' to frameset",
960  product_filename);
961  uves_msg("Master flat background '%s' added to frameset",
962  product_filename);
963  }
964 
965  /* Compute and save ratio MASTER_TFLAT / REF_TFLAT */
966  if (strcmp(recipe_id, make_str(UVES_TFLAT_ID)) == 0)
967  {
968 
969  uves_free_image(&ref_flat);
970  uves_free_propertylist(&ref_flat_header);
971 
972  check( uves_load_ref_flat(frames, chip_name, &ref_flat_filename,
973  &ref_flat, &ref_flat_header,
974  chip),
975  "Error loading reference flat field");
976 
977  uves_msg("Using reference flat field in '%s'", ref_flat_filename);
978 
979  check( ratio = cpl_image_divide_create(master_flat, ref_flat),
980  "Error computing ratio of master and reference flat");
981 
982  cpl_free(product_filename);
983  check( product_filename = uves_flat_ratio_filename(chip),
984  "Error getting filename");
985 
986  check( uves_frameset_insert(frames,
987  ratio,
988  CPL_FRAME_GROUP_PRODUCT,
989  CPL_FRAME_TYPE_IMAGE,
990  CPL_FRAME_LEVEL_INTERMEDIATE,
991  product_filename,
992  UVES_RATIO_TFLAT(chip),
993  raw_headers[raw_index][0],
994  product_header[raw_index],
995  NULL,
996  parameters,
997  recipe_id,
998  PACKAGE "/" PACKAGE_VERSION,
999  qclog,
1000  starttime, false,
1001  UVES_ALL_STATS),
1002  "Could not add ratio image '%s' to frameset", product_filename);
1003 
1004  uves_msg("Master flat ratio '%s' added to frameset", product_filename);
1005  }
1006 
1007 
1008  if(strcmp(PROCESS_CHIP,"REDL") == 0) {
1009  chip = uves_chip_get_next(chip);
1010  }
1011 
1012 
1013  } /* For each chip */
1014 
1015  cleanup:
1016  /* Input */
1017  if (raw_images[0] != NULL)
1018  {
1019  int i;
1020  for (i = 0; i < cpl_imagelist_get_size(raw_images[0]); i++)
1021  {
1022  if (raw_headers[0] != NULL) uves_free_propertylist(&raw_headers[0][i]);
1023  if (raw_headers[1] != NULL) uves_free_propertylist(&raw_headers[1][i]);
1024  }
1025  cpl_free(raw_headers[0]); raw_headers[0] = NULL;
1026  cpl_free(raw_headers[1]); raw_headers[1] = NULL;
1027  }
1028 
1029  uves_free_imagelist(&raw_images[0]);
1030  uves_free_imagelist(&raw_images[1]);
1031 
1032  /* Master bias */
1033  uves_free_image(&master_bias);
1034  uves_free_propertylist(&master_bias_header);
1035 
1036  /* Master dark */
1037  uves_free_image(&master_dark);
1038  uves_free_propertylist(&master_dark_header);
1039 
1040  /* Order table */
1041  uves_free_table(&ordertable);
1042  uves_free_propertylist(&ordertable_header);
1043  uves_polynomial_delete(&order_locations);
1044  uves_free_table(&traces);
1045 
1046  /* Reference master flat */
1047  uves_free_image(&ref_flat);
1048  uves_free_propertylist(&ref_flat_header);
1049 
1050  /* Output */
1051  uves_qclog_delete(&qclog[0]);
1052  uves_free_image(&master_flat);
1053  uves_free_image(&background);
1054  uves_free_image(&ratio);
1055  uves_free_propertylist(&product_header[0]);
1056  uves_free_propertylist(&product_header[1]);
1057  cpl_free(product_filename);
1058 
1059  return;
1060 }
1061 
1062 
1063 /*----------------------------------------------------------------------------*/
1069 /*----------------------------------------------------------------------------*/
1070 
1071 static void
1072 uves_mflat_qclog(const cpl_imagelist* raw_images,
1073  cpl_table* qclog)
1074 {
1075  int nraw=0;
1076 
1078  "QC TEST1 ID",
1079  "Test-on-Master-Flat",
1080  "Name of QC test",
1081  "%s"));
1082  check_nomsg(nraw=cpl_imagelist_get_size(raw_images));
1083 
1085  "PRO DATANCOM",
1086  nraw,
1087  "Number of frames combined",
1088  "%d"));
1089  cleanup:
1090  return;
1091 }
int uves_mflat_define_parameters_body(cpl_parameterlist *parameters, const char *recipe_id)
Setup the recipe options.
void uves_polynomial_delete(polynomial **p)
Delete a polynomial.
#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
static cpl_error_code uves_mflat_at_ypos(cpl_frameset *set, const cpl_parameterlist *parameters, const char *recipe_id, const char *starttime, const cpl_frameset *raw, const cpl_frameset *cdb, const int ref_x1enc, const int ref_x2enc, const int set_no)
Computes coherent master sflats.
cpl_image * uves_flat_create_normalized_master(cpl_imagelist *flats, const cpl_table *ordertable, const polynomial *order_locations, const cpl_vector *gain_vals, double *fnoise)
Stack images using k-sigma clipping.
Definition: uves_utils.c:702
double uves_pfits_get_gain(const uves_propertylist *plist, enum uves_chip chip)
Find out the gain.
Definition: uves_pfits.c:887
#define check_nomsg(CMD)
Definition: uves_error.h:204
cpl_image * uves_flat_create_normalized_master2(cpl_imagelist *flats, const cpl_table *ordertable, const polynomial *order_locations, const cpl_image *mflat)
Stack images using k-sigma clipping.
Definition: uves_utils.c:551
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_pfits_get_slit3_x2encoder(const uves_propertylist *plist)
find out the value of UVES_ENCODER_REF2
Definition: uves_pfits.c:174
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
static cpl_image * uves_mflat_process_chip(const cpl_imagelist *raw_images, uves_propertylist **raw_headers, uves_propertylist *master_flat_header, const cpl_image *master_bias, const cpl_image *master_dark, const uves_propertylist *mdark_header, const cpl_table *ordertable, const polynomial *order_locations, bool flames, const cpl_parameterlist *parameters, enum uves_chip chip, const char *recipe_id, bool debug_mode, cpl_image **background)
Process a single chip.
#define uves_msg(...)
Print a message on 'info' or 'debug' level.
Definition: uves_msg.h:119
uves_propertylist * uves_propertylist_load(const char *name, int position)
Create a property list from a file.
void uves_mflat_exe_body(cpl_frameset *frames, const cpl_parameterlist *parameters, const char *starttime, const char *recipe_id)
Get the command line options and execute the data reduction.
int uves_pfits_get_slit3_x1encoder(const uves_propertylist *plist)
find out the value of UVES_ENCODER_REF1
Definition: uves_pfits.c:156
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
static void uves_mflat_qclog(const cpl_imagelist *raw_images, cpl_table *qclog)
Process a single chip.
cpl_error_code uves_pfits_set_exptime(uves_propertylist *plist, double exptime)
Write the exposure time.
Definition: uves_pfits.c:944
#define uves_msg_low(...)
Print a message on a lower message level.
Definition: uves_msg.h:105
static void uves_reduce_mflat(cpl_frameset *frames, const cpl_parameterlist *parameters, bool flames, const char *recipe_id, const char *starttime, const char *prefix)
Get the command line options and execute the data reduction.
enum uves_chip uves_chip_get_next(enum uves_chip chip)
Get next chip.
Definition: uves_chip.c:108
static void uves_mflat_one(cpl_frameset *frames, const cpl_parameterlist *parameters, bool flames, const char *recipe_id, const char *starttime, const char *prefix)
Get the command line options and execute the data reduction.
#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
cpl_error_code uves_propertylist_append_c_double(uves_propertylist *self, const char *name, double value, const char *comment)
Append a double value to a property list.
#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
static cpl_error_code uves_msflats(cpl_frameset *set, const cpl_parameterlist *parameters, const char *recipe_id, const char *starttime)
Computes coherent master sflats.
const char * uves_pfits_get_chipid(const uves_propertylist *plist, enum uves_chip chip)
Find out the chip ID.
Definition: uves_pfits.c:619
cpl_frameset * uves_frameset_extract(const cpl_frameset *frames, const char *tag)
Extract frames with given tag from frameset.
Definition: uves_utils.c:1557