UVES Pipeline Reference Manual  5.4.0
uves_merge.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 /*
22  * $Author: amodigli $
23  * $Date: 2013-04-16 15:46:57 $
24  * $Revision: 1.65 $
25  * $Name: not supported by cvs2svn $
26  * $Log: not supported by cvs2svn $
27  * Revision 1.64 2013/04/05 08:02:31 amodigli
28  * changed WAVELENGTH to AWAV to be FITS compliant
29  *
30  * Revision 1.63 2012/05/02 06:08:32 amodigli
31  * replace Ang by Angstrom
32  *
33  * Revision 1.62 2012/03/02 16:53:31 amodigli
34  * fixed warning related to upgrade to CPL6
35  *
36  * Revision 1.61 2011/12/08 14:03:09 amodigli
37  * Fix warnings with CPL6
38  *
39  * Revision 1.60 2010/12/16 16:57:40 amodigli
40  * fixed compiler warnings
41  *
42  * Revision 1.59 2010/12/08 11:07:59 amodigli
43  * added chip parameter to uves_merge_orders() to have proper filenames. Fixed content err data for noappend case
44  *
45  * Revision 1.58 2010/09/27 06:32:22 amodigli
46  * fixed mem leaks
47  *
48  * Revision 1.57 2010/09/24 09:32:04 amodigli
49  * put back QFITS dependency to fix problem spot by NRI on FIBER mode (with MIDAS calibs) data
50  *
51  * Revision 1.55 2010/06/07 09:48:00 amodigli
52  * changed units: A-->Ang, FLUX-->ADU
53  *
54  * Revision 1.54 2010/06/01 16:06:55 amodigli
55  * added unit [A] to reduced product
56  *
57  * Revision 1.53 2008/09/29 06:57:41 amodigli
58  * add #include <string.h>
59  *
60  * Revision 1.52 2008/09/27 16:05:12 amodigli
61  * fixed bug using delta parmeters
62  *
63  * Revision 1.51 2008/09/23 11:32:39 amodigli
64  * added check on array upper bound access to fix DFS05803
65  *
66  * Revision 1.50 2008/08/29 09:52:39 amodigli
67  * fixed compiler warning
68  *
69  * Revision 1.49 2008/06/26 08:30:38 amodigli
70  * fixed bug in setting delta
71  *
72  * Revision 1.48 2008/06/11 14:42:50 amodigli
73  * fixed seg fault
74  *
75  * Revision 1.45 2008/03/04 07:35:31 amodigli
76  * generate spectra of each order only if NOAPPEND
77  *
78  * Revision 1.44 2008/02/21 07:50:38 amodigli
79  * added method NOAPPEND
80  *
81  * Revision 1.43 2007/08/21 13:08:26 jmlarsen
82  * Removed irplib_access module, largely deprecated by CPL-4
83  *
84  * Revision 1.42 2007/06/21 11:28:57 jmlarsen
85  * Added support for type float (for FLAMES)
86  *
87  * Revision 1.41 2007/06/06 08:17:33 amodigli
88  * replace tab with 4 spaces
89  *
90  * Revision 1.40 2007/05/03 15:21:13 jmlarsen
91  * Decreased output message verbosity
92  *
93  * Revision 1.39 2007/04/24 12:50:29 jmlarsen
94  * Replaced cpl_propertylist -> uves_propertylist which is much faster
95  *
96  * Revision 1.38 2007/02/09 08:57:54 jmlarsen
97  * Include <float.h>
98  *
99  * Revision 1.37 2007/02/09 08:14:16 jmlarsen
100  * Do not use CPL_PIXEL_MAXVAL which works only for integer images
101  *
102  * Revision 1.36 2007/02/08 07:34:28 jmlarsen
103  * Minor doc change
104  *
105  * Revision 1.35 2006/11/15 15:02:14 jmlarsen
106  * Implemented const safe workarounds for CPL functions
107  *
108  * Revision 1.33 2006/11/15 14:04:08 jmlarsen
109  * Removed non-const version of parameterlist_get_first/last/next which is already
110  * in CPL, added const-safe wrapper, unwrapper and deallocator functions
111  *
112  * Revision 1.32 2006/11/13 14:23:55 jmlarsen
113  * Removed workarounds for CPL const bugs
114  *
115  * Revision 1.31 2006/11/06 15:19:41 jmlarsen
116  * Removed unused include directives
117  *
118  * Revision 1.30 2006/09/11 14:00:11 jmlarsen
119  * Minor documentation change
120  *
121  * Revision 1.29 2006/08/17 13:56:53 jmlarsen
122  * Reduced max line length
123  *
124  * Revision 1.28 2006/08/17 09:16:47 jmlarsen
125  * Removed CPL2 code
126  *
127  * Revision 1.27 2006/08/11 14:37:59 jmlarsen
128  * Added input validation
129  *
130  * Revision 1.26 2006/08/10 10:50:12 jmlarsen
131  * Removed workaround for cpl_image_get_bpm
132  *
133  * Revision 1.25 2006/07/03 13:16:42 jmlarsen
134  * Reduced number of significant digits in message
135  *
136  * Revision 1.24 2006/04/06 08:38:56 jmlarsen
137  * Changed char* -> const char* for static string
138  *
139  * Revision 1.23 2006/03/03 13:54:11 jmlarsen
140  * Changed syntax of check macro
141  *
142  * Revision 1.22 2006/02/03 07:46:30 jmlarsen
143  * Moved recipe implementations to ./uves directory
144  *
145  * Revision 1.21 2006/01/31 08:24:29 jmlarsen
146  * Wrapper for cpl_image_get_bpm
147  *
148  * Revision 1.20 2006/01/25 16:13:20 jmlarsen
149  * Changed interface of gauss.fitting routine
150  *
151  * Revision 1.19 2005/12/19 16:17:56 jmlarsen
152  * Replaced bool -> int
153  *
154  * Revision 1.18 2005/12/16 14:22:23 jmlarsen
155  * Removed midas test data; Added sof files
156  *
157  * Revision 1.17 2005/11/24 15:09:06 jmlarsen
158  * Implemented 2d extraction/rebinning/merging
159  *
160  * Revision 1.16 2005/11/24 11:54:46 jmlarsen
161  * Added support for CPL 3 interface
162  *
163  * Revision 1.15 2005/11/18 10:52:06 jmlarsen
164  * Split into optimal/sum merge methods
165  *
166  * Revision 1.14 2005/11/11 13:18:54 jmlarsen
167  * Reorganized code, renamed source files
168  *
169  */
170 
171 #ifdef HAVE_CONFIG_H
172 # include <config.h>
173 #endif
174 
175 /*----------------------------------------------------------------------------*/
181 /*----------------------------------------------------------------------------*/
185 /*-----------------------------------------------------------------------------
186  Includes
187  -----------------------------------------------------------------------------*/
188 
189 #include <uves_merge.h>
190 
191 #include <uves_pfits.h>
192 #include <uves_utils.h>
193 #include <uves_utils_wrappers.h>
194 #include <uves_dump.h>
195 #include <uves_dfs.h>
196 #include <uves_error.h>
197 
198 #include <cpl.h>
199 #include <float.h>
200 #include <string.h>
201 /*-----------------------------------------------------------------------------
202  Functions prototypes
203  ----------------------------------------------------------------------------*/
204 
205 /*-----------------------------------------------------------------------------
206  Implementation
207  ----------------------------------------------------------------------------*/
208 
209 /*---------------------------------------------------------------------------*/
236 /*---------------------------------------------------------------------------*/
237 
238 cpl_image *
239 uves_merge_orders(const cpl_image *spectrum,
240  const cpl_image *spectrum_noise,
241  const uves_propertylist *spectrum_header,
242  merge_method m_method,
243  int n_traces,
244  uves_propertylist **merged_header,
245  const double delt1,
246  const double delt2,
247  enum uves_chip chip,
248  cpl_image **merged_noise)
249 {
250  cpl_image *merged = NULL; /* Result */
251 
252  const double *spectrum_data_double = NULL;
253  const float *spectrum_data_float = NULL;
254  const cpl_mask *spectrum_badmap = NULL;
255  const cpl_binary *spectrum_bad = NULL;
256 
257  const double *noise_data_double = NULL;
258  const float *noise_data_float = NULL;
259  const cpl_mask *noise_badmap = NULL;
260  const cpl_binary *noise_bad = NULL;
261  cpl_type type; /* input/output images type */
262 
263  int nbins, ny, norders; /* Input image size. ny = norders*n_traces */
264  double wavestep;
265  int bin_min = 0, bin_max = 0; /* wavelength of min/max bin in units of 'wavestep' */
266  int total_bins;
267  int order, trace;
268  int spectrum_sx=0;
269  int spectrum_sy=0;
270  double delt1_bin=0;
271  double delt2_bin=0;
272  char* filename=NULL;
273 
274  cpl_vector* image_1d=NULL;
275  uves_propertylist* hext=NULL;
276  //double med_noise=0;
277  passure( spectrum != NULL, " ");
278  passure( spectrum_noise != NULL, " ");
279  passure( spectrum_header != NULL, " ");
280  passure( merged_header != NULL, " ");
281  passure( merged_noise != NULL, " ");
282 
283  assure( m_method == MERGE_OPTIMAL ||
284  m_method == MERGE_SUM ||
285  m_method == MERGE_NOAPPEND,
286  CPL_ERROR_ILLEGAL_INPUT,
287  "Unknown merge method: %d", m_method);
288 
289  assure( cpl_image_get_type(spectrum) == CPL_TYPE_DOUBLE ||
290  cpl_image_get_type(spectrum) == CPL_TYPE_FLOAT,
291  CPL_ERROR_TYPE_MISMATCH,
292  "Spectrum must have type double or float. It is '%s'",
293  uves_tostring_cpl_type(cpl_image_get_type(spectrum)));
294 
295  assure( cpl_image_get_type(spectrum_noise) == CPL_TYPE_DOUBLE ||
296  cpl_image_get_type(spectrum_noise) == CPL_TYPE_FLOAT,
297  CPL_ERROR_TYPE_MISMATCH,
298  "Spectrum noise must have type double. It is '%s'",
299  uves_tostring_cpl_type(cpl_image_get_type(spectrum_noise)));
300 
301  assure( cpl_image_get_type(spectrum) ==
302  cpl_image_get_type(spectrum_noise),
303  CPL_ERROR_TYPE_MISMATCH,
304  "Spectrum and spectrum noise must have same type. They are "
305  "%s and %s, respectively",
306  uves_tostring_cpl_type(cpl_image_get_type(spectrum)),
307  uves_tostring_cpl_type(cpl_image_get_type(spectrum_noise)) );
308 
309  type = cpl_image_get_type(spectrum);
310 
311  /* Read input spectrum geometry */
312  nbins = cpl_image_get_size_x(spectrum);
313  ny = cpl_image_get_size_y(spectrum);
314 
315  assure( cpl_image_get_size_x(spectrum_noise) == nbins &&
316  cpl_image_get_size_y(spectrum_noise) == ny,
317  CPL_ERROR_INCOMPATIBLE_INPUT,
318  "Incompatible spectrum/noise image sizes: %dx%d vs. %" CPL_SIZE_FORMAT "x%" CPL_SIZE_FORMAT "",
319  nbins, ny,
320  cpl_image_get_size_x(spectrum_noise),
321  cpl_image_get_size_y(spectrum_noise) );
322 
323  assure( ny % n_traces == 0, CPL_ERROR_INCOMPATIBLE_INPUT,
324  "Spectrum image height (%d) is not a multiple of "
325  "the number of traces (%d). Confused, bailing out",
326  ny, n_traces);
327 
328  norders = ny / n_traces;
329 
330  check( wavestep = uves_pfits_get_cdelt1(spectrum_header),
331  "Error reading bin width");
332 
333  /* Get data pointers (for efficiency) */
334 
335  if (type == CPL_TYPE_DOUBLE) {
336  spectrum_data_double = cpl_image_get_data_double_const(spectrum);
337  }
338  else {
339  spectrum_data_float = cpl_image_get_data_float_const(spectrum);
340  }
341 
342  spectrum_sx=cpl_image_get_size_x(spectrum);
343  spectrum_sy=cpl_image_get_size_y(spectrum);
344 
345  spectrum_badmap = cpl_image_get_bpm_const(spectrum);
346  spectrum_bad = cpl_mask_get_data_const(spectrum_badmap);
347 
348  if (type == CPL_TYPE_DOUBLE) {
349  noise_data_double = cpl_image_get_data_double_const(spectrum_noise);
350  }
351  else {
352  noise_data_float = cpl_image_get_data_float_const(spectrum_noise);
353  }
354  noise_badmap = cpl_image_get_bpm_const(spectrum_noise);
355  noise_bad = cpl_mask_get_data_const(noise_badmap);
356  uves_msg("delt1=%f delt2=%f",delt1,delt2);
357  /* Read max/min lambda */
358  for (order = 1; order <= norders; order++)
359  {
360  double wstart, wend;
361  check( wstart = uves_pfits_get_wstart(spectrum_header, order),
362  "Error reading start wavelength for order #%d", order);
363 
364  check( wend = uves_pfits_get_wend(spectrum_header, order),
365  "Error reading end wavelength for order #%d", order);
366 
367  uves_msg_debug("Order #%d: wstart - wend = %f - %f wlu", order, wstart, wend);
368 
369  //wstart+=delt1;
370  //wend-=delt2;
371 
372  if (order == 1)
373  {
374  bin_min = uves_round_double(wstart/wavestep);
375  bin_max = uves_round_double(wend /wavestep);
376  }
377 
378  bin_min = uves_min_int(bin_min, uves_round_double(wstart/wavestep));
379  bin_max = uves_max_int(bin_max, uves_round_double(wend /wavestep));
380  }
381  total_bins = (bin_max - bin_min) + 1;
382 
383  uves_msg_debug("Merging orders into %d bins covering wavelengths %.3f - %.3f wlu",
384  total_bins, bin_min * wavestep, bin_max * wavestep);
385 
386  /* Initialize spectrum to zero and noise to negative */
387  if(m_method == MERGE_NOAPPEND) {
388  merged = cpl_image_new(total_bins, n_traces*norders, type);
389  *merged_noise = cpl_image_new(total_bins, n_traces*norders, type);
390  } else {
391  merged = cpl_image_new(total_bins, n_traces, type);
392  *merged_noise = cpl_image_new(total_bins, n_traces, type);
393  }
394  cpl_image_add_scalar(*merged_noise, -1.0);
395  //cpl_image_power(spectrum_noise,0.5);
396  //cpl_image_multiply_scalar(spectrum_noise,0.25);
397  /* Distribute input in output bins */
398  for (order = 1; order <= norders; order++)
399  {
400  double wstart, wend;
401  int wstart_bin, wend_bin; /* In 1d space */
402 
403 
404 
405  check( wstart = uves_pfits_get_wstart(spectrum_header, order),
406  "Error reading start wavelength for order #%d", order);
407 
408  check( wend = uves_pfits_get_wend(spectrum_header, order),
409  "Error reading end wavelength for order #%d", order);
410 
411  //wstart+=delt1;
412  //wend-=delt2;
413 
414  wstart_bin = uves_round_double(wstart/wavestep);
415  wend_bin = uves_round_double(wend/wavestep);
416  delt1_bin = uves_round_double(delt1/wavestep);
417  delt2_bin = uves_round_double(delt2/wavestep);
418 
419 
420  int bin_min_ord = uves_round_double(wstart/wavestep);
421  int bin_max_ord = uves_round_double(wend /wavestep);
422  int nbins_ord = (bin_max_ord - bin_min_ord) + 1;
423  cpl_image* merged_ord=NULL;
424  cpl_image * noise_ord=NULL;
425 
426  if(m_method == MERGE_NOAPPEND) {
427  merged_ord = cpl_image_new(nbins_ord, n_traces, type);
428  noise_ord = cpl_image_new(nbins_ord, n_traces, type);
429  }
430 
431  //if(order>1 && order<norders) {
432  // med_noise=cpl_image_get_median_window(spectrum_noise,
433  // 1,order,ny,order);
434  //} else {
435  // med_noise=cpl_image_get_median(spectrum_noise);
436  //}
437  /* Loop over spatial traces (only 1 trace, unless extraction was 2d) */
438  for (trace = 1; trace <= n_traces; trace++)
439  {
440  int merged_row = 0;
441  int spectrum_row = (order - 1)*n_traces + trace;
442  if(m_method == MERGE_NOAPPEND) {
443  merged_row = (order - 1)*n_traces + trace;
444  } else {
445  merged_row = trace;
446 
447  }
448  int rel_bin; /* Counting columns in input spectrum */
449 
450  for (rel_bin = 1+delt1_bin;
451  (rel_bin <= wend_bin - wstart_bin + 1-delt2_bin) &&
452  (rel_bin <(spectrum_sx*spectrum_sy+1-(spectrum_row-1)*nbins));
453  rel_bin++)
454  {
455  double flux, noise;
456  double current_flux, new_flux;
457  double current_noise, new_noise;
458  double weight;
459  int pis_rejected, noise_rejected;
460 
461  /* merged_bin = (offset of order) + (offset inside order) */
462  int merged_bin = (wstart_bin - bin_min) + rel_bin;
463  int merged_bin_ord = rel_bin;
464 
465  passure(1 <= merged_bin && merged_bin <= total_bins,
466  "%d %d %d", rel_bin, merged_bin, total_bins);
467 
468  /* This is slow:
469  check( flux = cpl_image_get(spectrum ,
470  rel_bin, spectrum_row, &pis_rejected);
471  noise = cpl_image_get(spectrum_noise, rel_bin,
472  spectrum_row, &noise_rejected),
473  "Error reading input spectrum");
474  */
475 
476  if (type == CPL_TYPE_DOUBLE) {
477  flux = spectrum_data_double[(rel_bin-1) + (spectrum_row-1) * nbins];
478  noise = noise_data_double [(rel_bin-1) + (spectrum_row-1) * nbins];
479 
480  }
481  else {
482  flux = spectrum_data_float[(rel_bin-1) + (spectrum_row-1) * nbins];
483  noise = noise_data_float [(rel_bin-1) + (spectrum_row-1) * nbins];
484  }
485 
486  pis_rejected = spectrum_bad[(rel_bin-1) + (spectrum_row-1) * nbins];
487  noise_rejected = noise_bad [(rel_bin-1) + (spectrum_row-1) * nbins];
488 
489  if (!pis_rejected && !noise_rejected)
490  {
491 
492  if(m_method == MERGE_NOAPPEND) {
493  check(( current_flux = cpl_image_get(merged,
494  merged_bin,
495  merged_row,
496  &pis_rejected),
497  current_noise = cpl_image_get(*merged_noise,
498  merged_bin,
499  merged_row,
500  &pis_rejected)),
501  "Error reading merged spetrum");
502  } else {
503  check(( current_flux = cpl_image_get(
504  merged , merged_bin, trace, &pis_rejected),
505  current_noise = cpl_image_get(
506  *merged_noise, merged_bin, trace, &pis_rejected)),
507  "Error reading merged spetrum");
508  }
509  weight = 1/(noise*noise);
510 
511  /*
512  * Optimal formulas for Variance and Flux are
513  *
514  * Vn = ( 1/sigma1^2 + ... + 1/sigmaN^2)^-1
515  * Fn = (f1/sigma1^2 + ... + fN/sigmaN^2) * Vn
516  *
517  * Update by using these recurrence relations
518  *
519  * Fn+1 = (Fn/Vn + fn+1/(sigma_{n+1})^2) * Vn+1 for n > 1
520  * Vn+1 = (Vn^-1 + 1/(sigma_{n+1})^2)^-1 for n > 1
521  *
522  *
523  * In the case of method = sum,
524  *
525  * Vn = sigma1^2 + ... + sigmaN^2
526  * Fn = f1 + ... + fN
527  *
528  */
529 
530  if (current_noise > 0)
531  {
532  if (m_method == MERGE_OPTIMAL)
533  {
534  new_noise = 1/(current_noise*current_noise);
535  new_noise += weight;
536  new_noise = 1/sqrt(new_noise);
537  }
538  else if (m_method == MERGE_SUM)
539  {
540  new_noise = sqrt(current_noise*current_noise
541  + noise*noise);
542  }
543  else if (m_method == MERGE_NOAPPEND)
544  {
545  new_noise = current_noise;
546  }
547  else
548  {
549  /* Impossible */
550  passure( false, "%d", m_method);
551  }
552  }
553  else
554  {
555  /* First time in this bin */
556  new_noise = noise;
557  }
558 
559  if (current_noise > 0)
560  {
561  if (m_method == MERGE_OPTIMAL)
562  {
563  new_flux = (current_flux /
564  (current_noise*current_noise)
565  + flux * weight) *
566  (new_noise*new_noise);
567  }
568  else if (m_method == MERGE_SUM)
569  {
570  new_flux = current_flux + flux;
571  }
572  else if (m_method == MERGE_NOAPPEND)
573  {
574  new_flux = flux;
575  }
576  else
577  {
578  /* Impossible */
579  passure( false, "%d", m_method);
580  }
581  }
582  else
583  {
584  new_flux = flux;
585  }
586 
587  if(m_method == MERGE_NOAPPEND) {
588 
589  /*
590  uves_msg_warning("flux[%d,%d]=%g noise=%g",
591  merged_bin,merged_row,
592  new_flux,current_noise);
593  */
594  check( cpl_image_set(
595  merged,
596  merged_bin,
597  merged_row,
598  new_flux),
599  "Error updating merged spectrum");
600 
601  check( cpl_image_set(
602  *merged_noise,
603  merged_bin,
604  merged_row,
605  new_noise),
606  "Error updating weights");
607 
608 
609  check( cpl_image_set(
610  merged_ord,
611  merged_bin_ord,
612  trace,
613  new_flux),
614  "Error updating merged spectrum");
615 
616  check( cpl_image_set(
617  noise_ord,
618  merged_bin_ord,
619  trace,
620  new_noise),
621  "Error updating merged spectrum");
622 
623 
624  } else {
625  check( cpl_image_set(
626  merged , merged_bin, trace, new_flux),
627  "Error updating merged spectrum");
628  check( cpl_image_set(
629  *merged_noise, merged_bin, trace, new_noise),
630  "Error updating weights");
631  }
632 /* uves_msg("Input flux = %e +- %e ;
633  Binned flux changed from %e +- %e to %e +- %e",
634  flux, noise,
635  current_flux, current_noise, new_flux, new_noise);*/
636 
637  } /* If pixel is good ... */
638 
639  } /* For each input bin */
640 
641  }/* For trace ... */
642 
643 
644  if (merged_header == NULL)
645  {
646  uves_free_propertylist(merged_header);
647  check( *merged_header = uves_initialize_image_header(
648  "AWAV", (n_traces > 1) ? "PIXEL" : " ",
649  "Angstrom", (n_traces > 1) ? "PIXEL" : NULL,
650  "ADU",0,
651  bin_min_ord * wavestep, 1.0,
652  1.0, 1.0,
653  wavestep, 1.0),
654  "Error initializing merged spectrum header");
655  }
656 
657  if(m_method == MERGE_NOAPPEND) {
658  filename=uves_sprintf("merged_data_noappend_%s.fits",
660  image_1d = cpl_vector_wrap(cpl_image_get_size_x(merged_ord),
661  cpl_image_get_data_double(merged_ord));
662  uves_free_propertylist(&hext);
663  hext=uves_propertylist_new();
664  uves_propertylist_append_double(hext,"CRVAL1",wstart-delt1);
665  uves_propertylist_append_double(hext,"CDELT1",wavestep);
666  uves_propertylist_append_double(hext,"CRPIX1",0);
667 
668  if(order==1) {
669  uves_vector_save(image_1d,filename,CPL_BPP_IEEE_FLOAT,hext,
670  CPL_IO_DEFAULT);
671  } else {
672  uves_vector_save(image_1d,filename,CPL_BPP_IEEE_FLOAT,hext,
673  CPL_IO_EXTEND);
674  }
675  cpl_vector_unwrap(image_1d);
676 
677  image_1d = cpl_vector_wrap(cpl_image_get_size_x(noise_ord),
678  cpl_image_get_data_double(noise_ord));
679 
680  uves_free(filename);
681 
682  filename=uves_sprintf("merged_sigma_noappend_%s.fits",
684  if(order==1) {
685  uves_vector_save(image_1d,filename,CPL_BPP_IEEE_FLOAT,hext,
686  CPL_IO_DEFAULT);
687  } else {
688  uves_vector_save(image_1d,filename,CPL_BPP_IEEE_FLOAT,hext,
689  CPL_IO_EXTEND);
690  }
691  cpl_vector_unwrap(image_1d);
692 
693  uves_free(filename);
694  uves_free_image(&merged_ord);
695  uves_free_image(&noise_ord);
696  uves_free_propertylist(&hext);
697  uves_free_propertylist(merged_header);
698  }
699 
700  }/* For order ... */
701 
702  /* Undefined bins have (flux, noise) = (0, -1) (the initial values).
703  * Set to (flux, noise) = (0, 1)
704  */
705 
706 /* Here commented out piece of code to be used eventually to have
707  noappend files files as products
708  if(m_method == MERGE_NOAPPEND) {
709  cpl_frame* mdata_noappend=NULL;
710  cpl_frame* msigma_noappend=NULL;
711  mdata_noappend=cpl_frame_new();
712  msigma_noappend=cpl_frame_new();
713  cpl_frame_set_group(mdata_noappend,CPL_FRAME_GROUP_PRODUCT);
714  cpl_frame_set_type(mdata_noappend,CPL_FRAME_TYPE_IMAGE);
715  cpl_frame_set_level(mdata_noappend,CPL_FRAME_LEVEL_FINAL);
716 
717  tag=uves_sprintf("MERGED_SCI_NOAPPEND_%s",
718  uves_chip_tostring_upper(chip));
719  filename=uves_sprintf("%s_%s.fits",tag,uves_chip_tostring_upper(chip));
720  cpl_frame_set_tag(mdata_noappend,tag);
721  cpl_frame_set_filename(mdata_noappend,filename);
722  uves_free(filename);
723  uves_free(tag);
724 
725  cpl_frame_set_group(msigma_noappend,CPL_FRAME_GROUP_PRODUCT);
726  cpl_frame_set_type(msigma_noappend,CPL_FRAME_TYPE_IMAGE);
727  cpl_frame_set_level(msigma_noappend,CPL_FRAME_LEVEL_FINAL);
728 
729  tag=uves_sprintf("MERGED_ERR_NOAPPEND_%s",
730  uves_chip_tostring_upper(chip));
731  filename=uves_sprintf("%s_%s.fits",tag,uves_chip_tostring_upper(chip));
732  cpl_frame_set_tag(msigma_noappend,tag);
733  cpl_frame_set_filename(msigma_noappend,filename);
734 
735  uves_free_frame(&mdata_noappend);
736  uves_free_frame(&msigma_noappend);
737  uves_free(filename);
738  uves_free(tag);
739 
740  }
741 */
742  check( cpl_image_threshold(*merged_noise,
743  0, DBL_MAX, /* Outside this interval */
744  1, 1), /* Set to these values */
745  "Error setting undefined noise");
746 
747 
748  if (merged_header != NULL)
749  {
750  check( *merged_header = uves_initialize_image_header(
751  "AWAV", (n_traces > 1) ? "PIXEL" : " ",
752  "Angstrom", (n_traces > 1) ? "PIXEL" : NULL,
753  "ADU",0,
754  bin_min * wavestep, 1.0,
755  1.0, 1.0,
756  wavestep, 1.0),
757  "Error initializing merged spectrum header");
758  }
759 
760 
761  cleanup:
762  return merged;
763 }
764 
765 /*---------------------------------------------------------------------------*/
775 /*---------------------------------------------------------------------------*/
776 merge_method
777 uves_get_merge_method(const cpl_parameterlist *parameters,
778  const char *context,
779  const char *subcontext)
780 {
781  const char *mm = "";
782  merge_method result = 0;
783 
784  check( uves_get_parameter(parameters, context, subcontext, "merge", CPL_TYPE_STRING, &mm),
785  "Could not read parameter");
786 
787  if (strcmp(mm, "optimal") == 0) result = MERGE_OPTIMAL;
788  else if (strcmp(mm, "sum" ) == 0) result = MERGE_SUM;
789  else if (strcmp(mm, "noappend") == 0) result = MERGE_NOAPPEND;
790  else
791  {
792  assure(false, CPL_ERROR_ILLEGAL_INPUT, "No such merging method: '%s'", mm);
793  }
794 
795  cleanup:
796  return result;
797 }
798 
799