UVES Pipeline Reference Manual  5.4.2
uves_reduce_scired.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.70 $
24  * $Name: not supported by cvs2svn $
25  *
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31 
32 /*----------------------------------------------------------------------------*/
37 /*----------------------------------------------------------------------------*/
41 /*-----------------------------------------------------------------------------
42  Includes
43  -----------------------------------------------------------------------------*/
44 #include <uves_reduce_scired.h>
45 
46 #include <uves_reduce.h>
47 #include <uves_reduce_utils.h>
48 #include <uves_corrbadpix.h>
49 
50 #include <uves_chip.h>
51 #include <uves_plot.h>
52 #include <uves_dfs.h>
53 #include <uves_pfits.h>
54 #include <uves_parameters.h>
55 #include <uves_msg.h>
56 #include <uves_utils.h>
57 #include <uves_utils_wrappers.h>
58 #include <uves_qclog.h>
59 #include <uves_error.h>
60 #include <uves_merge.h>
61 #include <uves.h>
62 #include <uves_dump.h>
63 
64 #include <cpl.h>
65 #include <string.h>
66 /*-----------------------------------------------------------------------------
67  Functions prototypes
68  -----------------------------------------------------------------------------*/
69 
70 static void
71 scired_qclog(const cpl_table* info_tbl,
72  const uves_propertylist *raw_header,
73  const cpl_image *raw_image,
74  double slit,
75  cpl_table* qclog);
76 
77 static void
78 tflat_qclog(const cpl_image* ima,
79  const uves_propertylist *raw_header,
80  cpl_table* qclog);
81 
82 
83 /*-----------------------------------------------------------------------------
84  Implementation
85  -----------------------------------------------------------------------------*/
86 const char * const uves_scired_desc_short = "Reduces a science frame";
87 const char * const uves_scired_desc =
88 "This recipe reduces a science frame (SCIENCE_BLUE or SCIENCE_RED, or\n"
89 "UVES_SCI_POINT_BLUE or UVES_SCI_POINT_RED, or \n"
90 "UVES_SCI_EXTND_BLUE or UVES_SCI_EXTND_RED or \n"
91 "UVES_SCI_SLICER_BLUE or UVES_SCI_SLICER_RED) using "
92 "a combination (depending on recipe parameters and provided input frames) of "
93 "the steps:\n"
94 " - bias subtraction,\n"
95 " - dark subtraction,\n"
96 " - background subtraction,\n"
97 " - extraction/cosmic ray removal,\n"
98 " - flat field correction,\n"
99 " - wavelength rebinning,\n"
100 " - sky subtraction,\n"
101 " - order merging,\n"
102 " - response correction (if response curve is provided).\n"
103 "\n"
104 "Additional input for this recipe are: \n"
105 "order table(s) for each chip, ORDER_TABLE_xxxx (where xxxx=BLUE, REDL, REDU),\n"
106 "line table(s) for each chip, LINE_TABLE_xxxx, a master bias frame,\n"
107 "MASTER_BIAS_xxxx, a master flat, MASTER_FLAT_xxxx, \n"
108 "optionally an instrument response table, INSTR_RESPONSE_xxx\n"
109 "optionally a table describing the atmospheric extintion,\n"
110 "EXTCOEFF_TABLE. \n"
111 "For each chip (xxxx = BLUE, REDL, REDU) the recipe produces a combination of "
112 "the products:\n"
113 " 'RED_SCIENCE_xxxx' Reduced science spectrum\n"
114 " 'MERGED_SCIENCE_xxxx' Merged spectrum, no sky subtraction\n"
115 " 'WCALIB_SCIENCE_xxxx' Extracted, wavelength calibrated frame in\n"
116 " (wavelength, order) space\n"
117 " 'WCALIB_FF_SCIENCE_xxxx' Extracted, flat-fielded, wave.cal. frame in\n"
118 " (wavelength, order) space\n"
119 " (Only if flatfielding done)\n"
120 " 'WCALIB_FLAT_OBJ_xxxx' Extracted, wavelength calibrated flat field\n"
121 " in (wavelength, order) space\n"
122 " (Only if flatfielding done)\n"
123 " 'ERRORBAR_SCIENCE_xxxx' Error bars of 'RED_SCIENCE_xxxx'\n"
124 " 'VARIANCE_SCIENCE_xxxx' Variance of extracted, flatfielded object in\n"
125 " (pixel, order) space\n"
126 " 'ORDER_TRACE_xxxx' Table describing the spatial profile\n"
127 " 'FLUXCAL_SCIENCE_xxxx' Flux-calibrated science spectrum\n"
128 " 'FLUXCAL_ERROR_xxxx' Error bars of 'FLUXCAL_SCIENCE_xxxx'\n"
129 " 'BKG_SCI_xxxx' The subtracted background image\n"
130 " 'CRMASK_xxxx' List of cosmic ray hits\n"
131 " 'MERGED_SKY_xxxx' The merged sky spectrum\n"
132 " 'EXT_2D_SCIENCE_xxxx' The 2d extracted spectrum\n"
133 " 'FF2D_SCIENCE_xxxx' The 2d extracted, flat-fielded spectrum\n"
134 " 'WCAL2D_SCIENCE_xxxx' The 2d extracted, flat-fielded, wave.cal. spectrum\n"
135 " 'MER2D_SCIENCE_xxxx' The 2d reduced, flux-calibrated (if possible) \n"
136 " science spectrum\n";
137 
138 
139 
140 
141 
142 static uves_propertylist*
143 uves_paste_wave_accuracy(const uves_propertylist* header_from)
144 {
145  uves_propertylist* header_add=NULL;
146  double waverms=0;
147  double wavenlin=0;
148  double waveerr=0;
149  double wavesys=0;
150  const char* key_comm=NULL;
151  char key_name_i[40];
152  char key_name_o[40];
153  uves_msg("paste wave accuracy");
154  header_add=uves_propertylist_new();
155 
156  sprintf(key_name_o,"CUNIT1");
157  key_comm="Wavelength units";
158  uves_propertylist_append_c_string(header_add,key_name_o,"Angstrom",key_comm);
159 
160  sprintf(key_name_i,"ESO QC LINE RESIDRMS WLU");
161  sprintf(key_name_o,"LAMRMS");
162  key_comm="RMS of wavelength solution [CUNIT1]";
163 
164  if(uves_propertylist_has(header_from,key_name_i)) {
165  waverms=uves_propertylist_get_double(header_from,key_name_i);
166  uves_propertylist_append_c_double(header_add,key_name_o,waverms,key_comm);
167 
168  }
169 
170 
171  sprintf(key_name_i,"ESO QC NLINSOL");
172  sprintf(key_name_o,"LAMNLIN");
173  key_comm="No. of lines used in wavelength solution";
174 
175  if(uves_propertylist_has(header_from,key_name_i)) {
176  wavenlin=uves_propertylist_get_int(header_from,key_name_i);
177  uves_propertylist_append_c_int(header_add,key_name_o,wavenlin,key_comm);
178 
179  }
180 
181 
182  sprintf(key_name_i,"ESO QC LINE WAVEERR");
183  sprintf(key_name_o,"CRDER1");
184  key_comm="Wavelength uncertainty [CUNIT1]";
185  if(uves_propertylist_has(header_from,key_name_i)) {
186  waveerr=uves_propertylist_get_double(header_from,key_name_i);
187  uves_propertylist_append_c_double(header_add,key_name_o,waveerr,key_comm);
188 
189  }
190 
191 
192  sprintf(key_name_i,"ESO QC LINE SYSERR");
193  sprintf(key_name_o,"CSYER1");
194  key_comm="Typical systematic wavelength error [CUNIT1]";
195  if(uves_propertylist_has(header_from,key_name_i)) {
196  wavesys=uves_propertylist_get_double(header_from,key_name_i);
197  uves_propertylist_append_c_double(header_add,key_name_o,wavesys,key_comm);
198 
199  }
200 
201  return header_add;
202 
203 }
204 
205 
206 
207 
208 /*----------------------------------------------------------------------------*/
215 /*----------------------------------------------------------------------------*/
216 int uves_scired_define_parameters_body(cpl_parameterlist *parameters,
217  const char *recipe_id)
218 {
219 
220  /*****************
221  * General *
222  *****************/
223  if (uves_define_global_parameters(parameters) != CPL_ERROR_NONE)
224  {
225  return -1;
226  }
227 
228  /**************************************
229  * detector's trap correction *
230  **************************************/
231 
232  if (uves_corr_traps_define_parameters(parameters,recipe_id)
233  != CPL_ERROR_NONE)
234  {
235  return -1;
236  }
237 
238  /*******************
239  * Reduce. *
240  ******************/
241  if (uves_propagate_parameters_step(UVES_REDUCE_ID, parameters,
242  recipe_id, NULL) != 0)
243  {
244  return -1;
245  }
246 
247  return (cpl_error_get_code() != CPL_ERROR_NONE);
248 }
249 
250 
251 const char*
252 uves_get_pro_catg_special(bool extract_is_2d, merge_method m_method) {
253  const char* result=NULL;
254  if(extract_is_2d && m_method == MERGE_NOAPPEND) {
255  result="";
256  } else if (!extract_is_2d &&
257  m_method == MERGE_NOAPPEND) {
258  result="_NONMERGED";
259  } else {
260  result="";
261  }
262 
263  return result;
264 }
265 
266 /*----------------------------------------------------------------------------*/
272 /*----------------------------------------------------------------------------*/
273 static cpl_frame **
274 set_all_raw_none(cpl_frameset *frames)
275 {
276  cpl_frame **result = NULL;
277  cpl_frame *f;
278  int i;
279 
280  result = cpl_calloc( cpl_frameset_get_size(frames) + 1,
281  sizeof(*result) );
282 
283  for (f = cpl_frameset_get_first(frames), i = 0;
284  f != NULL;
285  f = cpl_frameset_get_next(frames))
286  {
287  if (cpl_frame_get_group(f) == CPL_FRAME_GROUP_RAW)
288  {
289  /* Change + remember this frame */
290  cpl_frame_set_group(f, CPL_FRAME_GROUP_NONE);
291  result[i] = f;
292  i++;
293  }
294  }
295 
296  /* 'result' is now a NULL-terminated array of the frames that were changed */
297 
298  return result;
299 }
300 
301 /*----------------------------------------------------------------------------*/
371 /*----------------------------------------------------------------------------*/
372 
373 static cpl_error_code
374 uves_scired_process_chip(const cpl_image *raw_image,
375  const uves_propertylist *raw_header,
376  const uves_propertylist *rotated_header,
377  const cpl_image *master_bias,
378  const uves_propertylist *mbias_header,
379  const cpl_image *master_dark,
380  const uves_propertylist *mdark_header,
381  const cpl_image *master_flat,
382  const uves_propertylist *mflat_header,
383  const cpl_table *ordertable,
384  const polynomial *order_locations,
385  const cpl_table *linetable[3],
386  const uves_propertylist *linetable_header[3],
387  const polynomial *dispersion_relation[3],
388  const cpl_image *response_curve,
389  const cpl_table *master_response,
390  const uves_propertylist *response_curve_header,
391  const cpl_table *atm_extinction,
392  enum uves_chip chip,
393  /* General */
394  bool debug_mode,
395  /* Backsub */
396  /* Flat fielding */
397  /* Extraction */
398  /* Rebinning */
399  const cpl_parameterlist *parameters,
400  const char *recipe_id,
401  /* Output */
402  cpl_image **x2d, uves_propertylist **x2d_header,
403  cpl_image **fx2d,
404  cpl_image **background,
405  cpl_image **flatfielded_variance,
406  uves_propertylist **flatfielded_variance_header,
407  cpl_image **resampled_science,
408  cpl_image **resampled_mf,
409  cpl_image **rebinned_science,
410  cpl_image **rebinned_noise,
411  uves_propertylist **rebinned_header,
412  cpl_image **merged_sky,
413  cpl_image **merged_science,
414  uves_propertylist **merged_header,
415  cpl_image **reduced_science,
416  cpl_image **reduced_science_error,
417  cpl_table **cosmic_mask,
418  cpl_image **wave_map,
419  cpl_image **fluxcal_science,
420  cpl_image **fluxcal_error,
421  uves_propertylist **fluxcal_header,
422  cpl_table **info_tbl,
423  double *extraction_slit,
424  cpl_table **order_trace)
425 {
426 
427  cpl_image *merged_noise = NULL;
428 
429  cpl_image *reduced_rebinned = NULL;
430  cpl_image *reduced_rebinned_noise = NULL;
431 
432  cpl_table *response_table = NULL;
433 
434  /* Do the science reduction. Produces wave.cal. spectra. */
435  uves_msg("Reducing science object");
436 
437  check( uves_reduce(raw_image,
438  raw_header,
439  rotated_header,
440  master_bias,
441  mbias_header,
442  master_dark,
443  mdark_header,
444  master_flat,
445  mflat_header,
446  ordertable,
447  order_locations,
448  linetable,
449  linetable_header,
450  dispersion_relation,
451  chip,
452  debug_mode,
453  parameters,
454  recipe_id,
455  "",
456  /* Output */
457  x2d,
458  x2d_header,
459  fx2d,
460  cosmic_mask,
461  wave_map,
462  background,
463  flatfielded_variance,
464  flatfielded_variance_header,
465  resampled_science,
466  resampled_mf,
467  merged_sky,
468  rebinned_science,
469  rebinned_noise,
470  rebinned_header,
471  merged_science,
472  &merged_noise,
473  merged_header,
474  &reduced_rebinned,
475  &reduced_rebinned_noise,
476  reduced_science,
477  reduced_science_error,
478  info_tbl,
479  extraction_slit,
480  order_trace),
481  "Could not reduce frame");
482 
483  /* Plot middle row */
484  check( uves_plot_image_rows(*reduced_science,
485  1 + cpl_image_get_size_y(*reduced_science)/2,
486  1 + cpl_image_get_size_y(*reduced_science)/2, 1,
487  "Wavelength (arbitrary units)", "Relative flux",
488  "Reduced science spectrum"),
489  "Plotting failed");
490 
491 
492  /*
493  * Flux calibrate the reduced spectrum
494  * (which is an image of height 1, or more if extract.method=2d)
495  */
496 
497  if (response_curve != NULL || master_response != NULL)
498  {
499  double lambda_start;
500  double dlambda;
501  int bin;
502 
503  /* Number of spatial traces (> 1 for 2d extraction) */
504  int n_traces = cpl_image_get_size_y(*reduced_science);
505 
506  uves_msg("Flux calibrating spectrum");
507 
508  /* We cannot be certain that the formats (wavelength start, bin width)
509  of the science spectrum and the response curve are identical.
510  Therefore we interpolate the response curve at the wavelengths
511  defined by the bins of the science spectrum. */
512 
513 
514 
515  /* If the response curve is an image, convert to table.
516  This is needed for the interpolation */
517  if (response_curve != NULL) {
518  response_table = cpl_table_new(cpl_image_get_size_x(response_curve));
519  cpl_table_new_column(response_table, "LAMBDA", CPL_TYPE_DOUBLE);
520  cpl_table_new_column(response_table, "FLUX_CONV", CPL_TYPE_DOUBLE);
521 
522  check( lambda_start = uves_pfits_get_crval1(response_curve_header),
523  "Error reading response curve start wavelength from header");
524 
525  check( dlambda = uves_pfits_get_cdelt1(response_curve_header),
526  "Error reading bin width from header");
527 
528  for (bin = 1; bin <= cpl_image_get_size_x(response_curve); bin++) {
529  double lambda;
530  double response;
531  int pis_rejected;
532 
533  lambda = lambda_start + (bin-1) * dlambda;
534 
535  check( response = cpl_image_get(response_curve, bin, 1, &pis_rejected),
536  "Error reading response curve bin = %d", bin);
537 
538  check((cpl_table_set_double(response_table, "LAMBDA", bin - 1, lambda),
539  cpl_table_set_double(response_table, "FLUX_CONV", bin - 1, response)),
540  "Error updating response table at row %d", bin - 1);
541  }
542  }
543  else {
544  response_table = cpl_table_duplicate( master_response );
545  } /* Response table created */
546 
547  /*
548  * Correct for exposure time, gain, binning, atm. ext.
549  */
550 
551  check( *fluxcal_science = uves_normalize_spectrum(*reduced_science,
552  *reduced_science_error,
553  *merged_header,
554  raw_header,
555  n_traces,
556  chip,
557  atm_extinction,
558  true, /* Divide by binning? */
559  fluxcal_error),
560  "Error normalizing reduced spectrum");
561 
562  /*
563  * Flux calibrate reduced spectrum
564  * flux := flux * response
565  */
566  uves_msg("Multiplying by response function");
567  {
568  int nbins = cpl_image_get_size_x(*fluxcal_science);
569  int ntraces = cpl_image_get_size_y(*fluxcal_science);
570  double *fluxcal_science_data = cpl_image_get_data_double(*fluxcal_science);
571  double *fluxcal_science_noise = cpl_image_get_data_double(*fluxcal_error);
572 
573  check( lambda_start = uves_pfits_get_crval1(*merged_header),
574  "Error reading start wavelength from reduced science header");
575 
576  check( dlambda = uves_pfits_get_cdelt1(*merged_header),
577  "Error reading bin width from header");
578 
579  for (bin = 1; bin <= nbins; bin++)
580  {
581  double lambda;
582  double response;
583  int trace; /* Spatial traces (for 2d extracted spectra) */
584  int istart = 0;
585 
586  lambda = lambda_start + (bin-1) * dlambda;
587 
588  check( response =
589  uves_spline_hermite_table(lambda, response_table,
590  "LAMBDA", "FLUX_CONV", &istart),
591  "Error interpolating response curve at lambda = %f wlu", lambda);
592 
593  for (trace = 1; trace <= ntraces; trace++)
594  {
595  /* Don't check for bad pixels here, also correct those.
596  * The fluxcal image has the same bad pixels as the reduced_science
597  * image */
598 
599  fluxcal_science_data [(bin-1) + (trace-1)*nbins] *= response;
600  fluxcal_science_noise[(bin-1) + (trace-1)*nbins] *= response;
601 
602  /* Do not propagate the error of the response
603  curve which is negligibly small (and unknown at this point!).
604  */
605  }
606  }
607 
608  /* Plot middle row */
609  check( uves_plot_image_rows(*fluxcal_science,
610  1 + cpl_image_get_size_y(*fluxcal_science)/2,
611  1 + cpl_image_get_size_y(*fluxcal_science)/2, 1,
612  "Wavelength (arbitrary units)",
613  "Flux (10^-16 erg/cm^2/Angstrom/s)",
614  "Flux calibrated science spectrum"),
615  "Plotting failed");
616 
617  check( *fluxcal_header = uves_initialize_image_header("AWAV", " ",
618  "Angstrom", NULL,
619  "10^-16 erg/cm^2/Angstrom/s",
620  1,
621  lambda_start, 1.0,
622  1.0, 1.0,
623  dlambda, 1.0),
624  "Error initializing flux calibrated spectrum header");
625  } /* Done multiplying by response curve */
626  }
627  else
628  {
629  uves_msg("Skipping absolute flux calibration");
630  }
631 
632  cleanup:
633  uves_free_image(&merged_noise);
634  uves_free_image(&reduced_rebinned_noise);
635  uves_free_image(&reduced_rebinned);
636  uves_free_table(&response_table);
637 
638  if (cpl_error_get_code() != CPL_ERROR_NONE)
639  {
640  }
641 
642  return cpl_error_get_code();
643 }
644 
645 
646 /*----------------------------------------------------------------------------*/
655 /*----------------------------------------------------------------------------*/
656 void uves_reduce_scired(cpl_frameset *frames, const cpl_parameterlist *parameters,
657  const char *recipe_id, const char *starttime)
658 {
659  /* Recipe parameters */
660  bool debug_mode;
661  bool CLEAN_TRAPS;
662  bool extract_is_2d = false; /* Are we doing a 2d reduction? */
663 
664  /* Input, raw */
665  cpl_image *raw_image[2] = {NULL, NULL};
666  uves_propertylist *raw_header[2] = {NULL, NULL};
667  uves_propertylist *rotated_header[2] = {NULL, NULL};
668 
669  /* Input, calib */
670  cpl_image *master_bias = NULL;
671  uves_propertylist *master_bias_header = NULL;
672 
673  cpl_image *master_flat = NULL;
674  uves_propertylist *master_flat_header = NULL;
675 
676  cpl_image *master_dark = NULL;
677  uves_propertylist *master_dark_header = NULL;
678 
679  cpl_table *ordertable = NULL;
680  uves_propertylist *ordertable_header= NULL;
681  polynomial *order_locations = NULL;
682  cpl_table *traces = NULL;
683 
684  /* Line tables for sky, object, sky (UVES specific) */
685  const cpl_table *linetable[3] = {NULL, NULL, NULL};
686  const uves_propertylist *linetable_header[3] = {NULL, NULL, NULL};
687  const polynomial *dispersion_relation[3] = {NULL, NULL, NULL};
688 
689  cpl_image *response_curve = NULL;
690  uves_propertylist *response_curve_header = NULL;
691  cpl_table *master_response = NULL;
692 
693  cpl_table *atm_extinction = NULL;
694 
695  /* Output */
696  /* BKG_SCI */
697  cpl_image *background = NULL;
698 
699  /* VARIANCE_SCIENCE */
700  cpl_image *flatfielded_variance = NULL;
701  uves_propertylist *flatfielded_variance_header = NULL;
702 
703  /* WCALIB_SCIENCE */
704  cpl_image *resampled_science = NULL; /* extracted -> rebinned */
705  /* WCALIB_FLAT_OBJ */
706  cpl_image *resampled_mf = NULL;
707  /* WCALIB_FF_SCIENCE */
708  cpl_image *rebinned_science = NULL; /* extracted -> ff -> rebinned */
709  cpl_image *rebinned_science_error = NULL;
710  uves_propertylist *rebinned_header = NULL;
711 
712  /* MERGED_SKY */
713  cpl_image *merged_sky = NULL;
714 
715  /* MERGED_SCIENCE / MER2D_SCIENCE */
716  /* RED_SCIENCE */
717  /* ERRORBAR_SCIENCE */
718  cpl_image *merged_science = NULL;
719  uves_propertylist *merged_header = NULL;
720  cpl_image *reduced_science = NULL;
721  cpl_image *reduced_science_error = NULL;
722 
723 
724  /* FLUXCAL_SCIENCE / FLUXCAL_ERROR */
725  cpl_image *fluxcal_science = NULL;
726  cpl_image *fluxcal_error = NULL;
727  uves_propertylist *fluxcal_header = NULL;
728 
729  /* ORDER_TRACE */
730  cpl_table *order_trace = NULL;
731  uves_propertylist *order_trace_header = NULL;
732 
733 
734  /* EXT_2D_SCIENCE */
735  cpl_image *x2d = NULL;
736  uves_propertylist *x2d_header = NULL;
737  /* FF2D_SCIENCE */
738  cpl_image *fx2d = NULL;
739 
740  /* CRMASK */
741  cpl_table *cosmic_mask = NULL;
742  uves_propertylist *cosmic_mask_header = NULL;
743 
744  /* QC */
745  cpl_table* qclog[2] = {NULL, NULL};
746  cpl_table *qclog_tflat = NULL;
747 
748  /* Local variables */
749  const char *raw_filename = "";
750  const char *atm_ext_filename = "";
751  const char *sci_type = "";
752  cpl_frame **raw_frames = NULL; /* Array of cpl_frame pointers */
753  char *product_tag = NULL;
754  char *product_filename = NULL;
755  char *context = NULL;
756  double extraction_slit;
757 
758  bool blue = false;
759  enum uves_chip chip;
760  int binx = 0;
761  int biny = 0;
762 
763  cpl_table* info_tbl = NULL;
764  const char* PROCESS_CHIP=NULL;
765  bool red_ccd_is_new=0;
766  merge_method m_method;
767  const char* catg_is_noappend=NULL;
768  cpl_image* wave_map=NULL;
769  uves_propertylist* wave_map_header=NULL;
770  uves_propertylist* wave_acc_header=NULL;
771 
772  /* Read recipe parameters */
773  {
774  const char *ex_method = "";
775 
776  /* General */
777  check( uves_get_parameter(parameters, NULL, "uves", "debug", CPL_TYPE_BOOL, &debug_mode),
778  "Could not read parameter");
779 
780 
781 
782  check( uves_get_parameter(parameters, NULL, "uves", "debug", CPL_TYPE_BOOL, &debug_mode),
783  "Could not read parameter");
784 
785 
786 
787  check( uves_get_parameter(parameters, NULL, "uves", "process_chip", CPL_TYPE_STRING, &PROCESS_CHIP),
788  "Could not read parameter");
789  uves_string_toupper((char*)PROCESS_CHIP);
790 
791 
792  check( uves_get_parameter(parameters,NULL,recipe_id, "clean_traps", CPL_TYPE_BOOL, &CLEAN_TRAPS),
793  "Could not read parameter");
794 
795 
796 
797  /* Reduction method */
798  context = uves_sprintf("%s.%s.%s", recipe_id, UVES_REDUCE_ID, UVES_EXTRACT_ID);
799 
800  check( uves_get_parameter(parameters, NULL,
801  context, "method",
802  CPL_TYPE_STRING, &ex_method),
803  "Could not read parameter");
804 
805  extract_is_2d = (strcmp(ex_method, "2d") == 0);
806 
807  /* Load raw image and header, and identify input frame as red or blue */
808  check( uves_load_science(frames, &raw_filename, raw_image, raw_header, rotated_header,
809  &blue, &sci_type),
810  "Error loading raw frame");
811 
812  if ((strcmp(sci_type, "SCI_SLICER") == 0 ||
813  strcmp(sci_type, "SCI_EXTND" ) == 0) &&
814  strcmp(ex_method, "optimal") == 0)
815  {
816  uves_msg_warning("Going to optimally extract an extended object (%s). "
817  "This may not work because the sky cannot be "
818  "reliably determined",
819  sci_type);
820  }
821  }
822 
823  /* Load atmospheric extinction table if present */
824  if (cpl_frameset_find(frames, UVES_EXTCOEFF_TABLE) != NULL)
825  {
826  check( uves_load_atmo_ext(frames, &atm_ext_filename, &atm_extinction),
827  "Error loading atm. extinction coefficients");
828 
829  uves_msg_low("Using atmospheric extinction table in '%s'", atm_ext_filename);
830  }
831  else
832  {
833  uves_msg_low("No atmospheric extinction table. Flux calibration not done");
834  }
835 
836  check( m_method = uves_get_merge_method(parameters, recipe_id, "reduce"),
837  "Could not get merging method");
838 
839  /* Adjust parameters according to binning
840  * (note that x- and y-directions are swapped later by uves_crop_and_rotate())
841  */
842  check (binx = uves_pfits_get_binx(raw_header[0]),
843  "Could not read x binning factor from input header");
844  check (biny = uves_pfits_get_biny(raw_header[0]),
845  "Could not read y binning factor from input header");
846 
847  check_nomsg(red_ccd_is_new=uves_ccd_is_new(raw_header[0]));
848  /* Loop over one or two chips, over traces and
849  over extraction windows */
850  for (chip = uves_chip_get_first(blue);
851  chip != UVES_CHIP_INVALID;
852  chip = uves_chip_get_next(chip))
853  {
854 
855 
856 
857  if(strcmp(PROCESS_CHIP,"REDU") == 0) {
858  chip = uves_chip_get_next(chip);
859  }
860 
861  cpl_frame *mflat_frame = NULL;
862  const char *ordertable_filename = "";
863  const char *linetable_filename = "";
864  const char *master_bias_filename = "";
865  const char *master_dark_filename = "";
866  const char *master_flat_filename = "";
867  const char *response_curve_filename = "";
868  const char *chip_name = "";
869  /* const char *drs_filename = ""; not used */
870  /* Do this to skip REDL chip: chip = uves_chip_get_next(chip); */
871  int raw_index = uves_chip_get_index(chip);
872  int tracerow; /* Index of table row */
873 
874  uves_msg("Processing %s chip in '%s'",
875  uves_chip_tostring_upper(chip), raw_filename);
876 
877  check_nomsg( chip_name = uves_pfits_get_chipid(raw_header[raw_index], chip));
878 
879  uves_msg_debug("Binning = %dx%d", binx, biny);
880 
881 
882  /* Load master bias, set pointer to NULL if not present */
883  uves_free_image(&master_bias);
884  uves_free_propertylist(&master_bias_header);
885  if (cpl_frameset_find(frames, UVES_MASTER_BIAS(chip)) != NULL)
886  {
887  uves_free_image(&master_bias);
888  uves_free_propertylist(&master_bias_header);
889 
890  check( uves_load_mbias(frames, chip_name, &master_bias_filename,
891  &master_bias, &master_bias_header,
892  chip),
893  "Error loading master bias");
894 
895  uves_msg_low("Using master bias in '%s'", master_bias_filename);
896  }
897  else
898  {
899  uves_msg_low("No master bias in SOF. Bias subtraction not done");
900  }
901 
902  /* Load master dark, set pointer to NULL if not present */
903  uves_free_image(&master_dark);
904  uves_free_propertylist(&master_dark_header);
905  if (cpl_frameset_find(frames, UVES_MASTER_DARK(chip)) != NULL ||
906  cpl_frameset_find(frames, UVES_MASTER_PDARK(chip)) != NULL)
907 
908  {
909  check( uves_load_mdark(frames, chip_name, &master_dark_filename,
910  &master_dark, &master_dark_header, chip),
911  "Error loading master dark");
912 
913  uves_msg_low("Using master dark in '%s'", master_dark_filename);
914  }
915  else
916  {
917  uves_msg_low("No master dark in SOF. Dark subtraction not done");
918  }
919 
920  /* Load master flat */
921  uves_free_image(&master_flat);
922  uves_free_propertylist(&master_flat_header);
923  check( uves_load_mflat(frames, chip_name, &master_flat_filename, &master_flat,
924  &master_flat_header, chip, &mflat_frame),
925  "Error loading master flat");
926 
927  uves_msg_low("Using master flat in '%s'", master_flat_filename);
928 
929 
930  /* Load the order table for this chip */
931  uves_free_table (&ordertable);
932  uves_free_propertylist(&ordertable_header);
933  uves_polynomial_delete(&order_locations);
934  uves_free_table (&traces);
935 
936  check( uves_load_ordertable(frames,
937  false, /* FLAMES? */
938  chip_name,
939  &ordertable_filename,
940  &ordertable,
941  &ordertable_header,
942  NULL,
943  &order_locations,
944  &traces,
945  NULL, NULL,
946  NULL, NULL, /* fibre_pos,fibre_mask */
947  chip, false),
948  "Could not load order table");
949  uves_msg_low("Using order table in '%s'", ordertable_filename);
950 
951  /* Load response curve, if present.
952  Only if atm. extinction table was present. */
953  if (atm_extinction != NULL)
954  {
955  if (cpl_frameset_find(frames, UVES_INSTR_RESPONSE(chip)) != NULL ||
956  cpl_frameset_find(frames, UVES_MASTER_RESPONSE(chip)) != NULL)
957  {
958  uves_free_image(&response_curve);
959  uves_free_table(&master_response);
960  uves_free_propertylist(&response_curve_header);
961  check( uves_load_response_curve(frames, chip_name,
962  &response_curve_filename,
963  &response_curve,
964  &master_response,
965  &response_curve_header,
966  chip),
967  "Error loading response curve");
968 
969  uves_msg_low("Using %sresponse curve in '%s'",
970  master_response != NULL ? "master " : "",
971  response_curve_filename);
972  }
973  else
974  {
975  uves_msg_low("No response curve in SOF. "
976  "Flux calibration not done");
977  }
978  }
979  else
980  {
981  uves_msg_debug("There is no atmospheric extinction table. "
982  "Do not look for response curve");
983  }
984 
985  /* Loop over all traces (1 trace for UVES) */
986  for(tracerow = 0; tracerow < cpl_table_get_nrow(traces); tracerow++)
987  {
988  double trace_offset;
989  int trace_number;
990  int trace_enabled;
991  int badpixels_cleaned;
992  trace_offset = cpl_table_get_double(traces, "Offset" , tracerow, NULL);
993  trace_number = cpl_table_get_int (traces, "TraceID" , tracerow, NULL);
994  trace_enabled = cpl_table_get_int (traces, "Tracemask" , tracerow, NULL);
995 
996  if (trace_enabled != 0)
997  {
998  int window; /* window number */
999 
1000  if (cpl_table_get_nrow(traces) > 1) {
1001  uves_msg("Processing trace %d", trace_number);
1002  }
1003 
1004  /* This is UVES specific. Load linetable for the
1005  two sky windows (number 1, 3) and for the object
1006  window (number 2) */
1007 
1008  for (window = 1; window <= 3; window ++) {
1009  uves_free_table_const ( &(linetable[window-1]) );
1010  uves_free_propertylist_const( &(linetable_header[window-1]) );
1011  uves_polynomial_delete_const( &(dispersion_relation[window-1]) );
1012  check( uves_load_linetable_const(frames,
1013  false, /* FLAMES? */
1014  chip_name,
1015  order_locations,
1016  cpl_table_get_column_min(
1017  ordertable, "Order"),
1018  cpl_table_get_column_max(
1019  ordertable, "Order"),
1020  &linetable_filename,
1021  &(linetable [window-1]),
1022  &(linetable_header [window-1]),
1023  &(dispersion_relation[window-1]),
1024  NULL,
1025  chip,
1026  trace_number,
1027  window),
1028  "Could not load line table, window #%d", window);
1029 
1030  uves_msg_low("Using line table(s) in '%s'", linetable_filename);
1031 
1032  }
1033  uves_propertylist* plist=uves_propertylist_load(linetable_filename,0);
1034  uves_free_propertylist(&wave_acc_header);
1035  wave_acc_header=uves_paste_wave_accuracy(plist);
1036  uves_free_propertylist(&plist);
1037  /* end, UVES specific */
1038 
1039  /* Do the science reduction + flux calibration */
1040  uves_free_image(&x2d);
1041  uves_free_image(&fx2d);
1042  uves_free_propertylist(&x2d_header);
1043  uves_free_image(&background);
1044  uves_free_image(&flatfielded_variance);
1045  uves_free_propertylist(&flatfielded_variance_header);
1046  uves_free_image(&resampled_science);
1047  uves_free_image(&resampled_mf);
1048  uves_free_image(&rebinned_science);
1049  uves_free_image(&rebinned_science_error);
1050  uves_free_propertylist(&rebinned_header);
1051  uves_free_image(&merged_sky);
1052  uves_free_image(&merged_science);
1053  uves_free_propertylist(&merged_header);
1054  uves_free_image(&reduced_science);
1055  uves_free_image(&reduced_science_error);
1056  uves_free_table(&cosmic_mask);
1057  uves_free_image(&fluxcal_science);
1058  uves_free_image(&fluxcal_error);
1059  uves_free_propertylist(&fluxcal_header);
1060  uves_free_table(&info_tbl);
1061  uves_free_table(&order_trace);
1062 
1063  if(CLEAN_TRAPS) {
1064 
1065  check( badpixels_cleaned =
1066  uves_correct_badpix_all(raw_image[raw_index],
1067  raw_header[raw_index],
1068  chip, binx, biny,
1069  false,red_ccd_is_new),
1070  "Error replacing bad pixels");
1071 
1072  uves_msg("%d bad pixels replaced",
1073  badpixels_cleaned);
1074  }
1075 
1077  raw_image[raw_index],
1078  raw_header[raw_index], /* Raw */
1079  rotated_header[raw_index],
1080  master_bias, /* Calibration */
1081  master_bias_header,
1082  master_dark,
1083  master_dark_header,
1084  master_flat,
1085  master_flat_header,
1086  ordertable,
1087  order_locations,
1088  linetable,
1089  linetable_header,
1090  dispersion_relation,
1091  response_curve,
1092  master_response,
1093  response_curve_header,
1094  atm_extinction,
1095  chip,
1096  debug_mode,
1097  parameters,
1098  recipe_id,
1099  &x2d,
1100  &x2d_header,
1101  &fx2d, /* Products */
1102  &background,
1103  &flatfielded_variance,
1104  &flatfielded_variance_header,
1105  &resampled_science,
1106  &resampled_mf,
1107  &rebinned_science,
1108  &rebinned_science_error,
1109  &rebinned_header,
1110  &merged_sky,
1111  &merged_science,
1112  &merged_header,
1113  &reduced_science,
1114  &reduced_science_error,
1115  &cosmic_mask,
1116  &wave_map,
1117  &fluxcal_science,
1118  &fluxcal_error,
1119  &fluxcal_header,
1120  &info_tbl,
1121  &extraction_slit,
1122  &order_trace),
1123  "Science reduction failed");
1124 
1125  if (!extract_is_2d)
1126  {
1127  uves_qclog_delete(&qclog[0]);
1128  qclog[0] = uves_qclog_init(raw_header[raw_index], chip);
1129 
1130  check( scired_qclog(info_tbl,
1131  raw_header[raw_index],
1132  raw_image[raw_index],
1133  extraction_slit,
1134  qclog[0]),
1135  "Could not compute QC parameters");
1136  }
1137 
1138  uves_msg("Saving products...");
1139  /* It is important to save products in the correct
1140  * order, because users want to identify products depending on
1141  * their number rather than the PRO-CATG (which would perhaps
1142  * make more sense).
1143  */
1144 
1145  /* Save RED_SCIENCE / RED2D_SCIENCE =
1146  (reduced_science, merged_header) */
1147  cpl_free(product_filename);
1148  check( product_filename =
1149  (extract_is_2d) ?
1150  uves_scired_red_2d_science_filename(chip) :
1151  ((m_method == MERGE_NOAPPEND) ?
1152  uves_scired_red_noappend_science_filename(chip): uves_scired_red_science_filename(chip)),
1153  "Error getting filename");
1154 
1155  cpl_free(product_tag);
1156  catg_is_noappend=uves_get_pro_catg_special(extract_is_2d,m_method);
1157  product_tag = uves_sprintf(
1158  "RED%s%s_%s_%s",
1159  catg_is_noappend,
1160  (extract_is_2d) ? "_2D" : "",
1161  sci_type, uves_chip_tostring_upper(chip));
1162 
1163  uves_propertylist_append(merged_header,wave_acc_header);
1164 
1165  check( uves_frameset_insert(frames,
1166  reduced_science,
1167  CPL_FRAME_GROUP_PRODUCT,
1168  CPL_FRAME_TYPE_IMAGE,
1169  CPL_FRAME_LEVEL_FINAL,
1170  product_filename,
1171  product_tag,
1172  raw_header[raw_index],
1173  merged_header,
1174  NULL,
1175  parameters,
1176  recipe_id,
1177  PACKAGE "/" PACKAGE_VERSION,
1178  qclog,
1179  starttime,
1180  false, /* Do not create QC log */
1181  UVES_ALL_STATS),
1182  "Could not add reduced science spectrum '%s' (%s) to frameset",
1183  product_filename, product_tag);
1184 
1185  uves_msg("Reduced science spectrum '%s' (%s) added to frameset",
1186  product_filename, product_tag);
1187 
1188  if (extract_is_2d)
1189  {
1190  /* Save EXT_2D_SCIENCE_xxxx = (x2d, x2d_header) */
1191  cpl_free(product_filename);
1192  check( product_filename = uves_scired_ext2d_filename(chip),
1193  "Error getting filename");
1194 
1195  cpl_free(product_tag);
1196  product_tag =
1197  uves_sprintf("EXT_2D_%s_%s", sci_type,
1198  uves_chip_tostring_upper(chip));
1199 
1200 
1201 
1202  check( uves_frameset_insert(frames,
1203  x2d,
1204  CPL_FRAME_GROUP_PRODUCT,
1205  CPL_FRAME_TYPE_IMAGE,
1206  CPL_FRAME_LEVEL_FINAL,
1207  product_filename,
1208  product_tag,
1209  raw_header[raw_index],
1210  x2d_header,
1211  NULL,
1212  parameters,
1213  recipe_id,
1214  PACKAGE "/" PACKAGE_VERSION,
1215  qclog,
1216  starttime, false,
1217  UVES_ALL_STATS),
1218  "Could not add 2d extracted "
1219  "spectrum '%s' (%s) to frameset",
1220  product_filename, product_tag);
1221 
1222  uves_msg("2d extracted spectrum '%s' (%s) added to frameset",
1223  product_filename, product_tag);
1224 
1225  }
1226 
1227  /* Save MERGED_SCIENCE / MER2D_SCIENCE =
1228  (merged_science, merged_header) */
1229  cpl_free(product_filename);
1230  check( product_filename = (extract_is_2d) ?
1231  uves_scired_merged_2d_science_filename(chip) :
1232  uves_scired_merged_science_filename(chip),
1233  "Error getting filename");
1234  cpl_free(product_tag);
1235  product_tag = uves_sprintf(
1236  "%s_%s_%s",
1237  (extract_is_2d) ? "MER_2D" : "MERGED",
1238  sci_type, uves_chip_tostring_upper(chip));
1239 
1240  uves_propertylist_append(merged_header,wave_acc_header);
1241 
1242  check( uves_frameset_insert(frames,
1243  merged_science,
1244  CPL_FRAME_GROUP_PRODUCT,
1245  CPL_FRAME_TYPE_IMAGE,
1246  CPL_FRAME_LEVEL_FINAL,
1247  product_filename,
1248  product_tag,
1249  raw_header[raw_index],
1250  merged_header,
1251  NULL,
1252  parameters,
1253  recipe_id,
1254  PACKAGE "/" PACKAGE_VERSION,
1255  qclog,
1256  starttime, false,
1257  UVES_ALL_STATS),
1258  "Could not add merged science spectrum '%s' (%s) to frameset",
1259  product_filename, product_tag);
1260 
1261  uves_msg("Merged science spectrum '%s' (%s) added to frameset",
1262  product_filename, product_tag);
1263 
1264  if (!extract_is_2d)
1265  {
1266  /* Save WCALIB_SCIENCE = (resampled_science, rebinned_header)
1267  * If ff_method = extract, this product was not flat-fielded
1268  */
1269  cpl_free(product_filename);
1270  check( product_filename = (extract_is_2d) ?
1271  uves_scired_resampled_2d_filename(chip) :
1272  uves_scired_resampled_filename(chip),
1273  "Error getting filename");
1274 
1275  cpl_free(product_tag);
1276  product_tag =
1277  uves_sprintf("WCALIB_%s_%s", sci_type,
1278  uves_chip_tostring_upper(chip));
1279 
1280  uves_propertylist_append(rebinned_header,wave_acc_header);
1281 
1282  check( uves_frameset_insert(frames,
1283  resampled_science,
1284  CPL_FRAME_GROUP_PRODUCT,
1285  CPL_FRAME_TYPE_IMAGE,
1286  CPL_FRAME_LEVEL_FINAL,
1287  product_filename,
1288  product_tag,
1289  raw_header[raw_index],
1290  rebinned_header,
1291  NULL,
1292  parameters,
1293  recipe_id,
1294  PACKAGE "/" PACKAGE_VERSION,
1295  qclog,
1296  starttime, false,
1297  UVES_ALL_STATS),
1298  "Could not add wavelength calibrated science "
1299  "spectrum '%s' (%s) to frameset", product_filename,
1300  product_tag);
1301 
1302  uves_msg("Wavelength calibrated science spectrum '%s' "
1303  "(%s) added to frameset", product_filename,
1304  product_tag);
1305 
1306 
1307  cpl_free(product_filename);
1308 
1309  check( product_filename =
1310  uves_order_extract_qc_standard_filename(chip),
1311  "Error getting filename");
1312 
1313 
1314  check( uves_frameset_insert(frames,
1315  info_tbl,
1316  CPL_FRAME_GROUP_PRODUCT,
1317  CPL_FRAME_TYPE_TABLE,
1318  CPL_FRAME_LEVEL_INTERMEDIATE,
1319  product_filename,
1320  UVES_ORDER_EXTRACT_QC(chip),
1321  raw_header[raw_index],
1322  rotated_header[raw_index],
1323  NULL,
1324  parameters,
1325  recipe_id,
1326  PACKAGE "/" PACKAGE_VERSION,
1327  NULL,
1328  starttime, true,
1329  0),
1330  "Could not add extraction quality table %s (%s)"
1331  , product_filename,
1332  UVES_ORDER_EXTRACT_QC(chip));
1333 
1334  uves_msg("Extraction quality table '%s' "
1335  "(%s) added to frameset", product_filename,
1336  UVES_ORDER_EXTRACT_QC(chip));
1337 
1338 
1339  } /* if not 2d extracted */
1340 
1341 
1342  {
1343  const char *ff = "";
1344 
1345  /* Read uves_scired.reduce.ffmethd */
1346  cpl_free(context);
1347  context = uves_sprintf("%s.%s", recipe_id, UVES_REDUCE_ID);
1348  check( uves_get_parameter(parameters, NULL,
1349  context,
1350  "ffmethod",
1351  CPL_TYPE_STRING, &ff),
1352  "Could not read parameter");
1353 
1354  /* If flat-fielding was done */
1355  if (strcmp(ff, "no") != 0)
1356  {
1357  /* Save WCALIB_FF_SCIENCE / WCAL2D_SCIENCE =
1358  (rebinned_science, rebinned_header) */
1359  cpl_table *qc_tabs[] = {NULL, NULL, NULL};
1360 
1361  /* QC consists of usual science QC and
1362  optionally TFLAT QC
1363  */
1364 
1365  if ( strcmp(recipe_id, make_str(UVES_TFLAT_ID)) == 0 )
1366  {
1367  uves_qclog_delete(&qclog_tflat);
1368  qclog_tflat =
1369  uves_qclog_init(raw_header[raw_index], chip);
1370 
1371  check( tflat_qclog(resampled_science,
1372  raw_header[raw_index],
1373  qclog_tflat),
1374  "Could not compute QC parameters");
1375 
1376  qc_tabs[0] = qclog_tflat;
1377  qc_tabs[1] = qclog[0];
1378  }
1379  else
1380  {
1381  qc_tabs[0] = qclog[0];
1382  qc_tabs[1] = NULL;
1383  }
1384 
1385  cpl_free(product_filename);
1386  check( product_filename =
1387  (extract_is_2d) ?
1388  uves_scired_rebinned_2d_filename(chip) :
1389  uves_scired_rebinned_filename(chip),
1390  "Error getting filename");
1391 
1392  cpl_free(product_tag);
1393  product_tag = uves_sprintf(
1394  "%s_%s_%s",
1395  (extract_is_2d) ? "WCAL_2D" : "WCALIB_FF",
1396  sci_type, uves_chip_tostring_upper(chip));
1397 
1398  uves_propertylist_append(rebinned_header,wave_acc_header);
1399 
1400  check( uves_frameset_insert(frames,
1401  rebinned_science,
1402  CPL_FRAME_GROUP_PRODUCT,
1403  CPL_FRAME_TYPE_IMAGE,
1404  CPL_FRAME_LEVEL_FINAL,
1405  product_filename,
1406  product_tag,
1407  raw_header[raw_index],
1408  rebinned_header,
1409  NULL,
1410  parameters,
1411  recipe_id,
1412  PACKAGE "/"
1413  PACKAGE_VERSION,
1414  qc_tabs,
1415  starttime, true,
1416  UVES_ALL_STATS),
1417  "Could not add wavelength calibrated flat-fielded "
1418  "science spectrum '%s' (%s) to frameset",
1419  product_filename, product_tag);
1420 
1421  uves_msg("Wavelength calibrated flat-fielded science "
1422  "spectrum '%s' (%s) added to frameset",
1423  product_filename, product_tag);
1424 
1425  cpl_free(product_filename);
1426  check( product_filename =
1427  (extract_is_2d) ?
1428  uves_scired_rebinned_2d_error_filename(chip) :
1429  uves_scired_rebinned_error_filename(chip),
1430  "Error getting filename");
1431 
1432  cpl_free(product_tag);
1433  product_tag = uves_sprintf(
1434  "%s_%s_%s",
1435  (extract_is_2d) ? "ERRORBAR_WCAL_2D" : "ERRORBAR_WCALIB_FF",
1436  sci_type, uves_chip_tostring_upper(chip));
1437 
1438 
1439  /* not needed as done before
1440  //uves_propertylist_append(rebinned_header,wave_acc_header);
1441  */
1442  check( uves_frameset_insert(frames,
1443  rebinned_science_error,
1444  CPL_FRAME_GROUP_PRODUCT,
1445  CPL_FRAME_TYPE_IMAGE,
1446  CPL_FRAME_LEVEL_FINAL,
1447  product_filename,
1448  product_tag,
1449  raw_header[raw_index],
1450  rebinned_header,
1451  NULL,
1452  parameters,
1453  recipe_id,
1454  PACKAGE "/"
1455  PACKAGE_VERSION,
1456  qc_tabs,
1457  starttime, true,
1458  UVES_ALL_STATS),
1459  "Could not add wavelength calibrated flat-fielded "
1460  "science spectrum '%s' (%s) to frameset",
1461  product_filename, product_tag);
1462 
1463  uves_msg("Wavelength calibrated flat-fielded science "
1464  "spectrum error '%s' (%s) added to frameset",
1465  product_filename, product_tag);
1466 
1467 
1468 
1469  if (!extract_is_2d)
1470  {
1471  /* Save WCALIB_FLAT_OBJ_xxxx =
1472  (resampled_mf, rebinned_header) */
1473  cpl_free(product_filename);
1474  check( product_filename =
1475  uves_scired_resampledmf_filename(chip),
1476  "Error getting filename");
1477 
1478  cpl_free(product_tag);
1479  product_tag =
1480  uves_sprintf(
1481  "WCALIB_FLAT_OBJ_%s",
1482  uves_chip_tostring_upper(chip));
1483  /* Independent of sci_type */
1484 
1485 
1486  /* !!!Exception!!!
1487  *
1488  * For this reduced master flat frame we
1489  * want to propagate the keywords *not*
1490  * from the first raw input frame but
1491  * from the master flat field itself.
1492  *
1493  * For that to work we temporarily set
1494  *
1495  * all raw frames := NONE
1496  * master.flat frame := RAW
1497  *
1498  * This will make cpl_dfs_setup_product_header()
1499  * find the proper "raw" frame (i.e. the mf)
1500  * Also the required 'raw_header' must be
1501  * that of the master flat frame, not science.
1502  * After propagating keywords, we change back
1503  * to normal:
1504  *
1505  * all raw frames := RAW
1506  * master.flat frame := CALIB
1507  *
1508  * (Since there could be more than 1 raw frame,
1509  * simply changing the first raw frame would
1510  * not work)
1511  */
1512 
1513  cpl_free(raw_frames);
1514  check_nomsg( raw_frames =
1515  set_all_raw_none(frames) );
1516 
1517  cpl_frame_set_group(mflat_frame,
1518  CPL_FRAME_GROUP_RAW);
1519 
1520  uves_propertylist_append(rebinned_header,wave_acc_header);
1521 
1522  check( uves_frameset_insert(
1523  frames,
1524  resampled_mf,
1525  CPL_FRAME_GROUP_PRODUCT,
1526  CPL_FRAME_TYPE_IMAGE,
1527  CPL_FRAME_LEVEL_FINAL,
1528  product_filename,
1529  product_tag,
1530  master_flat_header, /* Note! */
1531  rebinned_header,
1532  NULL,
1533  parameters,
1534  recipe_id,
1535  PACKAGE "/"
1536  PACKAGE_VERSION,
1537  NULL, /* No QC: qclog */
1538  starttime, false,
1539  CPL_STATS_MIN | CPL_STATS_MAX),
1540  "Could not add wavelength calibrated "
1541  "flat-field '%s' (%s) to frameset",
1542  product_filename, product_tag);
1543 
1544  uves_msg("Wavelength calibrated flat-field "
1545  "spectrum '%s' (%s) added to frameset",
1546  product_filename, product_tag);
1547 
1548  /* Change frames groups back to normal */
1549  {
1550  int i;
1551  for (i = 0;
1552  raw_frames[i] != NULL;
1553  i++)
1554  {
1555  cpl_frame_set_group(
1556  raw_frames[i],
1557  CPL_FRAME_GROUP_RAW);
1558  }
1559  }
1560  cpl_frame_set_group(mflat_frame,
1561  CPL_FRAME_GROUP_CALIB);
1562  }
1563 
1564  if (extract_is_2d)
1565  {
1566  /* Save FF2D_SCIENCE_xxxx = (fx2d, x2d_header) */
1567  cpl_free(product_filename);
1568  check( product_filename =
1569  uves_scired_ff2d_filename(chip),
1570  "Error getting filename");
1571 
1572  cpl_free(product_tag);
1573  product_tag =
1574  uves_sprintf(
1575  "FF_2D_%s_%s", sci_type,
1576  uves_chip_tostring_upper(chip));
1577 
1578 
1579  check( uves_frameset_insert(
1580  frames,
1581  fx2d,
1582  CPL_FRAME_GROUP_PRODUCT,
1583  CPL_FRAME_TYPE_IMAGE,
1584  CPL_FRAME_LEVEL_FINAL,
1585  product_filename,
1586  product_tag,
1587  raw_header[raw_index],
1588  x2d_header,
1589  NULL,
1590  parameters,
1591  recipe_id,
1592  PACKAGE "/"
1593  PACKAGE_VERSION,
1594  qclog,
1595  starttime, false,
1596  UVES_ALL_STATS),
1597  "Could not add 2d extracted, flat-fielded "
1598  "spectrum '%s' (%s) to frameset",
1599  product_filename, product_tag);
1600 
1601  uves_msg("2d extracted, flat-fielded spectrum "
1602  "'%s' (%s) added to frameset",
1603  product_filename, product_tag);
1604 
1605  }
1606 
1607  }/* If flat-fielding != no */
1608 
1609  check( uves_pfits_set_bunit(merged_header, "ADU"),
1610  "Error writing error spectrum header");
1611 
1612  /* Save ERRORBAR_SCIENCE_xxxx =
1613  (reduced_science_error, merged_header) */
1614  cpl_free(product_filename);
1615 
1616  check( product_filename =
1617  (extract_is_2d) ?
1618  uves_scired_red_2d_error_filename(chip) :
1619  ((m_method == MERGE_NOAPPEND) ?
1620  uves_scired_red_noappend_error_filename(chip): uves_scired_red_error_filename(chip)),
1621  "Error getting filename");
1622 
1623 
1624  cpl_free(product_tag);
1625  catg_is_noappend=uves_get_pro_catg_special(extract_is_2d,m_method);
1626  product_tag = uves_sprintf("%s%s_%s_%s",
1627  (extract_is_2d) ? "ERR_2D" : "ERRORBAR",catg_is_noappend,
1628  sci_type, uves_chip_tostring_upper(chip));
1629 
1630 /*
1631  product_tag = uves_sprintf(
1632  "%s%s_%s_%s",
1633  (m_method == MERGE_NOAPPEND) ? "ERRORBAR_NONMERGED" : "ERRORBAR",
1634  (extract_is_2d) ? "_2D" : "",
1635  sci_type, uves_chip_tostring_upper(chip));
1636 
1637 */
1638  uves_propertylist_append(merged_header,wave_acc_header);
1639 
1640  check( uves_frameset_insert(
1641  frames,
1642  reduced_science_error,
1643  CPL_FRAME_GROUP_PRODUCT,
1644  CPL_FRAME_TYPE_IMAGE,
1645  CPL_FRAME_LEVEL_FINAL,
1646  product_filename,
1647  product_tag,
1648  raw_header[raw_index],
1649  merged_header,
1650  NULL,
1651  parameters,
1652  recipe_id,
1653  PACKAGE "/" PACKAGE_VERSION,
1654  qclog,
1655  starttime, false,
1656  CPL_STATS_MIN | CPL_STATS_MAX),
1657  "Could not add error bars '%s' (%s) to frameset",
1658  product_filename, product_tag);
1659 
1660  uves_msg("Science spectrum error '%s' (%s) "
1661  "added to frameset",
1662  product_filename, product_tag);
1663 
1664 
1665  if (!extract_is_2d)
1666  {
1667 
1668 
1669  /* Save VARIANCE_SCIENCE_xxxx =
1670  (flatfielded_variance, flatfielded_variance_header) */
1671  cpl_free(product_filename);
1672  check( product_filename =
1673  uves_scired_ff_variance_filename(chip),
1674  "Error getting filename");
1675 
1676  cpl_free(product_tag);
1677  product_tag =
1678  uves_sprintf("VARIANCE_%s_%s", sci_type,
1679  uves_chip_tostring_upper(chip));
1680 
1681 
1682 
1683 
1684  check( uves_frameset_insert(frames,
1685  flatfielded_variance,
1686  CPL_FRAME_GROUP_PRODUCT,
1687  CPL_FRAME_TYPE_IMAGE,
1688  CPL_FRAME_LEVEL_FINAL,
1689  product_filename,
1690  product_tag,
1691  raw_header[raw_index],
1692  flatfielded_variance_header,
1693  NULL,
1694  parameters,
1695  recipe_id,
1696  PACKAGE "/" PACKAGE_VERSION,
1697  qclog,
1698  starttime, false,
1699  CPL_STATS_MIN | CPL_STATS_MAX),
1700  "Could not add flat-fielded spectrum variance "
1701  "'%s' (%s) to frameset",
1702  product_filename, product_tag);
1703 
1704  uves_msg("Flat-fielded spectrum variance '%s' (%s) "
1705  "added to frameset",
1706  product_filename, product_tag);
1707 
1708  } /* if not 2d extraction */
1709  }
1710 
1711  if (!extract_is_2d)
1712  {
1713  /* Save BKG_SCI_xxxx = (background, rotated_header) */
1714  cpl_free(product_filename);
1715  check( product_filename =
1716  uves_scired_background_filename(chip),
1717  "Error getting filename");
1718 
1719  cpl_free(product_tag);
1720  product_tag =
1721  uves_sprintf("BKG_SCI_%s",
1722  uves_chip_tostring_upper(chip));
1723 
1724 
1725  check( uves_frameset_insert(frames,
1726  background,
1727  CPL_FRAME_GROUP_PRODUCT,
1728  CPL_FRAME_TYPE_IMAGE,
1729  CPL_FRAME_LEVEL_FINAL,
1730  product_filename,
1731  product_tag,
1732  raw_header[raw_index],
1733  rotated_header[raw_index],
1734  NULL,
1735  parameters,
1736  recipe_id,
1737  PACKAGE "/" PACKAGE_VERSION,
1738  NULL, /* QC */
1739  starttime, false,
1740  CPL_STATS_MIN | CPL_STATS_MAX),
1741  "Could not add background image '%s' (%s) "
1742  "to frameset", product_filename, product_tag);
1743 
1744  uves_msg("Background image '%s' (%s) added to frameset",
1745  product_filename, product_tag);
1746 
1747  /* If optimal extraction, also save
1748  cosmic_mask, order_trace */
1749  if (order_trace != NULL)
1750  {
1751  /* Save ORDER_TRACE_xxxx */
1752  uves_free_propertylist(&order_trace_header);
1753  order_trace_header = uves_propertylist_new();
1754 
1755 
1756  /* !WARNING!: Duplicate code follows, be careful if/when
1757  changing. These parameters should be calculated
1758  the same way as in uves_qclog_add_sci().
1759 
1760  The MIDAS pipeline wrote these parameters only
1761  in this product, and for backwards compatibility
1762  do the same here.
1763  */
1764 
1766  order_trace_header, "ESO QC OPTEX NORD",
1767  uves_round_double(
1768  cpl_table_get_column_max(ordertable, "Order")-
1769  cpl_table_get_column_min(ordertable, "Order")+1));
1770 
1772  order_trace_header, "ESO QC OPTEX XSIZE",
1773  cpl_image_get_size_x(raw_image[raw_index]));
1774 
1776  order_trace_header, "ESO QC OPTEX YSIZE",
1777  uves_round_double(extraction_slit));
1778 
1779 
1780  cpl_free(product_filename);
1781  check( product_filename =
1782  uves_scired_ordertrace_filename(chip),
1783  "Error getting filename");
1784 
1785  cpl_free(product_tag);
1786  product_tag =
1787  uves_sprintf("ORDER_TRACE_%s",
1788  uves_chip_tostring_upper(chip));
1789 
1790 
1791  check( uves_frameset_insert(frames,
1792  order_trace,
1793  CPL_FRAME_GROUP_PRODUCT,
1794  CPL_FRAME_TYPE_TABLE,
1795  CPL_FRAME_LEVEL_FINAL,
1796  product_filename,
1797  product_tag,
1798  raw_header[raw_index],
1799  order_trace_header,
1800  NULL,
1801  parameters,
1802  recipe_id,
1803  PACKAGE "/"
1804  PACKAGE_VERSION,
1805  qclog,
1806  starttime, false,
1807  0),
1808  "Could not add sky spectrum '%s' (%s) "
1809  "to frameset",
1810  product_filename, product_tag);
1811 
1812  uves_msg("Order trace table '%s' (%s) "
1813  "added to frameset",
1814  product_filename, product_tag);
1815  }
1816 
1817 
1818 
1819  if (cosmic_mask != NULL)
1820  {
1821  /* Save CRMASK_xxxx */
1822  uves_free_propertylist(&cosmic_mask_header);
1823  cosmic_mask_header = uves_propertylist_new();
1824 
1825  cpl_free(product_filename);
1826  check( product_filename =
1827  uves_scired_crmask_filename(chip),
1828  "Error getting filename");
1829 
1830  cpl_free(product_tag);
1831  product_tag =
1832  uves_sprintf("CRMASK_%s",
1833  uves_chip_tostring_upper(chip));
1834 
1835 
1836  check( uves_frameset_insert(frames,
1837  cosmic_mask,
1838  CPL_FRAME_GROUP_PRODUCT,
1839  CPL_FRAME_TYPE_TABLE,
1840  CPL_FRAME_LEVEL_FINAL,
1841  product_filename,
1842  product_tag,
1843  raw_header[raw_index],
1844  cosmic_mask_header,
1845  NULL,
1846  parameters,
1847  recipe_id,
1848  PACKAGE "/"
1849  PACKAGE_VERSION,
1850  NULL, /* qc */
1851  starttime, false,
1852  0),
1853  "Could not add cosmic ray table "
1854  "'%s' (%s) to frameset",
1855  product_filename, product_tag);
1856 
1857  uves_msg("Cosmic ray table '%s' (%s) "
1858  "added to frameset",
1859  product_filename, product_tag);
1860  }
1861 
1862 
1863 
1864 
1865 
1866 
1867 
1868 
1869  if (wave_map != NULL)
1870  {
1871  /* Save WAVE_MAP_xxxx */
1872  uves_free_propertylist(&wave_map_header);
1873  wave_map_header = uves_propertylist_new();
1874 
1875  cpl_free(product_filename);
1876  check( product_filename =
1877  uves_scired_wmap_filename(chip),
1878  "Error getting filename");
1879 
1880  cpl_free(product_tag);
1881  product_tag =
1882  uves_sprintf("WAVE_MAP_%s",
1883  uves_chip_tostring_upper(chip));
1884  uves_pfits_set_ctype1(wave_map_header,"PIXEL");
1885  uves_pfits_set_ctype2(wave_map_header,"PIXEL");
1886  check( uves_frameset_insert(frames,
1887  wave_map,
1888  CPL_FRAME_GROUP_PRODUCT,
1889  CPL_FRAME_TYPE_IMAGE,
1890  CPL_FRAME_LEVEL_FINAL,
1891  product_filename,
1892  product_tag,
1893  raw_header[raw_index],
1894  wave_map_header,
1895  NULL,
1896  parameters,
1897  recipe_id,
1898  PACKAGE "/"
1899  PACKAGE_VERSION,
1900  NULL, /* qc */
1901  starttime, false,
1902  0),
1903  "Could not add wave map "
1904  "'%s' (%s) to frameset",
1905  product_filename, product_tag);
1906 
1907  uves_msg("Wave map '%s' (%s) "
1908  "added to frameset",
1909  product_filename, product_tag);
1910  } else {
1911  uves_msg("no wave map!!!!!!!!!");
1912  }
1913  uves_free_image(&wave_map);
1914 
1915 
1916  if (merged_sky != NULL)
1917  /* In slicer mode / 2d mode, no sky
1918  spectrum is extracted */
1919  {
1920  /* Save MERGED_SKY_xxxx =
1921  (merged_sky, merged_header) */
1922  cpl_free(product_filename);
1923  check( product_filename =
1924  uves_scired_merged_sky_filename(chip),
1925  "Error getting filename");
1926 
1927  cpl_free(product_tag);
1928  product_tag =
1929  uves_sprintf("MERGED_SKY_%s",
1930  uves_chip_tostring_upper(chip));
1931 
1932  uves_propertylist_append(merged_header,wave_acc_header);
1933 
1934 
1935  check( uves_frameset_insert(
1936  frames,
1937  merged_sky,
1938  CPL_FRAME_GROUP_PRODUCT,
1939  CPL_FRAME_TYPE_IMAGE,
1940  CPL_FRAME_LEVEL_FINAL,
1941  product_filename,
1942  product_tag,
1943  raw_header[raw_index],
1944  merged_header,
1945  NULL,
1946  parameters,
1947  recipe_id,
1948  PACKAGE "/"
1949  PACKAGE_VERSION,
1950  NULL, /* QC */
1951  starttime, false,
1952  CPL_STATS_MIN | CPL_STATS_MAX),
1953  "Could not add sky spectrum "
1954  "'%s' (%s) to frameset",
1955  product_filename, product_tag);
1956 
1957  uves_msg("Sky spectrum '%s' (%s) added to frameset",
1958  product_filename, product_tag);
1959  }
1960  else
1961  {
1962  uves_msg_low("No sky spectrum to save");
1963  }
1964 
1965  }/* if extract is 2d */
1966 
1967  if (fluxcal_science != NULL)
1968  {
1969  /* Save FLUXCAL_SCIENCE =
1970  (fluxcal_science, fluxcal_header) */
1971  cpl_free(product_filename);
1972 
1973  check( product_filename =
1974  (extract_is_2d) ?
1975  uves_scired_fluxcal_science_2d_filename(chip) :
1976  ((m_method == MERGE_NOAPPEND) ?
1977  uves_scired_fluxcal_science_noappend_filename(chip): uves_scired_fluxcal_science_filename(chip)),
1978  "Error getting filename");
1979 
1980 
1981  cpl_free(product_tag);
1982 
1983 
1984 
1985  catg_is_noappend=uves_get_pro_catg_special(extract_is_2d,m_method);
1986  product_tag = uves_sprintf("FLUXCAL%s%s_%s_%s",
1987  (extract_is_2d) ? "_2D" : "",catg_is_noappend,
1988  sci_type, uves_chip_tostring_upper(chip));
1989 
1990 
1991  /* Always _SCIENCE_, independent of sci_type */
1992 
1993  uves_propertylist_append(fluxcal_header,wave_acc_header);
1994 
1995  check( uves_frameset_insert(frames,
1996  fluxcal_science,
1997  CPL_FRAME_GROUP_PRODUCT,
1998  CPL_FRAME_TYPE_IMAGE,
1999  CPL_FRAME_LEVEL_FINAL,
2000  product_filename,
2001  product_tag,
2002  raw_header[raw_index],
2003  fluxcal_header,
2004  NULL,
2005  parameters,
2006  recipe_id,
2007  PACKAGE "/"
2008  PACKAGE_VERSION,
2009  qclog,
2010  starttime, false,
2011  CPL_STATS_MIN | CPL_STATS_MAX),
2012  "Could not add flux-calibrated science "
2013  "spectrum '%s' (%s) to frameset",
2014  product_filename, product_tag);
2015 
2016  uves_msg("Flux-calibrated science spectrum "
2017  "'%s' (%s) added to frameset",
2018  product_filename, product_tag);
2019 
2020  /* Save FLUXCAL_ERRORBAR = (fluxcal_error, fluxcal_header) */
2021  check( uves_pfits_set_bunit(fluxcal_header,
2022  "10^-16 erg/cm^2/Angstrom/s"),
2023  "Error writing error spectrum header");
2024 
2025  cpl_free(product_filename);
2026 
2027  check( product_filename =
2028  (extract_is_2d) ?
2029  uves_scired_fluxcal_error_2d_filename(chip) :
2030  ((m_method == MERGE_NOAPPEND) ?
2031  uves_scired_fluxcal_error_noappend_filename(chip): uves_scired_fluxcal_error_filename(chip)),
2032  "Error getting filename");
2033 
2034 
2035  cpl_free(product_tag);
2036 
2037 
2038  catg_is_noappend=uves_get_pro_catg_special(extract_is_2d,m_method);
2039  product_tag = uves_sprintf("FLUXCAL_ERRORBAR%s%s_%s_%s",
2040  (extract_is_2d) ? "_2D" : "",catg_is_noappend,
2041  sci_type, uves_chip_tostring_upper(chip));
2042 
2043  uves_propertylist_append(fluxcal_header,wave_acc_header);
2044 
2045  check( uves_frameset_insert(frames,
2046  fluxcal_error,
2047  CPL_FRAME_GROUP_PRODUCT,
2048  CPL_FRAME_TYPE_IMAGE,
2049  CPL_FRAME_LEVEL_FINAL,
2050  product_filename,
2051  product_tag,
2052  raw_header[raw_index],
2053  fluxcal_header,
2054  NULL,
2055  parameters,
2056  recipe_id,
2057  PACKAGE "/"
2058  PACKAGE_VERSION,
2059  qclog,
2060  starttime, false,
2061  CPL_STATS_MIN | CPL_STATS_MAX),
2062  "Could not add flux-calibrated science "
2063  "spectrum error '%s' (%s) to frameset",
2064  product_filename, product_tag);
2065 
2066  uves_msg("Flux-calibrated science spectrum error "
2067  "'%s' (%s) added to frameset",
2068  product_filename, product_tag);
2069 
2070  } /* If flux calibration done */
2071 
2072  }/* if trace is enabled */
2073  else
2074  {
2075  uves_msg("Skipping trace number %d", trace_number);
2076  }
2077 
2078 
2079  }/* for each trace */
2080 
2081 
2082  if(strcmp(PROCESS_CHIP,"REDL") == 0) {
2083  chip = uves_chip_get_next(chip);
2084  }
2085 
2086 
2087  }/* For each chip */
2088 
2089  cleanup:
2090  /* Input */
2091  uves_free_table(&info_tbl);
2092  uves_free_image(&raw_image[0]);
2093  uves_free_image(&raw_image[1]);
2094  uves_free_propertylist(&raw_header[0]);
2095  uves_free_propertylist(&raw_header[1]);
2096  uves_free_propertylist(&rotated_header[0]);
2097  uves_free_propertylist(&rotated_header[1]);
2098  uves_free_propertylist(&wave_map_header);
2099  uves_free_propertylist(&wave_acc_header);
2100 
2101  /* Input, calib */
2102  uves_free_image(&master_bias);
2103  uves_free_propertylist(&master_bias_header);
2104 
2105  uves_free_image(&master_dark);
2106  uves_free_propertylist(&master_dark_header);
2107 
2108  uves_free_image(&master_flat);
2109  uves_free_propertylist(&master_flat_header);
2110 
2111  uves_free_table(&ordertable);
2112  uves_free_propertylist(&ordertable_header);
2113  uves_polynomial_delete(&order_locations);
2114  uves_free_table(&traces);
2115 
2116  uves_free_table_const( &(linetable[0]) );
2117  uves_free_table_const( &(linetable[1]) );
2118  uves_free_table_const( &(linetable[2]) );
2119  uves_free_propertylist_const( &(linetable_header[0]) );
2120  uves_free_propertylist_const( &(linetable_header[1]) );
2121  uves_free_propertylist_const( &(linetable_header[2]) );
2122  uves_polynomial_delete_const( &(dispersion_relation[0]) );
2123  uves_polynomial_delete_const( &(dispersion_relation[1]) );
2124  uves_polynomial_delete_const( &(dispersion_relation[2]) );
2125 
2126  uves_free_image(&response_curve);
2127  uves_free_propertylist(&response_curve_header);
2128  uves_free_table(&master_response);
2129 
2130  uves_free_table(&atm_extinction);
2131 
2132  /* Output */
2133  uves_qclog_delete(&qclog[0]);
2134  uves_qclog_delete(&qclog_tflat);
2135  uves_free_image(&background);
2136  uves_free_image(&flatfielded_variance);
2137  uves_free_propertylist(&flatfielded_variance_header);
2138  uves_free_image(&rebinned_science);
2139  uves_free_image(&rebinned_science_error);
2140  uves_free_propertylist(&rebinned_header);
2141  uves_free_image(&resampled_science);
2142  uves_free_image(&resampled_mf);
2143  uves_free_image(&merged_sky);
2144 
2145  uves_free_image(&merged_science);
2146  uves_free_propertylist(&merged_header);
2147  uves_free_image(&reduced_science);
2148  uves_free_image(&reduced_science_error);
2149  uves_free_image(&fluxcal_science);
2150  uves_free_image(&fluxcal_error);
2151  uves_free_propertylist(&fluxcal_header);
2152  uves_free_table(&cosmic_mask);
2153  uves_free_propertylist(&cosmic_mask_header);
2154 
2155  uves_free_table(&order_trace);
2156  uves_free_propertylist(&order_trace_header);
2157 
2158  uves_free_image(&x2d);
2159  uves_free_image(&fx2d);
2160  uves_free_propertylist(&x2d_header);
2161 
2162  cpl_free(raw_frames);
2163  cpl_free(product_filename);
2164  cpl_free(context);
2165  cpl_free(product_tag);
2166 
2167  return;
2168 }
2169 
2170 /*----------------------------------------------------------------------------*/
2179 /*----------------------------------------------------------------------------*/
2180 static void
2181 scired_qclog(const cpl_table* info_tbl,
2182  const uves_propertylist *raw_header,
2183  const cpl_image *raw_image,
2184  double slit,
2185  cpl_table* qclog)
2186 {
2187  /* This test does not exist as an official QC-TEST in the MIDAS pipeline. But
2188  the QC parameters are written to the product header */
2189 
2191  "QC TEST1 ID",
2192  "Science-Reduction-Test-Results",
2193  "Name of QC test",
2194  "%s"));
2195 
2197  raw_header,
2198  raw_image,
2199  slit,
2200  info_tbl) );
2201 
2202  cleanup:
2203  return;
2204 
2205 }
2206 
2207 /*----------------------------------------------------------------------------*/
2214 /*----------------------------------------------------------------------------*/
2215 static void
2216 tflat_qclog(const cpl_image* ima,
2217  const uves_propertylist *raw_header,
2218  cpl_table* qclog)
2219 {
2220  char key_name[80];
2221  cpl_image *window = NULL;
2222 
2223  double exptime;
2224  int nx;
2225  int ny;
2226  int i;
2227 
2229  "QC TEST1 ID",
2230  "TFLAT-QC",
2231  "Name of QC test",
2232  "%s"));
2233 
2234 
2236  uves_remove_string_prefix(UVES_INSMODE, "ESO "),
2237  uves_pfits_get_insmode(raw_header),
2238  "Instrument mode used.",
2239  "%s"));
2240 
2242  uves_remove_string_prefix(UVES_INSPATH, "ESO "),
2243  uves_pfits_get_inspath(raw_header),
2244  "Optical path used.",
2245  "%s"));
2246 
2248  uves_remove_string_prefix(UVES_SLIT1NAME, "ESO "),
2249  uves_pfits_get_slit1_name(raw_header),
2250  "Slit common name.",
2251  "%s"));
2252 
2253  check( exptime = uves_pfits_get_exptime(raw_header),
2254  "Error reading exposure time");
2255 
2256  nx = cpl_image_get_size_x(ima);
2257  ny = cpl_image_get_size_y(ima);
2258 
2259  for (i = 1; i <= ny; i++)
2260  /* Always count order numbers from 1, like MIDAS */
2261  {
2262  int size = 100;
2263  int xlo = uves_max_int(1 , (nx+1)/2 - size);
2264  int xhi = uves_min_int(nx, (nx+1)/2 + size);
2265 
2266  double min, max, avg, rms, med;
2267 
2268  uves_free_image(&window);
2269  window = cpl_image_extract(ima, xlo, i, xhi, i);
2270  assure_mem( window );
2271 
2272  if (cpl_image_count_rejected(window) >= cpl_image_get_size_x(window) - 2)
2273  {
2274  min = max = avg = rms = med = 0;
2275  }
2276  else
2277  {
2278  min = cpl_image_get_min (window) / exptime;
2279  max = cpl_image_get_max (window) / exptime;
2280  avg = cpl_image_get_mean (window) / exptime;
2281  rms = cpl_image_get_stdev (window) / exptime;
2282  med = cpl_image_get_median(window) / exptime;
2283  }
2284 
2285  sprintf(key_name, "QC ORD%d DATAMIN", i);
2287  key_name,
2288  min,
2289  "extracted order datamin",
2290  "%f"));
2291 
2292  sprintf(key_name, "QC ORD%d DATAMAX", i);
2294  key_name,
2295  max,
2296  "extracted order datamax",
2297  "%f"));
2298 
2299  sprintf(key_name, "QC ORD%d DATAAVG", i);
2301  key_name,
2302  avg,
2303  "extracted order datamean",
2304  "%f"));
2305 
2306  sprintf(key_name, "QC ORD%d DATARMS", i);
2308  key_name,
2309  rms,
2310  "extracted order datarms",
2311  "%f"));
2312 
2313  sprintf(key_name, "QC ORD%d DATAMED", i);
2315  key_name,
2316  med,
2317  "extracted order datamed",
2318  "%f"));
2319  }
2320 
2321  cleanup:
2322  uves_free_image(&window);
2323  return;
2324 
2325 }
2326