UVES Pipeline Reference Manual  5.5.5b3
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 
147 
148 
149 
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  double 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  double 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  double 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  double 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  char extname[80];
772  uves_propertylist* table_header=NULL;
773 
774  /* Read recipe parameters */
775  {
776  const char *ex_method = "";
777 
778  /* General */
779  check( uves_get_parameter(parameters, NULL, "uves", "debug", CPL_TYPE_BOOL, &debug_mode),
780  "Could not read parameter");
781 
782 
783 
784  check( uves_get_parameter(parameters, NULL, "uves", "debug", CPL_TYPE_BOOL, &debug_mode),
785  "Could not read parameter");
786 
787 
788 
789  check( uves_get_parameter(parameters, NULL, "uves", "process_chip", CPL_TYPE_STRING, &PROCESS_CHIP),
790  "Could not read parameter");
791  uves_string_toupper((char*)PROCESS_CHIP);
792 
793 
794  check( uves_get_parameter(parameters,NULL,recipe_id, "clean_traps", CPL_TYPE_BOOL, &CLEAN_TRAPS),
795  "Could not read parameter");
796 
797 
798 
799  /* Reduction method */
800  context = uves_sprintf("%s.%s.%s", recipe_id, UVES_REDUCE_ID, UVES_EXTRACT_ID);
801 
802  check( uves_get_parameter(parameters, NULL,
803  context, "method",
804  CPL_TYPE_STRING, &ex_method),
805  "Could not read parameter");
806 
807  extract_is_2d = (strcmp(ex_method, "2d") == 0);
808 
809  /* Load raw image and header, and identify input frame as red or blue */
810  check( uves_load_science(frames, &raw_filename, raw_image, raw_header, rotated_header,
811  &blue, &sci_type),
812  "Error loading raw frame");
813 
814  if ((strcmp(sci_type, "SCI_SLICER") == 0 ||
815  strcmp(sci_type, "SCI_EXTND" ) == 0) &&
816  strcmp(ex_method, "optimal") == 0)
817  {
818  uves_msg_warning("Going to optimally extract an extended object (%s). "
819  "This may not work because the sky cannot be "
820  "reliably determined",
821  sci_type);
822  }
823  }
824 
825  /* Load atmospheric extinction table if present */
826  if (cpl_frameset_find(frames, UVES_EXTCOEFF_TABLE) != NULL)
827  {
828  check( uves_load_atmo_ext(frames, &atm_ext_filename, &atm_extinction),
829  "Error loading atm. extinction coefficients");
830 
831  uves_msg_low("Using atmospheric extinction table in '%s'", atm_ext_filename);
832  }
833  else
834  {
835  uves_msg_low("No atmospheric extinction table. Flux calibration not done");
836  }
837 
838  check( m_method = uves_get_merge_method(parameters, recipe_id, "reduce"),
839  "Could not get merging method");
840 
841  /* Adjust parameters according to binning
842  * (note that x- and y-directions are swapped later by uves_crop_and_rotate())
843  */
844  check (binx = uves_pfits_get_binx(raw_header[0]),
845  "Could not read x binning factor from input header");
846  check (biny = uves_pfits_get_biny(raw_header[0]),
847  "Could not read y binning factor from input header");
848 
849  check_nomsg(red_ccd_is_new=uves_ccd_is_new(raw_header[0]));
850  /* Loop over one or two chips, over traces and
851  over extraction windows */
852  for (chip = uves_chip_get_first(blue);
853  chip != UVES_CHIP_INVALID;
854  chip = uves_chip_get_next(chip))
855  {
856 
857 
858 
859  if(strcmp(PROCESS_CHIP,"REDU") == 0) {
860  chip = uves_chip_get_next(chip);
861  }
862  table_header=uves_propertylist_new();
863  cpl_frame *mflat_frame = NULL;
864  const char *ordertable_filename = "";
865  const char *linetable_filename = "";
866  const char *master_bias_filename = "";
867  const char *master_dark_filename = "";
868  const char *master_flat_filename = "";
869  const char *response_curve_filename = "";
870  const char *chip_name = "";
871  /* const char *drs_filename = ""; not used */
872  /* Do this to skip REDL chip: chip = uves_chip_get_next(chip); */
873  int raw_index = uves_chip_get_index(chip);
874  int tracerow; /* Index of table row */
875 
876  uves_msg("Processing %s chip in '%s'",
877  uves_chip_tostring_upper(chip), raw_filename);
878 
879  check_nomsg( chip_name = uves_pfits_get_chipid(raw_header[raw_index], chip));
880 
881  uves_msg_debug("Binning = %dx%d", binx, biny);
882 
883 
884  /* Load master bias, set pointer to NULL if not present */
885  uves_free_image(&master_bias);
886  uves_free_propertylist(&master_bias_header);
887  if (cpl_frameset_find(frames, UVES_MASTER_BIAS(chip)) != NULL)
888  {
889  uves_free_image(&master_bias);
890  uves_free_propertylist(&master_bias_header);
891 
892  check( uves_load_mbias(frames, chip_name, &master_bias_filename,
893  &master_bias, &master_bias_header,
894  chip),
895  "Error loading master bias");
896 
897  uves_msg_low("Using master bias in '%s'", master_bias_filename);
898  }
899  else
900  {
901  uves_msg_low("No master bias in SOF. Bias subtraction not done");
902  }
903 
904  /* Load master dark, set pointer to NULL if not present */
905  uves_free_image(&master_dark);
906  uves_free_propertylist(&master_dark_header);
907  if (cpl_frameset_find(frames, UVES_MASTER_DARK(chip)) != NULL ||
908  cpl_frameset_find(frames, UVES_MASTER_PDARK(chip)) != NULL)
909 
910  {
911  check( uves_load_mdark(frames, chip_name, &master_dark_filename,
912  &master_dark, &master_dark_header, chip),
913  "Error loading master dark");
914 
915  uves_msg_low("Using master dark in '%s'", master_dark_filename);
916  }
917  else
918  {
919  uves_msg_low("No master dark in SOF. Dark subtraction not done");
920  }
921 
922  /* Load master flat */
923  uves_free_image(&master_flat);
924  uves_free_propertylist(&master_flat_header);
925  check( uves_load_mflat(frames, chip_name, &master_flat_filename, &master_flat,
926  &master_flat_header, chip, &mflat_frame),
927  "Error loading master flat");
928 
929  uves_msg_low("Using master flat in '%s'", master_flat_filename);
930 
931 
932  /* Load the order table for this chip */
933  uves_free_table (&ordertable);
934  uves_free_propertylist(&ordertable_header);
935  uves_polynomial_delete(&order_locations);
936  uves_free_table (&traces);
937 
938  check( uves_load_ordertable(frames,
939  false, /* FLAMES? */
940  chip_name,
941  &ordertable_filename,
942  &ordertable,
943  &ordertable_header,
944  NULL,
945  &order_locations,
946  &traces,
947  NULL, NULL,
948  NULL, NULL, /* fibre_pos,fibre_mask */
949  chip, false),
950  "Could not load order table");
951  uves_msg_low("Using order table in '%s'", ordertable_filename);
952 
953  /* Load response curve, if present.
954  Only if atm. extinction table was present. */
955  if (atm_extinction != NULL)
956  {
957  if (cpl_frameset_find(frames, UVES_INSTR_RESPONSE(chip)) != NULL ||
958  cpl_frameset_find(frames, UVES_MASTER_RESPONSE(chip)) != NULL)
959  {
960  uves_free_image(&response_curve);
961  uves_free_table(&master_response);
962  uves_free_propertylist(&response_curve_header);
963  check( uves_load_response_curve(frames, chip_name,
964  &response_curve_filename,
965  &response_curve,
966  &master_response,
967  &response_curve_header,
968  chip),
969  "Error loading response curve");
970 
971  uves_msg_low("Using %sresponse curve in '%s'",
972  master_response != NULL ? "master " : "",
973  response_curve_filename);
974  }
975  else
976  {
977  uves_msg_low("No response curve in SOF. "
978  "Flux calibration not done");
979  }
980  }
981  else
982  {
983  uves_msg_debug("There is no atmospheric extinction table. "
984  "Do not look for response curve");
985  }
986 
987  /* Loop over all traces (1 trace for UVES) */
988  for(tracerow = 0; tracerow < cpl_table_get_nrow(traces); tracerow++)
989  {
990  double trace_offset;
991  int trace_number;
992  int trace_enabled;
993  int badpixels_cleaned;
994  trace_offset = cpl_table_get_double(traces, "Offset" , tracerow, NULL);
995  trace_number = cpl_table_get_int (traces, "TraceID" , tracerow, NULL);
996  trace_enabled = cpl_table_get_int (traces, "Tracemask" , tracerow, NULL);
997 
998  if (trace_enabled != 0)
999  {
1000  int window; /* window number */
1001 
1002  if (cpl_table_get_nrow(traces) > 1) {
1003  uves_msg("Processing trace %d", trace_number);
1004  }
1005 
1006  /* This is UVES specific. Load linetable for the
1007  two sky windows (number 1, 3) and for the object
1008  window (number 2) */
1009 
1010  for (window = 1; window <= 3; window ++) {
1011  uves_free_table_const ( &(linetable[window-1]) );
1012  uves_free_propertylist_const( &(linetable_header[window-1]) );
1013  uves_polynomial_delete_const( &(dispersion_relation[window-1]) );
1014  check( uves_load_linetable_const(frames,
1015  false, /* FLAMES? */
1016  chip_name,
1017  order_locations,
1018  cpl_table_get_column_min(
1019  ordertable, "Order"),
1020  cpl_table_get_column_max(
1021  ordertable, "Order"),
1022  &linetable_filename,
1023  &(linetable [window-1]),
1024  &(linetable_header [window-1]),
1025  &(dispersion_relation[window-1]),
1026  NULL,
1027  chip,
1028  trace_number,
1029  window),
1030  "Could not load line table, window #%d", window);
1031 
1032  uves_msg_low("Using line table(s) in '%s'", linetable_filename);
1033 
1034  }
1035  uves_propertylist* plist=uves_propertylist_load(linetable_filename,0);
1036  uves_free_propertylist(&wave_acc_header);
1037  wave_acc_header=uves_paste_wave_accuracy(plist);
1038  uves_free_propertylist(&plist);
1039  /* end, UVES specific */
1040 
1041  /* Do the science reduction + flux calibration */
1042  uves_free_image(&x2d);
1043  uves_free_image(&fx2d);
1044  uves_free_propertylist(&x2d_header);
1045  uves_free_image(&background);
1046  uves_free_image(&flatfielded_variance);
1047  uves_free_propertylist(&flatfielded_variance_header);
1048  uves_free_image(&resampled_science);
1049  uves_free_image(&resampled_mf);
1050  uves_free_image(&rebinned_science);
1051  uves_free_image(&rebinned_science_error);
1052  uves_free_propertylist(&rebinned_header);
1053  uves_free_image(&merged_sky);
1054  uves_free_image(&merged_science);
1055  uves_free_propertylist(&merged_header);
1056  uves_free_image(&reduced_science);
1057  uves_free_image(&reduced_science_error);
1058  uves_free_table(&cosmic_mask);
1059  uves_free_image(&fluxcal_science);
1060  uves_free_image(&fluxcal_error);
1061  uves_free_propertylist(&fluxcal_header);
1062  uves_free_table(&info_tbl);
1063  uves_free_table(&order_trace);
1064 
1065  if(CLEAN_TRAPS) {
1066 
1067  check( badpixels_cleaned =
1068  uves_correct_badpix_all(raw_image[raw_index],
1069  raw_header[raw_index],
1070  chip, binx, biny,
1071  false,red_ccd_is_new),
1072  "Error replacing bad pixels");
1073 
1074  uves_msg("%d bad pixels replaced",
1075  badpixels_cleaned);
1076  }
1077 
1079  raw_image[raw_index],
1080  raw_header[raw_index], /* Raw */
1081  rotated_header[raw_index],
1082  master_bias, /* Calibration */
1083  master_bias_header,
1084  master_dark,
1085  master_dark_header,
1086  master_flat,
1087  master_flat_header,
1088  ordertable,
1089  order_locations,
1090  linetable,
1091  linetable_header,
1092  dispersion_relation,
1093  response_curve,
1094  master_response,
1095  response_curve_header,
1096  atm_extinction,
1097  chip,
1098  debug_mode,
1099  parameters,
1100  recipe_id,
1101  &x2d,
1102  &x2d_header,
1103  &fx2d, /* Products */
1104  &background,
1105  &flatfielded_variance,
1106  &flatfielded_variance_header,
1107  &resampled_science,
1108  &resampled_mf,
1109  &rebinned_science,
1110  &rebinned_science_error,
1111  &rebinned_header,
1112  &merged_sky,
1113  &merged_science,
1114  &merged_header,
1115  &reduced_science,
1116  &reduced_science_error,
1117  &cosmic_mask,
1118  &wave_map,
1119  &fluxcal_science,
1120  &fluxcal_error,
1121  &fluxcal_header,
1122  &info_tbl,
1123  &extraction_slit,
1124  &order_trace),
1125  "Science reduction failed");
1126 
1127  if (!extract_is_2d)
1128  {
1129  uves_qclog_delete(&qclog[0]);
1130  qclog[0] = uves_qclog_init(raw_header[raw_index], chip);
1131 
1132  check( scired_qclog(info_tbl,
1133  raw_header[raw_index],
1134  raw_image[raw_index],
1135  extraction_slit,
1136  qclog[0]),
1137  "Could not compute QC parameters");
1138  }
1139 
1140  uves_msg("Saving products...");
1141  /* It is important to save products in the correct
1142  * order, because users want to identify products depending on
1143  * their number rather than the PRO-CATG (which would perhaps
1144  * make more sense).
1145  */
1146 
1147  /* Save RED_SCIENCE / RED2D_SCIENCE =
1148  (reduced_science, merged_header) */
1149  cpl_free(product_filename);
1150  check( product_filename =
1151  (extract_is_2d) ?
1152  uves_scired_red_2d_science_filename(chip) :
1153  ((m_method == MERGE_NOAPPEND) ?
1154  uves_scired_red_noappend_science_filename(chip): uves_scired_red_science_filename(chip)),
1155  "Error getting filename");
1156 
1157  cpl_free(product_tag);
1158  catg_is_noappend=uves_get_pro_catg_special(extract_is_2d,m_method);
1159  product_tag = uves_sprintf(
1160  "RED%s%s_%s_%s",
1161  catg_is_noappend,
1162  (extract_is_2d) ? "_2D" : "",
1163  sci_type, uves_chip_tostring_upper(chip));
1164 
1165  uves_propertylist_append(merged_header,wave_acc_header);
1166  uves_pfits_set_extname(merged_header,"reduced 1d spectrum");
1167  check( uves_frameset_insert(frames,
1168  reduced_science,
1169  CPL_FRAME_GROUP_PRODUCT,
1170  CPL_FRAME_TYPE_IMAGE,
1171  CPL_FRAME_LEVEL_FINAL,
1172  product_filename,
1173  product_tag,
1174  raw_header[raw_index],
1175  merged_header,
1176  NULL,
1177  parameters,
1178  recipe_id,
1179  PACKAGE "/" PACKAGE_VERSION,
1180  qclog,
1181  starttime,
1182  false, /* Do not create QC log */
1183  UVES_ALL_STATS),
1184  "Could not add reduced science spectrum '%s' (%s) to frameset",
1185  product_filename, product_tag);
1186 
1187  uves_msg("Reduced science spectrum '%s' (%s) added to frameset",
1188  product_filename, product_tag);
1189 
1190  if (extract_is_2d)
1191  {
1192  /* Save EXT_2D_SCIENCE_xxxx = (x2d, x2d_header) */
1193  cpl_free(product_filename);
1194  check( product_filename = uves_scired_ext2d_filename(chip),
1195  "Error getting filename");
1196 
1197  cpl_free(product_tag);
1198  product_tag =
1199  uves_sprintf("EXT_2D_%s_%s", sci_type,
1200  uves_chip_tostring_upper(chip));
1201 
1202 
1203  uves_pfits_set_extname(x2d_header,"Extracted 2d spectrum");
1204  check( uves_frameset_insert(frames,
1205  x2d,
1206  CPL_FRAME_GROUP_PRODUCT,
1207  CPL_FRAME_TYPE_IMAGE,
1208  CPL_FRAME_LEVEL_FINAL,
1209  product_filename,
1210  product_tag,
1211  raw_header[raw_index],
1212  x2d_header,
1213  NULL,
1214  parameters,
1215  recipe_id,
1216  PACKAGE "/" PACKAGE_VERSION,
1217  qclog,
1218  starttime, false,
1219  UVES_ALL_STATS),
1220  "Could not add 2d extracted "
1221  "spectrum '%s' (%s) to frameset",
1222  product_filename, product_tag);
1223 
1224  uves_msg("2d extracted spectrum '%s' (%s) added to frameset",
1225  product_filename, product_tag);
1226 
1227  }
1228 
1229  /* Save MERGED_SCIENCE / MER2D_SCIENCE =
1230  (merged_science, merged_header) */
1231  cpl_free(product_filename);
1232  check( product_filename = (extract_is_2d) ?
1233  uves_scired_merged_2d_science_filename(chip) :
1234  uves_scired_merged_science_filename(chip),
1235  "Error getting filename");
1236  cpl_free(product_tag);
1237  product_tag = uves_sprintf(
1238  "%s_%s_%s",
1239  (extract_is_2d) ? "MER_2D" : "MERGED",
1240  sci_type, uves_chip_tostring_upper(chip));
1241 
1242  uves_propertylist_append(merged_header,wave_acc_header);
1243  uves_pfits_set_extname(merged_header,"merged 1d spectrum");
1244  check( uves_frameset_insert(frames,
1245  merged_science,
1246  CPL_FRAME_GROUP_PRODUCT,
1247  CPL_FRAME_TYPE_IMAGE,
1248  CPL_FRAME_LEVEL_FINAL,
1249  product_filename,
1250  product_tag,
1251  raw_header[raw_index],
1252  merged_header,
1253  NULL,
1254  parameters,
1255  recipe_id,
1256  PACKAGE "/" PACKAGE_VERSION,
1257  qclog,
1258  starttime, false,
1259  UVES_ALL_STATS),
1260  "Could not add merged science spectrum '%s' (%s) to frameset",
1261  product_filename, product_tag);
1262 
1263  uves_msg("Merged science spectrum '%s' (%s) added to frameset",
1264  product_filename, product_tag);
1265 
1266  if (!extract_is_2d)
1267  {
1268  /* Save WCALIB_SCIENCE = (resampled_science, rebinned_header)
1269  * If ff_method = extract, this product was not flat-fielded
1270  */
1271  cpl_free(product_filename);
1272  check( product_filename = (extract_is_2d) ?
1273  uves_scired_resampled_2d_filename(chip) :
1274  uves_scired_resampled_filename(chip),
1275  "Error getting filename");
1276 
1277  cpl_free(product_tag);
1278  product_tag =
1279  uves_sprintf("WCALIB_%s_%s", sci_type,
1280  uves_chip_tostring_upper(chip));
1281 
1282  uves_propertylist_append(rebinned_header,wave_acc_header);
1283  uves_pfits_set_extname(rebinned_header,"Rebinned 2d spectrum");
1284  check( uves_frameset_insert(frames,
1285  resampled_science,
1286  CPL_FRAME_GROUP_PRODUCT,
1287  CPL_FRAME_TYPE_IMAGE,
1288  CPL_FRAME_LEVEL_FINAL,
1289  product_filename,
1290  product_tag,
1291  raw_header[raw_index],
1292  rebinned_header,
1293  NULL,
1294  parameters,
1295  recipe_id,
1296  PACKAGE "/" PACKAGE_VERSION,
1297  qclog,
1298  starttime, false,
1299  UVES_ALL_STATS),
1300  "Could not add wavelength calibrated science "
1301  "spectrum '%s' (%s) to frameset", product_filename,
1302  product_tag);
1303 
1304  uves_msg("Wavelength calibrated science spectrum '%s' "
1305  "(%s) added to frameset", product_filename,
1306  product_tag);
1307 
1308 
1309  cpl_free(product_filename);
1310 
1311  check( product_filename =
1312  uves_order_extract_qc_standard_filename(chip),
1313  "Error getting filename");
1314 
1315  uves_pfits_set_extname(rotated_header[raw_index],"QC on extraction");
1316 
1317  sprintf(extname,"QC_INFO");
1318  uves_pfits_set_extname(table_header,extname);
1319 
1320  check( uves_frameset_insert(frames,
1321  info_tbl,
1322  CPL_FRAME_GROUP_PRODUCT,
1323  CPL_FRAME_TYPE_TABLE,
1324  CPL_FRAME_LEVEL_INTERMEDIATE,
1325  product_filename,
1326  UVES_ORDER_EXTRACT_QC(chip),
1327  raw_header[raw_index],
1328  rotated_header[raw_index],
1329  table_header,
1330  parameters,
1331  recipe_id,
1332  PACKAGE "/" PACKAGE_VERSION,
1333  NULL,
1334  starttime, true,
1335  0),
1336  "Could not add extraction quality table %s (%s)"
1337  , product_filename,
1338  UVES_ORDER_EXTRACT_QC(chip));
1339 
1340  uves_msg("Extraction quality table '%s' "
1341  "(%s) added to frameset", product_filename,
1342  UVES_ORDER_EXTRACT_QC(chip));
1343 
1344 
1345  } /* if not 2d extracted */
1346 
1347 
1348  {
1349  const char *ff = "";
1350 
1351  /* Read uves_scired.reduce.ffmethd */
1352  cpl_free(context);
1353  context = uves_sprintf("%s.%s", recipe_id, UVES_REDUCE_ID);
1354  check( uves_get_parameter(parameters, NULL,
1355  context,
1356  "ffmethod",
1357  CPL_TYPE_STRING, &ff),
1358  "Could not read parameter");
1359 
1360  /* If flat-fielding was done */
1361  if (strcmp(ff, "no") != 0)
1362  {
1363  /* Save WCALIB_FF_SCIENCE / WCAL2D_SCIENCE =
1364  (rebinned_science, rebinned_header) */
1365  cpl_table *qc_tabs[] = {NULL, NULL, NULL};
1366 
1367  /* QC consists of usual science QC and
1368  optionally TFLAT QC
1369  */
1370 
1371  if ( strcmp(recipe_id, make_str(UVES_TFLAT_ID)) == 0 )
1372  {
1373  uves_qclog_delete(&qclog_tflat);
1374  qclog_tflat =
1375  uves_qclog_init(raw_header[raw_index], chip);
1376 
1377  check( tflat_qclog(resampled_science,
1378  raw_header[raw_index],
1379  qclog_tflat),
1380  "Could not compute QC parameters");
1381 
1382  qc_tabs[0] = qclog_tflat;
1383  qc_tabs[1] = qclog[0];
1384  }
1385  else
1386  {
1387  qc_tabs[0] = qclog[0];
1388  qc_tabs[1] = NULL;
1389  }
1390 
1391  cpl_free(product_filename);
1392  check( product_filename =
1393  (extract_is_2d) ?
1394  uves_scired_rebinned_2d_filename(chip) :
1395  uves_scired_rebinned_filename(chip),
1396  "Error getting filename");
1397 
1398  cpl_free(product_tag);
1399  product_tag = uves_sprintf(
1400  "%s_%s_%s",
1401  (extract_is_2d) ? "WCAL_2D" : "WCALIB_FF",
1402  sci_type, uves_chip_tostring_upper(chip));
1403 
1404  uves_propertylist_append(rebinned_header,wave_acc_header);
1405  uves_pfits_set_extname(rebinned_header,"Rebinned 2d spectrum");
1406  check( uves_frameset_insert(frames,
1407  rebinned_science,
1408  CPL_FRAME_GROUP_PRODUCT,
1409  CPL_FRAME_TYPE_IMAGE,
1410  CPL_FRAME_LEVEL_FINAL,
1411  product_filename,
1412  product_tag,
1413  raw_header[raw_index],
1414  rebinned_header,
1415  NULL,
1416  parameters,
1417  recipe_id,
1418  PACKAGE "/"
1419  PACKAGE_VERSION,
1420  qc_tabs,
1421  starttime, true,
1422  UVES_ALL_STATS),
1423  "Could not add wavelength calibrated flat-fielded "
1424  "science spectrum '%s' (%s) to frameset",
1425  product_filename, product_tag);
1426 
1427  uves_msg("Wavelength calibrated flat-fielded science "
1428  "spectrum '%s' (%s) added to frameset",
1429  product_filename, product_tag);
1430 
1431  cpl_free(product_filename);
1432  check( product_filename =
1433  (extract_is_2d) ?
1434  uves_scired_rebinned_2d_error_filename(chip) :
1435  uves_scired_rebinned_error_filename(chip),
1436  "Error getting filename");
1437 
1438  cpl_free(product_tag);
1439  product_tag = uves_sprintf(
1440  "%s_%s_%s",
1441  (extract_is_2d) ? "ERRORBAR_WCAL_2D" : "ERRORBAR_WCALIB_FF",
1442  sci_type, uves_chip_tostring_upper(chip));
1443 
1444 
1445  /* not needed as done before
1446  //uves_propertylist_append(rebinned_header,wave_acc_header);
1447  */
1448  uves_pfits_set_extname(rebinned_header,"Error reduced spectrum");
1449  check( uves_frameset_insert(frames,
1450  rebinned_science_error,
1451  CPL_FRAME_GROUP_PRODUCT,
1452  CPL_FRAME_TYPE_IMAGE,
1453  CPL_FRAME_LEVEL_FINAL,
1454  product_filename,
1455  product_tag,
1456  raw_header[raw_index],
1457  rebinned_header,
1458  NULL,
1459  parameters,
1460  recipe_id,
1461  PACKAGE "/"
1462  PACKAGE_VERSION,
1463  qc_tabs,
1464  starttime, true,
1465  UVES_ALL_STATS),
1466  "Could not add wavelength calibrated flat-fielded "
1467  "science spectrum '%s' (%s) to frameset",
1468  product_filename, product_tag);
1469 
1470  uves_msg("Wavelength calibrated flat-fielded science "
1471  "spectrum error '%s' (%s) added to frameset",
1472  product_filename, product_tag);
1473 
1474 
1475 
1476  if (!extract_is_2d)
1477  {
1478  /* Save WCALIB_FLAT_OBJ_xxxx =
1479  (resampled_mf, rebinned_header) */
1480  cpl_free(product_filename);
1481  check( product_filename =
1482  uves_scired_resampledmf_filename(chip),
1483  "Error getting filename");
1484 
1485  cpl_free(product_tag);
1486  product_tag =
1487  uves_sprintf(
1488  "WCALIB_FLAT_OBJ_%s",
1489  uves_chip_tostring_upper(chip));
1490  /* Independent of sci_type */
1491 
1492 
1493  /* !!!Exception!!!
1494  *
1495  * For this reduced master flat frame we
1496  * want to propagate the keywords *not*
1497  * from the first raw input frame but
1498  * from the master flat field itself.
1499  *
1500  * For that to work we temporarily set
1501  *
1502  * all raw frames := NONE
1503  * master.flat frame := RAW
1504  *
1505  * This will make cpl_dfs_setup_product_header()
1506  * find the proper "raw" frame (i.e. the mf)
1507  * Also the required 'raw_header' must be
1508  * that of the master flat frame, not science.
1509  * After propagating keywords, we change back
1510  * to normal:
1511  *
1512  * all raw frames := RAW
1513  * master.flat frame := CALIB
1514  *
1515  * (Since there could be more than 1 raw frame,
1516  * simply changing the first raw frame would
1517  * not work)
1518  */
1519 
1520  cpl_free(raw_frames);
1521  check_nomsg( raw_frames =
1522  set_all_raw_none(frames) );
1523 
1524  cpl_frame_set_group(mflat_frame,
1525  CPL_FRAME_GROUP_RAW);
1526 
1527  uves_propertylist_append(rebinned_header,wave_acc_header);
1528  uves_pfits_set_extname(rebinned_header,"Rebinned master flat");
1529  check( uves_frameset_insert(
1530  frames,
1531  resampled_mf,
1532  CPL_FRAME_GROUP_PRODUCT,
1533  CPL_FRAME_TYPE_IMAGE,
1534  CPL_FRAME_LEVEL_FINAL,
1535  product_filename,
1536  product_tag,
1537  master_flat_header, /* Note! */
1538  rebinned_header,
1539  NULL,
1540  parameters,
1541  recipe_id,
1542  PACKAGE "/"
1543  PACKAGE_VERSION,
1544  NULL, /* No QC: qclog */
1545  starttime, false,
1546  CPL_STATS_MIN | CPL_STATS_MAX),
1547  "Could not add wavelength calibrated "
1548  "flat-field '%s' (%s) to frameset",
1549  product_filename, product_tag);
1550 
1551  uves_msg("Wavelength calibrated flat-field "
1552  "spectrum '%s' (%s) added to frameset",
1553  product_filename, product_tag);
1554 
1555  /* Change frames groups back to normal */
1556  {
1557  int i;
1558  for (i = 0;
1559  raw_frames[i] != NULL;
1560  i++)
1561  {
1562  cpl_frame_set_group(
1563  raw_frames[i],
1564  CPL_FRAME_GROUP_RAW);
1565  }
1566  }
1567  cpl_frame_set_group(mflat_frame,
1568  CPL_FRAME_GROUP_CALIB);
1569  }
1570 
1571  if (extract_is_2d)
1572  {
1573  /* Save FF2D_SCIENCE_xxxx = (fx2d, x2d_header) */
1574  cpl_free(product_filename);
1575  check( product_filename =
1576  uves_scired_ff2d_filename(chip),
1577  "Error getting filename");
1578 
1579  cpl_free(product_tag);
1580  product_tag =
1581  uves_sprintf(
1582  "FF_2D_%s_%s", sci_type,
1583  uves_chip_tostring_upper(chip));
1584 
1585  uves_pfits_set_extname(x2d_header,"Extracted 2d spectrum");
1586  check( uves_frameset_insert(
1587  frames,
1588  fx2d,
1589  CPL_FRAME_GROUP_PRODUCT,
1590  CPL_FRAME_TYPE_IMAGE,
1591  CPL_FRAME_LEVEL_FINAL,
1592  product_filename,
1593  product_tag,
1594  raw_header[raw_index],
1595  x2d_header,
1596  NULL,
1597  parameters,
1598  recipe_id,
1599  PACKAGE "/"
1600  PACKAGE_VERSION,
1601  qclog,
1602  starttime, false,
1603  UVES_ALL_STATS),
1604  "Could not add 2d extracted, flat-fielded "
1605  "spectrum '%s' (%s) to frameset",
1606  product_filename, product_tag);
1607 
1608  uves_msg("2d extracted, flat-fielded spectrum "
1609  "'%s' (%s) added to frameset",
1610  product_filename, product_tag);
1611 
1612  }
1613 
1614  }/* If flat-fielding != no */
1615 
1616  check( uves_pfits_set_bunit(merged_header, "ADU"),
1617  "Error writing error spectrum header");
1618 
1619  /* Save ERRORBAR_SCIENCE_xxxx =
1620  (reduced_science_error, merged_header) */
1621  cpl_free(product_filename);
1622 
1623  check( product_filename =
1624  (extract_is_2d) ?
1625  uves_scired_red_2d_error_filename(chip) :
1626  ((m_method == MERGE_NOAPPEND) ?
1627  uves_scired_red_noappend_error_filename(chip): uves_scired_red_error_filename(chip)),
1628  "Error getting filename");
1629 
1630 
1631  cpl_free(product_tag);
1632  catg_is_noappend=uves_get_pro_catg_special(extract_is_2d,m_method);
1633  product_tag = uves_sprintf("%s%s_%s_%s",
1634  (extract_is_2d) ? "ERR_2D" : "ERRORBAR",catg_is_noappend,
1635  sci_type, uves_chip_tostring_upper(chip));
1636 
1637 /*
1638  product_tag = uves_sprintf(
1639  "%s%s_%s_%s",
1640  (m_method == MERGE_NOAPPEND) ? "ERRORBAR_NONMERGED" : "ERRORBAR",
1641  (extract_is_2d) ? "_2D" : "",
1642  sci_type, uves_chip_tostring_upper(chip));
1643 
1644 */
1645  uves_propertylist_append(merged_header,wave_acc_header);
1646  uves_pfits_set_extname(merged_header,"Error reduced spectrum");
1647  check( uves_frameset_insert(
1648  frames,
1649  reduced_science_error,
1650  CPL_FRAME_GROUP_PRODUCT,
1651  CPL_FRAME_TYPE_IMAGE,
1652  CPL_FRAME_LEVEL_FINAL,
1653  product_filename,
1654  product_tag,
1655  raw_header[raw_index],
1656  merged_header,
1657  NULL,
1658  parameters,
1659  recipe_id,
1660  PACKAGE "/" PACKAGE_VERSION,
1661  qclog,
1662  starttime, false,
1663  CPL_STATS_MIN | CPL_STATS_MAX),
1664  "Could not add error bars '%s' (%s) to frameset",
1665  product_filename, product_tag);
1666 
1667  uves_msg("Science spectrum error '%s' (%s) "
1668  "added to frameset",
1669  product_filename, product_tag);
1670 
1671 
1672  if (!extract_is_2d)
1673  {
1674 
1675 
1676  /* Save VARIANCE_SCIENCE_xxxx =
1677  (flatfielded_variance, flatfielded_variance_header) */
1678  cpl_free(product_filename);
1679  check( product_filename =
1680  uves_scired_ff_variance_filename(chip),
1681  "Error getting filename");
1682 
1683  cpl_free(product_tag);
1684  product_tag =
1685  uves_sprintf("VARIANCE_%s_%s", sci_type,
1686  uves_chip_tostring_upper(chip));
1687 
1688 
1689 
1690  uves_pfits_set_extname(flatfielded_variance_header,"Variance reduced spectrum");
1691  check( uves_frameset_insert(frames,
1692  flatfielded_variance,
1693  CPL_FRAME_GROUP_PRODUCT,
1694  CPL_FRAME_TYPE_IMAGE,
1695  CPL_FRAME_LEVEL_FINAL,
1696  product_filename,
1697  product_tag,
1698  raw_header[raw_index],
1699  flatfielded_variance_header,
1700  NULL,
1701  parameters,
1702  recipe_id,
1703  PACKAGE "/" PACKAGE_VERSION,
1704  qclog,
1705  starttime, false,
1706  CPL_STATS_MIN | CPL_STATS_MAX),
1707  "Could not add flat-fielded spectrum variance "
1708  "'%s' (%s) to frameset",
1709  product_filename, product_tag);
1710 
1711  uves_msg("Flat-fielded spectrum variance '%s' (%s) "
1712  "added to frameset",
1713  product_filename, product_tag);
1714 
1715  } /* if not 2d extraction */
1716  }
1717 
1718  if (!extract_is_2d)
1719  {
1720  /* Save BKG_SCI_xxxx = (background, rotated_header) */
1721  cpl_free(product_filename);
1722  check( product_filename =
1723  uves_scired_background_filename(chip),
1724  "Error getting filename");
1725 
1726  cpl_free(product_tag);
1727  product_tag =
1728  uves_sprintf("BKG_SCI_%s",
1729  uves_chip_tostring_upper(chip));
1730 
1731 
1732  check( uves_frameset_insert(frames,
1733  background,
1734  CPL_FRAME_GROUP_PRODUCT,
1735  CPL_FRAME_TYPE_IMAGE,
1736  CPL_FRAME_LEVEL_FINAL,
1737  product_filename,
1738  product_tag,
1739  raw_header[raw_index],
1740  rotated_header[raw_index],
1741  NULL,
1742  parameters,
1743  recipe_id,
1744  PACKAGE "/" PACKAGE_VERSION,
1745  NULL, /* QC */
1746  starttime, false,
1747  CPL_STATS_MIN | CPL_STATS_MAX),
1748  "Could not add background image '%s' (%s) "
1749  "to frameset", product_filename, product_tag);
1750 
1751  uves_msg("Background image '%s' (%s) added to frameset",
1752  product_filename, product_tag);
1753 
1754  /* If optimal extraction, also save
1755  cosmic_mask, order_trace */
1756  if (order_trace != NULL)
1757  {
1758  /* Save ORDER_TRACE_xxxx */
1759  uves_free_propertylist(&order_trace_header);
1760  order_trace_header = uves_propertylist_new();
1761 
1762 
1763  /* !WARNING!: Duplicate code follows, be careful if/when
1764  changing. These parameters should be calculated
1765  the same way as in uves_qclog_add_sci().
1766 
1767  The MIDAS pipeline wrote these parameters only
1768  in this product, and for backwards compatibility
1769  do the same here.
1770  */
1771 
1773  order_trace_header, "ESO QC OPTEX NORD",
1774  uves_round_double(
1775  cpl_table_get_column_max(ordertable, "Order")-
1776  cpl_table_get_column_min(ordertable, "Order")+1));
1777 
1779  order_trace_header, "ESO QC OPTEX XSIZE",
1780  cpl_image_get_size_x(raw_image[raw_index]));
1781 
1783  order_trace_header, "ESO QC OPTEX YSIZE",
1784  uves_round_double(extraction_slit));
1785 
1786 
1787  cpl_free(product_filename);
1788  check( product_filename =
1789  uves_scired_ordertrace_filename(chip),
1790  "Error getting filename");
1791 
1792  cpl_free(product_tag);
1793  product_tag =
1794  uves_sprintf("ORDER_TRACE_%s",
1795  uves_chip_tostring_upper(chip));
1796 
1797  uves_pfits_set_extname(order_trace_header,"Order trace info");
1798  sprintf(extname,"TRACE_INFO");
1799  uves_pfits_set_extname(table_header,extname);
1800  check( uves_frameset_insert(frames,
1801  order_trace,
1802  CPL_FRAME_GROUP_PRODUCT,
1803  CPL_FRAME_TYPE_TABLE,
1804  CPL_FRAME_LEVEL_FINAL,
1805  product_filename,
1806  product_tag,
1807  raw_header[raw_index],
1808  order_trace_header,
1809  table_header,
1810  parameters,
1811  recipe_id,
1812  PACKAGE "/"
1813  PACKAGE_VERSION,
1814  qclog,
1815  starttime, false,
1816  0),
1817  "Could not add sky spectrum '%s' (%s) "
1818  "to frameset",
1819  product_filename, product_tag);
1820 
1821  uves_msg("Order trace table '%s' (%s) "
1822  "added to frameset",
1823  product_filename, product_tag);
1824  }
1825 
1826 
1827 
1828  if (cosmic_mask != NULL)
1829  {
1830  /* Save CRMASK_xxxx */
1831  uves_free_propertylist(&cosmic_mask_header);
1832  cosmic_mask_header = uves_propertylist_new();
1833 
1834  cpl_free(product_filename);
1835  check( product_filename =
1836  uves_scired_crmask_filename(chip),
1837  "Error getting filename");
1838 
1839  cpl_free(product_tag);
1840  product_tag =
1841  uves_sprintf("CRMASK_%s",
1842  uves_chip_tostring_upper(chip));
1843 
1844  uves_pfits_set_extname(cosmic_mask_header,"CRH mask");
1845  sprintf(extname,"CRH_MASK");
1846  uves_pfits_set_extname(table_header,extname);
1847 
1848  check( uves_frameset_insert(frames,
1849  cosmic_mask,
1850  CPL_FRAME_GROUP_PRODUCT,
1851  CPL_FRAME_TYPE_TABLE,
1852  CPL_FRAME_LEVEL_FINAL,
1853  product_filename,
1854  product_tag,
1855  raw_header[raw_index],
1856  cosmic_mask_header,
1857  table_header,
1858  parameters,
1859  recipe_id,
1860  PACKAGE "/"
1861  PACKAGE_VERSION,
1862  NULL, /* qc */
1863  starttime, false,
1864  0),
1865  "Could not add cosmic ray table "
1866  "'%s' (%s) to frameset",
1867  product_filename, product_tag);
1868 
1869  uves_msg("Cosmic ray table '%s' (%s) "
1870  "added to frameset",
1871  product_filename, product_tag);
1872  }
1873 
1874 
1875 
1876 
1877 
1878 
1879 
1880 
1881  if (wave_map != NULL)
1882  {
1883  /* Save WAVE_MAP_xxxx */
1884  uves_free_propertylist(&wave_map_header);
1885  wave_map_header = uves_propertylist_new();
1886 
1887  cpl_free(product_filename);
1888  check( product_filename =
1889  uves_scired_wmap_filename(chip),
1890  "Error getting filename");
1891 
1892  cpl_free(product_tag);
1893  product_tag =
1894  uves_sprintf("WAVE_MAP_%s",
1895  uves_chip_tostring_upper(chip));
1896  uves_pfits_set_ctype1(wave_map_header,"PIXEL");
1897  uves_pfits_set_ctype2(wave_map_header,"PIXEL");
1898  check( uves_frameset_insert(frames,
1899  wave_map,
1900  CPL_FRAME_GROUP_PRODUCT,
1901  CPL_FRAME_TYPE_IMAGE,
1902  CPL_FRAME_LEVEL_FINAL,
1903  product_filename,
1904  product_tag,
1905  raw_header[raw_index],
1906  wave_map_header,
1907  NULL,
1908  parameters,
1909  recipe_id,
1910  PACKAGE "/"
1911  PACKAGE_VERSION,
1912  NULL, /* qc */
1913  starttime, false,
1914  0),
1915  "Could not add wave map "
1916  "'%s' (%s) to frameset",
1917  product_filename, product_tag);
1918 
1919  uves_msg("Wave map '%s' (%s) "
1920  "added to frameset",
1921  product_filename, product_tag);
1922  } else {
1923  uves_msg("no wave map!!!!!!!!!");
1924  }
1925  uves_free_image(&wave_map);
1926 
1927 
1928  if (merged_sky != NULL)
1929  /* In slicer mode / 2d mode, no sky
1930  spectrum is extracted */
1931  {
1932  /* Save MERGED_SKY_xxxx =
1933  (merged_sky, merged_header) */
1934  cpl_free(product_filename);
1935  check( product_filename =
1936  uves_scired_merged_sky_filename(chip),
1937  "Error getting filename");
1938 
1939  cpl_free(product_tag);
1940  product_tag =
1941  uves_sprintf("MERGED_SKY_%s",
1942  uves_chip_tostring_upper(chip));
1943 
1944  uves_propertylist_append(merged_header,wave_acc_header);
1945 
1946 
1947  check( uves_frameset_insert(
1948  frames,
1949  merged_sky,
1950  CPL_FRAME_GROUP_PRODUCT,
1951  CPL_FRAME_TYPE_IMAGE,
1952  CPL_FRAME_LEVEL_FINAL,
1953  product_filename,
1954  product_tag,
1955  raw_header[raw_index],
1956  merged_header,
1957  NULL,
1958  parameters,
1959  recipe_id,
1960  PACKAGE "/"
1961  PACKAGE_VERSION,
1962  NULL, /* QC */
1963  starttime, false,
1964  CPL_STATS_MIN | CPL_STATS_MAX),
1965  "Could not add sky spectrum "
1966  "'%s' (%s) to frameset",
1967  product_filename, product_tag);
1968 
1969  uves_msg("Sky spectrum '%s' (%s) added to frameset",
1970  product_filename, product_tag);
1971  }
1972  else
1973  {
1974  uves_msg_low("No sky spectrum to save");
1975  }
1976 
1977  }/* if extract is 2d */
1978 
1979  if (fluxcal_science != NULL)
1980  {
1981  /* Save FLUXCAL_SCIENCE =
1982  (fluxcal_science, fluxcal_header) */
1983  cpl_free(product_filename);
1984 
1985  check( product_filename =
1986  (extract_is_2d) ?
1987  uves_scired_fluxcal_science_2d_filename(chip) :
1988  ((m_method == MERGE_NOAPPEND) ?
1989  uves_scired_fluxcal_science_noappend_filename(chip): uves_scired_fluxcal_science_filename(chip)),
1990  "Error getting filename");
1991 
1992 
1993  cpl_free(product_tag);
1994 
1995 
1996 
1997  catg_is_noappend=uves_get_pro_catg_special(extract_is_2d,m_method);
1998  product_tag = uves_sprintf("FLUXCAL%s%s_%s_%s",
1999  (extract_is_2d) ? "_2D" : "",catg_is_noappend,
2000  sci_type, uves_chip_tostring_upper(chip));
2001 
2002 
2003  /* Always _SCIENCE_, independent of sci_type */
2004 
2005  uves_propertylist_append(fluxcal_header,wave_acc_header);
2006 
2007  check( uves_frameset_insert(frames,
2008  fluxcal_science,
2009  CPL_FRAME_GROUP_PRODUCT,
2010  CPL_FRAME_TYPE_IMAGE,
2011  CPL_FRAME_LEVEL_FINAL,
2012  product_filename,
2013  product_tag,
2014  raw_header[raw_index],
2015  fluxcal_header,
2016  NULL,
2017  parameters,
2018  recipe_id,
2019  PACKAGE "/"
2020  PACKAGE_VERSION,
2021  qclog,
2022  starttime, false,
2023  CPL_STATS_MIN | CPL_STATS_MAX),
2024  "Could not add flux-calibrated science "
2025  "spectrum '%s' (%s) to frameset",
2026  product_filename, product_tag);
2027 
2028  uves_msg("Flux-calibrated science spectrum "
2029  "'%s' (%s) added to frameset",
2030  product_filename, product_tag);
2031 
2032  /* Save FLUXCAL_ERRORBAR = (fluxcal_error, fluxcal_header) */
2033  check( uves_pfits_set_bunit(fluxcal_header,
2034  "10^-16 erg/cm^2/Angstrom/s"),
2035  "Error writing error spectrum header");
2036 
2037  cpl_free(product_filename);
2038 
2039  check( product_filename =
2040  (extract_is_2d) ?
2041  uves_scired_fluxcal_error_2d_filename(chip) :
2042  ((m_method == MERGE_NOAPPEND) ?
2043  uves_scired_fluxcal_error_noappend_filename(chip): uves_scired_fluxcal_error_filename(chip)),
2044  "Error getting filename");
2045 
2046 
2047  cpl_free(product_tag);
2048 
2049 
2050  catg_is_noappend=uves_get_pro_catg_special(extract_is_2d,m_method);
2051  product_tag = uves_sprintf("FLUXCAL_ERRORBAR%s%s_%s_%s",
2052  (extract_is_2d) ? "_2D" : "",catg_is_noappend,
2053  sci_type, uves_chip_tostring_upper(chip));
2054 
2055  uves_propertylist_append(fluxcal_header,wave_acc_header);
2056 
2057  check( uves_frameset_insert(frames,
2058  fluxcal_error,
2059  CPL_FRAME_GROUP_PRODUCT,
2060  CPL_FRAME_TYPE_IMAGE,
2061  CPL_FRAME_LEVEL_FINAL,
2062  product_filename,
2063  product_tag,
2064  raw_header[raw_index],
2065  fluxcal_header,
2066  NULL,
2067  parameters,
2068  recipe_id,
2069  PACKAGE "/"
2070  PACKAGE_VERSION,
2071  qclog,
2072  starttime, false,
2073  CPL_STATS_MIN | CPL_STATS_MAX),
2074  "Could not add flux-calibrated science "
2075  "spectrum error '%s' (%s) to frameset",
2076  product_filename, product_tag);
2077 
2078  uves_msg("Flux-calibrated science spectrum error "
2079  "'%s' (%s) added to frameset",
2080  product_filename, product_tag);
2081 
2082  } /* If flux calibration done */
2083 
2084  }/* if trace is enabled */
2085  else
2086  {
2087  uves_msg("Skipping trace number %d", trace_number);
2088  }
2089 
2090 
2091  }/* for each trace */
2092 
2093 
2094  if(strcmp(PROCESS_CHIP,"REDL") == 0) {
2095  chip = uves_chip_get_next(chip);
2096  }
2097  uves_free_propertylist(&table_header);
2098 
2099  }/* For each chip */
2100 
2101  cleanup:
2102  /* Input */
2103  uves_free_table(&info_tbl);
2104  uves_free_image(&raw_image[0]);
2105  uves_free_image(&raw_image[1]);
2106  uves_free_propertylist(&raw_header[0]);
2107  uves_free_propertylist(&raw_header[1]);
2108  uves_free_propertylist(&rotated_header[0]);
2109  uves_free_propertylist(&rotated_header[1]);
2110  uves_free_propertylist(&wave_map_header);
2111  uves_free_propertylist(&wave_acc_header);
2112 
2113  /* Input, calib */
2114  uves_free_image(&master_bias);
2115  uves_free_propertylist(&master_bias_header);
2116 
2117  uves_free_image(&master_dark);
2118  uves_free_propertylist(&master_dark_header);
2119 
2120  uves_free_image(&master_flat);
2121  uves_free_propertylist(&master_flat_header);
2122 
2123  uves_free_table(&ordertable);
2124  uves_free_propertylist(&ordertable_header);
2125  uves_polynomial_delete(&order_locations);
2126  uves_free_table(&traces);
2127 
2128  uves_free_table_const( &(linetable[0]) );
2129  uves_free_table_const( &(linetable[1]) );
2130  uves_free_table_const( &(linetable[2]) );
2131  uves_free_propertylist_const( &(linetable_header[0]) );
2132  uves_free_propertylist_const( &(linetable_header[1]) );
2133  uves_free_propertylist_const( &(linetable_header[2]) );
2134  uves_polynomial_delete_const( &(dispersion_relation[0]) );
2135  uves_polynomial_delete_const( &(dispersion_relation[1]) );
2136  uves_polynomial_delete_const( &(dispersion_relation[2]) );
2137 
2138  uves_free_image(&response_curve);
2139  uves_free_propertylist(&response_curve_header);
2140  uves_free_table(&master_response);
2141 
2142  uves_free_table(&atm_extinction);
2143 
2144  /* Output */
2145  uves_qclog_delete(&qclog[0]);
2146  uves_qclog_delete(&qclog_tflat);
2147  uves_free_image(&background);
2148  uves_free_image(&flatfielded_variance);
2149  uves_free_propertylist(&flatfielded_variance_header);
2150  uves_free_image(&rebinned_science);
2151  uves_free_image(&rebinned_science_error);
2152  uves_free_propertylist(&rebinned_header);
2153  uves_free_image(&resampled_science);
2154  uves_free_image(&resampled_mf);
2155  uves_free_image(&merged_sky);
2156 
2157  uves_free_image(&merged_science);
2158  uves_free_propertylist(&merged_header);
2159  uves_free_image(&reduced_science);
2160  uves_free_image(&reduced_science_error);
2161  uves_free_image(&fluxcal_science);
2162  uves_free_image(&fluxcal_error);
2163  uves_free_propertylist(&fluxcal_header);
2164  uves_free_table(&cosmic_mask);
2165  uves_free_propertylist(&cosmic_mask_header);
2166 
2167  uves_free_table(&order_trace);
2168  uves_free_propertylist(&order_trace_header);
2169 
2170  uves_free_image(&x2d);
2171  uves_free_image(&fx2d);
2172  uves_free_propertylist(&x2d_header);
2173 
2174  cpl_free(raw_frames);
2175  cpl_free(product_filename);
2176  cpl_free(context);
2177  cpl_free(product_tag);
2178 
2179  return;
2180 }
2181 
2182 /*----------------------------------------------------------------------------*/
2191 /*----------------------------------------------------------------------------*/
2192 static void
2193 scired_qclog(const cpl_table* info_tbl,
2194  const uves_propertylist *raw_header,
2195  const cpl_image *raw_image,
2196  double slit,
2197  cpl_table* qclog)
2198 {
2199  /* This test does not exist as an official QC-TEST in the MIDAS pipeline. But
2200  the QC parameters are written to the product header */
2201 
2203  "QC TEST1 ID",
2204  "Science-Reduction-Test-Results",
2205  "Name of QC test",
2206  "%s"));
2207 
2209  raw_header,
2210  raw_image,
2211  slit,
2212  info_tbl) );
2213 
2214  cleanup:
2215  return;
2216 
2217 }
2218 
2219 /*----------------------------------------------------------------------------*/
2226 /*----------------------------------------------------------------------------*/
2227 static void
2228 tflat_qclog(const cpl_image* ima,
2229  const uves_propertylist *raw_header,
2230  cpl_table* qclog)
2231 {
2232  char key_name[80];
2233  cpl_image *window = NULL;
2234 
2235  double exptime;
2236  int nx;
2237  int ny;
2238  int i;
2239 
2241  "QC TEST1 ID",
2242  "TFLAT-QC",
2243  "Name of QC test",
2244  "%s"));
2245 
2246 
2248  uves_remove_string_prefix(UVES_INSMODE, "ESO "),
2249  uves_pfits_get_insmode(raw_header),
2250  "Instrument mode used.",
2251  "%s"));
2252 
2254  uves_remove_string_prefix(UVES_INSPATH, "ESO "),
2255  uves_pfits_get_inspath(raw_header),
2256  "Optical path used.",
2257  "%s"));
2258 
2260  uves_remove_string_prefix(UVES_SLIT1NAME, "ESO "),
2261  uves_pfits_get_slit1_name(raw_header),
2262  "Slit common name.",
2263  "%s"));
2264 
2265  check( exptime = uves_pfits_get_exptime(raw_header),
2266  "Error reading exposure time");
2267 
2268  nx = cpl_image_get_size_x(ima);
2269  ny = cpl_image_get_size_y(ima);
2270 
2271  for (i = 1; i <= ny; i++)
2272  /* Always count order numbers from 1, like MIDAS */
2273  {
2274  int size = 100;
2275  int xlo = uves_max_int(1 , (nx+1)/2 - size);
2276  int xhi = uves_min_int(nx, (nx+1)/2 + size);
2277 
2278  double min, max, avg, rms, med;
2279 
2280  uves_free_image(&window);
2281  window = cpl_image_extract(ima, xlo, i, xhi, i);
2282  assure_mem( window );
2283 
2284  if (cpl_image_count_rejected(window) >= cpl_image_get_size_x(window) - 2)
2285  {
2286  min = max = avg = rms = med = 0;
2287  }
2288  else
2289  {
2290  min = cpl_image_get_min (window) / exptime;
2291  max = cpl_image_get_max (window) / exptime;
2292  avg = cpl_image_get_mean (window) / exptime;
2293  rms = cpl_image_get_stdev (window) / exptime;
2294  med = cpl_image_get_median(window) / exptime;
2295  }
2296 
2297  sprintf(key_name, "QC ORD%d DATAMIN", i);
2299  key_name,
2300  min,
2301  "extracted order datamin",
2302  "%f"));
2303 
2304  sprintf(key_name, "QC ORD%d DATAMAX", i);
2306  key_name,
2307  max,
2308  "extracted order datamax",
2309  "%f"));
2310 
2311  sprintf(key_name, "QC ORD%d DATAAVG", i);
2313  key_name,
2314  avg,
2315  "extracted order datamean",
2316  "%f"));
2317 
2318  sprintf(key_name, "QC ORD%d DATARMS", i);
2320  key_name,
2321  rms,
2322  "extracted order datarms",
2323  "%f"));
2324 
2325  sprintf(key_name, "QC ORD%d DATAMED", i);
2327  key_name,
2328  med,
2329  "extracted order datamed",
2330  "%f"));
2331  }
2332 
2333  cleanup:
2334  uves_free_image(&window);
2335  return;
2336 
2337 }
2338 
void uves_reduce_scired(cpl_frameset *frames, const cpl_parameterlist *parameters, const char *recipe_id, const char *starttime)
Get the command line options and execute the data reduction.
static void scired_qclog(const cpl_table *info_tbl, const uves_propertylist *raw_header, const cpl_image *raw_image, double slit, cpl_table *qclog)
compute science QC
void uves_polynomial_delete(polynomial **p)
Delete a polynomial.
#define uves_msg_warning(...)
Print an warning message.
Definition: uves_msg.h:87
cpl_error_code uves_pfits_set_ctype1(uves_propertylist *plist, const char *ctype1)
Write the ctype1 keyword.
Definition: uves_pfits.c:2756
double uves_propertylist_get_double(const uves_propertylist *self, const char *name)
Get the double value of the given property list entry.
int uves_qclog_add_string(cpl_table *table, const char *key_name, const char *value, const char *key_help, const char *format)
Add string key to QC-LOG table.
Definition: uves_qclog.c:683
#define check_nomsg(CMD)
Definition: uves_error.h:204
static void tflat_qclog(const cpl_image *ima, const uves_propertylist *raw_header, cpl_table *qclog)
compute tflat QC
int uves_scired_define_parameters_body(cpl_parameterlist *parameters, const char *recipe_id)
Setup the recipe options.
int uves_qclog_delete(cpl_table **table)
delete QC-LOG table
Definition: uves_qclog.c:716
cpl_error_code uves_propertylist_append_c_int(uves_propertylist *self, const char *name, int value, const char *comment)
Append an integer value to a property list.
int uves_qclog_add_double(cpl_table *table, const char *key_name, const double value, const char *key_help, const char *format)
Add double key to QC-LOG table.
Definition: uves_qclog.c:641
const char * uves_pfits_get_slit1_name(const uves_propertylist *plist)
Get image slicer name.
Definition: uves_pfits.c:3116
uves_propertylist * uves_initialize_image_header(const char *ctype1, const char *ctype2, const char *cunit1, const char *cunit2, const char *bunit, const double bscale, double crval1, double crval2, double crpix1, double crpix2, double cdelt1, double cdelt2)
Initialize image header.
Definition: uves_utils.c:2174
uves_propertylist * uves_propertylist_new(void)
Create an empty property list.
int uves_pfits_get_binx(const uves_propertylist *plist)
Find out the x binning factor.
Definition: uves_pfits.c:1176
double uves_spline_hermite_table(double xp, const cpl_table *t, const char *column_x, const char *column_y, int *istart)
Spline interpolation based on Hermite polynomials.
Definition: uves_utils.c:3684
#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.
cpl_error_code uves_pfits_set_ctype2(uves_propertylist *plist, const char *ctype2)
Write the ctype2 keyword.
Definition: uves_pfits.c:2773
int uves_pfits_get_biny(const uves_propertylist *plist)
Find out the y binning factor.
Definition: uves_pfits.c:1194
void uves_qclog_add_sci(cpl_table *qclog, const uves_propertylist *raw_header, const cpl_image *raw_image, double slit, const cpl_table *info_tbl)
Write QC parameters related to science reduction.
Definition: uves_qclog.c:803
static cpl_error_code uves_scired_process_chip(const cpl_image *raw_image, const uves_propertylist *raw_header, const uves_propertylist *rotated_header, const cpl_image *master_bias, const uves_propertylist *mbias_header, const cpl_image *master_dark, const uves_propertylist *mdark_header, const cpl_image *master_flat, const uves_propertylist *mflat_header, const cpl_table *ordertable, const polynomial *order_locations, const cpl_table *linetable[3], const uves_propertylist *linetable_header[3], const polynomial *dispersion_relation[3], const cpl_image *response_curve, const cpl_table *master_response, const uves_propertylist *response_curve_header, const cpl_table *atm_extinction, enum uves_chip chip, bool debug_mode, const cpl_parameterlist *parameters, const char *recipe_id, cpl_image **x2d, uves_propertylist **x2d_header, cpl_image **fx2d, cpl_image **background, cpl_image **flatfielded_variance, uves_propertylist **flatfielded_variance_header, cpl_image **resampled_science, cpl_image **resampled_mf, cpl_image **rebinned_science, cpl_image **rebinned_noise, uves_propertylist **rebinned_header, cpl_image **merged_sky, cpl_image **merged_science, uves_propertylist **merged_header, cpl_image **reduced_science, cpl_image **reduced_science_error, cpl_table **cosmic_mask, cpl_image **wave_map, cpl_image **fluxcal_science, cpl_image **fluxcal_error, uves_propertylist **fluxcal_header, cpl_table **info_tbl, double *extraction_slit, cpl_table **order_trace)
Reduce one chip of a UVES science frame.
bool uves_ccd_is_new(const uves_propertylist *plist)
Find out if CCD header is new.
Definition: uves_pfits.c:553
const char * uves_remove_string_prefix(const char *s, const char *prefix)
Remove named prefix from string.
Definition: uves_utils.c:3613
void uves_polynomial_delete_const(const polynomial **p)
Delete a const polynomial.
double uves_pfits_get_exptime(const uves_propertylist *plist)
Find out the exposure time in seconds.
Definition: uves_pfits.c:922
cpl_error_code uves_propertylist_append_c_string(uves_propertylist *self, const char *name, const char *value, const char *comment)
Append a string value to a property list.
#define assure_mem(PTR)
Definition: uves_error.h:181
const char * uves_pfits_get_insmode(const uves_propertylist *plist)
find out the chip name value
Definition: uves_pfits.c:1391
const char * uves_pfits_get_inspath(const uves_propertylist *plist)
find out the chip name value
Definition: uves_pfits.c:1409
cpl_image * uves_normalize_spectrum(const cpl_image *spectrum, const cpl_image *spectrum_error, const uves_propertylist *spectrum_header, const uves_propertylist *raw_header, int n_traces, enum uves_chip chip, const cpl_table *atm_extinction, bool correct_binning, cpl_image **scaled_error)
Normalize a spectrum.
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
merge_method uves_get_merge_method(const cpl_parameterlist *parameters, const char *context, const char *subcontext)
Read merging method from parameter list.
Definition: uves_merge.c:777
cpl_error_code uves_pfits_set_extname(uves_propertylist *plist, const char *extname)
Write the EXTNAME keyword.
Definition: uves_pfits.c:2736
int uves_propertylist_get_int(const uves_propertylist *self, const char *name)
Get the integer value of the given property list entry.
#define uves_msg_low(...)
Print a message on a lower message level.
Definition: uves_msg.h:105
enum uves_chip uves_chip_get_next(enum uves_chip chip)
Get next chip.
Definition: uves_chip.c:108
#define uves_msg_debug(...)
Print a debug message.
Definition: uves_msg.h:97
const char * uves_chip_tostring_upper(enum uves_chip chip)
Convert to string.
Definition: uves_chip.c:156
double uves_pfits_get_cdelt1(const uves_propertylist *plist)
Find out the cdelt1.
Definition: uves_pfits.c:2465
static cpl_frame ** set_all_raw_none(cpl_frameset *frames)
Change tag of RAW frames to NONE.
int uves_correct_badpix_all(cpl_image *master_bias, uves_propertylist *mbias_header, enum uves_chip chip, int binx, int biny, int mark_bad, bool red_ccd_new)
Correct all bad pixels on a chip.
double uves_pfits_get_crval1(const uves_propertylist *plist)
Find out the crval1.
Definition: uves_pfits.c:2393
cpl_error_code uves_pfits_set_bunit(uves_propertylist *plist, const char *bunit)
Write the bunit keyword.
Definition: uves_pfits.c:2660
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
cpl_error_code uves_propertylist_update_int(uves_propertylist *self, const char *name, int value)
Update a property list with a integer value.
const char * uves_pfits_get_chipid(const uves_propertylist *plist, enum uves_chip chip)
Find out the chip ID.
Definition: uves_pfits.c:619
int uves_propertylist_has(const uves_propertylist *self, const char *name)
Check whether a property is present in a property list.
cpl_error_code uves_reduce(const cpl_image *raw_image, const uves_propertylist *raw_header, const uves_propertylist *rotated_header, const cpl_image *master_bias, const uves_propertylist *mbias_header, const cpl_image *master_dark, const uves_propertylist *mdark_header, const cpl_image *master_flat, const uves_propertylist *mflat_header, const cpl_table *ordertable, const polynomial *order_locations, const cpl_table *linetable[3], const uves_propertylist *linetable_header[3], const polynomial *dispersion_relation[3], enum uves_chip chip, bool debug_mode, const cpl_parameterlist *parameters, const char *rec_id, const char *mode, cpl_image **x, uves_propertylist **x_header, cpl_image **fx, cpl_table **cosmic_mask, cpl_image **wave_map, cpl_image **background, cpl_image **flatfielded_variance, uves_propertylist **flatfielded_variance_header, cpl_image **resampled_spectrum, cpl_image **resampled_mf, cpl_image **merged_sky, cpl_image **rebinned_spectrum, cpl_image **rebinned_noise, uves_propertylist **rebinned_header, cpl_image **merged_spectrum, cpl_image **merged_noise, uves_propertylist **merged_header, cpl_image **reduced_rebinned_spectrum, cpl_image **reduced_rebinned_noise, cpl_image **reduced_spectrum, cpl_image **reduced_noise, cpl_table **info_tbl, double *extraction_slit, cpl_table **order_trace)
Reduce a science frame.
Definition: uves_reduce.c:575
cpl_error_code uves_propertylist_append(uves_propertylist *self, const uves_propertylist *other)
Append a property list..