CR2RE Pipeline Reference Manual 1.6.10
cr2res_splice.c
1/*
2 * This file is part of the CR2RES Pipeline
3 * Copyright (C) 2002,2003 European Southern Observatory
4 *
5 * This program 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, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*-----------------------------------------------------------------------------
25 Includes
26 -----------------------------------------------------------------------------*/
27
28#include <string.h>
29#include <math.h>
30#include <cpl.h>
31
32#include "cr2res_dfs.h"
33#include "cr2res_utils.h"
34#include "cr2res_trace.h"
35#include "cr2res_splice.h"
36
37/*----------------------------------------------------------------------------*/
41/*----------------------------------------------------------------------------*/
42
43int cr2res_combine_spectra(cpl_bivector * spliced[],
44 cpl_bivector * spliced_err[],
45 cpl_vector * spectrum_order,
46 cpl_bivector * last,
47 int nspectra,
48 cpl_bivector ** spectrum,
49 cpl_bivector ** spectrum_err);
50
51int cr2res_extract_data(
52 cpl_table * trace_wave,
53 cpl_table * blaze,
54 cpl_table * spectra,
55 int order_idx,
56 int trace,
57 cpl_vector ** wave,
58 cpl_vector ** spec,
59 cpl_vector ** uncs,
60 cpl_vector ** cont);
61
64/*----------------------------------------------------------------------------*/
75/*----------------------------------------------------------------------------*/
76int cr2res_splice(
77 cpl_table ** extracted_1d,
78 cpl_table ** blaze,
79 cpl_table ** trace_wave,
80 int ninputs,
81 cpl_bivector ** spliced,
82 cpl_bivector ** spliced_err)
83{
84 int i, j, k, nspectra, nb_order_idx_values, nb_traces, success;
85 int * traces;
86 int count = 0;
87 // trace determines which trace to get from the table
88 // trace == -1, means all traces
89 // int trace = -1;
90
91 cpl_bivector ** sp;
92 cpl_bivector ** sp_err;
93 cpl_vector * sp_order;
94 cpl_bivector * first;
95 cpl_bivector * last;
96
97 cpl_vector ** wave;
98 cpl_vector ** spec;
99 cpl_vector ** uncs;
100 cpl_vector ** cont;
101
102
103 // Count total number of spectra
104 nspectra = 0;
105 for (i = 0; i < ninputs; i++){
106 nspectra += cpl_table_get_nrow(trace_wave[i]);
107 }
108 /*for (i = 0; i < ninputs; i++){
109 if (trace == -1){
110 nspectra += cpl_table_get_nrow(trace_wave[i]);
111 }
112 else{
113 order_idx_values = cr2res_trace_get_order_idx_values(trace_wave[i],
114 &nb_order_idx_values);
115 for (j = 0; j < nb_order_idx_values; j++){
116 if ((cr2res_get_trace_table_index(trace_wave[i],
117 order_idx_values[j], trace)) != -1) {
118 nspectra++;
119 }
120 }
121 cpl_free(order_idx_values);
122 }
123 }*/
124
125 cpl_msg_info(__func__, "Number of segments: %i", nspectra);
126
127
128 // Prepare data vectors
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 *));
133
134 // fill data vectors by reading table data
135 count = 0;
136 for (i = 0; i < ninputs; i++){
137 int * order_idx_values;
138 order_idx_values = cr2res_trace_get_order_idx_values(trace_wave[i],
139 &nb_order_idx_values);
140 for (j = 0; j < nb_order_idx_values; j++) {
141 traces = cr2res_get_trace_numbers(trace_wave[i],
142 order_idx_values[j], &nb_traces);
143 for (k = 0; k < nb_traces; k++) {
144 success =
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]);
149 if (success == 0) {
150 count++;
151 }
152 }
153 cpl_free(traces);
154 /*if (trace == -1){
155 traces = cr2res_get_trace_numbers(trace_wave[i],
156 order_idx_values[j], &nb_traces);
157 for (k = 0; k < nb_traces; k++) {
158 success = cr2res_extract_data(trace_wave[i], blaze[i],
159 extracted_1d[i], order_idx_values[j], traces[k],
160 &wave[count], &spec[count], &uncs[count], &cont[count]);
161 if (success == 0){
162 count++;
163 }
164
165 }
166 cpl_free(traces);
167 }
168 else
169 {
170 if (cr2res_extract_data(trace_wave[i], blaze[i],
171 extracted_1d[i], order_idx_values[j], trace,
172 &wave[count], &spec[count], &uncs[count],
173 &cont[count]) != -1) {
174 count++;
175 }
176 }*/
177 }
178 cpl_free(order_idx_values);
179 }
180
181 nspectra = count;
182 cpl_msg_info(__func__, "%i segments with data found", nspectra);
183
184 // Splice orders, but keep them separate
185 cr2res_splice_orders(wave, spec, uncs, cont, nspectra, &sp, &sp_err,
186 &sp_order, &first, &last);
187
188 // Combine orders into one big spectrum
189 cr2res_combine_spectra(sp, sp_err, sp_order, last, nspectra, spliced,
190 spliced_err);
191
192 cpl_bivector_delete(first);
193 cpl_bivector_delete(last);
194 cpl_vector_delete(sp_order);
195
196 for (i = 0; i < nspectra; i++){
197 cpl_bivector_delete(sp[i]);
198 cpl_bivector_delete(sp_err[i]);
199 }
200
201 cpl_free(sp);
202 cpl_free(sp_err);
203
204 for (i = 0; i < nspectra; i++){
205 // spec, uncs, cont were just wrapping table data
206 // while wave, is its own data (the evaluated polynomial)
207 cpl_vector_delete(wave[i]);
208 cpl_vector_unwrap(spec[i]);
209 cpl_vector_unwrap(uncs[i]);
210 cpl_vector_unwrap(cont[i]);
211 }
212 cpl_free(wave);
213 cpl_free(spec);
214 cpl_free(uncs);
215 cpl_free(cont);
216
217 if (cpl_error_get_code() == CPL_ERROR_DIVISION_BY_ZERO){
218 cpl_msg_warning(__func__,
219 "Division by Zero encountered. Resetting Error State");
220 cpl_error_reset();
221 }
222 return 0 ;
223}
224
225
226int cr2res_extract_data(
227 cpl_table * trace_wave,
228 cpl_table * blaze,
229 cpl_table * spectra,
230 int order_idx,
231 int trace,
232 cpl_vector ** wave,
233 cpl_vector ** spec,
234 cpl_vector ** uncs,
235 cpl_vector ** cont)
236{
237 int j, k, n = CR2RES_DETECTOR_SIZE;
238 const cpl_array * wave1;
239 cpl_polynomial * wave_poly;
240 double * tmp1;
241 char * colname;
242
243 j = cr2res_get_trace_table_index(trace_wave, order_idx, trace);
244 if (j == -1){
245 // trace or order not found
246 return -1;
247 }
248
249 // Get wavelength
250 wave1 = cpl_table_get_array(trace_wave, CR2RES_COL_WAVELENGTH, j);
251 if (wave1 == NULL){
252 cpl_msg_warning(__func__, "Order %i, Trace %i", order_idx, trace);
253 cpl_msg_warning(__func__, "Wavelength Array not set");
254 return -1;
255 }
256 wave_poly = cr2res_convert_array_to_poly(wave1);
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);
261
262 // Get Spectrum
263 colname = cr2res_dfs_SPEC_colname(order_idx, trace);
264 tmp1 = cpl_table_get_data_double(spectra, colname);
265 cpl_free(colname);
266
267 if (tmp1 == NULL){
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);
271 return -1;
272 }
273 *spec = cpl_vector_wrap(n, tmp1);
274
275
276 // Get Uncertainties
277 colname = cr2res_dfs_SPEC_ERR_colname(order_idx, trace);
278 tmp1 = cpl_table_get_data_double(spectra, colname);
279 cpl_free(colname);
280 if (tmp1 == NULL){
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);
285 return -1;
286 }
287 *uncs = cpl_vector_wrap(n, tmp1);
288
289 // Get Continuum
290 colname = cr2res_dfs_SPEC_colname(order_idx, trace);
291 tmp1 = cpl_table_get_data_double(blaze, colname);
292 cpl_free(colname);
293 if (tmp1 == NULL){
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);
299 return -1;
300 }
301 *cont = cpl_vector_wrap(n, tmp1);
302
303 return 0;
304}
305
306
307int cr2res_combine_spectra(
308 cpl_bivector * spliced[],
309 cpl_bivector * spliced_err[],
310 cpl_vector * spectrum_order,
311 cpl_bivector * last,
312 int nspectra,
313 cpl_bivector ** spectrum,
314 cpl_bivector ** spectrum_err)
315{
316
317 if (spliced == NULL || spliced_err == NULL || nspectra <= 0 ||
318 spectrum == NULL || spectrum_err == NULL || spectrum_order == NULL)
319 return -1;
320
321 int i = 0, k = 0;
322
323 *spectrum = cpl_bivector_new(nspectra * CR2RES_DETECTOR_SIZE);
324 *spectrum_err = cpl_bivector_new(nspectra * CR2RES_DETECTOR_SIZE);
325
326 for (i = 0; i < nspectra; i++){
327
328 int lx, ly;
329 int iord, j;
330 iord = cpl_vector_get(spectrum_order, i);
331
332 //fx = cpl_bivector_get_x_data(first)[iord];
333 lx = cpl_bivector_get_x_data(last)[iord] + 1;
334 //fy = cpl_bivector_get_y_data(first)[iord];
335 ly = cpl_bivector_get_y_data(last)[iord] + 1;
336
337 if ( i == 0 ){
338 //fx = 0;
339 lx = 0;
340 }
341 if (i == nspectra-1){
342 //fy = CR2RES_DETECTOR_SIZE;
343 ly = CR2RES_DETECTOR_SIZE;
344 }
345 cpl_msg_debug(__func__, "lx: %i, ly: %i", lx, ly);
346
347 // in the overlap region keep the data from the lower wavelength order
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));
353
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));
358
359 k++;
360 }
361
362 }
363
364 cpl_vector_set_size(cpl_bivector_get_x(*spectrum), k-1);
365 cpl_vector_set_size(cpl_bivector_get_y(*spectrum), k-1);
366
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);
369
370
371 return 0;
372}
373
374/*----------------------------------------------------------------------------*/
390/*----------------------------------------------------------------------------*/
391int cr2res_splice_orders(
392 cpl_vector ** wave,
393 cpl_vector ** spec,
394 cpl_vector ** uncs,
395 cpl_vector ** cont,
396 int nspectra,
397 cpl_bivector ** spliced[],
398 cpl_bivector ** spliced_err[],
399 cpl_vector ** spectrum_order,
400 cpl_bivector ** first,
401 cpl_bivector ** last)
402{
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;
406
407 cpl_size i, j, k;
408 int * loop0, *loop1;
409 int n = CR2RES_DETECTOR_SIZE;
410 double wgt0, wgt1;
411 // temporary work arrays
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;
418
419 loop0 = cpl_malloc((nspectra-1) * sizeof(int));
420 loop1 = cpl_malloc((nspectra-1) * sizeof(int));
421
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);
426
427
428 for (i = 0; i < nspectra; i++){
429 (*spliced)[i] = cpl_bivector_new(n);
430 (*spliced_err)[i] = cpl_bivector_new(n);
431 }
432 wave_center = cpl_bivector_new(nspectra);
433
434 // Load data into vector arrays
435 for (i=0; i<nspectra; i++){
436
437 cpl_vector * tmp4;
438 double median;
439
440 // Get Wavelength Center
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));
444
445 // scale all orders to spec/cont = 1
446 // also replace nans with 0 in spec
447 // and nan and 0 with 1 in cont
448 tmp4 = cpl_vector_duplicate(spec[i]);
449 for (j=0; j < n; j++)
450 {
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);
454 }
455 if (isfinite(cpl_vector_get(uncs[i], j)) == 0){
456 cpl_vector_set(uncs[i], j, 1);
457 }
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);
460 }
461 cpl_vector_set(tmp4, j,
462 cpl_vector_get(tmp4, j) / cpl_vector_get(cont[i], j));
463 }
464 // cpl_vector_divide(tmp4, cont[i]);
465 median = cpl_vector_get_median(tmp4);
466 cpl_vector_multiply_scalar(cont[i], median);
467 cpl_vector_delete(tmp4);
468 }
469
470 // Determine order of orders (wavelength sections)
471 cpl_bivector_sort(wave_center, wave_center, CPL_SORT_ASCENDING,
472 CPL_SORT_BY_Y);
473
474 // just loop from left to right?
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];
478 }
479
480 for (i=0; i < nspectra-1; i++){
481
482 int iord0, iord1;
483 int first0, first1, last0, last1, overlap0, overlap1;
484 cpl_size minW0pos, minW1pos, maxW0pos, maxW1pos;
485
486 double minW0, minW1, maxW0, maxW1;
487 cpl_vector *s0, *s1;
488 cpl_vector *u0, *u1;
489 cpl_vector *w0, *w1;
490 cpl_vector *c0, *c1;
491 // about the nomenclature
492 // Order "0" is closer to central
493 // Order "1" is the neighbour further away
494 iord0 = loop0[i];
495 iord1 = loop1[i];
496
497 // Get relevant data vectors
498 s0 = spec[iord0];
499 s1 = spec[iord1];
500 u0 = uncs[iord0];
501 u1 = uncs[iord1];
502 w0 = wave[iord0];
503 w1 = wave[iord1];
504 c0 = cont[iord0];
505 c1 = cont[iord1];
506
507 // Calculate overlap
508 // If the extraction was curved, the border points should be 0
509 // with the number of points depending on the curvature
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);
514
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--;
519
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);
524
525 // indices of the first and last overlapping value
526 first0 = -1;
527 first1 = -1;
528 last0 = -1;
529 last1 = -1;
530
531 // overlap0: number of overlap points of order "0"
532 // overlap1: number of overlap points of order "1"
533
534 overlap0 = 0;
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)){
537 // if its the first element
538 if (first0 == -1) first0 = j;
539 overlap0++;
540 // update so that it will be the last element
541 last0 = j;
542 }
543 }
544
545 overlap1 = 0;
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)){
548 // if its the first element
549 if (first1 == -1) first1 = j;
550 overlap1++;
551 // update so that it will be the last element
552 last1 = j;
553 }
554 }
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);
561
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));
567
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));
572
573
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));
578
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));
583
584 }
585
586 continue;
587 }
588
589 // It should be:
590 // first.x : first index of the overlap on the left (lower wavelength) side of the order
591 // first.y : first index of the overlap on the right (higher wavelength) side of the order
592 // last.x : last index of the overlap on the left (lower wavelength) side of the order
593 // last.y : last index of the overlap on the right (higher wavelength) side of the order
594
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);
599
600 // extract overlapping wavelength vectors
601 // point to the latter parts of the wavelength vector, no need for copies
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);
604
605 // Prepare new vectors with interpolated data
606 tmpS0 = cpl_vector_new(overlap0);
607 tmpU0 = cpl_vector_new(overlap0);
608 tmpC0 = cpl_vector_new(overlap0);
609
610 tmpS1 = cpl_vector_new(overlap1);
611 tmpU1 = cpl_vector_new(overlap1);
612 tmpC1 = cpl_vector_new(overlap1);
613
614 // Interpolate vectors on the other wavelength grid
615 // Note that this is just linear interpolation
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);
621
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);
627
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);
633
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);
639
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);
645
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);
651
652 // Combine Spectra with weighted average at each point
653 // its important to remember the continuum in the uncertainties/weights
654 k = 0;
655 for (j=first0; j<=last0; j++){
656
657 wgt0 = cpl_vector_get(c0, j) / cpl_vector_get(u0, j);
658 wgt0 = wgt0 * wgt0;
659 wgt1 = cpl_vector_get(tmpC0, k) / cpl_vector_get(tmpU0, k);
660 wgt1 = wgt1 * wgt1;
661
662 cpl_vector_set(s0, j, (cpl_vector_get(s0, j) * wgt0
663 + cpl_vector_get(tmpS0, k) * wgt1) / (wgt0 + wgt1));
664
665 cpl_vector_set(c0, j, (cpl_vector_get(c0, j) * wgt0
666 + cpl_vector_get(tmpC0, k) * wgt1) / (wgt0 + wgt1));
667
668 cpl_vector_set(u0, j, cpl_vector_get(c0, j) / sqrt(wgt0 + wgt1));
669
670 k++;
671 }
672
673 k = 0;
674 for (j=first1; j<=last1; j++){
675 // Weighted average
676 wgt0 = cpl_vector_get(c1, j) / cpl_vector_get(u1, j);
677 wgt0 = wgt0 * wgt0;
678 wgt1 = cpl_vector_get(tmpC1, k) / cpl_vector_get(tmpU1, k);
679 wgt1 = wgt1 * wgt1;
680
681 cpl_vector_set(s1, j, (cpl_vector_get(s1, j) * wgt0
682 + cpl_vector_get(tmpS1, k) * wgt1) / (wgt0 + wgt1));
683
684 cpl_vector_set(c1, j, (cpl_vector_get(c1, j) * wgt0
685 + cpl_vector_get(tmpC1, k) * wgt1) / (wgt0 + wgt1));
686
687 cpl_vector_set(u1, j, cpl_vector_get(c1, j) / sqrt(wgt0 + wgt1));
688
689 k++;
690 }
691
692 // remove temporary vectors
693 cpl_vector_delete(tmpS0);
694 cpl_vector_delete(tmpU0);
695 cpl_vector_delete(tmpC0);
696 cpl_vector_unwrap(tmpW0);
697
698 cpl_vector_delete(tmpS1);
699 cpl_vector_delete(tmpU1);
700 cpl_vector_delete(tmpC1);
701 cpl_vector_unwrap(tmpW1);
702
703 // Set data in output vector
704 // TODO, avoid duplicate copies
705
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));
711
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));
716
717
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));
722
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));
727
728 }
729 }
730
731 for (i = 0; i < nspectra; i++)
732 {
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]);
735 }
736
737 *spectrum_order = cpl_bivector_get_x(wave_center);
738 cpl_vector_delete(cpl_bivector_get_y(wave_center));
739 cpl_free(wave_center);
740
741 cpl_free(loop0);
742 cpl_free(loop1);
743 return 0;
744}
745
746/*----------------------------------------------------------------------------*/
753/*----------------------------------------------------------------------------*/
754cpl_table * cr2res_splice_SPLICED_1D_create(
755 cpl_bivector * spectrum,
756 cpl_bivector * spectrum_error)
757{
758 cpl_table * out ;
759 const double * pspec ;
760 const double * perr ;
761 const double * pwl ;
762 cpl_size nbins;
763
764 /* Check entries */
765 if (spectrum == NULL || spectrum_error == NULL) return NULL ;
766
767 /* Initialise */
768 nbins = cpl_bivector_get_size(spectrum) ;
769 if (cpl_bivector_get_size(spectrum_error) != nbins) return NULL ;
770
771 /* Create the table */
772 out = cpl_table_new(nbins);
773
774 /* Create SPLICED_1D_SPEC columns */
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);
778
779 /* Fill the table */
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);
783
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) ;
787
788 return out ;
789}
790
char * cr2res_dfs_SPEC_ERR_colname(int order_idx, int trace)
Get the ERR column name for a given order/trace.
Definition: cr2res_dfs.c:414
char * cr2res_dfs_SPEC_colname(int order_idx, int trace)
Get the SPEC column name for a given order/trace.
Definition: cr2res_dfs.c:378
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.
Definition: cr2res_trace.c:652
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.
Definition: cr2res_trace.c:517
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.
Definition: cr2res_trace.c:431
cpl_polynomial * cr2res_convert_array_to_poly(const cpl_array *arr)
Convert an array to polynomial.