32#include "cr2res_dfs.h"
33#include "cr2res_utils.h"
34#include "cr2res_trace.h"
35#include "cr2res_splice.h"
43int cr2res_combine_spectra(cpl_bivector * spliced[],
44 cpl_bivector * spliced_err[],
45 cpl_vector * spectrum_order,
48 cpl_bivector ** spectrum,
49 cpl_bivector ** spectrum_err);
51int cr2res_extract_data(
52 cpl_table * trace_wave,
77 cpl_table ** extracted_1d,
79 cpl_table ** trace_wave,
81 cpl_bivector ** spliced,
82 cpl_bivector ** spliced_err)
84 int i, j, k, nspectra, nb_order_idx_values, nb_traces, success;
92 cpl_bivector ** sp_err;
93 cpl_vector * sp_order;
105 for (i = 0; i < ninputs; i++){
106 nspectra += cpl_table_get_nrow(trace_wave[i]);
125 cpl_msg_info(__func__,
"Number of segments: %i", nspectra);
129 wave = cpl_malloc(nspectra *
sizeof(cpl_vector *));
130 spec = cpl_malloc(nspectra *
sizeof(cpl_vector *));
131 uncs = cpl_malloc(nspectra *
sizeof(cpl_vector *));
132 cont = cpl_malloc(nspectra *
sizeof(cpl_vector *));
136 for (i = 0; i < ninputs; i++){
137 int * order_idx_values;
139 &nb_order_idx_values);
140 for (j = 0; j < nb_order_idx_values; j++) {
142 order_idx_values[j], &nb_traces);
143 for (k = 0; k < nb_traces; k++) {
145 cr2res_extract_data(trace_wave[i], blaze[i],
146 extracted_1d[i], order_idx_values[j],
147 traces[k], &wave[count], &spec[count],
148 &uncs[count], &cont[count]);
178 cpl_free(order_idx_values);
182 cpl_msg_info(__func__,
"%i segments with data found", nspectra);
185 cr2res_splice_orders(wave, spec, uncs, cont, nspectra, &sp, &sp_err,
186 &sp_order, &first, &last);
189 cr2res_combine_spectra(sp, sp_err, sp_order, last, nspectra, spliced,
192 cpl_bivector_delete(first);
193 cpl_bivector_delete(last);
194 cpl_vector_delete(sp_order);
196 for (i = 0; i < nspectra; i++){
197 cpl_bivector_delete(sp[i]);
198 cpl_bivector_delete(sp_err[i]);
204 for (i = 0; i < nspectra; i++){
207 cpl_vector_delete(wave[i]);
208 cpl_vector_unwrap(spec[i]);
209 cpl_vector_unwrap(uncs[i]);
210 cpl_vector_unwrap(cont[i]);
217 if (cpl_error_get_code() == CPL_ERROR_DIVISION_BY_ZERO){
218 cpl_msg_warning(__func__,
219 "Division by Zero encountered. Resetting Error State");
226int cr2res_extract_data(
227 cpl_table * trace_wave,
237 int j, k, n = CR2RES_DETECTOR_SIZE;
238 const cpl_array * wave1;
239 cpl_polynomial * wave_poly;
250 wave1 = cpl_table_get_array(trace_wave, CR2RES_COL_WAVELENGTH, j);
252 cpl_msg_warning(__func__,
"Order %i, Trace %i", order_idx, trace);
253 cpl_msg_warning(__func__,
"Wavelength Array not set");
257 *wave = cpl_vector_new(n);
258 for (k = 0; k < n; k++)
259 cpl_vector_set(*wave, k, cpl_polynomial_eval_1d(wave_poly, k, NULL));
260 cpl_polynomial_delete(wave_poly);
264 tmp1 = cpl_table_get_data_double(spectra, colname);
268 cpl_msg_warning(__func__,
"Order %i, Trace %i", order_idx, trace);
269 cpl_msg_warning(__func__,
"Spectrum not set");
270 cpl_vector_delete(*wave);
273 *spec = cpl_vector_wrap(n, tmp1);
278 tmp1 = cpl_table_get_data_double(spectra, colname);
281 cpl_msg_warning(__func__,
"Order %i, Trace %i", order_idx, trace);
282 cpl_msg_warning(__func__,
"Error not set");
283 cpl_vector_delete(*wave);
284 cpl_vector_unwrap(*spec);
287 *uncs = cpl_vector_wrap(n, tmp1);
291 tmp1 = cpl_table_get_data_double(blaze, colname);
294 cpl_msg_warning(__func__,
"Order %i, Trace %i", order_idx, trace);
295 cpl_msg_warning(__func__,
"Blaze not set");
296 cpl_vector_delete(*wave);
297 cpl_vector_unwrap(*spec);
298 cpl_vector_unwrap(*uncs);
301 *cont = cpl_vector_wrap(n, tmp1);
307int cr2res_combine_spectra(
308 cpl_bivector * spliced[],
309 cpl_bivector * spliced_err[],
310 cpl_vector * spectrum_order,
313 cpl_bivector ** spectrum,
314 cpl_bivector ** spectrum_err)
317 if (spliced == NULL || spliced_err == NULL || nspectra <= 0 ||
318 spectrum == NULL || spectrum_err == NULL || spectrum_order == NULL)
323 *spectrum = cpl_bivector_new(nspectra * CR2RES_DETECTOR_SIZE);
324 *spectrum_err = cpl_bivector_new(nspectra * CR2RES_DETECTOR_SIZE);
326 for (i = 0; i < nspectra; i++){
330 iord = cpl_vector_get(spectrum_order, i);
333 lx = cpl_bivector_get_x_data(last)[iord] + 1;
335 ly = cpl_bivector_get_y_data(last)[iord] + 1;
341 if (i == nspectra-1){
343 ly = CR2RES_DETECTOR_SIZE;
345 cpl_msg_debug(__func__,
"lx: %i, ly: %i", lx, ly);
348 for (j = lx; j < ly; j++){
349 cpl_vector_set(cpl_bivector_get_x(*spectrum), k,
350 cpl_vector_get(cpl_bivector_get_x(spliced[iord]), j));
351 cpl_vector_set(cpl_bivector_get_y(*spectrum), k,
352 cpl_vector_get(cpl_bivector_get_y(spliced[iord]), j));
354 cpl_vector_set(cpl_bivector_get_x(*spectrum_err), k,
355 cpl_vector_get(cpl_bivector_get_x(spliced_err[iord]), j));
356 cpl_vector_set(cpl_bivector_get_y(*spectrum_err), k,
357 cpl_vector_get(cpl_bivector_get_y(spliced_err[iord]), j));
364 cpl_vector_set_size(cpl_bivector_get_x(*spectrum), k-1);
365 cpl_vector_set_size(cpl_bivector_get_y(*spectrum), k-1);
367 cpl_vector_set_size(cpl_bivector_get_x(*spectrum_err), k-1);
368 cpl_vector_set_size(cpl_bivector_get_y(*spectrum_err), k-1);
391int cr2res_splice_orders(
397 cpl_bivector ** spliced[],
398 cpl_bivector ** spliced_err[],
399 cpl_vector ** spectrum_order,
400 cpl_bivector ** first,
401 cpl_bivector ** last)
403 if (wave == NULL || spec == NULL || cont == NULL || uncs == NULL
404 || spliced == NULL || spliced_err == NULL || nspectra <= 0
405 || spectrum_order == NULL || first == NULL || last == NULL)
return -1;
409 int n = CR2RES_DETECTOR_SIZE;
412 cpl_bivector * wave_center;
413 cpl_vector *tmpS0, *tmpS1;
414 cpl_vector *tmpU0, *tmpU1;
415 cpl_vector *tmpW0, *tmpW1;
416 cpl_vector *tmpC0, *tmpC1;
417 cpl_bivector * tmp2, * tmp3;
419 loop0 = cpl_malloc((nspectra-1) *
sizeof(
int));
420 loop1 = cpl_malloc((nspectra-1) *
sizeof(
int));
422 *spliced = cpl_malloc(nspectra *
sizeof(cpl_bivector*));
423 *spliced_err = cpl_malloc(nspectra *
sizeof(cpl_bivector*));
424 *first = cpl_bivector_new(nspectra);
425 *last = cpl_bivector_new(nspectra);
428 for (i = 0; i < nspectra; i++){
429 (*spliced)[i] = cpl_bivector_new(n);
430 (*spliced_err)[i] = cpl_bivector_new(n);
432 wave_center = cpl_bivector_new(nspectra);
435 for (i=0; i<nspectra; i++){
441 cpl_vector_set(cpl_bivector_get_x(wave_center), i, i);
442 cpl_vector_set(cpl_bivector_get_y(wave_center), i,
443 cpl_vector_get(wave[i], n/2));
448 tmp4 = cpl_vector_duplicate(spec[i]);
449 for (j=0; j < n; j++)
451 if (isfinite(cpl_vector_get(spec[i], j)) == 0){
452 cpl_vector_set(tmp4, j, 0);
453 cpl_vector_set(spec[i], j, 0);
455 if (isfinite(cpl_vector_get(uncs[i], j)) == 0){
456 cpl_vector_set(uncs[i], j, 1);
458 if ((cpl_vector_get(cont[i], j) == 0) | (isfinite(cpl_vector_get(cont[i], j)) == 0)){
459 cpl_vector_set(cont[i], j, 1);
461 cpl_vector_set(tmp4, j,
462 cpl_vector_get(tmp4, j) / cpl_vector_get(cont[i], j));
465 median = cpl_vector_get_median(tmp4);
466 cpl_vector_multiply_scalar(cont[i], median);
467 cpl_vector_delete(tmp4);
471 cpl_bivector_sort(wave_center, wave_center, CPL_SORT_ASCENDING,
475 for (i = 0; i < nspectra-1; i++){
476 loop0[i] = cpl_bivector_get_x_data(wave_center)[i];
477 loop1[i] = cpl_bivector_get_x_data(wave_center)[i+1];
480 for (i=0; i < nspectra-1; i++){
483 int first0, first1, last0, last1, overlap0, overlap1;
484 cpl_size minW0pos, minW1pos, maxW0pos, maxW1pos;
486 double minW0, minW1, maxW0, maxW1;
510 minW1pos = cpl_vector_get_minpos(w1);
511 minW0pos = cpl_vector_get_minpos(w0);
512 maxW1pos = cpl_vector_get_maxpos(w1);
513 maxW0pos = cpl_vector_get_maxpos(w0);
515 while (cpl_vector_get(s1, minW1pos) == 0) minW1pos++;
516 while (cpl_vector_get(s0, minW0pos) == 0) minW0pos++;
517 while (cpl_vector_get(s1, maxW1pos) == 0) maxW1pos--;
518 while (cpl_vector_get(s0, maxW0pos) == 0) maxW0pos--;
520 minW1 = cpl_vector_get(w1, minW1pos);
521 minW0 = cpl_vector_get(w0, minW0pos);
522 maxW1 = cpl_vector_get(w1, maxW1pos);
523 maxW0 = cpl_vector_get(w0, maxW0pos);
535 for (j = 0; j < cpl_vector_get_size(w0); j++){
536 if ((cpl_vector_get(w0, j) >= minW1) & (cpl_vector_get(w0, j) <= maxW1)){
538 if (first0 == -1) first0 = j;
546 for (j = 0; j < cpl_vector_get_size(w1); j++){
547 if ((cpl_vector_get(w1, j) >= minW0) & (cpl_vector_get(w1, j) <= maxW0)){
549 if (first1 == -1) first1 = j;
555 cpl_msg_debug(__func__,
"Overlap: %i, %i", overlap0, overlap1);
556 if (overlap0 == 0 || overlap1 == 0){
557 cpl_vector_set(cpl_bivector_get_y(*first), iord0, CR2RES_DETECTOR_SIZE);
558 cpl_vector_set(cpl_bivector_get_y(*last), iord0, maxW0pos-1);
559 cpl_vector_set(cpl_bivector_get_x(*first), iord1, 0);
560 cpl_vector_set(cpl_bivector_get_x(*last), iord1, minW1pos-1);
562 for (k = 0; k < CR2RES_DETECTOR_SIZE; k++){
563 cpl_vector_set(cpl_bivector_get_x((*spliced)[iord0]), k,
564 cpl_vector_get(w0, k));
565 cpl_vector_set(cpl_bivector_get_x((*spliced)[iord1]), k,
566 cpl_vector_get(w1, k));
568 cpl_vector_set(cpl_bivector_get_x((*spliced_err)[iord0]), k,
569 cpl_vector_get(w0, k));
570 cpl_vector_set(cpl_bivector_get_x((*spliced_err)[iord1]), k,
571 cpl_vector_get(w1, k));
574 cpl_vector_set(cpl_bivector_get_y((*spliced)[iord0]), k,
575 cpl_vector_get(s0, k));
576 cpl_vector_set(cpl_bivector_get_y((*spliced)[iord1]), k,
577 cpl_vector_get(s1, k));
579 cpl_vector_set(cpl_bivector_get_y((*spliced_err)[iord0]), k,
580 cpl_vector_get(u0, k));
581 cpl_vector_set(cpl_bivector_get_y((*spliced_err)[iord1]), k,
582 cpl_vector_get(u1, k));
595 cpl_vector_set(cpl_bivector_get_y(*first), iord0, first0);
596 cpl_vector_set(cpl_bivector_get_y(*last), iord0, last0);
597 cpl_vector_set(cpl_bivector_get_x(*first), iord1, first1);
598 cpl_vector_set(cpl_bivector_get_x(*last), iord1, last1);
602 tmpW0 = cpl_vector_wrap(last0 - first0 + 1, cpl_vector_get_data(w0) + first0);
603 tmpW1 = cpl_vector_wrap(last1 - first1 + 1, cpl_vector_get_data(w1) + first1);
606 tmpS0 = cpl_vector_new(overlap0);
607 tmpU0 = cpl_vector_new(overlap0);
608 tmpC0 = cpl_vector_new(overlap0);
610 tmpS1 = cpl_vector_new(overlap1);
611 tmpU1 = cpl_vector_new(overlap1);
612 tmpC1 = cpl_vector_new(overlap1);
616 tmp3 = cpl_bivector_wrap_vectors(w1, s1);
617 tmp2 = cpl_bivector_wrap_vectors(tmpW0, tmpS0);
618 cpl_bivector_interpolate_linear(tmp2, tmp3);
619 cpl_bivector_unwrap_vectors(tmp3);
620 cpl_bivector_unwrap_vectors(tmp2);
622 tmp3 = cpl_bivector_wrap_vectors(w0, s0);
623 tmp2 = cpl_bivector_wrap_vectors(tmpW1, tmpS1);
624 cpl_bivector_interpolate_linear(tmp2, tmp3);
625 cpl_bivector_unwrap_vectors(tmp3);
626 cpl_bivector_unwrap_vectors(tmp2);
628 tmp3 = cpl_bivector_wrap_vectors(w1, u1);
629 tmp2 = cpl_bivector_wrap_vectors(tmpW0, tmpU0);
630 cpl_bivector_interpolate_linear(tmp2, tmp3);
631 cpl_bivector_unwrap_vectors(tmp3);
632 cpl_bivector_unwrap_vectors(tmp2);
634 tmp3 = cpl_bivector_wrap_vectors(w0, u0);
635 tmp2 = cpl_bivector_wrap_vectors(tmpW1, tmpU1);
636 cpl_bivector_interpolate_linear(tmp2, tmp3);
637 cpl_bivector_unwrap_vectors(tmp3);
638 cpl_bivector_unwrap_vectors(tmp2);
640 tmp3 = cpl_bivector_wrap_vectors(w1, c1);
641 tmp2 = cpl_bivector_wrap_vectors(tmpW0, tmpC0);
642 cpl_bivector_interpolate_linear(tmp2, tmp3);
643 cpl_bivector_unwrap_vectors(tmp3);
644 cpl_bivector_unwrap_vectors(tmp2);
646 tmp3 = cpl_bivector_wrap_vectors(w0, c0);
647 tmp2 = cpl_bivector_wrap_vectors(tmpW1, tmpC1);
648 cpl_bivector_interpolate_linear(tmp2, tmp3);
649 cpl_bivector_unwrap_vectors(tmp3);
650 cpl_bivector_unwrap_vectors(tmp2);
655 for (j=first0; j<=last0; j++){
657 wgt0 = cpl_vector_get(c0, j) / cpl_vector_get(u0, j);
659 wgt1 = cpl_vector_get(tmpC0, k) / cpl_vector_get(tmpU0, k);
662 cpl_vector_set(s0, j, (cpl_vector_get(s0, j) * wgt0
663 + cpl_vector_get(tmpS0, k) * wgt1) / (wgt0 + wgt1));
665 cpl_vector_set(c0, j, (cpl_vector_get(c0, j) * wgt0
666 + cpl_vector_get(tmpC0, k) * wgt1) / (wgt0 + wgt1));
668 cpl_vector_set(u0, j, cpl_vector_get(c0, j) / sqrt(wgt0 + wgt1));
674 for (j=first1; j<=last1; j++){
676 wgt0 = cpl_vector_get(c1, j) / cpl_vector_get(u1, j);
678 wgt1 = cpl_vector_get(tmpC1, k) / cpl_vector_get(tmpU1, k);
681 cpl_vector_set(s1, j, (cpl_vector_get(s1, j) * wgt0
682 + cpl_vector_get(tmpS1, k) * wgt1) / (wgt0 + wgt1));
684 cpl_vector_set(c1, j, (cpl_vector_get(c1, j) * wgt0
685 + cpl_vector_get(tmpC1, k) * wgt1) / (wgt0 + wgt1));
687 cpl_vector_set(u1, j, cpl_vector_get(c1, j) / sqrt(wgt0 + wgt1));
693 cpl_vector_delete(tmpS0);
694 cpl_vector_delete(tmpU0);
695 cpl_vector_delete(tmpC0);
696 cpl_vector_unwrap(tmpW0);
698 cpl_vector_delete(tmpS1);
699 cpl_vector_delete(tmpU1);
700 cpl_vector_delete(tmpC1);
701 cpl_vector_unwrap(tmpW1);
706 for (k = 0; k < n; k++){
707 cpl_vector_set(cpl_bivector_get_x((*spliced)[iord0]), k,
708 cpl_vector_get(w0, k));
709 cpl_vector_set(cpl_bivector_get_x((*spliced)[iord1]), k,
710 cpl_vector_get(w1, k));
712 cpl_vector_set(cpl_bivector_get_x((*spliced_err)[iord0]), k,
713 cpl_vector_get(w0, k));
714 cpl_vector_set(cpl_bivector_get_x((*spliced_err)[iord1]), k,
715 cpl_vector_get(w1, k));
718 cpl_vector_set(cpl_bivector_get_y((*spliced)[iord0]), k,
719 cpl_vector_get(s0, k));
720 cpl_vector_set(cpl_bivector_get_y((*spliced)[iord1]), k,
721 cpl_vector_get(s1, k));
723 cpl_vector_set(cpl_bivector_get_y((*spliced_err)[iord0]), k,
724 cpl_vector_get(u0, k));
725 cpl_vector_set(cpl_bivector_get_y((*spliced_err)[iord1]), k,
726 cpl_vector_get(u1, k));
731 for (i = 0; i < nspectra; i++)
733 cpl_vector_divide(cpl_bivector_get_y((*spliced)[i]), cont[i]);
734 cpl_vector_divide(cpl_bivector_get_y((*spliced_err)[i]), cont[i]);
737 *spectrum_order = cpl_bivector_get_x(wave_center);
738 cpl_vector_delete(cpl_bivector_get_y(wave_center));
739 cpl_free(wave_center);
754cpl_table * cr2res_splice_SPLICED_1D_create(
755 cpl_bivector * spectrum,
756 cpl_bivector * spectrum_error)
759 const double * pspec ;
760 const double * perr ;
765 if (spectrum == NULL || spectrum_error == NULL)
return NULL ;
768 nbins = cpl_bivector_get_size(spectrum) ;
769 if (cpl_bivector_get_size(spectrum_error) != nbins)
return NULL ;
772 out = cpl_table_new(nbins);
775 cpl_table_new_column(out, CR2RES_COL_SPLICED_1D_WL, CPL_TYPE_DOUBLE);
776 cpl_table_new_column(out, CR2RES_COL_SPLICED_1D_SPEC, CPL_TYPE_DOUBLE);
777 cpl_table_new_column(out, CR2RES_COL_SPLICED_1D_ERROR, CPL_TYPE_DOUBLE);
780 pwl = cpl_bivector_get_x_data_const(spectrum) ;
781 pspec = cpl_bivector_get_y_data_const(spectrum) ;
782 perr = cpl_bivector_get_y_data_const(spectrum_error);
784 cpl_table_copy_data_double(out, CR2RES_COL_SPLICED_1D_WL, pwl) ;
785 cpl_table_copy_data_double(out, CR2RES_COL_SPLICED_1D_SPEC, pspec) ;
786 cpl_table_copy_data_double(out, CR2RES_COL_SPLICED_1D_ERROR, perr) ;
char * cr2res_dfs_SPEC_ERR_colname(int order_idx, int trace)
Get the ERR column name for a given order/trace.
char * cr2res_dfs_SPEC_colname(int order_idx, int trace)
Get the SPEC column name for a given order/trace.
cpl_size cr2res_get_trace_table_index(const cpl_table *trace_wave, int order_idx, int trace_nb)
Get the index in a TRACE_WAVE table.
int * cr2res_get_trace_numbers(const cpl_table *trace_wave, int order_idx, int *nb_traces)
Get the trace numbers for a specified order_idx.
int * cr2res_trace_get_order_idx_values(const cpl_table *trace, int *nb_order_idx_values)
Count and return the different order_idx values from a TW table.
cpl_polynomial * cr2res_convert_array_to_poly(const cpl_array *arr)
Convert an array to polynomial.