X-shooter Pipeline Reference Manual 3.8.15
xsh_subtract_sky_single.c
Go to the documentation of this file.
1/* *
2 * This file is part of the ESO X-shooter Pipeline *
3 * Copyright (C) 2006 European Southern Observatory *
4 * *
5 * This library 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, 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA *
18 * */
19
20/*
21 * $Author: amodigli $
22 * $Date: 2013-10-13 07:37:56 $
23 * $Revision: 1.122 $
24*/
25
26#ifdef HAVE_CONFIG_H
27#include <config.h>
28#endif
29
30
31/*----------------------------------------------------------------------------*/
38/*----------------------------------------------------------------------------*/
41/*-----------------------------------------------------------------------------
42 Includes
43 ----------------------------------------------------------------------------*/
44
45#include <math.h>
46#include <hdrl.h>
47
48#include <cpl.h>
49
50#include <gsl/gsl_bspline.h>
51#include <gsl/gsl_linalg.h>
52#include <gsl/gsl_rng.h>
53#include <gsl/gsl_statistics_double.h>
54#include <gsl/gsl_multifit.h>
55
56#include <xsh_drl.h>
57#include <xsh_drl_check.h>
58#include <xsh_badpixelmap.h>
59#include <xsh_data_pre.h>
60#include <xsh_data_order.h>
61#include <xsh_data_wavemap.h>
63#include <xsh_data_rec.h>
64#include <xsh_dfs.h>
65#include <xsh_pfits.h>
66#include <xsh_error.h>
67#include <xsh_utils.h>
68#include <xsh_utils_image.h>
69#include <xsh_utils_table.h>
70#include <xsh_msg.h>
71#include <xsh_fit.h>
72#include <xsh_model_r250.h>
74
75#define HAVE_INLINE 1
76#define REGDEBUG_MEDIAN_SPLINE 0
77#define REGDEBUG_BSPLINE 0
78
79/*-----------------------------------------------------------------------------
80 Functions prototypes
81 -----------------------------------------------------------------------------*/
82static xsh_wavemap_list* xsh_wavemap_list_new( cpl_frame *wavemap_frame,
83 cpl_frame *slitmap_frame, xsh_localization *list,
84 cpl_frame *order_table_frame, xsh_pre *pre_sci, int nbkpts,
85 cpl_frame* usr_def_sampl_points,cpl_frame* ref_sky_list,
86 cpl_frame* sky_orders_chunks,
90
91static int xsh_wave_compare( const void * un, const void * deux ) ;
92
93static cpl_frame* xsh_wavelist_subtract_sky( xsh_pre * pre_sci,
94 xsh_rec_list* sky_list,
95 xsh_wavemap_list * wave_list,
97 const char* rec_prefix,
99
100
101/* remove duplicate wavelength entries */
102static cpl_table*
103xsh_table_unique_wave(cpl_table* tab,const char* wname, const char* fname) {
104
105 cpl_table* xtab=NULL;
106 xtab=cpl_table_duplicate(tab);
107 int norg=cpl_table_get_nrow(xtab);
108 //xsh_msg("N orig %d",norg);
109 double* pwave=cpl_table_get_data_double(xtab,wname);
110 double* pflux=cpl_table_get_data_double(xtab,fname);
111 int ninv=1;
112 int nrow=0;
113 int nbad=0;
114 int j=0;
115
116 for(j=0;ninv>0 && j<3;j++) {
117
118 nrow=cpl_table_get_nrow(xtab);
119 /*
120 if (!(pwave[0] < pwave[1])) {
121 cpl_table_set_invalid(xtab,fname,1);
122 nbad++;
123 }
124 */
125 pwave=cpl_table_get_data_double(xtab,wname);
126 pflux=cpl_table_get_data_double(xtab,fname);
127 for(int i=1;i < nrow; i++) {
128 //xsh_msg("j=%d i=%d norg=%d nbad=%d nrow=%d",j,i,norg,nbad,nrow);
129 if ((pwave[i-1] == pwave[i])) {
130 /*
131 if(pwave[i-1]>1665.0 && pwave[i-1]<1665.8) {
132 xsh_msg("pwave=%g",pwave[i-1]);
133 }
134 */
135 if( ( pflux[i-1] <= pflux[i] ) && i >1 ) {
136
137 cpl_table_set_invalid(xtab,fname,i-1);
138 cpl_table_set_invalid(xtab,wname,i-1);
139 } else {
140 cpl_table_set_invalid(xtab,fname,i);
141 cpl_table_set_invalid(xtab,wname,i);
142 }
143 nbad++;
144 }
145 }
146 /*
147 if (!(pwave[nrow-2] < pwave[nrow-1])) {
148 cpl_table_set_invalid(xtab,fname,nrow-2);
149 nbad++;
150 }
151 */
152
153 ninv=cpl_table_count_invalid(xtab,fname);
154 xsh_msg("iter=%d nrow=%d nbad=%d ninv=%d",j,nrow,nbad,ninv);
155 if(ninv>0) {
156 cpl_table_erase_invalid(xtab);
157 } else {
158 break;
159 }
160 }
161
162
163 int nnew=cpl_table_get_nrow(xtab);
164 xsh_msg("niter %d N orig %d flagged %d expected %d new %d",
165 j,norg,nbad,norg-nbad,nnew);
166 return xtab;
167}
168
169
170/* not uniform data distribution */
171#if 0
172static double *
173xsh_bspline_fit_smooth(double* wave, double* flux,const int size_data,
174 double* swave, const int sno,
175 double ron2, double gain, xsh_instrument* inst)
176{
177 double * sflux=NULL;
178 size_t n = 0;
179 size_t order = 4;
180 size_t ncoeffs = 0;
181 size_t nbreak = 0;
182
183 size_t i, j;
184 gsl_bspline_workspace *bw;
185 gsl_vector *B;
186 gsl_vector *Bkpts;
187 //double dy;
188
189 gsl_vector *c, *w;
190 gsl_vector * x, *y;
191 gsl_matrix *X, *cov;
192 gsl_multifit_linear_workspace *mw;
193 double chisq=0, Rsq=0, dof=0;
194 double* pwav = NULL;
195 double* pfit = NULL;
196 cpl_table* tab_resp_fit = NULL;
197
198 double dump_factor=1.e10;
199 double *Bkpts_ptr;
200
201 /* set optimal number of coeffs for each arm */
202 if (xsh_instrument_get_arm(inst) == XSH_ARM_UVB) {
203 ncoeffs = 21;
204 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_VIS) {
205 ncoeffs = 16;
206 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_NIR) {
207 ncoeffs = 12;
208 } else {
209 xsh_msg("instrument arm not set");
210 abort();
211 }
212 ncoeffs=(wave[0]-wave[n-1])/0.5;
213 //xsh_msg("ncoeffs=%d",ncoeffs);
214 nbreak = ncoeffs + 2 - order;
215
216 n = size_data ;
217
218 gsl_rng_env_setup();
219
220 /* allocate a cubic bspline workspace (ORDER = order) */
221 bw = gsl_bspline_alloc(order, nbreak);
222
223 B = gsl_vector_alloc(ncoeffs);
224
225 Bkpts = gsl_vector_alloc(nbreak);
226
227 x = gsl_vector_alloc(n);
228 y = gsl_vector_alloc(n);
229 X = gsl_matrix_alloc(n, ncoeffs);
230 c = gsl_vector_alloc(ncoeffs);
231 w = gsl_vector_alloc(n);
232
233 cov = gsl_matrix_alloc(ncoeffs, ncoeffs);
234 mw = gsl_multifit_linear_alloc(n, ncoeffs);
235
236 /* this is the data to be fitted */
237 for (i = 0; i < n; ++i) {
238 double variance;
239 double xi = wave[i];
240 double yi = flux[i];
241
242 variance = ron2 * fabs(yi)/gain ;
243
244 gsl_vector_set(x, i, xi);
245 if(isnan(yi) || isinf(yi)) {
246 gsl_vector_set(y, i, 0);
247 gsl_vector_set(w, i, 1.0 / dump_factor);
248 } else {
249 gsl_vector_set(y, i, yi);
250 gsl_vector_set(w, i, 1.0 / variance );
251 }
252 }
253 //xsh_msg("ok5");
254 /* use uniform breakpoints on [wave[0], wave[n]] */
255 Bkpts_ptr=gsl_vector_ptr(Bkpts,0);
256 int nfit_div_nbreak=n/nbreak;
257
258 for(i=0;i<nbreak;i++) {
259 Bkpts_ptr[i]=wave[i*nfit_div_nbreak];
260 }
261 Bkpts_ptr[0]=wave[0];
262 Bkpts_ptr[nbreak-1]=wave[n-1];
263
264 gsl_bspline_knots(Bkpts, bw);
265 /*
266 for(i=0;i<10;i++){
267 xsh_msg("x[%d]=%g",i,gsl_vector_get(x,i));
268 }
269 for(i=n-10;i<n;i++){
270 xsh_msg("x[%d]=%g",i,gsl_vector_get(x,i));
271 }
272 */
273 //xsh_bspline_knots_not_uniform(x,bw);
274 //xsh_msg("ok1");
275 /* construct the fit matrix X */
276 for (i = 0; i < n; ++i) {
277 double xi = gsl_vector_get(x, i);
278 //xsh_msg("xi[%d]=%g",i,xi);
279 /* compute B_j(xi) for all j */
280 //xsh_msg("ok2");
281 gsl_bspline_eval(xi, B, bw);
282 //xsh_msg("ok3");
283 /* fill in row i of X */
284 for (j = 0; j < ncoeffs; ++j) {
285 double Bj = gsl_vector_get(B, j);
286 //xsh_msg("ok4 Bj=%g",Bj);
287 gsl_matrix_set(X, i, j, Bj);
288 //xsh_msg("ok5");
289 }
290 //xsh_msg("ok6");
291 }
292
293 //xsh_msg("ok7");
294 /* do the fit */
295 gsl_multifit_wlinear(X, w, y, c, cov, &chisq, mw);
296 //xsh_msg("ok8");
297 dof = n - ncoeffs;
298 /*
299 tss = gsl_stats_wtss(w->data, 1, y->data, 1, y->size);
300 Rsq = 1.0 - chisq / tss;
301 */
302 printf("chisq/dof = %e, Rsq = %f\n", chisq / dof, Rsq);
303
304 tab_resp_fit = cpl_table_new(sno);
305 cpl_table_new_column(tab_resp_fit, "wave", CPL_TYPE_DOUBLE);
306 cpl_table_new_column(tab_resp_fit, "fit", CPL_TYPE_DOUBLE);
307 cpl_table_fill_column_window_double(tab_resp_fit, "wave", 0, sno, 0);
308 cpl_table_fill_column_window_double(tab_resp_fit, "fit", 0, sno, 0);
309 pwav = cpl_table_get_data_double(tab_resp_fit, "wave");
310 pfit = cpl_table_get_data_double(tab_resp_fit, "fit");
311 sflux=cpl_calloc(sno, sizeof(double));
312 /* output the smoothed curve */
313 {
314 double xi, yi, yerr;
315 //printf("#m=1,S=0\n");
316 for (i = 0; i < sno; i++) {
317 xi = (double) swave[i];
318 gsl_bspline_eval(xi, B, bw);
319 gsl_multifit_linear_est(B, c, cov, &yi, &yerr);
320 //printf("%f %g\n", xi, yi);
321 pwav[i] = xi;
322 pfit[i] = yi;
323 swave[i]=xi;
324 sflux[i]=yi;
325 }
326 }
327 cpl_table_save(tab_resp_fit, NULL, NULL, "resp_fit.fits", CPL_IO_DEFAULT);
328 //xsh_msg("ok9");
329 //cleanup:
330 xsh_free_table(&tab_resp_fit);
331
332 gsl_bspline_free(bw);
333 gsl_vector_free(B);
334 gsl_vector_free(Bkpts);
335 gsl_vector_free(x);
336 gsl_vector_free(y);
337 gsl_matrix_free(X);
338 gsl_vector_free(c);
339 gsl_vector_free(w);
340 gsl_matrix_free(cov);
341 gsl_multifit_linear_free(mw);
342
343 return sflux;
344}
345#endif
346#if 0
347static cpl_table*
348xsh_detect_outliers_tab(const int order,const int idx, const int nitem,
349 const xsh_wavemap_list* wlist, const float* yf,
350 const int iter)
351{
352 double* pw=NULL;
353 double* pslit=NULL;
354
355 double* pf=NULL;
356 double* ps=NULL;
357 double* px=NULL;
358 double* py=NULL;
359 double* pfit=NULL;
360 double* prat=NULL;
361 double* perr=NULL;
362 int * pflag=NULL;
363 wavemap_item* pentry=NULL;
364 char fname[128];
365
366 cpl_table* otab=cpl_table_new(nitem);
367 cpl_table_new_column(otab,"WAVE",CPL_TYPE_DOUBLE);
368 cpl_table_new_column(otab,"SLIT",CPL_TYPE_DOUBLE);
369 cpl_table_new_column(otab,"FLUX",CPL_TYPE_DOUBLE);
370 cpl_table_new_column(otab,"SIGMA",CPL_TYPE_DOUBLE);
371 cpl_table_new_column(otab,"FIT",CPL_TYPE_DOUBLE);
372
373 cpl_table_new_column(otab,"ERR",CPL_TYPE_DOUBLE);
374 cpl_table_new_column(otab,"RAT",CPL_TYPE_DOUBLE);
375 cpl_table_new_column(otab,"X",CPL_TYPE_DOUBLE);
376 cpl_table_new_column(otab,"Y",CPL_TYPE_DOUBLE);
377 cpl_table_new_column(otab,"FLAG",CPL_TYPE_INT);
378
379 cpl_table_fill_column_window_double(otab,"WAVE",0,nitem,0.);
380 cpl_table_fill_column_window_double(otab,"SLIT",0,nitem,0.);
381 cpl_table_fill_column_window_double(otab,"FLUX",0,nitem,0.);
382 cpl_table_fill_column_window_double(otab,"SIGMA",0,nitem,0.);
383 cpl_table_fill_column_window_double(otab,"FIT",0,nitem,0.);
384 cpl_table_fill_column_window_double(otab,"ERR",0,nitem,0.);
385 cpl_table_fill_column_window_double(otab,"RAT",0,nitem,0.);
386 cpl_table_fill_column_window_int(otab,"FLAG",0,nitem,0.);
387 cpl_table_fill_column_window_double(otab,"X",0,nitem,0.);
388 cpl_table_fill_column_window_double(otab,"Y",0,nitem,0.);
389
390 pw=cpl_table_get_data_double(otab,"WAVE");
391 pf=cpl_table_get_data_double(otab,"FLUX");
392 pslit=cpl_table_get_data_double(otab,"SLIT");
393 ps=cpl_table_get_data_double(otab,"SIGMA");
394 pfit=cpl_table_get_data_double(otab,"FIT");
395 prat=cpl_table_get_data_double(otab,"RAT");
396 perr=cpl_table_get_data_double(otab,"ERR");
397 px=cpl_table_get_data_double(otab,"X");
398 py=cpl_table_get_data_double(otab,"Y");
399
400
401
402 pentry = wlist->list[idx].sky;
403 int i;
404 /* fill table with values */
405 for (i = 0; i < nitem; i++, pentry++) {
406 double yerr = 0;
407 double yi = yf[i];
408 pentry->fitted = yi;
409 pentry->fit_err = yerr;
410
411 pw[i] = pentry->lambda;
412 pslit[i] = pentry->slit;
413 pf[i] = pentry->flux;
414 ps[i] = pentry->sigma;
415 pfit[i] = pentry->fitted;
416 perr[i] = pentry->fit_err;
417 prat[i] = pf[i] / pfit[i];
418 px[i] = pentry->ix;
419 py[i] = pentry->iy;
420 }
421
422 cpl_table_duplicate_column(otab,"FLUX_SMOOTH",otab,"FLUX");
423 cpl_vector* vec_flux=NULL;
424 cpl_vector* vec_smooth=NULL;
425 vec_flux = cpl_vector_wrap(nitem,cpl_table_get_data_double(otab,"FLUX"));
426 vec_smooth=cpl_vector_filter_lowpass_create(vec_flux,CPL_LOWPASS_LINEAR,1);
427 cpl_vector_unwrap(vec_flux);
428 double* pts=cpl_table_get_data_double(otab,"FLUX_SMOOTH");
429 double* pvs=cpl_vector_get_data(vec_smooth);
430 pentry = wlist->list[idx].sky;
431 for (i = 0; i < nitem; i++, pentry++) {
432 pts[i]=pvs[i];
433 }
434 cpl_vector_delete(vec_smooth);
435 cpl_table_duplicate_column(otab,"FLUX_SMO",otab,"FLUX");
436 cpl_table_divide_columns(otab,"FLUX_SMO","FLUX_SMOOTH");
437
438
439
440 double mean=0;
441 double median=0;
442 double min=0;
443 double max=0;
444 double rms=0;
445 double kappa=10;
446 int niter=1;
447 int n=0;
448 int j=0;
449 prat=cpl_table_get_data_double(otab,"RAT");
450 pflag=cpl_table_get_data_int(otab,"FLAG");
451
452 /* check for bad pix */
453 prat=cpl_table_get_data_double(otab,"FLUX_SMO");
454 pflag=cpl_table_get_data_int(otab,"FLAG");
455
456 for(i=0 ;i<niter;i++) {
457 mean=cpl_table_get_column_mean(otab,"FLUX_SMO");
458 median=cpl_table_get_column_median(otab,"FLUX_SMO");
459 rms=cpl_table_get_column_stdev(otab,"FLUX_SMO");
460 min=cpl_table_get_column_min(otab,"FLUX_SMO");
461 max=cpl_table_get_column_max(otab,"FLUX_SMO");
462 for(j=0;j<nitem;j++) {
463 if( prat[j] < mean-kappa*rms ) {
464 cpl_table_set_invalid(otab,"FLUX_SMO",j);
465 pflag[j]=-2;
466 } else if( prat[j] > mean+kappa*rms ) {
467 cpl_table_set_invalid(otab,"FLUX_SMO",j);
468 pflag[j]=2;
469 }
470 }
471
472 n=cpl_table_count_invalid(otab,"FLUX_SMO");
473 xsh_msg("mean=%g median=%g rms=%g min=%g max=%g invalid=%d",
474 mean,median,rms,min,max,n);
475
476 }
477
478
479 prat=cpl_table_get_data_double(otab,"RAT");
480 /* check for bad fit */
481 for(i=0 ;i<niter;i++) {
482 mean=cpl_table_get_column_mean(otab,"RAT");
483 median=cpl_table_get_column_median(otab,"RAT");
484 rms=cpl_table_get_column_stdev(otab,"RAT");
485 min=cpl_table_get_column_min(otab,"RAT");
486 max=cpl_table_get_column_max(otab,"RAT");
487 for(j=0;j<nitem;j++) {
488 if( prat[j] < mean-kappa*rms ) {
489 cpl_table_set_invalid(otab,"RAT",j);
490 pflag[j]=-1;
491 } else if( prat[j] > mean+kappa*rms ) {
492 cpl_table_set_invalid(otab,"RAT",j);
493 pflag[j]=1;
494 }
495 }
496
497 n=cpl_table_count_invalid(otab,"RAT");
498 xsh_msg("mean=%g median=%g rms=%g min=%g max=%g invalid=%d",
499 mean,median,rms,min,max,n);
500
501 }
502
503
504 FILE* fout = NULL;
505 xsh_msg_dbg_medium("Output fitted data");
506#if REGDEBUG_BSPLINE
507 sprintf(fname, "outlier1d_ord_%02d_iter_%02d.reg", order,iter);
508 fout = fopen(fname, "w");
509 fprintf(fout, "# x y\n");
510#endif
511 pentry = wlist->list[idx].sky;
512 for (i = 0; i < nitem; i++, pentry++) {
513
514 if(pflag[i] == -1 || pflag[i] == 1 )
515 {
516#if REGDEBUG_BSPLINE
517 fprintf(fout,"x point (%f %f) #color=red \n", px[i]+1,py[i]+1);
518#endif
520 }
521 if(pflag[i] == -2 || pflag[i] == 2 ) {
522#if REGDEBUG_BSPLINE
523 fprintf(fout,"x point (%f %f) #color=blue \n",px[i]+1,py[i]+1);
524#endif
526 }
527
528 }
529
530
531 sprintf(fname,"outlier1d_order_%02d_iter_%02d.fits",order,iter);
532 //cpl_table_save(otab,NULL,NULL,fname,CPL_IO_DEFAULT);
533 cpl_table_and_selected_int(otab,"FLAG", CPL_EQUAL_TO, 2);
534 cpl_table_or_selected_int(otab,"FLAG", CPL_EQUAL_TO, -2);
535 cpl_table* xtab=cpl_table_extract_selected(otab);
536
537
538
539 cpl_table_erase_column(xtab,"RAT");
540 cpl_table_erase_column(xtab,"FLUX_SMOOTH");
541 cpl_table_erase_column(xtab,"FLUX_SMO");
542 cpl_table_erase_column(xtab,"SIGMA");
543 cpl_table_erase_column(xtab,"FIT");
544 cpl_table_erase_column(xtab,"FLAG");
545 cpl_table_erase_column(xtab,"SLIT");
546 cpl_table_erase_column(xtab,"FLUX");
547 cpl_table_erase_column(xtab,"ERR");
548
549 /* adjust column names */
550 cpl_table_name_column(otab,"WAVE","WAVELENGTH");
551 /* make sure there are no 0 */
552 cpl_table_and_selected_double(otab,"WAVELENGTH",CPL_EQUAL_TO,0);
553 cpl_table_erase_selected(otab);
554
555
556 //xsh_msg("iter=%d idx=%d",iter,idx);
557
558
559 xsh_free_table(&otab);
560 if ( fout ) fclose( fout ) ;
561
562 return xtab;
563}
564#endif
573static cpl_table*
575{
576 double* pwave=NULL;
577 double* pflux=NULL;
578 double* px=NULL;
579 double* py=NULL;
580 double* perr=NULL;
581 double* pslit=NULL;
582 int* pqual=NULL;
583 int sky_ndata = wlist->list[order].sky_size;
584
585 /* put data in a table */
586 cpl_table* otab=cpl_table_new(sky_ndata);
587 cpl_table_new_column(otab,"WAVE",CPL_TYPE_DOUBLE);
588 cpl_table_new_column(otab,"FLUX",CPL_TYPE_DOUBLE);
589 cpl_table_new_column(otab,"ERR",CPL_TYPE_DOUBLE);
590 cpl_table_new_column(otab,"QUAL",CPL_TYPE_INT);
591 cpl_table_new_column(otab,"SLIT",CPL_TYPE_DOUBLE);
592 cpl_table_new_column(otab,"X",CPL_TYPE_DOUBLE);
593 cpl_table_new_column(otab,"Y",CPL_TYPE_DOUBLE);
594
595 cpl_table_fill_column_window_double(otab,"WAVE",0,sky_ndata,0.);
596 cpl_table_fill_column_window_double(otab,"FLUX",0,sky_ndata,0.);
597 cpl_table_fill_column_window_double(otab,"ERR",0,sky_ndata,0.);
598 cpl_table_fill_column_window_int(otab,"QUAL",0,sky_ndata,0);
599 cpl_table_fill_column_window_double(otab,"SLIT",0,sky_ndata,0.);
600 cpl_table_fill_column_window_double(otab,"X",0,sky_ndata,0.);
601 cpl_table_fill_column_window_double(otab,"Y",0,sky_ndata,0.);
602
603 pwave=cpl_table_get_data_double(otab,"WAVE");
604 pflux=cpl_table_get_data_double(otab,"FLUX");
605 perr=cpl_table_get_data_double(otab,"ERR");
606 pqual=cpl_table_get_data_int(otab,"QUAL");
607 pslit=cpl_table_get_data_double(otab,"SLIT");
608 px=cpl_table_get_data_double(otab,"X");
609 py=cpl_table_get_data_double(otab,"Y");
610 //int decode_bp=wlist->instrument->decode_bp;
611 wavemap_item* psky=NULL;
612 psky = wlist->list[order].sky;
613
614 /* fill table with values */
615 for (int i = 0; i < sky_ndata; i++, psky++) {
616 pwave[i] = psky->lambda;
617 pflux[i] = psky->flux;
618 perr[i] = psky->sigma;
619 pqual[i] = psky->qual;
620 pslit[i] = psky->slit;
621 px[i] = psky->ix;
622 py[i] = psky->iy;
623 }
624
625 return otab;
626}
637static cpl_error_code
639 const char* name_i, const char* name_o, const int hsize)
640{
641 /* smooth data to later find bad pixels */
642 cpl_table_duplicate_column(*tab,name_o,*tab,name_i);
643
644 cpl_vector* v_flux=NULL;
645 cpl_vector* v_smooth=NULL;
646 int nrow=cpl_table_get_nrow(*tab);
647 v_flux = cpl_vector_wrap(nrow,cpl_table_get_data_double(*tab,name_i));
648 v_smooth=cpl_vector_filter_median_create(v_flux,hsize);
649 cpl_vector_unwrap(v_flux);
650 double* pts=cpl_table_get_data_double(*tab,"FLUX_SMOOTH");
651
652 double* pvs=cpl_vector_get_data(v_smooth);
653
654 for (int i = 0; i < nrow; i++) {
655 pts[i]=pvs[i];
656 }
657 cpl_vector_delete(v_smooth);
658
659 return cpl_error_get_code();
660}
661
662
663static cpl_error_code
664xsh_table_column_clip(cpl_table** tab, const char* name_d, const char* name_s,
665 const double kappa, const int niter,
666 const double gain, const double ron2, const int decode_bp)
667{
668 double median=0;
669 int n=0;
670
671 int nrow=cpl_table_get_nrow(*tab);
672 cpl_table_new_column(*tab,"FLAG",CPL_TYPE_INT);
673 cpl_table_fill_column_window_int(*tab,"FLAG",0,nrow,0);
674 int* pflag=cpl_table_get_data_int(*tab,"FLAG");
675
676 //cpl_table_duplicate_column(*tab,"RAT",*tab,"FLUX");
677 cpl_table_duplicate_column(*tab,"DIF",*tab,name_d);
678 cpl_table_subtract_columns(*tab,"DIF",name_s);
679 //CONTROLLA
680 cpl_table_duplicate_column(*tab,"SIG",*tab,name_s);
681 //cpl_table_duplicate_column(*tab,"SIG",*tab,"ERR");
682
683 cpl_table_abs_column(*tab,"SIG");
684 cpl_table_divide_scalar(*tab,"SIG",gain);
685 cpl_table_add_scalar(*tab,"SIG",ron2);
686 cpl_table_power_column(*tab,"SIG",0.5);
687 //cpl_table_divide_columns(*tab,"RAT","FLUX_SMOOTH");
688 //prat=cpl_table_get_data_double(*tab,"RAT");
689 double* pdif=cpl_table_get_data_double(*tab,"DIF");
690 double* perr=cpl_table_get_data_double(*tab,"SIG");
691 int* pqual=cpl_table_get_data_int(*tab,"QUAL");
692 int ninv=0;
693 int n_tot=0;
694 int k=0;
695 //cpl_table_save(*tab,NULL,NULL,"pippo.fits",CPL_IO_DEFAULT);
696
697 for(int i=0 ;i<niter;i++) {
698 median=cpl_table_get_column_median(*tab,"DIF");
699
700 //double mean=cpl_table_get_column_mean(*tab,"DIF");
701 //xsh_msg("median=%g mean=%g",median,mean);
702 //we keep the 1st and last points even if outliers to keep the full
703 // wave range
704 for (k = 1; k < nrow-1; k++) {
705 int check_data_quality = (( ( pqual[k] & decode_bp ) > 0 ) &&
706 ( pqual[k] != QFLAG_SATURATED_DATA )) ? 1:0;
707 check_data_quality=0;
708
709 if( (pdif[k] < median-kappa*perr[k] ||
710 pdif[k] > median+kappa*perr[k] ) ||
711 (check_data_quality == 1) ){
712 /*
713 xsh_msg("median=%g kappa=%g err=%g thresh min=%g max=%g",
714 median,kappa,perr[k],-kappa*perr[k],kappa*perr[k]);
715 xsh_msg("xsh dif=%g thresh min=%g max=%g",pdif[k],median-kappa*perr[k],median+kappa*perr[k]);
716 */
717 cpl_table_set_invalid(*tab,"DIF",k);
718 pflag[k]=1;
719 ninv++;
720 }
721
722 n=cpl_table_count_invalid(*tab,"DIF");
723 }
724 n_tot+=n;
725
726 //xsh_msg("mean=%g median=%g rms=%g min=%g max=%g invalid=%d",
727 // mean,median,rms,min,max,n);
728
729 }
730 xsh_msg("Points flagged as invalid %d vs n_tot %d", ninv,n_tot);
731
732 //exit(0);
733 return cpl_error_get_code();
734}
735
736
737
750static cpl_table*
752 const double ron2, const double gain,
753 const int order, const int iter,
754 const int decode_bp)
755{
756
757 cpl_table* otab=NULL;
758 /* put data in a table */
759 otab=xsh_model_to_table(wlist,order);
760
761 // smooth data to later find bad pixels
762 xsh_table_column_smooth(&otab,"FLUX", "FLUX_SMOOTH", hsize);
763 double kappa=5;
764 int niter=10;
765 xsh_table_column_clip(&otab, "FLUX", "FLUX_SMOOTH", kappa, niter, gain,
766 ron2, decode_bp);
767
768 /* save outliers location in region files */
769 FILE* fout = NULL;
770
771 xsh_msg_dbg_medium("Output fitted data");
772 //char fname[128];
773#if REGDEBUG_BSPLINE
774 sprintf(fname, "outlier1d_ord_%02d_iter_%02d.reg", order,iter);
775 fout = fopen(fname, "w");
776 fprintf(fout, "# x y\n");
777#endif
778 /* reset the sky to the starting point */
779 wavemap_item* psky = wlist->list[order].sky;
780 psky = wlist->list[order].sky;
781
782 /*we keep the 1st and last points even if outliers to keep the full
783 * wave range */
784 int * pflag=NULL;
785#if REGDEBUG_BSPLINE
786 double* px=NULL;
787 double* py=NULL;
788 px=cpl_table_get_data_double(otab,"X");
789 py=cpl_table_get_data_double(otab,"Y");
790#endif
791 pflag=cpl_table_get_data_int(otab,"FLAG");
792 int* pqual=cpl_table_get_data_int(otab,"QUAL");
793 int sky_ndata = wlist->list[order].sky_size;
794
795 for (int i = 1; i < sky_ndata-1; i++,psky++) {
796 if( pflag[i] == 1 ) {
797#if REGDEBUG_BSPLINE
798 fprintf(fout,"x point (%f %f) #color=blue \n",px[i]+1,py[i]+1);
799#endif
802 }
803 }
804
805#if REGDEBUG_BSPLINE
806 sprintf(fname,"outlier1d_order_%02d_iter_%02d.fits",order,iter);
807 cpl_table_save(otab,NULL,NULL,fname,CPL_IO_DEFAULT);
808#endif
809
810 /* keep only good points */
811 cpl_table_and_selected_int(otab,"FLAG", CPL_EQUAL_TO, 0);
812 cpl_table* xtab=cpl_table_extract_selected(otab);
813 int n=cpl_table_get_nrow(xtab);
814 xsh_msg("Points remained after flagging outliers %d", n);
815 /* as the initial table was oversampled make sure there are no 0 */
816 cpl_table_and_selected_double(xtab,"WAVE",CPL_EQUAL_TO,0);
817 cpl_table_erase_selected(xtab);
818 n=cpl_table_get_nrow(xtab);
819#if REGDEBUG_BSPLINE
820 sprintf(fname,"tab_clean_order_%02d_iter_%02d.fits",order,iter);
821 cpl_table_save(xtab,NULL,NULL,fname,CPL_IO_DEFAULT);
822#endif
823 xsh_msg("Points remained after removal 0 waves %d", n);
824
825 cpl_table_erase_column(xtab,"SIG");
826 xsh_free_table(&otab);
827 if ( fout ) fclose( fout ) ;
828//cleanup:
829 return xtab;
830}
831
832
833
846static cpl_table*
848 const double ron2, const double gain,
849 const int order, const int iter,
850 const int decode_bp,
851 const double s1,
852 const double s2, const int slice_id)
853{
854
855 cpl_table* otab=NULL;
856 /* put data in a table */
857 check(otab=xsh_model_to_table(wlist,order));
858 xsh_msg("s1=%g s2=%g",s1,s2);
859 cpl_table_and_selected_double(otab,"SLIT",CPL_NOT_LESS_THAN,s1);
860 cpl_table_and_selected_double(otab,"SLIT",CPL_LESS_THAN,s2);
861 //cpl_table_and_selected_double(otab,"SLIT",CPL_NOT_GREATER_THAN,s2);
862 cpl_table* stab=NULL;
863 stab=cpl_table_extract_selected(otab);
864 xsh_free_table(&otab);
865 //xsh_msg("ck1 hsize=%d",hsize);
866 //cpl_table_dump_structure(stab,stdout);
867 // smooth data to later find bad pixels
868 check(xsh_table_column_smooth(&stab,"FLUX", "FLUX_SMOOTH", hsize));
869 double kappa=5;
870 int niter=10;
871 check(xsh_table_column_clip(&stab, "FLUX", "FLUX_SMOOTH", kappa, niter, gain,
872 ron2, decode_bp));
873 /* save outliers location in region files */
874 FILE* fout = NULL;
875
876 xsh_msg_dbg_medium("Output fitted data");
877 //char fname[128];
878#if REGDEBUG_BSPLINE
879 sprintf(fname, "outlier1d_ord_%02d_slice_%02d_order_%02d.reg",
880 order,slice_id,iter);
881 fout = fopen(fname, "w");
882 fprintf(fout, "# x y\n");
883#endif
884 /* reset the sky to the starting point */
885 wavemap_item* psky = wlist->list[order].sky;
886 psky = wlist->list[order].sky;
887
888 /*we keep the 1st and last points even if outliers to keep the full
889 * wave range */
890 double* px=NULL;
891 double* py=NULL;
892 double* pw=NULL;
893 int * pflag=NULL;
894 int nrow=0;
895 nrow=cpl_table_get_nrow(stab);
896 px=cpl_table_get_data_double(stab,"X");
897 py=cpl_table_get_data_double(stab,"Y");
898 pw=cpl_table_get_data_double(stab,"WAVE");
899 pflag=cpl_table_get_data_int(stab,"FLAG");
900 int* pqual=cpl_table_get_data_int(stab,"QUAL");
901 int sky_ndata = wlist->list[order].sky_size;
902
903 for(int k=0; k<nrow; k++) {
904 if( pflag[k] == 1 ) {
905 psky = wlist->list[order].sky;
906 for (int i = 1; i < sky_ndata-1; i++,psky++) {
907 if( psky->slit >= s1 && psky->slit <= s2 ) {
908 if( pw[k] == psky->lambda &&
909 px[k] == psky->ix && py[k] == psky->iy ) {
910#if REGDEBUG_BSPLINE
911 fprintf(fout,"x point (%f %f) #color=blue \n",px[k]+1,py[k]+1);
912#endif
915 }
916 }
917 }
918 }
919 }
920
921#if REGDEBUG_BSPLINE
922 sprintf(fname,"outlier1d_order_%02d_slice_%02d_iter_%02d.fits",
923 order,slice_id,iter);
924 cpl_table_save(stab,NULL,NULL,fname,CPL_IO_DEFAULT);
925#endif
926
927 /* keep only good points */
928 check(cpl_table_and_selected_int(stab,"FLAG", CPL_EQUAL_TO, 0));
929 cpl_table* xtab=cpl_table_extract_selected(stab);
930
931 xsh_free_table(&stab);
932 int n=cpl_table_get_nrow(xtab);
933 xsh_msg("Points remained after flagging outliers %d", n);
934 /* as the initial table was oversampled make sure there are no 0 */
935 cpl_table_and_selected_double(xtab,"WAVE",CPL_EQUAL_TO,0);
936 cpl_table_erase_selected(xtab);
937 n=cpl_table_get_nrow(xtab);
938#if REGDEBUG_BSPLINE
939 sprintf(fname,"tab_clean_order_%02d_slice_%02d_iter_%02d.fits",
940 order,slice_id,iter);
941 cpl_table_save(xtab,NULL,NULL,fname,CPL_IO_DEFAULT);
942#endif
943 xsh_msg("Points remained after removal 0 waves %d", n);
944 cpl_table_erase_column(xtab,"SIG");
945
946 if ( fout ) fclose( fout ) ;
947cleanup:
948 return xtab;
949}
950
951#if 0
952/* not used ! */
953static cpl_error_code
954xsh_dump_sky_fit(const int order,const int idx, const int nitem,
955 const xsh_wavemap_list* wlist, const float* yf,
956 const int iter)
957{
958 double* pw=NULL;
959 double* pslit=NULL;
960
961 double* pf=NULL;
962 double* ps=NULL;
963 double* px=NULL;
964 double* py=NULL;
965 double* pfit=NULL;
966 double* prat=NULL;
967 double* perr=NULL;
968 double* pdif=NULL;
969 wavemap_item* pentry=NULL;
970 //char fname[128];
971
972
973 cpl_table* debug_fit=cpl_table_new(nitem);
974 cpl_table_new_column(debug_fit,"WAVE",CPL_TYPE_DOUBLE);
975 cpl_table_new_column(debug_fit,"SLIT",CPL_TYPE_DOUBLE);
976 cpl_table_new_column(debug_fit,"FLUX",CPL_TYPE_DOUBLE);
977 cpl_table_new_column(debug_fit,"SIGMA",CPL_TYPE_DOUBLE);
978 cpl_table_new_column(debug_fit,"DIF",CPL_TYPE_DOUBLE);
979 cpl_table_new_column(debug_fit,"FIT",CPL_TYPE_DOUBLE);
980 cpl_table_new_column(debug_fit,"ERR",CPL_TYPE_DOUBLE);
981 cpl_table_new_column(debug_fit,"RAT",CPL_TYPE_DOUBLE);
982 cpl_table_new_column(debug_fit,"X",CPL_TYPE_DOUBLE);
983 cpl_table_new_column(debug_fit,"Y",CPL_TYPE_DOUBLE);
984
985 cpl_table_fill_column_window_double(debug_fit,"WAVE",0,nitem,0.);
986 cpl_table_fill_column_window_double(debug_fit,"SLIT",0,nitem,0.);
987 cpl_table_fill_column_window_double(debug_fit,"FLUX",0,nitem,0.);
988 cpl_table_fill_column_window_double(debug_fit,"SIGMA",0,nitem,0.);
989 cpl_table_fill_column_window_double(debug_fit,"DIF",0,nitem,0.);
990 cpl_table_fill_column_window_double(debug_fit,"FIT",0,nitem,0.);
991 cpl_table_fill_column_window_double(debug_fit,"ERR",0,nitem,0.);
992 cpl_table_fill_column_window_double(debug_fit,"RAT",0,nitem,0.);
993 cpl_table_fill_column_window_double(debug_fit,"X",0,nitem,0.);
994 cpl_table_fill_column_window_double(debug_fit,"Y",0,nitem,0.);
995
996 pw=cpl_table_get_data_double(debug_fit,"WAVE");
997 pf=cpl_table_get_data_double(debug_fit,"FLUX");
998 pslit=cpl_table_get_data_double(debug_fit,"SLIT");
999 ps=cpl_table_get_data_double(debug_fit,"SIGMA");
1000 pfit=cpl_table_get_data_double(debug_fit,"FIT");
1001 pdif=cpl_table_get_data_double(debug_fit,"DIF");
1002 prat=cpl_table_get_data_double(debug_fit,"RAT");
1003 perr=cpl_table_get_data_double(debug_fit,"ERR");
1004 px=cpl_table_get_data_double(debug_fit,"X");
1005 py=cpl_table_get_data_double(debug_fit,"Y");
1006 xsh_msg_dbg_medium("Output fitted data");
1007
1008 FILE* fout = NULL;
1009#if REGDEBUG_BSPLINE
1010 sprintf(fname, "sky_fit_%02d_%02d.dat", order,iter);
1011 fout = fopen(fname, "w");
1012#endif
1013 pentry = wlist->list[idx].sky;
1014 int i;
1015 for (i = 0; i < nitem; i++, pentry++) {
1016 double yerr = 0;
1017 double yi = yf[i];
1018 pentry->fitted = yi;
1019 pentry->fit_err = yerr;
1020#if REGDEBUG_BSPLINE
1021 fprintf(fout, "%f %f %f %d %d ", pentry->lambda, pentry->flux,
1022 pentry->sigma, pentry->ix, pentry->iy);
1023 fprintf(fout, "%lf %lf\n", yi, yerr);
1024#endif
1025
1026 pw[i] = pentry->lambda;
1027 pslit[i] = pentry->slit;
1028 pf[i] = pentry->flux;
1029 ps[i] = pentry->sigma;
1030 pfit[i] = pentry->fitted;
1031 perr[i] = pentry->fit_err;
1032 prat[i] = pf[i] / pfit[i];
1033 pdif[i] = pf[i] - pfit[i];
1034 px[i] = pentry->ix;
1035 py[i] = pentry->iy;
1036 }
1037
1038
1039#if REGDEBUG_BSPLINE
1040 sprintf(fname,"sky_fit_%02d_%02d.fits",order,iter);
1041 cpl_table_save(debug_fit,NULL,NULL,fname,CPL_IO_DEFAULT);
1042#endif
1043 double rms =cpl_table_get_column_stdev(debug_fit,"DIF");
1044 xsh_msg("iter=%d idx=%d rms=%g",iter,idx,rms);
1045
1046 xsh_free_table(&debug_fit);
1047 if ( fout ) fclose( fout ) ;
1048 return cpl_error_get_code();
1049}
1050#endif
1051
1052static int
1053xsh_get_edge_x_min(xsh_order_list* otab, const int iorder, const int iy)
1054{
1055 int x_min_offset = +1; /* was +1 */
1056
1057 int minx = xsh_order_list_eval_int(otab, otab->list[iorder].edglopoly, iy)
1058 + x_min_offset;
1059
1060 return minx;
1061}
1062
1063static int
1064xsh_get_edge_x_max(xsh_order_list* otab, const int iorder, const int iy)
1065{
1066 int x_max_offset = -1; /* was -1 */
1067
1068 int maxx = xsh_order_list_eval_int(otab, otab->list[iorder].edguppoly, iy)
1069 + x_max_offset;
1070
1071 return maxx;
1072}
1073
1074/*
1075static cpl_error_code
1076xsh_dump_sky_sampl(const int order, const int idx, const int nitem,
1077 const xsh_wavemap_list* wlist, gsl_vector *Bkpts,
1078 const int nbkpts)
1079{
1080
1081 double* pw=NULL;
1082 double* px=NULL;
1083 double* py=NULL;
1084 wavemap_item* pentry=NULL;
1085 wavemap_item* pentry_start=NULL;
1086 double *Bkpts_ptr=gsl_vector_ptr(Bkpts,0);
1087 //char fname[128];
1088
1089 pentry_start = wlist->list[idx].sky;
1090 int i,j;
1091
1092#if REGDEBUG_BSPLINE
1093 FILE* fout = NULL;
1094 sprintf(fname, "sky_line_sampl_pts_%02d.reg", order);
1095 fout = fopen(fname, "w");
1096#endif
1097
1098 cpl_table* sampl_fit=cpl_table_new(nbkpts);
1099 cpl_table_new_column(sampl_fit,"WAVE",CPL_TYPE_DOUBLE);
1100 cpl_table_new_column(sampl_fit,"X",CPL_TYPE_DOUBLE);
1101 cpl_table_new_column(sampl_fit,"Y",CPL_TYPE_DOUBLE);
1102 cpl_table_fill_column_window_double(sampl_fit,"WAVE",0,nbkpts,0.);
1103 cpl_table_fill_column_window_double(sampl_fit,"X",0,nbkpts,0.);
1104 cpl_table_fill_column_window_double(sampl_fit,"Y",0,nbkpts,0.);
1105 pw=cpl_table_get_data_double(sampl_fit,"WAVE");
1106 px=cpl_table_get_data_double(sampl_fit,"X");
1107 py=cpl_table_get_data_double(sampl_fit,"Y");
1108
1109 for(i=0;i<nbkpts-1;i++) {
1110 pw[i]=Bkpts_ptr[i];
1111 for (j = 0,pentry=pentry_start; j < nitem; j++, pentry++) {
1112 //xsh_msg("sk4 i=%d nbkpts=%d j=%d nitem=%d",i,nbkpts,j,nitem);
1113
1114 xsh_msg("pw=%g lambda=%g diff=%g",
1115 pw[i],pentry->lambda,pw[i]-pentry->lambda);
1116
1117 if(pw[i]==pentry->lambda) {
1118 px[i] = pentry->ix;
1119 py[i] = pentry->iy;
1120#if REGDEBUG_BSPLINE
1121 fprintf(fout, "x point (%g %g) #color=blue \n", px[i]+1, py[i]+1);
1122#endif
1123 }
1124 }
1125 }
1126 //exit(0);
1127#if REGDEBUG_BSPLINE
1128 sprintf(fname,"sky_lines_sampl_pts.fits");
1129 if(idx == 0) {
1130 cpl_table_save(sampl_fit,NULL,NULL,fname,CPL_IO_DEFAULT);
1131 } else {
1132 cpl_table_save(sampl_fit,NULL,NULL,fname,CPL_IO_EXTEND);
1133 }
1134#endif
1135
1136 xsh_free_table(&sampl_fit);
1137#if REGDEBUG_BSPLINE
1138 if ( fout ) fclose( fout ) ;
1139#endif
1140 return cpl_error_get_code();
1141}
1142*/
1143
1144static void
1145xsh_dump_table_on_region_file(cpl_table* tab, const char* fname, const int symbol){
1146 //double * w = NULL;
1147 double * x = NULL;
1148 double * y = NULL;
1149 FILE* fout = NULL;
1150 fout = fopen(fname, "w");
1151 int nrow = cpl_table_get_nrow(tab);
1152 //cpl_table_dump_structure(tab,stdout);
1153 //w=cpl_table_get_data_double(tab,"WAVELENGTH");
1154 x=cpl_table_get_data_double(tab,"X");
1155 y=cpl_table_get_data_double(tab,"Y");
1156 fprintf(fout, "# x y\n");
1157 switch(symbol){
1158 case 0:
1159 for(int i=0;i<nrow;i++) {
1160 fprintf(fout,"x point (%g %g) #color=green \n",x[i]+1,y[i]+1);
1161 /*
1162 fprintf( fout, "point(%g,%g) #point=cross color=green "\
1163 "font=\"helvetica 10 normal\" text={%5.1f %5.1f}\n",
1164 x[i]+1, y[i]+1, x[i]+1,y[i]+1);
1165 */
1166
1167 }
1168 break;
1169 case 1:
1170 for(int i=0;i<nrow;i++) {
1171 fprintf(fout,"circle point (%g %g) #color=red \n",x[i]+1,y[i]+1);
1172 /*
1173 fprintf( fout, "point(%5g,%5g) #point=cross color=red "\
1174 "font=\"helvetica 10 normal\" text={%5.1f %5.1f}\n",
1175 x[i]+1, y[i]+1, x[i]+1,y[i]+1);
1176 */
1177 }
1178 break;
1179 case 2:
1180 for(int i=0;i<nrow;i++) {
1181 fprintf(fout,"diamond point (%g %g) #color=cyan \n",x[i]+1,y[i]+1);
1182 /*
1183 fprintf( fout, "point(%g,%g) #point=cross color=cyan "\
1184 "font=\"helvetica 10 normal\" text={%5.1f %5.1f}\n",
1185 x[i]+1, y[i]+1, x[i]+1,y[i]+1);
1186 */
1187 }
1188 break;
1189 case 3:
1190 for(int i=0;i<nrow;i++) {
1191 fprintf(fout,"cross point (%g %g) #color=black \n",x[i]+1,y[i]+1);
1192 /*
1193 fprintf( fout, "point(%g,%g) #point=cross color=black "\
1194 "font=\"helvetica 10 normal\" text={%5.1f %5.1f}\n",
1195 x[i]+1, y[i]+1, x[i]+1,y[i]+1);
1196 */
1197 }
1198 break;
1199 case 4:
1200 for(int i=0;i<nrow;i++) {
1201 fprintf(fout,"point (%g %g) #color=red \n",x[i]+1,y[i]+1);
1202 /*
1203 fprintf( fout, "point(%g,%g) #point=cross color=orange "\
1204 "font=\"helvetica 10 normal\" text={%5.1f %5.1f}\n",
1205 x[i]+1, y[i]+1, x[i]+1,y[i]+1);
1206 */
1207 }
1208 break;
1209 case 5:
1210 for(int i=0;i<nrow;i++) {
1211 fprintf(fout,"box point (%g %g) #color=blue \n",x[i]+1,y[i]+1);
1212 /*
1213 fprintf( fout, "point(%g,%g) #point=cross color=blue "\
1214 "font=\"helvetica 10 normal\" text={%5.1f %5.1f}\n",
1215 x[i]+1, y[i]+1, x[i]+1,y[i]+1);
1216 */
1217 }
1218 break;
1219 default:
1220 for(int i=0;i<nrow;i++) {
1221 fprintf(fout,"point (%g %g) #color=yellow \n",x[i]+1,y[i]+1);
1222 fprintf( fout, "point(%g,%g) #point=cross color=yellow "\
1223 "font=\"helvetica 10 normal\" text={%5.1f %5.1f}\n",
1224 x[i]+1, y[i]+1, x[i]+1,y[i]+1);
1225 }
1226 break;
1227 }
1228
1229 if ( fout ) fclose( fout ) ;
1230 return;
1231}
1232
1233static cpl_table*
1234xsh_create_sampl_table(const int iorder, double* wave_ref, const int nref,
1235 xsh_wavemap_list* wlist,const int nsampl_2,
1236 const char* prefix)
1237{
1238
1239 double * w_mod = NULL;
1240 double * x_mod = NULL;
1241 double * y_mod = NULL;
1242 int * o_mod =NULL;
1243 wavemap_item* pentry = NULL;
1244 wavemap_item* pentry_start = NULL;
1245 wavemap_item* pentry_ref = NULL;
1246 pentry_start = wlist->list[iorder].sky;
1247 int nsampl_line=2*nsampl_2+1;
1248 int nitem = wlist->list[iorder].sky_size;
1249 double wtol = 10.e-3;//10.e-4;
1250 int nsampl=nsampl_line*nref;
1251 char rname[80];
1252 char tname[80];
1253 cpl_table* sampl_tab=cpl_table_new(nsampl);
1254 cpl_table_new_column(sampl_tab,"WAVELENGTH",CPL_TYPE_DOUBLE);
1255 cpl_table_new_column(sampl_tab,"X",CPL_TYPE_DOUBLE);
1256 cpl_table_new_column(sampl_tab,"Y",CPL_TYPE_DOUBLE);
1257 cpl_table_new_column(sampl_tab,"ORDER",CPL_TYPE_INT);
1258 cpl_table_fill_column_window_double(sampl_tab,"WAVELENGTH",0,nsampl,0.);
1259 cpl_table_fill_column_window_double(sampl_tab,"X",0,nsampl,0.);
1260 cpl_table_fill_column_window_double(sampl_tab,"Y",0,nsampl,0.);
1261 cpl_table_fill_column_window_int(sampl_tab,"ORDER",0,nsampl,0.);
1262 w_mod=cpl_table_get_data_double(sampl_tab,"WAVELENGTH");
1263 x_mod=cpl_table_get_data_double(sampl_tab,"X");
1264 y_mod=cpl_table_get_data_double(sampl_tab,"Y");
1265 o_mod=cpl_table_get_data_int(sampl_tab,"ORDER");
1266
1267 int k=0;
1268 int j=0;
1269 int m=0;
1270
1271 double wdif_min_start=9999;
1272 double wdif_min=wdif_min_start;
1273 double wdif_max=-wdif_min_start;
1274 double wdif_tmp=0;
1275 int found_match=0;
1276 int k_step=10;
1277/*
1278 xsh_msg("nref=%d nitem=%d",nref,nitem);
1279 xsh_msg("wave_ref[0]=%g wave_ref[nref-1]=%g",
1280 wave_ref[0],wave_ref[nref-1]);
1281*/
1282 double lambda_min=wlist->list[iorder].lambda_min;
1283 double lambda_margin=(pentry_start+k_step)->lambda-lambda_min;
1284 xsh_msg("Ref sky tab sampl points=%d sky data sampl points=%d",nref,nitem);
1285 for(int i = 0; i < nref ; i++ ) {
1286 //xsh_msg("ok2 i=%d nsampl=%d j=%d nitem=%d m=%d nsampl=%d",i,nrow,j,nitem,m,nsampl);
1287 wdif_min=wdif_min_start;
1288 found_match=0;
1289 for(j = 0, pentry = pentry_start ; j < nitem ; j++, pentry++) {
1290 /* we loop over the wave sampling space to find the best match
1291 * to the reference wavelength
1292 */
1293
1294 if( fabs( wave_ref[i] - pentry->lambda ) <= wtol ) {
1295 /* if there is a sampled wavelength close enough to the
1296 * reference one, we search for the closest one.
1297 */
1298 //xsh_msg("differenze %g",fabs( wave_ref[i] - pentry->lambda ));
1299 wdif_tmp=fabs(wave_ref[i] - pentry->lambda);
1300 if(wdif_tmp<wdif_min) {
1301 found_match=1;
1302 wdif_min=wdif_tmp;
1303 pentry_ref = pentry;
1304 /*
1305 xsh_msg("wref=%10.9g wmod=%10.9g wdif=%10.9g wdif_min=%10.9g",
1306 wave_ref[i],pentry->lambda,wdif_tmp,wdif_min);
1307 */
1308
1309 }
1310 }
1311 }
1312 /* now we found the model wavelength closest to the reference one
1313 * (wave_ref[i]) we can start to take sampling points around its value
1314 */
1315 double wdiff=0;
1316 if(found_match) {
1317 //for(k = -nsampl_2; k <= nsampl_2, (pentry_ref-k)>= pentry_start ; k+=k_step) {
1318 for(k = -nsampl_2; k <= nsampl_2 &&
1319 (pentry_ref-k)->lambda > lambda_min+lambda_margin ; k+=k_step) {
1320 m=i*nsampl_line+k+nsampl_2;
1321 /*
1322 xsh_msg("m=%d nsampl=%d k=%d nsampl_2=%d nitem=%d",
1323 m,nsampl,k,nsampl_2,nitem);
1324 */
1325
1326 //xsh_msg("pentry lambda=%g",(pentry_ref-k)->lambda);
1327 w_mod[m]=(pentry_ref-k)->lambda;
1328 x_mod[m]=(pentry_ref-k)->ix;
1329 y_mod[m]=(pentry_ref-k)->iy;
1330 o_mod[m]=iorder;
1331 }
1332 }
1333
1334
1335 }
1336 //xsh_msg("m=%d",m);
1337 xsh_msg("wdif_min=%18.15g wdif_max=%18.15g",wdif_min,wdif_max);
1338 /* there are cases where the sampl_tabl was over dimensioned.
1339 * Thus we need to remove empty wavelengths. In our case as wave
1340 * cannot be less than ~298 we check that it is not less than 200.
1341 * We also know that result should be smaller than 2500,
1342 * thus we remove values above 3000.
1343 */
1344 cpl_table_and_selected_double(sampl_tab,"WAVELENGTH",CPL_LESS_THAN,200.);
1345 cpl_table_erase_selected(sampl_tab);
1346 cpl_table_and_selected_double(sampl_tab,"WAVELENGTH",CPL_GREATER_THAN,3000.);
1347 cpl_table_erase_selected(sampl_tab);
1348 check(xsh_sort_table_3(sampl_tab,"WAVELENGTH","Y","X",CPL_TRUE,CPL_TRUE,CPL_TRUE));
1349 sprintf(rname,"%s.reg",prefix);
1350 sprintf(tname,"%s.fits",prefix);
1351 //xsh_msg("rname=%s",rname);
1352 int nrow=cpl_table_get_nrow(sampl_tab);
1353 xsh_msg(">>>>>order %d line sampling points %d",iorder,nrow);
1354 //xsh_msg("tname=%s",tname);
1355#if REGDEBUG_BSPLINE
1356 xsh_dump_table_on_region_file(sampl_tab, rname,0);
1357 cpl_table_save(sampl_tab,NULL,NULL,tname,CPL_IO_DEFAULT);
1358#endif
1359
1360
1361
1362 cleanup:
1363 if(cpl_error_get_code() != CPL_ERROR_NONE) {
1365 return NULL;
1366 } else {
1367 return sampl_tab;
1368 }
1369
1370
1371}
1372
1373
1374
1375
1376/*
1377
1378static cpl_table*
1379xsh_create_sampl_random(const int iorder,
1380 xsh_wavemap_list* wlist,const int nsampl,
1381 const char* prefix)
1382{
1383
1384 double * w_mod = NULL;
1385 double * x_mod = NULL;
1386 double * y_mod = NULL;
1387 int * o_mod =NULL;
1388 we add two points to cover order wmin,wmax
1389 int nrow=nsampl+2;
1390 wavemap_item* pentry = NULL;
1391 wavemap_item* pentry_start = NULL;
1392 pentry_start = wlist->list[iorder].sky;
1393 int nitem = wlist->list[iorder].sky_size;
1394 char rname[80];
1395 char tname[80];
1396
1397
1398 cpl_table* sampl_tab=cpl_table_new(nrow);
1399 cpl_table_new_column(sampl_tab,"WAVELENGTH",CPL_TYPE_DOUBLE);
1400 cpl_table_new_column(sampl_tab,"X",CPL_TYPE_DOUBLE);
1401 cpl_table_new_column(sampl_tab,"Y",CPL_TYPE_DOUBLE);
1402 cpl_table_new_column(sampl_tab,"ORDER",CPL_TYPE_INT);
1403 cpl_table_fill_column_window_double(sampl_tab,"WAVELENGTH",0,nrow,0.);
1404 cpl_table_fill_column_window_double(sampl_tab,"X",0,nrow,0.);
1405 cpl_table_fill_column_window_double(sampl_tab,"Y",0,nrow,0.);
1406 cpl_table_fill_column_window_int(sampl_tab,"ORDER",0,nrow,0.);
1407 w_mod=cpl_table_get_data_double(sampl_tab,"WAVELENGTH");
1408 x_mod=cpl_table_get_data_double(sampl_tab,"X");
1409 y_mod=cpl_table_get_data_double(sampl_tab,"Y");
1410 o_mod=cpl_table_get_data_int(sampl_tab,"ORDER");
1411
1412 int j=0;
1413 sprintf(rname,"%s.reg",prefix);
1414 sprintf(tname,"%s.fits",prefix);
1415 //xsh_msg("rname=%s",rname);
1416 //xsh_msg("tname=%s",tname);
1417
1418
1419 //xsh_msg("nitem=%d",nitem);
1420 generate random distribution of sampling points in range [wmin,wmax]
1421 pentry=pentry_start;
1422
1423 xsh_random_init();
1424
1425 add start and end wave and corresponding x,y points
1426 w_mod[0]=pentry->lambda;
1427 x_mod[0]=pentry->ix;
1428 y_mod[0]=pentry->iy;
1429 o_mod[0]=iorder;
1430
1431 w_mod[nrow-1]=(pentry+nitem-1)->lambda;
1432 x_mod[nrow-1]=(pentry+nitem-1)->ix;
1433 y_mod[nrow-1]=(pentry+nitem-1)->iy;
1434 o_mod[nrow-1]=iorder;
1435 //xsh_msg("edges=%g %g",pentry->lambda,(pentry+nitem-1)->lambda);
1436 add remaining points
1437 xsh_random_init();
1438
1439 for(int i = 1; i < nrow-1 ; i++ ) {
1440 j=xsh_get_random_int_window(0, nitem);
1441
1442 w_mod[i]=(pentry+j)->lambda;
1443 x_mod[i]=(pentry+j)->ix;
1444 y_mod[i]=(pentry+j)->iy;
1445 o_mod[i]=iorder;
1446 }
1447
1448 check(xsh_sort_table_3(sampl_tab,"WAVELENGTH","Y","X",CPL_TRUE,CPL_TRUE,CPL_TRUE));
1449#if REGDEBUG_BSPLINE
1450 xsh_dump_table_on_region_file(sampl_tab, rname,1);
1451#endif
1452 //xsh_msg("No sampling points on order %d %d",wlist->list[iorder].order,nrow);
1453 //cpl_table_save(sampl_tab,NULL,NULL,tname,CPL_IO_DEFAULT);
1454 cleanup:
1455 if(cpl_error_get_code() != CPL_ERROR_NONE) {
1456 xsh_print_rec_status(0);
1457 return NULL;
1458 } else {
1459 return sampl_tab;
1460 }
1461
1462
1463}
1464*/
1465
1466static cpl_table*
1468 xsh_wavemap_list* wlist,const int nsampl,
1469 const char* prefix)
1470{
1471
1472 double * w_mod = NULL;
1473 double * x_mod = NULL;
1474 double * y_mod = NULL;
1475 int * o_mod =NULL;
1476 int nrow=nsampl+2;
1477 wavemap_item* pentry = NULL;
1478 wavemap_item* pentry_start = NULL;
1479 pentry_start = wlist->list[iorder].sky;
1480 int nitem = wlist->list[iorder].sky_size;
1481 double wtol = 0.01;
1482 char rname[80];
1483 char tname[80];
1484
1485 cpl_table* sampl_tab=cpl_table_new(nrow);
1486 cpl_table_new_column(sampl_tab,"WAVELENGTH",CPL_TYPE_DOUBLE);
1487 cpl_table_new_column(sampl_tab,"X",CPL_TYPE_DOUBLE);
1488 cpl_table_new_column(sampl_tab,"Y",CPL_TYPE_DOUBLE);
1489 cpl_table_new_column(sampl_tab,"ORDER",CPL_TYPE_INT);
1490 cpl_table_fill_column_window_double(sampl_tab,"WAVELENGTH",0,nrow,0.);
1491 cpl_table_fill_column_window_double(sampl_tab,"X",0,nrow,0.);
1492 cpl_table_fill_column_window_double(sampl_tab,"Y",0,nrow,0.);
1493 cpl_table_fill_column_window_int(sampl_tab,"ORDER",0,nrow,0.);
1494 w_mod=cpl_table_get_data_double(sampl_tab,"WAVELENGTH");
1495 x_mod=cpl_table_get_data_double(sampl_tab,"X");
1496 y_mod=cpl_table_get_data_double(sampl_tab,"Y");
1497 o_mod=cpl_table_get_data_int(sampl_tab,"ORDER");
1498
1499 int k=0;
1500 int j=0;
1501
1502 sprintf(rname,"%s.reg",prefix);
1503 sprintf(tname,"%s.fits",prefix);
1504 xsh_msg("rname=%s",rname);
1505 xsh_msg("tname=%s",tname);
1506
1507 double wstep=(wlist->list[iorder].lambda_max-wlist->list[iorder].lambda_min)/nsampl;
1508 double wmin=wlist->list[iorder].lambda_min;
1509 double wave=0;
1510
1511 pentry=pentry_start;
1512 /*add start and end wave and corresponding x,y points */
1513 w_mod[0]=pentry->lambda;
1514 x_mod[0]=pentry->ix;
1515 y_mod[0]=pentry->iy;
1516 o_mod[0]=iorder;
1517
1518 w_mod[nrow-1]=(pentry+nitem-1)->lambda;
1519 x_mod[nrow-1]=(pentry+nitem-1)->ix;
1520 y_mod[nrow-1]=(pentry+nitem-1)->iy;
1521 o_mod[nrow-1]=iorder;
1522 xsh_msg("edges=%g %g",pentry->lambda,(pentry+nitem-1)->lambda);
1523 for(int i = 1; i < nrow-1 ; i++ ) {
1524 wave=wmin+i*wstep;
1525 for(j = 0, pentry = pentry_start ; j < nitem ; j++, pentry++) {
1526 if( fabs( wave - pentry->lambda ) <= wtol ) {
1527 w_mod[i]=(pentry-k)->lambda;
1528 x_mod[i]=(pentry-k)->ix;
1529 y_mod[i]=(pentry-k)->iy;
1530 o_mod[i]=iorder;
1531 }
1532 }
1533 }
1534
1535 check(xsh_sort_table_3(sampl_tab,"WAVELENGTH","Y","X",CPL_TRUE,CPL_TRUE,CPL_TRUE));
1536 //xsh_dump_table_on_region_file(sampl_tab, rname,0);
1537 //cpl_table_save(sampl_tab,NULL,NULL,tname,CPL_IO_DEFAULT);
1538 cleanup:
1539 if(cpl_error_get_code() != CPL_ERROR_NONE) {
1541 return NULL;
1542 } else {
1543 return sampl_tab;
1544 }
1545
1546
1547}
1548
1549/*
1550
1551static cpl_table*
1552xsh_create_sampl_uniform_line(const int iorder,
1553 xsh_wavemap_list* wlist,const int nsampl,
1554 const char* prefix)
1555{
1556
1557 double * w_mod = NULL;
1558 double * x_mod = NULL;
1559 double * y_mod = NULL;
1560 int * o_mod =NULL;
1561 int nrow=nsampl+2;
1562 wavemap_item* pentry = NULL;
1563 wavemap_item* pentry_start = NULL;
1564 pentry_start = wlist->list[iorder].sky;
1565 int nitem = wlist->list[iorder].sky_size;
1566 double wtol = 0.01;
1567 char rname[80];
1568 char tname[80];
1569
1570 cpl_table* sampl_tab=cpl_table_new(nrow);
1571 cpl_table_new_column(sampl_tab,"WAVELENGTH",CPL_TYPE_DOUBLE);
1572 cpl_table_new_column(sampl_tab,"X",CPL_TYPE_DOUBLE);
1573 cpl_table_new_column(sampl_tab,"Y",CPL_TYPE_DOUBLE);
1574 cpl_table_new_column(sampl_tab,"ORDER",CPL_TYPE_INT);
1575 cpl_table_fill_column_window_double(sampl_tab,"WAVELENGTH",0,nrow,0.);
1576 cpl_table_fill_column_window_double(sampl_tab,"X",0,nrow,0.);
1577 cpl_table_fill_column_window_double(sampl_tab,"Y",0,nrow,0.);
1578 cpl_table_fill_column_window_int(sampl_tab,"ORDER",0,nrow,0.);
1579 w_mod=cpl_table_get_data_double(sampl_tab,"WAVELENGTH");
1580 x_mod=cpl_table_get_data_double(sampl_tab,"X");
1581 y_mod=cpl_table_get_data_double(sampl_tab,"Y");
1582 o_mod=cpl_table_get_data_int(sampl_tab,"ORDER");
1583
1584 int k=0;
1585 int j=0;
1586
1587 sprintf(rname,"%s.reg",prefix);
1588 sprintf(tname,"%s.fits",prefix);
1589 xsh_msg("rname=%s",rname);
1590 xsh_msg("tname=%s",tname);
1591
1592 double wstep=(wlist->list[iorder].lambda_max-wlist->list[iorder].lambda_min)/nsampl;
1593 double wmin=wlist->list[iorder].lambda_min;
1594 double wave=0;
1595
1596 pentry=pentry_start;
1597 add start and end wave and corresponding x,y points
1598 w_mod[0]=pentry->lambda;
1599 x_mod[0]=pentry->ix;
1600 y_mod[0]=pentry->iy;
1601 o_mod[0]=iorder;
1602
1603 w_mod[nrow-1]=(pentry+nitem-1)->lambda;
1604 x_mod[nrow-1]=(pentry+nitem-1)->ix;
1605 y_mod[nrow-1]=(pentry+nitem-1)->iy;
1606 o_mod[nrow-1]=iorder;
1607 xsh_msg("edges=%g %g",pentry->lambda,(pentry+nitem-1)->lambda);
1608 for(int i = 1; i < nrow-1 ; i++ ) {
1609 wave=wmin+i*wstep;
1610 for(j = 0, pentry = pentry_start ; j < nitem ; j++, pentry++) {
1611 if( fabs( wave - pentry->lambda ) <= wtol ) {
1612 w_mod[i]=(pentry-k)->lambda;
1613 x_mod[i]=(pentry-k)->ix;
1614 y_mod[i]=(pentry-k)->iy;
1615 o_mod[i]=iorder;
1616 }
1617 }
1618 }
1619
1620 check(xsh_sort_table_3(sampl_tab,"WAVELENGTH","Y","X",CPL_TRUE,CPL_TRUE,CPL_TRUE));
1621 xsh_dump_table_on_region_file(sampl_tab, rname,0);
1622 cpl_table_save(sampl_tab,NULL,NULL,tname,CPL_IO_DEFAULT);
1623 cleanup:
1624 if(cpl_error_get_code() != CPL_ERROR_NONE) {
1625 xsh_print_rec_status(0);
1626 return NULL;
1627 } else {
1628 return sampl_tab;
1629 }
1630
1631
1632}
1633*/
1634
1635static cpl_error_code
1637 const double ron2, const double gain,
1638 xsh_instrument * instr,
1639 const int iter)
1640{
1641
1642 cpl_image* sky_rms = NULL;
1643 cpl_image* sky_dif = NULL;
1644 cpl_image* sky_rat = NULL;
1645 float* psky_rms =NULL;
1646 float* psky_dif =NULL;
1647 float* psky_rat =NULL;
1648 int order;
1649 int sx, sy ;
1650 //char fname[80];
1651 XSH_ASSURE_NOT_NULL( smap ) ;
1652 XSH_ASSURE_NOT_NULL( instr ) ;
1653
1654 sx = instr->config->nx / instr->binx;
1655 sy = instr->config->ny / instr->biny;
1656 xsh_msg( "Image size:%d,%d", sx, sy ) ;
1657
1658 /* associate to object and sky the corresponding wave and slit maps */
1659 sky_rms = cpl_image_new(sx,sy,XSH_PRE_DATA_TYPE);
1660 psky_rms = cpl_image_get_data_float(sky_rms);
1661
1662 sky_dif = cpl_image_new(sx,sy,XSH_PRE_DATA_TYPE);
1663 psky_dif = cpl_image_get_data_float(sky_dif);
1664
1665 sky_rat = cpl_image_new(sx,sy,XSH_PRE_DATA_TYPE);
1666 psky_rat = cpl_image_get_data_float(sky_rat);
1667
1668 int ix, iy,pix;
1669 double flux=0;
1670 double fit=0;
1671 double sigma2=0;
1672
1673 double arg;
1674 double dif;
1675
1676 for( order = 0 ; order < smap->size ; order++ ) {
1677
1678 wavemap_item * psky = smap->list[order].sky;
1679 int sky_size = smap->list[order].sky_size;
1680
1681 for (int k = 0; k < sky_size; k++) {
1682 ix = psky->ix;
1683 iy = psky->iy;
1684 pix = iy*sx+ix;
1685 flux = psky->flux;
1686 fit = psky->fitted;
1687 sigma2 =ron2+(fabs(fit)/gain);
1688 dif = (flux-fit);
1689 arg = (flux-fit);
1690 arg *= arg;
1691 arg /= sigma2;
1692 psky_rms[pix]=arg;
1693 psky_dif[pix]=dif;
1694 psky_rat[pix]=dif/flux;
1695 psky++;
1696 }
1697 }
1698#if REGDEBUG_BSPLINE
1699 sprintf(fname,"sky_model_rms_%2.2d.fits",iter);
1700 cpl_image_save(sky_rms, fname, CPL_TYPE_FLOAT, NULL, CPL_IO_DEFAULT);
1701 sprintf(fname,"sky_model_dif_%2.2d.fits",iter);
1702 cpl_image_save(sky_dif, fname, CPL_TYPE_FLOAT, NULL, CPL_IO_DEFAULT);
1703 sprintf(fname,"sky_model_rat_%2.2d.fits",iter);
1704 cpl_image_save(sky_rat, fname, CPL_TYPE_FLOAT, NULL, CPL_IO_DEFAULT);
1705#endif
1706
1707 cleanup:
1708 xsh_free_image(&sky_rms);
1709 xsh_free_image(&sky_dif);
1710 xsh_free_image(&sky_rat);
1711 return cpl_error_get_code() ;
1712}
1713
1714static double
1715xsh_skycorr_rms(xsh_wavemap_list* wlist,const int iorder,
1716 const double ron2,const double gain)
1717{
1718
1719 double rms=0;
1720 int nitem = wlist->list[iorder].sky_size;
1721 wavemap_item* psky = NULL;
1722 wavemap_item* psky_start = NULL;
1723
1724 double flux=0;
1725 double fit=0;
1726 double sigma2=0;
1727 int i=0;
1728 double arg;
1729 int npix=0;
1730 double line_ratio=0;
1731 int decode_bp=wlist->instrument->decode_bp;
1732 psky_start = wlist->list[iorder].sky;
1733 for(i = 0, psky = psky_start ; i < nitem ; i++, psky++) {
1734 if( ( ( psky->qual & decode_bp ) == 0) ) {
1735 /* we compute rms only on good pixels */
1736 flux = psky->flux;
1737 fit = psky->fitted;
1738 sigma2 =ron2+(fabs(fit)/gain);
1739 arg = (flux-fit);
1740 line_ratio += fabs(arg/flux);
1741 arg *= arg;
1742 arg /=sigma2;
1743 rms += arg;
1744 npix++;
1745 }
1746 }
1747 rms /= npix;
1748 line_ratio /=npix;
1749 xsh_msg("Average spectrum ratio: %g",line_ratio);
1750 return rms;
1751
1752}
1753#if 0
1754static double
1755xsh_skycorr_gen_rms_image(xsh_wavemap_list* wlist,const int iorder)
1756{
1757
1758 double rms=0;
1759 int nitem = wlist->list[iorder].sky_size;
1760 wavemap_item* psky = NULL;
1761 wavemap_item* psky_start = NULL;
1762 double flux=0;
1763 double fit=0;
1764 double sigma=0;
1765 int i=0;
1766 double arg;
1767 int npix=0;
1768 int decode_bp=wlist->instrument->decode_bp;
1769 for(i = 0, psky = psky_start ; i < nitem ; i++, psky++) {
1770 if( ( ( psky->qual & decode_bp ) == 0) ) {
1771 /* we compute rms only on good pixels */
1772 flux = psky->flux;
1773 fit = psky->fitted;
1774 sigma =psky->sigma;
1775 arg = (flux-fit)/sigma;
1776 arg *= arg;
1777 rms += arg;
1778 npix++;
1779 }
1780 }
1781 rms /= npix;
1782
1783 return rms;
1784
1785}
1786#endif
1787static cpl_table*
1788xsh_table_unique_column(cpl_table* tab_inp,const char* col_wav){
1789 XSH_ASSURE_NOT_NULL( tab_inp ) ;
1790 cpl_table* tab_out=NULL;
1791 double* pcol_w;
1792
1793
1794 tab_out=cpl_table_duplicate(tab_inp);
1795 int nrow=cpl_table_get_nrow(tab_out);
1796 pcol_w=cpl_table_get_data_double(tab_inp,col_wav);
1797
1798 nrow=cpl_table_get_nrow(tab_out);
1799
1800 for(int i=1;i<nrow;i++) {
1801 if(pcol_w[i]==pcol_w[i-1]) {
1802 //xsh_msg("found invalid value %g",pcol_inp[i]);
1803 cpl_table_set_column_invalid(tab_out,col_wav,i,1);
1804 }
1805 }
1806
1807 cpl_table_erase_invalid(tab_out);
1808 nrow=cpl_table_get_nrow(tab_out);
1809 check(xsh_sort_table_1(tab_out,col_wav,CPL_TRUE));
1810
1811 cleanup:
1812 return tab_out;
1813}
1814static cpl_table*
1816 const int ord, const int n){
1817 int ord_abs=wlist->list[ord].order;
1818 int i_step=1;
1819 double wmin=wlist->list[ord].lambda_min;
1820 double wmax=wlist->list[ord].lambda_max;
1821 double* wave=cpl_calloc(n, sizeof(double));
1822 double wstep=(wmax-wmin)/n;
1823 xsh_msg("order=%d wmin=%g wmax=%g",ord,wmin,wmax);
1824 for(int i = 0; i < n ; i+=i_step ) {
1825 wave[i]=wmin+i*wstep;
1826 }
1827 char tname[80];
1828 sprintf(tname, "points_sampl_cont_%02d", ord);
1829 xsh_msg("nbkpts_ord=%d",n);
1830 cpl_free(wave);
1831 cpl_table* ctab=xsh_create_sampl_uniform_continuum(ord, wlist, n, tname);
1832 int nrow=cpl_table_get_nrow(ctab);
1833 xsh_msg("Total sampling points sky continuum on order %d(%d) is =%d",
1834 ord,ord_abs,nrow);
1835
1836 return ctab;
1837 }
1838
1839
1840
1841static cpl_table*
1843 const cpl_table* tab_ord,const int ord)
1844{
1845 int hsampl_line=169;//199;//129//169
1846 cpl_table* xtab=cpl_table_duplicate(tab_ord);
1847 int nrow = cpl_table_get_nrow(tab_ord);
1848
1849 xsh_msg("Total number of sky lines in reference table on order %d is =%d",ord,nrow);
1850 cpl_table_cast_column(xtab,"FLUX","DFLUX",CPL_TYPE_DOUBLE);
1851 cpl_table_cast_column(xtab,"WAVELENGTH","DWAVE",CPL_TYPE_DOUBLE);
1852 double* wref = cpl_table_get_data_double(xtab,"DWAVE");
1853 char tname[80];
1854 sprintf(tname, "points_sampl_lines_%02d", ord);
1855 cpl_table* ltab=xsh_create_sampl_table(ord, wref, nrow, wlist, hsampl_line, tname);
1856 nrow=cpl_table_get_nrow(ltab);
1857 xsh_msg("Total sampling points ref sky line on order %d is =%d",ord,nrow);
1858 xsh_free_table(&xtab);
1859
1860 return ltab;
1861}
1862
1863
1864
1865static cpl_table*
1867cpl_table* res=NULL;
1868xsh_msg("model2tab");
1869int sky_ndata = wlist->list[order].sky_size;
1870res=cpl_table_new(sky_ndata);
1871cpl_table_new_column(res,"WAVE",CPL_TYPE_DOUBLE);
1872cpl_table_new_column(res,"FLUX",CPL_TYPE_DOUBLE);
1873cpl_table_fill_column_window_double(res,"WAVE",0,sky_ndata,0.);
1874cpl_table_fill_column_window_double(res,"FLUX",0,sky_ndata,0.);
1875double* pwave=cpl_table_get_data_double(res,"WAVE");
1876double* pflux=cpl_table_get_data_double(res,"FLUX");
1877int i_step=1;
1878int decode_bp=wlist->instrument->decode_bp;
1879int check_data_quality=0;
1880wavemap_item * psky = wlist->list[order].sky;
1881
1882for(int i=0;i<sky_ndata;i+=i_step,psky+=i_step) {
1883
1884 /* the following is condition to have good pixel quality
1885 * (or saturated line) */
1886
1887 check_data_quality = (( ( psky->qual & decode_bp ) == 0 ) ||
1888 ( psky->qual == QFLAG_SATURATED_DATA )) ? 0:1;
1889
1890 //check_data_quality = (psky->qual == QFLAG_SKY_MODEL_BAD_PIX) ? 0:1;
1891 //check_data_quality=0;
1892 if( check_data_quality == 0) {
1893 /* if good pixel sample it */
1894 pwave[i]=psky->lambda;
1895 pflux[i]=psky->flux;
1896 } else {
1897 cpl_table_set_invalid(res,"WAVE",i);
1898 }
1899
1900}
1901
1902xsh_msg("elements before check %" CPL_SIZE_FORMAT ,cpl_table_get_nrow(res));
1903xsh_msg("invalid elements %" CPL_SIZE_FORMAT ,cpl_table_count_invalid(res,"WAVE"));
1904cpl_table_erase_invalid(res);
1905cpl_table_and_selected_double(res,"WAVE",CPL_EQUAL_TO,0);
1906
1907cpl_table_erase_selected(res);
1908xsh_msg("elements after check %" CPL_SIZE_FORMAT ,cpl_table_get_nrow(res));
1909return res;
1910
1911}
1912
1913#if 0
1914static cpl_table*
1915xsh_skycorr_sampl_lines_from_data(xsh_wavemap_list* wlist,const int ord)
1916{
1917 cpl_table* ltab=NULL;
1918
1919 /*
1920 cpl_table* tab_clean=xsh_detect_raw_data_outliers_1d(wlist,3,ord, 1);
1921 int n=cpl_table_get_nrow(tab_clean);
1922 cpl_table* xtab=xsh_table_unique_wave(tab_clean,"WAVE","FLUX");
1923 xsh_free_table(&tab_clean);
1924 n=cpl_table_get_nrow(xtab);
1925 cpl_table_duplicate_column(xtab,"SWAVE",xtab,"WAVE");
1926 cpl_table_duplicate_column(xtab,"SFLUX",xtab,"FLUX");
1927 double * wave=cpl_table_get_data_double(xtab,"WAVE");
1928 double * flux=cpl_table_get_data_double(xtab,"FLUX");
1929 double * swave=cpl_table_get_data_double(xtab,"SVAVE");
1930 double * sflux=cpl_table_get_data_double(xtab,"SFLUX");
1931 int sno=n;
1932 double gain=1;
1933 double ron2=1;
1934
1935 sflux=xsh_bspline_fit_smooth(wave, flux,n,swave, sno,ron2, gain,wlist->instrument);
1936 cpl_table_wrap_double(xtab,"SFLUX",sflux);
1937 cpl_table_save(xtab,NULL,NULL,"smooth_fit.fits",CPL_IO_DEFAULT);
1938
1939
1940 */
1941 cpl_table* xtab=NULL;
1942 cpl_table* dtab=xsh_model2tab(wlist,ord);
1943 int nrow=cpl_table_get_nrow(dtab);
1944
1945
1946
1947
1948 int hsize=1000;
1949 /* smooth data to later find bad pixels */
1950 cpl_table_duplicate_column(dtab,"FLUX_SMOOTH",dtab,"FLUX");
1951 cpl_vector* v_flux=NULL;
1952 cpl_vector* v_smooth=NULL;
1953 v_flux = cpl_vector_wrap(nrow,cpl_table_get_data_double(dtab,"FLUX"));
1954 v_smooth=cpl_vector_filter_lowpass_create(v_flux,CPL_LOWPASS_LINEAR,hsize);
1955 cpl_vector_unwrap(v_flux);
1956 double* pts=cpl_table_get_data_double(dtab,"FLUX_SMOOTH");
1957 double* pvs=cpl_vector_get_data(v_smooth);
1958 for (int i = 0; i < nrow; i++) {
1959 pts[i]=pvs[i];
1960 }
1961 cpl_vector_delete(v_smooth);
1962
1963 cpl_table_save(dtab,NULL,NULL,"tab_sel.fits",CPL_IO_DEFAULT);
1964
1965
1966
1967
1968
1969
1970
1971 int niter=5;
1972 double kappa=5;
1973 double med=cpl_table_get_column_median(dtab,"FLUX");
1974 double rms=cpl_table_get_column_stdev(dtab,"FLUX");
1975 cpl_table_and_selected_double(dtab,"FLUX",CPL_LESS_THAN,med+kappa*rms);
1976 cpl_table_and_selected_double(dtab,"FLUX",CPL_GREATER_THAN,med-kappa*rms);
1977 xtab=cpl_table_extract_selected(dtab);
1978 med=cpl_table_get_column_median(xtab,"FLUX");
1979 rms=cpl_table_get_column_stdev(xtab,"FLUX");
1980
1981 for(int i=0;i<niter;i++){
1982 cpl_table_select_all(dtab);
1983 cpl_table_and_selected_double(dtab,"FLUX",CPL_LESS_THAN,med+kappa*rms);
1984 cpl_table_and_selected_double(dtab,"FLUX",CPL_GREATER_THAN,med-kappa*rms);
1985 cpl_table* xtab=cpl_table_extract_selected(dtab);
1986 med=cpl_table_get_column_median(xtab,"FLUX");
1987 rms=cpl_table_get_column_stdev(xtab,"FLUX");
1988 xsh_msg("med=%g rms=%g",med,rms);
1989 xsh_free_table(&xtab);
1990 }
1991 nrow=cpl_table_get_nrow(dtab);
1992 cpl_table_new_column(dtab,"FLAG",CPL_TYPE_INT);
1993 cpl_table_fill_column_window_int(dtab,"FLAG",1,nrow,0);
1994 int* pflag=cpl_table_get_data_int(dtab,"FALG");
1995 double* pflux=cpl_table_get_data_double(dtab,"FLUX");
1996 for(int i=0;i<nrow;i++){
1997 if( pflux[i] < med-kappa*rms &&
1998 pflux[i] > med+kappa*rms ) {
1999 pflag[i]=1;
2000 }
2001 }
2002 cpl_table_save(dtab,NULL,NULL,"tab_sel.fits",CPL_IO_DEFAULT);
2003 return ltab;
2004}
2005#endif
2006static cpl_table*
2008 const int nbkpts_ord,
2009 const cpl_table* bkpts_tab)
2010{
2011 cpl_table* rtab=NULL;
2012 cpl_table* ltab=NULL;
2013 cpl_table* ctab=NULL;
2014 int nrow=0;
2015 char rname[80];
2016 XSH_ASSURE_NOT_NULL( wlist ) ;
2017 XSH_ASSURE_NOT_NULL( bkpts_tab ) ;
2018
2019
2020 double sky_slit_size= (wlist->sky_slit_max-wlist->sky_slit_min)-
2021 (wlist->obj_slit_max-wlist->obj_slit_min);
2022 xsh_msg("sky_slit_size=%g",sky_slit_size);
2023
2024 /* creates continuum sampling points table */
2025
2026 ctab=xsh_skycorr_sample_continuum(wlist, ord, nbkpts_ord);
2027
2028 /* creates line sampling points table */
2029 ltab=xsh_skycorr_sampl_lines_from_static_tab(wlist,bkpts_tab,ord);
2030 //ltab=xsh_skycorr_sampl_lines_from_data(wlist,ord);
2031 nrow=cpl_table_get_nrow(ltab);
2032 cpl_table_insert(ltab,ctab,nrow);
2033
2034 /* add order wmin, wmax to be sure the full range is covered */
2035 nrow=cpl_table_get_nrow(ltab);
2036 check(xsh_sort_table_3(ltab,"WAVELENGTH","Y","X",CPL_TRUE,CPL_TRUE,CPL_TRUE));
2037 cpl_table_and_selected_double(ltab,"WAVELENGTH",CPL_EQUAL_TO,0);
2038 cpl_table_erase_selected(ltab);
2039 //cpl_table_save(ltab,NULL,NULL,"pippo.fits",CPL_IO_DEFAULT);
2040 rtab=xsh_table_unique_column(ltab,"WAVELENGTH");
2041 //rtab=cpl_table_duplicate(ltab);
2042 //cpl_table_save(rtab,NULL,NULL,tname,CPL_IO_DEFAULT);
2043 //cpl_table_dump_structure(rtab,stdout);
2044 sprintf(rname, "points_sampl_order_%02d.reg", ord);
2045#if REGDEBUG_BSPLINE
2046 xsh_dump_table_on_region_file(rtab, rname,3);
2047#endif
2048 cpl_table_erase_column(rtab,"ORDER");
2049 nrow=cpl_table_get_nrow(rtab);
2050
2051 xsh_msg("Total sampling points for sky spectrum on order %d is =%d",ord,nrow);
2052 xsh_free_table(&ctab);
2053 xsh_free_table(&ltab);
2054
2055 cleanup:
2056 if(cpl_error_get_code() != CPL_ERROR_NONE) {
2058 return NULL;
2059 } else {
2060 return rtab;
2061 }
2062
2063}
2064
2065/*-----------------------------------------------------------------------------
2066 Implementation
2067 ---------------------------------------------------------------------------*/
2068
2069/*
2070gsl_bspline_knots_uniform()
2071 Construct uniformly spaced knots on the interval [a,b] using
2072the previously specified number of breakpoints. 'a' is the position
2073of the first breakpoint and 'b' is the position of the last
2074breakpoint.
2075
2076Inputs: a - left side of interval
2077 b - right side of interval
2078 w - bspline workspace
2079
2080Return: success or error
2081
2082Notes: 1) w->knots is modified to contain the uniformly spaced
2083 knots
2084
2085 2) The knots vector is set up as follows (using octave syntax):
2086
2087 knots(1:k) = a
2088 knots(k+1:k+l-1) = a + i*delta, i = 1 .. l - 1
2089 knots(n+1:n+k) = b
2090*/
2091
2092/*
2093static int
2094xsh_bspline_knots_not_uniform (const double* value,
2095 gsl_bspline_workspace * w)
2096{
2097 // gsl_bspline_knots_uniform()
2098 size_t i,k; // looping
2099 //double delta; // interval spacing
2100 //double x;
2101 double a = value[w->l];
2102 double b = value[0];
2103 xsh_msg("workspace size=%d",(int)w->l);
2104 xsh_msg("a=%g",a);
2105 xsh_msg("b=%g",b);
2106 //delta = (b - a) / (double) w->l;
2107
2108 for (i = 0; i < w->k; i++)
2109 gsl_vector_set (w->knots, i, a);
2110
2111 for (i = 0, k=w->l-1 ; i < w->l - 1; i++,k--)
2112 {
2113 gsl_vector_set (w->knots, w->k + i, value[k]);
2114
2115 }
2116
2117 for (i = w->n; i < w->n + w->k; i++)
2118 gsl_vector_set (w->knots, i, b);
2119
2120 return GSL_SUCCESS;
2121}
2122*/
2123/*
2124
2125static int
2126xsh_bspline_knots_not_uniform2 (const double* value,
2127 gsl_bspline_workspace * w)
2128{
2129 // gsl_bspline_knots_uniform()
2130 size_t i,k; // looping
2131 //double delta; // interval spacing
2132 //double x;
2133 double a = value[w->l];
2134 double b = value[0];
2135 xsh_msg("workspace size=%d",(int)w->l);
2136 xsh_msg("a=%g",a);
2137 xsh_msg("b=%g",b);
2138 //delta = (b - a) / (double) w->l;
2139
2140 for (i = 0; i < w->k; i++)
2141 gsl_vector_set (w->knots, i, a);
2142
2143 for (i = 0, k=w->l-1 ; i < w->l - 1; i++)
2144 {
2145 gsl_vector_set (w->knots, w->k + i, value[i]);
2146
2147 }
2148
2149 for (i = w->n; i < w->n + w->k; i++)
2150 gsl_vector_set (w->knots, i, b);
2151
2152 return GSL_SUCCESS;
2153}
2154*/
2155
2156/*****************************************************************************/
2157/*****************************************************************************/
2158/*
2159static void
2160sinfo_matrix_Bn_debug(const int i, const int ord, const int nitem, double* Bn_ptr)
2161{
2162 {
2163 we check the metric: dumping the matrix Bn into an image (ord,nitem)
2164 char name[80];
2165 sprintf(name, "Bn_%d.fits", i);
2166 cpl_image* ima = cpl_image_wrap_double(ord, nitem, Bn_ptr);
2167 cpl_image_save(ima, name, CPL_TYPE_FLOAT, NULL, CPL_IO_DEFAULT);
2168 cpl_image_unwrap(ima);
2169 }
2170 return;
2171}*/
2172
2173/*
2174
2175{
2176
2177 cpl_image* sky_rms = NULL;
2178 cpl_image* sky_dif = NULL;
2179 float* psky_rms =NULL;
2180 float* psky_dif =NULL;
2181 int order;
2182 int nx, ny ;
2183
2184 XSH_ASSURE_NOT_NULL( smap ) ;
2185 XSH_ASSURE_NOT_NULL( prefix ) ;
2186 XSH_ASSURE_NOT_NULL( instr ) ;
2187
2188 nx = instr->config->nx ;
2189 ny = instr->config->ny ;
2190 xsh_msg( "Image size:%d,%d", nx, ny ) ;
2191
2192 // associate to object and sky the corresponding wave and slit maps
2193 sky_rms = cpl_image_new(nx,ny,XSH_PRE_DATA_TYPE);
2194 psky_rms = cpl_image_get_data_float(sky_rms);
2195
2196 sky_dif = cpl_image_new(nx,ny,XSH_PRE_DATA_TYPE);
2197 psky_dif = cpl_image_get_data_float(sky_dif);
2198
2199 int ix, iy,pix;
2200 double flux=0;
2201 double fit=0;
2202 double sigma=0;
2203 int i=0;
2204 double arg;
2205 double dif;
2206
2207 for( order = 0 ; order < smap->size ; order++ ) {
2208
2209 wavemap_item * psky = smap->list[order].sky;
2210 int sky_size = smap->list[order].sky_size;
2211
2212 for (int k = 0; k < sky_size; k++) {
2213 ix = psky->ix;
2214 iy = psky->iy;
2215 pix = iy*nx+ix;
2216 flux = psky->flux;
2217 fit = psky->fitted;
2218 sigma =psky->sigma;
2219 dif = (flux-fit);
2220 arg = (flux-fit)/sigma;
2221 arg *= arg;
2222
2223 psky_rms[pix]=arg;
2224 psky_dif[pix]=dif;
2225 psky++;
2226 }
2227 }
2228
2229 cpl_image_save(sky_rms, "sky_model_rms.fits", CPL_TYPE_FLOAT, NULL, CPL_IO_DEFAULT);
2230 cpl_image_save(sky_dif, "sky_model_dif.fits", CPL_TYPE_FLOAT, NULL, CPL_IO_DEFAULT);
2231
2232 cleanup:
2233 xsh_free_image(&sky_rms);
2234 xsh_free_image(&sky_dif);
2235
2236 return cpl_error_get_code() ;
2237}
2238*/
2239/*
2240
2241static cpl_error_code
2242xsh_detect_outliers_image(xsh_wavemap_list * wlist, int iorder)
2243{
2244
2245 wavemap_item * pentry ;
2246 //wavemap_item * pstart ;
2247 pentry = wlist->list[iorder].sky;
2248 //pstart = wlist->list[iorder].sky;
2249 //cpl_mask* mask_order=NULL;
2250 int nitems=wlist->list[iorder].sky_size;
2251
2252
2253 we initially search for CRHs (possibly not previously detected)
2254 * Then we search for bad pixels in an image using HDRL bpm_2d
2255 * Finally we need to identify what are real CRHs, what are just
2256 * not detected lines, what are line residuals, and what are real bad pixels
2257
2258
2259 we initially prepare the images where to flag CRH and BP
2260 cpl_size nx=wlist->instrument->config->nx;
2261 cpl_size ny=wlist->instrument->config->ny;
2262 int decode_bp=wlist->instrument->decode_bp;
2263 cpl_image* resi_ima=cpl_image_new(nx,ny,XSH_PRE_DATA_TYPE);
2264 cpl_image* errs_ima=cpl_image_new(nx,ny,XSH_PRE_ERRS_TYPE);
2265 cpl_image* qual_ima=cpl_image_new(nx,ny,XSH_PRE_QUAL_TYPE);
2266 we initialise the qualifier to QFLAG_MISSING_DATA to flag as bad
2267 * pixels any other order except the one we are going now to fill with
2268 * the real bad pixel quality. In this way later the computations
2269 * are performed only on the good pixels of the currently analised order
2270
2271
2272 cpl_image_add_scalar(qual_ima,QFLAG_MISSING_DATA);
2273 //cpl_image_save(qual_ima, "qual.fits", XSH_PRE_QUAL_BPP, NULL, CPL_IO_DEFAULT);
2274 float* presi=cpl_image_get_data_float(resi_ima);
2275 float* perrs=cpl_image_get_data_float(errs_ima);
2276 int* pqual=cpl_image_get_data_int(qual_ima);
2277 int pix=0;
2278 //int pad=0;
2279
2280 for (int i = 0;i < nitems; i++,pentry++) {
2281 pix=pentry->ix+nx*(pentry->iy);
2282 presi[pix]=fabs(pentry->flux/pentry->fitted);
2283
2284 perrs[pix]=sqrt(pentry->sigma*pentry->sigma+
2285 pentry->fit_err*pentry->fit_err);
2286
2287 perrs[pix]=1;
2288 pqual[pix]=pentry->qual;
2289 }
2290 //cpl_image_save(qual_ima, "qual_after.fits", XSH_PRE_QUAL_BPP, NULL, CPL_IO_DEFAULT);
2291 cpl_mask* qual_mask=xsh_qual_to_cpl_mask(qual_ima, decode_bp);
2292 //cpl_mask_save(qual_mask,"qual_mask.fits",NULL,CPL_IO_DEFAULT);
2293
2294 cpl_image_reject_from_mask(resi_ima,qual_mask);
2295 hdrl_image * hima;
2296 char fname[80];
2297 CRH detection
2298 {
2299
2300 double sigma_lim=20;
2301 double f_lim=2;
2302 int max_iter=4;
2303
2304 hdrl_parameter * lacosmic_params =
2305 hdrl_lacosmic_parameter_create(sigma_lim, f_lim, max_iter);
2306
2307 hima = hdrl_image_create(resi_ima, errs_ima);
2308
2309 cpl_mask* crh_mask = hdrl_lacosmic_edgedetect(hima, lacosmic_params);
2310
2311 sprintf(fname,"mask_crh_%2.2d.fits",iorder);
2312 cpl_mask_save(crh_mask,fname,NULL,CPL_IO_DEFAULT);
2313
2314 hdrl_parameter_delete(lacosmic_params);
2315 xsh_free_mask(&crh_mask);
2316 }
2317 BPM_2D
2318 {
2319 hdrl_parameter* bpm_params =
2320 hdrl_bpm_2d_parameter_create_filtersmooth(10., 19., 3,
2321 CPL_FILTER_MEDIAN, CPL_BORDER_FILTER, 5, 3) ;
2322
2323 cpl_mask* bpm2d_mask = hdrl_bpm_2d_compute(hima, bpm_params);
2324
2325 sprintf(fname,"mask_bpm2d_%2.2d.fits",iorder);
2326 cpl_mask_save(bpm2d_mask,fname,NULL,CPL_IO_DEFAULT);
2327
2328 hdrl_parameter_delete(bpm_params);
2329 xsh_free_mask(&bpm2d_mask);
2330 }
2331
2332 xsh_free_mask(&qual_mask);
2333 xsh_free_image(&resi_ima);
2334 xsh_free_image(&errs_ima);
2335 xsh_free_image(&qual_ima);
2336 hdrl_image_delete(hima);
2337
2338 return cpl_error_get_code();
2339}
2340
2341*/
2342
2343/*
2344
2345static cpl_error_code
2346xsh_bspline_matrix_transpose(const int nfit, const int ord_minus_1,
2347 const int ord, const int Bn_strd, const int* Border,
2348 double* Bn_ptr, float* Xtp, double* px, double* py)
2349{
2350 Filling Transpose matrix before model coefficients determination
2351 * See GSL doc section 39.1: f(x)=Sum_i c_i B_{i,k}(x)
2352 * This means: Y=B*C==> C = Xt.Y = Trans(B).B.Y
2353 * Xtp=Transpose(Bn).Bn and c=Bn.y
2354 size_t orderb=0;
2355 int jbi=0, kbi=0;
2356 for (int i = 0; i < nfit; i++) {
2357 orderb = Border[i] - ord_minus_1;
2358 for (int j = 0; j < ord; j++) {
2359 jbi = j * Bn_strd+i;
2360
2361 for (int k = j; k < ord; k++) {
2362 kbi = k * Bn_strd +i;
2363 if (!isnan(Bn_ptr[jbi] * Bn_ptr[kbi])) {
2364 Xtp[((orderb + k) * ord) + ord_minus_1 - k + j] +=
2365 Bn_ptr[jbi] * Bn_ptr[kbi];
2366 }
2367 else {
2368 xsh_msg("bad matrix coef at %f %f", px[i], py[i]);
2369 }
2370 }
2371 }
2372 }
2373 return cpl_error_get_code();
2374}
2375*/
2376
2377/*
2378static cpl_error_code
2379xsh_bspline_get_model_coeffs(const int ncoeffs, const int nfit,
2380 const int ord_minus_1, const int ord,
2381 const int Bn_strd, const int* Border,
2382 const double* Bn_ptr, const float* y, float* c)
2383{
2384 DEBUG WE DUMP IN A TABLE THE VALUES OF THE C COEFFS
2385 cpl_table * tab = cpl_table_new(ncoeffs);
2386 cpl_table_new_column(tab, "C", CPL_TYPE_DOUBLE);
2387 cpl_table_fill_column_window_double(tab, "C", 0, ncoeffs, 0);
2388 double* pc = cpl_table_get_data_double(tab, "C");
2389 for (int ii = 0; ii < nfit; ii++) {
2390 size_t orderb = Border[ii] - ord_minus_1;
2391 for (int jj = 0; jj < ord; jj++) {
2392 //if(!isnan(Bn_ptr[jj*Bn_strd+ii])) {
2393 c[orderb + jj] += Bn_ptr[jj * Bn_strd + ii] * y[ii];
2394 pc[orderb + jj] += Bn_ptr[jj * Bn_strd + ii] * y[ii];
2395 //}
2396 }
2397 }
2398 cpl_table_save(tab, NULL, NULL, "c.fits", CPL_IO_DEFAULT);
2399 xsh_free_table(&tab);
2400 return cpl_error_get_code();
2401}*/
2402/*
2403
2404static cpl_error_code
2405xsh_bspline_get_sky_model(const int sky_ndata, const int ord_minus_1,
2406 const int ord, const int Bn_full_strd,
2407 const int* Border_full, const float* c,
2408 const double* Bn_full_ptr, float* yf)
2409{
2410 Fill y with the predicted flux from the fit, over all values (using Bn_full)
2411 Next not needed as yf was initialised with gsl_vector_calloc
2412 int i;
2413 for (i = 0; i < sky_ndata; i++) {
2414 yf[i] = 0;
2415 }
2416 Define the model: fill-up yf
2417 for (i = 0; i < sky_ndata; i++) {
2418 size_t orderb = Border_full[i] - ord_minus_1;
2419 for (int j = 0; j < ord; j++) {
2420 if (!isnan(c[orderb + j])) {
2421 yf[i] += Bn_full_ptr[j * Bn_full_strd + i] * c[orderb + j];
2422 }
2423 else {
2424 //xsh_msg("found NAN");
2425 //exit(0);
2426 }
2427 }
2428 }
2429 return cpl_error_get_code();
2430}
2431
2432*/
2433
2434/*****************************************************************************/
2435
2436static cpl_table*
2438 const double ron2, const double gain,
2439 const int order,const int iter,
2440 cpl_table** tab_line_res)
2441{
2442
2443
2444 wavemap_item * psky ;
2445 int sky_ndata = wlist->list[order].sky_size;
2446 cpl_table* tab_bad_fit=cpl_table_new(sky_ndata);
2447
2448 cpl_table_new_column(tab_bad_fit,"WAVE",CPL_TYPE_DOUBLE);
2449 cpl_table_new_column(tab_bad_fit,"FLUX",CPL_TYPE_FLOAT);
2450 cpl_table_new_column(tab_bad_fit,"FIT",CPL_TYPE_DOUBLE);
2451 cpl_table_new_column(tab_bad_fit,"SIGMA",CPL_TYPE_DOUBLE);
2452 cpl_table_new_column(tab_bad_fit,"X",CPL_TYPE_DOUBLE);
2453 cpl_table_new_column(tab_bad_fit,"Y",CPL_TYPE_DOUBLE);
2454 cpl_table_new_column(tab_bad_fit,"FLAG",CPL_TYPE_INT);
2455
2456 cpl_table_fill_column_window_double(tab_bad_fit, "WAVE", 0, sky_ndata, 0);
2457 cpl_table_fill_column_window_float(tab_bad_fit, "FLUX", 0, sky_ndata, 0);
2458 cpl_table_fill_column_window_double(tab_bad_fit, "FIT", 0, sky_ndata, 0);
2459 cpl_table_fill_column_window_double(tab_bad_fit, "SIGMA", 0, sky_ndata, 0);
2460 cpl_table_fill_column_window_double(tab_bad_fit, "X", 0, sky_ndata, 0);
2461 cpl_table_fill_column_window_double(tab_bad_fit, "Y", 0, sky_ndata, 0);
2462 cpl_table_fill_column_window_int(tab_bad_fit, "FLAG", 0, sky_ndata, 0);
2463
2464 double* pbwav=cpl_table_get_data_double(tab_bad_fit,"WAVE");
2465 float* pbflux=cpl_table_get_data_float(tab_bad_fit,"FLUX");
2466 double* pbfit=cpl_table_get_data_double(tab_bad_fit,"FIT");
2467 double* pbsigma=cpl_table_get_data_double(tab_bad_fit,"SIGMA");
2468 double* pbx=cpl_table_get_data_double(tab_bad_fit,"X");
2469 double* pby=cpl_table_get_data_double(tab_bad_fit,"Y");
2470 int* pflag=cpl_table_get_data_int(tab_bad_fit,"FLAG");
2471 int nbad=0;
2472 //int decode_bp=wlist->instrument->decode_bp;
2473 psky = wlist->list[order].sky;
2474 xsh_msg("kappa2=%g ron2=%g gain=%g",kappa2,ron2,gain);
2475
2476 for ( int i = 0 ; i<sky_ndata ; i++, psky++ ) {
2477 double tmp_val = psky->flux-psky->fitted;
2478 double tmp_err = psky->sigma;
2479 //double tmp_var = ( ron2 + (fabs(psky->fitted)/gain));
2480 double tmp_var = tmp_err * tmp_err;
2481 int check_data_value = (( tmp_val * tmp_val ) < kappa2 * tmp_var) ? 0:1;
2482
2483 /* check if pixel is bad */
2484 /*
2485 int check_data_quality = (( ( psky->qual & decode_bp ) > 0 ) &&
2486 ( psky->qual != QFLAG_SATURATED_DATA )) ? 1:0;
2487 */
2488 // define sky values used to evaluate the sky model
2489
2490 if( check_data_value == 1){
2491 /* these must be only a few points */
2492 //xsh_msg("check_value=%d",check_data_value);
2493 //xsh_msg("val1 %g val2 %g",tmp_val * tmp_val, kappa2 * ( psky->sigma * psky->sigma));
2494 //xsh_msg("val1 %g val2 %g",tmp_val * tmp_val, kappa2 * ( ron2 + (fabs(yf[i])/gain)));
2495 pbwav[nbad]=psky->lambda;
2496 pbflux[nbad]=psky->flux;
2497 pbfit[nbad]=psky->fitted;
2498 //pbsigma[nbad]=sqrt(tmp_var);
2499 pbsigma[nbad]=tmp_err;
2500 pbx[nbad]=psky->ix;
2501 pby[nbad]=psky->iy;
2502 pflag[nbad]=1;
2503 nbad++;
2505
2506 }
2507
2508 }
2509 cpl_table_set_size(tab_bad_fit,nbad);
2510 xsh_msg("Flagging sky line residuals order %d iter %d ndata %d nbad_thresh %d",
2511 order,iter,sky_ndata,nbad);
2512
2513
2514
2515
2516
2517
2518 //char bname[80];
2519#if REGDEBUG_BSPLINE
2520 sprintf(bname,"bad_fit_thres_ord_%2.2d_%2.2d.fits",order,iter);
2521 //cpl_table_save(tab_bad_fit,NULL,NULL,bname,CPL_IO_DEFAULT);
2522 sprintf(bname,"bad_fit_thres_ord_%2.2d_%2.2d.reg",order,iter);
2523 xsh_dump_table_on_region_file(tab_bad_fit,bname, 4);
2524#endif
2525 int nsel=cpl_table_and_selected_int(tab_bad_fit,"FLAG",CPL_EQUAL_TO,1);
2526 cpl_table_name_column(tab_bad_fit,"WAVE","WAVELENGTH");
2527
2528 if (nsel == 0) {
2529 return NULL;
2530 }
2531 double hmin=cpl_table_get_column_min(tab_bad_fit,"WAVELENGTH");
2532 double hmax=cpl_table_get_column_max(tab_bad_fit,"WAVELENGTH");
2533
2534 int nbins=(int)(hmax-hmin);
2535 if (nbins == 0) {
2536 return NULL;
2537 }
2538 double hstp=(hmax-hmin)/(nbins-1);
2539 xsh_msg("nbins=%d",nbins);
2540 cpl_table* h = xsh_histogram(tab_bad_fit,"WAVELENGTH",nbins,hmin,hmax);
2541
2542 double histo_min=0;
2543 double histo_max=0;
2544 double histo_mean=0;
2545 double histo_median=0;
2546 double histo_stdev=0;
2547
2548 histo_min=cpl_table_get_column_min(h,"HY");
2549 histo_max=cpl_table_get_column_max(h,"HY");
2550
2551 histo_mean=cpl_table_get_column_mean(h,"HY");
2552 histo_median=cpl_table_get_column_median(h,"HY");
2553 histo_stdev=cpl_table_get_column_stdev(h,"HY");
2554 xsh_msg("histo info: min=%g max=%g mean=%g median=%g,stdev=%g",
2555 histo_min,histo_max,histo_mean,histo_median,histo_stdev);
2556
2557 double kappa=3;
2558 int* phy=cpl_table_get_data_int(h,"HY");
2559 double* phw=cpl_table_get_data_double(h,"HL");
2560 double* pbw=cpl_table_get_data_double(tab_bad_fit,"WAVELENGTH");
2561 pflag=cpl_table_get_data_int(tab_bad_fit,"FLAG");
2562 pbx=cpl_table_get_data_double(tab_bad_fit,"X");
2563 pby=cpl_table_get_data_double(tab_bad_fit,"Y");
2564 *tab_line_res = cpl_table_new(nbins);
2565 cpl_table_new_column(*tab_line_res,"WAVELENGTH",CPL_TYPE_FLOAT);
2566 cpl_table_new_column(*tab_line_res,"FLUX",CPL_TYPE_FLOAT);
2567
2568 cpl_table_fill_column_window_float(*tab_line_res, "WAVELENGTH", 0, nbad, 0);
2569 cpl_table_fill_column_window_float(*tab_line_res, "FLUX", 0, nbad, 999);
2570 float* plwav=cpl_table_get_data_float(*tab_line_res,"WAVELENGTH");
2571
2572#if REGDEBUG_BSPLINE
2573 sprintf(bname,"residual_lines_thres_ord_%2.2d_%2.2d.reg",order,iter);
2574 FILE* fout = NULL;
2575 fout = fopen(bname, "w");
2576#endif
2577 int k=0;
2578 for(int i=0;i<nbins;i++) {
2579 if(phy[i]>histo_median+kappa*histo_stdev) {
2580 plwav[k]=phw[i];
2581 for(int j=0;j<nbad;j++) {
2582 if( pbw[j] > phw[i] - hstp &&
2583 pbw[j] < phw[i] + hstp ) {
2584 pflag[j]=2;
2585#if REGDEBUG_BSPLINE
2586 fprintf(fout,"x point (%g %g) #color=green \n",
2587 pbx[j]+1,pby[j]+1);
2588#endif
2589 }
2590 }
2591 k++;
2592 }
2593 }
2594
2595#if REGDEBUG_BSPLINE
2596 fclose(fout);
2597#endif
2598 cpl_table_set_size(*tab_line_res,k);
2599 cpl_table_set_column_unit(*tab_line_res,"WAVELENGTH","nm");
2600 cpl_table_set_column_unit(*tab_line_res,"FLUX","rel-flux");
2601 xsh_msg("Flagging outliers found %d line outliers",k);
2602
2603
2604 char hname[80];
2605 sprintf(hname,"histo_ord_%2.2d_%2.2d.fits",order,iter);
2606 //cpl_table_save(h, NULL, NULL, hname, CPL_IO_DEFAULT);
2607 xsh_free_table(&h);
2608
2609 cpl_table_erase_column(tab_bad_fit,"FLUX");
2610 cpl_table_erase_column(tab_bad_fit,"FIT");
2611 cpl_table_erase_column(tab_bad_fit,"SIGMA");
2612 //cpl_table_erase_column(tab_bad_fit,"FLAG");
2613 cpl_table_and_selected_double(tab_bad_fit,"WAVELENGTH",CPL_EQUAL_TO,0);
2614 cpl_table_erase_selected(tab_bad_fit);
2615
2616 return tab_bad_fit;
2617}
2618
2619
2620
2621/*****************************************************************************/
2622
2623/*
2624
2625static cpl_table*
2626xsh_detect_outliers_thres(xsh_wavemap_list * wlist, const float* yf,
2627 const double kappa2,const double ron2,
2628 const double gain, const int order,const int iter,
2629 const int decode_bp,cpl_table** tab_line_res)
2630{
2631
2632
2633 wavemap_item * psky ;
2634 int sky_ndata = wlist->list[order].sky_size;
2635 cpl_table* tab_bad_fit=cpl_table_new(sky_ndata);
2636
2637 cpl_table_new_column(tab_bad_fit,"WAVE",CPL_TYPE_DOUBLE);
2638 cpl_table_new_column(tab_bad_fit,"FLUX",CPL_TYPE_FLOAT);
2639 cpl_table_new_column(tab_bad_fit,"FIT",CPL_TYPE_DOUBLE);
2640 cpl_table_new_column(tab_bad_fit,"SIGMA",CPL_TYPE_DOUBLE);
2641 cpl_table_new_column(tab_bad_fit,"X",CPL_TYPE_DOUBLE);
2642 cpl_table_new_column(tab_bad_fit,"Y",CPL_TYPE_DOUBLE);
2643 cpl_table_new_column(tab_bad_fit,"FLAG",CPL_TYPE_INT);
2644
2645 cpl_table_fill_column_window_double(tab_bad_fit, "WAVE", 0, sky_ndata, 0);
2646 cpl_table_fill_column_window_float(tab_bad_fit, "FLUX", 0, sky_ndata, 0);
2647 cpl_table_fill_column_window_double(tab_bad_fit, "FIT", 0, sky_ndata, 0);
2648 cpl_table_fill_column_window_double(tab_bad_fit, "SIGMA", 0, sky_ndata, 0);
2649 cpl_table_fill_column_window_double(tab_bad_fit, "X", 0, sky_ndata, 0);
2650 cpl_table_fill_column_window_double(tab_bad_fit, "Y", 0, sky_ndata, 0);
2651 cpl_table_fill_column_window_int(tab_bad_fit, "FLAG", 0, sky_ndata, 0);
2652
2653 double* pbwav=cpl_table_get_data_double(tab_bad_fit,"WAVE");
2654 float* pbflux=cpl_table_get_data_float(tab_bad_fit,"FLUX");
2655 double* pbfit=cpl_table_get_data_double(tab_bad_fit,"FIT");
2656 double* pbsigma=cpl_table_get_data_double(tab_bad_fit,"SIGMA");
2657 double* pbx=cpl_table_get_data_double(tab_bad_fit,"X");
2658 double* pby=cpl_table_get_data_double(tab_bad_fit,"Y");
2659 int* pflag=cpl_table_get_data_int(tab_bad_fit,"FLAG");
2660 int nbad=0;
2661 psky = wlist->list[order].sky;
2662 xsh_msg("kappa2=%g ron2=%g gain=%g",kappa2,ron2,gain);
2663
2664 for ( int i = 0 ; i<sky_ndata ; i++, psky++ ) {
2665 double tmp_val = yf[i] - psky->flux;
2666 double tmp_err = psky->sigma;
2667
2668 //xsh_msg("yf=%g",yf[i]);
2669
2670 int check_data_value = (( tmp_val * tmp_val ) <
2671 kappa2 * ( ron2 + (fabs(yf[i])/gain))) ? 0:1;
2672
2673 int check_data_value = (( tmp_val * tmp_val ) <
2674 kappa2 * (tmp_err * tmp_err)) ? 0:1;
2675
2676 int check_data_quality = (( ( psky->qual & decode_bp ) == 0 ) ||
2677 ( psky->qual == QFLAG_SATURATED_DATA )) ? 0:1;
2678
2679 // define sky values used to evaluate the sky model
2680
2681 if( check_data_value ){
2682 these must be only a few points
2683 //xsh_msg("check_value=%d",check_data_value);
2684 //xsh_msg("val1 %g val2 %g",tmp_val * tmp_val, kappa2 * ( psky->sigma * psky->sigma));
2685 //xsh_msg("val1 %g val2 %g",tmp_val * tmp_val, kappa2 * ( ron2 + (fabs(yf[i])/gain)));
2686 pbwav[nbad]=psky->lambda;
2687 pbflux[nbad]=psky->flux;
2688 pbfit[nbad]=yf[i];
2689 //pbsigma[nbad]=sqrt(ron2 + (fabs(yf[i])/gain));
2690 pbsigma[nbad]=tmp_err;
2691 pbx[nbad]=psky->ix;
2692 pby[nbad]=psky->iy;
2693 pflag[nbad]=1;
2694 nbad++;
2695 psky->qual=QFLAG_SKY_MODEL_BAD_FIT;
2696
2697 }
2698
2699 }
2700 cpl_table_set_size(tab_bad_fit,nbad);
2701 xsh_msg("order %d iter %d ndata %d nbad_thresh %d",
2702 order,iter,sky_ndata,nbad);
2703 //char bname[80];
2704#if REGDEBUG_BSPLINE
2705 sprintf(bname,"bad_fit_thres_ord_%2.2d_%2.2d.fits",order,iter);
2706 cpl_table_save(tab_bad_fit,NULL,NULL,bname,CPL_IO_DEFAULT);
2707 sprintf(bname,"bad_fit_thres_ord_%2.2d_%2.2d.reg",order,iter);
2708 xsh_dump_table_on_region_file(tab_bad_fit,bname, 4);
2709#endif
2710 cpl_table_and_selected_int(tab_bad_fit,"FLAG",CPL_EQUAL_TO,1);
2711 cpl_table_name_column(tab_bad_fit,"WAVE","WAVELENGTH");
2712
2713
2714 double hmin=cpl_table_get_column_min(tab_bad_fit,"WAVELENGTH");
2715 double hmax=cpl_table_get_column_max(tab_bad_fit,"WAVELENGTH");
2716
2717 int nbins=(int)(hmax-hmin);
2718 xsh_msg("nbins=%d",nbins);
2719 cpl_table* h=xsh_histogram(tab_bad_fit,"WAVELENGTH",nbins,hmin,hmax);
2720 double hstp=(hmax-hmin)/(nbins-1);
2721 xsh_msg("hstp=%g",hstp);
2722 double histo_min=0;
2723 double histo_max=0;
2724 double histo_mean=0;
2725 double histo_median=0;
2726 double histo_stdev=0;
2727 histo_min=cpl_table_get_column_min(h,"HY");
2728 histo_max=cpl_table_get_column_max(h,"HY");
2729 histo_mean=cpl_table_get_column_mean(h,"HY");
2730 histo_median=cpl_table_get_column_median(h,"HY");
2731 histo_stdev=cpl_table_get_column_stdev(h,"HY");
2732 xsh_msg("histo info: min=%g max=%g mean=%g median=%g,stdev=%g",
2733 histo_min,histo_max,histo_mean,histo_median,histo_stdev);
2734
2735 double kappa=3;
2736 int* phy=cpl_table_get_data_int(h,"HY");
2737 double* phw=cpl_table_get_data_double(h,"HL");
2738 double* pbw=cpl_table_get_data_double(tab_bad_fit,"WAVELENGTH");
2739 pflag=cpl_table_get_data_int(tab_bad_fit,"FLAG");
2740 pbx=cpl_table_get_data_double(tab_bad_fit,"X");
2741 pby=cpl_table_get_data_double(tab_bad_fit,"Y");
2742
2743
2744 *tab_line_res = cpl_table_new(nbins);
2745 cpl_table_new_column(*tab_line_res,"WAVELENGTH",CPL_TYPE_FLOAT);
2746 cpl_table_new_column(*tab_line_res,"FLUX",CPL_TYPE_FLOAT);
2747
2748 cpl_table_fill_column_window_float(*tab_line_res, "WAVELENGTH", 0, nbad, 0);
2749 cpl_table_fill_column_window_float(*tab_line_res, "FLUX", 0, nbad, 999);
2750 float* plwav=cpl_table_get_data_float(*tab_line_res,"WAVELENGTH");
2751
2752
2753
2754 int k=0;
2755#if REGDEBUG_BSPLINE
2756 sprintf(bname,"residual_lines_thres_ord_%2.2d_%2.2d.reg",order,iter);
2757 FILE* fout = NULL;
2758 fout = fopen(bname, "w");
2759#endif
2760 for(int i=0;i<nbins;i++) {
2761 if(phy[i]>histo_median+kappa*histo_stdev) {
2762 for(int j=0;j<nbad;j++) {
2763 plwav[k]=phw[i];
2764 if( pbw[j] > phw[i] - hstp &&
2765 pbw[j] < phw[i] + hstp ) {
2766 pflag[j]=2;
2767#if REGDEBUG_BSPLINE
2768 fprintf(fout,"x point (%g %g) #color=green \n",
2769 pbx[j]+1,pby[j]+1);
2770#endif
2771 }
2772 }
2773 k++;
2774 }
2775 }
2776#if REGDEBUG_BSPLINE
2777 fclose(fout);
2778#endif
2779 cpl_table_set_size(*tab_line_res,k);
2780 cpl_table_set_column_unit(*tab_line_res,"WAVELENGTH","nm");
2781 cpl_table_set_column_unit(*tab_line_res,"FLUX","rel-flux");
2782 xsh_msg("found %d line outliers",k);
2783#if REGDEBUG_BSPLINE
2784 char hname[80];
2785 sprintf(hname,"histo_ord_%2.2d_%2.2d.fits",order,iter);
2786 cpl_table_save(h, NULL, NULL, hname, CPL_IO_DEFAULT);
2787#endif
2788 xsh_free_table(&h);
2789
2790 cpl_table_erase_column(tab_bad_fit,"FLUX");
2791 cpl_table_erase_column(tab_bad_fit,"FIT");
2792 cpl_table_erase_column(tab_bad_fit,"SIGMA");
2793 //cpl_table_erase_column(tab_bad_fit,"FLAG");
2794 cpl_table_and_selected_double(tab_bad_fit,"WAVELENGTH",CPL_EQUAL_TO,0);
2795 cpl_table_erase_selected(tab_bad_fit);
2796
2797 return tab_bad_fit;
2798}*/
2799/*****************************************************************************/
2800
2801
2802static cpl_error_code
2803xsh_model_fill_fit(xsh_wavemap_list* wlist,const int order, cpl_table* stab,
2804 const float ron2, const float gain){
2805
2806
2807 int sky_ndata = wlist->list[order].sky_size;
2808 int all_ndata = wlist->list[order].all_size;
2809
2810 double* pwave=cpl_table_get_data_double(stab,"WAVE");
2811 double* pfit=cpl_table_get_data_double(stab,"FIT");
2812
2813 //cpl_table_dump(stab,0,5,stdout);
2814 wavemap_item * psky = wlist->list[order].sky;
2815 int nrow=cpl_table_get_nrow(stab);
2816 int j_min=0;
2817
2818 cpl_table_dump_structure(stab,stdout);
2819 for(int i=0;i<sky_ndata;i++,psky++) {
2820 for(int j=j_min;j<nrow;j++) {
2821 if(pwave[j]==psky->lambda) {
2822 psky->fitted=pfit[j];
2823 /* we assume error free model */
2824 //psky->fit_err=sqrt(ron2+fabs(pfit[j]/gain));
2825 j_min=j;
2826 break;
2827 }
2828 }
2829 }
2830
2831 wavemap_item * pall = wlist->list[order].all;
2832 j_min=0;
2833 for(int i=0;i<all_ndata;i++,pall++) {
2834 for(int j=j_min;j<nrow;j++) {
2835 if(pwave[j]==pall->lambda) {
2836 pall->fitted=pfit[j];
2837 /* we assume error free model */
2838 //psky->fit_err=sqrt(ron2+fabs(pfit[j]/gain));
2839 j_min=j;
2840 break;
2841 }
2842 }
2843 }
2844
2845
2846 return cpl_error_get_code();
2847}
2848
2849
2850static cpl_error_code
2851xsh_model_fill_obj(xsh_wavemap_list* wlist,const int order, const double s1,
2852 const double s2,cpl_table* stab,
2853 const float ron2, const float gain){
2854
2855
2856 int sky_ndata = wlist->list[order].sky_size;
2857 int all_ndata = wlist->list[order].all_size;
2858 //int obj_ndata = wlist->list[order].object_size;
2859
2860 double* pwave=cpl_table_get_data_double(stab,"WAVE");
2861 double* pfit=cpl_table_get_data_double(stab,"FIT");
2862
2863 //cpl_table_dump(stab,0,5,stdout);
2864 //wavemap_item * psky = wlist->list[order].sky;
2865 wavemap_item * pall = wlist->list[order].all;
2866 int nrow=cpl_table_get_nrow(stab);
2867 int j_min=0;
2868
2869 cpl_table_dump_structure(stab,stdout);
2870
2871 for(int i=0;i<all_ndata;i++,pall++) {
2872 wavemap_item * psky = wlist->list[order].sky;
2873 for(int j=0;j<sky_ndata;j++,psky++) {
2874 if(pall->lambda==psky->lambda) {
2875 pall->fitted=psky->fitted;
2876 //psky->fit_err=sqrt(ron2+fabs(pfit[j]/gain));
2877 break;
2878 }
2879 }
2880 }
2881 pall = wlist->list[order].all;
2882 j_min=0;
2883 for(int i=0;i<all_ndata;i++,pall++) {
2884 for(int j=j_min;j<nrow;j++) {
2885 if(pwave[j]==pall->lambda && pall->slit >= s1 && pall->slit<=s2) {
2886 pall->fitted=pfit[j];
2887 //psky->fit_err=sqrt(ron2+fabs(pfit[j]/gain));
2888 j_min=j;
2889 break;
2890 }
2891 }
2892 }
2893
2894
2895 return cpl_error_get_code();
2896}
2897
2898static cpl_error_code
2899xsh_model_fill_fit_bfit(xsh_wavemap_list* wlist,const int order, cpl_table* stab,
2900 const float ron2, const float gain){
2901
2902 int sky_ndata = wlist->list[order].sky_size;
2903 int all_ndata = wlist->list[order].all_size;
2904 double* pwave=cpl_table_get_data_double(stab,"WAVE");
2905 double* pfit=cpl_table_get_data_double(stab,"BFIT");
2906 //cpl_table_dump(stab,0,5,stdout);
2907 wavemap_item * psky = wlist->list[order].sky;
2908 int nrow=cpl_table_get_nrow(stab);
2909 int j_min=0;
2910
2911 for(int i=0;i<sky_ndata;i++,psky++) {
2912 for(int j=j_min;j<nrow;j++) {
2913 if(pwave[j]==psky->lambda) {
2914 psky->fitted=pfit[j];
2915 //psky->fit_err=sqrt(ron2+fabs(pfit[j]/gain));
2916 j_min=j;
2917 break;
2918 }
2919 }
2920 }
2921
2922 wavemap_item * pall = wlist->list[order].all;
2923 j_min=0;
2924 for(int i=0;i<all_ndata;i++,pall++) {
2925 for(int j=j_min;j<nrow;j++) {
2926 if(pwave[j]==pall->lambda) {
2927 pall->fitted=pfit[j];
2928 //psky->fit_err=sqrt(ron2+fabs(pfit[j]/gain));
2929 j_min=j;
2930 break;
2931 }
2932 }
2933 }
2934
2935
2936 return cpl_error_get_code();
2937}
2938
2939
2940static cpl_error_code
2942 const double s1, const double s2, cpl_table* stab,
2943 const float ron2, const float gain){
2944
2945 int sky_ndata = wlist->list[order].sky_size;
2946 int all_ndata = wlist->list[order].all_size;
2947 double* pwave=cpl_table_get_data_double(stab,"WAVE");
2948 double* pfit=cpl_table_get_data_double(stab,"FIT");
2949 //cpl_table_dump(stab,0,5,stdout);
2950 wavemap_item * psky = wlist->list[order].sky;
2951 int nrow=cpl_table_get_nrow(stab);
2952 int j_min=0;
2953
2954 for(int i=0;i<sky_ndata;i++,psky++) {
2955 for(int j=j_min;j<nrow;j++) {
2956 if(pwave[j]==psky->lambda &&
2957 psky->slit > s1 &&
2958 psky->slit < s2) {
2959 psky->fitted=pfit[j];
2960 //psky->fit_err=sqrt(ron2+fabs(pfit[j]/gain));
2961 j_min=j;
2962 break;
2963 }
2964 }
2965 }
2966
2967 wavemap_item * pall = wlist->list[order].all;
2968 j_min=0;
2969 for(int i=0;i<all_ndata;i++,pall++) {
2970 for(int j=j_min;j<nrow;j++) {
2971 if(pwave[j]==pall->lambda) {
2972 pall->fitted=pfit[j];
2973 //psky->fit_err=sqrt(ron2+fabs(pfit[j]/gain));
2974 j_min=j;
2975 break;
2976 }
2977 }
2978 }
2979
2980 return cpl_error_get_code();
2981}
2982
2983
2984static cpl_error_code
2986 const double s1, const double s2, cpl_table* stab,
2987 const float ron2, const float gain){
2988
2989 int sky_ndata = wlist->list[order].sky_size;
2990 int all_ndata = wlist->list[order].all_size;
2991 double* pwave=cpl_table_get_data_double(stab,"WAVE");
2992 double* pfit=cpl_table_get_data_double(stab,"BFIT");
2993 //cpl_table_dump(stab,0,5,stdout);
2994 wavemap_item * psky = wlist->list[order].sky;
2995 int nrow=cpl_table_get_nrow(stab);
2996 int j_min=0;
2997
2998 for(int i=0;i<sky_ndata;i++,psky++) {
2999 for(int j=j_min;j<nrow;j++) {
3000 if(pwave[j]==psky->lambda &&
3001 psky->slit >= s1 &&
3002 psky->slit < s2) {
3003 psky->fitted=pfit[j];
3004 //psky->fit_err=sqrt(ron2+fabs(pfit[j]/gain));
3005 j_min=j;
3006 break;
3007 }
3008 }
3009 }
3010
3011 wavemap_item * pall = wlist->list[order].all;
3012 j_min=0;
3013 for(int i=0;i<all_ndata;i++,pall++) {
3014 for(int j=j_min;j<nrow;j++) {
3015 if(pwave[j]==pall->lambda &&
3016 pall->slit >= s1 &&
3017 pall->slit < s2) {
3018 pall->fitted=pfit[j];
3019 //psky->fit_err=sqrt(ron2+fabs(pfit[j]/gain));
3020 j_min=j;
3021 break;
3022 }
3023 }
3024 }
3025
3026 return cpl_error_get_code();
3027}
3028
3029
3030static void
3031test_gsl_example(double* data_x, double* data_y,double* data_e,double* yfit,
3032 const int i_start, const size_t n, const size_t ncoeffs) {
3033
3034 const size_t nbreak = ncoeffs-2;
3035 size_t i, j;
3036 gsl_bspline_workspace *bw;
3037 gsl_vector *B;
3038 //double dy;
3039 gsl_rng *r;
3040 gsl_vector *c, *w;
3041 gsl_vector *x, *y;
3042 gsl_matrix *X, *cov;
3043 gsl_multifit_linear_workspace *mw;
3044 //gsl_multifit_robust_workspace *mw;
3045 double chisq;
3046 double dof;
3047 //double tss, Rsq;
3048
3049
3050 gsl_rng_env_setup();
3051 r = gsl_rng_alloc(gsl_rng_default);
3052
3053 /* allocate a cubic bspline workspace (k = 4) */
3054 bw = gsl_bspline_alloc(4, nbreak);
3055 B = gsl_vector_alloc(ncoeffs);
3056
3057 x = gsl_vector_alloc(n);
3058 y = gsl_vector_alloc(n);
3059 X = gsl_matrix_alloc(n, ncoeffs);
3060 c = gsl_vector_alloc(ncoeffs);
3061 w = gsl_vector_alloc(n);
3062 cov = gsl_matrix_alloc(ncoeffs, ncoeffs);
3063 mw = gsl_multifit_linear_alloc(n, ncoeffs);
3064 //mw = gsl_multifit_robust_alloc(gsl_multifit_robust_bisquare, n, ncoeffs);
3065
3066 //printf("#m=0,S=0 n=%d\n",n);
3067 /* Fill vectors with data to be fitted */
3068 for (i = 0; i < n; ++i)
3069 {
3070 double sigma;
3071 sigma = data_e[i];
3072
3073 gsl_vector_set(x, i, data_x[i]);
3074 gsl_vector_set(y, i, data_y[i]);
3075 gsl_vector_set(w, i, 1.0 / (sigma * sigma));
3076
3077 //printf("%f %f\n", data_x[i], data_y[i]);
3078 }
3079
3080 /* use uniform breakpoints on [0, 15]. bw is sized nord*nbreak=4*nbreak */
3081 gsl_bspline_knots_uniform(data_x[0], data_x[n-1], bw);
3082
3083 /* construct the fit matrix X */
3084 for (i = 0; i < n; ++i)
3085 {
3086 double xi = gsl_vector_get(x, i);
3087
3088 /* compute B_j(xi) for all j */
3089 gsl_bspline_eval(xi, B, bw);
3090
3091 /* fill in row i of X */
3092 for (j = 0; j < ncoeffs; ++j)
3093 {
3094 double Bj = gsl_vector_get(B, j);
3095 gsl_matrix_set(X, i, j, Bj);
3096 }
3097 }
3098
3099 /* do the fit */
3100 gsl_multifit_wlinear(X, w, y, c, cov, &chisq, mw);
3101
3102 dof = n - ncoeffs;
3103 /*
3104 tss = gsl_stats_wtss(w->data, 1, y->data, 1, y->size);
3105 Rsq = 1.0 - chisq / tss;
3106
3107 fprintf(stderr, "chisq/dof = %e, Rsq = %f\n",
3108 chisq / dof, Rsq);
3109 */
3110 /* output the smoothed curve */
3111 //printf("fit\n");
3112 {
3113 //double xi;
3114 double yi, yerr;
3115
3116 //printf("#m=1,S=0\n");
3117 for (i = 0; i < n; i++)
3118 {
3119 gsl_bspline_eval(data_x[i], B, bw);
3120 gsl_multifit_linear_est(B, c, cov, &yi, &yerr);
3121 //gsl_multifit_robust_est(B, c, cov, &yi, &yerr);
3122 yfit[i_start+i]=yi;
3123 //printf("%f %f\n", data_x[i], yi);
3124 }
3125 }
3126
3127 gsl_rng_free(r);
3128 gsl_bspline_free(bw);
3129 gsl_vector_free(B);
3130 gsl_vector_free(x);
3131 gsl_vector_free(y);
3132 gsl_matrix_free(X);
3133 gsl_vector_free(c);
3134 gsl_vector_free(w);
3135 gsl_matrix_free(cov);
3136 gsl_multifit_linear_free(mw);
3137 //gsl_multifit_robust_free(mw);
3138
3139 //exit(0);
3140 return;
3141}
3142
3143static void xsh_gsl_bspline_non_uniform(double* data_x, double* data_y,double* data_e,
3144 double* bkpts, double* yfit,
3145 const int i_start, const size_t n, const size_t ncoeffs) {
3146
3147 const size_t nbreak = ncoeffs-2;
3148 size_t i, j;
3149 gsl_bspline_workspace *bw;
3150 gsl_vector *B;
3151 //double dy;
3152 gsl_rng *r;
3153 gsl_vector *c, *w;
3154 gsl_vector *x, *y;
3155 gsl_matrix *X, *cov;
3156 gsl_multifit_linear_workspace *mw;
3157 //gsl_multifit_robust_workspace *mw;
3158 double chisq;
3159 double dof;
3160 //double tss, Rsq;
3161
3162 gsl_rng_env_setup();
3163 r = gsl_rng_alloc(gsl_rng_default);
3164
3165 /* allocate a cubic bspline workspace (k = 4) */
3166 bw = gsl_bspline_alloc(4, nbreak);
3167 //B = gsl_vector_alloc(n);
3168 B = gsl_vector_alloc(ncoeffs);
3169 gsl_vector* bkpts_v = gsl_vector_alloc(nbreak);
3170 x = gsl_vector_alloc(n);
3171 y = gsl_vector_alloc(n);
3172 X = gsl_matrix_alloc(n, ncoeffs);
3173 c = gsl_vector_alloc(ncoeffs);
3174 w = gsl_vector_alloc(n);
3175 cov = gsl_matrix_alloc(ncoeffs, ncoeffs);
3176 mw = gsl_multifit_linear_alloc(n, ncoeffs);
3177
3178 //mw = gsl_multifit_robust_alloc(gsl_multifit_robust_ols,n, ncoeffs);
3179 //mw->maxiter=200;
3180 //printf("#m=0,S=0 n=%d\n",n);
3181 /* Fill gsl vector with defined break points */
3182 //printf("data\n");
3183 /*force start and end break points to be start/end data points */
3184 bkpts[0]=data_x[0];
3185 bkpts[nbreak-1]=data_x[n-1];
3186 for (i = 0; i < nbreak; ++i){
3187 gsl_vector_set(bkpts_v, i, bkpts[i]);
3188 //xsh_msg("knots=%13.8g",bkpts[i]);
3189 }
3190
3191 /* Fill gsl vector with data points */
3192 for (i = 0; i < n; ++i)
3193 {
3194 double sigma;
3195 sigma = data_e[i];
3196
3197 gsl_vector_set(x, i, data_x[i]);
3198 gsl_vector_set(y, i, data_y[i]);
3199 gsl_vector_set(w, i, 1.0 / (sigma * sigma));
3200
3201 //printf("%f %f\n", data_x[i], data_y[i]);
3202 }
3203
3204 /* use non uniform breakpoints */
3205 /*
3206 xsh_msg("ncoeffs=%d nbkpts=%d ndata=%d",ncoeffs,nbreak,n);
3207 xsh_msg("ok1 xmin=%13.8g xmax=%13.8g",data_x[0],data_x[n-1]);
3208 xsh_msg("ok1 bkg_min=%13.8g bkg_max=%13.8g",bkpts[0],bkpts[nbreak-1]);
3209 xsh_msg("breakpts->size %d", bkpts_v->size);
3210 xsh_msg("w->nbreak %d",bw->nbreak);
3211 */
3212 gsl_bspline_knots(bkpts_v, bw);
3213 /* construct the fit matrix X */
3214 //int k=0;
3215 //int flat=0;
3216 //double vx;
3217 for (i = 0; i < n; ++i)
3218 {
3219
3220 double xi = gsl_vector_get(x, i);
3221 //xsh_msg("ok22 B->size=%d bw->n=%d",B->size,bw->n);
3222 /* compute B_j(xi) for all j */
3223 /*
3224 xsh_msg("i=%d xi=%13.8g bkg_min=%g bkg_max=%13.8g xmin=%13.8g xmax=%13.8g",
3225 i,xi,bkpts[0],bkpts[nbreak+1],data_x[0],data_x[n-1]);
3226 */
3227
3228 gsl_bspline_eval(xi, B, bw);
3229
3230 /* fill in row i of X */
3231 for (j = 0; j < ncoeffs; ++j)
3232 {
3233 double Bj = gsl_vector_get(B, j);
3234 gsl_matrix_set(X, i, j, Bj);
3235 }
3236
3237 }
3238
3239 /* do the fit */
3240 gsl_multifit_wlinear(X, w, y, c, cov, &chisq, mw);
3241 //gsl_multifit_robust(X, y, c, cov, mw);
3242
3243 dof = n - ncoeffs;
3244 /*
3245 tss = gsl_stats_wtss(w->data, 1, y->data, 1, y->size);
3246 Rsq = 1.0 - chisq / tss;
3247
3248 fprintf(stderr, "chisq/dof = %e, Rsq = %f\n",
3249 chisq / dof, Rsq);
3250 */
3251 /* compute the smoothed curve */
3252 {
3253 //double xi;
3254 double yi, yerr;
3255 for (i = 0; i < n; i++)
3256 {
3257 gsl_bspline_eval(data_x[i], B, bw);
3258 gsl_multifit_linear_est(B, c, cov, &yi, &yerr);
3259 //gsl_multifit_robust_est(B, c, cov, &yi, &yerr);
3260 yfit[i_start+i]=yi;
3261 }
3262 }
3263
3264 gsl_rng_free(r);
3265 gsl_bspline_free(bw);
3266 gsl_vector_free(B);
3267 gsl_vector_free(x);
3268 gsl_vector_free(y);
3269 gsl_matrix_free(X);
3270 gsl_vector_free(c);
3271 gsl_vector_free(w);
3272 gsl_matrix_free(cov);
3273 //gsl_multifit_robust_free(mw);
3274
3275 gsl_multifit_linear_free(mw);
3276 return;
3277}
3278
3279cpl_error_code
3281 const double s1,const double s2){
3282
3283
3284 int nrow=cpl_table_get_nrow(*tab);
3285 int nchunks=20;
3286
3287 int npart=(int)(nrow/nchunks+0.5);
3288 double* pwave=cpl_table_get_data_double(*tab,"WAVE");
3289 //double* pflux=cpl_table_get_data_double(*tab,"FLUX_SMOOTH");
3290 double* perr=cpl_table_get_data_double(*tab,"ERR");
3291 double* pbfit=cpl_table_get_data_double(*tab,"BFIT");
3292 cpl_table* xtab=NULL;
3293 int i_min=0;
3294 int i_max=0;
3295 xsh_msg("npart=%d",npart);
3296 int npoints=0;
3297 for(int i=0;i<=nchunks-1;i++) {
3298 i_min=i*npart;
3299 i_max=((i+1)*npart<nrow) ? (i+1)*npart: nrow-1;
3300 cpl_table_and_selected_double(*tab,"SLIT",CPL_NOT_LESS_THAN,s1);
3301 cpl_table_and_selected_double(*tab,"SLIT",CPL_LESS_THAN,s2);
3302 cpl_table_and_selected_double(*tab,"WAVE",CPL_NOT_LESS_THAN,pwave[i_min]);
3303 cpl_table_and_selected_double(*tab,"WAVE",CPL_LESS_THAN,pwave[i_max]);
3304 xtab=cpl_table_extract_selected(*tab);
3305 xsh_sort_table_1(*tab,"WAVE",CPL_FALSE);
3306 npoints=cpl_table_get_nrow(xtab);
3307 //xsh_msg("npoints=%d",npoints);
3308 double* pw=cpl_table_get_data_double(xtab,"WAVE");
3309 double* pf=cpl_table_get_data_double(xtab,"FLUX_SMOOTH");
3310 //double* pbf=cpl_table_get_data_double(xtab,"BFIT");
3311 //cpl_table_save(xtab,NULL,NULL,"pippo_xtab.fits",CPL_IO_DEFAULT);
3312
3313 xsh_msg("nscan=%d",i_max-i_min+1);
3314 test_gsl_example(pw, pf,perr,pbfit,i_min,npoints,51);
3315 cpl_table_save(*tab,NULL,NULL,"pippo.fits",CPL_IO_DEFAULT);
3316 //exit(0);
3317 cpl_table_select_all(*tab);
3318 xsh_free_table(&xtab);
3319 }
3320 cpl_table_save(*tab,NULL,NULL,"pippo.fits",CPL_IO_DEFAULT);
3321 //exit(0);
3322 return cpl_error_get_code();
3323}
3324
3325cpl_error_code
3327
3328
3329 int nrow=cpl_table_get_nrow(*tab);
3330 int nchunks=20;
3331 cpl_table_new_column(*tab,"BFIT",CPL_TYPE_DOUBLE);
3332 cpl_table_fill_column_window_double(*tab,"BFIT",0,nrow,0);
3333 int npart=(int)(nrow/nchunks+0.5);
3334 double* pwave=cpl_table_get_data_double(*tab,"WAVE");
3335 //double* pflux=cpl_table_get_data_double(*tab,"FLUX_SMOOTH");
3336 double* perr=cpl_table_get_data_double(*tab,"ERR");
3337 double* pbfit=cpl_table_get_data_double(*tab,"BFIT");
3338 cpl_table* xtab=NULL;
3339 int i_min=0;
3340 int i_max=0;
3341 xsh_msg("npart=%d",npart);
3342 int npoints=0;
3343 int nbkpts=151;//131; //151;
3344 for(int i=0;i<=nchunks-1;i++) {
3345 i_min=i*npart;
3346 i_max=((i+1)*npart<nrow) ? (i+1)*npart: nrow-1;
3347 cpl_table_and_selected_double(*tab,"WAVE",CPL_NOT_LESS_THAN,pwave[i_min]);
3348 cpl_table_and_selected_double(*tab,"WAVE",CPL_LESS_THAN,pwave[i_max]);
3349 xtab=cpl_table_extract_selected(*tab);
3350 npoints=cpl_table_get_nrow(xtab);
3351 //xsh_msg("npoints=%d",npoints);
3352 double* pw=cpl_table_get_data_double(xtab,"WAVE");
3353 double* pf=cpl_table_get_data_double(xtab,"FLUX_SMOOTH");
3354 //double* pbf=cpl_table_get_data_double(xtab,"BFIT");
3355 /*
3356 cpl_table_save(xtab,NULL,NULL,"pippo_xtab.fits",CPL_IO_DEFAULT);
3357 if(pwave[i_min]<2272) {
3358 xsh_msg("wave[i_min]=%g pw[0]=%g",pwave[i_min],pw[0]);
3359 xsh_msg("wave[i_max]=%g pw[npoints-1]=%g",pwave[i_max],pw[npoints-1]);
3360 }
3361
3362 */
3363 //xsh_msg("nscan=%d nbkpts=%d",i_max-i_min+1,nbkpts);
3364 if( i_max-i_min+1 <= nbkpts) {
3365 nbkpts=i_max-i_min-1;
3366 if(nbkpts < 4) {
3367 break;
3368 }
3369 }
3370
3371 //xsh_msg("nscan=%d nbkpts=%d",i_max-i_min+1,nbkpts);
3372 test_gsl_example(pw, pf,perr,pbfit,i_min,npoints,nbkpts);
3373 cpl_table_select_all(*tab);
3374 xsh_free_table(&xtab);
3375 }
3376 //cpl_table_save(*tab,NULL,NULL,"pippo.fits",CPL_IO_DEFAULT);
3377
3378 return cpl_error_get_code();
3379}
3380
3381#if 0
3382static cpl_error_code
3383xsh_bspline_smooth_non_uniform(cpl_table* bkpts, cpl_table** tab,
3385
3386
3387 int nrow=cpl_table_get_nrow(*tab);
3388 int nchunks=50;
3389 cpl_table_new_column(*tab,"BFIT",CPL_TYPE_DOUBLE);
3390 cpl_table_fill_column_window_double(*tab,"BFIT",0,nrow,0);
3391 int npart=(int)(nrow/nchunks+0.5);
3392 double* pwave=cpl_table_get_data_double(*tab,"WAVE");
3393 double* pflux=cpl_table_get_data_double(*tab,"FLUX_SMOOTH");
3394 double* perr=cpl_table_get_data_double(*tab,"ERR");
3395 double* pbfit=cpl_table_get_data_double(*tab,"BFIT");
3396 cpl_table* xtab=NULL;
3397 cpl_table* btab=NULL;
3398 int i_min=0;
3399 int i_max=0;
3400 //xsh_msg("npart=%d",npart);
3401 int npoints=0;
3402
3403 for(int i=0;i<=nchunks-1;i++) {
3404 i_min=i*npart;
3405 i_max=((i+1)*npart<nrow) ? (i+1)*npart: nrow-1;
3406 //xsh_msg("wmin=%13.8g wmax=%13.8g",pwave[i_min],pwave[i_max]);
3407 cpl_table_and_selected_double(bkpts,"WAVELENGTH",CPL_NOT_LESS_THAN,pwave[i_min]);
3408 cpl_table_and_selected_double(bkpts,"WAVELENGTH",CPL_LESS_THAN,pwave[i_max]);
3409 btab=cpl_table_extract_selected(bkpts);
3410 int nbkpts=cpl_table_get_nrow(btab);
3411 double* pbkpts=cpl_table_get_data_double(btab,"WAVELENGTH");
3412 //xsh_msg("bkg_min=%13.8g bkg_max=%13.8g",pbkpts[0],pbkpts[nbkpts-1]);
3413 //xsh_msg(">>>>>>>nbkpts=%d",nbkpts);
3414
3415 cpl_table_and_selected_double(*tab,"WAVE",CPL_NOT_LESS_THAN,pwave[i_min]);
3416 cpl_table_and_selected_double(*tab,"WAVE",CPL_LESS_THAN,pwave[i_max]);
3417 xtab=cpl_table_extract_selected(*tab);
3418 npoints=cpl_table_get_nrow(xtab);
3419 //xsh_msg("npoints=%d",npoints);
3420
3421 double* pw=cpl_table_get_data_double(xtab,"WAVE");
3422 double* pf=cpl_table_get_data_double(xtab,"FLUX_SMOOTH");
3423 double* pbf=cpl_table_get_data_double(xtab,"BFIT");
3424
3425 cpl_table_save(xtab,NULL,NULL,"pippo_xtab.fits",CPL_IO_DEFAULT);
3426 cpl_table_save(btab,NULL,NULL,"pippo_btab.fits",CPL_IO_DEFAULT);
3427 //xsh_msg("nscan=%d",i_max-i_min+1);
3428
3429 /*
3430 xsh_msg("i_min=%d i_max=%d wmin=%13.8g wmax=%13.8g xmin=%13.8g xmax=%13.8g",
3431 i_min, i_min+npoints-1, pwave[i_min],pwave[i_min+npoints-1],
3432 pw[0],pw[npoints-1]);
3433 */
3434
3435 xsh_gsl_bspline_non_uniform(pw, pf,perr,pbkpts,pbfit,i_min,npoints,nbkpts);
3436 cpl_table_save(*tab,NULL,NULL,"pippo.fits",CPL_IO_DEFAULT);
3437 cpl_table_select_all(*tab);
3438 cpl_table_select_all(bkpts);
3439 xsh_free_table(&xtab);
3440 xsh_free_table(&btab);
3441 }
3442 //cpl_table_save(*tab,NULL,NULL,"pippo.fits",CPL_IO_DEFAULT);
3443
3444 return cpl_error_get_code();
3445}
3446#endif
3447
3448static cpl_error_code
3449xsh_bspline_smooth_non_uniform2(cpl_table* bkpts, cpl_frame* sky_orders_chunks,
3450 cpl_table** tab,
3451 const int iorder, xsh_instrument* instrument){
3452
3453
3454 xsh_msg("Spline smooth of non uniformly sampled & chopped profile");
3455 const char* name=cpl_frame_get_filename(sky_orders_chunks);
3456 int order_nb=0;
3457 /* load proper table to specify order chunk locations */
3458 if(instrument->arm == XSH_ARM_UVB) {
3459 order_nb=instrument->uvb_orders_nb;
3460 } else if(instrument->arm == XSH_ARM_VIS) {
3461 order_nb=instrument->vis_orders_nb;
3462 } else if(instrument->arm == XSH_ARM_NIR) {
3463 order_nb=instrument->nir_orders_nb;
3464 }
3465 xsh_msg("name=%s iorder=%d order_nb=%d",name,iorder,order_nb);
3466 cpl_table* tab_chunks=cpl_table_load(name,order_nb-iorder,1);
3467
3468 int nchunks=cpl_table_get_nrow(tab_chunks);
3469
3470 int nrow=cpl_table_get_nrow(*tab);
3471 double* pchunk=cpl_table_get_data_double(tab_chunks,"col1");
3472
3473 /* prepare table with results */
3474 cpl_table_new_column(*tab,"BFIT",CPL_TYPE_DOUBLE);
3475 cpl_table_fill_column_window_double(*tab,"BFIT",0,nrow,0);
3476 int npart=(int)(nrow/nchunks+0.5);
3477 double* pwave=cpl_table_get_data_double(*tab,"WAVE");
3478 //double* pflux=cpl_table_get_data_double(*tab,"FLUX_SMOOTH");
3479 double* perr=cpl_table_get_data_double(*tab,"ERR");
3480 double* pbfit=cpl_table_get_data_double(*tab,"BFIT");
3481 cpl_table* xtab=NULL;
3482 cpl_table* btab=NULL;
3483 double wmin=0;
3484 //double wmax=0;
3485 double chunk_wmin=0;
3486 double chunk_wmax=0;
3487 int i_min=0;
3488 int i_max=0;
3489 //xsh_msg("npart=%d",npart);
3490 int npoints=0;
3491
3492 for(int i=0;i<nchunks-1;i++) {
3493
3494 i_max=((i+1)*npart<nrow) ? (i+1)*npart: nrow-1;
3495 /* restrict break points to given chunk region */
3496 chunk_wmin=pchunk[i];
3497 chunk_wmax=pchunk[i+1];
3498 //wmin = ( pwave[i_min] < chunk_wmin ) ? pwave[i_min] : chunk_wmin;
3499 wmin = pwave[i_min];
3500 xsh_msg("order splitting wmin=%13.8g wmax=%13.8g",chunk_wmin,chunk_wmax);
3501 //cpl_table_and_selected_double(bkpts,"WAVELENGTH",CPL_NOT_LESS_THAN,chunk_wmin);
3502 cpl_table_and_selected_double(bkpts,"WAVELENGTH",CPL_NOT_LESS_THAN,wmin);
3503 cpl_table_and_selected_double(bkpts,"WAVELENGTH",CPL_LESS_THAN,chunk_wmax);
3504 btab=cpl_table_extract_selected(bkpts);
3505 int nbkpts=cpl_table_get_nrow(btab);
3506 double* pbkpts=cpl_table_get_data_double(btab,"WAVELENGTH");
3507 //xsh_msg("bkg_min=%13.8g bkg_max=%13.8g",pbkpts[0],pbkpts[nbkpts-1]);
3508 //xsh_msg(">>>>>>>nbkpts=%d",nbkpts);
3509
3510
3511 xsh_msg("wmin=%g chunk_wmin=%g pwave[i_min]=%g chunk_wmax=%g",
3512 wmin,chunk_wmin,pwave[i_min],chunk_wmax);
3513 /* restrict fit of data to region delimited by chunk region */
3514 cpl_table_and_selected_double(*tab,"WAVE",CPL_NOT_LESS_THAN,wmin);
3515 cpl_table_and_selected_double(*tab,"WAVE",CPL_LESS_THAN,chunk_wmax);
3516 xtab=cpl_table_extract_selected(*tab);
3517 npoints=cpl_table_get_nrow(xtab);
3518 //xsh_msg("npoints=%d",npoints);
3519 if(npoints > 0 ) {
3520 double* pw=cpl_table_get_data_double(xtab,"WAVE");
3521 double* pf=cpl_table_get_data_double(xtab,"FLUX_SMOOTH");
3522 //double* pbf=cpl_table_get_data_double(xtab,"BFIT");
3523
3524 cpl_table_save(xtab,NULL,NULL,"pippo_xtab.fits",CPL_IO_DEFAULT);
3525 cpl_table_save(btab,NULL,NULL,"pippo_btab.fits",CPL_IO_DEFAULT);
3526 //xsh_msg("nscan=%d",i_max-i_min+1);
3527 /*
3528 xsh_msg("i_min=%d i_max=%d wmin=%13.8g wmax=%13.8g xmin=%13.8g xmax=%13.8g",
3529 i_min, i_min+npoints-1, pwave[i_min],pwave[i_min+npoints-1],
3530 pw[0],pw[npoints-1]);
3531 */
3532 //xsh_msg("ok1 nbkpts=%d npoints=%d",nbkpts,npoints);
3533 if( i_max-i_min+1 <= nbkpts) {
3534 nbkpts=i_max-i_min-1;
3535 if(nbkpts < 4) {
3536 break;
3537 }
3538 }
3539
3540
3541 xsh_gsl_bspline_non_uniform(pw, pf,perr,pbkpts,pbfit,i_min,npoints,nbkpts);
3542
3543 i_min+=npoints;
3544 cpl_table_save(*tab,NULL,NULL,"pippo.fits",CPL_IO_DEFAULT);
3545 } else {
3546 break;
3547 }
3548 cpl_table_select_all(*tab);
3549 cpl_table_select_all(bkpts);
3550 xsh_free_table(&xtab);
3551 xsh_free_table(&btab);
3552 }
3553 //cpl_table_save(*tab,NULL,NULL,"pippo.fits",CPL_IO_DEFAULT);
3554
3555 return cpl_error_get_code();
3556}
3557
3558
3575static cpl_table*
3576xsh_fit_spline1( xsh_wavemap_list * wlist, int order,cpl_table* sampl_tab,
3577 cpl_frame* sky_orders_chunks,int sampl_pts_no, int iter_no,
3579 float ron2, float gain, cpl_table** tab_line_res)
3580{
3581 /* init variables and log some message */
3582 xsh_msg("xsh_fit_spline1");
3583 cpl_table* tab_bad_fit=NULL;
3584 float kappa=sky_par->kappa;
3585 //int bs_order = sky_par->bezier_spline_order;
3586 int i=0;
3587 //wavemap_item * psky = wlist->list[order].sky;
3588 int abs_order = wlist->list[order].order;
3589 int sky_ndata = wlist->list[order].sky_size;
3590 int n=sky_ndata;
3591 //double wmin=wlist->list[order].lambda_min;
3592 //double wmax=wlist->list[order].lambda_max;
3593 cpl_table* tab_mod=NULL;
3594
3595 tab_mod=xsh_model_to_table(wlist,order);
3596
3597
3598 cpl_table* tab_clean=NULL;
3599 //xsh_msg("total sky data %d",sky_ndata);
3600
3601
3602 /* remove outliers (as Kelson recommends) and determined spectrum to be fit
3603 * as clean median filter of sky data.
3604 */
3605
3606 int decode_bp = wlist->instrument->decode_bp;
3607 tab_clean=xsh_detect_raw_data_outliers_1d(wlist,sky_par->median_hsize,
3608 ron2,gain,order, iter_no, decode_bp);
3609
3610 n=cpl_table_get_nrow(tab_clean);
3611 //xsh_msg("After outlier flagging %d",n);
3612
3613 /* make sure to remove duplicate wavelength entries */
3614 xsh_sort_table_1(tab_clean,"WAVE",CPL_FALSE);
3615 cpl_table* xtab=xsh_table_unique_wave(tab_clean,"WAVE","FLUX");
3616 xsh_free_table(&tab_clean);
3617
3618 /* make sure wavelength are decreasing (as original input) */
3619 xsh_sort_table_1(sampl_tab,"WAVELENGTH",CPL_FALSE);
3620 if( sky_par->method == BSPLINE_METHOD ||
3621 sky_par->method == BSPLINE_METHOD1 ||
3622 wlist->instrument->arm == XSH_ARM_UVB) {
3623
3625 } else {
3626 //xsh_bspline_smooth_non_uniform(sampl_tab,&xtab,wlist->instrument);
3627 check(xsh_bspline_smooth_non_uniform2(sampl_tab,sky_orders_chunks,
3628 &xtab,order,wlist->instrument));
3629 }
3630
3631 char sname[80];
3632 sprintf(sname,"tab_bspline_smooth_ord_%2.2d_%2.2d.fits",abs_order,iter_no);
3633 //cpl_table_save(xtab,NULL,NULL,sname,CPL_IO_DEFAULT);
3634 sprintf(sname,"tab_bspline_bkpts_ord_%2.2d_%2.2d.fits",abs_order,iter_no);
3635 //cpl_table_save(sampl_tab,NULL,NULL,sname,CPL_IO_DEFAULT);
3636 n=cpl_table_get_nrow(xtab);
3637 xsh_msg("After removal wave duplicates %d",n);
3638
3639
3640
3641
3642 sprintf(sname,"tab_data_ord_%2.2d_%2.2d.fits",abs_order,iter_no);
3643 //cpl_table_save(sampl_tab,NULL,NULL,sname,CPL_IO_DEFAULT);
3644
3645 //double* swave=cpl_table_get_data_double(sampl_tab,"WAVELENGTH");
3646 double* wave=cpl_table_get_data_double(xtab,"WAVE");
3647 double* flux=NULL;
3648 /* We always fit to the BSPLINE SMOOTH FIT value, never to the data
3649 * to prevent spikes
3650 flux=cpl_table_get_data_double(xtab,"FLUX");
3651 */
3652 //flux=cpl_table_get_data_double(xtab,"FLUX_SMOOTH");
3653 flux=cpl_table_get_data_double(xtab,"BFIT");
3654
3655#if REGDEBUG_BSPLINE
3656 sprintf(sname,"xtab_ord_%2.2d_%2.2d.fits",abs_order,iter_no);
3657 cpl_table_save(xtab,NULL,NULL,sname,CPL_IO_DEFAULT);
3658#endif
3659
3660 /* put wlist structure info in a table, make sure it is sorted properly */
3661 cpl_table* mtab=NULL;
3662 mtab=xsh_model2tab(wlist,order);
3663 xsh_sort_table_1(mtab,"WAVE",CPL_FALSE);
3664
3665 /* remove wavelength duplicates */
3666 cpl_table* stab=NULL;
3667 stab=xsh_table_unique_wave(mtab,"WAVE","FLUX");
3668 xsh_free_table(&mtab);
3669
3670 /* (B-spline) interpolate model data (swave,sflux) to get back full
3671 * resolution (wave,flux)
3672 */
3673 /*
3674 double* swave=cpl_table_get_data_double(stab,"WAVE");
3675 int sno=cpl_table_get_nrow(stab);
3676 double* sflux=xsh_bspline_interpolate_data_at_pos(wave,flux,n,swave, sno);
3677 */
3678 double* swave = cpl_calloc(wlist->list[order].all_size,sizeof(double));
3679 wavemap_item* pall=NULL;
3680 pall = wlist->list[order].all;
3681 int sno=wlist->list[order].all_size;
3682 for(i=0;i<wlist->list[order].all_size;i++,pall++){
3683 swave[i]=pall->lambda;
3684 }
3685 cpl_table* atab=cpl_table_new(wlist->list[order].all_size);
3686 cpl_table_wrap_double(atab,swave,"WAVE");
3687 double* sflux=xsh_bspline_interpolate_data_at_pos(wave,flux,n,swave, sno);
3688 /*
3689 double* sflux=xsh_bspline_fit_smooth(wave, flux, n, swave, sno, ron2,
3690 gain, wlist->instrument);
3691 */
3692
3693 //cpl_table_wrap_double(sampl_tab,sflux,"FIT");
3694 //cpl_table_wrap_double(stab,sflux,"FIT");
3695 cpl_table_wrap_double(atab,sflux,"FIT");
3696
3697#if REGDEBUG_BSPLINE
3698 sprintf(sname,"tab_sampl_ord_%2.2d_%2.2d.fits",abs_order,iter_no);
3699 cpl_table_save(atab,NULL,NULL,sname,CPL_IO_DEFAULT);
3700#endif
3701
3702 //xsh_msg("abs order %d",abs_order);
3703 //xsh_dump_sky_fit(abs_order, order, n, wlist, yf,iter_no);
3704
3705 /* copy model solution back to wlist structure */
3706 //xsh_model_fill_fit(wlist,order,stab,ron2,gain);
3707 xsh_model_fill_fit(wlist,order,atab,ron2,gain);
3708
3709 /* identify model outliers (bad pixels and lines) */
3710 check(tab_bad_fit=xsh_detect_outliers_thres_new(wlist,kappa*kappa, ron2,
3711 gain,order,iter_no,tab_line_res));
3712
3713 cleanup:
3714 xsh_free_table(&atab);
3715 xsh_free_table(&stab);
3716 xsh_free_table(&xtab);
3717 xsh_free_table(&tab_mod);
3718 return tab_bad_fit;
3719}
3720
3721/*
3722
3723static cpl_table*
3724xsh_fit_spline11( xsh_wavemap_list * wlist, int order,cpl_table* sampl_tab,
3725 cpl_frame* sky_orders_chunks,int sampl_pts_no, int iter_no,
3726 xsh_subtract_sky_single_param *sky_par,
3727 float ron2, float gain, cpl_table** tab_line_res)
3728{
3729 init variables and log some message
3730 xsh_msg("xsh_fit_spline11");
3731 cpl_table* tab_bad_fit=NULL;
3732 float kappa=sky_par->kappa;
3733 //int bs_order = sky_par->bezier_spline_order;
3734 //int i=0;
3735 wavemap_item * psky = wlist->list[order].sky;
3736 int abs_order = wlist->list[order].order;
3737 int sky_ndata = wlist->list[order].sky_size;
3738 int n=sky_ndata;
3739 //double wmin=wlist->list[order].lambda_min;
3740 //double wmax=wlist->list[order].lambda_max;
3741 cpl_table* tab_mod=NULL;
3742
3743 tab_mod=xsh_model_to_table(wlist,order);
3744
3745
3746 cpl_table* tab_clean=NULL;
3747 //xsh_msg("total sky data %d",sky_ndata);
3748
3749
3750 remove outliers (as Kelson recommends) and determined spectrum to be fit
3751 * as clean median filter of sky data.
3752
3753
3754 int decode_bp = wlist->instrument->decode_bp;
3755 tab_clean=xsh_detect_raw_data_outliers_1d(wlist,sky_par->median_hsize,
3756 ron2,gain,order, iter_no, decode_bp);
3757
3758 n=cpl_table_get_nrow(tab_clean);
3759 //xsh_msg("After outlier flagging %d",n);
3760
3761 make sure to remove duplicate wavelength entries
3762 cpl_table* xtab=xsh_table_unique_wave(tab_clean,"WAVE","FLUX");
3763 xsh_free_table(&tab_clean);
3764
3765 make sure wavelength are decreasing (as original input)
3766 xsh_sort_table_1(sampl_tab,"WAVELENGTH",CPL_FALSE);
3767 if( sky_par->method == BSPLINE_METHOD ||
3768 sky_par->method == BSPLINE_METHOD1 ||
3769 wlist->instrument->arm == XSH_ARM_UVB) {
3770 xsh_bspline_smooth_uniform(&xtab,wlist->instrument);
3771 } else {
3772 exit(0);
3773 //xsh_bspline_smooth_non_uniform(sampl_tab,&xtab,wlist->instrument);
3774 check(xsh_bspline_smooth_non_uniform2(sampl_tab,sky_orders_chunks,
3775 &xtab,order,wlist->instrument));
3776 }
3777
3778 char sname[80];
3779 sprintf(sname,"tab_bspline_smooth_ord_%2.2d_%2.2d.fits",abs_order,iter_no);
3780 //cpl_table_save(xtab,NULL,NULL,sname,CPL_IO_DEFAULT);
3781 sprintf(sname,"tab_bspline_bkpts_ord_%2.2d_%2.2d.fits",abs_order,iter_no);
3782 //cpl_table_save(sampl_tab,NULL,NULL,sname,CPL_IO_DEFAULT);
3783 n=cpl_table_get_nrow(xtab);
3784 xsh_msg("After removal wave duplicates %d",n);
3785
3786
3787
3788 sprintf(sname,"tab_data_ord_%2.2d_%2.2d.fits",abs_order,iter_no);
3789 //cpl_table_save(sampl_tab,NULL,NULL,sname,CPL_IO_DEFAULT);
3790
3791 //double* swave=cpl_table_get_data_double(sampl_tab,"WAVELENGTH");
3792 //double* wave=cpl_table_get_data_double(xtab,"WAVE");
3793 double* flux=NULL;
3794 we always fit to the B-spline smooth of the data never to the data
3795 * to prevent spikes
3796 flux=cpl_table_get_data_double(xtab,"FLUX");
3797
3798 //flux=cpl_table_get_data_double(xtab,"FLUX_SMOOTH");
3799 flux=cpl_table_get_data_double(xtab,"BFIT");
3800 //}
3801#if REGDEBUG_BSPLINE
3802 sprintf(sname,"xtab_ord_%2.2d_%2.2d.fits",abs_order,iter_no);
3803 cpl_table_save(xtab,NULL,NULL,sname,CPL_IO_DEFAULT);
3804#endif
3805
3806
3807 copy model solution back to wlist structure
3808 //xsh_model_fill_fit(wlist,order,stab,ron2,gain);
3809 xsh_model_fill_fit_bfit(wlist,order,xtab,ron2,gain);
3810
3811 identify model outliers (bad pixels and lines)
3812 check(tab_bad_fit=xsh_detect_outliers_thres_new(wlist,kappa*kappa, ron2,
3813 gain,order,iter_no,tab_line_res));
3814
3815 cleanup:
3816 return tab_bad_fit;
3817}
3818*/
3819
3837/*
3838
3839
3840static cpl_table*
3841xsh_fit_spline6( xsh_wavemap_list * wlist, int order,cpl_table* sampl_tab,
3842 cpl_frame* sky_orders_chunks,int sampl_pts_no, int iter_no,
3843 xsh_subtract_sky_single_param *sky_par,
3844 float ron2, float gain, cpl_table** tab_line_res)
3845{
3846 init variables and log some message
3847 xsh_msg("xsh_fit_spline6");
3848 cpl_table* tab_bad_fit=NULL;
3849 float kappa=sky_par->kappa;
3850 //int bs_order = sky_par->bezier_spline_order;
3851 int i=0;
3852 wavemap_item * psky = wlist->list[order].sky;
3853 int abs_order = wlist->list[order].order;
3854 int sky_ndata = wlist->list[order].sky_size;
3855 int n=sky_ndata;
3856 //double wmin=wlist->list[order].lambda_min;
3857 //double wmax=wlist->list[order].lambda_max;
3858
3859 //xsh_msg("sky slit min=%g max=%g",wlist->sky_slit_min,wlist->sky_slit_max);
3860
3861
3862 double smin=wlist->sky_slit_min;
3863 double smax=wlist->sky_slit_max;
3864 //xsh_msg("sky slit min=%g max=%g",smax);
3865 double omin=wlist->obj_slit_min;
3866 double omax=wlist->obj_slit_max;
3867 int ns=5;
3868 double s_step=(smax-smin)/ns;
3869 double s_extra=0.0; //s_step;
3870 double s, s1,s2;
3871 int sid=0;
3872 cpl_table* xtab=NULL;
3873 cpl_table* tab_clean=NULL;
3874 char sname[80];
3875 //xsh_msg("total sky data %d",sky_ndata);
3876
3877 remove outliers (as Kelson recommends) and determined spectrum to be fit
3878 * as clean median filter of sky data.
3879
3880 //xsh_msg("ok1 s_extra s_extra=%g",s_extra);
3881 int decode_bp = wlist->instrument->decode_bp;
3882 int med_hsize=sky_par->median_hsize;
3883 cpl_table* ttab=cpl_table_new(0);
3884
3885 int ntot=0;
3886 for(s=smin, sid=0; s<smax-0.0001;s+=s_step,sid++) {
3887 xsh_msg("sid=%d start s=%10.8g smax=%10.8g",sid,s,smax);
3888 if(s>=omin && s <=omax) {
3889 xsh_msg("sid=%d obj slit",sid);
3890 if(s+s_step<omax) {
3891 xsh_msg("sid=%d s=%g continue",sid,s);
3892 continue;
3893 } else {
3894 s1=omax;
3895 s2=s+s_step;
3896 xsh_msg("sid=%d s=%g s1=%g s2=%g",sid,s,s1,s2);
3897 if(s1==s2) {
3898 xsh_msg("sid=%d s=%g s1=%g s2=%g continue",sid,s,s1,s2);
3899 break;
3900 }
3901 }
3902 } else {
3903
3904 if(s<omin) {
3905 xsh_msg("sid=%d sky slit small",sid);
3906 s1=(s>smin) ? s: smin-s_extra;
3907 s2=(s+s_step<=omin) ?s+s_step: omin+s_extra;
3908
3909 } else {
3910 xsh_msg("sid=%d sky slit large",sid);
3911 s1=(s>=omin) ? s: omin-s_extra;
3912 s2=(s+s_step<=smax) ?s+s_step: smax+s_extra;
3913 if(s1==s2) {
3914 xsh_msg("sid=%d s=%g s1=%g s2=%g continue",sid,s,s1,s2);
3915 break;
3916 }
3917 }
3918 xsh_msg("sid=%d s1=%g s2=%g",sid,s1,s2);
3919 tab_clean=xsh_detect_raw_data_outliers_1d_slice(wlist,med_hsize,
3920 ron2, gain, order, iter_no, decode_bp,s1,s2,sid);
3921
3922 n=cpl_table_get_nrow(tab_clean);
3923 if(sid==0) {
3924 cpl_table_copy_structure(ttab,tab_clean);
3925 cpl_table_new_column(ttab,"BFIT",CPL_TYPE_DOUBLE);
3926 }
3927
3928 //xsh_msg("After outlier flagging %d",n);
3929
3930 make sure to remove duplicate wavelength entries
3931 cpl_table* xtab=xsh_table_unique_wave(tab_clean,"WAVE","FLUX");
3932 xsh_free_table(&tab_clean);
3933
3934 make sure wavelength are decreasing (as original input)
3935 check(xsh_sort_table_1(sampl_tab,"WAVELENGTH",CPL_FALSE));
3936
3937 if( sky_par->method == BSPLINE_METHOD1 ||
3938 sky_par->method == BSPLINE_METHOD2 ||
3939 wlist->instrument->arm == XSH_ARM_UVB) {
3940 xsh_bspline_smooth_uniform(&xtab,wlist->instrument);
3941 } else {
3942 //xsh_bspline_smooth_non_uniform(sampl_tab,&xtab,wlist->instrument);
3943 xsh_bspline_smooth_non_uniform2(sampl_tab,sky_orders_chunks,
3944 &xtab,order,wlist->instrument);
3945 }
3946
3947 cpl_table_insert(ttab,xtab,ntot);
3948 ntot += cpl_table_get_nrow(xtab);
3949 sprintf(sname,"tab_bspline_smooth_ord_%2.2d_slice_%2.2d_iter_%2.2d.fits",
3950 abs_order,sid,iter_no);
3951 //cpl_table_save(xtab,NULL,NULL,sname,CPL_IO_DEFAULT);
3952
3953 sprintf(sname,"tab_bspline_bkpts_ord_%2.2d_slice_%2.2d_iter_%2.2d.fits",
3954 abs_order,sid,iter_no);
3955 //cpl_table_save(sampl_tab,NULL,NULL,sname,CPL_IO_DEFAULT);
3956
3957 n=cpl_table_get_nrow(xtab);
3958 xsh_msg("After removal wave duplicates %d",n);
3959
3960
3961 sprintf(sname,"tab_data_ord_%2.2d_slice_%2.2d_iter_%2.2d.fits",
3962 abs_order,sid,iter_no);
3963 //cpl_table_save(sampl_tab,NULL,NULL,sname,CPL_IO_DEFAULT);
3964
3965 //double* swave=cpl_table_get_data_double(sampl_tab,"WAVELENGTH");
3966
3967
3968
3969 double* wave=cpl_table_get_data_double(xtab,"WAVE");
3970 double* flux=NULL;
3971 we always fit to the B-spline smooth of the data, never to the
3972 * data to prevent spikes
3973
3974
3975 flux=cpl_table_get_data_double(xtab,"FLUX");
3976
3977 //flux=cpl_table_get_data_double(xtab,"FLUX_SMOOTH");
3978 flux=cpl_table_get_data_double(xtab,"BFIT");
3979
3980 #if REGDEBUG_BSPLINE
3981 sprintf(sname,"xtab_ord_%2.2d_%2.2d.fits",abs_order,iter_no);
3982 cpl_table_save(xtab,NULL,NULL,sname,CPL_IO_DEFAULT);
3983 #endif
3984
3985 put wlist structure info in a table, make sure it is sorted properly
3986 cpl_table* mtab=NULL;
3987 mtab=xsh_model2tab(wlist,order);
3988 xsh_sort_table_1(mtab,"WAVE",CPL_FALSE);
3989
3990 remove wavelength duplicates
3991 cpl_table* stab=NULL;
3992 stab=xsh_table_unique_wave(mtab,"WAVE","FLUX");
3993 xsh_free_table(&mtab);
3994
3995 (B-spline) interpolate model data (swave,sflux) to get back full
3996 * resolution (wave,flux)
3997
3998
3999 double* swave=cpl_table_get_data_double(stab,"WAVE");
4000 int sno=cpl_table_get_nrow(stab);
4001 double* sflux=xsh_bspline_interpolate_data_at_pos(wave,flux,n,swave, sno);
4002
4003 double* swave = cpl_calloc(wlist->list[order].all_size,sizeof(double));
4004
4005 wavemap_item* pall=NULL;
4006 pall = wlist->list[order].all;
4007 int sno=wlist->list[order].all_size;
4008 for(i=0;i<wlist->list[order].all_size;i++,pall++){
4009 swave[i]=pall->lambda;
4010 }
4011
4012 cpl_table* atab=cpl_table_new(wlist->list[order].all_size);
4013 cpl_table_wrap_double(atab,swave,"WAVE");
4014 int nxtab=cpl_table_get_nrow(xtab);
4015 int xsno=cpl_table_and_selected_double(atab,"WAVE",CPL_NOT_LESS_THAN,wave[0]);
4016 xsno=cpl_table_and_selected_double(atab,"WAVE",CPL_NOT_GREATER_THAN,wave[nxtab-1]);
4017 //xsno=cpl_table_and_selected_double(atab,"WAVE",CPL_NOT_GREATER_THAN,wave[nxtab]);
4018 cpl_table* xstab=cpl_table_extract_selected(atab);
4019 double* xswave=cpl_table_get_data_double(xstab,"WAVE");
4020 //xsh_msg("ok8 wave[0]=%g swave[0]=%g",wave[0],swave[0]);
4021 //xsh_msg("ok8 wave[0]=%g xswave[0]=%g",wave[0],xswave[0]);
4022
4023 double* sflux=NULL;
4024 sflux=xsh_bspline_interpolate_data_at_pos(wave,flux,n,xswave, xsno);
4025
4026
4027
4028 double* sflux=xsh_bspline_fit_smooth(wave, flux, n, swave, sno, ron2,
4029 gain, wlist->instrument);
4030
4031
4032 //cpl_table_wrap_double(sampl_tab,sflux,"FIT");
4033 //cpl_table_wrap_double(stab,sflux,"FIT");
4034 cpl_table_wrap_double(xstab,sflux,"FIT");
4035
4036 #if REGDEBUG_BSPLINE
4037 sprintf(sname,"tab_sampl_ord_%2.2d_slice_%2.2d_iter_%2.2d.fits",
4038 abs_order,sid,iter_no);
4039 cpl_table_save(xstab,NULL,NULL,sname,CPL_IO_DEFAULT);
4040 #endif
4041
4042 //xsh_msg("abs order %d",abs_order);
4043 //xsh_dump_sky_fit(abs_order, order, n, wlist, yf,iter_no);
4044
4045 copy model solution back to wlist structure
4046 //xsh_model_fill_fit(wlist,order,stab,ron2,gain);
4047
4048 xsh_model_fill_fit_slice(wlist,order,s1,s2,xstab,ron2,gain);
4049 sprintf(sname,"model_ord_%2.2d_slice_%2.2d_iter_%2.2d.fits",
4050 abs_order,sid,iter_no);
4051
4052 xsh_wavemap_list_sky_image_save( wlist, wlist->instrument, abs_order,sid,444);
4053 xsh_wavemap_list_rms_sky_image_save(wlist,ron2,gain,wlist->instrument,555);
4054
4055
4056 }
4057 }
4058 //exit(0);
4059 sprintf(sname,"tab_bspline_smooth_ord_%2.2d_iter_%2.2d.fits",
4060 abs_order,iter_no);
4061 //cpl_table_save(ttab,NULL,NULL,sname,CPL_IO_DEFAULT);
4062 sprintf(sname,"tab_bspline_bkpts_ord_%2.2d_iter_%2.2d.fits",
4063 abs_order,iter_no);
4064 //cpl_table_save(sampl_tab,NULL,NULL,sname,CPL_IO_DEFAULT);
4065 //exit(0);
4066
4067
4068
4069
4070
4071 identify model outliers (bad pixels and lines)
4072 check(tab_bad_fit=xsh_detect_outliers_thres_new(wlist,kappa*kappa, ron2,
4073 gain,order,iter_no,tab_line_res));
4074
4075 cleanup:
4076 return tab_bad_fit;
4077}
4078
4079*/
4080
4081static cpl_table*
4082xsh_fit_spline2( xsh_wavemap_list * wlist, int order,cpl_table* sampl_tab,
4083 cpl_frame* sky_orders_chunks,int sampl_pts_no, int iter_no,
4085 float ron2, float gain, cpl_table** tab_line_res)
4086{
4087 /* init variables and log some message */
4088 xsh_msg("xsh_fit_spline2");
4089 cpl_table* tab_bad_fit=NULL;
4090 float kappa=sky_par->kappa;
4091 //int bs_order = sky_par->bezier_spline_order;
4092 int i=0;
4093 wavemap_item * psky = wlist->list[order].sky;
4094 int abs_order = wlist->list[order].order;
4095 int sky_ndata = wlist->list[order].sky_size;
4096 int n=sky_ndata;
4097 double wmin=wlist->list[order].lambda_min;
4098 double wmax=wlist->list[order].lambda_max;
4099
4100 //xsh_msg("sky slit min=%g max=%g",wlist->sky_slit_min,wlist->sky_slit_max);
4101
4102
4103 double smin=wlist->sky_slit_min;
4104 double smax=wlist->sky_slit_max;
4105 //xsh_msg("sky slit min=%g max=%g",smax);
4106 double omin=wlist->obj_slit_min;
4107 double omax=wlist->obj_slit_max;
4108 int ns=5;
4109 double s_step=(smax-smin)/ns;
4110 //double s_extra=0.0; //s_step;
4111 double s, s1,s2;
4112 int sid=0;
4113 cpl_table* xtab=NULL;
4114 cpl_table* tab_clean=NULL;
4115 char sname[80];
4116 //xsh_msg("total sky data %d",sky_ndata);
4117
4118 /* remove outliers (as Kelson recommends) and determined spectrum to be fit
4119 * as clean median filter of sky data.
4120 */
4121 //xsh_msg("ok1 s_extra s_extra=%g",s_extra);
4122 int decode_bp = wlist->instrument->decode_bp;
4123 int med_hsize=sky_par->median_hsize;
4124 cpl_table* ttab=cpl_table_new(0);
4125
4126 double s_margin=0.001;
4127
4128 int ntot=0;
4129 for(s=smin, sid=0; s<smax-0.0001;s+=s_step,sid++) {
4130 xsh_msg("sid=%d start s=%10.8g smax=%10.8g splus=%10.8g",sid,s,smax,s+s_step);
4131 if(s < omin) {
4132 xsh_msg("sid=%d sky slit small",sid);
4133 //if(s+s_step < omin-s_margin) {
4134 s1=s;
4135 s2=( s+s_step < omin-s_margin ) ? s+s_step: omin;
4136 /*
4137 } else {
4138 xsh_msg("sid=%d sky slit small continue",sid);
4139 continue;
4140 }
4141 */
4142 } else if (s > omin && s < omax) {
4143
4144 if( s+s_step < omax+s_margin) {
4145 xsh_msg("sid=%d object slit continue",sid);
4146 continue;
4147 } else {
4148 xsh_msg("sid=%d obj slit special",sid);
4149 s1 = omax;
4150 s2 = s+s_step;
4151 }
4152 } else {
4153 xsh_msg("sid=%d sky slit large",sid);
4154 s1 = s;
4155 s2 = (s+s_step < smax) ? s+s_step: smax;
4156
4157 }
4158 xsh_msg("sid=%d s1=%g s2=%g",sid,s1,s2);
4159 tab_clean=xsh_detect_raw_data_outliers_1d_slice(wlist,med_hsize,
4160 ron2, gain, order, iter_no, decode_bp,s1,s2,sid);
4161
4162 n=cpl_table_get_nrow(tab_clean);
4163 if(sid==0) {
4164 cpl_table_copy_structure(ttab,tab_clean);
4165 cpl_table_new_column(ttab,"BFIT",CPL_TYPE_DOUBLE);
4166 }
4167
4168 //xsh_msg("After outlier flagging %d",n);
4169
4170 /* make sure to remove duplicate wavelength entries */
4171 cpl_table* xtab=xsh_table_unique_wave(tab_clean,"WAVE","FLUX");
4172 xsh_free_table(&tab_clean);
4173
4174 /* make sure wavelength are decreasing (as original input) */
4175 check(xsh_sort_table_1(sampl_tab,"WAVELENGTH",CPL_FALSE));
4176
4177 if( sky_par->method == BSPLINE_METHOD2 ||
4178 wlist->instrument->arm == XSH_ARM_UVB) {
4180 } else {
4181
4182 //xsh_bspline_smooth_non_uniform(sampl_tab,&xtab,wlist->instrument);
4183 xsh_bspline_smooth_non_uniform2(sampl_tab,sky_orders_chunks,
4184 &xtab,order,wlist->instrument);
4185 }
4186
4187 cpl_table_insert(ttab,xtab,ntot);
4188 ntot += cpl_table_get_nrow(xtab);
4189 sprintf(sname,"tab_bspline_smooth_ord_%2.2d_slice_%2.2d_iter_%2.2d.fits",
4190 abs_order,sid,iter_no);
4191 //cpl_table_save(xtab,NULL,NULL,sname,CPL_IO_DEFAULT);
4192
4193 sprintf(sname,"tab_bspline_bkpts_ord_%2.2d_slice_%2.2d_iter_%2.2d.fits",
4194 abs_order,sid,iter_no);
4195 //cpl_table_save(sampl_tab,NULL,NULL,sname,CPL_IO_DEFAULT);
4196
4197 n=cpl_table_get_nrow(xtab);
4198 xsh_msg("After removal wave duplicates %d",n);
4199
4200
4201 sprintf(sname,"tab_data_ord_%2.2d_slice_%2.2d_iter_%2.2d.fits",
4202 abs_order,sid,iter_no);
4203
4204
4205 xsh_model_fill_fit_slice_bfit(wlist,order,s1,s2,xtab,ron2,gain);
4206
4207 sprintf(sname,"model_ord_%2.2d_slice_%2.2d_iter_%2.2d.fits",
4208 abs_order,sid,iter_no);
4209 xsh_msg("order=%d sid=%d s1=%g s2=%g omin=%g omax=%g",
4210 order,sid,s1,s2,omin,omax);
4211
4212 xsh_wavemap_list_sky_image_save( wlist, wlist->instrument, abs_order,sid,444);
4213
4214 xsh_wavemap_list_rms_sky_image_save(wlist,ron2,gain,wlist->instrument,555);
4215 xsh_free_table(&xtab);
4216
4217 }
4218 /* at this point we have the sky model on the sky region and we need to get
4219 * the sky model on the obj region. The best approximation is to
4220 * spline-interpolate the data from the slice next to the object edges.
4221 */
4222 /* */
4223 s1=(omin-s_step<smin)? smin: omin-s_step;
4224 s2=(omax+s_step>smax)? smax: omax+s_step;
4225
4226 //s1=smin;
4227 //s2=smax;
4228 cpl_table_and_selected_double(ttab,"SLIT",CPL_GREATER_THAN,s1);
4229 cpl_table_and_selected_double(ttab,"SLIT",CPL_LESS_THAN,s2);
4230 xtab=cpl_table_extract_selected(ttab);
4231
4232 xsh_sort_table_1(xtab,"WAVE",CPL_FALSE);
4233 cpl_table* utab=xsh_table_unique_wave(xtab,"WAVE", "BFIT");
4234 xsh_free_table(&xtab);
4235 cpl_table_save(utab,NULL,NULL,"utab.fits",CPL_IO_DEFAULT);
4236
4237 //xsh_model_fill_fit_slice_bfit(wlist,order,s1,s2,utab,ron2,gain);
4238
4239
4240 n=cpl_table_get_nrow(utab);
4241 double* flux=cpl_table_get_data_double(utab,"BFIT");
4242 double* wave=cpl_table_get_data_double(utab,"WAVE");
4243 wmin=cpl_table_get_column_min(utab,"WAVE");
4244 wmax=cpl_table_get_column_max(utab,"WAVE");
4245 //cpl_table_save(xtab,NULL,NULL,"utab.fits",CPL_IO_DEFAULT);
4246 double* swave = cpl_calloc(wlist->list[order].object_size,sizeof(double));
4247 wavemap_item* pobj=NULL;
4248
4249 pobj = wlist->list[order].object;
4250 int sno=wlist->list[order].object_size;
4251 for(i=0;i<wlist->list[order].object_size;i++,pobj++){
4252 swave[i]=pobj->lambda;
4253 }
4254
4255 cpl_table* otab=cpl_table_new(wlist->list[order].object_size);
4256 cpl_table_wrap_double(otab,swave,"WAVE");
4257 cpl_table_and_selected_double(otab,"WAVE",CPL_NOT_LESS_THAN,wmin);
4258 cpl_table_and_selected_double(otab,"WAVE",CPL_NOT_GREATER_THAN,wmax);
4259 cpl_table* stab=cpl_table_extract_selected(otab);
4260 cpl_table_save(stab,NULL,NULL,"stab.fits",CPL_IO_DEFAULT);
4261 sno=cpl_table_get_nrow(stab);
4262 swave=cpl_table_get_data_double(stab,"WAVE");
4263 double* sflux=xsh_bspline_interpolate_data_at_pos(wave,flux,n,swave, sno);
4264 xsh_free_table(&utab);
4265 check(cpl_table_wrap_double(stab,sflux,"FIT"));
4266
4267#if REGDEBUG_BSPLINE
4268 sprintf(sname,"tab_sampl_ord_%2.2d_%2.2d.fits",abs_order,iter_no);
4269 cpl_table_save(stab,NULL,NULL,sname,CPL_IO_DEFAULT);
4270#endif
4271 sprintf(sname,"tab_sampl_ord_%2.2d_%2.2d.fits",abs_order,iter_no);
4272 //cpl_table_save(stab,NULL,NULL,sname,CPL_IO_DEFAULT);
4273
4274 xsh_model_fill_obj(wlist, order, s1, s2, stab, ron2, gain);
4275
4276 //xsh_model_fill_fit(wlist,order,atab,ron2,gain);
4277 //xsh_model_fill_fit_slice_bfit(wlist,order,omin,omax,ttab,ron2,gain);
4278
4279
4280
4281
4282 sprintf(sname,"tab_bspline_smooth_ord_%2.2d_iter_%2.2d.fits",
4283 abs_order,iter_no);
4284 //cpl_table_save(ttab,NULL,NULL,sname,CPL_IO_DEFAULT);
4285 sprintf(sname,"tab_bspline_bkpts_ord_%2.2d_iter_%2.2d.fits",
4286 abs_order,iter_no);
4287 //cpl_table_save(sampl_tab,NULL,NULL,sname,CPL_IO_DEFAULT);
4288 //exit(0);
4289
4290
4291
4292
4293
4294 /* identify model outliers (bad pixels and lines) */
4295 check(tab_bad_fit=xsh_detect_outliers_thres_new(wlist,kappa*kappa, ron2,
4296 gain,order,iter_no,tab_line_res));
4297
4298 cleanup:
4299 xsh_free_table(&otab);
4300 xsh_free_table(&stab);
4301 xsh_free_table(&ttab);
4302 return tab_bad_fit;
4303}
4304
4305
4306/*****************************************************************************/
4307/*****************************************************************************/
4308static int xsh_wave_compare( const void * un, const void * deux )
4309{
4310 wavemap_item * one = (wavemap_item *)un ;
4311 wavemap_item * two = (wavemap_item *)deux ;
4312
4313 if ( one->lambda < two->lambda ) return -1 ;
4314 else if ( one->lambda == two->lambda ) return 0 ;
4315 return 1 ;
4316}
4317/*****************************************************************************/
4318
4319/*****************************************************************************/
4324/*****************************************************************************/
4325double xsh_nbkpts_uvb[XSH_ORDERS_UVB]={2.0,2.0,2.0,2.0,
4326 2.0,2.0,2.0,2.0,
4327 2.0,2.0,2.0,2.0}; //XSH_ORDERS_UVB=12
4328
4329
4330
4331 /* order= 16 17 18 19 */
4332double xsh_nbkpts_vis[XSH_ORDERS_VIS]={1.5,0.8,0.8,0.7,
4333 0.8,0.8,0.7,0.7,
4334 0.7,0.75,0.7,0.6,
4335 0.6,0.6,0.6}; //XSH_ORDERS_VIS=15
4336
4337
4338/*
4339double xsh_nbkpts_vis[XSH_ORDERS_VIS]={1.5,0.8,0.8,0.8,
4340 0.8,0.8,0.9,0.9,
4341 0.9,0.8,0.9,0.9,
4342 0.8,0.8,0.6}; //XSH_ORDERS_VIS=15
4343
4344*/
4345 /* right */
4346//0.28,0.28,0.28,0.3, STD
4347//0.30,0.28,0.28,0.7
4348/* REF
4349double xsh_nbkpts_nir[XSH_ORDERS_NIR]={0.30,0.28,0.28,0.7,
4350 0.9,0.8,0.9,0.9,
4351 0.5,0.7,1.0,0.5,
4352 0.7,0.7,0.7,0.4}; //XSH_ORDERS_NIR=16
4353*/
4354double xsh_nbkpts_nir[XSH_ORDERS_NIR]={0.30,0.28,0.28,0.7,
4355 0.9,0.8,0.9,0.9,
4356 0.5,0.7,1.0,0.5,
4357 0.7,0.7,0.7,0.4}; //XSH_ORDERS_NIR=16
4358
4359
4360static cpl_error_code
4362 xsh_localization* list,
4363 const double smap_min,
4364 const double smap_max,
4365 double* obj_slit_min,
4366 double* obj_slit_max,
4367 double* sky_slit_min,
4368 double* sky_slit_max)
4369{
4370
4371 double pos1 = sky_par->pos1;
4372 double hheight1 = sky_par->hheight1;
4373 double pos2 = sky_par->pos2;
4374 double hheight2 = sky_par->hheight2;
4375 double s2_min, s2_max, s1_min, s1_max;
4376 xsh_msg("Kelson Sky Model");
4377 xsh_msg_warning("Start obj_slit_min=%g obj_slit_max=%g",*obj_slit_min,*obj_slit_max);
4378 xsh_msg_warning("pos1=%g hheight1=%g pos2=%g hheight2=%g",pos1,hheight1,pos2,hheight2);
4379 /* if hheight1 or hheight2 is defined */
4380 if ((hheight1 == 0) && (hheight2 == 0) && (list != NULL)) {
4381 *obj_slit_min = cpl_polynomial_eval_1d(list->edglopoly, 600, NULL);
4382 *obj_slit_max = cpl_polynomial_eval_1d(list->edguppoly, 600, NULL);
4383 xsh_msg_warning("Limit in slit given by localization %f => %f",
4384 *obj_slit_min, *obj_slit_max);
4385
4386 xsh_msg_dbg_medium("Limit in slit given by localization %f => %f",
4387 *obj_slit_min, *obj_slit_max);
4388 s1_min=smap_min;
4389 s1_max=*obj_slit_min;
4390 s2_min=*obj_slit_max;
4391 s2_max=smap_max;
4392 //xsh_msg("Automatic Set sky window1: [%g,%g] window2=[%g,%g] arcsec",s1_min,s1_max,s2_min,s2_max);
4393 }
4394 else {
4395 if (hheight1 > 0) {
4396 *sky_slit_min = pos1 - hheight1;
4397 *sky_slit_max = pos1 + hheight1;
4398 s1_min=*sky_slit_min;
4399 s1_max=*sky_slit_max;
4400 //xsh_msg_warning("sky_slit_min=%g sky_slit_max=%g",*sky_slit_min,*sky_slit_max);
4401
4402 if (hheight2 > 0) {
4403
4404
4405 s1_min = pos1 - hheight1;
4406 s1_max = pos1 + hheight1;
4407
4408 s2_min = pos2 - hheight2;
4409 s2_max = pos2 + hheight2;
4410
4411 if (s2_min < s1_min) {
4412 *sky_slit_min = s2_min;
4413 }
4414 else {
4415 *sky_slit_min = s1_min;
4416 }
4417
4418 if (s2_max > s1_max) {
4419 *sky_slit_max = s2_max;
4420 }
4421 else {
4422 *sky_slit_max = s1_max;
4423 }
4424
4425 if (s2_min >= s1_max) {
4426 *obj_slit_min = s1_max;
4427 *obj_slit_max = s2_min;
4428 }
4429
4430 if (s1_min >= s2_max) {
4431 *obj_slit_min = s2_max;
4432 *obj_slit_max = s1_min;
4433 }
4434 //xsh_msg_warning("obj_slit_min=%g obj_slit_max=%g",*obj_slit_min,*obj_slit_max);
4435 xsh_msg("User Set sky window1: [%g,%g] window2=[%g,%g] arcsec",s1_min,s1_max,s2_min,s2_max);
4436 } else {
4437 xsh_msg("User Set sky window: [%g,%g] arcsec",s1_min,s1_max);
4438 }
4439
4440 }
4441 else {
4442 *sky_slit_min = pos2 - hheight2;
4443 *sky_slit_max = pos2 + hheight2;
4444 s2_min=*sky_slit_min;
4445 s2_max=*sky_slit_max;
4446 xsh_msg("User Set sky window: [%g,%g]",s2_min,s2_max);
4447 }
4448 //xsh_msg_warning("sky_slit_min=%g sky_slit_max=%g",*sky_slit_min,*sky_slit_max);
4449 }
4450 xsh_msg("Object window: [%g,%g]",*obj_slit_min,*obj_slit_max);
4451 //xsh_msg_warning("inside sky_slit_min=%g sky_slit_max=%g",*sky_slit_min,*sky_slit_max);
4452 return cpl_error_get_code();
4453}
4454
4455static cpl_error_code
4457 const int miny, const int maxy,
4458 const int iorder, const int order,
4459 const int nx, const int wmap_xsize_diff,
4460 xsh_order_list* ord_tab,
4461 cpl_image* slitmap,
4462 double* sky_slit_min,
4463 double* sky_slit_max,
4464 int *max_size, int*max_size_x)
4465{
4466 /* NOTE that because sky_par->slit_edges_mask (=0.5arcsec)>0 not all order
4467 * space is sampled.
4468 */
4469 /*
4470 For each Y calculate the nb of pixels in X.
4471 */
4472 *max_size = 0;
4473 *max_size_x = 0;
4474 double* pslit = cpl_image_get_data_double( slitmap);
4475 double sky_slit_min_edge=0;
4476 double sky_slit_max_edge=0;
4477 for (int iy = miny; iy < maxy; iy++) {
4478 int minx=xsh_get_edge_x_min(ord_tab, iorder, iy);
4479 int maxx=xsh_get_edge_x_max(ord_tab, iorder, iy);
4480
4481 int offset = iy * (nx - wmap_xsize_diff);
4482 float slit_val = pslit[minx + offset];
4483
4484 if (slit_val > sky_slit_max_edge) {
4485 sky_slit_max_edge = slit_val;
4486 }
4487 if (slit_val < sky_slit_min_edge) {
4488 sky_slit_min_edge = slit_val;
4489 }
4490
4491 slit_val = pslit[maxx + offset];
4492
4493 if (slit_val > sky_slit_max_edge) {
4494 sky_slit_max_edge = slit_val;
4495 }
4496 if (slit_val < sky_slit_min_edge) {
4497 sky_slit_min_edge = slit_val;
4498 }
4499 /* Add nb of pixels in the X range */
4500 *max_size += (maxx - minx + 1);
4501 if(maxx - minx + 1 > *max_size_x) {
4502 *max_size_x = (maxx - minx + 1);
4503 }
4504 }
4505 //xsh_msg("max_size=%d",*max_size);
4506
4507 XSH_ASSURE_NOT_ILLEGAL( sky_slit_min_edge <= sky_slit_max_edge);
4508 XSH_CMP_INT( *max_size, >, 0, "Not enough points for the sky order %d",
4509 ,order);
4510 double slit_edges_mask = sky_par->slit_edges_mask;
4511 //slit_edges_mask=0;
4512 //xsh_msg("sky_edges=%g %g",sky_slit_min_edge,sky_slit_max_edge);
4513 sky_slit_min_edge = sky_slit_min_edge+slit_edges_mask;
4514 sky_slit_max_edge = sky_slit_max_edge-slit_edges_mask;
4515 //xsh_msg("sky_edges=%g %g",sky_slit_min_edge,sky_slit_max_edge);
4516
4517 double hheight1 = sky_par->hheight1;
4518 double hheight2 = sky_par->hheight2;
4519 //xsh_msg("sky height=%g %g",hheight1,hheight2);
4520 if ( (hheight1 == 0) && (hheight2 == 0)){
4521 *sky_slit_min = sky_slit_min_edge;
4522 *sky_slit_max = sky_slit_max_edge;
4523 }
4524 else{
4525 if (sky_slit_min_edge > *sky_slit_min){
4526 *sky_slit_min = sky_slit_min_edge;
4527 }
4528 if (sky_slit_max_edge < *sky_slit_max){
4529 *sky_slit_max = sky_slit_max_edge;
4530 }
4531 }
4532 //xsh_msg("sky_edges=%g %g",*sky_slit_min,*sky_slit_max);
4533
4534 cleanup:
4535
4536 return cpl_error_get_code();
4537}
4538
4539static cpl_error_code
4540xsh_wavecal_list_pupulate(xsh_pre *pre_sci, const int iorder, const int miny,
4541 const int maxy, const int wmap_xsize_diff,
4542 const int decode_bp, const double obj_slit_min,
4543 const double obj_slit_max, const double sky_slit_min,
4544 const double sky_slit_max, const int order,
4545 xsh_wavemap_list* wave_list, int* sky_size,
4546 xsh_order_list* ord_tab, cpl_image *wavemap,
4547 cpl_image *slitmap)
4548{
4549 /* Populate the wavecal list */
4550 wavemap_item * psky = wave_list->list[iorder].sky;
4551 wavemap_item * pobject = wave_list->list[iorder].object;
4552 wavemap_item * pall = wave_list->list[iorder].all;
4553 double* plambda = cpl_image_get_data_double( wavemap);
4554 double* pslit = cpl_image_get_data_double( slitmap);
4555
4556 float* pflux = cpl_image_get_data_float( xsh_pre_get_data( pre_sci));
4557 float* perrs = cpl_image_get_data_float( xsh_pre_get_errs( pre_sci));
4558 int* pqual = cpl_image_get_data_int( xsh_pre_get_qual( pre_sci));
4559
4560 *sky_size = 0;
4561 int object_size = 0;
4562 int all_size = 0;
4563 double derrs;
4564 int idx;
4565 int sdx;
4566 double lambda_min = 10000., lambda_max = 0. ;
4567 int nx = xsh_pre_get_nx( pre_sci);
4568 //int ny = xsh_pre_get_ny( pre_sci);
4569 /*
4570 xsh_msg("nx=%d ny=%d",nx,ny);
4571 xsh_msg("slit map nx=%d ny=%d",(int)cpl_image_get_size_x(slitmap),(int)cpl_image_get_size_y(slitmap));
4572 xsh_msg("wave map nx=%d ny=%d",(int)cpl_image_get_size_x(wavemap),(int)cpl_image_get_size_y(wavemap));
4573 */
4574 float slit_val;
4575 /*
4576 xsh_msg("miny=%d maxy=%d",miny,maxy);
4577 xsh_msg("obj slit min=%g max=%g",obj_slit_min,obj_slit_max);
4578 xsh_msg("sky slit min=%g max=%g",sky_slit_min,sky_slit_max);
4579 */
4580 for (int iy = miny; iy < maxy; iy++) {
4581 //xsh_msg("ok0: iy=%d",iy);
4582 int minx=xsh_get_edge_x_min(ord_tab, iorder, iy);
4583 int maxx=xsh_get_edge_x_max(ord_tab, iorder, iy);
4584
4585 int offset_idx = iy * nx;
4586 int offset_sdx = iy * (nx - wmap_xsize_diff);
4587 //xsh_msg("ok2: iy=%d",iy);
4588 //xsh_msg("minx=%d maxx=%d",minx,maxx);
4589 //exit(0);
4590 for (int ix = minx; ix <= maxx; ix++) {
4591
4592 idx = ix + offset_idx;
4593 //xsh_msg("ok1: ix=%d idx=%d",ix,idx);
4594 if ((pqual[idx] & decode_bp) == 0) {
4595 /* good pix */
4596
4597 sdx = ix + offset_sdx;
4598 //xsh_msg("ok1: sdx=%d",sdx);
4599 double lambda = plambda[sdx];
4600 if (lambda == 0) {
4601 continue;
4602 }
4603 if (lambda < lambda_min) {
4604 lambda_min = lambda;
4605 }
4606 if (lambda > lambda_max) {
4607 lambda_max = lambda;
4608 }
4609 slit_val = pslit[sdx];
4610
4611
4612 pall->lambda = lambda;
4613 pall->slit = slit_val;
4614 pall->flux = *(pflux + idx);
4615 derrs = *(perrs + idx);
4616
4617 //pobject->sigma = (double) 1. / (derrs * derrs);
4618
4619 pall->sigma = (double) derrs;
4620 pall->qual = *(pqual + idx);
4621 pall->ix = ix;
4622 pall->iy = iy;
4623
4624
4625 pobject->fitted = 0;
4626 pobject->fit_err =0;
4627 psky->fitted = 0;
4628 psky->fit_err =0;
4629 pall->fitted = 0;
4630 pall->fit_err =0;
4631
4632
4633 all_size++;
4634 pall++;
4635
4636/*
4637 if ( ( (slit_val >= obj_slit_min) && (slit_val <= obj_slit_max) ) ||
4638 (slit_val < sky_slit_min) || (slit_val > sky_slit_max) ) {
4639 */
4640
4641
4642
4643 if ( ( (slit_val >= obj_slit_min) && (slit_val <= obj_slit_max) ) ) {
4644
4645 //xsh_msg("object");
4646 pobject->lambda = lambda;
4647 pobject->slit = slit_val;
4648 pobject->flux = *(pflux + idx);
4649 derrs = *(perrs + idx);
4650 //pobject->sigma = (double) 1. / (derrs * derrs);
4651
4652 pobject->sigma = (double) derrs;
4653 pobject->qual = *(pqual + idx);
4654 pobject->ix = ix;
4655 pobject->iy = iy;
4656 object_size++;
4657 pobject++;
4658 }
4659 else {
4660 //xsh_msg("sky");
4661 psky->lambda = lambda;
4662 psky->slit = slit_val;
4663 psky->flux = *(pflux + idx);
4664 derrs = *(perrs + idx);
4665 //psky->sigma = (double) 1. / (derrs * derrs);
4666 psky->sigma = (double) derrs;
4667 psky->qual = *(pqual + idx);
4668 psky->ix = ix;
4669 psky->iy = iy;
4670
4671
4672 (*sky_size)++;
4673 psky++;
4674 }
4675
4676 }
4677 //xsh_msg("ok2: ix=%d idx=%d",ix,idx);
4678 }
4679 //xsh_msg("ok3: iy=%d",iy);
4680 }
4681
4682
4683
4684 assure(*sky_size > 0, CPL_ERROR_ILLEGAL_INPUT,
4685 "On order %d sky_size 0. Order edge tab may "
4686 "over-estimate corresponding order size or "
4687 "localize-slit-hheight is too large or "
4688 "sky-slit-edges-mask too large or "
4689 "sky-hheight1 too small or too large ",
4690 order);
4691
4692 wave_list->list[iorder].all_size = all_size;
4693 wave_list->list[iorder].sky_size = *sky_size;
4694 wave_list->list[iorder].object_size = object_size;
4695 wave_list->list[iorder].lambda_min = lambda_min;
4696 wave_list->list[iorder].lambda_max = lambda_max;
4697 wave_list->sky_slit_min=sky_slit_min;
4698 wave_list->sky_slit_max=sky_slit_max;
4699 wave_list->obj_slit_min=obj_slit_min;
4700 wave_list->obj_slit_max=obj_slit_max;
4701
4702 /* Sort by lambda */
4703 qsort(wave_list->list[iorder].all, all_size, sizeof(wavemap_item),
4705 qsort(wave_list->list[iorder].sky, *sky_size, sizeof(wavemap_item),
4707 qsort(wave_list->list[iorder].object, object_size, sizeof(wavemap_item),
4709
4710 cleanup:
4711 return cpl_error_get_code();
4712}
4713
4714static cpl_error_code
4715xsh_skycor_def_nbkpts_ord(const int iorder, const int nbkpts,
4716 cpl_frame* break_pts_frame, xsh_instrument* inst,
4717 int bspline_sampling_method, int* nbkpts_ord)
4718{
4719
4720 if (break_pts_frame != NULL) {
4721 /* if the user specifies different factors use those */
4722 const char * name = cpl_frame_get_filename(break_pts_frame);
4723 cpl_table* break_pts_tab = cpl_table_load(name, 1, 0);
4724 int nrow = cpl_table_get_nrow(break_pts_tab);
4725 const double* pfactor = cpl_table_get_data_double_const(break_pts_tab,
4726 "FACTOR");
4727 switch (xsh_instrument_get_arm(inst))
4728 {
4729 case XSH_ARM_UVB:
4731 "Wrong number of factors for single frame sky subtraction table");
4732 xsh_nbkpts_uvb[iorder] = pfactor[iorder];
4733 break;
4734 case XSH_ARM_VIS:
4736 "Wrong number of factors for single frame sky subtraction table");
4737 xsh_msg("iorder=%d factor=%f", iorder, pfactor[iorder]);
4738 xsh_nbkpts_vis[iorder] = pfactor[iorder];
4739 break;
4740 case XSH_ARM_NIR:
4742 "Wrong number of factors for single frame sky subtraction table");
4743 xsh_nbkpts_nir[iorder] = pfactor[iorder];
4744 break;
4745 default:
4746 xsh_msg("Arm not supported");
4747 break;
4748 }
4749 xsh_free_table(&break_pts_tab);
4750 }
4751 double nbkpts_arm=0;
4752 switch (xsh_instrument_get_arm(inst))
4753 {
4754 case XSH_ARM_UVB:
4755 nbkpts_arm = xsh_nbkpts_uvb[iorder];break;
4756 case XSH_ARM_VIS:
4757 nbkpts_arm = xsh_nbkpts_vis[iorder];break;
4758 case XSH_ARM_NIR:
4759 nbkpts_arm = xsh_nbkpts_nir[iorder];break;
4760 default:
4761 xsh_msg("Arm not supported");break;
4762 }
4763 if (bspline_sampling_method == FINE) {
4764 *nbkpts_ord = (int) (nbkpts * nbkpts_arm + 0.5);
4765 }
4766 else {
4767 *nbkpts_ord = nbkpts;
4768 }
4769
4770 cleanup:
4771 return cpl_error_get_code();
4772}
4773
4774
4775static xsh_wavemap_list*
4776xsh_wavemap_list_new( cpl_frame *wavemap_frame, cpl_frame *slitmap_frame,
4777 xsh_localization *list, cpl_frame *order_table_frame,
4778 xsh_pre *pre_sci, int nbkpts,
4779 cpl_frame* break_points_frame,
4780 cpl_frame* ref_sky_list, cpl_frame* sky_orders_chunks,
4783{
4784 xsh_wavemap_list *wave_list = NULL;
4785 cpl_image *wavemap=NULL;
4786 cpl_image *slitmap=NULL;
4787 const char* wavemap_name=NULL;
4788 const char* slitmap_name=NULL;
4789
4790 int wmap_xsize_diff=0;
4791 double obj_slit_min=0, obj_slit_max=0;
4792 double sky_slit_min=0, sky_slit_max=0;
4793 int decode_bp=instrument->decode_bp;
4794 double gain=sky_par->gain;
4795 double ron2=sky_par->ron*sky_par->ron;
4796 xsh_order_list* order_table;
4797 int nbkpts_ord_max=50000;
4798 /* Check input parameters */
4799 XSH_ASSURE_NOT_NULL( wavemap_frame);
4800 XSH_ASSURE_NOT_NULL( slitmap_frame);
4801 XSH_ASSURE_NOT_NULL( order_table_frame);
4802 XSH_ASSURE_NOT_NULL( pre_sci);
4803 XSH_ASSURE_NOT_NULL( sky_par);
4805 XSH_ASSURE_NOT_NULL( ref_sky_list );
4806
4807 int nx = xsh_pre_get_nx( pre_sci);
4808 check( wavemap_name = cpl_frame_get_filename( wavemap_frame));
4809 check( wavemap = cpl_image_load( wavemap_name, CPL_TYPE_DOUBLE, 0, 0));
4810 check( slitmap_name = cpl_frame_get_filename( slitmap_frame));
4811 check( slitmap = cpl_image_load( slitmap_name, CPL_TYPE_DOUBLE,0, 0));
4813 wmap_xsize_diff=pre_sci->nx-cpl_image_get_size_x(slitmap);
4814 }
4816 nbkpts_ord_max=90000;
4817 }
4819 nbkpts_ord_max=90000;
4820 }
4822 double smap_min = cpl_image_get_min(slitmap);
4823 double smap_max = cpl_image_get_max(slitmap);
4824 xsh_get_obj_and_sky_extraction_slits(sky_par,list,smap_min,smap_max,
4825 &obj_slit_min, &obj_slit_max, &sky_slit_min, &sky_slit_max);
4826 //exit(0);
4827 //TODO: wmap_xsize_diff seems to be always 0 should be removed?
4828 check( order_table = xsh_order_list_load (order_table_frame, instrument));
4829 cpl_table* bkpts_tab=NULL;
4830
4831 const char* fname;
4832 if ( sky_par->method != MEDIAN_METHOD){
4833 fname = cpl_frame_get_filename(ref_sky_list);
4834
4835 }
4836
4837 if ( sky_par->method == BSPLINE_METHOD ||
4838 sky_par->method == BSPLINE_METHOD1 ||
4839 sky_par->method == BSPLINE_METHOD2 ||
4840 sky_par->method == BSPLINE_METHOD3 ||
4841 sky_par->method == BSPLINE_METHOD4 )
4842 {
4843 /* convert input table frame into cpl table */
4844 bkpts_tab = cpl_table_load(fname, 1, 0);
4845 if (cpl_table_get_column_type(bkpts_tab, "WAVELENGTH") == CPL_TYPE_DOUBLE) {
4846 cpl_table_duplicate_column(bkpts_tab,"TWAVELENGTH",bkpts_tab,"WAVELENGTH");
4847 cpl_table_erase_column(bkpts_tab,"WAVELENGTH");
4848 cpl_table_cast_column(bkpts_tab,"TWAVELENGTH","WAVELENGTH",CPL_TYPE_FLOAT);
4849 }
4850 if (cpl_table_get_column_type(bkpts_tab, "FLUX") == CPL_TYPE_DOUBLE) {
4851 cpl_table_duplicate_column(bkpts_tab,"TFLUX",bkpts_tab,"FLUX");
4852 cpl_table_erase_column(bkpts_tab,"FLUX");
4853 cpl_table_cast_column(bkpts_tab,"TFLUX","FLUX",CPL_TYPE_FLOAT);
4854 }
4855 cpl_table_erase_column(bkpts_tab,"NAME");
4856 cpl_table_erase_column(bkpts_tab,"COMMENT");
4857
4858 }
4859
4860 /* Loop over orders */
4861 for ( int iorder = 0; iorder < order_table->size; iorder++){
4862
4863 /* Calculate x,y limits --> minx, maxx, miny, maxy */
4864 int miny = xsh_order_list_get_starty( order_table, iorder);
4865 int maxy = xsh_order_list_get_endy( order_table, iorder);
4866
4867 int starty = order_table->list[iorder].starty/instrument->biny;
4868
4869 int endy = order_table->list[iorder].endy/instrument->biny;
4870
4871 miny = ( miny > starty ) ? miny : starty;
4872 maxy = ( maxy < endy ) ? maxy : endy;
4873
4874 int order = order_table->list[iorder].absorder ;
4875 xsh_msg_dbg_medium( "Order %d, miny %d, maxy %d", order, miny, maxy ) ;
4876 int max_size=0;
4877 int max_size_x=0;
4878
4879 xsh_get_sky_edges_min_max_and_size(sky_par, miny, maxy, iorder, order,
4880 nx, wmap_xsize_diff, order_table,
4881 slitmap, &sky_slit_min,
4882 &sky_slit_max, &max_size, &max_size_x);
4883
4884 xsh_msg( "SKY data slit range : [%f,%f],[%f,%f]",
4885 sky_slit_min, obj_slit_min, obj_slit_max, sky_slit_max);
4886
4887 check(xsh_wavemap_list_set_max_size( wave_list, iorder, order, max_size));
4888
4889 int sky_size = 0;
4890 xsh_wavecal_list_pupulate(pre_sci, iorder, miny, maxy, wmap_xsize_diff,
4891 decode_bp, obj_slit_min, obj_slit_max,
4892 sky_slit_min, sky_slit_max, order, wave_list,
4893 &sky_size, order_table, wavemap, slitmap);
4894
4895 if ( sky_par->method != MEDIAN_METHOD){
4896 /* Fit spline */
4897
4898 int nbkpts_ord=0;
4899 double* wsampl=NULL;
4900 cpl_table* wsampl_tab=NULL;
4901 check(xsh_skycor_def_nbkpts_ord(iorder, nbkpts, break_points_frame,
4902 instrument, sky_par->bspline_sampling, &nbkpts_ord));
4903
4904 double wmin=wave_list->list[iorder].lambda_min;
4905 double wmax=wave_list->list[iorder].lambda_max;
4906
4907
4908 cpl_table* tab_ord=NULL;
4909
4910 if ( sky_par->method == BSPLINE_METHOD ||
4911 sky_par->method == BSPLINE_METHOD1 ||
4912 sky_par->method == BSPLINE_METHOD2 ||
4913 sky_par->method == BSPLINE_METHOD3 ||
4914 sky_par->method == BSPLINE_METHOD4 ){
4915
4916 //xsh_msg("ref sky list: %s nrows=%d",fname,(int)cpl_table_get_nrow(bkpts_tab));
4917 cpl_table_and_selected_float(bkpts_tab,"WAVELENGTH",CPL_NOT_GREATER_THAN,wmax);
4918 cpl_table_and_selected_float(bkpts_tab,"WAVELENGTH",CPL_GREATER_THAN,wmin);
4919 tab_ord=cpl_table_extract_selected(bkpts_tab);
4920 cpl_table_select_all(bkpts_tab);
4921
4922 } else if ( sky_par->method == BSPLINE_METHOD5) {
4923
4924 /* load sampling points from proper extension */
4925 int orders_nb;
4926 const char* name;
4927 if(instrument->arm == XSH_ARM_UVB) {
4928 orders_nb=instrument->uvb_orders_nb;
4929 name="xsh_kelson_becker_bkpts_uvb.fits";
4930 } else if (instrument->arm == XSH_ARM_VIS) {
4931 orders_nb=instrument->vis_orders_nb;
4932 name="xsh_kelson_becker_bkpts_vis.fits";
4933 } else {
4934 orders_nb=instrument->nir_orders_nb;
4935 name="xsh_kelson_becker_bkpts_nir.fits";
4936 }
4937 xsh_msg("iorder=%d wmin=%g wmax=%g orders=%d",
4938 iorder,wmin,wmax,orders_nb);
4939
4940 wsampl_tab = cpl_table_load(name, orders_nb-iorder, 0);
4941 cpl_table_name_column(wsampl_tab,"col1","WAVELENGTH");
4942 cpl_table_divide_scalar(wsampl_tab,"WAVELENGTH",10.);
4943
4944 }
4945
4946 cpl_table* tab_line_res=NULL;
4947 wavemap_item * psky=NULL;
4948 wavemap_item * psky_start=NULL;
4949
4950 for(int i=0;i<sky_par->niter;i++) {
4951 if ( sky_par->method == BSPLINE_METHOD ||
4952 sky_par->method == BSPLINE_METHOD1 ||
4953 sky_par->method == BSPLINE_METHOD2 ||
4954 sky_par->method == BSPLINE_METHOD3 ||
4955 sky_par->method == BSPLINE_METHOD4 ){
4956
4957 /* correct sampling table if new break points need to be added */
4958 int nbkpts=cpl_table_get_nrow(tab_ord);
4959 //xsh_msg("selected sampling lines %d wmin=%g wmax=%g",nbkpts,wmin,wmax);
4960 if(tab_line_res != NULL) {
4961 int nres=cpl_table_get_nrow(tab_line_res);
4962 if(nres>0) {
4963 if (cpl_table_get_column_type(tab_ord, "FLUX") == CPL_TYPE_INT) {
4964 cpl_table_duplicate_column(tab_ord,"FFLUX",tab_ord,"FLUX");
4965 cpl_table_erase_column(tab_ord,"FLUX");
4966 cpl_table_cast_column(tab_ord,"FFLUX","FLUX",CPL_TYPE_FLOAT);
4967 cpl_table_erase_column(tab_ord,"FFLUX");
4968 cpl_table_set_column_unit(tab_ord,"FLUX","rel-flux");
4969 cpl_table_set_column_unit(tab_ord,"WAVELENGTH","nm");
4970 }
4971 check(cpl_table_insert(tab_ord,tab_line_res,nbkpts));
4972 xsh_sort_table_1(tab_ord,"WAVELENGTH",CPL_FALSE);
4973 }
4974 xsh_free_table(&tab_line_res);
4975
4976 }
4977
4978 check(wsampl_tab=xsh_skycorr_wave_sampling_create(wave_list,
4979 iorder,nbkpts_ord,tab_ord));
4980
4981 }
4982
4983 check(wsampl=cpl_table_get_data_double(wsampl_tab,"WAVELENGTH"));
4984 //int nrow=0;
4985 int j=0;
4986 cpl_table* tab_bad_fit=NULL;
4987 nbkpts_ord=cpl_table_get_nrow(wsampl_tab);
4988 xsh_msg("Sampling iter=%d nbkpts_ord=%d",i,nbkpts_ord);
4989 if(nbkpts_ord > nbkpts_ord_max) {
4990 xsh_msg_error("too many break points");
4991 exit(0);
4992 }
4993
4994 //cpl_table_save(wsampl_tab,NULL,NULL,"line_sampl_tab.fits",CPL_IO_DEFAULT);
4995 //char sname[80];
4996
4997 int sky_ndata = wave_list->list[iorder].sky_size;
4998 psky = wave_list->list[iorder].sky;
4999 psky_start = wave_list->list[iorder].sky;
5000 for(j=0, psky=psky_start;j< sky_ndata;j++,psky++) {
5001 psky->fitted=0;
5002 psky->fit_err=0;
5003 }
5004 /*
5005 xsh_msg("sky slit min=%g max=%g",
5006 wave_list->sky_slit_min,wave_list->sky_slit_max);
5007 */
5008 if ( sky_par->method == BSPLINE_METHOD ||
5009 sky_par->method == BSPLINE_METHOD1 ||
5010 sky_par->method == BSPLINE_METHOD3) {
5011 check(tab_bad_fit=xsh_fit_spline1(wave_list,iorder,
5012 wsampl_tab,sky_orders_chunks,nbkpts_ord,i,
5013 sky_par, ron2, gain, &tab_line_res));
5014 } else if ( sky_par->method == BSPLINE_METHOD2 ||
5015 sky_par->method == BSPLINE_METHOD4 ){
5016 check(tab_bad_fit=xsh_fit_spline2(wave_list,iorder,
5017 wsampl_tab,sky_orders_chunks,nbkpts_ord,i,
5018 sky_par, ron2, gain, &tab_line_res));
5019
5020
5021 }
5022
5023 if(tab_bad_fit!=NULL) {
5024
5025 cpl_table_and_selected_int(tab_bad_fit,"FLAG",CPL_EQUAL_TO,1);
5026 cpl_table* tab_bp=cpl_table_extract_selected(tab_bad_fit);
5027 cpl_table_select_all(tab_bad_fit);
5028 cpl_table_and_selected_int(tab_bad_fit,"FLAG",CPL_EQUAL_TO,2);
5029 cpl_table* tab_lr=cpl_table_extract_selected(tab_bad_fit);
5030#if REGDEBUG_BSPLINE
5031 cpl_table_save(tab_lr,NULL,NULL,"tab_lr.fits",CPL_IO_DEFAULT);
5032 cpl_table_save(tab_bp,NULL,NULL,"tab_bp.fits",CPL_IO_DEFAULT);
5033#endif
5034 xsh_free_table(&tab_bad_fit);
5035 cpl_table_erase_column(tab_lr,"FLAG");
5036 cpl_table_erase_column(tab_bp,"FLAG");
5037#if REGDEBUG_BSPLINE
5038 sprintf(sname,"tab_lr_ord_%2.2d_%2.2d.reg",order,i);
5039 xsh_dump_table_on_region_file(tab_lr,sname,1);
5040 sprintf(sname,"tab_lr_ord_%2.2d_%2.2d.fits",order,i);
5041 //cpl_table_save(tab_lr,NULL,NULL,sname,CPL_IO_DEFAULT);
5042 sprintf(sname,"tab_bp_ord_%2.2d_%2.2d.reg",order,i);
5043 xsh_dump_table_on_region_file(tab_bp,sname,2);
5044 sprintf(sname,"tab_bp_ord_%2.2d_%2.2d.fits",order,i);
5045 //cpl_table_save(tab_bp,NULL,NULL,sname,CPL_IO_DEFAULT);
5046#endif
5047
5048
5049 /* adding sampling points
5050 nrow=cpl_table_get_nrow(wsampl_tab);
5051 cpl_table_insert(wsampl_tab,tab_lr,nrow);
5052 cpl_table* tmp=cpl_table_duplicate(wsampl_tab);
5053 xsh_free_table(&wsampl_tab);
5054 check(wsampl_tab=xsh_table_unique_column(tmp,"WAVELENGTH"));
5055 check(xsh_sort_table_3(wsampl_tab,"WAVELENGTH","Y","X",CPL_TRUE,CPL_TRUE,CPL_TRUE));
5056 xsh_free_table(&tmp);
5057 */
5058 /* removing sampling points */
5059 int nbp_row=cpl_table_get_nrow(tab_bp);
5060 int nlr_row=cpl_table_get_nrow(tab_lr);
5061 int nsrow=cpl_table_get_nrow(wsampl_tab);
5062 xsh_msg("Sampling: adding %d removing %d points",nlr_row,nbp_row);
5063 xsh_msg("Sampling: original %d points",nbkpts_ord);
5064 double* pbw = cpl_table_get_data_double(tab_bp,"WAVELENGTH");
5065 double* psw = cpl_table_get_data_double(wsampl_tab,"WAVELENGTH");
5066 int nbad=0;
5067 for(int k=0;k<nbp_row;k++) {
5068 // NOTE that we do not remove the 1st and the last
5069 // sampling points in order to have full coverage of
5070 // the wavelength range!!
5071
5072 for(int j=1;j<nsrow-1;j++) {
5073 if(psw[j] == pbw[k]) {
5074 check(cpl_table_set_invalid(wsampl_tab,"WAVELENGTH",j));
5075 nbad++;
5076 }
5077 }
5078 }
5079 cpl_table_erase_invalid(wsampl_tab);
5080 nbkpts_ord=cpl_table_get_nrow(wsampl_tab);
5081 xsh_msg("Sampling: removed %d bad pixels",nbad);
5082 xsh_msg("Sampling: After update %d points",nbkpts_ord);
5083 //cpl_table_dump_structure(wsampl_tab,stdout);
5084#if REDDEBUG_SPLINE
5085 sprintf(sname,"samplin_ord_%2.2d_%2.2d.reg",order,i);
5086 check(xsh_dump_table_on_region_file(wsampl_tab,sname, 4));
5087 sprintf(sname,"samplin_ord_%2.2d_%2.2d.fits",order,i);
5088 //cpl_table_save(wsampl_tab,NULL,NULL,sname,CPL_IO_DEFAULT);
5089#endif
5090 xsh_free_table(&tab_bp);
5091 xsh_free_table(&tab_lr);
5092 }
5093
5094 xsh_wavemap_list_rms_sky_image_save(wave_list,ron2,gain,instrument,i);
5096 xsh_wavemap_list_sky_image_save( wave_list, instrument, 0,0,i);
5097
5098 }
5099 xsh_free_table(&tab_ord);
5100 xsh_free_table(&tab_line_res);
5101 xsh_free_table(&wsampl_tab);
5102 double rms=0;
5103 rms=xsh_skycorr_rms(wave_list,iorder,ron2,gain);
5104 xsh_msg("rms=%g",rms);
5105 //check(xsh_wavemap_list_sky_image_save(wave_list,instrument,"sky"));
5106
5107 //exit(0);
5108
5109 /*
5110 xsh_msg("sk0");
5111 cpl_frame* wlist =
5112 xsh_wavemap_list_save(wave_list, order_table_frame, pre_sci, instrument,
5113 "pippo");
5114 xsh_msg("sk1");
5115 exit(0);
5116 */
5117 xsh_msg("Sampling points nbkpts_ord=%d",nbkpts_ord);
5118 }
5119 else{
5120 /* median method */
5121 int median_hsize = sky_par->median_hsize;
5122 int nb_points = 2*median_hsize+1;
5123 //double m_pi_2 = 0.5*M_PI;
5124 cpl_vector* median_vector = cpl_vector_new( nb_points);
5125 wavemap_item *psky = wave_list->list[iorder].sky;
5126
5127 for( int i=median_hsize; i< (sky_size-median_hsize); i++){
5128 //double median_err=0.0;
5129 int pixel = i-median_hsize;
5130 //double wght=0;
5131 for(int mediani=0; mediani< nb_points; mediani++){
5132 cpl_vector_set( median_vector, mediani, psky[pixel+mediani].flux);
5133 /* NB: psky[pixel+mediani].sigma contains actually the 1./(sigma*sigma) value
5134 * Thus formula after is numerically correct despite "appears" wrong
5135 *
5136 */
5137 //median_err += 1.0/psky[pixel+mediani].sigma;
5138
5139 //wght = psky[pixel+mediani].sigma;
5140 //median_err += (wght*wght);
5141 }
5142 double median = cpl_vector_get_median(median_vector);
5143 psky[i].fitted = median;
5144 /* we assume eeror-free model */
5145 psky[i].fit_err = 0;
5146 }
5147 xsh_free_vector( &median_vector);
5148
5149 }
5150
5151 }
5152
5153 //xsh_wavemap_list_sky_image_save( wave_list, wave_list->instrument, 0,0,90);
5154 //xsh_wavemap_list_object_image_save( wave_list, instrument, 91);
5155 //exit(0);
5156
5157 xsh_wavemap_list_rms_sky_image_save(wave_list,ron2,gain,instrument,100);
5159 xsh_wavemap_list_sky_image_save( wave_list, instrument, 0,0,100);
5160
5161
5162 cleanup :
5163 xsh_free_image( &slitmap);
5164 xsh_free_image( &wavemap);
5165 xsh_order_list_free( &order_table);
5166
5167 return wave_list ;
5168}
5169/*****************************************************************************/
5170
5171/*****************************************************************************/
5177/*****************************************************************************/
5180 xsh_rec_list* sky_list = NULL;
5181 int i, j;
5182 int level;
5183
5184 /* check input parameters */
5185 XSH_ASSURE_NOT_NULL( wave_list);
5186 XSH_ASSURE_NOT_NULL( instr);
5187
5188 xsh_msg("Build sky model");
5189 level = xsh_debug_level_get();
5190
5191 check( sky_list = xsh_rec_list_create_with_size( wave_list->size, instr));
5192
5193 /* Loop over orders */
5194 for (i = 0; i < wave_list->size; i++) {
5195
5196 wavemap_item *psky = NULL;
5197 int order;
5198 int sky_size;
5199 double *lambdas = NULL;
5200 float *sky_flux = NULL;
5201 float *sky_err = NULL;
5202 int *sky_qua = NULL;
5203 //float* pflat = NULL;
5204 //int sx = 0;
5205
5206 psky = wave_list->list[i].sky;
5207 sky_size = wave_list->list[i].sky_size;
5208 order = wave_list->list[i].order;
5209
5210 check( xsh_rec_list_set_data_size( sky_list, i, order, sky_size, 1));
5211 check( lambdas = xsh_rec_list_get_lambda( sky_list, i));
5212 check( sky_flux = xsh_rec_list_get_data1( sky_list, i));
5213 check( sky_err = xsh_rec_list_get_errs1( sky_list, i));
5214 check( sky_qua = xsh_rec_list_get_qual1( sky_list, i));
5215
5216 for (j = 0; j < sky_size; j++) {
5217 lambdas[j] = psky->lambda;
5218 sky_flux[j] = psky->fitted;
5219 sky_err[j] = psky->fit_err;
5220 sky_qua[j] = psky->qual;
5221 psky++;
5222 }
5223
5224 if (level >= XSH_DEBUG_LEVEL_MEDIUM) {
5225 FILE* debug = NULL;
5226 char debug_name[256];
5227
5228 sprintf(debug_name, "fitted_data_sky_%d.log", order);
5229 debug = fopen(debug_name, "w");
5230 fprintf(debug, "# lambda flux err x y slit\n");
5231 psky = wave_list->list[i].sky;
5232
5233 for (j = 0; j < sky_size; j++) {
5234 fprintf(debug, "%f %f %f %d %d %f\n", psky->lambda, psky->fitted,
5235 psky->fit_err, psky->ix, psky->iy, psky->slit);
5236 psky++;
5237 }
5238 fclose(debug);
5239 }
5240
5241 }
5242
5243 cleanup:
5244 if (cpl_error_get_code() != CPL_ERROR_NONE) {
5245 xsh_rec_list_free(&sky_list);
5246 }
5247
5248 return sky_list;
5249}
5250
5251cpl_error_code
5253 xsh_rec_list* sky_list = NULL;
5254 int i, j;
5255 int level;
5256
5257 /* check input parameters */
5258 XSH_ASSURE_NOT_NULL( wave_list);
5259 XSH_ASSURE_NOT_NULL( instr);
5260
5261 xsh_msg("Build sky model");
5262 level = xsh_debug_level_get();
5263 int nx=wave_list->instrument->config->nx/wave_list->instrument->binx;
5264 int ny=wave_list->instrument->config->ny/wave_list->instrument->biny;
5265 xsh_msg("nx=%d ny=%d",nx,ny);
5266 check( sky_list = xsh_rec_list_create_with_size( wave_list->size, instr));
5267 cpl_image* sky_ima=cpl_image_new(nx,ny,CPL_TYPE_FLOAT);
5268 cpl_image* qua_ima=cpl_image_new(nx,ny,CPL_TYPE_INT);
5269 float* psky_ima=cpl_image_get_data_float(sky_ima);
5270 int* pqua_ima=cpl_image_get_data_int(qua_ima);
5271 /* Loop over orders */
5272 for (i = 0; i < wave_list->size; i++) {
5273
5274 wavemap_item * psky = wave_list->list[i].sky;
5275 int sky_size = wave_list->list[i].sky_size;
5276
5277 wavemap_item * pobj = wave_list->list[i].object;
5278 int obj_size = wave_list->list[i].object_size;
5279
5280 for (j = 0; j < sky_size; j++,psky++) {
5281 psky_ima[psky->ix+nx*psky->iy]=psky->fitted;
5282 pqua_ima[psky->ix+nx*psky->iy]=psky->qual;
5283 }
5284
5285 for (j = 0; j < obj_size; j++,pobj++) {
5286 psky_ima[pobj->ix+nx*pobj->iy]=pobj->fitted;
5287 pqua_ima[pobj->ix+nx*pobj->iy]=pobj->qual;
5288 }
5289
5290 }
5291
5292/*
5293 cpl_image_save(sky_ima, "sky_model_full.fits",XSH_PRE_DATA_BPP ,wave_list->header, CPL_IO_DEFAULT);
5294 cpl_image_save(qua_ima, "sky_model_full.fits",XSH_PRE_QUAL_BPP ,wave_list->header, CPL_IO_EXTEND);
5295*/
5296
5297 cleanup:
5298 xsh_rec_list_free(&sky_list);
5299 xsh_free_image(&sky_ima);
5300 xsh_free_image(&qua_ima);
5301 if (cpl_error_get_code() != CPL_ERROR_NONE) {
5302 xsh_rec_list_free(&sky_list);
5303 }
5304
5305 return cpl_error_get_code();
5306}
5307static void
5308xsh_obj_fit_dump(int iorder, xsh_wavemap_list* wave_list)
5309{
5310 int level = xsh_debug_level_get();
5311 if (level >= XSH_DEBUG_LEVEL_MEDIUM) {
5312 for (iorder = 0; iorder < wave_list->size; iorder++) {
5313 wavemap_item* pobject = NULL;
5314 int j, order, object_size;
5315 FILE* debug = NULL;
5316 char debug_name[256];
5317
5318 order = wave_list->list[iorder].order;
5319 object_size = wave_list->list[iorder].object_size;
5320 pobject = wave_list->list[iorder].object;
5321
5322 sprintf(debug_name, "fitted_data_obj_%d.log", order);
5323 debug = fopen(debug_name, "w");
5324 fprintf(debug, "# lambda flux err x y slit\n");
5325
5326 for (j = 0; j < object_size; j++) {
5327 fprintf(debug, "%f %f %f %d %d %f\n", pobject->lambda,
5328 pobject->fitted, pobject->fit_err, pobject->ix,
5329 pobject->iy, pobject->slit);
5330 pobject++;
5331 }
5332 fclose(debug);
5333 }
5334 }
5335 return;
5336}
5337
5338static cpl_error_code
5339xsh_subtract_sky_at_pix2(const int all_size,const int sky_size, const int nx,
5340 wavemap_item* pall,wavemap_item* psky,
5341 float* pflux, float* pflat, float* perrs, int* pqual)
5342{
5343 for (int i = 0; i < all_size; i++) {
5344 int x, y;
5345 float flux, fitted, err, fitted_err;
5346
5347 x = pall->ix;
5348 y = pall->iy;
5349 int pixel = x + y * nx;
5350 flux = pflux[pixel];
5351 fitted = pall->fitted;
5352 fitted_err = pall->fit_err;
5353 pflux[pixel] = flux - fitted;
5354 err = perrs[pixel];
5355 perrs[pixel] = sqrt(fitted_err * fitted_err + err * err);
5356 pqual[pixel] = pall->qual;
5357 pall++;
5358 }
5359
5360 for (int i = 0; i < sky_size; i++) {
5361 int x, y;
5362 //float flux, fitted, err, fitted_err;
5363 x = psky->ix;
5364 y = psky->iy;
5365 int pixel = x + y * nx;
5366 //flux = pflux[pixel];
5367 //fitted = psky->fitted;
5368 //fitted_err = psky->fit_err;
5369 //pflux[pixel] /= flux - fitted;
5370 //err = perrs[pixel];
5371 //perrs[pixel] = sqrt(fitted_err * fitted_err + err * err);
5372 pqual[pixel] = psky->qual;
5373 psky++;
5374 }
5375 return cpl_error_get_code();
5376}
5377
5378static cpl_error_code
5379xsh_subtract_sky_at_pix(const int sky_size, const int nx, wavemap_item* psky,
5380 float* pflux, float* pflat, float* perrs, int* pqual)
5381{
5382 for (int i = 0; i < sky_size; i++) {
5383 int x, y;
5384 float flux, fitted, err, fitted_err;
5385
5386 x = psky->ix;
5387 y = psky->iy;
5388 int pixel = x + y * nx;
5389 flux = pflux[pixel];
5390 fitted = psky->fitted;
5391 fitted_err = psky->fit_err;
5392 pflux[pixel] = flux - fitted;
5393 err = perrs[pixel];
5394 perrs[pixel] = sqrt(fitted_err * fitted_err + err * err);
5395 pqual[pixel] = psky->qual;
5396 psky++;
5397 }
5398 return cpl_error_get_code();
5399}
5400
5401
5402
5403static cpl_error_code
5405 const int object_size, const int nx,
5406 wavemap_item** pobject, float* pflux,
5407 float* perrs, int* pqual)
5408{
5409 int sky_lambdas_size = xsh_rec_list_get_nlambda( sky_list, iorder);
5410 double* sky_lambdas = xsh_rec_list_get_lambda( sky_list, iorder);
5411 float* sky_flux = xsh_rec_list_get_data1( sky_list, iorder);
5412 float* sky_err = xsh_rec_list_get_errs1( sky_list, iorder);
5413 //int* sky_qua = xsh_rec_list_get_qual1( sky_list, iorder);
5414 int sky_lambdas_idx=0;
5415 for (int i = 0; i < object_size; i++) {
5416 int x, y;
5417 float flux, err, fitted, fitted_err;
5418 float lambda, lambda_min, lambda_max;
5419 float flux_min, flux_max, err_min, err_max;
5420 float cte_min, cte_max;
5421 //double slope=0;
5422 x = (*pobject)->ix;
5423 y = (*pobject)->iy;
5424 lambda = (*pobject)->lambda;
5425 //int obj_qual = (*pobject)->qual;
5426 int pixel = x + y * nx;
5427 flux = pflux[pixel];
5428 while ((sky_lambdas_idx < sky_lambdas_size)
5429 && (sky_lambdas[sky_lambdas_idx] <= lambda)) {
5430 (sky_lambdas_idx)++;
5431 }
5432 if (sky_lambdas_idx >= (sky_lambdas_size - 1)) {
5433 break;
5434 }
5435 lambda_max = sky_lambdas[sky_lambdas_idx];
5436 if (sky_lambdas_idx == 0) {
5437 (*pobject)++;
5438 continue;
5439 }
5440 lambda_min = sky_lambdas[sky_lambdas_idx - 1];
5441 flux_min = sky_flux[sky_lambdas_idx - 1];
5442 flux_max = sky_flux[sky_lambdas_idx];
5443 err_min = sky_err[sky_lambdas_idx - 1];
5444 err_max = sky_err[sky_lambdas_idx];
5445 cte_max = (lambda - lambda_min) / (lambda_max - lambda_min);
5446 cte_min = 1 - cte_max;
5447
5448
5449 fitted = flux_min * cte_min + flux_max * cte_max;
5450 //slope=(flux_max-flux_min)/(lambda_max-lambda_min);
5451 //fitted = flux_min + slope * (lambda - lambda_min);
5452
5453 fitted_err = sqrt(
5454 err_min * err_min * cte_min
5455 + err_max * err_max * cte_max);
5456 (*pobject)->fitted = fitted;
5457 (*pobject)->fit_err = fitted_err;
5458 pflux[pixel] = flux - fitted;
5459 err = perrs[pixel];
5460 perrs[pixel] = sqrt(err * err + fitted_err * fitted_err);
5461 //pqual[pixel] = obj_qual |= sky_qua[pixel];
5462 (*pobject)++;
5463 }
5464
5465 return cpl_error_get_code();
5466}
5467
5468/*****************************************************************************/
5469
5470/*****************************************************************************/
5471#if 0
5472static void
5473xsh_image_clean(xsh_pre* pre,const int decode_bp){
5474 double *spectrum_flux = NULL;
5475 double *spectrum_errs = NULL;
5476 int *spectrum_qual = NULL;
5477
5478
5479 cpl_mask* mask = xsh_qual_to_cpl_mask(pre->qual,decode_bp);
5480
5481 cpl_mask * filtered = xsh_bpm_filter(mask,5,5,CPL_FILTER_CLOSING);
5483 xsh_free_mask(&mask);
5484 //cpl_image_save(pre->data, "before.fits", CPL_TYPE_FLOAT, NULL, CPL_IO_CREATE);
5485
5486 cpl_image_reject_from_mask(pre->data,filtered);
5487
5488 cpl_image_reject_from_mask(pre->errs,filtered);
5489 //cpl_detector_interpolate_rejected(pre->data);
5490 //cpl_detector_interpolate_rejected(pre->errs);
5491
5492 //cpl_image_save(pre->data, "after.fits", CPL_TYPE_FLOAT, NULL, CPL_IO_CREATE);
5493 xsh_free_mask(&filtered);
5494
5495 return;
5496
5497}
5498#endif
5499/*****************************************************************************/
5504/*****************************************************************************/
5505static cpl_frame*
5508 const char* rec_prefix,xsh_subtract_sky_single_param* sky_par) {
5509
5510 float* perrs = NULL;
5511 float* pflux = NULL;
5512 float* pflat = NULL;
5513 int* pqual = NULL;
5514 int nx, ny;
5515 xsh_pre* pre_res = NULL;
5516 cpl_image* res_image = NULL;
5517 cpl_frame* res_frame = NULL;
5518 int iorder;
5519 char tag[256];
5520 char fname[256];
5521
5522 /* check input parameters */
5523 XSH_ASSURE_NOT_NULL( pre_sci);
5524 XSH_ASSURE_NOT_NULL( sky_list);
5525 XSH_ASSURE_NOT_NULL( wave_list);
5526
5527 check( pre_res = xsh_pre_duplicate( pre_sci));
5528 check( res_image = xsh_pre_get_data( pre_res));
5529 check( pflux = cpl_image_get_data_float( res_image));
5530 check( perrs = cpl_image_get_data_float( xsh_pre_get_errs( pre_res)));
5531 check( pqual = cpl_image_get_data_int( xsh_pre_get_qual( pre_res)));
5532
5533 nx = xsh_pre_get_nx(pre_res);
5534 ny = xsh_pre_get_ny(pre_res);
5535
5536 for (iorder = 0; iorder < wave_list->size; iorder++) {
5537 wavemap_item* psky = NULL;
5538 wavemap_item* pall = NULL;
5539 wavemap_item* pobject = NULL;
5540 int order, sky_size, object_size,all_size;
5541
5542 order = wave_list->list[iorder].order;
5543 psky = wave_list->list[iorder].sky;
5544 pall = wave_list->list[iorder].all;
5545 sky_size = wave_list->list[iorder].sky_size;
5546 all_size = wave_list->list[iorder].all_size;
5547
5548 xsh_msg_dbg_medium( "Subtract Sky - Order %d", order);
5549 if(sky_par->method == BSPLINE_METHOD ||
5550 sky_par->method == BSPLINE_METHOD1 ||
5551 sky_par->method == BSPLINE_METHOD2 ||
5552 sky_par->method == BSPLINE_METHOD3 ||
5553 sky_par->method == BSPLINE_METHOD4) { //3
5554 xsh_subtract_sky_at_pix2(all_size, sky_size, nx, pall, psky, pflux, pflat, perrs,pqual);
5555 } else {
5556 xsh_subtract_sky_at_pix(sky_size, nx, psky, pflux, pflat, perrs,pqual);
5557 }
5558 object_size = wave_list->list[iorder].object_size;
5559 pobject = wave_list->list[iorder].object;
5560
5562 "Subtract Sky on object - Order %d size %d", order, object_size);
5563 if(sky_par->method == BSPLINE_METHOD ||
5564 sky_par->method == BSPLINE_METHOD1 ||
5565 sky_par->method == BSPLINE_METHOD2 ||
5566 sky_par->method == BSPLINE_METHOD3 ||
5567 sky_par->method == BSPLINE_METHOD4) { //3
5568
5569 } else {
5570
5571 xsh_subtract_sky_on_obj_at_pix(sky_list,iorder, object_size, nx, &pobject,
5572 pflux, perrs, pqual);
5573
5574 }
5575 }
5576
5577 xsh_obj_fit_dump(iorder, wave_list);
5578
5580
5582 xsh_wavemap_list_sky_image_save( wave_list, instrument, 0,0,99);
5583 sprintf(tag, "%s_SUB_SKY_%s", rec_prefix,
5585 sprintf(fname, "%s.fits", tag);
5586
5587 /* AMO FILTER filter BP */
5588 //xsh_image_clean(pre_res,instrument->decode_bp);
5589
5590 if (strstr(fname, "TMPSKY") != NULL) {
5591 check( res_frame = xsh_pre_save( pre_res, fname, tag, 1 ));
5592 } else {
5593 check( res_frame = xsh_pre_save( pre_res, fname, tag, 0 ));
5594 }
5595
5596 check(
5597 xsh_frame_config(fname,tag,CPL_FRAME_TYPE_IMAGE,CPL_FRAME_GROUP_CALIB, CPL_FRAME_LEVEL_FINAL,&res_frame));
5598 //xsh_add_temporary_file(fname);
5599
5600 cleanup:
5601 xsh_pre_free(&pre_res);
5602
5603
5604 return res_frame;
5605}
5606/*****************************************************************************/
5607/*
5608
5609static cpl_error_code
5610xsh_result_check(cpl_frame* res_frame,cpl_frame* wavemap_frame){
5611 const char* res_name = cpl_frame_get_filename(res_frame);
5612 const char* wav_name = cpl_frame_get_filename(wavemap_frame);
5613 cpl_image* res_ima=cpl_image_load(res_name,CPL_TYPE_DOUBLE,0,0);
5614 cpl_image* wav_ima=cpl_image_load(wav_name,CPL_TYPE_DOUBLE,0,0);
5615 double* pres=cpl_image_get_data_double(res_ima);
5616 double* pwav=cpl_image_get_data_double(wav_ima);
5617 int nx =cpl_image_get_size_x(res_ima);
5618 int ny =cpl_image_get_size_y(res_ima);
5619 int i;
5620 int nx_ny=nx*ny;
5621 for(i=0;i<nx_ny;i++) {
5622 if(pwav[i] == 0.) pres[i]=0.;
5623 }
5624 cpl_image_save(res_ima, "obj_result.fits", CPL_BPP_IEEE_FLOAT, NULL, CPL_IO_DEFAULT);
5625
5626 cpl_image_delete(res_ima);
5627 cpl_image_delete(wav_ima);
5628 return cpl_error_get_code();
5629}
5630*/
5631
5632
5633/*****************************************************************************/
5666/* TODO
5667 * slitmap_frame,wavemap_frame may be replaced by the physical model
5668 * usr_defined_break_points_frame should be removed
5669 * nbkpts should be removed (made automatic optimisation or part of sky_params)
5670 * why two different parameters for order_table_frame, loc_table_frame?
5671 */
5672/*****************************************************************************/
5673cpl_frame *
5674xsh_subtract_sky_single (cpl_frame *sci_frame,
5675 cpl_frame *order_table_frame,
5676 cpl_frame *slitmap_frame,
5677 cpl_frame *wavemap_frame,
5678 cpl_frame *loc_table_frame,
5679 cpl_frame *ref_sky_list,
5680 cpl_frame *ref_sky_orders_chunks,
5681 cpl_frame *usr_def_sampl_points,
5683 int nbkpts,
5685 cpl_frame **sky_spectrum,
5686 cpl_frame** sky_spectrum_eso,
5687 const char* rec_prefix,const int clean_tmp)
5688{
5689 cpl_frame *res_frame = NULL ;
5690 xsh_pre *pre_sci = NULL;
5691 xsh_wavemap_list *wave_list = NULL;
5692 xsh_localization *local_list = NULL;
5693 xsh_rec_list *sky_list = NULL;
5694 cpl_frame *sky_frame = NULL;
5695 cpl_frame *sky_frame2 = NULL;
5696 char fname[256];
5697 char tag[256];
5698
5699 /* check input parameters */
5700 XSH_ASSURE_NOT_NULL_MSG( sci_frame,"Required science frame is missing");
5701 XSH_ASSURE_NOT_NULL_MSG( order_table_frame,"Required order table frame is missing");
5702 XSH_ASSURE_NOT_NULL_MSG( slitmap_frame, "Required slitmap frame is missing, provide it or set compute-map to TRUE");
5703 XSH_ASSURE_NOT_NULL_MSG( wavemap_frame,"Required wavemap frame is missing");
5704 XSH_ASSURE_NOT_NULL_MSG( instrument,"Instrument setting undefined");
5705 XSH_ASSURE_NOT_ILLEGAL( nbkpts > 1);
5706 XSH_ASSURE_NOT_NULL_MSG( sky_par,"Undefined input sky parameters");
5707 XSH_ASSURE_NOT_NULL_MSG(ref_sky_list,"Null input reference sky line list");
5708
5709 xsh_msg_dbg_low( "method %s edges slit mask %f",
5710 SKY_METHOD_PRINT( sky_par->method), sky_par->slit_edges_mask);
5711 if (sky_par->method != MEDIAN_METHOD){
5712 xsh_msg_dbg_medium("start niter=%d kappa=%f",
5713 sky_par->niter, sky_par->kappa);
5714 if(sky_par->niter>3) {
5715 sky_par->niter=3;
5716 xsh_msg_warning("With sky-method=BSPLINE, sky-bspline-niter must be < 4");
5717 }
5718 }
5719 else{
5720 xsh_msg_dbg_low("median_hsize %d", sky_par->median_hsize);
5721 }
5722
5723 if ( loc_table_frame == NULL ) {
5724 xsh_msg( "Subtract sky single no localization");
5725 }
5726 else {
5727 xsh_msg( "Subtract sky single using localization");
5728 check( local_list = xsh_localization_load( loc_table_frame));
5729 }
5730
5731 check( pre_sci = xsh_pre_load( sci_frame, instrument));
5732
5734 sky_par->gain = 2.12;
5735 sky_par->ron = 10;/* this should come from a curve: 22 (DIT=2s)- 6 (DIT=100s) */
5736 double dit = xsh_pfits_get_dit(pre_sci->data_header);
5737 sky_par->ron = xsh_compute_ron_nir(dit);
5738 } else {
5739 sky_par->gain = xsh_pfits_get_gain(pre_sci->data_header);
5740 sky_par->ron = xsh_pfits_get_ron(pre_sci->data_header);
5741 }
5742
5743 /* Create data to build spectrum */
5744 check( wave_list = xsh_wavemap_list_new( wavemap_frame, slitmap_frame,
5745 local_list, order_table_frame, pre_sci, nbkpts,
5746 usr_def_sampl_points,ref_sky_list,ref_sky_orders_chunks,
5747 sky_par, instrument));
5748
5749 /* build sky spectrum */
5750 check (sky_list = xsh_wavemap_list_build_sky(wave_list,instrument));
5751 /* AMO added to debug: Note that the sky list is a 1D spectrum (order by order
5752 * with error and qualifier information) */
5753 //cpl_frame* tmp_frame = xsh_rec_list_save2( sky_list,"sky_list.fits","TEST");
5754
5755 sprintf(tag,"%s_DRL_SKY_ORD1D_%s", rec_prefix,
5757 sprintf(fname,"%s.fits",tag);
5758
5759 check( sky_frame = xsh_rec_list_save( sky_list,fname,tag, CPL_TRUE));
5761
5762 if ( sky_spectrum != NULL){
5763 *sky_spectrum = cpl_frame_duplicate( sky_frame);
5764 }
5765
5766 sprintf( tag,"%s_SKY_ORD1D_%s", rec_prefix,
5768 sprintf(fname,"%s.fits",tag);
5769
5770 check( sky_frame2 = xsh_rec_list1D_save_as_tab( sky_list,fname,tag));
5771
5772 if( (clean_tmp==1) || (strstr(rec_prefix,"TMPSKY")!=NULL) ) {
5774 }
5775
5776 if ( sky_spectrum != NULL){
5777 *sky_spectrum_eso = cpl_frame_duplicate( sky_frame2);
5778 }
5779
5780 /* Now subtract sky */
5781 check( res_frame = xsh_wavelist_subtract_sky( pre_sci, sky_list,
5782 wave_list,instrument,
5783 rec_prefix,sky_par));
5784
5785 //check(xsh_result_check(res_frame,wavemap_frame));
5786
5787 cleanup:
5788 xsh_free_frame( &sky_frame);
5789 xsh_free_frame( &sky_frame2);
5790 xsh_pre_free( &pre_sci);
5791 xsh_localization_free( &local_list);
5792 xsh_wavemap_list_free( &wave_list);
5793 xsh_rec_list_free( &sky_list);
5794
5795 return res_frame;
5796}
5797/*****************************************************************************/
5798/*----------------------------------------------------------------------------*/
5799/*----------------------------------------------------------------------------*/
5800cpl_frame* xsh_save_sky_model( cpl_frame* obj_frame, cpl_frame* sub_sky_frame,
5801 const char* sky_tag,xsh_instrument* instrument)
5802{
5803 char sky_name[256];
5804 cpl_frame* result=NULL;
5805
5806 sprintf(sky_name,"%s.fits",sky_tag);
5807 result=xsh_pre_frame_subtract( obj_frame, sub_sky_frame, sky_name, instrument,0);
5808
5809 cpl_frame_set_filename(result,sky_name);
5810 cpl_frame_set_tag(result,sky_tag);
5811
5812 return result;
5813}
5814/*----------------------------------------------------------------------------*/
5815
5816/*----------------------------------------------------------------------------*/
5817/*----------------------------------------------------------------------------*/
5818cpl_frame * xsh_add_sky_model( cpl_frame *subsky_frame, cpl_frame *sky_frame,
5819 xsh_instrument * instrument, const char* prefix)
5820{
5821 char result_tag[256];
5822 char result_name[256];
5823 cpl_frame *result = NULL;
5824 xsh_pre *pre_sci = NULL;
5825 const char *sky_name = NULL;
5826 cpl_image *sky_img = NULL;
5827
5828 sprintf( result_tag, "%s_OBJ_AND_SKY_NOCRH_%s", prefix,
5830 sprintf( result_name, "%s.fits", result_tag);
5831
5832
5833 check( pre_sci = xsh_pre_load( subsky_frame, instrument));
5834
5835 check( sky_name = cpl_frame_get_filename(sky_frame));
5836 /* we put back just the sky level: for this reason we
5837 * correct only the data part, not the associated errors */
5838 check( sky_img = cpl_image_load( sky_name, CPL_TYPE_FLOAT, 0, 0));
5839 check( cpl_image_add( pre_sci->data, sky_img));
5840 check( result = xsh_pre_save( pre_sci, result_name, result_tag, 1));
5841
5842 cleanup:
5843 xsh_free_image( &sky_img);
5844 xsh_pre_free( &pre_sci);
5845
5846 return result;
5847}
5848/*----------------------------------------------------------------------------*/
5849
int test_gsl_example()
static int starty
static int endy
static double sigma
static xsh_instrument * instrument
cpl_mask * xsh_qual_to_cpl_mask(cpl_image *qual, const int decode_bp)
cpl_mask * xsh_bpm_filter(const cpl_mask *input_mask, cpl_size kernel_nx, cpl_size kernel_ny, cpl_filter_mode filter)
Allows the growing and shrinking of bad pixel masks. It can be used to e.g. set pixels to bad if the ...
void xsh_bpmap_mask_bad_pixel(cpl_image *bpmap, cpl_mask *mask, int flag)
xsh_localization * xsh_localization_load(cpl_frame *frame)
Load a localization list from a frame.
void xsh_localization_free(xsh_localization **list)
free memory associated to a localization_list
int xsh_order_list_eval_int(xsh_order_list *list, cpl_polynomial *poly, double y)
Evaluate an order list poly but return the central pixel position rounding the polynomial.
xsh_order_list * xsh_order_list_load(cpl_frame *frame, xsh_instrument *instr)
load an order list from a frame
int xsh_order_list_get_starty(xsh_order_list *list, int i)
get position on Y axis of first pixel detected on order
int xsh_order_list_get_endy(xsh_order_list *list, int i)
get position on Y axis of last pixel detected on order
void xsh_order_list_free(xsh_order_list **list)
free memory associated to an order_list
cpl_image * xsh_pre_get_data(xsh_pre *pre)
Get data.
xsh_pre * xsh_pre_duplicate(const xsh_pre *pre)
Copy a PRE structure.
Definition: xsh_data_pre.c:953
xsh_pre * xsh_pre_load(cpl_frame *frame, xsh_instrument *instr)
Load a xsh_pre structure from a frame.
Definition: xsh_data_pre.c:849
cpl_image * xsh_pre_get_qual(xsh_pre *pre)
Get qual.
int xsh_pre_get_ny(const xsh_pre *pre)
Get ny of pre structure.
cpl_frame * xsh_pre_frame_subtract(cpl_frame *one, cpl_frame *two, const char *filename, xsh_instrument *instr, const int clean_tmp)
Subtract 2 frames (in XSH_PRE format) Just loads the 2 frames, subtract (xsh_pre_subtract) and save r...
void xsh_pre_free(xsh_pre **pre)
Free a xsh_pre structure.
Definition: xsh_data_pre.c:823
int xsh_pre_get_nx(const xsh_pre *pre)
Get nx of pre structure.
double xsh_compute_ron_nir(const double dit)
Definition: xsh_data_pre.c:247
cpl_image * xsh_pre_get_errs(xsh_pre *pre)
Get errs.
cpl_frame * xsh_pre_save(const xsh_pre *pre, const char *filename, const char *tag, int temp)
Save PRE on disk.
double * xsh_rec_list_get_lambda(xsh_rec_list *list, int idx)
float * xsh_rec_list_get_data1(xsh_rec_list *list, int idx)
cpl_frame * xsh_rec_list_save(xsh_rec_list *list, const char *filename, const char *tag, int is_temp)
Save a rec list in a frame.
xsh_rec_list * xsh_rec_list_create_with_size(int size, xsh_instrument *instr)
Create an empty order list.
Definition: xsh_data_rec.c:147
float * xsh_rec_list_get_errs1(xsh_rec_list *list, int idx)
void xsh_rec_list_set_data_size(xsh_rec_list *list, int idx, int absorder, int nlambda, int ns)
Allocate memory for the order idx of the rectify list.
Definition: xsh_data_rec.c:191
cpl_frame * xsh_rec_list1D_save_as_tab(xsh_rec_list *list, const char *filename, const char *tag)
save an rec list to a frame
int * xsh_rec_list_get_qual1(xsh_rec_list *list, int idx)
int xsh_rec_list_get_nlambda(xsh_rec_list *list, int idx)
Definition: xsh_data_rec.c:865
void xsh_rec_list_free(xsh_rec_list **list)
free memory associated to a rec_list
Definition: xsh_data_rec.c:760
void xsh_wavemap_list_free(xsh_wavemap_list **list)
free memory associated to a wavemap_list
cpl_error_code xsh_wavemap_list_sky_image_save(xsh_wavemap_list *smap, xsh_instrument *instr, const int abs_ord, const int sid, const int iter)
cpl_error_code xsh_wavemap_list_object_image_save(xsh_wavemap_list *omap, xsh_instrument *instr, const int iter)
void xsh_wavemap_list_set_max_size(xsh_wavemap_list *list, int idx, int absorder, int max_size)
set max size of wavemap
xsh_wavemap_list * xsh_wavemap_list_create(xsh_instrument *instr)
create an empty order list
#define XSH_ASSURE_NOT_NULL_MSG(pointer, msg)
Definition: xsh_error.h:103
#define XSH_ASSURE_NOT_ILLEGAL(cond)
Definition: xsh_error.h:107
#define assure(CONDITION, ERROR_CODE,...)
Definition: xsh_error.h:54
#define check(COMMAND)
Definition: xsh_error.h:71
#define XSH_CMP_INT(A, OPERATOR, B, SUFFIX,...)
Definition: xsh_error.h:119
#define XSH_ASSURE_NOT_ILLEGAL_MSG(cond, msg)
Definition: xsh_error.h:111
#define XSH_ASSURE_NOT_NULL(pointer)
Definition: xsh_error.h:99
const char * xsh_instrument_arm_tostring(xsh_instrument *i)
Get the string associated with an arm.
XSH_ARM xsh_instrument_get_arm(xsh_instrument *i)
Get an arm on instrument structure.
int * y
int * x
static SimAnneal s
Definition: xsh_model_sa.c:99
#define xsh_msg_warning(...)
Print an warning message.
Definition: xsh_msg.h:88
#define xsh_msg_dbg_medium(...)
Definition: xsh_msg.h:44
#define xsh_msg_error(...)
Print an error message.
Definition: xsh_msg.h:62
#define xsh_msg(...)
Print a message on info level.
Definition: xsh_msg.h:121
#define xsh_msg_dbg_low(...)
Definition: xsh_msg.h:48
double xsh_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
Definition: xsh_pfits.c:1405
double xsh_pfits_get_gain(const cpl_propertylist *plist)
find out the GAIN value
Definition: xsh_pfits.c:675
double xsh_pfits_get_ron(const cpl_propertylist *plist)
find out the RON value
Definition: xsh_pfits.c:459
static cpl_error_code xsh_model_fill_obj(xsh_wavemap_list *wlist, const int order, const double s1, const double s2, cpl_table *stab, const float ron2, const float gain)
static cpl_table * xsh_fit_spline1(xsh_wavemap_list *wlist, int order, cpl_table *sampl_tab, cpl_frame *sky_orders_chunks, int sampl_pts_no, int iter_no, xsh_subtract_sky_single_param *sky_par, float ron2, float gain, cpl_table **tab_line_res)
This routine performs the B-SPLINE fit of a set of sky data non-uniformly sampled.
static void xsh_gsl_bspline_non_uniform(double *data_x, double *data_y, double *data_e, double *bkpts, double *yfit, const int i_start, const size_t n, const size_t ncoeffs)
static cpl_error_code xsh_subtract_sky_on_obj_at_pix(xsh_rec_list *sky_list, const int iorder, const int object_size, const int nx, wavemap_item **pobject, float *pflux, float *perrs, int *pqual)
cpl_frame * xsh_save_sky_model(cpl_frame *obj_frame, cpl_frame *sub_sky_frame, const char *sky_tag, xsh_instrument *instrument)
static xsh_rec_list * xsh_wavemap_list_build_sky(xsh_wavemap_list *list, xsh_instrument *instrument)
Build the sky spectrum list.
static cpl_error_code xsh_model_fill_fit_bfit(xsh_wavemap_list *wlist, const int order, cpl_table *stab, const float ron2, const float gain)
static cpl_error_code xsh_subtract_sky_at_pix2(const int all_size, const int sky_size, const int nx, wavemap_item *pall, wavemap_item *psky, float *pflux, float *pflat, float *perrs, int *pqual)
static int xsh_get_edge_x_min(xsh_order_list *otab, const int iorder, const int iy)
static cpl_table * xsh_table_unique_wave(cpl_table *tab, const char *wname, const char *fname)
static cpl_table * xsh_detect_raw_data_outliers_1d_slice(const xsh_wavemap_list *wlist, const int hsize, const double ron2, const double gain, const int order, const int iter, const int decode_bp, const double s1, const double s2, const int slice_id)
determines sky outliers on a 1D spectrum via kappa-sigma clipping
static void xsh_dump_table_on_region_file(cpl_table *tab, const char *fname, const int symbol)
static int xsh_wave_compare(const void *un, const void *deux)
static cpl_table * xsh_table_unique_column(cpl_table *tab_inp, const char *col_wav)
double xsh_nbkpts_vis[XSH_ORDERS_VIS]
static cpl_table * xsh_skycorr_sampl_lines_from_static_tab(xsh_wavemap_list *wlist, const cpl_table *tab_ord, const int ord)
cpl_frame * xsh_add_sky_model(cpl_frame *subsky_frame, cpl_frame *sky_frame, xsh_instrument *instrument, const char *prefix)
cpl_frame * xsh_subtract_sky_single(cpl_frame *sci_frame, cpl_frame *order_table_frame, cpl_frame *slitmap_frame, cpl_frame *wavemap_frame, cpl_frame *loc_table_frame, cpl_frame *ref_sky_list, cpl_frame *ref_sky_orders_chunks, cpl_frame *usr_def_sampl_points, xsh_instrument *instrument, int nbkpts, xsh_subtract_sky_single_param *sky_par, cpl_frame **sky_spectrum, cpl_frame **sky_spectrum_eso, const char *rec_prefix, const int clean_tmp)
Subtract the sky background for single frame. If sky_spectrum is NOT NULL it is saved as a product,...
static cpl_error_code xsh_skycor_def_nbkpts_ord(const int iorder, const int nbkpts, cpl_frame *break_pts_frame, xsh_instrument *inst, int bspline_sampling_method, int *nbkpts_ord)
static double xsh_skycorr_rms(xsh_wavemap_list *wlist, const int iorder, const double ron2, const double gain)
static cpl_error_code xsh_wavecal_list_pupulate(xsh_pre *pre_sci, const int iorder, const int miny, const int maxy, const int wmap_xsize_diff, const int decode_bp, const double obj_slit_min, const double obj_slit_max, const double sky_slit_min, const double sky_slit_max, const int order, xsh_wavemap_list *wave_list, int *sky_size, xsh_order_list *ord_tab, cpl_image *wavemap, cpl_image *slitmap)
static cpl_error_code xsh_get_sky_edges_min_max_and_size(xsh_subtract_sky_single_param *sky_par, const int miny, const int maxy, const int iorder, const int order, const int nx, const int wmap_xsize_diff, xsh_order_list *ord_tab, cpl_image *slitmap, double *sky_slit_min, double *sky_slit_max, int *max_size, int *max_size_x)
static xsh_wavemap_list * xsh_wavemap_list_new(cpl_frame *wavemap_frame, cpl_frame *slitmap_frame, xsh_localization *list, cpl_frame *order_table_frame, xsh_pre *pre_sci, int nbkpts, cpl_frame *usr_def_sampl_points, cpl_frame *ref_sky_list, cpl_frame *sky_orders_chunks, xsh_subtract_sky_single_param *sky_par, xsh_instrument *instrument)
static cpl_frame * xsh_wavelist_subtract_sky(xsh_pre *pre_sci, xsh_rec_list *sky_list, xsh_wavemap_list *wave_list, xsh_instrument *instrument, const char *rec_prefix, xsh_subtract_sky_single_param *sky_par)
subtract sky
static cpl_table * xsh_model_to_table(const xsh_wavemap_list *wlist, const int order)
determines sky outliers on a 1D spectrum via kappa-sigma clipping
static cpl_error_code xsh_wavemap_list_rms_sky_image_save(xsh_wavemap_list *smap, const double ron2, const double gain, xsh_instrument *instr, const int iter)
static cpl_error_code xsh_model_fill_fit_slice_bfit(xsh_wavemap_list *wlist, const int order, const double s1, const double s2, cpl_table *stab, const float ron2, const float gain)
static cpl_table * xsh_fit_spline2(xsh_wavemap_list *wlist, int order, cpl_table *sampl_tab, cpl_frame *sky_orders_chunks, int sampl_pts_no, int iter_no, xsh_subtract_sky_single_param *sky_par, float ron2, float gain, cpl_table **tab_line_res)
This routine performs the B-SPLINE fit of a set of sky data non-uniformly sampled.
static cpl_table * xsh_skycorr_sample_continuum(xsh_wavemap_list *wlist, const int ord, const int n)
static void xsh_obj_fit_dump(int iorder, xsh_wavemap_list *wave_list)
static cpl_error_code xsh_model_fill_fit(xsh_wavemap_list *wlist, const int order, cpl_table *stab, const float ron2, const float gain)
static cpl_error_code xsh_bspline_smooth_non_uniform2(cpl_table *bkpts, cpl_frame *sky_orders_chunks, cpl_table **tab, const int iorder, xsh_instrument *instrument)
static cpl_error_code xsh_subtract_sky_at_pix(const int sky_size, const int nx, wavemap_item *psky, float *pflux, float *pflat, float *perrs, int *pqual)
static cpl_error_code xsh_table_column_smooth(cpl_table **tab, const char *name_i, const char *name_o, const int hsize)
determines sky outliers on a 1D spectrum via kappa-sigma clipping
static int xsh_get_edge_x_max(xsh_order_list *otab, const int iorder, const int iy)
static cpl_table * xsh_model2tab(xsh_wavemap_list *wlist, int order)
static cpl_table * xsh_detect_raw_data_outliers_1d(const xsh_wavemap_list *wlist, const int hsize, const double ron2, const double gain, const int order, const int iter, const int decode_bp)
determines sky outliers on a 1D spectrum via kappa-sigma clipping
static cpl_error_code xsh_table_column_clip(cpl_table **tab, const char *name_d, const char *name_s, const double kappa, const int niter, const double gain, const double ron2, const int decode_bp)
double xsh_nbkpts_uvb[XSH_ORDERS_UVB]
Create the wavemap list.
static cpl_table * xsh_create_sampl_uniform_continuum(const int iorder, xsh_wavemap_list *wlist, const int nsampl, const char *prefix)
static cpl_error_code xsh_get_obj_and_sky_extraction_slits(xsh_subtract_sky_single_param *sky_par, xsh_localization *list, const double smap_min, const double smap_max, double *obj_slit_min, double *obj_slit_max, double *sky_slit_min, double *sky_slit_max)
cpl_error_code xsh_bspline_smooth_uniform_sl(cpl_table **tab, xsh_instrument *instrument, const double s1, const double s2)
cpl_error_code xsh_bspline_smooth_uniform(cpl_table **tab, xsh_instrument *instrument)
cpl_error_code xsh_wavemap_list_full_sky_save(xsh_wavemap_list *wave_list, xsh_instrument *instr)
static cpl_error_code xsh_model_fill_fit_slice(xsh_wavemap_list *wlist, const int order, const double s1, const double s2, cpl_table *stab, const float ron2, const float gain)
static cpl_table * xsh_skycorr_wave_sampling_create(xsh_wavemap_list *wlist, const int ord, const int nbkpts_ord, const cpl_table *bkpts_tab)
static cpl_table * xsh_detect_outliers_thres_new(xsh_wavemap_list *wlist, const double kappa2, const double ron2, const double gain, const int order, const int iter, cpl_table **tab_line_res)
static cpl_table * xsh_create_sampl_table(const int iorder, double *wave_ref, const int nref, xsh_wavemap_list *wlist, const int nsampl_2, const char *prefix)
double xsh_nbkpts_nir[XSH_ORDERS_NIR]
void xsh_free_vector(cpl_vector **v)
Deallocate a vector and set the pointer to NULL.
Definition: xsh_utils.c:2284
void xsh_free_image(cpl_image **i)
Deallocate an image and set the pointer to NULL.
Definition: xsh_utils.c:2116
int xsh_debug_level_get(void)
get debug level
Definition: xsh_utils.c:3142
void xsh_free_frame(cpl_frame **f)
Deallocate a frame and set the pointer to NULL.
Definition: xsh_utils.c:2269
cpl_error_code xsh_sort_table_1(cpl_table *t, const char *column, cpl_boolean reverse)
Sort a table by one column.
void xsh_free_mask(cpl_mask **m)
Deallocate an image mask and set the pointer to NULL.
Definition: xsh_utils.c:2149
cpl_table * xsh_histogram(const cpl_table *data, const char *cname, const int nbins, const double min, const double max)
void xsh_free_table(cpl_table **t)
Deallocate a table and set the pointer to NULL.
Definition: xsh_utils.c:2133
cpl_error_code xsh_sort_table_3(cpl_table *t, const char *column1, const char *column2, const char *column3, cpl_boolean reverse1, cpl_boolean reverse2, cpl_boolean reverse3)
Sort a table by two columns.
void xsh_add_temporary_file(const char *name)
Add temporary file to temprary files list.
Definition: xsh_utils.c:1432
XSH_INSTRCONFIG * config
cpl_polynomial * edguppoly
cpl_polynomial * edglopoly
xsh_order * list
cpl_polynomial * edguppoly
cpl_polynomial * edglopoly
cpl_image * qual
Definition: xsh_data_pre.h:71
cpl_image * data
Definition: xsh_data_pre.h:65
cpl_propertylist * data_header
Definition: xsh_data_pre.h:66
cpl_image * errs
Definition: xsh_data_pre.h:68
enum bspline_sampling bspline_sampling
xsh_instrument * instrument
xsh_wavemap * list
wavemap_item * sky
wavemap_item * all
wavemap_item * object
#define QFLAG_QUESTIONABLE_PIXEL
#define QFLAG_SKY_MODEL_BAD_FIT
#define QFLAG_SKY_MODEL_BAD_PIX
#define QFLAG_SATURATED_DATA
static xsh_star_flux_list * xsh_bspline_fit_smooth(xsh_star_flux_list *ref_std_star_list, HIGH_ABS_REGION *phigh, xsh_instrument *inst)
double * xsh_bspline_interpolate_data_at_pos(double *w_data, double *f_data, const int n_data, double *w_pos, const int n_pos)
#define XSH_ORDERS_NIR
#define XSH_ORDERS_VIS
@ XSH_ARM_UVB
@ XSH_ARM_NIR
@ XSH_ARM_VIS
#define XSH_ORDERS_UVB
#define XSH_PRE_DATA_TYPE
Definition: xsh_data_pre.h:42
int nx
double kappa
Definition: xsh_detmon_lg.c:81
int niter
Definition: xsh_detmon_lg.c:82
int m
Definition: xsh_detmon_lg.c:91
int n
Definition: xsh_detmon_lg.c:92
int ny
int order
Definition: xsh_detmon_lg.c:80
int xsh_print_rec_status(const int val)
Check if an error has happened and returns error kind and location.
Definition: xsh_dfs.c:877
void xsh_frame_config(const char *fname, const char *tag, cpl_frame_type type, cpl_frame_group group, cpl_frame_level level, cpl_frame **frame)
Define a frame characteristics.
Definition: xsh_dfs.c:900
#define max(a, b)
#define SKY_METHOD_PRINT(method)
@ FINE
@ BSPLINE_METHOD4
@ MEDIAN_METHOD
@ BSPLINE_METHOD2
@ BSPLINE_METHOD
@ BSPLINE_METHOD5
@ BSPLINE_METHOD1
@ BSPLINE_METHOD3
@ XSH_DEBUG_LEVEL_MEDIUM
Definition: xsh_utils.h:138