UVES Pipeline Reference Manual  5.4.6
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,sz;
279  sz=cpl_frameset_get_size(frames);
280  result = cpl_calloc( sz + 1,sizeof(*result) );
281 
282  for ( i = 0;i < sz; i++ )
283  {
284  f=cpl_frameset_get_frame(frames, i);
285  if (cpl_frame_get_group(f) == CPL_FRAME_GROUP_RAW)
286  {
287  /* Change + remember this frame */
288  cpl_frame_set_group(f, CPL_FRAME_GROUP_NONE);
289  result[i] = f;
290  i++;
291  }
292  }
293 
294  /* 'result' is now a NULL-terminated array of the frames that were changed */
295 
296  return result;
297 }
298 
299 /*----------------------------------------------------------------------------*/
369 /*----------------------------------------------------------------------------*/
370 
371 static cpl_error_code
372 uves_scired_process_chip(const cpl_image *raw_image,
373  const uves_propertylist *raw_header,
374  const uves_propertylist *rotated_header,
375  const cpl_image *master_bias,
376  const uves_propertylist *mbias_header,
377  const cpl_image *master_dark,
378  const uves_propertylist *mdark_header,
379  const cpl_image *master_flat,
380  const uves_propertylist *mflat_header,
381  const cpl_table *ordertable,
382  const polynomial *order_locations,
383  const cpl_table *linetable[3],
384  const uves_propertylist *linetable_header[3],
385  const polynomial *dispersion_relation[3],
386  const cpl_image *response_curve,
387  const cpl_table *master_response,
388  const uves_propertylist *response_curve_header,
389  const cpl_table *atm_extinction,
390  enum uves_chip chip,
391  /* General */
392  bool debug_mode,
393  /* Backsub */
394  /* Flat fielding */
395  /* Extraction */
396  /* Rebinning */
397  const cpl_parameterlist *parameters,
398  const char *recipe_id,
399  /* Output */
400  cpl_image **x2d, uves_propertylist **x2d_header,
401  cpl_image **fx2d,
402  cpl_image **background,
403  cpl_image **flatfielded_variance,
404  uves_propertylist **flatfielded_variance_header,
405  cpl_image **resampled_science,
406  cpl_image **resampled_mf,
407  cpl_image **rebinned_science,
408  cpl_image **rebinned_noise,
409  uves_propertylist **rebinned_header,
410  cpl_image **merged_sky,
411  cpl_image **merged_science,
412  uves_propertylist **merged_header,
413  cpl_image **reduced_science,
414  cpl_image **reduced_science_error,
415  cpl_table **cosmic_mask,
416  cpl_image **wave_map,
417  cpl_image **fluxcal_science,
418  cpl_image **fluxcal_error,
419  uves_propertylist **fluxcal_header,
420  cpl_table **info_tbl,
421  double *extraction_slit,
422  cpl_table **order_trace)
423 {
424 
425  cpl_image *merged_noise = NULL;
426 
427  cpl_image *reduced_rebinned = NULL;
428  cpl_image *reduced_rebinned_noise = NULL;
429 
430  cpl_table *response_table = NULL;
431 
432  /* Do the science reduction. Produces wave.cal. spectra. */
433  uves_msg("Reducing science object");
434 
435  check( uves_reduce(raw_image,
436  raw_header,
437  rotated_header,
438  master_bias,
439  mbias_header,
440  master_dark,
441  mdark_header,
442  master_flat,
443  mflat_header,
444  ordertable,
445  order_locations,
446  linetable,
447  linetable_header,
448  dispersion_relation,
449  chip,
450  debug_mode,
451  parameters,
452  recipe_id,
453  "",
454  /* Output */
455  x2d,
456  x2d_header,
457  fx2d,
458  cosmic_mask,
459  wave_map,
460  background,
461  flatfielded_variance,
462  flatfielded_variance_header,
463  resampled_science,
464  resampled_mf,
465  merged_sky,
466  rebinned_science,
467  rebinned_noise,
468  rebinned_header,
469  merged_science,
470  &merged_noise,
471  merged_header,
472  &reduced_rebinned,
473  &reduced_rebinned_noise,
474  reduced_science,
475  reduced_science_error,
476  info_tbl,
477  extraction_slit,
478  order_trace),
479  "Could not reduce frame");
480 
481  /* Plot middle row */
482  check( uves_plot_image_rows(*reduced_science,
483  1 + cpl_image_get_size_y(*reduced_science)/2,
484  1 + cpl_image_get_size_y(*reduced_science)/2, 1,
485  "Wavelength (arbitrary units)", "Relative flux",
486  "Reduced science spectrum"),
487  "Plotting failed");
488 
489 
490  /*
491  * Flux calibrate the reduced spectrum
492  * (which is an image of height 1, or more if extract.method=2d)
493  */
494 
495  if (response_curve != NULL || master_response != NULL)
496  {
497  double lambda_start;
498  double dlambda;
499  int bin;
500 
501  /* Number of spatial traces (> 1 for 2d extraction) */
502  int n_traces = cpl_image_get_size_y(*reduced_science);
503 
504  uves_msg("Flux calibrating spectrum");
505 
506  /* We cannot be certain that the formats (wavelength start, bin width)
507  of the science spectrum and the response curve are identical.
508  Therefore we interpolate the response curve at the wavelengths
509  defined by the bins of the science spectrum. */
510 
511 
512 
513  /* If the response curve is an image, convert to table.
514  This is needed for the interpolation */
515  if (response_curve != NULL) {
516  response_table = cpl_table_new(cpl_image_get_size_x(response_curve));
517  cpl_table_new_column(response_table, "LAMBDA", CPL_TYPE_DOUBLE);
518  cpl_table_new_column(response_table, "FLUX_CONV", CPL_TYPE_DOUBLE);
519 
520  check( lambda_start = uves_pfits_get_crval1(response_curve_header),
521  "Error reading response curve start wavelength from header");
522 
523  check( dlambda = uves_pfits_get_cdelt1(response_curve_header),
524  "Error reading bin width from header");
525 
526  for (bin = 1; bin <= cpl_image_get_size_x(response_curve); bin++) {
527  double lambda;
528  double response;
529  int pis_rejected;
530 
531  lambda = lambda_start + (bin-1) * dlambda;
532 
533  check( response = cpl_image_get(response_curve, bin, 1, &pis_rejected),
534  "Error reading response curve bin = %d", bin);
535 
536  check((cpl_table_set_double(response_table, "LAMBDA", bin - 1, lambda),
537  cpl_table_set_double(response_table, "FLUX_CONV", bin - 1, response)),
538  "Error updating response table at row %d", bin - 1);
539  }
540  }
541  else {
542  response_table = cpl_table_duplicate( master_response );
543  } /* Response table created */
544 
545  /*
546  * Correct for exposure time, gain, binning, atm. ext.
547  */
548 
549  check( *fluxcal_science = uves_normalize_spectrum(*reduced_science,
550  *reduced_science_error,
551  *merged_header,
552  raw_header,
553  n_traces,
554  chip,
555  atm_extinction,
556  true, /* Divide by binning? */
557  fluxcal_error),
558  "Error normalizing reduced spectrum");
559 
560  /*
561  * Flux calibrate reduced spectrum
562  * flux := flux * response
563  */
564  uves_msg("Multiplying by response function");
565  {
566  int nbins = cpl_image_get_size_x(*fluxcal_science);
567  int ntraces = cpl_image_get_size_y(*fluxcal_science);
568  double *fluxcal_science_data = cpl_image_get_data_double(*fluxcal_science);
569  double *fluxcal_science_noise = cpl_image_get_data_double(*fluxcal_error);
570 
571  check( lambda_start = uves_pfits_get_crval1(*merged_header),
572  "Error reading start wavelength from reduced science header");
573 
574  check( dlambda = uves_pfits_get_cdelt1(*merged_header),
575  "Error reading bin width from header");
576 
577  for (bin = 1; bin <= nbins; bin++)
578  {
579  double lambda;
580  double response;
581  int trace; /* Spatial traces (for 2d extracted spectra) */
582  int istart = 0;
583 
584  lambda = lambda_start + (bin-1) * dlambda;
585 
586  check( response =
587  uves_spline_hermite_table(lambda, response_table,
588  "LAMBDA", "FLUX_CONV", &istart),
589  "Error interpolating response curve at lambda = %f wlu", lambda);
590 
591  for (trace = 1; trace <= ntraces; trace++)
592  {
593  /* Don't check for bad pixels here, also correct those.
594  * The fluxcal image has the same bad pixels as the reduced_science
595  * image */
596 
597  fluxcal_science_data [(bin-1) + (trace-1)*nbins] *= response;
598  fluxcal_science_noise[(bin-1) + (trace-1)*nbins] *= response;
599 
600  /* Do not propagate the error of the response
601  curve which is negligibly small (and unknown at this point!).
602  */
603  }
604  }
605 
606  /* Plot middle row */
607  check( uves_plot_image_rows(*fluxcal_science,
608  1 + cpl_image_get_size_y(*fluxcal_science)/2,
609  1 + cpl_image_get_size_y(*fluxcal_science)/2, 1,
610  "Wavelength (arbitrary units)",
611  "Flux (10^-16 erg/cm^2/Angstrom/s)",
612  "Flux calibrated science spectrum"),
613  "Plotting failed");
614 
615  check( *fluxcal_header = uves_initialize_image_header("AWAV", " ",
616  "Angstrom", NULL,
617  "10^-16 erg/cm^2/Angstrom/s",
618  1,
619  lambda_start, 1.0,
620  1.0, 1.0,
621  dlambda, 1.0),
622  "Error initializing flux calibrated spectrum header");
623  } /* Done multiplying by response curve */
624  }
625  else
626  {
627  uves_msg("Skipping absolute flux calibration");
628  }
629 
630  cleanup:
631  uves_free_image(&merged_noise);
632  uves_free_image(&reduced_rebinned_noise);
633  uves_free_image(&reduced_rebinned);
634  uves_free_table(&response_table);
635 
636  if (cpl_error_get_code() != CPL_ERROR_NONE)
637  {
638  }
639 
640  return cpl_error_get_code();
641 }
642 
643 
644 /*----------------------------------------------------------------------------*/
653 /*----------------------------------------------------------------------------*/
654 void uves_reduce_scired(cpl_frameset *frames, const cpl_parameterlist *parameters,
655  const char *recipe_id, const char *starttime)
656 {
657  /* Recipe parameters */
658  bool debug_mode;
659  bool CLEAN_TRAPS;
660  bool extract_is_2d = false; /* Are we doing a 2d reduction? */
661 
662  /* Input, raw */
663  cpl_image *raw_image[2] = {NULL, NULL};
664  uves_propertylist *raw_header[2] = {NULL, NULL};
665  uves_propertylist *rotated_header[2] = {NULL, NULL};
666 
667  /* Input, calib */
668  cpl_image *master_bias = NULL;
669  uves_propertylist *master_bias_header = NULL;
670 
671  cpl_image *master_flat = NULL;
672  uves_propertylist *master_flat_header = NULL;
673 
674  cpl_image *master_dark = NULL;
675  uves_propertylist *master_dark_header = NULL;
676 
677  cpl_table *ordertable = NULL;
678  uves_propertylist *ordertable_header= NULL;
679  polynomial *order_locations = NULL;
680  cpl_table *traces = NULL;
681 
682  /* Line tables for sky, object, sky (UVES specific) */
683  const cpl_table *linetable[3] = {NULL, NULL, NULL};
684  const uves_propertylist *linetable_header[3] = {NULL, NULL, NULL};
685  const polynomial *dispersion_relation[3] = {NULL, NULL, NULL};
686 
687  cpl_image *response_curve = NULL;
688  uves_propertylist *response_curve_header = NULL;
689  cpl_table *master_response = NULL;
690 
691  cpl_table *atm_extinction = NULL;
692 
693  /* Output */
694  /* BKG_SCI */
695  cpl_image *background = NULL;
696 
697  /* VARIANCE_SCIENCE */
698  cpl_image *flatfielded_variance = NULL;
699  uves_propertylist *flatfielded_variance_header = NULL;
700 
701  /* WCALIB_SCIENCE */
702  cpl_image *resampled_science = NULL; /* extracted -> rebinned */
703  /* WCALIB_FLAT_OBJ */
704  cpl_image *resampled_mf = NULL;
705  /* WCALIB_FF_SCIENCE */
706  cpl_image *rebinned_science = NULL; /* extracted -> ff -> rebinned */
707  cpl_image *rebinned_science_error = NULL;
708  uves_propertylist *rebinned_header = NULL;
709 
710  /* MERGED_SKY */
711  cpl_image *merged_sky = NULL;
712 
713  /* MERGED_SCIENCE / MER2D_SCIENCE */
714  /* RED_SCIENCE */
715  /* ERRORBAR_SCIENCE */
716  cpl_image *merged_science = NULL;
717  uves_propertylist *merged_header = NULL;
718  cpl_image *reduced_science = NULL;
719  cpl_image *reduced_science_error = NULL;
720 
721 
722  /* FLUXCAL_SCIENCE / FLUXCAL_ERROR */
723  cpl_image *fluxcal_science = NULL;
724  cpl_image *fluxcal_error = NULL;
725  uves_propertylist *fluxcal_header = NULL;
726 
727  /* ORDER_TRACE */
728  cpl_table *order_trace = NULL;
729  uves_propertylist *order_trace_header = NULL;
730 
731 
732  /* EXT_2D_SCIENCE */
733  cpl_image *x2d = NULL;
734  uves_propertylist *x2d_header = NULL;
735  /* FF2D_SCIENCE */
736  cpl_image *fx2d = NULL;
737 
738  /* CRMASK */
739  cpl_table *cosmic_mask = NULL;
740  uves_propertylist *cosmic_mask_header = NULL;
741 
742  /* QC */
743  cpl_table* qclog[2] = {NULL, NULL};
744  cpl_table *qclog_tflat = NULL;
745 
746  /* Local variables */
747  const char *raw_filename = "";
748  const char *atm_ext_filename = "";
749  const char *sci_type = "";
750  cpl_frame **raw_frames = NULL; /* Array of cpl_frame pointers */
751  char *product_tag = NULL;
752  char *product_filename = NULL;
753  char *context = NULL;
754  double extraction_slit;
755 
756  bool blue = false;
757  enum uves_chip chip;
758  int binx = 0;
759  int biny = 0;
760 
761  cpl_table* info_tbl = NULL;
762  const char* PROCESS_CHIP=NULL;
763  bool red_ccd_is_new=0;
764  merge_method m_method;
765  const char* catg_is_noappend=NULL;
766  cpl_image* wave_map=NULL;
767  uves_propertylist* wave_map_header=NULL;
768  uves_propertylist* wave_acc_header=NULL;
769  char extname[80];
770  uves_propertylist* table_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  table_header=uves_propertylist_new();
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  uves_pfits_set_extname(merged_header,"reduced 1d spectrum");
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  uves_pfits_set_extname(x2d_header,"Extracted 2d spectrum");
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  uves_pfits_set_extname(merged_header,"merged 1d spectrum");
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  uves_pfits_set_extname(rebinned_header,"Rebinned 2d spectrum");
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  uves_pfits_set_extname(rotated_header[raw_index],"QC on extraction");
1314 
1315  sprintf(extname,"QC_INFO");
1316  uves_pfits_set_extname(table_header,extname);
1317 
1318  check( uves_frameset_insert(frames,
1319  info_tbl,
1320  CPL_FRAME_GROUP_PRODUCT,
1321  CPL_FRAME_TYPE_TABLE,
1322  CPL_FRAME_LEVEL_INTERMEDIATE,
1323  product_filename,
1324  UVES_ORDER_EXTRACT_QC(chip),
1325  raw_header[raw_index],
1326  rotated_header[raw_index],
1327  table_header,
1328  parameters,
1329  recipe_id,
1330  PACKAGE "/" PACKAGE_VERSION,
1331  NULL,
1332  starttime, true,
1333  0),
1334  "Could not add extraction quality table %s (%s)"
1335  , product_filename,
1336  UVES_ORDER_EXTRACT_QC(chip));
1337 
1338  uves_msg("Extraction quality table '%s' "
1339  "(%s) added to frameset", product_filename,
1340  UVES_ORDER_EXTRACT_QC(chip));
1341 
1342 
1343  } /* if not 2d extracted */
1344 
1345 
1346  {
1347  const char *ff = "";
1348 
1349  /* Read uves_scired.reduce.ffmethd */
1350  cpl_free(context);
1351  context = uves_sprintf("%s.%s", recipe_id, UVES_REDUCE_ID);
1352  check( uves_get_parameter(parameters, NULL,
1353  context,
1354  "ffmethod",
1355  CPL_TYPE_STRING, &ff),
1356  "Could not read parameter");
1357 
1358  /* If flat-fielding was done */
1359  if (strcmp(ff, "no") != 0)
1360  {
1361  /* Save WCALIB_FF_SCIENCE / WCAL2D_SCIENCE =
1362  (rebinned_science, rebinned_header) */
1363  cpl_table *qc_tabs[] = {NULL, NULL, NULL};
1364 
1365  /* QC consists of usual science QC and
1366  optionally TFLAT QC
1367  */
1368 
1369  if ( strcmp(recipe_id, make_str(UVES_TFLAT_ID)) == 0 )
1370  {
1371  uves_qclog_delete(&qclog_tflat);
1372  qclog_tflat =
1373  uves_qclog_init(raw_header[raw_index], chip);
1374 
1375  check( tflat_qclog(resampled_science,
1376  raw_header[raw_index],
1377  qclog_tflat),
1378  "Could not compute QC parameters");
1379 
1380  qc_tabs[0] = qclog_tflat;
1381  qc_tabs[1] = qclog[0];
1382  }
1383  else
1384  {
1385  qc_tabs[0] = qclog[0];
1386  qc_tabs[1] = NULL;
1387  }
1388 
1389  cpl_free(product_filename);
1390  check( product_filename =
1391  (extract_is_2d) ?
1392  uves_scired_rebinned_2d_filename(chip) :
1393  uves_scired_rebinned_filename(chip),
1394  "Error getting filename");
1395 
1396  cpl_free(product_tag);
1397  product_tag = uves_sprintf(
1398  "%s_%s_%s",
1399  (extract_is_2d) ? "WCAL_2D" : "WCALIB_FF",
1400  sci_type, uves_chip_tostring_upper(chip));
1401 
1402  uves_propertylist_append(rebinned_header,wave_acc_header);
1403  uves_pfits_set_extname(rebinned_header,"Rebinned 2d spectrum");
1404  check( uves_frameset_insert(frames,
1405  rebinned_science,
1406  CPL_FRAME_GROUP_PRODUCT,
1407  CPL_FRAME_TYPE_IMAGE,
1408  CPL_FRAME_LEVEL_FINAL,
1409  product_filename,
1410  product_tag,
1411  raw_header[raw_index],
1412  rebinned_header,
1413  NULL,
1414  parameters,
1415  recipe_id,
1416  PACKAGE "/"
1417  PACKAGE_VERSION,
1418  qc_tabs,
1419  starttime, true,
1420  UVES_ALL_STATS),
1421  "Could not add wavelength calibrated flat-fielded "
1422  "science spectrum '%s' (%s) to frameset",
1423  product_filename, product_tag);
1424 
1425  uves_msg("Wavelength calibrated flat-fielded science "
1426  "spectrum '%s' (%s) added to frameset",
1427  product_filename, product_tag);
1428 
1429  cpl_free(product_filename);
1430  check( product_filename =
1431  (extract_is_2d) ?
1432  uves_scired_rebinned_2d_error_filename(chip) :
1433  uves_scired_rebinned_error_filename(chip),
1434  "Error getting filename");
1435 
1436  cpl_free(product_tag);
1437  product_tag = uves_sprintf(
1438  "%s_%s_%s",
1439  (extract_is_2d) ? "ERRORBAR_WCAL_2D" : "ERRORBAR_WCALIB_FF",
1440  sci_type, uves_chip_tostring_upper(chip));
1441 
1442 
1443  /* not needed as done before
1444  //uves_propertylist_append(rebinned_header,wave_acc_header);
1445  */
1446  uves_pfits_set_extname(rebinned_header,"Error reduced spectrum");
1447  check( uves_frameset_insert(frames,
1448  rebinned_science_error,
1449  CPL_FRAME_GROUP_PRODUCT,
1450  CPL_FRAME_TYPE_IMAGE,
1451  CPL_FRAME_LEVEL_FINAL,
1452  product_filename,
1453  product_tag,
1454  raw_header[raw_index],
1455  rebinned_header,
1456  NULL,
1457  parameters,
1458  recipe_id,
1459  PACKAGE "/"
1460  PACKAGE_VERSION,
1461  qc_tabs,
1462  starttime, true,
1463  UVES_ALL_STATS),
1464  "Could not add wavelength calibrated flat-fielded "
1465  "science spectrum '%s' (%s) to frameset",
1466  product_filename, product_tag);
1467 
1468  uves_msg("Wavelength calibrated flat-fielded science "
1469  "spectrum error '%s' (%s) added to frameset",
1470  product_filename, product_tag);
1471 
1472 
1473 
1474  if (!extract_is_2d)
1475  {
1476  /* Save WCALIB_FLAT_OBJ_xxxx =
1477  (resampled_mf, rebinned_header) */
1478  cpl_free(product_filename);
1479  check( product_filename =
1480  uves_scired_resampledmf_filename(chip),
1481  "Error getting filename");
1482 
1483  cpl_free(product_tag);
1484  product_tag =
1485  uves_sprintf(
1486  "WCALIB_FLAT_OBJ_%s",
1487  uves_chip_tostring_upper(chip));
1488  /* Independent of sci_type */
1489 
1490 
1491  /* !!!Exception!!!
1492  *
1493  * For this reduced master flat frame we
1494  * want to propagate the keywords *not*
1495  * from the first raw input frame but
1496  * from the master flat field itself.
1497  *
1498  * For that to work we temporarily set
1499  *
1500  * all raw frames := NONE
1501  * master.flat frame := RAW
1502  *
1503  * This will make cpl_dfs_setup_product_header()
1504  * find the proper "raw" frame (i.e. the mf)
1505  * Also the required 'raw_header' must be
1506  * that of the master flat frame, not science.
1507  * After propagating keywords, we change back
1508  * to normal:
1509  *
1510  * all raw frames := RAW
1511  * master.flat frame := CALIB
1512  *
1513  * (Since there could be more than 1 raw frame,
1514  * simply changing the first raw frame would
1515  * not work)
1516  */
1517 
1518  cpl_free(raw_frames);
1519  check_nomsg( raw_frames =
1520  set_all_raw_none(frames) );
1521 
1522  cpl_frame_set_group(mflat_frame,
1523  CPL_FRAME_GROUP_RAW);
1524 
1525  uves_propertylist_append(rebinned_header,wave_acc_header);
1526  uves_pfits_set_extname(rebinned_header,"Rebinned master flat");
1527  check( uves_frameset_insert(
1528  frames,
1529  resampled_mf,
1530  CPL_FRAME_GROUP_PRODUCT,
1531  CPL_FRAME_TYPE_IMAGE,
1532  CPL_FRAME_LEVEL_FINAL,
1533  product_filename,
1534  product_tag,
1535  master_flat_header, /* Note! */
1536  rebinned_header,
1537  NULL,
1538  parameters,
1539  recipe_id,
1540  PACKAGE "/"
1541  PACKAGE_VERSION,
1542  NULL, /* No QC: qclog */
1543  starttime, false,
1544  CPL_STATS_MIN | CPL_STATS_MAX),
1545  "Could not add wavelength calibrated "
1546  "flat-field '%s' (%s) to frameset",
1547  product_filename, product_tag);
1548 
1549  uves_msg("Wavelength calibrated flat-field "
1550  "spectrum '%s' (%s) added to frameset",
1551  product_filename, product_tag);
1552 
1553  /* Change frames groups back to normal */
1554  {
1555  int i;
1556  for (i = 0;
1557  raw_frames[i] != NULL;
1558  i++)
1559  {
1560  cpl_frame_set_group(
1561  raw_frames[i],
1562  CPL_FRAME_GROUP_RAW);
1563  }
1564  }
1565  cpl_frame_set_group(mflat_frame,
1566  CPL_FRAME_GROUP_CALIB);
1567  }
1568 
1569  if (extract_is_2d)
1570  {
1571  /* Save FF2D_SCIENCE_xxxx = (fx2d, x2d_header) */
1572  cpl_free(product_filename);
1573  check( product_filename =
1574  uves_scired_ff2d_filename(chip),
1575  "Error getting filename");
1576 
1577  cpl_free(product_tag);
1578  product_tag =
1579  uves_sprintf(
1580  "FF_2D_%s_%s", sci_type,
1581  uves_chip_tostring_upper(chip));
1582 
1583  uves_pfits_set_extname(x2d_header,"Extracted 2d spectrum");
1584  check( uves_frameset_insert(
1585  frames,
1586  fx2d,
1587  CPL_FRAME_GROUP_PRODUCT,
1588  CPL_FRAME_TYPE_IMAGE,
1589  CPL_FRAME_LEVEL_FINAL,
1590  product_filename,
1591  product_tag,
1592  raw_header[raw_index],
1593  x2d_header,
1594  NULL,
1595  parameters,
1596  recipe_id,
1597  PACKAGE "/"
1598  PACKAGE_VERSION,
1599  qclog,
1600  starttime, false,
1601  UVES_ALL_STATS),
1602  "Could not add 2d extracted, flat-fielded "
1603  "spectrum '%s' (%s) to frameset",
1604  product_filename, product_tag);
1605 
1606  uves_msg("2d extracted, flat-fielded spectrum "
1607  "'%s' (%s) added to frameset",
1608  product_filename, product_tag);
1609 
1610  }
1611 
1612  }/* If flat-fielding != no */
1613 
1614  check( uves_pfits_set_bunit(merged_header, "ADU"),
1615  "Error writing error spectrum header");
1616 
1617  /* Save ERRORBAR_SCIENCE_xxxx =
1618  (reduced_science_error, merged_header) */
1619  cpl_free(product_filename);
1620 
1621  check( product_filename =
1622  (extract_is_2d) ?
1623  uves_scired_red_2d_error_filename(chip) :
1624  ((m_method == MERGE_NOAPPEND) ?
1625  uves_scired_red_noappend_error_filename(chip): uves_scired_red_error_filename(chip)),
1626  "Error getting filename");
1627 
1628 
1629  cpl_free(product_tag);
1630  catg_is_noappend=uves_get_pro_catg_special(extract_is_2d,m_method);
1631  product_tag = uves_sprintf("%s%s_%s_%s",
1632  (extract_is_2d) ? "ERR_2D" : "ERRORBAR",catg_is_noappend,
1633  sci_type, uves_chip_tostring_upper(chip));
1634 
1635 /*
1636  product_tag = uves_sprintf(
1637  "%s%s_%s_%s",
1638  (m_method == MERGE_NOAPPEND) ? "ERRORBAR_NONMERGED" : "ERRORBAR",
1639  (extract_is_2d) ? "_2D" : "",
1640  sci_type, uves_chip_tostring_upper(chip));
1641 
1642 */
1643  uves_propertylist_append(merged_header,wave_acc_header);
1644  uves_pfits_set_extname(merged_header,"Error reduced spectrum");
1645  check( uves_frameset_insert(
1646  frames,
1647  reduced_science_error,
1648  CPL_FRAME_GROUP_PRODUCT,
1649  CPL_FRAME_TYPE_IMAGE,
1650  CPL_FRAME_LEVEL_FINAL,
1651  product_filename,
1652  product_tag,
1653  raw_header[raw_index],
1654  merged_header,
1655  NULL,
1656  parameters,
1657  recipe_id,
1658  PACKAGE "/" PACKAGE_VERSION,
1659  qclog,
1660  starttime, false,
1661  CPL_STATS_MIN | CPL_STATS_MAX),
1662  "Could not add error bars '%s' (%s) to frameset",
1663  product_filename, product_tag);
1664 
1665  uves_msg("Science spectrum error '%s' (%s) "
1666  "added to frameset",
1667  product_filename, product_tag);
1668 
1669 
1670  if (!extract_is_2d)
1671  {
1672 
1673 
1674  /* Save VARIANCE_SCIENCE_xxxx =
1675  (flatfielded_variance, flatfielded_variance_header) */
1676  cpl_free(product_filename);
1677  check( product_filename =
1678  uves_scired_ff_variance_filename(chip),
1679  "Error getting filename");
1680 
1681  cpl_free(product_tag);
1682  product_tag =
1683  uves_sprintf("VARIANCE_%s_%s", sci_type,
1684  uves_chip_tostring_upper(chip));
1685 
1686 
1687 
1688  uves_pfits_set_extname(flatfielded_variance_header,"Variance reduced spectrum");
1689  check( uves_frameset_insert(frames,
1690  flatfielded_variance,
1691  CPL_FRAME_GROUP_PRODUCT,
1692  CPL_FRAME_TYPE_IMAGE,
1693  CPL_FRAME_LEVEL_FINAL,
1694  product_filename,
1695  product_tag,
1696  raw_header[raw_index],
1697  flatfielded_variance_header,
1698  NULL,
1699  parameters,
1700  recipe_id,
1701  PACKAGE "/" PACKAGE_VERSION,
1702  qclog,
1703  starttime, false,
1704  CPL_STATS_MIN | CPL_STATS_MAX),
1705  "Could not add flat-fielded spectrum variance "
1706  "'%s' (%s) to frameset",
1707  product_filename, product_tag);
1708 
1709  uves_msg("Flat-fielded spectrum variance '%s' (%s) "
1710  "added to frameset",
1711  product_filename, product_tag);
1712 
1713  } /* if not 2d extraction */
1714  }
1715 
1716  if (!extract_is_2d)
1717  {
1718  /* Save BKG_SCI_xxxx = (background, rotated_header) */
1719  cpl_free(product_filename);
1720  check( product_filename =
1721  uves_scired_background_filename(chip),
1722  "Error getting filename");
1723 
1724  cpl_free(product_tag);
1725  product_tag =
1726  uves_sprintf("BKG_SCI_%s",
1727  uves_chip_tostring_upper(chip));
1728 
1729 
1730  check( uves_frameset_insert(frames,
1731  background,
1732  CPL_FRAME_GROUP_PRODUCT,
1733  CPL_FRAME_TYPE_IMAGE,
1734  CPL_FRAME_LEVEL_FINAL,
1735  product_filename,
1736  product_tag,
1737  raw_header[raw_index],
1738  rotated_header[raw_index],
1739  NULL,
1740  parameters,
1741  recipe_id,
1742  PACKAGE "/" PACKAGE_VERSION,
1743  NULL, /* QC */
1744  starttime, false,
1745  CPL_STATS_MIN | CPL_STATS_MAX),
1746  "Could not add background image '%s' (%s) "
1747  "to frameset", product_filename, product_tag);
1748 
1749  uves_msg("Background image '%s' (%s) added to frameset",
1750  product_filename, product_tag);
1751 
1752  /* If optimal extraction, also save
1753  cosmic_mask, order_trace */
1754  if (order_trace != NULL)
1755  {
1756  /* Save ORDER_TRACE_xxxx */
1757  uves_free_propertylist(&order_trace_header);
1758  order_trace_header = uves_propertylist_new();
1759 
1760 
1761  /* !WARNING!: Duplicate code follows, be careful if/when
1762  changing. These parameters should be calculated
1763  the same way as in uves_qclog_add_sci().
1764 
1765  The MIDAS pipeline wrote these parameters only
1766  in this product, and for backwards compatibility
1767  do the same here.
1768  */
1769 
1771  order_trace_header, "ESO QC OPTEX NORD",
1772  uves_round_double(
1773  cpl_table_get_column_max(ordertable, "Order")-
1774  cpl_table_get_column_min(ordertable, "Order")+1));
1775 
1777  order_trace_header, "ESO QC OPTEX XSIZE",
1778  cpl_image_get_size_x(raw_image[raw_index]));
1779 
1781  order_trace_header, "ESO QC OPTEX YSIZE",
1782  uves_round_double(extraction_slit));
1783 
1784 
1785  cpl_free(product_filename);
1786  check( product_filename =
1787  uves_scired_ordertrace_filename(chip),
1788  "Error getting filename");
1789 
1790  cpl_free(product_tag);
1791  product_tag =
1792  uves_sprintf("ORDER_TRACE_%s",
1793  uves_chip_tostring_upper(chip));
1794 
1795  uves_pfits_set_extname(order_trace_header,"Order trace info");
1796  sprintf(extname,"TRACE_INFO");
1797  uves_pfits_set_extname(table_header,extname);
1798  check( uves_frameset_insert(frames,
1799  order_trace,
1800  CPL_FRAME_GROUP_PRODUCT,
1801  CPL_FRAME_TYPE_TABLE,
1802  CPL_FRAME_LEVEL_FINAL,
1803  product_filename,
1804  product_tag,
1805  raw_header[raw_index],
1806  order_trace_header,
1807  table_header,
1808  parameters,
1809  recipe_id,
1810  PACKAGE "/"
1811  PACKAGE_VERSION,
1812  qclog,
1813  starttime, false,
1814  0),
1815  "Could not add sky spectrum '%s' (%s) "
1816  "to frameset",
1817  product_filename, product_tag);
1818 
1819  uves_msg("Order trace table '%s' (%s) "
1820  "added to frameset",
1821  product_filename, product_tag);
1822  }
1823 
1824 
1825 
1826  if (cosmic_mask != NULL)
1827  {
1828  /* Save CRMASK_xxxx */
1829  uves_free_propertylist(&cosmic_mask_header);
1830  cosmic_mask_header = uves_propertylist_new();
1831 
1832  cpl_free(product_filename);
1833  check( product_filename =
1834  uves_scired_crmask_filename(chip),
1835  "Error getting filename");
1836 
1837  cpl_free(product_tag);
1838  product_tag =
1839  uves_sprintf("CRMASK_%s",
1840  uves_chip_tostring_upper(chip));
1841 
1842  uves_pfits_set_extname(cosmic_mask_header,"CRH mask");
1843  sprintf(extname,"CRH_MASK");
1844  uves_pfits_set_extname(table_header,extname);
1845 
1846  check( uves_frameset_insert(frames,
1847  cosmic_mask,
1848  CPL_FRAME_GROUP_PRODUCT,
1849  CPL_FRAME_TYPE_TABLE,
1850  CPL_FRAME_LEVEL_FINAL,
1851  product_filename,
1852  product_tag,
1853  raw_header[raw_index],
1854  cosmic_mask_header,
1855  table_header,
1856  parameters,
1857  recipe_id,
1858  PACKAGE "/"
1859  PACKAGE_VERSION,
1860  NULL, /* qc */
1861  starttime, false,
1862  0),
1863  "Could not add cosmic ray table "
1864  "'%s' (%s) to frameset",
1865  product_filename, product_tag);
1866 
1867  uves_msg("Cosmic ray table '%s' (%s) "
1868  "added to frameset",
1869  product_filename, product_tag);
1870  }
1871 
1872 
1873 
1874 
1875 
1876 
1877 
1878 
1879  if (wave_map != NULL)
1880  {
1881  /* Save WAVE_MAP_xxxx */
1882  uves_free_propertylist(&wave_map_header);
1883  wave_map_header = uves_propertylist_new();
1884 
1885  cpl_free(product_filename);
1886  check( product_filename =
1887  uves_scired_wmap_filename(chip),
1888  "Error getting filename");
1889 
1890  cpl_free(product_tag);
1891  product_tag =
1892  uves_sprintf("WAVE_MAP_%s",
1893  uves_chip_tostring_upper(chip));
1894  uves_pfits_set_ctype1(wave_map_header,"PIXEL");
1895  uves_pfits_set_ctype2(wave_map_header,"PIXEL");
1896  check( uves_frameset_insert(frames,
1897  wave_map,
1898  CPL_FRAME_GROUP_PRODUCT,
1899  CPL_FRAME_TYPE_IMAGE,
1900  CPL_FRAME_LEVEL_FINAL,
1901  product_filename,
1902  product_tag,
1903  raw_header[raw_index],
1904  wave_map_header,
1905  NULL,
1906  parameters,
1907  recipe_id,
1908  PACKAGE "/"
1909  PACKAGE_VERSION,
1910  NULL, /* qc */
1911  starttime, false,
1912  0),
1913  "Could not add wave map "
1914  "'%s' (%s) to frameset",
1915  product_filename, product_tag);
1916 
1917  uves_msg("Wave map '%s' (%s) "
1918  "added to frameset",
1919  product_filename, product_tag);
1920  } else {
1921  uves_msg("no wave map!!!!!!!!!");
1922  }
1923  uves_free_image(&wave_map);
1924 
1925 
1926  if (merged_sky != NULL)
1927  /* In slicer mode / 2d mode, no sky
1928  spectrum is extracted */
1929  {
1930  /* Save MERGED_SKY_xxxx =
1931  (merged_sky, merged_header) */
1932  cpl_free(product_filename);
1933  check( product_filename =
1934  uves_scired_merged_sky_filename(chip),
1935  "Error getting filename");
1936 
1937  cpl_free(product_tag);
1938  product_tag =
1939  uves_sprintf("MERGED_SKY_%s",
1940  uves_chip_tostring_upper(chip));
1941 
1942  uves_propertylist_append(merged_header,wave_acc_header);
1943 
1944 
1945  check( uves_frameset_insert(
1946  frames,
1947  merged_sky,
1948  CPL_FRAME_GROUP_PRODUCT,
1949  CPL_FRAME_TYPE_IMAGE,
1950  CPL_FRAME_LEVEL_FINAL,
1951  product_filename,
1952  product_tag,
1953  raw_header[raw_index],
1954  merged_header,
1955  NULL,
1956  parameters,
1957  recipe_id,
1958  PACKAGE "/"
1959  PACKAGE_VERSION,
1960  NULL, /* QC */
1961  starttime, false,
1962  CPL_STATS_MIN | CPL_STATS_MAX),
1963  "Could not add sky spectrum "
1964  "'%s' (%s) to frameset",
1965  product_filename, product_tag);
1966 
1967  uves_msg("Sky spectrum '%s' (%s) added to frameset",
1968  product_filename, product_tag);
1969  }
1970  else
1971  {
1972  uves_msg_low("No sky spectrum to save");
1973  }
1974 
1975  }/* if extract is 2d */
1976 
1977  if (fluxcal_science != NULL)
1978  {
1979  /* Save FLUXCAL_SCIENCE =
1980  (fluxcal_science, fluxcal_header) */
1981  cpl_free(product_filename);
1982 
1983  check( product_filename =
1984  (extract_is_2d) ?
1985  uves_scired_fluxcal_science_2d_filename(chip) :
1986  ((m_method == MERGE_NOAPPEND) ?
1987  uves_scired_fluxcal_science_noappend_filename(chip): uves_scired_fluxcal_science_filename(chip)),
1988  "Error getting filename");
1989 
1990 
1991  cpl_free(product_tag);
1992 
1993 
1994 
1995  catg_is_noappend=uves_get_pro_catg_special(extract_is_2d,m_method);
1996  product_tag = uves_sprintf("FLUXCAL%s%s_%s_%s",
1997  (extract_is_2d) ? "_2D" : "",catg_is_noappend,
1998  sci_type, uves_chip_tostring_upper(chip));
1999 
2000 
2001  /* Always _SCIENCE_, independent of sci_type */
2002 
2003  uves_propertylist_append(fluxcal_header,wave_acc_header);
2004 
2005  check( uves_frameset_insert(frames,
2006  fluxcal_science,
2007  CPL_FRAME_GROUP_PRODUCT,
2008  CPL_FRAME_TYPE_IMAGE,
2009  CPL_FRAME_LEVEL_FINAL,
2010  product_filename,
2011  product_tag,
2012  raw_header[raw_index],
2013  fluxcal_header,
2014  NULL,
2015  parameters,
2016  recipe_id,
2017  PACKAGE "/"
2018  PACKAGE_VERSION,
2019  qclog,
2020  starttime, false,
2021  CPL_STATS_MIN | CPL_STATS_MAX),
2022  "Could not add flux-calibrated science "
2023  "spectrum '%s' (%s) to frameset",
2024  product_filename, product_tag);
2025 
2026  uves_msg("Flux-calibrated science spectrum "
2027  "'%s' (%s) added to frameset",
2028  product_filename, product_tag);
2029 
2030  /* Save FLUXCAL_ERRORBAR = (fluxcal_error, fluxcal_header) */
2031  check( uves_pfits_set_bunit(fluxcal_header,
2032  "10^-16 erg/cm^2/Angstrom/s"),
2033  "Error writing error spectrum header");
2034 
2035  cpl_free(product_filename);
2036 
2037  check( product_filename =
2038  (extract_is_2d) ?
2039  uves_scired_fluxcal_error_2d_filename(chip) :
2040  ((m_method == MERGE_NOAPPEND) ?
2041  uves_scired_fluxcal_error_noappend_filename(chip): uves_scired_fluxcal_error_filename(chip)),
2042  "Error getting filename");
2043 
2044 
2045  cpl_free(product_tag);
2046 
2047 
2048  catg_is_noappend=uves_get_pro_catg_special(extract_is_2d,m_method);
2049  product_tag = uves_sprintf("FLUXCAL_ERRORBAR%s%s_%s_%s",
2050  (extract_is_2d) ? "_2D" : "",catg_is_noappend,
2051  sci_type, uves_chip_tostring_upper(chip));
2052 
2053  uves_propertylist_append(fluxcal_header,wave_acc_header);
2054 
2055  check( uves_frameset_insert(frames,
2056  fluxcal_error,
2057  CPL_FRAME_GROUP_PRODUCT,
2058  CPL_FRAME_TYPE_IMAGE,
2059  CPL_FRAME_LEVEL_FINAL,
2060  product_filename,
2061  product_tag,
2062  raw_header[raw_index],
2063  fluxcal_header,
2064  NULL,
2065  parameters,
2066  recipe_id,
2067  PACKAGE "/"
2068  PACKAGE_VERSION,
2069  qclog,
2070  starttime, false,
2071  CPL_STATS_MIN | CPL_STATS_MAX),
2072  "Could not add flux-calibrated science "
2073  "spectrum error '%s' (%s) to frameset",
2074  product_filename, product_tag);
2075 
2076  uves_msg("Flux-calibrated science spectrum error "
2077  "'%s' (%s) added to frameset",
2078  product_filename, product_tag);
2079 
2080  } /* If flux calibration done */
2081 
2082  }/* if trace is enabled */
2083  else
2084  {
2085  uves_msg("Skipping trace number %d", trace_number);
2086  }
2087 
2088 
2089  }/* for each trace */
2090 
2091 
2092  if(strcmp(PROCESS_CHIP,"REDL") == 0) {
2093  chip = uves_chip_get_next(chip);
2094  }
2095  uves_free_propertylist(&table_header);
2096 
2097  }/* For each chip */
2098 
2099  cleanup:
2100  /* Input */
2101  uves_free_table(&info_tbl);
2102  uves_free_image(&raw_image[0]);
2103  uves_free_image(&raw_image[1]);
2104  uves_free_propertylist(&raw_header[0]);
2105  uves_free_propertylist(&raw_header[1]);
2106  uves_free_propertylist(&rotated_header[0]);
2107  uves_free_propertylist(&rotated_header[1]);
2108  uves_free_propertylist(&wave_map_header);
2109  uves_free_propertylist(&wave_acc_header);
2110 
2111  /* Input, calib */
2112  uves_free_image(&master_bias);
2113  uves_free_propertylist(&master_bias_header);
2114 
2115  uves_free_image(&master_dark);
2116  uves_free_propertylist(&master_dark_header);
2117 
2118  uves_free_image(&master_flat);
2119  uves_free_propertylist(&master_flat_header);
2120 
2121  uves_free_table(&ordertable);
2122  uves_free_propertylist(&ordertable_header);
2123  uves_polynomial_delete(&order_locations);
2124  uves_free_table(&traces);
2125 
2126  uves_free_table_const( &(linetable[0]) );
2127  uves_free_table_const( &(linetable[1]) );
2128  uves_free_table_const( &(linetable[2]) );
2129  uves_free_propertylist_const( &(linetable_header[0]) );
2130  uves_free_propertylist_const( &(linetable_header[1]) );
2131  uves_free_propertylist_const( &(linetable_header[2]) );
2132  uves_polynomial_delete_const( &(dispersion_relation[0]) );
2133  uves_polynomial_delete_const( &(dispersion_relation[1]) );
2134  uves_polynomial_delete_const( &(dispersion_relation[2]) );
2135 
2136  uves_free_image(&response_curve);
2137  uves_free_propertylist(&response_curve_header);
2138  uves_free_table(&master_response);
2139 
2140  uves_free_table(&atm_extinction);
2141 
2142  /* Output */
2143  uves_qclog_delete(&qclog[0]);
2144  uves_qclog_delete(&qclog_tflat);
2145  uves_free_image(&background);
2146  uves_free_image(&flatfielded_variance);
2147  uves_free_propertylist(&flatfielded_variance_header);
2148  uves_free_image(&rebinned_science);
2149  uves_free_image(&rebinned_science_error);
2150  uves_free_propertylist(&rebinned_header);
2151  uves_free_image(&resampled_science);
2152  uves_free_image(&resampled_mf);
2153  uves_free_image(&merged_sky);
2154 
2155  uves_free_image(&merged_science);
2156  uves_free_propertylist(&merged_header);
2157  uves_free_image(&reduced_science);
2158  uves_free_image(&reduced_science_error);
2159  uves_free_image(&fluxcal_science);
2160  uves_free_image(&fluxcal_error);
2161  uves_free_propertylist(&fluxcal_header);
2162  uves_free_table(&cosmic_mask);
2163  uves_free_propertylist(&cosmic_mask_header);
2164 
2165  uves_free_table(&order_trace);
2166  uves_free_propertylist(&order_trace_header);
2167 
2168  uves_free_image(&x2d);
2169  uves_free_image(&fx2d);
2170  uves_free_propertylist(&x2d_header);
2171 
2172  cpl_free(raw_frames);
2173  cpl_free(product_filename);
2174  cpl_free(context);
2175  cpl_free(product_tag);
2176 
2177  return;
2178 }
2179 
2180 /*----------------------------------------------------------------------------*/
2189 /*----------------------------------------------------------------------------*/
2190 static void
2191 scired_qclog(const cpl_table* info_tbl,
2192  const uves_propertylist *raw_header,
2193  const cpl_image *raw_image,
2194  double slit,
2195  cpl_table* qclog)
2196 {
2197  /* This test does not exist as an official QC-TEST in the MIDAS pipeline. But
2198  the QC parameters are written to the product header */
2199 
2201  "QC TEST1 ID",
2202  "Science-Reduction-Test-Results",
2203  "Name of QC test",
2204  "%s"));
2205 
2207  raw_header,
2208  raw_image,
2209  slit,
2210  info_tbl) );
2211 
2212  cleanup:
2213  return;
2214 
2215 }
2216 
2217 /*----------------------------------------------------------------------------*/
2224 /*----------------------------------------------------------------------------*/
2225 static void
2226 tflat_qclog(const cpl_image* ima,
2227  const uves_propertylist *raw_header,
2228  cpl_table* qclog)
2229 {
2230  char key_name[80];
2231  cpl_image *window = NULL;
2232 
2233  double exptime;
2234  int nx;
2235  int ny;
2236  int i;
2237 
2239  "QC TEST1 ID",
2240  "TFLAT-QC",
2241  "Name of QC test",
2242  "%s"));
2243 
2244 
2246  uves_remove_string_prefix(UVES_INSMODE, "ESO "),
2247  uves_pfits_get_insmode(raw_header),
2248  "Instrument mode used.",
2249  "%s"));
2250 
2252  uves_remove_string_prefix(UVES_INSPATH, "ESO "),
2253  uves_pfits_get_inspath(raw_header),
2254  "Optical path used.",
2255  "%s"));
2256 
2258  uves_remove_string_prefix(UVES_SLIT1NAME, "ESO "),
2259  uves_pfits_get_slit1_name(raw_header),
2260  "Slit common name.",
2261  "%s"));
2262 
2263  check( exptime = uves_pfits_get_exptime(raw_header),
2264  "Error reading exposure time");
2265 
2266  nx = cpl_image_get_size_x(ima);
2267  ny = cpl_image_get_size_y(ima);
2268 
2269  for (i = 1; i <= ny; i++)
2270  /* Always count order numbers from 1, like MIDAS */
2271  {
2272  int size = 100;
2273  int xlo = uves_max_int(1 , (nx+1)/2 - size);
2274  int xhi = uves_min_int(nx, (nx+1)/2 + size);
2275 
2276  double min, max, avg, rms, med;
2277 
2278  uves_free_image(&window);
2279  window = cpl_image_extract(ima, xlo, i, xhi, i);
2280  assure_mem( window );
2281 
2282  if (cpl_image_count_rejected(window) >= cpl_image_get_size_x(window) - 2)
2283  {
2284  min = max = avg = rms = med = 0;
2285  }
2286  else
2287  {
2288  min = cpl_image_get_min (window) / exptime;
2289  max = cpl_image_get_max (window) / exptime;
2290  avg = cpl_image_get_mean (window) / exptime;
2291  rms = cpl_image_get_stdev (window) / exptime;
2292  med = cpl_image_get_median(window) / exptime;
2293  }
2294 
2295  sprintf(key_name, "QC ORD%d DATAMIN", i);
2297  key_name,
2298  min,
2299  "extracted order datamin",
2300  "%f"));
2301 
2302  sprintf(key_name, "QC ORD%d DATAMAX", i);
2304  key_name,
2305  max,
2306  "extracted order datamax",
2307  "%f"));
2308 
2309  sprintf(key_name, "QC ORD%d DATAAVG", i);
2311  key_name,
2312  avg,
2313  "extracted order datamean",
2314  "%f"));
2315 
2316  sprintf(key_name, "QC ORD%d DATARMS", i);
2318  key_name,
2319  rms,
2320  "extracted order datarms",
2321  "%f"));
2322 
2323  sprintf(key_name, "QC ORD%d DATAMED", i);
2325  key_name,
2326  med,
2327  "extracted order datamed",
2328  "%f"));
2329  }
2330 
2331  cleanup:
2332  uves_free_image(&window);
2333  return;
2334 
2335 }
2336 
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:3683
#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:3612
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..