ERIS Pipeline Reference Manual 1.8.15
sc_modsky.c
Go to the documentation of this file.
1/*
2 * This file is part of the SKYCORR software package.
3 * Copyright (C) 2009-2013 European Southern Observatory
4 *
5 * This programme 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 programme 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 programme. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19
38/*****************************************************************************
39 * INCLUDES *
40 ****************************************************************************/
41
42#include <sc_mpfit.h>
43#include <sc_modsky.h>
44
45#include <math.h>
46#include <assert.h>
47
48
49/*****************************************************************************
50 * CODE *
51 ****************************************************************************/
52
53cpl_error_code sc_modsky(cpl_table *scispec, cpl_table *skyspec,
54 cpl_table *fitpar, const cpl_vector *sinc,
55 const cpl_parameterlist *parlist)
56{
84 int nrow = 0;
85
86 /* Prepare columns in sky spectrum table */
87 nrow = cpl_table_get_nrow(skyspec);
88 cpl_table_fill_column_window(skyspec, "mlflux", 0, nrow, 0.);
89 cpl_table_add_columns(skyspec, "mlflux", "lflux");
90 if (lastcall == CPL_TRUE &&
91 cpl_table_has_column(skyspec, "mdflux") == 1) {
92 cpl_table_fill_column_window(skyspec, "mdflux", 0, nrow, 0.);
93 cpl_table_add_columns(skyspec, "mdflux", "dflux");
94 }
95 cpl_table_fill_column_window(skyspec, "mlflux", 0, nrow, 0.);
96 cpl_table_add_columns(skyspec, "mlflux", "lflux");
97 cpl_table_fill_column_window(skyspec, "mweight", 0, nrow, 0.);
98 cpl_table_add_columns(skyspec, "mweight", "weight");
99
100 /* Modify line group fluxes in sky spectrum */
101 sc_modsky_modlines(skyspec, fitpar, 'A'); /* A groups */
102 sc_modsky_modlines(skyspec, fitpar, 'B'); /* B groups */
103
104 /* Modify flux errors if provided by sky spectrum table */
105 sc_modsky_moderrors(skyspec);
106
107 /* Modify wavelength grid of sky spectrum by means of a Chebyshev
108 polynomial */
109 sc_modsky_modwavegrid(skyspec, fitpar);
110
111 /* Rebin modified sky spectrum to wavelength grid of science spectrum */
112 sc_modsky_rebin(scispec, skyspec, sinc, parlist);
113
114 /* Calculate weighted deviations between modified sky and science
115 spectrum */
116 sc_modsky_calcdev(scispec);
117
118 return CPL_ERROR_NONE;
119}
120
121
122cpl_error_code sc_modsky_modlines(cpl_table *skyspec, cpl_table *fitpar,
123 const char grouptype)
124{
143 cpl_table *grouppar;
144 char type[2], ncolname[SC_LENLINE+1], wcolname[SC_LENLINE+1];
145 int *rel = NULL;
146 int ngroup = 0, depth = 0, nrow = 0, i = 0, n = 0, j = 0, group = 0;
147 double *val = NULL;
148 const cpl_array ** pa_narray, ** pa_warray;
149 double * pd_flux;
150
151 /* Create subtable from fit parameter table that only contains the
152 coefficients for the wavelength correction */
153 sprintf(type, "%c", grouptype);
154 cpl_table_unselect_all(fitpar);
155 cpl_table_or_selected_string(fitpar, "type", CPL_EQUAL_TO, type);
156 grouppar = cpl_table_extract_selected(fitpar);
157 cpl_table_select_all(fitpar);
158
159 /* Get number of line groups */
160 ngroup = cpl_table_get_nrow(grouppar);
161
162 /* Build group number and weight column name */
163 sprintf(ncolname, "ng%c", grouptype);
164 sprintf(wcolname, "wg%c", grouptype);
165
166 /* Get depth of line group column */
167 depth = cpl_table_get_column_depth(skyspec, ncolname);
168
169 /* No data -> print warning message and return without change */
170 if (ngroup == 0 || depth == 0) {
171 if (nfev == 1) {
172 /* Print message only once */
173 cpl_msg_warning(cpl_func, "No %c line groups", grouptype);
174 }
175 cpl_table_delete(grouppar);
176 return CPL_ERROR_NONE;
177 }
178
179 /* Get pointer to fit parameter values and relevance flags */
180 val = cpl_table_get_data_double(grouppar, "value");
181 rel = cpl_table_get_data_int(grouppar, "relevance");
182
183 /* Get number of rows in sky spectrum table */
184 nrow = cpl_table_get_nrow(skyspec);
185
186 /* Modify flux of sky line spectrum depending on pixel-specific line
187 group weights */
188
189 assert(cpl_table_count_invalid(skyspec, wcolname) == 0);
190 assert(cpl_table_count_invalid(skyspec, ncolname) == 0);
191 pa_narray = cpl_table_get_data_array_const(skyspec, ncolname);
192 pa_warray = cpl_table_get_data_array_const(skyspec, wcolname);
193 pd_flux = cpl_table_get_data_double(skyspec, "mlflux");
194 cpl_table_fill_invalid_double(skyspec, "mlflux", 0.);
195 for (i = 0; i < nrow; i++) {
196 double flux = pd_flux[i];
197
198 /* Skip pixel if flux is zero */
199 if (flux > 0) {
200 double wsum, wgroup;
201
202 /* Get arrays */
203 const cpl_array * narray = pa_narray[i];
204 const cpl_array * warray = pa_warray[i];
205
206 /* Get number of contributing line groups */
207 n = depth - cpl_array_count_invalid(narray);
208
209 /* Skip pixel if no line group contributes */
210 if (n == 0) {
211 continue;
212 }
213
214 /* Get weight of each line group and multiply it by the
215 corresponding fit parameter value */
216 wsum = 0;
217 for (j = 0; j < n; j++) {
218 group = cpl_array_get(narray, j, NULL);
219 wgroup = cpl_array_get(warray, j, NULL);
220 if (group <= 0 || rel[group-1] == 0) {
221 /* Do not change flux for group with relevance flag = 0
222 and group 0 */
223 wsum += wgroup;
224 } else {
225 wsum += wgroup * val[group-1];
226 }
227 }
228
229 /* Multiply flux by weight sum to get modified pixel flux */
230 flux *= wsum;
231
232 /* must be valid or flux > 0 check would have been false */
233 pd_flux[i] = flux;
234
235 }
236
237 }
238
239 /* Free memory */
240 cpl_table_delete(grouppar);
241
242 return CPL_ERROR_NONE;
243}
244
245
246cpl_error_code sc_modsky_moderrors(cpl_table *skyspec)
247{
263 int nrow = 0, i = 0;
264 double *cflux = NULL, *lflux = NULL, *mlflux = NULL, *dflux = NULL;
265 double *mdflux = NULL;
266
267 /* Return without change if the modsky call is not the last one or an
268 error column is lacking */
269 if (lastcall == CPL_FALSE ||
270 cpl_table_has_column(skyspec, "mdflux") != 1) {
271 return CPL_ERROR_NONE;
272 }
273
274 /* Get pointers to table columns */
275 cflux = cpl_table_get_data_double(skyspec, "cflux");
276 lflux = cpl_table_get_data_double(skyspec, "lflux");
277 mlflux = cpl_table_get_data_double(skyspec, "mlflux");
278 dflux = cpl_table_get_data_double(skyspec, "dflux");
279 mdflux = cpl_table_get_data_double(skyspec, "mdflux");
280
281 /* Get number of rows in sky spectrum table */
282 nrow = cpl_table_get_nrow(skyspec);
283
284 /* Modify flux errors */
285 for (i = 0; i < nrow; i++) {
286 mdflux[i] = dflux[i];
287 if (cflux[i] + lflux[i] > 0. && cflux[i] + mlflux[i] > 0.) {
288 mdflux[i] *= (cflux[i] + mlflux[i]) / (cflux[i] + lflux[i]);
289 }
290 }
291
292 return CPL_ERROR_NONE;
293}
294
295
296cpl_error_code sc_modsky_modwavegrid(cpl_table *skyspec, cpl_table *fitpar)
297{
319 cpl_array *cheby;
320 cpl_table *wpar;
321 int nlam = 0, ncoef = 0, i = 0, maxpix = -1, j = 0;
322 int *class;
323 double limlam[2] = {0., 0.}, dlam = 0., wmean = 0., dellam = 0.;
324 const double *par;
325 double *slam, *mlam, *t;
326
327 /* Default output wavelength grid = input wavelength grid */
328 nlam = cpl_table_get_nrow(skyspec);
329 cpl_table_fill_column_window(skyspec, "mlambda", 0, nlam, 0.);
330 cpl_table_add_columns(skyspec, "mlambda", "lambda");
331
332 /* Create subtable from fit parameter table that only contains the
333 relevant coefficients for the wavelength correction */
334 cpl_table_unselect_all(fitpar);
335 cpl_table_or_selected_string(fitpar, "type", CPL_EQUAL_TO, "w");
336 cpl_table_and_selected_int(fitpar, "relevance", CPL_EQUAL_TO, 1);
337 wpar = cpl_table_extract_selected(fitpar);
338 cpl_table_select_all(fitpar);
339
340 /* Get number of coefficients for wavelength correction */
341 ncoef = cpl_table_get_nrow(wpar);
342
343 /* Fit flag = 0 for coefficient < maximum degree in selected fit parameter
344 table -> print warning message and return without change */
345 if (ncoef > 0 && ncoef - 1 < cpl_table_get(wpar, "N", ncoef - 1, NULL)) {
346 if (nfev == 1) {
347 /* Print message only once */
348 cpl_msg_warning(cpl_func, "Invalid set of coefficients "
349 "for wavelength correction -> skip");
350 }
351 cpl_table_delete(wpar);
352 return CPL_ERROR_NONE;
353 }
354
355 /* N of coef. < 2 -> print warning message if N = 1 and return without
356 change */
357 if (ncoef < 2) {
358 if (nfev == 1 && ncoef == 1) {
359 /* Print message only once */
360 cpl_msg_warning(cpl_func, "Only one coefficient "
361 "for wavelength correction -> skip");
362 }
363 cpl_table_delete(wpar);
364 return CPL_ERROR_NONE;
365 }
366
367 /* Get pointer to fit parameters */
368 par = cpl_table_get_data_double(wpar, "value");
369
370 /* Scale wavelengths in the way that the interval [-1,1] is covered */
371 limlam[0] = cpl_table_get(skyspec, "lambda", 0, NULL);
372 limlam[1] = cpl_table_get(skyspec, "lambda", nlam-1, NULL);
373 dlam = limlam[1] - limlam[0];
374 wmean = (limlam[0] + limlam[1]) / 2;
375 cpl_table_duplicate_column(skyspec, "slambda", skyspec, "lambda");
376 cpl_table_subtract_scalar(skyspec, "slambda", wmean);
377 cpl_table_divide_scalar(skyspec, "slambda", dlam / 2.);
378
379 /* Get pointer to normalised wavelength grid */
380 slam = cpl_table_get_data_double(skyspec, "slambda");
381
382 /* Set wavelengths in output column "mlambda" to 0 and get pointer */
383 cpl_table_fill_column_window(skyspec, "mlambda", 0, nlam, 0.);
384 mlam = cpl_table_get_data_double(skyspec, "mlambda");
385
386 /* Find last line pixel for wavelength shift in the thermal IR */
387 class = cpl_table_get_data_int(skyspec, "class");
388 maxpix = nlam - 1;
389 if (limlam[1] >= SC_THERMIRLIM) {
390 for (i = nlam-1; i >= 0; i--) {
391 if (class[i] > 0) {
392 maxpix = i;
393 break;
394 }
395 }
396 }
397
398 /* Create array for Chebyshev polynomials */
399 cheby = cpl_array_new(ncoef, CPL_TYPE_DOUBLE);
400 t = cpl_array_get_data_double(cheby);
401 t[0] = 1;
402
403 /* Compute Chebyshev polynomials */
404 for (i = 0; i < nlam; i++) {
405 if (i <= maxpix) {
406 for (j = 0; j < ncoef; j++) {
407 if (j == 1) {
408 t[j] = slam[i];
409 } else if (j > 1) {
410 t[j] = 2 * slam[i] * t[j-1] - t[j-2];
411 }
412 mlam[i] += par[j] * t[j];
413 }
414 if (i == maxpix) {
415 dellam = mlam[i] - slam[i];
416 }
417 } else {
418 /* constant shift for thermal infrared */
419 mlam[i] = slam[i] + dellam;
420 }
421 }
422
423 /* Rescale wavelengths */
424 cpl_table_multiply_scalar(skyspec, "mlambda", dlam / 2.);
425 cpl_table_add_scalar(skyspec, "mlambda", wmean);
426
427 /* Free memory */
428 cpl_array_delete(cheby);
429 cpl_table_delete(wpar);
430 cpl_table_erase_column(skyspec, "slambda");
431
432 return CPL_ERROR_NONE;
433}
434
435
436cpl_error_code sc_modsky_rebin(cpl_table *scispec, cpl_table *skyspec,
437 const cpl_vector *sinc,
438 const cpl_parameterlist *parlist)
439{
471 const cpl_parameter *p;
472 int rebintype = 0, nsky = 0, i = 0, pmin = 0, pmax = 0, nsci = 0;
473 double wmin = 0., maxerr = 0.;
474 double * pd_mweight , * pd_tdflux, * pdsky_weight;
475
476 /* Derive pixel shifts */
477 sc_modsky_getpixelshifts(skyspec, scispec);
478
479 /* Get method for rebinning from parameter list */
480 p = cpl_parameterlist_find_const(parlist, "rebintype");
481 rebintype = cpl_parameter_get_int(p);
482
483 /* Rebin sky continuum spectrum by using selected type of rebinning
484 (only in the case of last modsky call) */
485 if (lastcall == CPL_TRUE) {
486 if (rebintype == 1) {
487 sc_modsky_sincrebin(scispec, "mcflux", skyspec, "cflux", sinc);
488 } else {
489 sc_basic_rebin(scispec, "lambda", "mcflux",
490 skyspec, "mlambda", "cflux");
491 }
492 }
493
494 /* Rebin modified sky line spectrum by using selected type of rebinning */
495 if (rebintype == 1) {
496 sc_modsky_sincrebin(scispec, "mlflux", skyspec, "mlflux", sinc);
497 } else {
498 sc_basic_rebin(scispec, "lambda", "mlflux",
499 skyspec, "mlambda", "mlflux");
500 }
501
502 /* Rebin flux errors (if present) by using selected type of rebinning
503 (only in the case of last modsky call) */
504 if (lastcall == CPL_TRUE &&
505 cpl_table_has_column(skyspec, "mdflux") == 1) {
506 if (rebintype == 1) {
507 sc_modsky_sincrebin(scispec, "mdflux", skyspec, "mdflux", sinc);
508 } else {
509 sc_basic_rebin(scispec, "lambda", "mdflux",
510 skyspec, "mlambda", "mdflux");
511 }
512 }
513
514 /* Create temporary error columns in sky and science spectrum */
515 cpl_table_new_column(scispec, "tdflux", CPL_TYPE_DOUBLE);
516 cpl_table_new_column(skyspec, "tdflux", CPL_TYPE_DOUBLE);
517
518 /* Get minimum non-zero weight of sky spectrum */
519 nsky = cpl_table_get_nrow(skyspec);
520 cpl_table_fill_invalid_double(skyspec, "weight", 0.);
521 pdsky_weight = cpl_table_get_data_double(skyspec, "weight");
522 for (i = 0; i < nsky; i++) {
523 double weight = pdsky_weight[i];
524 if (weight != 0 && weight < wmin) {
525 wmin = weight;
526 }
527 }
528
529 /* Derive maximum error for weight = 0 substitution */
530 wmin /= (1 + SC_TOL);
531 maxerr = SC_RELMAXERR / wmin;
532
533 /* Fill error column of sky spectrum */
534 pd_tdflux = cpl_table_get_data_double(skyspec, "tdflux");
535 /* make sure column is valid */
536 cpl_table_fill_column_window_double(skyspec, "tdflux", 0, nsky, 0.);
537 for (i = 0; i < nsky; i++) {
538 double weight = pdsky_weight[i];
539 /* Handle weight = 0 */
540 if (weight == 0) {
541 pd_tdflux[i] = maxerr;
542 } else {
543 pd_tdflux[i] = 1. / weight;
544 }
545 }
546
547 /* Rebin errors of sky spectrum
548 (no sinc function to avoid negative errors) */
549 sc_basic_rebin(scispec, "lambda", "tdflux", skyspec, "mlambda", "tdflux");
550
551 /* Get minimum and maximum pixel in column "mpix" to identify
552 non-overlapping wavelength ranges */
553 pmin = cpl_table_get(skyspec, "mpix", 0, NULL);
554 pmax = cpl_table_get(skyspec, "mpix", nsky-1, NULL);
555
556 /* Convert errors back to weights */
557 nsci = cpl_table_get_nrow(scispec);
558 pd_mweight = cpl_table_get_data_double(scispec, "mweight");
559 assert(cpl_table_count_invalid(scispec, "tdflux") == 0);
560 pd_tdflux = cpl_table_get_data_double(scispec, "tdflux");
561 /* make sure column is valid and fill in weight = 0 */
562 cpl_table_fill_column_window_double(scispec, "mweight", 0, nsci, 0.);
563 for (i = 0; i < nsci; i++) {
564 double err = pd_tdflux[i];
565 /* Identify weight = 0 */
566 if (!(err > 1. / wmin || i < pmin || i > pmax)) {
567 pd_mweight[i] = 1. / err;
568 }
569 }
570
571 /* Delete temporary columns */
572 cpl_table_erase_column(skyspec, "tdflux");
573 cpl_table_erase_column(scispec, "tdflux");
574
575 return CPL_ERROR_NONE;
576}
577
578
579cpl_error_code sc_modsky_getpixelshifts(cpl_table *skyspec,
580 const cpl_table *scispec)
581{
602 int nsci = 0, nsky = 0, *mpix, i = 0, j = 1;
603 double *skylam, *dpix, dlam = 0., shift = 0.;
604 const double *scilam;
605
606 /* Get number of data points in science and sky spectrum */
607 nsci = cpl_table_get_nrow(scispec);
608 nsky = cpl_table_get_nrow(skyspec);
609
610 /* Initialise "mpix" and "dpix" columns in sky spectrum */
611 cpl_table_fill_column_window_int(skyspec, "mpix", 0, nsky, 0);
612 cpl_table_fill_column_window_double(skyspec, "dpix", 0, nsky, 0.);
613
614 /* Get pointers to CPL table columns */
615 scilam = cpl_table_get_data_double_const(scispec, "lambda");
616 skylam = cpl_table_get_data_double(skyspec, "mlambda");
617 mpix = cpl_table_get_data_int(skyspec, "mpix");
618 dpix = cpl_table_get_data_double(skyspec, "dpix");
619
620 /* Find central pixel and subpixel shift for the kernel for each pixel in
621 sky spectrum */
622
623 for (i = 0; i < nsky; i++) {
624
625 while (j < nsci - 1 && scilam[j] < skylam[i]) {
626 j++;
627 }
628
629 dlam = scilam[j] - scilam[j-1];
630 shift = (skylam[i] - scilam[j]) / dlam;
631 mpix[i] = (int) floor(shift + 0.5) + j;
632 dpix[i] = shift - (double) mpix[i] + j;
633
634 }
635
636 return CPL_ERROR_NONE;
637}
638
639
640cpl_error_code sc_modsky_sincrebin(cpl_table *scispec, const char *scicol,
641 const cpl_table *skyspec,
642 const char *skycol,
643 const cpl_vector *sinc)
644{
675 int nsci = 0, nsky = 0, pmin = 0, pmax = 0, i = 0, k = 0, nsinc = 0;
676 const int *mpix;
677 double *cflux;
678 const double *dpix, *flux, *psinc;
679
680 /* Get kernel size */
681 const double radius = 5.;
682 const int nkpix = 2 * radius + 1;
683 double kernel[nkpix];
684 /* indexing offset into precomputed kernel */
685 const double k_offset = ((double)(SC_SINCRAD_PRECOMP) - (radius));
686 assert(k_offset >= 0);
687
688 /* Get number of data points in science and sky spectrum */
689 nsci = cpl_table_get_nrow(scispec);
690 nsky = cpl_table_get_nrow(skyspec);
691
692 /* Initialise output column with 0 values */
693 cpl_table_fill_column_window_double(scispec, scicol, 0, nsci, 0.);
694
695 /* Get pointer to output column */
696 cflux = cpl_table_get_data_double(scispec, scicol);
697
698 /* Get pointers to required table columns of sky spectrum */
699 mpix = cpl_table_get_data_int_const(skyspec, "mpix");
700 dpix = cpl_table_get_data_double_const(skyspec, "dpix");
701 flux = cpl_table_get_data_double_const(skyspec, skycol);
702
703 /* Get minimum and maximum pixel in column "mpix" */
704 pmin = mpix[0];
705 pmax = mpix[nsky-1];
706
707 /* Get number of data points in sinc vector */
708 nsinc = cpl_vector_get_size(sinc);
709
710 /* for interpolation of kernel we need a precomputed kernel one larger than
711 * the maximum shift of 0.5 */
712 assert(((nkpix - 1.) + 0.5 + k_offset) * SC_SINCNBIN + 1 < nsinc);
713 assert(((0 - 0.5 + k_offset)) * SC_SINCNBIN > 0);
714
715 /* Get pointer to sinc vector */
716 psinc = cpl_vector_get_data_const(sinc);
717
718 /* Do convolution in science spectrum table for each pixel of the modified
719 sky spectrum */
720
721 for (i = 0; i < nsky; i++) {
722 double shift, rsum, sum;
723 int npix, sign, h;
724
725 if (dpix[i] > 0.5 || dpix[i] < -0.5) {
726 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IIP,
727 "%s: shift < -0.5 or > 0.5",
728 SC_ERROR_IIP_TXT);
729 }
730
731 shift = dpix[i] - k_offset;
732 /* Get kernel values for given subpixel shift from sinc vector */
733 for (sum = 0., k = 0; k < nkpix; k++) {
734 double x = (double) (k - shift) * SC_SINCNBIN;
735 double low = psinc[(intptr_t)x];
736 double high = psinc[(intptr_t)(x + 1)];
737 kernel[k] = low + (high - low) * (x - floor(x));
738 sum += kernel[k];
739 }
740
741 /* Normalise kernel values */
742 rsum = 1. / sum;
743 for (k = 0; k < nkpix; k++) {
744 kernel[k] *= rsum;
745 }
746
747 /* Number of central pixels for convolution with same kernel
748 (> 1 only possible for margins) */
749 if (i == 0 && pmin > -radius) {
750 /* Lower margin */
751 npix = pmin + radius + 1;
752 sign = -1;
753 } else if (i == nsky - 1 && pmax < nsci - 1 + radius) {
754 /* Upper margin */
755 npix = nsci - pmax + radius;
756 sign = +1;
757 } else {
758 npix = 1;
759 sign = +1;
760 }
761
762 /* Convolve pixel(s) with kernel */
763 for (h = 0; h < npix; h++) {
764 int j;
765 for (k = 0, j = mpix[i] - radius + sign * h; k < nkpix;
766 k++, j++) {
767 if (j < 0 || j >= nsci) {
768 /* Skip invalid pixels */
769 continue;
770 }
771 cflux[j] += flux[i] * kernel[k];
772 }
773 }
774
775 }
776
777 return CPL_ERROR_NONE;
778}
779
780
781cpl_error_code sc_modsky_calcdev(cpl_table *scispec)
782{
803 size_t i, nrow;
804 const double * pdweight, * pdmweight;
805 const int * pisigclip;
806 double * pdcweight;
807
808 /* Calculate combined pixel weights of science spectrum and rebinned
809 modified sky spectrum under consideration of the sigma clipping
810 results for science data pixels from the initial estimate */
811
812 nrow = cpl_table_get_nrow(scispec);
813 cpl_table_fill_invalid_double(scispec, "weight", 0.);
814 cpl_table_fill_invalid_double(scispec, "mweight", 0.);
815 pdweight = cpl_table_get_data_double_const(scispec, "weight");
816 pdmweight = cpl_table_get_data_double_const(scispec, "mweight");
817 pisigclip = cpl_table_get_data_int_const(scispec, "sigclip");
818 pdcweight = cpl_table_get_data_double(scispec, "cweight");
819 cpl_table_fill_column_window(scispec, "cweight", 0, nrow, 0.);
820 for (i = 0; i < nrow; i++) {
821 double weff;
822 double wsci = pdweight[i];
823 double wsky = pdmweight[i];
824 int sigclip = pisigclip[i];
825 if (wsci > 0. && wsky > 0. && sigclip == 0) {
826 weff = 1. / sqrt(1. / (wsci * wsci) + 1. / (wsky * wsky));
827 } else {
828 weff = 0.;
829 }
830 pdcweight[i] = weff;
831 }
832
833 /* Calculate weighted deviations between modified sky and science
834 spectrum */
835 cpl_table_fill_column_window(scispec, "dev", 0, nrow, 0.);
836 cpl_table_add_columns(scispec, "dev", "mlflux");
837 cpl_table_subtract_columns(scispec, "dev", "lflux");
838 cpl_table_multiply_columns(scispec, "dev", "cweight");
839
840 return CPL_ERROR_NONE;
841}
842
cpl_error_code sc_basic_rebin(cpl_table *outspec, const char *outlam, const char *outflux, const cpl_table *inspec, const char *inlam, const char *influx)
Definition: sc_basic.c:296
#define SC_THERMIRLIM
Definition: sc_basic.h:102
#define SC_SINCRAD_PRECOMP
Definition: sc_basic.h:118
#define SC_TOL
Definition: sc_basic.h:96
#define SC_LENLINE
Definition: sc_basic.h:92
#define SC_SINCNBIN
Definition: sc_basic.h:120
cpl_error_code sc_modsky_moderrors(cpl_table *skyspec)
Definition: sc_modsky.c:246
cpl_error_code sc_modsky_rebin(cpl_table *scispec, cpl_table *skyspec, const cpl_vector *sinc, const cpl_parameterlist *parlist)
Definition: sc_modsky.c:436
cpl_error_code sc_modsky_modlines(cpl_table *skyspec, cpl_table *fitpar, const char grouptype)
Definition: sc_modsky.c:122
cpl_error_code sc_modsky(cpl_table *scispec, cpl_table *skyspec, cpl_table *fitpar, const cpl_vector *sinc, const cpl_parameterlist *parlist)
Definition: sc_modsky.c:53
cpl_error_code sc_modsky_calcdev(cpl_table *scispec)
Definition: sc_modsky.c:781
cpl_error_code sc_modsky_getpixelshifts(cpl_table *skyspec, const cpl_table *scispec)
Definition: sc_modsky.c:579
cpl_error_code sc_modsky_modwavegrid(cpl_table *skyspec, cpl_table *fitpar)
Definition: sc_modsky.c:296
cpl_error_code sc_modsky_sincrebin(cpl_table *scispec, const char *scicol, const cpl_table *skyspec, const char *skycol, const cpl_vector *sinc)
Definition: sc_modsky.c:640
#define SC_RELMAXERR
Definition: sc_modsky.h:66
int nfev
Definition: sc_mpfit.c:51
cpl_boolean lastcall
Definition: sc_mpfit.c:53