189 #include <uves_merge.h>
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>
240 const cpl_image *spectrum_noise,
242 merge_method m_method,
248 cpl_image **merged_noise)
250 cpl_image *merged = NULL;
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;
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;
263 int nbins, ny, norders;
265 int bin_min = 0, bin_max = 0;
274 cpl_vector* image_1d=NULL;
277 passure( spectrum != NULL,
" ");
278 passure( spectrum_noise != NULL,
" ");
279 passure( spectrum_header != NULL,
" ");
280 passure( merged_header != NULL,
" ");
281 passure( merged_noise != NULL,
" ");
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);
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'",
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'",
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",
309 type = cpl_image_get_type(spectrum);
312 nbins = cpl_image_get_size_x(spectrum);
313 ny = cpl_image_get_size_y(spectrum);
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
"",
320 cpl_image_get_size_x(spectrum_noise),
321 cpl_image_get_size_y(spectrum_noise) );
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",
328 norders = ny / n_traces;
331 "Error reading bin width");
335 if (type == CPL_TYPE_DOUBLE) {
336 spectrum_data_double = cpl_image_get_data_double_const(spectrum);
339 spectrum_data_float = cpl_image_get_data_float_const(spectrum);
342 spectrum_sx=cpl_image_get_size_x(spectrum);
343 spectrum_sy=cpl_image_get_size_y(spectrum);
345 spectrum_badmap = cpl_image_get_bpm_const(spectrum);
346 spectrum_bad = cpl_mask_get_data_const(spectrum_badmap);
348 if (type == CPL_TYPE_DOUBLE) {
349 noise_data_double = cpl_image_get_data_double_const(spectrum_noise);
352 noise_data_float = cpl_image_get_data_float_const(spectrum_noise);
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);
358 for (order = 1; order <= norders; order++)
362 "Error reading start wavelength for order #%d", order);
365 "Error reading end wavelength for order #%d", order);
367 uves_msg_debug(
"Order #%d: wstart - wend = %f - %f wlu", order, wstart, wend);
374 bin_min = uves_round_double(wstart/wavestep);
375 bin_max = uves_round_double(wend /wavestep);
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));
381 total_bins = (bin_max - bin_min) + 1;
383 uves_msg_debug(
"Merging orders into %d bins covering wavelengths %.3f - %.3f wlu",
384 total_bins, bin_min * wavestep, bin_max * wavestep);
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);
391 merged = cpl_image_new(total_bins, n_traces, type);
392 *merged_noise = cpl_image_new(total_bins, n_traces, type);
394 cpl_image_add_scalar(*merged_noise, -1.0);
398 for (order = 1; order <= norders; order++)
401 int wstart_bin, wend_bin;
406 "Error reading start wavelength for order #%d", order);
409 "Error reading end wavelength for order #%d", order);
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);
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;
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);
438 for (trace = 1; trace <= n_traces; trace++)
441 int spectrum_row = (order - 1)*n_traces + trace;
442 if(m_method == MERGE_NOAPPEND) {
443 merged_row = (order - 1)*n_traces + trace;
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));
456 double current_flux, new_flux;
457 double current_noise, new_noise;
459 int pis_rejected, noise_rejected;
462 int merged_bin = (wstart_bin - bin_min) + rel_bin;
463 int merged_bin_ord = rel_bin;
465 passure(1 <= merged_bin && merged_bin <= total_bins,
466 "%d %d %d", rel_bin, merged_bin, total_bins);
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];
482 flux = spectrum_data_float[(rel_bin-1) + (spectrum_row-1) * nbins];
483 noise = noise_data_float [(rel_bin-1) + (spectrum_row-1) * nbins];
486 pis_rejected = spectrum_bad[(rel_bin-1) + (spectrum_row-1) * nbins];
487 noise_rejected = noise_bad [(rel_bin-1) + (spectrum_row-1) * nbins];
489 if (!pis_rejected && !noise_rejected)
492 if(m_method == MERGE_NOAPPEND) {
493 check(( current_flux = cpl_image_get(merged,
497 current_noise = cpl_image_get(*merged_noise,
501 "Error reading merged spetrum");
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");
509 weight = 1/(noise*noise);
530 if (current_noise > 0)
532 if (m_method == MERGE_OPTIMAL)
534 new_noise = 1/(current_noise*current_noise);
536 new_noise = 1/sqrt(new_noise);
538 else if (m_method == MERGE_SUM)
540 new_noise = sqrt(current_noise*current_noise
543 else if (m_method == MERGE_NOAPPEND)
545 new_noise = current_noise;
550 passure(
false,
"%d", m_method);
559 if (current_noise > 0)
561 if (m_method == MERGE_OPTIMAL)
563 new_flux = (current_flux /
564 (current_noise*current_noise)
566 (new_noise*new_noise);
568 else if (m_method == MERGE_SUM)
570 new_flux = current_flux + flux;
572 else if (m_method == MERGE_NOAPPEND)
579 passure(
false,
"%d", m_method);
587 if(m_method == MERGE_NOAPPEND) {
594 check( cpl_image_set(
599 "Error updating merged spectrum");
601 check( cpl_image_set(
606 "Error updating weights");
609 check( cpl_image_set(
614 "Error updating merged spectrum");
616 check( cpl_image_set(
621 "Error updating merged spectrum");
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");
644 if (merged_header == NULL)
646 uves_free_propertylist(merged_header);
648 "AWAV", (n_traces > 1) ?
"PIXEL" :
" ",
649 "Angstrom", (n_traces > 1) ?
"PIXEL" : NULL,
651 bin_min_ord * wavestep, 1.0,
654 "Error initializing merged spectrum header");
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);
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);
669 uves_vector_save(image_1d,filename,CPL_BPP_IEEE_FLOAT,hext,
672 uves_vector_save(image_1d,filename,CPL_BPP_IEEE_FLOAT,hext,
675 cpl_vector_unwrap(image_1d);
677 image_1d = cpl_vector_wrap(cpl_image_get_size_x(noise_ord),
678 cpl_image_get_data_double(noise_ord));
682 filename=uves_sprintf(
"merged_sigma_noappend_%s.fits",
685 uves_vector_save(image_1d,filename,CPL_BPP_IEEE_FLOAT,hext,
688 uves_vector_save(image_1d,filename,CPL_BPP_IEEE_FLOAT,hext,
691 cpl_vector_unwrap(image_1d);
694 uves_free_image(&merged_ord);
695 uves_free_image(&noise_ord);
696 uves_free_propertylist(&hext);
697 uves_free_propertylist(merged_header);
742 check( cpl_image_threshold(*merged_noise,
745 "Error setting undefined noise");
748 if (merged_header != NULL)
751 "AWAV", (n_traces > 1) ?
"PIXEL" :
" ",
752 "Angstrom", (n_traces > 1) ?
"PIXEL" : NULL,
754 bin_min * wavestep, 1.0,
757 "Error initializing merged spectrum header");
779 const char *subcontext)
782 merge_method result = 0;
784 check( uves_get_parameter(parameters, context, subcontext,
"merge", CPL_TYPE_STRING, &mm),
785 "Could not read parameter");
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;
792 assure(
false, CPL_ERROR_ILLEGAL_INPUT,
"No such merging method: '%s'", mm);
#define passure(BOOL,...)
double uves_pfits_get_wstart(const uves_propertylist *plist, int order)
Read the wstart keyword.
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.
uves_propertylist * uves_propertylist_new(void)
Create an empty property list.
#define uves_msg(...)
Print a message on 'info' or 'debug' level.
merge_method uves_get_merge_method(const cpl_parameterlist *parameters, const char *context, const char *subcontext)
Read merging method from parameter list.
const char * uves_tostring_cpl_type(cpl_type t)
Convert a CPL type to a string.
cpl_image * uves_merge_orders(const cpl_image *spectrum, const cpl_image *spectrum_noise, const uves_propertylist *spectrum_header, merge_method m_method, int n_traces, uves_propertylist **merged_header, const double delt1, const double delt2, enum uves_chip chip, cpl_image **merged_noise)
Merge orders.
#define uves_msg_debug(...)
Print a debug message.
const char * uves_chip_tostring_upper(enum uves_chip chip)
Convert to string.
double uves_pfits_get_cdelt1(const uves_propertylist *plist)
Find out the cdelt1.
double uves_pfits_get_wend(const uves_propertylist *plist, int order)
Read the wend keyword.