53cpl_error_code
sc_modsky(cpl_table *scispec, cpl_table *skyspec,
54 cpl_table *fitpar,
const cpl_vector *sinc,
55 const cpl_parameterlist *parlist)
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");
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");
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");
118 return CPL_ERROR_NONE;
123 const char grouptype)
146 int ngroup = 0, depth = 0, nrow = 0, i = 0, n = 0, j = 0, group = 0;
148 const cpl_array ** pa_narray, ** pa_warray;
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);
160 ngroup = cpl_table_get_nrow(grouppar);
163 sprintf(ncolname,
"ng%c", grouptype);
164 sprintf(wcolname,
"wg%c", grouptype);
167 depth = cpl_table_get_column_depth(skyspec, ncolname);
170 if (ngroup == 0 || depth == 0) {
173 cpl_msg_warning(cpl_func,
"No %c line groups", grouptype);
175 cpl_table_delete(grouppar);
176 return CPL_ERROR_NONE;
180 val = cpl_table_get_data_double(grouppar,
"value");
181 rel = cpl_table_get_data_int(grouppar,
"relevance");
184 nrow = cpl_table_get_nrow(skyspec);
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];
203 const cpl_array * narray = pa_narray[i];
204 const cpl_array * warray = pa_warray[i];
207 n = depth - cpl_array_count_invalid(narray);
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) {
225 wsum += wgroup * val[group-1];
240 cpl_table_delete(grouppar);
242 return CPL_ERROR_NONE;
264 double *cflux = NULL, *lflux = NULL, *mlflux = NULL, *dflux = NULL;
265 double *mdflux = NULL;
270 cpl_table_has_column(skyspec,
"mdflux") != 1) {
271 return CPL_ERROR_NONE;
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");
282 nrow = cpl_table_get_nrow(skyspec);
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]);
292 return CPL_ERROR_NONE;
321 int nlam = 0, ncoef = 0, i = 0, maxpix = -1, j = 0;
323 double limlam[2] = {0., 0.}, dlam = 0., wmean = 0., dellam = 0.;
325 double *slam, *mlam, *t;
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");
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);
341 ncoef = cpl_table_get_nrow(wpar);
345 if (ncoef > 0 && ncoef - 1 < cpl_table_get(wpar,
"N", ncoef - 1, NULL)) {
348 cpl_msg_warning(cpl_func,
"Invalid set of coefficients "
349 "for wavelength correction -> skip");
351 cpl_table_delete(wpar);
352 return CPL_ERROR_NONE;
358 if (
nfev == 1 && ncoef == 1) {
360 cpl_msg_warning(cpl_func,
"Only one coefficient "
361 "for wavelength correction -> skip");
363 cpl_table_delete(wpar);
364 return CPL_ERROR_NONE;
368 par = cpl_table_get_data_double(wpar,
"value");
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.);
380 slam = cpl_table_get_data_double(skyspec,
"slambda");
383 cpl_table_fill_column_window(skyspec,
"mlambda", 0, nlam, 0.);
384 mlam = cpl_table_get_data_double(skyspec,
"mlambda");
387 class = cpl_table_get_data_int(skyspec,
"class");
390 for (i = nlam-1; i >= 0; i--) {
399 cheby = cpl_array_new(ncoef, CPL_TYPE_DOUBLE);
400 t = cpl_array_get_data_double(cheby);
404 for (i = 0; i < nlam; i++) {
406 for (j = 0; j < ncoef; j++) {
410 t[j] = 2 * slam[i] * t[j-1] - t[j-2];
412 mlam[i] += par[j] * t[j];
415 dellam = mlam[i] - slam[i];
419 mlam[i] = slam[i] + dellam;
424 cpl_table_multiply_scalar(skyspec,
"mlambda", dlam / 2.);
425 cpl_table_add_scalar(skyspec,
"mlambda", wmean);
428 cpl_array_delete(cheby);
429 cpl_table_delete(wpar);
430 cpl_table_erase_column(skyspec,
"slambda");
432 return CPL_ERROR_NONE;
437 const cpl_vector *sinc,
438 const cpl_parameterlist *parlist)
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;
480 p = cpl_parameterlist_find_const(parlist,
"rebintype");
481 rebintype = cpl_parameter_get_int(p);
486 if (rebintype == 1) {
490 skyspec,
"mlambda",
"cflux");
495 if (rebintype == 1) {
499 skyspec,
"mlambda",
"mlflux");
505 cpl_table_has_column(skyspec,
"mdflux") == 1) {
506 if (rebintype == 1) {
510 skyspec,
"mlambda",
"mdflux");
515 cpl_table_new_column(scispec,
"tdflux", CPL_TYPE_DOUBLE);
516 cpl_table_new_column(skyspec,
"tdflux", CPL_TYPE_DOUBLE);
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) {
534 pd_tdflux = cpl_table_get_data_double(skyspec,
"tdflux");
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];
541 pd_tdflux[i] = maxerr;
543 pd_tdflux[i] = 1. / weight;
549 sc_basic_rebin(scispec,
"lambda",
"tdflux", skyspec,
"mlambda",
"tdflux");
553 pmin = cpl_table_get(skyspec,
"mpix", 0, NULL);
554 pmax = cpl_table_get(skyspec,
"mpix", nsky-1, NULL);
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");
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];
566 if (!(err > 1. / wmin || i < pmin || i > pmax)) {
567 pd_mweight[i] = 1. / err;
572 cpl_table_erase_column(skyspec,
"tdflux");
573 cpl_table_erase_column(scispec,
"tdflux");
575 return CPL_ERROR_NONE;
580 const cpl_table *scispec)
602 int nsci = 0, nsky = 0, *mpix, i = 0, j = 1;
603 double *skylam, *dpix, dlam = 0., shift = 0.;
604 const double *scilam;
607 nsci = cpl_table_get_nrow(scispec);
608 nsky = cpl_table_get_nrow(skyspec);
611 cpl_table_fill_column_window_int(skyspec,
"mpix", 0, nsky, 0);
612 cpl_table_fill_column_window_double(skyspec,
"dpix", 0, nsky, 0.);
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");
623 for (i = 0; i < nsky; i++) {
625 while (j < nsci - 1 && scilam[j] < skylam[i]) {
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;
636 return CPL_ERROR_NONE;
641 const cpl_table *skyspec,
643 const cpl_vector *sinc)
675 int nsci = 0, nsky = 0, pmin = 0, pmax = 0, i = 0, k = 0, nsinc = 0;
678 const double *dpix, *flux, *psinc;
681 const double radius = 5.;
682 const int nkpix = 2 * radius + 1;
683 double kernel[nkpix];
686 assert(k_offset >= 0);
689 nsci = cpl_table_get_nrow(scispec);
690 nsky = cpl_table_get_nrow(skyspec);
693 cpl_table_fill_column_window_double(scispec, scicol, 0, nsci, 0.);
696 cflux = cpl_table_get_data_double(scispec, scicol);
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);
708 nsinc = cpl_vector_get_size(sinc);
712 assert(((nkpix - 1.) + 0.5 + k_offset) *
SC_SINCNBIN + 1 < nsinc);
716 psinc = cpl_vector_get_data_const(sinc);
721 for (i = 0; i < nsky; i++) {
722 double shift, rsum, sum;
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",
731 shift = dpix[i] - k_offset;
733 for (sum = 0., k = 0; k < nkpix; k++) {
735 double low = psinc[(intptr_t)x];
736 double high = psinc[(intptr_t)(x + 1)];
737 kernel[k] = low + (high - low) * (x - floor(x));
743 for (k = 0; k < nkpix; k++) {
749 if (i == 0 && pmin > -radius) {
751 npix = pmin + radius + 1;
753 }
else if (i == nsky - 1 && pmax < nsci - 1 + radius) {
755 npix = nsci - pmax + radius;
763 for (h = 0; h < npix; h++) {
765 for (k = 0, j = mpix[i] - radius + sign * h; k < nkpix;
767 if (j < 0 || j >= nsci) {
771 cflux[j] += flux[i] * kernel[k];
777 return CPL_ERROR_NONE;
804 const double * pdweight, * pdmweight;
805 const int * pisigclip;
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++) {
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));
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");
840 return CPL_ERROR_NONE;
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)
#define SC_SINCRAD_PRECOMP
cpl_error_code sc_modsky_moderrors(cpl_table *skyspec)
cpl_error_code sc_modsky_rebin(cpl_table *scispec, cpl_table *skyspec, const cpl_vector *sinc, const cpl_parameterlist *parlist)
cpl_error_code sc_modsky_modlines(cpl_table *skyspec, cpl_table *fitpar, const char grouptype)
cpl_error_code sc_modsky(cpl_table *scispec, cpl_table *skyspec, cpl_table *fitpar, const cpl_vector *sinc, const cpl_parameterlist *parlist)
cpl_error_code sc_modsky_calcdev(cpl_table *scispec)
cpl_error_code sc_modsky_getpixelshifts(cpl_table *skyspec, const cpl_table *scispec)
cpl_error_code sc_modsky_modwavegrid(cpl_table *skyspec, cpl_table *fitpar)
cpl_error_code sc_modsky_sincrebin(cpl_table *scispec, const char *scicol, const cpl_table *skyspec, const char *skycol, const cpl_vector *sinc)