X-shooter Pipeline Reference Manual 3.8.15
xsh_compute_response.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-08-29 10:53:17 $
23 * $Revision: 1.139 $
24 */
25
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30
31/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39
40/*----------------------------------------------------------------------------
41 Includes
42 ----------------------------------------------------------------------------*/
43#include <gsl/gsl_spline.h>
44#include <gsl/gsl_errno.h>
45
46#include <gsl/gsl_bspline.h>
47#include <gsl/gsl_multifit.h>
48#include <gsl/gsl_rng.h>
49#include <gsl/gsl_randist.h>
50#include <gsl/gsl_statistics.h>
51
52
53
54#include <xsh_dfs.h>
55#include <xsh_error.h>
56#include <xsh_msg.h>
57#include <cpl.h>
58#include <string.h>
59#include <time.h>
60#include <xsh_utils_table.h>
61#include <xsh_data_star_flux.h>
62#include <xsh_data_atmos_ext.h>
63#include <xsh_data_spectrum.h>
64#include <xsh_pfits.h>
65#include <xsh_utils.h>
66#include <xsh_utils_wrappers.h>
67#include <xsh_drl.h>
70#include <xsh_utils_response.h>
71#include <xsh_utils_vector.h>
72/*----------------------------------------------------------------------------
73 Function prototypes
74 ----------------------------------------------------------------------------*/
75
76/*-----------------------------------------------------------------------------
77 Implementation
78 -----------------------------------------------------------------------------*/
79
80#define INTERPOL_WSTEP_NM 2
81#define FILTER_MEDIAN_HSIZE 3
82/*
83static double
84find_high_abs_wave_max(HIGH_ABS_REGION * phigh)
85{
86 double max=0;
87 for( ; phigh->lambda_min != 0. ; phigh++ ) {
88 if(phigh->lambda_max>max) max=phigh->lambda_max>max;
89 }
90 return max;
91
92}
93 */
94
95static int
96find_lambda_idx( double lambda, double * wave, int from, int to,
97 double step )
98{
99 int idx ;
100 double * pwave ;
101
102 for( idx = from, pwave = wave+from ; idx < to ; pwave++, idx++ ) {
103 if ( *pwave >= (lambda-step/2) && *pwave < (lambda+step/2) ) {
104 return idx ;
105 }
106 }
107
108 return -1 ;
109}
110
111
112
113/*
114static int
115find_lambda_idx2( double lambda, double * wave, int from, int to,
116 double step )
117{
118 int idx ;
119 double * pwave ;
120
121 for( idx = from, pwave = wave+from ; idx < to ; pwave++, idx++ ) {
122
123 //xsh_msg("Testing wave=%g thresh_lam_min=%g thresh_lam_max=%g",
124 // *pwave,(lambda-step/2),(lambda+step/2));
125
126 if ( *pwave >= (lambda-step/2) ) {
127 if ( *pwave <= (lambda+step/2) ) {
128
129 //xsh_msg("Found index %d wave=%g thresh_lam_min=%g thresh_lam_max=%g",
130 // idx,*pwave,(lambda-step/2),(lambda+step/2));
131
132 return idx ;
133 }
134 }
135 }
136
137 return -1 ;
138}
139 */
140
141
142/*
143 * static int
144find_lambda_idx_min( double lambda, double * wave, int from, int to,
145 double step )
146{
147 int idx ;
148 double * pwave ;
149
150 for( idx = from, pwave = wave+from ; idx < to ; pwave++, idx++ ) {
151
152 xsh_msg("Testing wave=%g thresh_lam_min=%g thresh_lam_max=%g",
153 *pwave,(lambda-step/2),(lambda+step/2));
154
155 if ( *pwave > (lambda-step/2) ) {
156
157 xsh_msg("Found index %d wave=%g thresh_lam_min=%g thresh_lam_max=%g",
158 idx,*pwave,(lambda-step/2),(lambda+step/2));
159
160 return idx ;
161 }
162 }
163
164 return -1 ;
165}
166*/
167
168
169/*
170
171static int
172find_lambda_idx_max( double lambda, double * wave, int from, int to,
173 double step )
174{
175 int idx ;
176 double * pwave ;
177
178 for( idx = from, pwave = wave+from ; idx >= to ; pwave--, idx-- ) {
179
180 xsh_msg("Testing wave=%g thresh_lam_min=%g thresh_lam_max=%g",
181 *pwave,(lambda-step/2),(lambda+step/2));
182
183 if ( *pwave < (lambda+step/2) ) {
184
185 xsh_msg("Found index %d wave=%g thresh_lam_min=%g thresh_lam_max=%g",
186 idx,*pwave,(lambda-step/2),(lambda+step/2));
187
188 return idx ;
189 }
190 }
191
192 return -1 ;
193}
194*/
195
196static void
197find_lambda_idx_limit( double min, double max, double * spectrum,
198 int from, int to, double step,
199 int * if0, int * if1 )
200{
201 int idx ;
202 double *pspec ;
203
204 xsh_msg_dbg_high( "From: %d, To: %d, step: %lf, min: %lf, max: %lf",
205 from, to, step, min, max ) ;
206
207 for( idx = from, pspec = spectrum+from ; idx < to ; pspec++, idx++ ) {
208 xsh_msg_dbg_high( " Search Min - Spectrum_lambda: %lf (%lf)", *pspec,
209 min-(step/2.) ) ;
210 if ( *pspec >= (min-(step/2.)) ) break ;
211 }
212 *if0 = idx ;
213 for( ; idx < to ; pspec++, idx++ ) {
214 xsh_msg_dbg_high( " Search Max - Spectrum_lambda: %lf", *pspec ) ;
215 if ( *pspec > (max+(step/2.)) ) break ;
216 }
217 *if1 = idx-1 ;
218
219 xsh_msg_dbg_low( "Lambda Min: %lf, Max: %lf (in [%lf,%lf[",
220 spectrum[*if0], spectrum[*if1], min, max ) ;
221 if ( *if1 > to ) *if1 = to ;
222
223 return ;
224}
225
236static cpl_error_code
238 cpl_table*atmos_ext_tab,
240 double** atmos_lambda,
241 double** atmos_K)
242{
243
244 int nrow=0;
245 double* pk=0;
246 double* pw=0;
247 int j=0 ;
248 int nlambda_star=0 ;
249 double * lambda_star = NULL;
250
251 XSH_ASSURE_NOT_NULL_MSG (star_list,"null input ref std flux table!");
252 XSH_ASSURE_NOT_NULL_MSG (atmos_ext_tab,"null input atm ext table!");
253
254 nlambda_star = star_list->size ;
255 lambda_star = star_list->lambda ;
256
257 /* Fill the atmos_lambda and K with only the subset of lambdas available
258 in star list (the std star) */
259 XSH_CALLOC( *atmos_lambda, double, nlambda_star ) ;
260 XSH_CALLOC( *atmos_K, double, nlambda_star ) ;
261 if(!cpl_table_has_column(atmos_ext_tab,XSH_ATMOS_EXT_LIST_COLNAME_K)){
262 xsh_msg_warning("You are using an obsolete atm extinction line table");
263 cpl_table_duplicate_column(atmos_ext_tab,XSH_ATMOS_EXT_LIST_COLNAME_K,
264 atmos_ext_tab,XSH_ATMOS_EXT_LIST_COLNAME_OLD);
265 }
266 cpl_table_cast_column(atmos_ext_tab,XSH_ATMOS_EXT_LIST_COLNAME_K,"K",CPL_TYPE_DOUBLE);
267 cpl_table_cast_column(atmos_ext_tab,"LAMBDA","WAVE",CPL_TYPE_DOUBLE);
268
269 nrow=cpl_table_get_nrow(atmos_ext_tab);
270 pw=cpl_table_get_data_double(atmos_ext_tab,"WAVE");
271 pk=cpl_table_get_data_double(atmos_ext_tab,"K");
272
274 for( j = 0 ; j<nlambda_star ; j++) {
275 //if(j<10) xsh_msg("atmo lambda=%g",lambda_star[j] );
276 (*atmos_lambda)[j] = lambda_star[j] ;
277 (*atmos_K)[j] = xsh_data_interpolate((*atmos_lambda)[j],nrow,pw,pk);
278
279 //xsh_msg("w=%g k=%g",atmos_lambda[j],atmos_K[j]);
280 }
281 } else {
282 for( j = 0 ; j<nlambda_star ; j++) {
283
284 (*atmos_lambda)[j] = lambda_star[j] ;
285 (*atmos_K)[j] = 0;
286
287 //xsh_msg("w=%g k=%g",atmos_lambda[j],atmos_K[j]);
288 }
289 }
290
291 cpl_table_erase_column(atmos_ext_tab,"WAVE");
292 cpl_table_erase_column(atmos_ext_tab,"K");
293
294
295 cleanup:
296 return cpl_error_get_code();
297}
298
307static cpl_error_code
309 xsh_star_flux_list * resp_list,
310 HIGH_ABS_REGION * phigh)
311
312{
313 int kh=0;
314 int min_idx=0;
315 int max_idx=0;
316 int start_idx=0;
317 double min_flux=0;
318 double max_flux=0;
319 double delta_flux=0;
320 double cur_flux=0;
321 int ll=0;
322 int min_step=5;
323 int nlambda_star=0;
324 double step_star=0;
325 double * lambda_star = NULL;
326 double lambda_star_min=0;
327 double lambda_star_max=0;
328 //int i=0;
329 XSH_ASSURE_NOT_NULL_MSG (star_list,"null input ref std flux table!");
330 XSH_ASSURE_NOT_NULL_MSG (resp_list,"null input response table!");
331
332 nlambda_star = star_list->size ;
333 lambda_star = star_list->lambda ;
334 lambda_star_min = *lambda_star ;
335 lambda_star_max = *(lambda_star+nlambda_star-1) ;
336 step_star = (lambda_star_max-lambda_star_min)/(nlambda_star-1) ;
337
338 if ( phigh != NULL ) {
339
340 xsh_msg_dbg_medium( "Interpolate in High Absorption Regions" ) ;
341 for( kh = 0 ; phigh->lambda_min != 0. ; kh++, phigh++ ) {
342 start_idx=0;
343 min_idx = find_lambda_idx( phigh->lambda_min, resp_list->lambda,
344 start_idx, nlambda_star, step_star ) ;
345 if(min_idx>=0) {
346 start_idx=min_idx;
347 }
348 max_idx = find_lambda_idx( phigh->lambda_max, resp_list->lambda,
349 start_idx, nlambda_star, step_star ) ;
350 xsh_msg_dbg_medium( "Indexes[%d]: %d (lambda=%lf), %d (lambda=%lf)",
351 kh,min_idx, phigh->lambda_min, max_idx,
352 phigh->lambda_max ) ;
353 /*
354 for(i=0;i<resp_list->size;i++) {
355 xsh_msg("rsp list lambda=%g",resp_list->lambda[i]);
356 }
357 */
358 xsh_msg_dbg_low( "Indexes[%d]: %d (lambda=%lf), %d (lambda=%lf)",
359 kh,min_idx, phigh->lambda_min, max_idx,
360 phigh->lambda_max ) ;
361
362
363 if(min_idx>=resp_list->size || max_idx>=resp_list->size) {
364 xsh_msg("min_idx=%d max_idx=%d size=%d",
365 min_idx,max_idx,resp_list->size);
366 }
367 //xsh_msg("resp list size=%d min_idx=%d max_idx=%d",resp_list->size,min_idx,max_idx);
368
369 /* decide if we need to
370 1) extrapolate toward lower wavelength
371 2) interpolate between min-max wavelength
372 3) extrapolate toward higher wavelength
373 */
374 if( (min_idx==-1) && (max_idx == -1) ) {
375 xsh_msg_debug("The high abs region is longer than the order length");
376 return cpl_error_get_code();
377 } else if(min_idx==-1) {
378 min_idx=0;
379 min_flux = resp_list->flux[max_idx] ;
380 max_flux = resp_list->flux[max_idx+min_step] ;
381 } else if (max_idx == -1) {
382 max_idx=nlambda_star;
383 min_flux = resp_list->flux[min_idx-min_step] ;
384 max_flux = resp_list->flux[min_idx] ;
385 } else {
386 /* do nothing min_idx and max_idx are ok */
387 min_flux = resp_list->flux[min_idx] ;
388 max_flux = resp_list->flux[max_idx] ;
389 }
390
391 xsh_msg_dbg_medium( "Min Flux: %le, Max Flux: %le",
392 min_flux, max_flux ) ;
393 delta_flux = (max_flux-min_flux)/(min_step) ;
394 // Now interpolate
395 for ( ll = min_idx+1 ; ll < max_idx ; ll++ ) {
396 cur_flux=min_flux+delta_flux*(ll-min_idx);
397 xsh_msg_dbg_low( " ==> Interpolate at %lf: %le replaced by %le",
398 resp_list->lambda[ll],
399 resp_list->flux[ll], cur_flux ) ;
400 resp_list->flux[ll] = cur_flux ;
401 }
402 }
403 }
404
405 cleanup:
406
407
408 return cpl_error_get_code();
409}
410
411
412
413
414/*
415static cpl_error_code
416xsh_interpolate_high_abs_regions2(xsh_star_flux_list * star_list,
417 xsh_star_flux_list * resp_list,
418 HIGH_ABS_REGION * phigh)
419
420{
421 int kh=0;
422 int min_idx=0;
423 int max_idx=0;
424 double min_flux=0;
425 double max_flux=0;
426 double delta_flux=0;
427 double cur_flux=0;
428 int ll=0;
429 int nlambda_star=0;
430 double step_star=0;
431 double * lambda_star = NULL;
432 double lambda_star_min=0;
433 double lambda_star_max=0;
434
435 XSH_ASSURE_NOT_NULL_MSG (star_list,"null input ref std flux table!");
436 XSH_ASSURE_NOT_NULL_MSG (resp_list,"null input response table!");
437
438 nlambda_star = star_list->size ;
439 lambda_star = star_list->lambda ;
440 lambda_star_min = *lambda_star ;
441 lambda_star_max = *(lambda_star+nlambda_star-1) ;
442 step_star = (lambda_star_max-lambda_star_min)/(nlambda_star-1) ;
443
444 if ( phigh != NULL ) {
445 int i=0;
446 const int nsampl=5;
447 cpl_vector* wave=cpl_vector_new(2*nsampl);
448 cpl_vector* flux=cpl_vector_new(2*nsampl);
449 cpl_polynomial * poly=NULL;
450 double mse=0;
451 const int deg=4;
452 double flux_interpol=0;
453 xsh_msg_dbg_medium( "Interpolate in High Absorption Regions" ) ;
454 for( kh = 0 ; phigh->lambda_min != 0. ; kh++, phigh++ ) {
455 min_idx = find_lambda_idx_min( phigh->lambda_min, resp_list->lambda,
456 max_idx, nlambda_star, step_star ) ;
457 max_idx = find_lambda_idx_max( phigh->lambda_max, resp_list->lambda,
458 nlambda_star-1, min_idx, step_star ) ;
459 xsh_msg_dbg_medium( "Indexes[%d]: %d (lambda=%lf), %d (lambda=%lf)",
460 kh,min_idx, phigh->lambda_min, max_idx,
461 phigh->lambda_max ) ;
462
463 xsh_msg( "Indexes[%d]: %d (lambda=%lf), %d (lambda=%lf)",
464 kh,min_idx, phigh->lambda_min, max_idx,
465 phigh->lambda_max ) ;
466
467 if(min_idx>=resp_list->size || max_idx>=resp_list->size) {
468 xsh_msg("min_idx=%d max_idx=%d size=%d",
469 min_idx,max_idx,resp_list->size);
470 }
471 for(i=0;i<nsampl;i++) {
472 cpl_vector_set(wave,i,resp_list->lambda[min_idx+i-nsampl]);
473 cpl_vector_set(wave,i+nsampl,resp_list->lambda[max_idx+i]);
474 cpl_vector_set(flux,i,resp_list->flux[min_idx+i-nsampl]);
475 cpl_vector_set(flux,i+nsampl,resp_list->flux[max_idx+i]);
476 }
477 //double* ws=NULL;
478 //double* fs=NULL;
479 //ws=cpl_vector_get_data(wave);
480 //fs=cpl_vector_get_data(flux);
481
482 poly=xsh_polynomial_fit_1d_create(wave,flux,deg,&mse);
483 for(i=min_idx;i<=max_idx;i++) {
484 //flux_interpol=xsh_spline_hermite(resp_list->lambda[i],ws,fs,nsampl,0);
485 flux_interpol=cpl_polynomial_eval_1d(poly,resp_list->lambda[i],NULL);
486 //xsh_msg("Interpol flux=%g",flux_interpol);
487 resp_list->flux[i]=flux_interpol;
488 }
489
490 cpl_vector_dump(wave,stdout);
491 cpl_vector_dump(flux,stdout);
492
493 here new code for windowing:
494 * we get a few (5) sampling points before min_idx and after max_idx
495 * we fill 2 vectors with wave, flux values
496 * we make a low order (2) polynomial fit
497 * we then compute the data points between
498 * flux(idx_min) and flux(idx_max)
499 * we finally replace the response values with the fitted values
500
501
502 min_flux = resp_list->flux[min_idx] ;
503 max_flux = resp_list->flux[max_idx] ;
504 xsh_msg_dbg_medium( "Min Flux: %le, Max Flux: %le",
505 min_flux, max_flux ) ;
506 delta_flux = (max_flux-min_flux)/(max_idx-min_idx) ;
507 // Now interpolate
508 cur_flux = min_flux ;
509 for ( ll = min_idx+1 ; ll < max_idx ; ll++ ) {
510 cur_flux += delta_flux ;
511 xsh_msg_dbg_medium( " ==> InSterpolate at %lf: %le replaced by %le",
512 resp_list->lambda[ll],
513 resp_list->flux[ll], cur_flux ) ;
514 resp_list->flux[ll] = cur_flux ;
515 }
516 }
517 xsh_free_vector(&wave);
518 xsh_free_vector(&flux);
519
520 }
521
522 cleanup:
523
524
525 return cpl_error_get_code();
526}
527
528*/
542static cpl_error_code
544 xsh_star_flux_list * star_list,
545 double * lambda_spectrum,
546 double * flux_spectrum,
547 double * flux_added)
548{
549
550 FILE * fout ;
551 int i=0;
552 int nlambda_star=0;
553 int nlambda_spectrum=0;
554 double * lambda_star = NULL;
555 double * flux_star = NULL ;
556
557 XSH_ASSURE_NOT_NULL_MSG (star_list,"null input ref std flux table!");
558 XSH_ASSURE_NOT_NULL_MSG (resp_list,"null input response table!");
559
560 nlambda_star = star_list->size ;
561 lambda_star = star_list->lambda ;
562 flux_star = star_list->flux ;
563
564 fout = fopen( "summed.dat", "w" ) ;
565 for( i = 0 ; i < nlambda_star ; i++ ) {
566 fprintf( fout, "%lf %le\n", resp_list->lambda[i],
567 flux_added[i] ) ;
568 }
569 fclose( fout ) ;
570
571 fout = fopen( "response.dat", "w" ) ;
572 for( i = 0 ; i < nlambda_star ; i++ ) {
573 fprintf( fout, "%lf %le\n", resp_list->lambda[i],
574 resp_list->flux[i] ) ;
575 }
576 fclose( fout ) ;
577
578 fout = fopen( "spectrum.dat", "w" ) ;
579 for ( i = 0 ; i < nlambda_spectrum ; i++ )
580 fprintf( fout, "%lf %lf\n", lambda_spectrum[i], flux_spectrum[i] ) ;
581 fclose( fout ) ;
582
583 fout = fopen( "star.dat", "w" ) ;
584 for ( i = 0 ; i < nlambda_star ; i++ )
585 fprintf( fout, "%lf %le\n", lambda_star[i], flux_star[i] ) ;
586 fclose( fout ) ;
587
588 cleanup:
589 return cpl_error_get_code();
590}
591
592
593
594static cpl_error_code
596 double * flux_spectrum,
597 int * qual_spectrum,
598 int if0,int if1,
599 int i,double** flux_added,int* npixels,int* nbad)
600
601{
602
603 double * pf0=NULL;
604 double * pf1=NULL;
605 double * pf=NULL;
606
607 int * qf0=NULL;
608 int * qf=NULL;
609 int i_dif=if1-if0;
610 XSH_ASSURE_NOT_NULL_MSG (flux_spectrum,"null flux_spectrum !");
611 XSH_ASSURE_NOT_NULL_MSG (qual_spectrum,"null qual_spectrum !");
612
613 if ( (npix_in_interval - i_dif)>0.9 ) {
614 *nbad = npix_in_interval -i_dif ;
615 }
616 pf0 = flux_spectrum + if0 ;
617 pf1 = flux_spectrum + if1 ;
618 qf0 = qual_spectrum + if0 ;
619 for( pf = pf0, qf = qf0 ; pf < pf1 ; pf++, qf++ ) {
620 /* TBD: handle correctly the borders (for example with a step_spectrum
621 of 0.2, and a step_star of 5, one should use only half of the
622 flux on the edges
623 */
624 (*npixels)++ ;
625 if ( *qf != QFLAG_GOOD_PIXEL ) {
626 (*nbad)++ ;
627 }
628 else (*flux_added)[i] += *pf;
629 }
630
631 if ( nbad != 0 && (npix_in_interval-*nbad) > 0 ) {
632 (*flux_added)[i] /= (double)(npix_in_interval-*nbad)/
633 (double)npix_in_interval ;
634 }
635 /*
636 xsh_msg("factor=%g npix_in_interval=%d nbad=%d if1=%d if0=%d i_dif=%d ck=%d",
637(double)(npix_in_interval-*nbad)/
638 (double)npix_in_interval,npix_in_interval,*nbad,if1,if0,i_dif,(npix_in_interval - i_dif));
639 */
640 cleanup:
641 return cpl_error_get_code();
642}
643
658static cpl_error_code
660 xsh_star_flux_list * star_list,
661 xsh_spectrum * spectrum,
662 double * atmos_K,
663 XSH_ARM the_arm,
664 double airmass,
665 double exptime,
666 double gain,
667 xsh_star_flux_list ** obj_list)
668{
669
670 double lambda=0;
671 double kvalue=0;
672
673
674 double * flux_added = NULL ;
675 double * lambda_star = NULL;
676 double * flux_star = NULL ;
677
678 double * lambda_spectrum = NULL;
679 double * plambda=NULL ;
680 double * flux_spectrum = NULL ;
681 //int * qual_spectrum = NULL ;
682
683 int i=0;
684 int size=0;
685 int nlambda_spectrum=0;
686 double lambda_spectrum_min=0;
687 double lambda_spectrum_max=0;
688 double lambda_star_min=0;
689 double lambda_star_max=0;
690 double step_spectrum=0 ;
691 double step_star=0 ;
692 int npix_in_interval=0 ;
693 int bin_size=1;
694 int binx=1;
695 int biny=1;
696 cpl_frame* obj_integrated=NULL;
697
698 check( nlambda_spectrum = xsh_spectrum_get_size( spectrum ) ) ;
699 check( flux_spectrum = xsh_spectrum_get_flux( spectrum ) ) ;
700 //check( qual_spectrum = xsh_spectrum_get_qual( spectrum ) ) ;
701 check( lambda_spectrum_min = xsh_spectrum_get_lambda_min( spectrum ) ) ;
702 check( lambda_spectrum_max = xsh_spectrum_get_lambda_max( spectrum ) ) ;
703 check( step_spectrum = xsh_spectrum_get_lambda_step( spectrum ) ) ;
704
705 /* In NIR, no binning ==> set 1x1 */
706 if ( the_arm != XSH_ARM_NIR ) {
707 /* we correct for bin size:
708 * bin along wave direction* bin along spatial direction
709 */
710 check(binx = xsh_pfits_get_binx( spectrum->flux_header )) ;
711 check(biny = xsh_pfits_get_biny( spectrum->flux_header )) ;
712 bin_size=binx*biny;
713 }
714
715
716 flux_star = star_list->flux ;
717 size = star_list->size ;
718 lambda_star = star_list->lambda ;
719
720
721 lambda_star_min = *lambda_star ;
722 lambda_star_max = *(lambda_star+size-1) ;
723 step_star = (lambda_star_max-lambda_star_min)/(size-1) ;
724
725 xsh_msg( "Spectrum - size %d Nlambda: %d, Min: %lf, Max: %lf, Step: %lf",
726 size,nlambda_spectrum, lambda_spectrum_min, lambda_spectrum_max,
727 step_spectrum ) ;
728 xsh_msg_dbg_low( " - BinX: %d, BinY: %d", binx, biny ) ;
729
730
731 XSH_CALLOC( flux_added, double, size ) ;
732 /* For each lambda in star_list
733 if there is such a lambda in rec_list Then
734 integrate (add) the flux from (lambda-delta/2) to (lambda+delta/2)
735 calculate ratio rec_add_flux/star_flux
736 endif
737 EndFor
738 */
739 /* First create lambda_spectrum array */
740 XSH_CALLOC( lambda_spectrum, double, nlambda_spectrum ) ;
741
742 for( lambda = lambda_spectrum_min, plambda = lambda_spectrum, i = 0 ;
743 i<nlambda_spectrum ;
744 i++, plambda++, lambda += step_spectrum )
745 {
746 *plambda = lambda ;
747 }
748
749 /* Create response list (identical to star_list ?) */
750 //xsh_msg("step_star=%g step_spectrum=%g", step_star,step_spectrum);
751
752 npix_in_interval = step_star/step_spectrum ;
753 xsh_msg_dbg_low( "Nb of pixels max in interval: %d", npix_in_interval ) ;
754
755 /* for debug purposes uses stores results in a table */
756 cpl_table* debug = NULL;
757 double* pwav = NULL;
758 double* pflux_obs = NULL;
759 double* pflux_ref = NULL;
760 double* pflux_corr=NULL;
761 double* pkavalue = NULL;
762 double* pobj_atm_corr = NULL;
763 double* pobj_bin_cor = NULL;
764 double cor_fct = 0;
765 debug = cpl_table_new(size);
766
767 cpl_table_new_column(debug, "wavelength", CPL_TYPE_DOUBLE);
768 cpl_table_new_column(debug, "flux_obs", CPL_TYPE_DOUBLE);
769 cpl_table_new_column(debug, "flux_ref", CPL_TYPE_DOUBLE);
770 cpl_table_new_column(debug, "flux_obs_cor_gain_bin_exptime", CPL_TYPE_DOUBLE);
771
772 cpl_table_new_column(debug, "kvalue", CPL_TYPE_DOUBLE);
773 cpl_table_new_column(debug, "flux_obs_cor_atm", CPL_TYPE_DOUBLE);
774 cpl_table_new_column(debug, "flux_obs_cor_obs2ref_bin_size", CPL_TYPE_DOUBLE);
775
776 cpl_table_fill_column_window_double(debug, "wavelength", 0, size, 0.);
777 cpl_table_fill_column_window_double(debug, "flux_obs", 0, size,0.);
778 cpl_table_fill_column_window_double(debug, "flux_obs_cor_gain_bin_exptime", 0,size, 0.);
779 cpl_table_fill_column_window_double(debug, "flux_ref", 0, size, 0.);
780 cpl_table_fill_column_window_double(debug, "kvalue", 0, size, 0.);
781 cpl_table_fill_column_window_double(debug, "flux_obs_cor_atm", 0, size,0.);
782 cpl_table_fill_column_window_double(debug, "flux_obs_cor_obs2ref_bin_size", 0, size,0.);
783
784 pwav = cpl_table_get_data_double(debug, "wavelength");
785 pflux_obs = cpl_table_get_data_double(debug, "flux_obs");
786 pflux_corr = cpl_table_get_data_double(debug, "flux_obs_cor_gain_bin_exptime");
787 pflux_ref = cpl_table_get_data_double(debug, "flux_ref");
788 pkavalue = cpl_table_get_data_double(debug, "kvalue");
789 pobj_atm_corr = cpl_table_get_data_double(debug, "flux_obs_cor_atm");
790 pobj_bin_cor = cpl_table_get_data_double(debug, "flux_obs_cor_obs2ref_bin_size");
791 check(*obj_list = xsh_star_flux_list_create( size ));
792
793 cor_fct = gain * exptime * bin_size;
794 //xsh_msg("cor factor=%g",cor_fct);
795 xsh_msg("cor lambda sampling: %g %g %g",step_star/step_spectrum,step_star,step_spectrum );
796 /* Loop over lamba_star */
797 for ( i = 0 ; i < size ; i++ ) {
798 /* correct for gain,bin,exptime */
799 /* TODO: We should use only good pixels */
800 (*obj_list)->flux[i] = flux_spectrum[i]/cor_fct ;
801 (*obj_list)->lambda[i] = lambda_star[i] ;
802
803 pwav[i]=lambda_star[i];
804 pflux_corr[i]=(*obj_list)->flux[i];
805 pflux_obs[i]=flux_spectrum[i];
806 pflux_ref[i]=flux_star[i];
807
808 /* Correct for atmos ext*/
809 if ( atmos_K != NULL ) {
810 kvalue = pow(10., -airmass*atmos_K[i]*0.4 ) ;
811 (*obj_list)->flux[i] /= kvalue ;
812 pobj_atm_corr[i]=(*obj_list)->flux[i];
813 pkavalue[i]=kvalue;
814 //xsh_msg("resp: %g kvalue %g k %g",(*obj_list)->flux[i],kvalue,atmos_K[i]);
815 }
816
817 /* Multiply by ratio star_binning/spectrum_binning */
818 (*obj_list)->flux[i] *= step_star/step_spectrum ;
819 pobj_bin_cor[i]=(*obj_list)->flux[i];
820
821 }
822
823 check(cpl_table_duplicate_column(debug,"response",debug,"flux_ref"));
824
825 check(cpl_table_divide_columns(debug,"response","flux_obs_cor_obs2ref_bin_size"));
826 //check(cpl_table_save(debug,NULL,NULL,"debug.fits",CPL_IO_DEFAULT));
827 xsh_free_table(&debug);
828
829 check(obj_integrated=xsh_star_flux_list_save(*obj_list,"obj_list_corrected.fits","TEST")) ;
830 xsh_add_temporary_file("obj_list_corrected.fits");
831
832 cleanup:
833
834 XSH_FREE( lambda_spectrum ) ;
835 XSH_FREE( flux_added ) ;
836 xsh_free_frame(&obj_integrated);
837 xsh_free_table(&debug);
838 return cpl_error_get_code();
839
840}
841
842static xsh_star_flux_list *
844 xsh_star_flux_list * star_list,
845 xsh_star_flux_list ** obj_list,
846 xsh_spectrum * spectrum,
847 cpl_table * atmos_ext_tab,
848 XSH_ARM the_arm,
849 double * atmos_K,
850 double airmass,
851 double exptime,
852 double gain)
853{
854 xsh_star_flux_list * resp_list=NULL;
855 int npixels = 0;
856 int nbad = 0 ;
857
858 double lambda=0;
859 double min=0;
860 double max=0;
861 double kvalue=0;
862
863
864 double * lambda_resp = NULL ;
865 double * flux_resp = NULL ;
866 double * flux_added = NULL ;
867 double * lambda_star = NULL;
868 double * flux_star = NULL ;
869
870 double * lambda_spectrum = NULL;
871 double * plambda=NULL ;
872 double * flux_spectrum = NULL ;
873 int * qual_spectrum = NULL ;
874
875 int i=0;
876 int if0=0;
877 int if1=0;
878 int nlambda_star=0;
879 int nlambda_spectrum=0;
880 double lambda_spectrum_min=0;
881 double lambda_spectrum_max=0;
882 double lambda_star_min=0;
883 double lambda_star_max=0;
884 double step_spectrum=0 ;
885 double step_star=0 ;
886 int npix_in_interval=0 ;
887 int bin=1;
888 int binx=1;
889 int biny=1;
890 cpl_frame* resp_integrated=NULL;
891 cpl_frame* obj_integrated=NULL;
892
893 check( nlambda_spectrum = xsh_spectrum_get_size( spectrum ) ) ;
894 check( flux_spectrum = xsh_spectrum_get_flux( spectrum ) ) ;
895 check( qual_spectrum = xsh_spectrum_get_qual( spectrum ) ) ;
896 check( lambda_spectrum_min = xsh_spectrum_get_lambda_min( spectrum ) ) ;
897 check( lambda_spectrum_max = xsh_spectrum_get_lambda_max( spectrum ) ) ;
898 check( step_spectrum = xsh_spectrum_get_lambda_step( spectrum ) ) ;
899
900 /* In NIR, no binning ==> set 1x1 */
901 if ( the_arm != XSH_ARM_NIR ) {
902 /* we correct for biny: bin along wave direction
903 bin = xsh_pfits_get_biny( spectrum->flux_header ) ;
904 binx = xsh_pfits_get_binx( spectrum->flux_header ) ;
905 biny = xsh_pfits_get_biny( spectrum->flux_header ) ;
906 */
907 }
908 else {
909 bin = 1 ;
910 binx=1;
911 biny=1;
912
913 }
914
915 flux_star = star_list->flux ;
916 nlambda_star = star_list->size ;
917 lambda_star = star_list->lambda ;
918 lambda_star_min = *lambda_star ;
919 lambda_star_max = *(lambda_star+nlambda_star-1) ;
920 step_star = (lambda_star_max-lambda_star_min)/(nlambda_star-1) ;
921
922 xsh_msg_dbg_low( "Spectrum - Nlambda: %d, Min: %lf, Max: %lf, Step: %lf",
923 nlambda_spectrum, lambda_spectrum_min, lambda_spectrum_max,
924 step_spectrum ) ;
925 xsh_msg_dbg_low( " - BinX: %d, BinY: %d", binx, biny ) ;
926
927 XSH_CALLOC( lambda_resp, double, nlambda_star ) ;
928 XSH_CALLOC( flux_resp, double, nlambda_star ) ;
929 XSH_CALLOC( flux_added, double, nlambda_star ) ;
930 /* For each lambda in star_list
931 if there is such a lambda in rec_list Then
932 integrate (add) the flux from (lambda-delta/2) to (lambda+delta/2)
933 calculate ratio rec_add_flux/star_flux
934 endif
935 EndFor
936 */
937 /* First create lambda_spectrum array */
938 XSH_CALLOC( lambda_spectrum, double, nlambda_spectrum ) ;
939
940 //xsh_msg("lambda min=%g lambda max=%g",lambda_spectrum_min,lambda_spectrum_max);
941
942 for( lambda = lambda_spectrum_min, plambda = lambda_spectrum, i = 0 ;
943 i<nlambda_spectrum ;
944 i++, plambda++, lambda += step_spectrum )
945 {
946 *plambda = lambda ;
947 }
948
949 /* Create response list (identical to star_list ?) */
950 check( resp_list = xsh_star_flux_list_create( nlambda_star ) ) ;
951 check( *obj_list = xsh_star_flux_list_create( nlambda_star ) ) ;
952 //xsh_msg("step_star=%g step_spectrum=%g", step_star,step_spectrum);
953
954 npix_in_interval = step_star/step_spectrum ;
955 xsh_msg_dbg_low( "Nb of pixels max in interval: %d", npix_in_interval ) ;
956
957
958
959 cpl_table* debug = NULL;
960 double* pwav = NULL;
961 double* pflux_spectrum = NULL;
962 double* pflux_added = NULL;
963 double* pflux_star = NULL;
964 double* presp = NULL;
965 double* pkavalue = NULL;
966 double* presp_atm_corr = NULL;
967 double* presp_bin_cor = NULL;
968 double cor_fct=0;
969 debug=cpl_table_new(nlambda_star);
970
971 cpl_table_new_column(debug, "wavelength", CPL_TYPE_DOUBLE);
972 cpl_table_new_column(debug, "flux_spectrum", CPL_TYPE_DOUBLE);
973 cpl_table_new_column(debug, "flux_added", CPL_TYPE_DOUBLE);
974 cpl_table_new_column(debug, "flux_star", CPL_TYPE_DOUBLE);
975 cpl_table_new_column(debug, "resp", CPL_TYPE_DOUBLE);
976 cpl_table_new_column(debug, "kvalue", CPL_TYPE_DOUBLE);
977 cpl_table_new_column(debug, "resp_atm_corr", CPL_TYPE_DOUBLE);
978 cpl_table_new_column(debug, "resp_bin_corr", CPL_TYPE_DOUBLE);
979
980 cpl_table_fill_column_window_double(debug, "wavelength", 0, nlambda_star, 0.);
981 cpl_table_fill_column_window_double(debug, "flux_spectrum", 0, nlambda_star,0.);
982 cpl_table_fill_column_window_double(debug, "flux_added", 0, nlambda_star, 0.);
983 cpl_table_fill_column_window_double(debug, "flux_star", 0, nlambda_star, 0.);
984 cpl_table_fill_column_window_double(debug, "resp", 0, nlambda_star, 0.);
985 cpl_table_fill_column_window_double(debug, "kvalue", 0, nlambda_star, 0.);
986 cpl_table_fill_column_window_double(debug, "resp_atm_corr", 0, nlambda_star,0.);
987 cpl_table_fill_column_window_double(debug, "resp_bin_corr", 0, nlambda_star,0.);
988
989 pwav = cpl_table_get_data_double(debug,"wavelength");
990 pflux_spectrum = cpl_table_get_data_double(debug,"flux_spectrum");
991 pflux_added = cpl_table_get_data_double(debug,"flux_added");
992 pflux_star = cpl_table_get_data_double(debug,"flux_star");
993 presp = cpl_table_get_data_double(debug,"resp");
994 pkavalue = cpl_table_get_data_double(debug,"kvalue");
995 presp_atm_corr = cpl_table_get_data_double(debug,"resp_atm_corr");
996 presp_bin_cor = cpl_table_get_data_double(debug,"resp_bin_corr");
997
998
999 cor_fct=gain*bin*exptime;
1000 /* Loop over lamba_star */
1001 for ( i = 0 ; i < nlambda_star ; i++ ) {
1002 /* Now add spectrum flux in the star sampling interval */
1003
1004 flux_added[i] = 0. ;
1005 min = lambda_star[i] - step_star/2 ;
1006 max = lambda_star[i] + step_star/2 ;
1007
1008 xsh_msg_dbg_medium( "Lambda_star[%d] = %lf, Min = %lf, Max = %lf", i,
1009 lambda_star[i], min, max ) ;
1010
1011 find_lambda_idx_limit( min, max, lambda_spectrum, if0, nlambda_spectrum,
1012 step_spectrum, &if0, &if1 ) ;
1013
1014 xsh_msg_dbg_low( " Actual nb of pixels in interval: %d/%d", if1-if0,
1015 npix_in_interval ) ;
1016
1017 /* correct integrated flux for bad pixels */
1018 /* initializes bad pix counter to 0 ! */
1019 nbad=0;
1020 xsh_flux_integrate_and_corr_for_badpix(npix_in_interval,flux_spectrum,
1021 qual_spectrum,if0,if1,i,
1022 &flux_added,&npixels,&nbad);
1023
1024 /* initialize respons correcting also by gain (response in electrons) */
1025 resp_list->flux[i] = flux_star[i]/(flux_added[i]/cor_fct) ;
1026 resp_list->lambda[i] = lambda_star[i] ;
1027
1028
1029 (*obj_list)->flux[i] = flux_added[i] ;
1030 (*obj_list)->lambda[i] = lambda_star[i] ;
1031
1032 pwav[i]=resp_list->lambda[i];
1033 pflux_spectrum[i]=flux_spectrum[i];
1034 pflux_added[i]=flux_added[i];
1035 pflux_star[i]=flux_star[i];
1036 presp[i]=resp_list->flux[i];
1037
1038 xsh_msg_dbg_low(" Flux Star = %le, Integrated = %lf (%d pixels, %d bad)",
1039 flux_star[i], flux_added[i], npixels, nbad ) ;
1040 xsh_msg_dbg_low(" =====> Response at Lambda=%lf: %le",
1041 lambda_star[i], resp_list->flux[i] ) ;
1042
1043 /* Multiply by atmos ext
1044 * TODO: AMO here the check on atmos_ext_tab could be done out of the loop:
1045 * if missing error should be issued.
1046 * On the other hand if present there is no need to make the check in the loop.
1047 */
1048 if ( atmos_ext_tab != NULL ) {
1049 kvalue = pow(10., -airmass*atmos_K[i]*0.4 ) ;
1050 resp_list->flux[i] *= kvalue ;
1051 presp_atm_corr[i]=resp_list->flux[i];
1052 pkavalue[i]=kvalue;
1053 //xsh_msg("resp: %g kvalue %g k %g",resp_list->flux[i],kvalue,atmos_K[i]);
1054 }
1055
1056 /* Multiply by ratio star_binning/spectrum_binning */
1057 resp_list->flux[i] *= step_star/step_spectrum ;
1058 presp_bin_cor[i]=resp_list->flux[i];
1059 if0 = if1 ;
1060 }
1061 /* cpl_table_save(debug,NULL,NULL,"debug.fits",CPL_IO_DEFAULT); */
1062 xsh_free_table(&debug);
1063
1064 /* filter median response to smooth out local jumps */
1065 if(resp_list->size > 2*FILTER_MEDIAN_HSIZE) {
1067 }
1068
1069 resp_integrated=xsh_star_flux_list_save(resp_list,"resp_list_integrated.fits","TEST") ;
1070 xsh_add_temporary_file("resp_list_integrated.fits");
1071 obj_integrated=xsh_star_flux_list_save(*obj_list,"obj_list_integrated.fits","TEST") ;
1072 xsh_add_temporary_file("obj_list_integrated.fits");
1073
1075 check(xsh_response_crea_ascii(resp_list,star_list,lambda_spectrum,
1076 flux_spectrum,flux_added));
1077 }
1078
1079 cleanup:
1080
1081 XSH_FREE( lambda_spectrum ) ;
1082 XSH_FREE( lambda_resp ) ;
1083 XSH_FREE( lambda_resp ) ;
1084 XSH_FREE( flux_resp ) ;
1085 XSH_FREE( flux_added ) ;
1086 xsh_free_frame(&resp_integrated);
1087 xsh_free_frame(&obj_integrated);
1088 xsh_free_table(&debug);
1089
1090 if(cpl_error_get_code() == CPL_ERROR_NONE) {
1091 return resp_list;
1092 } else {
1093 return NULL;
1094 }
1095}
1096
1097/*
1098static xsh_star_flux_list *
1099xsh_response_calculate2(
1100 xsh_star_flux_list * star_list,
1101 xsh_spectrum * spectrum,
1102 cpl_table * atmos_ext_tab,
1103 XSH_ARM the_arm,
1104 double * atmos_K,
1105 double airmass,
1106 double exptime,
1107 double gain)
1108{
1109 xsh_star_flux_list * resp_list=NULL;
1110
1111 double lambda=0;
1112 double min=0;
1113 double max=0;
1114 double kvalue=0;
1115
1116
1117 double * lambda_resp = NULL ;
1118 double * flux_resp = NULL ;
1119 double * flux_added = NULL ;
1120 double * lambda_star = NULL;
1121 double * flux_star = NULL ;
1122
1123 double * lambda_spectrum = NULL;
1124 double * plambda=NULL ;
1125 double * flux_spectrum = NULL ;
1126 int * qual_spectrum = NULL ;
1127
1128 int i=0;
1129 int nlambda_star=0;
1130 int nlambda_spectrum=0;
1131 double lambda_spectrum_min=0;
1132 double lambda_spectrum_max=0;
1133 double lambda_star_min=0;
1134 double lambda_star_max=0;
1135 double step_spectrum=0 ;
1136 double step_star=0 ;
1137 int npix_in_interval=0 ;
1138 int binx, biny ;
1139
1140 check( nlambda_spectrum = xsh_spectrum_get_size( spectrum ) ) ;
1141 check( flux_spectrum = xsh_spectrum_get_flux( spectrum ) ) ;
1142 check( qual_spectrum = xsh_spectrum_get_qual( spectrum ) ) ;
1143 check( lambda_spectrum_min = xsh_spectrum_get_lambda_min( spectrum ) ) ;
1144 check( lambda_spectrum_max = xsh_spectrum_get_lambda_max( spectrum ) ) ;
1145 check( step_spectrum = xsh_spectrum_get_lambda_step( spectrum ) ) ;
1146
1147 // In NIR, no binning ==> set 1x1
1148 if ( the_arm != XSH_ARM_NIR ) {
1149 binx = xsh_pfits_get_binx( spectrum->flux_header ) ;
1150 biny = xsh_pfits_get_biny( spectrum->flux_header ) ;
1151 }
1152 else {
1153 binx = 1 ;
1154 biny = 1 ;
1155 }
1156
1157 flux_star = star_list->flux ;
1158 nlambda_star = star_list->size ;
1159 lambda_star = star_list->lambda ;
1160 lambda_star_min = *lambda_star ;
1161 lambda_star_max = *(lambda_star+nlambda_star-1) ;
1162 step_star = (lambda_star_max-lambda_star_min)/(nlambda_star-1) ;
1163
1164 xsh_msg_dbg_low( "Spectrum - Nlambda: %d, Min: %lf, Max: %lf, Step: %lf",
1165 nlambda_spectrum, lambda_spectrum_min, lambda_spectrum_max,
1166 step_spectrum ) ;
1167 xsh_msg_dbg_low( " - BinX: %d, BinY: %d", binx, biny ) ;
1168
1169 XSH_CALLOC( lambda_resp, double, nlambda_star ) ;
1170 XSH_CALLOC( flux_resp, double, nlambda_star ) ;
1171 XSH_CALLOC( flux_added, double, nlambda_star ) ;
1172 // For each lambda in star_list
1173 // if there is such a lambda in rec_list Then
1174 // integrate (add) the flux from (lambda-delta/2) to (lambda+delta/2)
1175 // calculate ratio rec_add_flux/star_flux
1176 // endif
1177 // EndFor
1178
1179 // First create lambda_spectrum array
1180 XSH_CALLOC( lambda_spectrum, double, nlambda_spectrum ) ;
1181
1182 //xsh_msg("lambda min=%g lambda max=%g",lambda_spectrum_min,lambda_spectrum_max);
1183
1184 for( lambda = lambda_spectrum_min, plambda = lambda_spectrum, i = 0 ;
1185 i<nlambda_spectrum ;
1186 i++, plambda++, lambda += step_spectrum )
1187 {
1188 *plambda = lambda ;
1189 }
1190
1191 // Create response list (identical to star_list ?)
1192 check( resp_list = xsh_star_flux_list_create( nlambda_star ) ) ;
1193 //xsh_msg("step_star=%g step_spectrum=%g", step_star,step_spectrum);
1194
1195 npix_in_interval = step_star/step_spectrum ;
1196 xsh_msg_dbg_low( "Nb of pixels max in interval: %d", npix_in_interval ) ;
1197
1198 int i_start=0;
1199 int i_end=0;
1200 int i1_inf=0;
1201 int i1_sup=0;
1202 int i2_inf=0;
1203 int i2_sup=0;
1204
1205 // Loop over lamba_star
1206 for ( i = 0 ; i < nlambda_star ; i++ ) {
1207 // Now add spectrum flux in the star sampling interval
1208
1209 flux_added[i] = 0. ;
1210 min = lambda_star[i] - step_star/2 ;
1211 max = lambda_star[i] + step_star/2 ;
1212 i_start=0;
1213 i_end=nlambda_spectrum ;
1214
1215 xsh_util_get_infsup(lambda_star,min,i_start,i_end,&i1_inf,&i1_sup);
1216 xsh_util_get_infsup(lambda_star,max,i_start,i_end,&i2_inf,&i2_sup);
1217
1218 flux_added[i]=xsh_spectrum_integrate(flux_spectrum,lambda_spectrum,
1219 i1_inf,i1_sup,i2_inf,i2_sup,
1220 lambda_star[i],step_star);
1221
1222 // initialize respons correcting also by gain (response in electrons)
1223 resp_list->flux[i] = flux_star[i]/(flux_added[i]/gain) ;
1224 resp_list->lambda[i] = lambda_star[i] ;
1225
1226 // Multiply by atmos ext
1227 if ( atmos_ext_tab != NULL ) {
1228 kvalue = pow(10., -airmass*atmos_K[i]*0.4 ) ;
1229 resp_list->flux[i] *= kvalue ;
1230 //xsh_msg("resp: %g kvalue %g k %g",resp_list->flux[i],kvalue,atmos_K[i]);
1231 }
1232
1233 // Multiply by ratio star_binning/spectrum_binning
1234 resp_list->flux[i] *= step_star/step_spectrum ;
1235
1236
1237 }
1238
1239 xsh_star_flux_list_save(resp_list,"resp_list_integrated.fits","TEST") ;
1240
1241
1242 if ( xsh_debug_level_get() >= XSH_DEBUG_LEVEL_LOW ) {
1243 check(xsh_response_crea_ascii(resp_list,star_list,lambda_spectrum,
1244 flux_spectrum,flux_added));
1245 }
1246
1247 cleanup:
1248
1249 XSH_FREE( lambda_spectrum ) ;
1250 XSH_FREE( lambda_resp ) ;
1251 XSH_FREE( lambda_resp ) ;
1252 XSH_FREE( flux_resp ) ;
1253 XSH_FREE( flux_added ) ;
1254
1255 if(cpl_error_get_code() == CPL_ERROR_NONE) {
1256 return resp_list;
1257 } else {
1258 return NULL;
1259 }
1260}
1261 */
1262
1279static xsh_star_flux_list *
1281 xsh_star_flux_list * star_list,
1282 xsh_star_flux_list ** obj_list,
1283 xsh_spectrum * spectrum,
1284 cpl_table * atmos_ext_tab,
1285 HIGH_ABS_REGION * phigh,
1286 double airmass,
1287 double exptime,
1288 double gain,
1290{
1291 xsh_star_flux_list * resp_list = NULL ;
1292
1293 int nlambda_star ;
1294 //double step_spectrum ;
1295 double step_star ;
1296 double * lambda_star = NULL;
1297 //double * flux_star = NULL ;
1298 double lambda_star_min, lambda_star_max ;
1299 //double * flux_spectrum = NULL ;
1300 //int * qual_spectrum = NULL ;
1301 //double lambda_spectrum_min, lambda_spectrum_max ;
1302 double * atmos_lambda = NULL ;
1303 double * atmos_K = NULL ;
1304 XSH_ARM the_arm ;
1305
1306 XSH_ASSURE_NOT_NULL( star_list ) ;
1307 XSH_ASSURE_NOT_NULL( spectrum ) ;
1308 /*
1309 get Nb of lambda, etc in spectrum.
1310 */
1311 //check( flux_spectrum = xsh_spectrum_get_flux( spectrum ) ) ;
1312 //check( qual_spectrum = xsh_spectrum_get_qual( spectrum ) ) ;
1313 //check( lambda_spectrum_min = xsh_spectrum_get_lambda_min( spectrum ) ) ;
1314 //check( lambda_spectrum_max = xsh_spectrum_get_lambda_max( spectrum ) ) ;
1315 //check( step_spectrum = xsh_spectrum_get_lambda_step( spectrum ) ) ;
1317 /*
1318 get Nb of lambda in star_list.
1319 */
1320 nlambda_star = star_list->size ;
1321 lambda_star = star_list->lambda ;
1322 //flux_star = star_list->flux ;
1323 lambda_star_min = *lambda_star ;
1324 lambda_star_max = *(lambda_star+nlambda_star-1) ;
1325 step_star = (lambda_star_max-lambda_star_min)/(nlambda_star-1) ;
1326 xsh_msg_dbg_low( "Star - Nlambda: %d, Min: %le, Max: %le, Step: %lf",
1327 nlambda_star,
1328 lambda_star_min, lambda_star_max, step_star ) ;
1329
1330 check(xsh_interpolate_atm_ext(star_list,atmos_ext_tab,instrument,
1331 &atmos_lambda,&atmos_K));
1332
1333 check(resp_list=xsh_response_calculate(star_list,obj_list,spectrum,
1334 atmos_ext_tab,the_arm,atmos_K,
1335 airmass,exptime,gain));
1336
1337 /* linear interpolation of high absorbtion regions (NIR and VIS only) */
1338 //PAPERO;
1339 //double wave_high_abs=find_high_abs_wave_max(phigh);
1340 for( ; phigh->lambda_min != 0. ; phigh++ ) {
1341
1342 if(phigh->lambda_min < lambda_star_max &&
1343 phigh->lambda_max > lambda_star_min) {
1344 /*
1345 xsh_msg("plambda_min=%g lambda_star_max=%g plambda_max=%g lambda_star_min=%g",phigh->lambda_min,lambda_star_max,phigh->lambda_max,lambda_star_min);
1346 */
1347 check(xsh_interpolate_high_abs_regions(star_list,resp_list,phigh));
1348 }
1349 }
1350 cleanup:
1351 xsh_msg_dbg_medium( "End compute_response" ) ;
1352 XSH_FREE( atmos_lambda ) ;
1353 XSH_FREE( atmos_K ) ;
1354
1355 return resp_list ;
1356
1357}
1358
1359
1360
1361cpl_error_code
1363 xsh_star_flux_list * star_list,
1364 xsh_star_flux_list * obj_list)
1365{
1366
1367 cpl_table* table=NULL;
1368 const char* name=NULL;
1369 cpl_propertylist* plist=NULL;
1370 int nrow=0;
1371 int i=0;
1372
1373 double* pobj=NULL;
1374 double* pref=NULL;
1375 double* pdiv=NULL;
1376
1377 name=cpl_frame_get_filename(result);
1378 plist=cpl_propertylist_load(name,0);
1379 table=cpl_table_load(name,1,0);
1380 nrow=cpl_table_get_nrow(table);
1381
1382 check(cpl_table_name_column(table,"FLUX", "RESPONSE"));
1383 cpl_table_new_column(table,"OBS",CPL_TYPE_DOUBLE);
1384 cpl_table_new_column(table,"REF",CPL_TYPE_DOUBLE);
1385 cpl_table_new_column(table,"REF_DIV_OBS",CPL_TYPE_DOUBLE);
1386 cpl_table_fill_column_window_double(table,"OBS",0,nrow,0);
1387 cpl_table_fill_column_window_double(table,"REF",0,nrow,0);
1388 cpl_table_fill_column_window_double(table,"REF_DIV_OBS",0,nrow,0);
1389
1390 pobj=cpl_table_get_data_double(table,"OBS");
1391 pref=cpl_table_get_data_double(table,"REF");
1392 pdiv=cpl_table_get_data_double(table,"REF_DIV_OBS");
1393
1394 for(i=0;i<nrow;i++) {
1395 pobj[i]=obj_list->flux[i];
1396 pref[i]=star_list->flux[i];
1397 pdiv[i]=pref[i]/pobj[i];
1398 }
1399
1400 cpl_table_save(table,plist,NULL,name,CPL_IO_DEFAULT);
1401
1402 cleanup:
1403 xsh_free_table(&table);
1404 xsh_free_propertylist(&plist);
1405
1406 return cpl_error_get_code();
1407}
1408
1409
1422static xsh_star_flux_list *
1423xsh_obs_std_correct(cpl_frame* obs_std_star, xsh_star_flux_list * ref_std_star_list,
1424 cpl_frame* atmos_ext, HIGH_ABS_REGION * phigh,xsh_instrument* instrument )
1425{
1426
1427 xsh_star_flux_list * corr_obs_std_star_list=NULL;
1428 double dRA = 0;
1429 double dDEC = 0;
1430 double airmass = 0;
1431 double exptime=0;
1432
1433 /* extract relevant info (STD RA,DEC,airmass, ID; bin x,y, gain, exptime/DIT) from observed spectrum */
1434 check(xsh_frame_sci_get_ra_dec_airmass(obs_std_star, &dRA, &dDEC,&airmass));
1435
1436 const char* filename = NULL;
1437 cpl_propertylist* plist = NULL;
1438 double gain = 0;
1439
1440
1441
1442 check(filename = cpl_frame_get_filename(obs_std_star));
1443 check(plist = cpl_propertylist_load(filename, 0));
1444 /* extract airmass from observed spectrum */
1445 airmass=xsh_pfits_get_airm_mean(plist);
1446 /* we get the bin along the dispersion direction */
1448 /* we assume gain in units of ADU/e- as ESO standard */
1449 gain = 1. / 2.12;
1450 //bin = 1;
1451 } else {
1452 check_msg( gain = xsh_pfits_get_gain(plist), "Could not read gain factor");
1453 }
1455
1456
1457 /* load atmospheric extinction frame */
1458 xsh_atmos_ext_list * atmos_ext_list = NULL;
1459 cpl_table* atmos_ext_tab = NULL;
1460
1461 if (atmos_ext != NULL) {
1462 check( atmos_ext_list = xsh_atmos_ext_list_load( atmos_ext) );
1463 filename=cpl_frame_get_filename(atmos_ext);
1464 atmos_ext_tab=cpl_table_load(filename,1,0);
1465 } else {
1467 "Missing input %s_%s frame. Skip response and efficiency computation", XSH_ATMOS_EXT, xsh_instrument_arm_tostring(instrument));
1468 }
1469
1470
1471 double * atmos_lambda = NULL ;
1472 double * atmos_K = NULL ;
1473
1474 check(xsh_interpolate_atm_ext(ref_std_star_list,atmos_ext_tab,instrument, &atmos_lambda,&atmos_K));
1475
1477
1478 xsh_spectrum * obs_std_spectrum = NULL ;
1479 check( obs_std_spectrum = xsh_spectrum_load( obs_std_star));
1480 check(xsh_spectrum_correct(ref_std_star_list,
1481 obs_std_spectrum,atmos_K,the_arm,
1482 airmass,exptime,gain,&corr_obs_std_star_list));
1483
1484
1485 cleanup:
1486 xsh_free_table(&atmos_ext_tab);
1487 xsh_atmos_ext_list_free(&atmos_ext_list);
1488 xsh_free_propertylist(&plist);
1489 XSH_FREE( atmos_lambda ) ;
1490 XSH_FREE( atmos_K ) ;
1491
1492 xsh_spectrum_free( &obs_std_spectrum ) ;
1493 return corr_obs_std_star_list;
1494}
1495/*
1496static double
1497xsh_get_ref_std_star_wave_ref(cpl_table* tbl_ref,const double wavec,const double wstep)
1498{
1499
1500 cpl_vector* vx=NULL;
1501 cpl_vector* vy=NULL;
1502 cpl_table* ext=NULL;
1503
1504 XSH_GAUSSIAN_FIT gfit;
1505 // assumes wave core of 0.5 nm)
1506 int rad=(int)(0.5/wstep+0.5);
1507 double wmax=wavec+rad*wstep;
1508 double wmin=wavec-rad*wstep;
1509 double wavefit=0;
1510 int nrows=0;
1511 xsh_msg("table selection wmin %g wmax %g",wmin,wmax);
1512
1513 cpl_table_and_selected_double(tbl_ref,"LAMBDA",CPL_GREATER_THAN,wmin);
1514 cpl_table_and_selected_double(tbl_ref,"LAMBDA",CPL_LESS_THAN,wmax);
1515 ext=cpl_table_extract_selected(tbl_ref);
1516 nrows=cpl_table_get_nrow(tbl_ref);
1517
1518 cpl_table_cast_column(tbl_ref,"LAMBDA","W",CPL_TYPE_DOUBLE);
1519 cpl_table_cast_column(tbl_ref,"FLUX","F",CPL_TYPE_DOUBLE);
1520
1521 vx=cpl_vector_wrap(nrows,cpl_table_get_data_double(tbl_ref,"W"));
1522 vy=cpl_vector_wrap(nrows,cpl_table_get_data_double(tbl_ref,"F"));
1523
1524 xsh_vector_fit_gaussian(vx,vy,&gfit);
1525 wavefit=gfit.peakpos;
1526 xsh_msg("wave ref fit=%g",wavefit);
1527
1528 cpl_vector_unwrap(vx);
1529 cpl_vector_unwrap(vy);
1530 xsh_free_table(&ext);
1531
1532 return wavefit;
1533}
1534 */
1535/*
1536static double
1537xsh_get_obs_std_star_wave_ref(cpl_frame* obs_std_star,const double wavec,
1538 const double wmin, const double wstep)
1539{
1540
1541 cpl_vector* vx=NULL;
1542 cpl_vector* vy=NULL;
1543 XSH_GAUSSIAN_FIT gfit;
1544 xsh_spectrum* obs_spectrum=NULL;
1545 cpl_image* sub_ima=NULL;
1546
1547 double* px=0;
1548 double* py=0;
1549 double* pima=NULL;
1550
1551 double wavefit=0;
1552 // assumes wave core of 0.5 nm
1553 int rad=(int)(0.5/wstep+0.5);
1554 int i=0;
1555 int xlo=(wavec-wmin)/wstep-rad;
1556 int xhi=xlo+2*rad;
1557
1558 obs_spectrum=xsh_spectrum_load(obs_std_star);
1559
1560 sub_ima=cpl_image_extract(obs_spectrum->flux,xlo,1,xhi,1);
1561 pima=cpl_image_get_data_double(sub_ima);
1562
1563 vx=cpl_vector_new(2*rad);
1564 vy=cpl_vector_new(2*rad);
1565 px=cpl_vector_get_data(vx);
1566 py=cpl_vector_get_data(vy);
1567
1568
1569
1570 int k=0;
1571 for(i=0;i<2*rad;i++){
1572 k=i-rad;
1573 px[i]=wavec+k*wstep;
1574 py[i]=pima[i];
1575 }
1576
1577 xsh_vector_fit_gaussian(vx,vy,&gfit);
1578
1579 wavefit=gfit.peakpos;
1580
1581 xsh_msg("wave obs fit=%g",wavefit);
1582
1583 xsh_free_vector(&vx);
1584 xsh_free_vector(&vy);
1585 xsh_spectrum_free(&obs_spectrum);
1586 xsh_free_image(&sub_ima);
1587
1588 return wavefit;
1589}
1590 */
1591/* copy flux(wave) values from wmin to wmax in two output vectors */
1592
1593static cpl_error_code
1595 const double wmin,
1596 const double wmax,
1597 cpl_vector** vec_wave,
1598 cpl_vector** vec_flux)
1599{
1600 double* pwave_in=NULL;
1601 double* pflux_in=NULL;
1602
1603 double* pwave_ou=NULL;
1604 double* pflux_ou=NULL;
1605
1606 int size=0;
1607 int i=0;
1608 int k=0;
1609
1610 pwave_in=obs_std_star_list->lambda;
1611 pflux_in=obs_std_star_list->flux;
1612 size=obs_std_star_list->size;
1613
1614 *vec_wave=cpl_vector_new(size);
1615 *vec_flux=cpl_vector_new(size);
1616 pwave_ou=cpl_vector_get_data(*vec_wave);
1617 pflux_ou=cpl_vector_get_data(*vec_flux);
1618
1619 for(i=0;i<size;i++) {
1620 if(pwave_in[i]>=wmin && pwave_in[i]<= wmax) {
1621 pwave_ou[k]=pwave_in[i];
1622 pflux_ou[k]=pflux_in[i];
1623 k++;
1624 }
1625 }
1626 cpl_vector_set_size(*vec_wave,k);
1627 cpl_vector_set_size(*vec_flux,k);
1628
1629 return cpl_error_get_code();
1630}
1631
1632/*---------------------------------------------------------------------------*/
1643/*---------------------------------------------------------------------------*/
1644cpl_error_code xsh_sort_double_pairs(double *u1, double *u2, cpl_size n)
1645{
1646 cpl_vector * biu1=NULL;
1647 cpl_vector * biu2=NULL;
1648 cpl_bivector * bi_all=NULL;
1649
1650 if (n < 1)
1651 return cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
1652 cpl_ensure_code(u1 != NULL, CPL_ERROR_NULL_INPUT);
1653 cpl_ensure_code(u2 != NULL, CPL_ERROR_NULL_INPUT);
1654
1655
1656 biu1=cpl_vector_wrap(n,u1);
1657 biu2=cpl_vector_wrap(n,u2);
1658
1659 bi_all=cpl_bivector_wrap_vectors(biu1, biu2);
1660 cpl_bivector_sort(bi_all,bi_all, CPL_SORT_ASCENDING,CPL_SORT_BY_X);
1661
1662
1663 /* cleaning up */
1664
1665 cpl_bivector_unwrap_vectors(bi_all);
1666 cpl_vector_unwrap(biu1);
1667 cpl_vector_unwrap(biu2);
1668
1669 return CPL_ERROR_NONE;
1670}
1671
1672/* selects a sub range in a star line spectrum */
1673static cpl_error_code
1674xsh_select_line_core(cpl_vector* wave,cpl_vector* flux,const double wguess,const double wrange,cpl_vector** xfit,cpl_vector** yfit)
1675{
1676
1677 int size=0;
1678 double* pxfit=NULL;
1679 double* pyfit=NULL;
1680 double* pwave=NULL;
1681 double* pflux=NULL;
1682 int i=0;
1683 int k=0;
1684
1685 size=cpl_vector_get_size(wave);
1686 *xfit=cpl_vector_new(size);
1687 *yfit=cpl_vector_new(size);
1688 pxfit=cpl_vector_get_data(*xfit);
1689 pyfit=cpl_vector_get_data(*yfit);
1690
1691 pwave=cpl_vector_get_data(wave);
1692 pflux=cpl_vector_get_data(flux);
1693
1694 k=0;
1695 for(i=0;i<size;i++) {
1696 if(pwave[i]>=(wguess-wrange) &&
1697 pwave[i]<=(wguess+wrange) ) {
1698
1699 pxfit[k]=pwave[i];
1700 pyfit[k]=pflux[i];
1701 k++;
1702 }
1703 }
1704 check(cpl_vector_set_size(*xfit,k));
1705 check(cpl_vector_set_size(*yfit,k));
1706
1707 cleanup:
1708 return cpl_error_get_code();
1709}
1710#if 0
1711static cpl_error_code
1712xsh_line_balance(cpl_vector** x,cpl_vector** y,const double ymax)
1713{
1714
1715 double* px=NULL;
1716 double* py=NULL;
1717 int k=0;
1718 int size=0;
1719 int i=0;
1720
1721 px=cpl_vector_get_data(*x);
1722 py=cpl_vector_get_data(*y);
1723
1724 size=cpl_vector_get_size(*x);
1725
1726 for(i=0;i<size;i++) {
1727 if(py[i] <= ymax) {
1728
1729 px[k]=px[i];
1730 py[k]=py[i];
1731 k++;
1732 }
1733 }
1734 cpl_vector_set_size(*x,k);
1735 cpl_vector_set_size(*y,k);
1736
1737 //cleanup:
1738 return cpl_error_get_code();
1739}
1740#endif
1741
1742static double
1744 xsh_star_flux_list * ref_std_star_list,xsh_rv_ref_wave_param* w)
1745
1746{
1747
1748 double wave_shift = 0;
1749 int naxis1 = 0;
1750 double wstep = 0;
1751 double wmin = 0;
1752 double wmax = 0;
1753
1754 /*
1755 double* prw = 0;
1756 double* prf = 0;
1757 double* pow = 0;
1758 double* pof = 0;
1759 double* pvrf = 0;
1760 double* pvof = 0;
1761 */
1762 //double* pvrw = 0;
1763
1764 //double* pvow = 0;
1765
1766 double hbox_wave=0.5;
1767 int hbox = (int)(hbox_wave/wstep+0.5);
1768 //int hbox = 500;
1769
1770
1771 int i=0;
1772 /*
1773 int k=0;
1774 int box=2*hbox+1;
1775 int size=0;
1776 */
1777 naxis1 = xsh_pfits_get_naxis1(obs_std_star_list->header);
1778 wstep = xsh_pfits_get_cdelt1(obs_std_star_list->header);
1779 wmin = xsh_pfits_get_crval1(obs_std_star_list->header);
1780 wmax = wmin + naxis1 * wstep;
1781
1782
1783
1784 wmin=w->wguess-hbox*wstep;
1785 wmax=w->wguess+(hbox+1)*wstep;
1786
1787 //xsh_msg("hbox=%d",hbox);
1788 /* wrap the observed std star spectrum into a vector */
1789 cpl_vector* vec_wave_obs = NULL;
1790 cpl_vector* vec_flux_obs = NULL;
1791 cpl_vector* vec_wave_ref=NULL;
1792 cpl_vector* vec_flux_ref=NULL;
1793 cpl_vector* vec_slope_obs=NULL;
1794 cpl_vector* vec_slope_ref=NULL;
1795 cpl_vector* correl=NULL;
1796
1797 /* we first extract the relevant wavelength range used for cross correlation, covering just one line */
1798 wmin=w->range_wmin;
1799 wmax=w->range_wmax;
1800 //xsh_msg("wmin=%g wmax=%g",wmin,wmax);
1801 xsh_std_star_spectra_to_vector_range(obs_std_star_list,wmin,wmax,&vec_wave_obs,&vec_flux_obs);
1802 xsh_std_star_spectra_to_vector_range(ref_std_star_list,wmin,wmax,&vec_wave_ref,&vec_flux_ref);
1803
1804 /*
1805 check(cpl_vector_save(vec_flux_obs,"vec_flux_obs.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
1806 check(cpl_vector_save(vec_flux_ref,"vec_flux_ref.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
1807 */
1808
1809 /* we fit a slope (or parabola) on the flat region of the spectrum */
1810 double wmin_max=w->ipol_wmin_max;
1811 double wmax_min=w->ipol_wmax_min;
1812 //xsh_msg("wmin_max=%g wmax_min=%g",wmin_max,wmax_min);
1813 vec_slope_obs=xsh_vector_fit_slope(vec_wave_obs,vec_flux_obs,wmin_max,wmax_min,2);
1814 vec_slope_ref=xsh_vector_fit_slope(vec_wave_ref,vec_flux_ref,wmin_max,wmax_min,2);
1815
1816 /*
1817 check(cpl_vector_save(vec_slope_obs,"vec_slope_obs.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
1818 check(cpl_vector_save(vec_slope_ref,"vec_slope_ref.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
1819 */
1820
1821 /* we divide the spectrum by the slope */
1822 cpl_vector_divide(vec_flux_obs,vec_slope_obs);
1823 cpl_vector_divide(vec_flux_ref,vec_slope_ref);
1824 xsh_free_vector(&vec_slope_obs);
1825 xsh_free_vector(&vec_slope_ref);
1826
1827 cpl_vector_add_scalar(vec_flux_obs,2);
1828 cpl_vector_add_scalar(vec_flux_ref,2);
1829 /*
1830 check(cpl_vector_save(vec_flux_obs,"vec_flux_obs_corr.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
1831 check(cpl_vector_save(vec_flux_ref,"vec_flux_ref_corr.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
1832 check(cpl_vector_save(vec_wave_obs,"vec_wave_obs.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
1833 check(cpl_vector_save(vec_wave_ref,"vec_wave_ref.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
1834
1835 */
1836
1837 /* at this points both line spectra (on ref std star and on observed std) have same ranges and a "continuum" */
1838
1839 /* we now restrict to the line core to limit the effects introduced by the wide line wings */
1840
1841 double wave_range=w->ipol_hbox;
1842 cpl_vector* xfit_obs=NULL;
1843 cpl_vector* yfit_obs=NULL;
1844 cpl_vector* xfit_ref=NULL;
1845 cpl_vector* yfit_ref=NULL;
1846 double* pxfit=NULL;
1847 double* pyfit=NULL;
1848 /*
1849 double* pwave=NULL;
1850 double* pflux=NULL;
1851 */
1852
1853 xsh_select_line_core(vec_wave_obs,vec_flux_obs,w->wguess,wave_range,&xfit_obs,&yfit_obs);
1854 /*
1855 cpl_vector_save(xfit_obs,"xfit_obs.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
1856 cpl_vector_save(yfit_obs,"yfit_obs.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
1857 */
1858 xsh_select_line_core(vec_wave_ref,vec_flux_ref,w->wguess,wave_range,&xfit_ref,&yfit_ref);
1859 /*
1860 cpl_vector_save(xfit_ref,"xfit_ref.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
1861 cpl_vector_save(yfit_ref,"yfit_ref.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
1862 */
1863 /*
1864 xsh_free_vector(&vec_flux_obs);
1865 xsh_free_vector(&vec_wave_obs);
1866 */
1867
1868 /*
1869 double ymax_obs=0;
1870 double ymax_ref=0;
1871 k=cpl_vector_get_size(yfit_obs);
1872 pflux=cpl_vector_get_data(yfit_obs);
1873 ymax_obs=(pflux[0] <= pflux[k-1]) ? pflux[0] : pflux[k-1];
1874
1875 k=cpl_vector_get_size(yfit_ref);
1876 pflux=cpl_vector_get_data(yfit_ref);
1877 ymax_ref=(pflux[0] <= pflux[k-1]) ? pflux[0] : pflux[k-1];
1878 */
1879 /*
1880 int size_x=k;
1881 int size_x_ref=0;
1882 */
1883 int size_x_obs=0;
1884 /* we now make sure to have a symmetric distribution (because later we get the fit-centroid)
1885 xsh_line_balance(&xfit_ref,&yfit_ref,ymax_ref);
1886 pwave=cpl_vector_get_data(xfit_ref);
1887 pflux=cpl_vector_get_data(yfit_ref);
1888
1889 k=0;
1890 for(i=0;i<size_x;i++) {
1891 if(pflux[i]<=ymax_ref) {
1892
1893 pxfit[k]=pwave[i];
1894 pyfit[k]=pflux[i];
1895 k++;
1896 }
1897 }
1898 check(cpl_vector_set_size(xfit_ref,k));
1899 cpl_vector_set_size(yfit_ref,k);
1900 size_x_ref=k;
1901 */
1902
1903 /* we now make sure to have a symmetric distribution (because later we get the fit-centroid)
1904 pwave=cpl_vector_get_data(xfit_obs);
1905 pflux=cpl_vector_get_data(yfit_obs);
1906
1907 k=0;
1908 for(i=0;i<size_x;i++) {
1909 if(pflux[i]<=ymax_obs) {
1910
1911 pxfit[k]=pwave[i];
1912 pyfit[k]=pflux[i];
1913 k++;
1914 }
1915 }
1916 xsh_msg(">>>k=%d ymax_obs=%g",k,ymax_obs);
1917 check(cpl_vector_set_size(xfit_obs,k));
1918 check(cpl_vector_set_size(yfit_obs,k));
1919
1920 size_x_obs=k;
1921 */
1922
1923
1924 /* here we try to do median smoothing to have better fit */
1925 //cpl_vector* yfit_obs_med=cpl_vector_filter_median_create(yfit_obs,3);
1926 //check(cpl_vector_save(yfit_obs_med,"yfit_obs_med.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
1927 hbox=cpl_vector_get_size(vec_flux_ref);
1928
1929 /* because lines cross correlation is not very accurate, here we try to make a poly (parabola)lation
1930 * fit to have more robust min determination */
1931 cpl_polynomial* poly_fit_obs=NULL;
1932
1933 double mse=0;
1934 double* pindex=NULL;
1935 poly_fit_obs=xsh_polynomial_fit_1d_create(xfit_obs,yfit_obs,4,&mse);
1936 //xsh_msg("mse=%g",mse);
1937 cpl_vector* yfit_pol_obs=NULL;
1938 cpl_vector* yfit_index=NULL;
1939 size_x_obs=cpl_vector_get_size(xfit_obs);
1940 yfit_pol_obs=cpl_vector_new(size_x_obs);
1941 yfit_index=cpl_vector_new(size_x_obs);
1942 check(pyfit=cpl_vector_get_data(yfit_pol_obs));
1943 check(pxfit=cpl_vector_get_data(xfit_obs));
1944 check(pindex=cpl_vector_get_data(yfit_index));
1945
1946 for(i=0;i<size_x_obs;i++) {
1947 pyfit[i]=cpl_polynomial_eval_1d(poly_fit_obs,pxfit[i],NULL);
1948 pindex[i]=i;
1949 }
1950 xsh_free_polynomial(&poly_fit_obs);
1951 //check(cpl_vector_save(yfit_pol_obs,"yfit_pol_obs.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
1952 //double ymin=0;
1953 double xmin=0;
1954
1955 /* we get the parabola min/max */
1956 xsh_sort_double_pairs(pyfit,pindex,size_x_obs);
1957 //cpl_vector_dump(yfit_index,stdout);
1958 //cpl_vector_dump(yfit_pol_obs,stdout);
1959 xmin=pxfit[(int)pindex[0]];
1960 //ymin=pyfit[0];
1961 xsh_free_vector(&yfit_index);
1962 //xsh_msg("Obs line spectrum poly fit min wave pos=%g value=%g",xmin,ymin);
1963
1964 /* makes Gaussian fit to obs spectrum
1965 cpl_vector* sigy_obs=NULL;
1966 cpl_vector* sigy_ref=NULL;
1967
1968 sigy_obs=cpl_vector_duplicate(yfit_obs);
1969 cpl_vector_multiply_scalar(sigy_obs,0.1);
1970
1971 sigy_ref=cpl_vector_duplicate(yfit_ref);
1972 cpl_vector_multiply_scalar(sigy_ref,0.1);
1973
1974
1975 double peakpos_obs=xmin;
1976 double sigma=1;
1977 double area=1;
1978 double offset=0;
1979 double red_chisq=0;
1980 cpl_matrix* covariance=NULL;
1981
1982 check(cpl_vector_fit_gaussian(xfit_obs,NULL,yfit_obs,sigy_obs,CPL_FIT_CENTROID,&peakpos_obs,&sigma,&area,&offset,&mse,&red_chisq,&covariance));
1983 xsh_msg("sigma=%g area=%g offset=%g",sigma,area,offset);
1984 */
1985 double peakpos_obs=xmin;
1986 double peakpos_ref=w->wguess;
1987 xsh_msg("Pos guess: %g obs: %10.8g Pos ref: %10.8g diff=%10.8g",
1988 w->wguess,peakpos_obs,peakpos_ref,peakpos_obs-peakpos_ref);
1989
1990
1991 xsh_msg("Now compute shift by spectra correlation");
1992
1993 //PIPPO
1994 /* WE DECIDED NOT TO FIT THE MODEL FOR RV COMPUTATION, ONLY THE OBJECT AND TO MAKE A POLY FIT
1995 * BECAUSE THE FOLLOWING WAS NOT VERY ACCURATE: IN ANY CASE ONE WOULD HAVE TO FIT A GAUUSS TO
1996 * THE CORRELATION MAX
1997 *
1998
1999 cpl_vector* flux_obs_fine=NULL;
2000 cpl_vector* flux_ref_fine=NULL;
2001
2002 flux_obs_fine=xsh_vector_upsample(vec_flux_obs,10);
2003 flux_ref_fine=xsh_vector_upsample(vec_flux_ref,10);
2004 cpl_vector_save(flux_obs_fine,"flux_obs_fine.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
2005 cpl_vector_save(flux_ref_fine,"flux_ref_fine.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
2006
2007 cpl_size shift=0;
2008 hbox=5000;
2009 hbox=cpl_vector_get_size(vec_flux_ref);
2010 correl=cpl_vector_new(2*hbox+1);
2011
2012 check(shift=cpl_vector_correlate(correl,vec_flux_obs,vec_flux_ref));
2013 //UFFA
2014 cpl_vector_save(correl,"correl.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
2015
2016 double* flux_o =cpl_vector_get_data(flux_obs_fine);
2017 double* flux_r =cpl_vector_get_data(flux_ref_fine);
2018 int width_i=2*hbox+1;
2019 int width_t=2*hbox+1;
2020 int half_search=(int)(0.5*hbox+1);
2021 double delta=0;
2022 double corr=0;
2023 double* xcorr=NULL;
2024
2025
2026 XSH_GAUSSIAN_FIT gfit;
2027 int size_o=0;
2028 size_o = cpl_vector_get_size(flux_obs_fine);
2029 double step=(wmax-wmin)/size_o;
2030
2031 check(xsh_correl_spectra(flux_o,flux_r,size_o,hbox,step,0.1,0,&gfit));
2032
2033 xsh_msg("sigma=%g",gfit.sigma);
2034 xsh_msg("computed shift[lognm]=%g",(gfit.peakpos-hbox*step));
2035
2036 hbox=(int)3.*CPL_MATH_FWHM_SIG * gfit.sigma/step;
2037 xsh_msg("hsearch=%d",hbox);
2038 check(xsh_correl_spectra(flux_o,flux_r,size_o,hbox,step,0.1,0,&gfit));
2039
2040
2041
2042
2043 //check(xcorr=xsh_function1d_xcorrelate(line_i,width_i,line_t,width_t,half_search,0,&corr,&delta));
2044 //cpl_vector_save(xcorr,"xcorr.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
2045 xsh_msg("RV corr=%g delta=%g shift=%g",corr,delta,delta*wstep);
2046
2047 xsh_free(xcorr);
2048 */
2049 /*
2050 check(correl_max=cpl_vector_get_max(correl));
2051 xsh_msg("correl_max=%g",correl_max);
2052 check(correl_pos=cpl_vector_find(correl,correl_max));
2053 xsh_msg("correl: shift=%d max=%g val(shift)=%g pos=%d",
2054 (int)shift,correl_max,cpl_vector_get(correl,shift+1),(int)correl_pos);
2055 wave_shift=delta*wstep;
2056 */
2057 wave_shift=peakpos_obs-peakpos_ref;
2058 //check(cpl_vector_save(correl,"correl.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
2059
2060 cleanup:
2061
2062 xsh_free_vector(&yfit_pol_obs);
2063 xsh_free_vector(&xfit_obs);
2064 xsh_free_vector(&yfit_obs);
2065 xsh_free_vector(&xfit_ref);
2066 xsh_free_vector(&yfit_ref);
2067 xsh_free_vector(&vec_wave_obs);
2068 xsh_free_vector(&vec_flux_obs);
2069 xsh_free_vector(&vec_wave_ref);
2070 xsh_free_vector(&vec_flux_ref);
2071 xsh_free_vector(&correl);
2072
2073 return wave_shift;
2074}
2075
2076/*
2077static xsh_star_flux_list *
2078xsh_bspline_interpol(xsh_star_flux_list * ref_std_star_list,
2079 HIGH_ABS_REGION * phigh, xsh_instrument* inst) {
2080 int i = 0;
2081 xsh_star_flux_list * result = NULL;
2082 const int n = ref_std_star_list->size;
2083 //double x[n], y[n];
2084 double* wave=NULL;
2085 double* response=NULL;
2086 double wmin=0;
2087 double wmax=0;
2088 double wstep=0;
2089
2090 cpl_table* tab_data=NULL;
2091
2092 wave = ref_std_star_list->lambda;
2093 response = ref_std_star_list->flux;
2094
2095 wmin = *wave;
2096 wmax = *(wave + n - 1);
2097 wstep = (wmax - wmin) / (n - 1);
2098
2099 int k=0;
2100 // store input values in a table
2101 tab_data = cpl_table_new(n);
2102 cpl_table_new_column(tab_data, "wave", CPL_TYPE_DOUBLE);
2103 cpl_table_new_column(tab_data, "resp", CPL_TYPE_DOUBLE);
2104 cpl_table_fill_column_window_double(tab_data, "wave", 0, n, 0);
2105 cpl_table_fill_column_window_double(tab_data, "resp", 0, n, 0);
2106
2107
2108 double* px=NULL;
2109 double* py=NULL;
2110 px = cpl_table_get_data_double(tab_data, "wave");
2111 py = cpl_table_get_data_double(tab_data, "resp");
2112 // flag NAN or INF values
2113 for (i = 0; i < n; i++) {
2114 if(isnan(response[i]) || isinf(response[i])) {
2115 // bad point: skip it
2116 } else {
2117 px[k]=wave[i];
2118 py[k]=response[i];
2119 k++;
2120 }
2121 }
2122 int ndata=k+1;
2123 cpl_table_set_size(tab_data,ndata);
2124
2125 if (phigh != NULL) {
2126 xsh_msg("Flag High Absorption Regions" );
2127 for (; phigh->lambda_min != 0.; phigh++) {
2128 xsh_msg("Flag [%g,%g]",phigh->lambda_min,phigh->lambda_max);
2129 for (i = 0; i < ndata; i++) {
2130 if (wave[i] >= phigh->lambda_min && wave[i] <= phigh->lambda_max) {
2131 cpl_table_set_invalid(tab_data,"wave", i);
2132 }
2133 }
2134 }
2135 }
2136 cpl_table_erase_invalid(tab_data);
2137 cpl_table_save(tab_data, NULL, NULL, "resp_data.fits", CPL_IO_DEFAULT);
2138 ndata=cpl_table_get_nrow(tab_data);
2139
2140 printf("Found %d good points over %d total points",ndata,n);
2141
2142 // compute median flux values
2143 int hsize=200;
2144 int size=2*hsize+1;
2145 int nsampl=ndata/size-1;
2146
2147 int j=0;
2148 int m=0;
2149
2150 //double* psx=NULL;
2151 //double* psy=NULL;
2152 cpl_table* tab_sampl=NULL;
2153 //cpl_vector* sx=NULL;
2154 //cpl_vector* sy=NULL;
2155 double* pwav=NULL;
2156 double* pmed=NULL;
2157 // prepare table to store median flux values
2158
2159 tab_sampl = cpl_table_new(nsampl);
2160 cpl_table_new_column(tab_sampl, "wave", CPL_TYPE_DOUBLE);
2161 cpl_table_new_column(tab_sampl, "median", CPL_TYPE_DOUBLE);
2162 cpl_table_fill_column_window_double(tab_sampl, "wave", 0, nsampl, 0);
2163 cpl_table_fill_column_window_double(tab_sampl, "median", 0, nsampl, 0);
2164 pwav = cpl_table_get_data_double(tab_sampl, "wave");
2165 pmed = cpl_table_get_data_double(tab_sampl, "median");
2166
2167 // pre set edge values to be able to interpolate
2168 pwav[0]=wave[0];
2169 pmed[0]=response[0];
2170
2171 pwav[nsampl-1]=wave[n-1];
2172 pmed[nsampl-1]=response[n-1];
2173
2174 cpl_vector* rx=NULL;
2175 cpl_vector* ry=NULL;
2176 double* prx=NULL;
2177 double* pry=NULL;
2178
2179 rx=cpl_vector_new(size);
2180 ry=cpl_vector_new(size);
2181 prx=cpl_vector_get_data(rx);
2182 pry=cpl_vector_get_data(ry);
2183 px = cpl_table_get_data_double(tab_data, "wave");
2184 py = cpl_table_get_data_double(tab_data, "resp");
2185
2186 for(i=1;i<n && m<nsampl-1;i+=size,m++) {
2187 for(j=-hsize;j<=hsize;j++) {
2188 k=j+hsize;
2189 prx[k]=px[k+i];
2190 pry[k]=py[k+i];
2191 }
2192 pwav[m]=cpl_vector_get_mean(rx);
2193 pmed[m]=cpl_vector_get_median(ry);
2194 //printf("sx[%d]=%g sy[%d]=%g\n", m,psx[m], m,psy[m]);
2195 }
2196
2197 cpl_table_save(tab_sampl, NULL, NULL, "resp_sampl.fits", CPL_IO_DEFAULT);
2198 printf("nsampl=%d ",nsampl);
2199 pwav = cpl_table_get_data_double(tab_sampl, "wave");
2200 pmed = cpl_table_get_data_double(tab_sampl, "median");
2201
2202 cpl_table* tab_resp_fit=NULL;
2203 {
2204
2205 gsl_interp_accel* acc = gsl_interp_accel_alloc();
2206 gsl_spline* spline = gsl_spline_alloc(gsl_interp_cspline, nsampl);
2207 gsl_spline_init(spline, pwav, pmed, nsampl);
2208
2209 // Use table to store results
2210 double* pres=NULL;
2211 tab_resp_fit = cpl_table_new(n);
2212 cpl_table_new_column(tab_resp_fit, "wave", CPL_TYPE_DOUBLE);
2213 cpl_table_new_column(tab_resp_fit, "resp", CPL_TYPE_DOUBLE);
2214 cpl_table_fill_column_window_double(tab_resp_fit, "wave", 0, n, 0);
2215 cpl_table_fill_column_window_double(tab_resp_fit, "resp", 0, n, 0);
2216 pwav = cpl_table_get_data_double(tab_resp_fit, "wave");
2217 pres = cpl_table_get_data_double(tab_resp_fit, "resp");
2218 result = xsh_star_flux_list_create(n);
2219 double xi=0;
2220 double yi=0;
2221
2222
2223 // actual interpolation
2224 for (i = 0; i < n; i++) {
2225 xi=wmin+i*wstep;
2226 yi = gsl_spline_eval(spline, xi, acc);
2227 result->lambda[i] = xi;
2228 result->flux[i] = yi;
2229 pwav[i] = xi;
2230 pres[i] = yi;
2231 printf("%g %g\n", xi, yi);
2232 }
2233
2234 gsl_spline_free(spline);
2235 gsl_interp_accel_free(acc);
2236
2237 }
2238 // save result
2239 //cpl_table_s
2240}
2241 */
2242
2243static xsh_star_flux_list *
2244xsh_bspline_fit_interpol(xsh_star_flux_list * ref_std_star_list,cpl_table* resp_fit_points,
2245 HIGH_ABS_REGION * phigh,xsh_instrument* inst)
2246{
2247 xsh_star_flux_list * res=NULL;
2248 cpl_table* tab=NULL;
2249 cpl_table* ext_data=NULL;
2250 cpl_table* ext_fit=NULL;
2251 /*
2252 const char* fname=NULL;
2253 double* lambda=NULL;
2254 double wstp_fit=0;
2255 */
2256 double* wave=NULL;
2257 double* plambda=NULL;
2258 double* flux=NULL;
2259 double* xfit=NULL;
2260 double* yfit=NULL;
2261 double wrange=0;
2262 double wmin_data=0;
2263 double wmax_data=0;
2264 double wmin_fit=0;
2265 double wmax_fit=0;
2266
2267
2268 int i=0;
2269 int size_data=0;
2270 int size_fit=0;
2271 double med=0;
2272 int imin=0;
2273 int imax=0;
2274 int nsel=0;
2275 double * pflux=NULL;
2276
2277 double flux_save=0;
2278
2279 cpl_error_ensure(ref_std_star_list != NULL, CPL_ERROR_NULL_INPUT,return res,"NULL input reference std star list");
2280 cpl_error_ensure(resp_fit_points != NULL, CPL_ERROR_NULL_INPUT,return res,"NULL input table with response fit points");
2281 cpl_error_ensure(inst != NULL, CPL_ERROR_NULL_INPUT,return res,"NULL input instrument");
2282
2283 //fname=cpl_frame_get_filename(resp_fit_points);
2284 //fit_points=cpl_table_load(fname,1,0);
2285 plambda=cpl_table_get_data_double(resp_fit_points,"LAMBDA");
2286 int resp_fit_points_n=cpl_table_get_nrow(resp_fit_points);
2287 if (xsh_instrument_get_arm(inst) == XSH_ARM_UVB) {
2288 wrange=0.4;
2289 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_VIS) {
2290 wrange=1.0;
2291 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_NIR) {
2292 wrange=5.0;
2293 }
2294
2295 size_data = ref_std_star_list->size ;
2296 wave = xsh_star_flux_list_get_lambda(ref_std_star_list) ;
2297 flux = xsh_star_flux_list_get_flux(ref_std_star_list) ;
2298 res=xsh_star_flux_list_duplicate(ref_std_star_list);
2299
2300 tab=cpl_table_new(size_data);
2301 cpl_table_wrap_double(tab,wave,"wave");
2302 cpl_table_wrap_double(tab,flux,"response");
2303 check(wmin_data=cpl_table_get_column_min(tab,"wave"));
2304 check(wmax_data=cpl_table_get_column_max(tab,"wave"));
2305 xsh_msg("wmin_data=%g wmax_data=%g",wmin_data,wmax_data);
2306 size_fit=cpl_table_get_nrow(resp_fit_points);
2307 //cpl_table_save(resp_fit_points,NULL,NULL,"pippo.fits",CPL_IO_DEFAULT);
2308
2309 pflux=cpl_table_get_data_double(tab,"response");
2310 /* remove points that have either value NAN or INF */
2311 for(i=0;i<size_data;i++) {
2312 if(isnan(pflux[i])) {
2313 cpl_table_set_invalid(tab,"response",i);
2314 }
2315 if(isinf(pflux[i])) {
2316
2317 cpl_table_set_invalid(tab,"response",i);
2318 }
2319 }
2320
2321 /* check that the sampling points are not falling in any of the high abs windows */
2322 if (phigh != NULL) {
2323 xsh_msg("Flag High Absorption Regions" );
2324 for (; phigh->lambda_min != 0.; phigh++) {
2325 xsh_msg("Flag [%g,%g]",phigh->lambda_min,phigh->lambda_max);
2326 for (i = 0; i < size_data; i++) {
2327 if ( (wave[i] >= phigh->lambda_min && wave[i] <= phigh->lambda_max) &&
2328 (wave[i] >= wmin_data && wave[i] <= wmax_data) ){
2329 cpl_table_set_invalid(tab,"wave", i);
2330 }
2331 }
2332 }
2333 }
2334 //cpl_table_erase_invalid(tab);
2335
2336 check(wmin_fit=cpl_table_get_column_min(resp_fit_points,"LAMBDA"));
2337 check(wmax_fit=cpl_table_get_column_max(resp_fit_points,"LAMBDA"));
2338
2339 cpl_table_and_selected_double(resp_fit_points,"LAMBDA",CPL_NOT_LESS_THAN,wmin_data);
2340 cpl_table_and_selected_double(resp_fit_points,"LAMBDA",CPL_NOT_GREATER_THAN,wmax_data);
2341 ext_fit=cpl_table_extract_selected(resp_fit_points);
2342 //cpl_table_save(tab,NULL,NULL,"resp_data.fits",CPL_IO_DEFAULT);
2343 check(wmin_fit=cpl_table_get_column_min(ext_fit,"LAMBDA"));
2344 check(wmax_fit=cpl_table_get_column_max(ext_fit,"LAMBDA"));
2345 xsh_msg("wmin_fit=%g wmax_fit=%g",wmin_fit,wmax_fit);
2346
2347 size_fit=cpl_table_get_nrow(ext_fit);
2348 //xsh_msg("size_fit=%d wstp_fit=%g",size_fit,wstp_fit);
2349 imin=0;
2350 if(wmin_fit>wmin_data) {
2351 //xsh_msg("wmin_fit>wmin_data");
2352 //size_fit+=1;
2353 imin=1;
2354 }
2355 imax=size_fit-1;
2356 if(wmax_fit<wmax_data) {
2357 //xsh_msg("wmax_fit<wmax_data");
2358 size_fit+=1;
2359 imax=size_fit-1;
2360 }
2361 xsh_msg("size_fit=%d",size_fit);
2362
2363 xsh_msg("imin=%d imax=%d",imin,imax);
2364 XSH_CALLOC( xfit, double, size_fit) ;
2365 XSH_CALLOC( yfit, double, size_fit) ;
2366
2367 if(wmin_fit>wmin_data) {
2368 xsh_msg("wmin_fit>wmin_data");
2369
2370 nsel=cpl_table_and_selected_double(tab,"wave",CPL_NOT_GREATER_THAN,wmin_data+wrange);
2371 if(nsel==0) {
2372 xsh_msg("Problem to get spline fit sampling points");
2373 xsh_msg("Possibly XSH_HIGH_ABS_WIN table wave ranges incompatible with RESP_FIT_POINTS_CAT table");
2374 }
2375 ext_data=cpl_table_extract_selected(tab);
2376 cpl_table_select_all(tab);
2377 if( cpl_table_has_valid(ext_data, "response") > 0 ) {
2378 check(med=cpl_table_get_column_median(ext_data,"response"));
2379 } else {
2380 med=0;
2381 }
2382 xfit[0]=wmin_data;
2383 yfit[0]=med;
2384 //xsh_msg("xfit=%g yfit=%g",wmin_data,med);
2385 xsh_free_table(&ext_data);
2386
2387 }
2388 /*
2389 xsh_msg("wmin_data=%g",wmin_data);
2390 xsh_msg("wmin_fit=%g",wmin_fit);
2391 xsh_msg("wmax_data=%g",wmax_data);
2392 xsh_msg("wmax_fit=%g",wmax_fit);
2393 xsh_msg("imin=%d imax=%d",imin,imax);
2394 */
2395 int n_invalid=0;
2396 //int n_rows=cpl_table_get_nrow(tab);
2397 //xsh_print_rec_status(0);
2398 imax = (imax <= resp_fit_points_n-1) ? imax : resp_fit_points_n-1;
2399 for(i=imin;i<=imax;i++) {
2400 check(cpl_table_and_selected_double(tab,"wave",CPL_NOT_LESS_THAN,plambda[i]-wrange));
2401 check(nsel=cpl_table_and_selected_double(tab,"wave",CPL_NOT_GREATER_THAN,plambda[i]+wrange));
2402 check(n_invalid=cpl_table_count_invalid(tab,"wave"));
2403 //xsh_msg("lambda start: %g end:%g",plambda[i]-wrange,plambda[i]+wrange);
2404 n_invalid=cpl_table_count_invalid(tab,"response");
2405 //xsh_msg("n_sel=%d n_rows=%d n_wave=%d",nsel, n_rows,n_invalid);
2406
2407 xfit[i]=plambda[i];
2408 //xsh_msg("n_sel=%d n_rows=%d n_resp=%d",nsel, n_rows,n_invalid);
2409 check(ext_data=cpl_table_extract_selected(tab));
2410 nsel=cpl_table_get_nrow(ext_data);
2411 n_invalid=cpl_table_count_invalid(ext_data,"response");
2412 //xsh_msg("n_sel=%d n_rows=%d n_wave=%d",nsel, n_rows,n_invalid);
2413 if(nsel>0 && n_invalid < nsel) {
2414
2415 //n_invalid=cpl_table_count_invalid(ext_data,"response");
2416 //xsh_msg("2n_resp=%d",n_invalid);
2417 //n_invalid=cpl_table_count_invalid(ext_data,"wave");
2418 //xsh_msg("2n_wave=%d",n_invalid);
2419 //n_rows=cpl_table_get_nrow(ext_data);
2420 //xsh_msg("2n_rows=%d",n_rows);
2421 //xsh_msg("ext_data nrows: %d",cpl_table_get_nrow(ext_data));
2422 //xsh_msg("wmin=%g wmax=%g",plambda[i]-wrange,plambda[i]+wrange);
2423 //cpl_table_dump_structure(ext_data,stdout);
2424 //xsh_print_rec_status(1);
2425 check(med=cpl_table_get_column_median(ext_data,"response"));
2426 //xsh_print_rec_status(2);
2427 yfit[i]=med;
2428 flux_save=med;
2429 //xsh_msg("xfit=%g yfit=%g",xfit[i],yfit[i]);
2430
2431 } else {
2432 yfit[i]=flux_save;
2433 }
2434 //xsh_print_rec_status(16);
2435 check(cpl_table_select_all(tab));
2436 //xsh_print_rec_status(17);
2437 xsh_free_table(&ext_data);
2438 }
2439
2440 //xsh_print_rec_status(18);
2441 cpl_table_select_all(tab);
2442
2443 if(wmax_fit<wmax_data) {
2444
2445 //xsh_msg("wmax_fit<wmax_data");
2446 cpl_table_and_selected_double(tab,"wave",CPL_NOT_LESS_THAN,wmax_data-wrange);
2447 ext_data=cpl_table_extract_selected(tab);
2448 cpl_table_select_all(tab);
2449 if( cpl_table_has_valid(ext_data, "response") > 0 ) {
2450 check(med=cpl_table_get_column_median(ext_data,"response"));
2451 } else {
2452 med=0;
2453 }
2454 xfit[size_fit-1]=wmax_data;
2455
2456 yfit[size_fit-1]=med;
2457 //xsh_msg("xfit=%g yfit=%g",wmax_data,med);
2458 xsh_free_table(&ext_data);
2459 }
2460
2461 /*
2462 tab=cpl_table_new(size_fit);
2463 cpl_table_wrap_double(tab,xfit,"xfit");
2464 check(cpl_table_wrap_double(tab,yfit,"yfit"));
2465 cpl_table_save(tab,NULL,NULL,"resp_data_fit.fits",CPL_IO_DEFAULT);
2466 */
2467 //xsh_msg("size_fit=%d size_data=%d",size_fit,size_data);
2468 /* as xsh_bspline_interpolate_data_at_pos allocates memory for flux vector
2469 * and we store it in an already allocated structure we need to deallocate
2470 * the corresponding memory first: better would be to replace the res->flux
2471 * values by the newly computed ones
2472 */
2473 cpl_free(res->flux);
2474 check(res->flux=xsh_bspline_interpolate_data_at_pos(xfit,yfit,size_fit,res->lambda,size_data));
2475 //xsh_star_flux_list_save(res,"fit_response.fits", "TEST" ) ;
2476
2477 cleanup:
2478 XSH_FREE(xfit);
2479 XSH_FREE(yfit);
2480 xsh_free_table(&ext_fit);
2481 xsh_free_table(&ext_data);
2482 cpl_table_unwrap(tab,"wave");
2483 cpl_table_unwrap(tab,"response");
2484 cpl_free(tab);
2485 return res;
2486}
2487static xsh_star_flux_list *
2489{
2490 xsh_star_flux_list * result=NULL;
2491 size_t n = 0;
2492 size_t order = 4;
2493 size_t ncoeffs = 0;
2494 size_t nbreak = 0;
2495
2496 size_t i, j;
2497 gsl_bspline_workspace *bw;
2498 gsl_vector *B;
2499 double dy;
2500 gsl_rng *r;
2501 gsl_vector *c, *w;
2502 gsl_vector * x, *y;
2503 gsl_matrix *X, *cov;
2504 gsl_multifit_linear_workspace *mw;
2505 double chisq=0, Rsq=0, dof=0;
2506 //double tss;
2507 //double wmin=0;
2508 //double wmax=0;
2509 //double wstep=0;
2510 double* wave = NULL;
2511 double* response = NULL;
2512 double* pwav = NULL;
2513 double* pfit = NULL;
2514 //int kh = 0;
2515 double dump_factor = 1.e10;
2516 //cpl_table* tab_response = NULL;
2517 cpl_table* tab_resp_fit = NULL;
2518 //const char* fname = NULL;
2519
2520 /* set optimal number of coeffs for each arm */
2521 if (xsh_instrument_get_arm(inst) == XSH_ARM_UVB) {
2522 ncoeffs = 21;
2523 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_VIS) {
2524 ncoeffs = 16;
2525 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_NIR) {
2526 ncoeffs = 6;
2527 }
2528 nbreak = ncoeffs + 2 - order;
2529
2530 n = ref_std_star_list->size ;
2531 wave = ref_std_star_list->lambda ;
2532 response = ref_std_star_list->flux ;
2533 //wmin = *wave ;
2534 //wmax = *(wave+n-1) ;
2535 //wstep = (wmax-wmin)/(n-1) ;
2536
2537 gsl_rng_env_setup();
2538 r = gsl_rng_alloc(gsl_rng_default);
2539
2540 /* allocate a cubic bspline workspace (ORDER = order) */
2541 bw = gsl_bspline_alloc(order, nbreak);
2542 B = gsl_vector_alloc(ncoeffs);
2543
2544 x = gsl_vector_alloc(n);
2545 y = gsl_vector_alloc(n);
2546 X = gsl_matrix_alloc(n, ncoeffs);
2547 c = gsl_vector_alloc(ncoeffs);
2548 w = gsl_vector_alloc(n);
2549 cov = gsl_matrix_alloc(ncoeffs, ncoeffs);
2550 mw = gsl_multifit_linear_alloc(n, ncoeffs);
2551
2552 //printf("#m=0,S=0\n");
2553 /* this is the data to be fitted */
2554 for (i = 0; i < n; ++i) {
2555 double sigma;
2556 double xi = (double) wave[i];
2557 double yi = (double) response[i];
2558
2559 sigma = 0.001 * yi;
2560 dy = gsl_ran_gaussian(r, sigma);
2561 yi += dy;
2562
2563 gsl_vector_set(x, i, xi);
2564
2565 if(isnan(yi) || isinf(yi)) {
2566 gsl_vector_set(y, i, 0);
2567 gsl_vector_set(w, i, 1.0 / dump_factor);
2568 //xsh_msg("wave=%g y=%g w=%g",xi,yi,gsl_vector_get(w, i));
2569 } else {
2570 gsl_vector_set(y, i, yi);
2571 gsl_vector_set(w, i, 1.0 / (sigma * sigma));
2572 //xsh_msg("wave=%g y=%g w=%g",xi,yi,gsl_vector_get(w, i));
2573 }
2574 //printf("%f %g\n", xi, yi);
2575 }
2576
2577 if (phigh != NULL) {
2578
2579 xsh_msg("Flag High Absorption Regions" );
2580 for (; phigh->lambda_min != 0.; phigh++) {
2581 xsh_msg("Flag [%g,%g]",phigh->lambda_min,phigh->lambda_max);
2582 for (i = 0; i < n; i++) {
2583 if (wave[i] >= phigh->lambda_min && wave[i] <= phigh->lambda_max) {
2584 //gsl_vector_set(w, i, gsl_vector_get(w, i) / dump_factor);
2585 gsl_vector_set(w, i, 1.0 / dump_factor);
2586 //xsh_msg("w=%g",gsl_vector_get(w, i));
2587 }
2588 }
2589 }
2590 }
2591
2592 /* use uniform breakpoints on [0, 15] */
2593 gsl_bspline_knots_uniform(wave[0], wave[n - 1], bw);
2594
2595 /* construct the fit matrix X */
2596 for (i = 0; i < n; ++i) {
2597 double xi = gsl_vector_get(x, i);
2598
2599 /* compute B_j(xi) for all j */
2600 gsl_bspline_eval(xi, B, bw);
2601
2602 /* fill in row i of X */
2603 for (j = 0; j < ncoeffs; ++j) {
2604 double Bj = gsl_vector_get(B, j);
2605 gsl_matrix_set(X, i, j, Bj);
2606 }
2607 }
2608
2609 /* do the fit */
2610 gsl_multifit_wlinear(X, w, y, c, cov, &chisq, mw);
2611
2612 dof = n - ncoeffs;
2613 /*
2614 tss = gsl_stats_wtss(w->data, 1, y->data, 1, y->size);
2615 Rsq = 1.0 - chisq / tss;
2616 */
2617 printf("chisq/dof = %e, Rsq = %f\n", chisq / dof, Rsq);
2618
2619 tab_resp_fit = cpl_table_new(n);
2620 cpl_table_new_column(tab_resp_fit, "wave", CPL_TYPE_DOUBLE);
2621 cpl_table_new_column(tab_resp_fit, "fit", CPL_TYPE_DOUBLE);
2622 cpl_table_fill_column_window_double(tab_resp_fit, "wave", 0, n, 0);
2623 cpl_table_fill_column_window_double(tab_resp_fit, "fit", 0, n, 0);
2624 pwav = cpl_table_get_data_double(tab_resp_fit, "wave");
2625 pfit = cpl_table_get_data_double(tab_resp_fit, "fit");
2627 /* output the smoothed curve */
2628 {
2629 double xi, yi, yerr;
2630 //printf("#m=1,S=0\n");
2631 for (i = 0; i < n; i++) {
2632 xi = (double) wave[i];
2633 gsl_bspline_eval(xi, B, bw);
2634 gsl_multifit_linear_est(B, c, cov, &yi, &yerr);
2635 //printf("%f %g\n", xi, yi);
2636 pwav[i] = xi;
2637 pfit[i] = yi;
2638 result->lambda[i]=xi;
2639 result->flux[i]=yi;
2640 }
2641 }
2642 //cpl_table_save(tab_resp_fit, NULL, NULL, "resp_fit.fits", CPL_IO_DEFAULT);
2643
2644
2645 //cleanup:
2646 gsl_rng_free(r);
2647 gsl_bspline_free(bw);
2648 gsl_vector_free(B);
2649 gsl_vector_free(x);
2650 gsl_vector_free(y);
2651 gsl_matrix_free(X);
2652 gsl_vector_free(c);
2653 gsl_vector_free(w);
2654 gsl_matrix_free(cov);
2655 gsl_multifit_linear_free(mw);
2656 xsh_free_table(&tab_resp_fit);
2657
2658 return result;
2659}
2660
2661
2662
2663double *
2664xsh_bspline_interpolate_data_at_pos(double* w_data, double* f_data,
2665 const int n_data,
2666 double* w_pos, const int n_pos)
2667{
2668 double * result=NULL;
2669 double xi, yi;
2670 int i_min = 0;
2671 int i_max = n_pos;
2672 gsl_interp_accel *acc = gsl_interp_accel_alloc ();
2673 int i=0;
2674 xsh_msg("w_pos[0]=%g w_data[0]=%g",w_pos[0],w_data[0]);
2675 xsh_msg("w_pos[n_pos-1]=%g w_data[n_data-1]=%g",w_pos[n_pos-1],w_data[n_data-1]);
2676 cpl_ensure(w_pos[0] >= w_data[0], CPL_ERROR_ILLEGAL_INPUT,NULL);
2677 cpl_ensure(w_pos[n_pos-1] <= w_data[n_data-1], CPL_ERROR_ILLEGAL_INPUT,NULL);
2678
2679 gsl_spline *spline = gsl_spline_alloc (gsl_interp_cspline, n_data);
2680
2681 gsl_spline_init (spline, w_data, f_data, n_data);
2682
2683
2684 result=cpl_calloc(n_pos, sizeof(double));
2685
2686 if(w_pos[0] == w_data[0]) {
2687 result[0] = f_data[0];
2688 i_min = 1;
2689 }
2690
2691 if(w_pos[n_pos-1] == w_data[n_data-1]) {
2692 result[n_pos-1] = f_data[n_data-1];
2693 i_max = n_pos-1;
2694 }
2695
2696 for (i = i_min; i < i_max; i ++) {
2697 xi = w_pos[i];
2698 yi = gsl_spline_eval (spline, xi, acc);
2699 //printf ("%g %g\n", xi, yi);
2700 result[i]=yi;
2701 }
2702
2703 gsl_spline_free (spline);
2704 gsl_interp_accel_free (acc);
2705
2706 return result;
2707}
2708
2709
2710
2711
2712
2713
2714double *
2715xsh_bspline_fit_smooth_data(double* wave, double* flux,const int size,
2716 HIGH_ABS_REGION * phigh,xsh_instrument* inst, const int fit_region)
2717{
2718 double * result=NULL;
2719 size_t n = 0;
2720 size_t order = 4;
2721 size_t ncoeffs = 0;
2722 size_t nbreak = 0;
2723
2724 size_t i, j;
2725 gsl_bspline_workspace *bw;
2726 gsl_vector *B;
2727 double dy;
2728 gsl_rng *r;
2729 gsl_vector *c, *w;
2730 gsl_vector * x, *y;
2731 gsl_matrix *X, *cov;
2732 gsl_multifit_linear_workspace *mw;
2733 double chisq=0, Rsq=0, dof=0;
2734 //double tss;
2735 //double wmin=0;
2736 //double wmax=0;
2737 //double wstep=0;
2738 //double* wave = NULL;
2739 //double* response = NULL;
2740 double* pwav = NULL;
2741 double* pfit = NULL;
2742 //int kh = 0;
2743 double dump_factor_in = 1.e10;
2744 double dump_factor_ou = 1.e10;
2745 //cpl_table* tab_response = NULL;
2746 cpl_table* tab_resp_fit = NULL;
2747 //const char* fname = NULL;
2748 double dump_factor=1.e10;
2749
2750 if(fit_region){
2751 dump_factor_in = 1.;
2752 dump_factor_ou = 1.e10;
2753 } else {
2754 dump_factor_in = 1.e10;
2755 dump_factor_ou = 1;
2756 }
2757 /* set optimal number of coeffs for each arm */
2758 if (xsh_instrument_get_arm(inst) == XSH_ARM_UVB) {
2759 ncoeffs = 21;
2760 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_VIS) {
2761 ncoeffs = 16;
2762 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_NIR) {
2763 ncoeffs = 6;
2764 }
2765 nbreak = ncoeffs + 2 - order;
2766
2767 n = size ;
2768 //wave = lambda ;
2769 //response = flux ;
2770 //wmin = wave[0] ;
2771 //wmax = wave[n-1] ;
2772 //wstep = (wmax-wmin)/(n-1) ;
2773
2774 gsl_rng_env_setup();
2775 r = gsl_rng_alloc(gsl_rng_default);
2776
2777 /* allocate a cubic bspline workspace (ORDER = order) */
2778 bw = gsl_bspline_alloc(order, nbreak);
2779 B = gsl_vector_alloc(ncoeffs);
2780
2781 x = gsl_vector_alloc(n);
2782 y = gsl_vector_alloc(n);
2783 X = gsl_matrix_alloc(n, ncoeffs);
2784 c = gsl_vector_alloc(ncoeffs);
2785 w = gsl_vector_alloc(n);
2786 cov = gsl_matrix_alloc(ncoeffs, ncoeffs);
2787 mw = gsl_multifit_linear_alloc(n, ncoeffs);
2788
2789 //printf("#m=0,S=0\n");
2790 /* this is the data to be fitted */
2791 for (i = 0; i < n; ++i) {
2792 double sigma;
2793 double xi = wave[i];
2794 double yi = flux[i];
2795 sigma = 0.001 * yi;
2796 //sigma = 0.1 * sqrt(fabs(yi));
2797 dy = gsl_ran_gaussian(r, sigma);
2798 yi += dy;
2799
2800 gsl_vector_set(x, i, xi);
2801
2802 if(isnan(yi) || isinf(yi)) {
2803 gsl_vector_set(y, i, 0);
2804 gsl_vector_set(w, i, 1.0 / dump_factor);
2805 //xsh_msg("wave=%g y=%g w=%g",xi,yi,gsl_vector_get(w, i));
2806 } else {
2807 gsl_vector_set(y, i, yi);
2808 gsl_vector_set(w, i, 1.0 / (sigma * sigma));
2809 //xsh_msg("wave=%g y=%g w=%g",xi,yi,gsl_vector_get(w, i));
2810 }
2811
2812 //printf("%f %g\n", xi, yi);
2813 }
2814 printf("Dump factor in %g out %g\n", dump_factor_in, dump_factor_ou);
2815 if (phigh != NULL) {
2816
2817 xsh_msg("Flag High Absorption Regions" );
2818 for (; phigh->lambda_min != 0.; phigh++) {
2819 xsh_msg("Flag [%g,%g]",phigh->lambda_min,phigh->lambda_max);
2820 for (i = 0; i < n; i++) {
2821
2822 if (wave[i] >= phigh->lambda_min && wave[i] <= phigh->lambda_max) {
2823 //xsh_msg("wave in %g",wave[i]);
2824 gsl_vector_set(w, i, gsl_vector_get(w, i) / dump_factor_in);
2825 //xsh_msg("inp wave=%g flux %g err=%g",wave[i],gsl_vector_get(y, i), gsl_vector_get(w, i) / dump_factor_in);
2826 } else {
2827 //xsh_msg("wave out %g",wave[i]);
2828 gsl_vector_set(w, i, gsl_vector_get(w, i) / dump_factor_ou);
2829 //xsh_msg("out wave %g flux %g err=%g",wave[i],gsl_vector_get(y, i), gsl_vector_get(w, i) / dump_factor_ou);
2830 }
2831 }
2832 }
2833 }
2834
2835 /* use uniform breakpoints on [0, 15] */
2836 gsl_bspline_knots_uniform(wave[0], wave[n - 1], bw);
2837
2838 /* construct the fit matrix X */
2839 for (i = 0; i < n; ++i) {
2840 double xi = gsl_vector_get(x, i);
2841
2842 /* compute B_j(xi) for all j */
2843 gsl_bspline_eval(xi, B, bw);
2844
2845 /* fill in row i of X */
2846 for (j = 0; j < ncoeffs; ++j) {
2847 double Bj = gsl_vector_get(B, j);
2848 gsl_matrix_set(X, i, j, Bj);
2849 }
2850 }
2851
2852 /* do the fit */
2853 gsl_multifit_wlinear(X, w, y, c, cov, &chisq, mw);
2854
2855 dof = n - ncoeffs;
2856 /*
2857 tss = gsl_stats_wtss(w->data, 1, y->data, 1, y->size);
2858 Rsq = 1.0 - chisq / tss;
2859 */
2860 printf("chisq/dof = %e, Rsq = %f\n", chisq / dof, Rsq);
2861
2862 tab_resp_fit = cpl_table_new(n);
2863 cpl_table_new_column(tab_resp_fit, "wave", CPL_TYPE_DOUBLE);
2864 cpl_table_new_column(tab_resp_fit, "fit", CPL_TYPE_DOUBLE);
2865 cpl_table_fill_column_window_double(tab_resp_fit, "wave", 0, n, 0);
2866 cpl_table_fill_column_window_double(tab_resp_fit, "fit", 0, n, 0);
2867 pwav = cpl_table_get_data_double(tab_resp_fit, "wave");
2868 pfit = cpl_table_get_data_double(tab_resp_fit, "fit");
2869 result=cpl_calloc(n, sizeof(double));
2870 /* output the smoothed curve */
2871 {
2872 double xi, yi, yerr;
2873 //printf("#m=1,S=0\n");
2874 for (i = 0; i < n; i++) {
2875 xi = (double) wave[i];
2876 gsl_bspline_eval(xi, B, bw);
2877 gsl_multifit_linear_est(B, c, cov, &yi, &yerr);
2878 //printf("%f %g\n", xi, yi);
2879 pwav[i] = xi;
2880 pfit[i] = yi;
2881 //result->lambda[i]=xi;
2882 result[i]=yi;
2883 }
2884 }
2885 //cpl_table_save(tab_resp_fit, NULL, NULL, "resp_fit.fits", CPL_IO_DEFAULT);
2886
2887
2888 //cleanup:
2889 xsh_free_table(&tab_resp_fit);
2890 gsl_rng_free(r);
2891 gsl_bspline_free(bw);
2892 gsl_vector_free(B);
2893 gsl_vector_free(x);
2894 gsl_vector_free(y);
2895 gsl_matrix_free(X);
2896 gsl_vector_free(c);
2897 gsl_vector_free(w);
2898 gsl_matrix_free(cov);
2899 gsl_multifit_linear_free(mw);
2900
2901
2902 return result;
2903}
2904
2905
2906
2907
2908
2909/* not uniform data distribution */
2910double *
2911xsh_bspline_fit_smooth_data2(double* wave, double* flux,const int size,
2912 HIGH_ABS_REGION * phigh,xsh_instrument* inst, const int fit_region)
2913{
2914 double * result=NULL;
2915 size_t n = 0;
2916 size_t order = 4;
2917 size_t ncoeffs = 0;
2918 size_t nbreak = 0;
2919
2920 size_t i, j;
2921 gsl_bspline_workspace *bw;
2922 gsl_vector *B;
2923 gsl_vector *Bkpts;
2924 double dy;
2925 gsl_rng *r;
2926 gsl_vector *c, *w;
2927 gsl_vector * x, *y;
2928 gsl_matrix *X, *cov;
2929 gsl_multifit_linear_workspace *mw;
2930 double chisq=0, Rsq=0, dof=0;
2931 //double tss;
2932 //double wmin=0;
2933 //double wmax=0;
2934 //double wstep=0;
2935 //double* wave = NULL;
2936 //double* response = NULL;
2937 double* pwav = NULL;
2938 double* pfit = NULL;
2939 //int kh = 0;
2940 //double dump_factor_in = 1.e10;
2941 //double dump_factor_ou = 1.e10;
2942 //cpl_table* tab_response = NULL;
2943 cpl_table* tab_resp_fit = NULL;
2944 //const char* fname = NULL;
2945 double dump_factor=1.e10;
2946 double *Bkpts_ptr;
2947
2948 /* set optimal number of coeffs for each arm */
2949 if (xsh_instrument_get_arm(inst) == XSH_ARM_UVB) {
2950 ncoeffs = 21;
2951 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_VIS) {
2952 ncoeffs = 16;
2953 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_NIR) {
2954 ncoeffs = 12;
2955 } else {
2956 xsh_msg("instrument arm not set");
2957 abort();
2958 }
2959 nbreak = ncoeffs + 2 - order;
2960
2961 n = size ;
2962 //wave = lambda ;
2963 //response = flux ;
2964 //wmin = wave[0] ;
2965 //wmax = wave[n-1] ;
2966 //wstep = (wmax-wmin)/(n-1) ;
2967 gsl_rng_env_setup();
2968 r = gsl_rng_alloc(gsl_rng_default);
2969
2970 /* allocate a cubic bspline workspace (ORDER = order) */
2971 bw = gsl_bspline_alloc(order, nbreak);
2972
2973 B = gsl_vector_alloc(ncoeffs);
2974
2975 Bkpts = gsl_vector_alloc(nbreak);
2976
2977
2978 x = gsl_vector_alloc(n);
2979 y = gsl_vector_alloc(n);
2980 X = gsl_matrix_alloc(n, ncoeffs);
2981 c = gsl_vector_alloc(ncoeffs);
2982 w = gsl_vector_alloc(n);
2983
2984 cov = gsl_matrix_alloc(ncoeffs, ncoeffs);
2985
2986 mw = gsl_multifit_linear_alloc(n, ncoeffs);
2987
2988
2989 //printf("#m=0,S=0\n");
2990 /* this is the data to be fitted */
2991 for (i = 0; i < n; ++i) {
2992 double sigma;
2993 double xi = wave[i];
2994 double yi = flux[i];
2995
2996 //sigma = 0.1 * sqrt(fabs(yi));
2997 sigma = 0.001 * yi;
2998 dy = gsl_ran_gaussian(r, sigma);
2999 yi += dy;
3000
3001 gsl_vector_set(x, i, xi);
3002 if(isnan(yi) || isinf(yi)) {
3003 gsl_vector_set(y, i, 0);
3004 gsl_vector_set(w, i, 1.0 / dump_factor);
3005 //xsh_msg("wave=%g y=%g w=%g",xi,yi,gsl_vector_get(w, i));
3006 } else {
3007 gsl_vector_set(y, i, yi);
3008 gsl_vector_set(w, i, 1.0 / (sigma * sigma));
3009 //xsh_msg("wave=%g y=%g w=%g",xi,yi,gsl_vector_get(w, i));
3010 }
3011 //gsl_vector_set(y, i, yi);
3012 //gsl_vector_set(w, i, 1.0 / (sigma * sigma));
3013 //xsh_msg("x=%g y=%g er=%g w=%g",xi,yi,sigma,1.0/(sigma*sigma));
3014
3015 //printf("%f %g\n", xi, yi);
3016 }
3017
3018 /*
3019 printf("Dump factor in %g out %g\n", dump_factor_in, dump_factor_ou);
3020 if (phigh != NULL) {
3021
3022 xsh_msg("Flag High Absorption Regions" );
3023 for (kh = 0; phigh->lambda_min != 0.; phigh++) {
3024 xsh_msg("Flag [%g,%g]",phigh->lambda_min,phigh->lambda_max);
3025 for (i = 0; i < n; i++) {
3026
3027 if (wave[i] >= phigh->lambda_min && wave[i] <= phigh->lambda_max) {
3028 //xsh_msg("wave in %g",wave[i]);
3029 gsl_vector_set(w, i, gsl_vector_get(w, i) / dump_factor_in);
3030 //xsh_msg("inp wave=%g flux %g err=%g",wave[i],gsl_vector_get(y, i), gsl_vector_get(w, i) / dump_factor_in);
3031 } else {
3032 //xsh_msg("wave out %g",wave[i]);
3033 gsl_vector_set(w, i, gsl_vector_get(w, i) / dump_factor_ou);
3034 //xsh_msg("out wave %g flux %g err=%g",wave[i],gsl_vector_get(y, i), gsl_vector_get(w, i) / dump_factor_ou);
3035 }
3036 }
3037 }
3038 }
3039 */
3040
3041 /* use uniform breakpoints on [0, 15] */
3042 Bkpts_ptr=gsl_vector_ptr(Bkpts,0);
3043 int nfit_div_nbreak=n/nbreak;
3044 //xsh_msg("nbreak=%d nfit_div_nbreak=%d",nbreak,nfit_div_nbreak);
3045
3046 for(i=0;i<nbreak;i++) {
3047 Bkpts_ptr[i]=wave[i*nfit_div_nbreak];
3048 /*
3049 xsh_msg("breaks=%g ival=%d wave=%g flux=%g",
3050 Bkpts_ptr[i],i*nfit_div_nbreak,wave[i*nfit_div_nbreak],flux[i*nfit_div_nbreak]);
3051 */
3052 }
3053 Bkpts_ptr[0]=wave[0];
3054 Bkpts_ptr[nbreak-1]=wave[n-1];
3055 gsl_bspline_knots(Bkpts, bw);
3056
3057
3058 /* construct the fit matrix X */
3059 for (i = 0; i < n; ++i) {
3060 double xi = gsl_vector_get(x, i);
3061
3062 /* compute B_j(xi) for all j */
3063 gsl_bspline_eval(xi, B, bw);
3064
3065 /* fill in row i of X */
3066 for (j = 0; j < ncoeffs; ++j) {
3067 double Bj = gsl_vector_get(B, j);
3068 gsl_matrix_set(X, i, j, Bj);
3069 }
3070 }
3071
3072
3073 /* do the fit */
3074 gsl_multifit_wlinear(X, w, y, c, cov, &chisq, mw);
3075
3076 dof = n - ncoeffs;
3077 /*
3078 tss = gsl_stats_wtss(w->data, 1, y->data, 1, y->size);
3079 Rsq = 1.0 - chisq / tss;
3080 */
3081 printf("chisq/dof = %e, Rsq = %f\n", chisq / dof, Rsq);
3082
3083 tab_resp_fit = cpl_table_new(n);
3084 cpl_table_new_column(tab_resp_fit, "wave", CPL_TYPE_DOUBLE);
3085 cpl_table_new_column(tab_resp_fit, "fit", CPL_TYPE_DOUBLE);
3086 cpl_table_fill_column_window_double(tab_resp_fit, "wave", 0, n, 0);
3087 cpl_table_fill_column_window_double(tab_resp_fit, "fit", 0, n, 0);
3088 pwav = cpl_table_get_data_double(tab_resp_fit, "wave");
3089 pfit = cpl_table_get_data_double(tab_resp_fit, "fit");
3090 result=cpl_calloc(n, sizeof(double));
3091 /* output the smoothed curve */
3092 {
3093 double xi, yi, yerr;
3094 //printf("#m=1,S=0\n");
3095 for (i = 0; i < n; i++) {
3096 xi = (double) wave[i];
3097 gsl_bspline_eval(xi, B, bw);
3098 gsl_multifit_linear_est(B, c, cov, &yi, &yerr);
3099 //printf("%f %g\n", xi, yi);
3100 pwav[i] = xi;
3101 pfit[i] = yi;
3102 //result->lambda[i]=xi;
3103 result[i]=yi;
3104 }
3105 }
3106 //cpl_table_save(tab_resp_fit, NULL, NULL, "resp_fit.fits", CPL_IO_DEFAULT);
3107
3108
3109
3110 //cleanup:
3111 xsh_free_table(&tab_resp_fit);
3112 gsl_rng_free(r);
3113 gsl_bspline_free(bw);
3114 gsl_vector_free(B);
3115 gsl_vector_free(Bkpts);
3116 gsl_vector_free(x);
3117 gsl_vector_free(y);
3118 gsl_matrix_free(X);
3119 gsl_vector_free(c);
3120 gsl_vector_free(w);
3121 gsl_matrix_free(cov);
3122 gsl_multifit_linear_free(mw);
3123
3124
3125 return result;
3126}
3127
3128
3145cpl_frame * xsh_compute_response2( cpl_frame * obs_std_star,
3146 cpl_frame * flux_std_star_cat,
3147 cpl_frame * atmos_ext,
3148 cpl_frame* high_abs,
3149 cpl_frame* resp_fit_points,
3150 cpl_frame* tell_mod_cat,
3152 double exptime,
3153 const int tell_corr )
3154{
3155 /* TODO: exptime should not appear in this function interface as it can be retrieved from input frame */
3156 cpl_frame* result = NULL;
3157
3158 XSH_ASSURE_NOT_NULL( obs_std_star ) ;
3159 XSH_ASSURE_NOT_NULL( flux_std_star_cat ) ;
3161
3162 double dRA = 0;
3163 double dDEC = 0;
3164 double airmass = 0;
3165
3166 double wmin = 0;
3167 double wmax = 0;
3168 double wstep = 0;
3169 int naxis1 = 0;
3170 double cdelt1 = 0;
3171 const char* filename = NULL;
3172 cpl_propertylist* plist = NULL;
3173 int is_complete=0;
3174 cpl_frame* ipol_ref_std_star_frame=NULL;
3175 xsh_star_flux_list * ref_std_star_list = NULL;
3176 cpl_frame* frm_tmp=NULL;
3177 xsh_star_flux_list * obs_std_star_list = NULL;
3178 xsh_spectrum* obs_spectrum=NULL;
3179 cpl_table* tbl_shift_std_spectrum=NULL;
3180 cpl_frame* shift_std_star_frame=NULL;
3181 const char* tbl_shift_std_fname="shift_flux_std_star.fits";
3182 HIGH_ABS_REGION * phigh = NULL;
3183 cpl_frame* ipol_shift_std_star_frame=NULL;
3184 xsh_star_flux_list * shift_std_star_list = NULL;
3185 xsh_star_flux_list * corr_obs_std_star_list = NULL;
3186 xsh_star_flux_list * response =NULL;
3187 xsh_star_flux_list * response_fit =NULL;
3188 xsh_rv_ref_wave_param* rv_ref_wave=NULL;
3189 char resp_obs_std_star_fname[256];
3190 cpl_frame* obs_std_star_resp=NULL;
3191 cpl_table* resp_fit_points_tbl=NULL;
3192 cpl_table* tbl_ref_std_spectrum = NULL;
3193
3194 /* Get wmin,wmax,wstep to re-sample ref std spectrum at same step as observed one */
3195
3196 filename = cpl_frame_get_filename(obs_std_star);
3197 plist = cpl_propertylist_load(filename, 0);
3198
3199 naxis1 = xsh_pfits_get_naxis1(plist);
3200 cdelt1 = xsh_pfits_get_cdelt1(plist);
3201 wstep=cdelt1;
3202 wmin = xsh_pfits_get_crval1(plist);
3203 xsh_free_propertylist(&plist);
3204
3205 /* Not to overwrite input spectrum save result on different filename */
3206 filename=cpl_frame_get_filename(obs_std_star);
3207 sprintf(resp_obs_std_star_fname,"resp_%s",xsh_get_basename(filename));
3208 obs_std_star_resp=cpl_frame_duplicate(obs_std_star);
3209 xsh_frame_spectrum_save(obs_std_star_resp,resp_obs_std_star_fname);
3210 xsh_add_temporary_file(resp_obs_std_star_fname);
3211
3212 check(filename=cpl_frame_get_filename(flux_std_star_cat));
3213 plist=cpl_propertylist_load(filename,0);
3214 is_complete=cpl_propertylist_has(plist,"WRANGE");
3215 xsh_free_propertylist(&plist);
3216
3217
3218 wmax = wmin + cdelt1 * naxis1;
3219 //xsh_msg("wmin=%g wmax=%g wstep=%g",wmin,wmax,wstep);
3220 /* Search and eventually load STD star from reference catalog */
3221
3222 /* get RA DEC from obs std, to be able to identify in the ref catalog the STD star spectrum*/
3223 check(xsh_frame_sci_get_ra_dec_airmass(obs_std_star_resp,&dRA,&dDEC,&airmass));
3224 xsh_std_star_id std_star_id=0;
3225
3226
3227 if (CPL_ERROR_NONE
3228 != xsh_parse_catalog_std_stars(flux_std_star_cat, dRA, dDEC,
3229 STAR_MATCH_DEPSILON, &tbl_ref_std_spectrum,&std_star_id)) {
3231 "Problem parsing input STD catalog. For robustness recipe goes on.");
3232 xsh_msg_warning("%s", cpl_error_get_message());
3233 cpl_error_reset();
3234 xsh_free_table(&tbl_ref_std_spectrum);
3235 return NULL;
3236 }
3237
3238 /* for QC we save the ref STD spectrum in a FITS file to be used for comparison */
3239 cpl_frame* ref_std_star_frame=NULL;
3240 const char* tbl_ref_std_fname="ref_flux_std_star.fits";
3241 check(cpl_table_save(tbl_ref_std_spectrum,NULL,NULL,tbl_ref_std_fname,
3242 CPL_IO_DEFAULT));
3243 xsh_add_temporary_file(tbl_ref_std_fname);
3244
3245 check(ref_std_star_frame=xsh_frame_product(tbl_ref_std_fname,"FLUX_STD_STAR",
3246 CPL_FRAME_TYPE_TABLE,
3247 CPL_FRAME_GROUP_PRODUCT,
3248 CPL_FRAME_LEVEL_INTERMEDIATE));
3249
3250 /* re-sample reference STD spectrum on the same sampling pixel base of the observed STD spectrum.
3251 * over the allowed wave ranges. This operation need to conserve flux.QC: verify that after
3252 * re-sampling the re-sampled spectrum overlaps the original one. The re-sampling should be given by a
3253 * (Hermite) spline fit of large enough degree
3254 * */
3255
3256
3257 check(ipol_ref_std_star_frame=xsh_spectrum_interpolate_linear(ref_std_star_frame,wstep,wmin,wmax));
3258
3259
3260 check( ref_std_star_list = xsh_star_flux_list_load( ipol_ref_std_star_frame ) ) ;
3261 xsh_free_frame(&ipol_ref_std_star_frame);
3262 xsh_free_frame(&ref_std_star_frame);
3263
3264 //xsh_star_flux_list_save( ref_std_star_list,"ref_std_star_list.fits", "TEST" ) ;
3265 if( xsh_instrument_get_arm(instrument) == XSH_ARM_UVB && is_complete!=0){
3266 check(xsh_star_flux_list_extrapolate_wave_end(ref_std_star_list,545.));
3267 frm_tmp=xsh_star_flux_list_save( ref_std_star_list,"extrapol_ref_std_star_list.fits", "TEST" ) ;
3268 xsh_free_frame(&frm_tmp);
3269 }
3270
3271 //PIPPO: we moved here telluric correction.
3272 xsh_msg("tell_corr=%d tell_mod_cal=%p",tell_corr,tell_mod_cat);
3273 if(xsh_instrument_get_arm(instrument) != XSH_ARM_UVB && tell_corr == 1 && tell_mod_cat!= NULL) {
3274 xsh_msg("Telluric correction");
3275 cpl_table* tab_res=NULL;
3276 //int next=0;
3277 cpl_size model_idx=0;
3278
3279 check(obs_std_star_list = xsh_star_flux_list_load_spectrum(obs_std_star_resp)) ;
3280 //xsh_star_flux_list_save( obs_std_star_list,"obs_std_star_list.fits", "TEST" ) ;
3281 check( obs_spectrum = xsh_spectrum_load( obs_std_star_resp));
3282 check(tab_res=xsh_telluric_model_eval(tell_mod_cat,obs_spectrum,instrument,
3283 &model_idx));
3284
3285 xsh_spectrum_free(&obs_spectrum);
3286
3287 /*
3288 xsh_msg("response size %d table size %d",
3289 response->size,cpl_table_get_nrow(tab_obs_tell_cor));
3290 xsh_msg("wstep=%g",wstep);
3291 tab_res=xsh_table_resample_uniform(tab_obs_tell_cor,"wave","ratio",wstep);
3292 xsh_msg("response size %d table size %d",
3293 response->size,cpl_table_get_nrow(tab_res));
3294 */
3295 double* pwav=NULL;
3296 double* pflx=NULL;
3297 int i=0;
3298 //cpl_table_dump(tab_res,1,2,stdout);
3299 check(pwav = cpl_table_get_data_double(tab_res, "wavelength"));
3300
3301 check(pflx = cpl_table_get_data_double(tab_res, "ratio"));
3302 /*
3303 xsh_msg("ok1 size_obs=%d size_mod_corr=%d",
3304 obs_std_star_list->size,(int)cpl_table_get_nrow(tab_res));
3305 */
3306 for(i=0;i<obs_std_star_list->size;i++) {
3307 obs_std_star_list->lambda[i]=pwav[i];
3308 obs_std_star_list->flux[i]=pflx[i];
3309 }
3310 xsh_free_table(&tab_res);
3311 //frm_tmp=xsh_star_flux_list_save( obs_std_star_list,"obs_std_star_list_tell.fits", "TEST" ) ;
3312 xsh_free_frame(&frm_tmp);
3313 check(xsh_star_flux_list_to_frame(obs_std_star_list,obs_std_star_resp));
3314 } else {
3315 check(obs_std_star_list = xsh_star_flux_list_load_spectrum(obs_std_star_resp)) ;
3316 //frm_tmp=xsh_star_flux_list_save( obs_std_star_list,"obs_std_star_list.fits", "TEST" ) ;
3317 xsh_free_frame(&frm_tmp);
3318
3319 }
3320
3321
3322 /* TODO: here we need to have the image converted in table
3323 check(ipol_obs_std_star_frame=xsh_spectrum_interpolate_linear(obs_std_star_resp,wstep/10,wmin,wmax));
3324 */
3325
3326
3327 /* TODO: shift the ref STD star spectrum by a value corresponding to the its radial velocity */
3328 rv_ref_wave=xsh_rv_ref_wave_param_create();
3329
3330 /* get reference lambda from given ref std star */
3331 xsh_rv_ref_wave_init(std_star_id ,xsh_instrument_get_arm(instrument),rv_ref_wave);
3332 //xsh_msg("guess=%12.8g",rv_ref_wave->wguess);
3333
3334
3335 /* get corresponding lambda from observed std star */
3336 /* this method is not very robust to get the shift between spectra as:
3337 * 1) the observed spectrum is noisy
3338 * 2) the lines are in absorbtion and do not have a Gaussian shape
3339 * 3) some line have an inversion (a small max in the minimum area of the line)
3340 * Thus it is better to make a cross correlation between lines that allows to solve all problems
3341 */
3342 /*
3343 double wave_obs=0;
3344 wave_obs=xsh_get_obs_std_star_wave_ref(obs_std_star_resp,wave_guess,wmin,wstep);
3345 double wave_shift=0;
3346 double wave_ref=0;
3347 wave_ref=xsh_get_ref_std_star_wave_ref(tbl_ref_std_spectrum,wave_guess,wstep);
3348 xsh_msg("wave: guess %g ref %g shift %g",wave_guess,wave_ref,wave_guess-wave_ref);
3349 */
3350 //xsh_star_flux_list_save( obs_std_star_list,"obs_std_star_list.fits", "TEST" ) ;
3351 frm_tmp=xsh_star_flux_list_save( ref_std_star_list,"ref_flux_std_star.fits", "TEST" ) ;
3352 xsh_free_frame(&frm_tmp);
3353 double wave_shift=0;
3354
3355 wave_shift=xsh_std_star_spectra_correlate(obs_std_star_list,ref_std_star_list,rv_ref_wave);
3356
3357 //double offset=(wave_obs-wave_guess)/wave_guess;
3358 double offset=(wave_shift)/rv_ref_wave->wguess;
3359 xsh_msg("wave: guess[nm] %g RV shift[nm] %g offset[unitless]=%g",rv_ref_wave->wguess,wave_shift,offset);
3360
3361 tbl_shift_std_spectrum=xsh_table_shift_rv(tbl_ref_std_spectrum,"LAMBDA",offset);
3362
3363 xsh_free_table(&tbl_ref_std_spectrum);
3364
3365 check(cpl_table_save(tbl_shift_std_spectrum,NULL,NULL,tbl_shift_std_fname,
3366 CPL_IO_DEFAULT));
3367
3368 //TODO: This tmp product has been left for SABINE to check the RV shift
3369 xsh_add_temporary_file(tbl_shift_std_fname);
3370 xsh_free_table(& tbl_shift_std_spectrum);
3371 check(shift_std_star_frame=xsh_frame_product(tbl_shift_std_fname,"FLUX_STD_STAR",
3372 CPL_FRAME_TYPE_TABLE,
3373 CPL_FRAME_GROUP_PRODUCT,
3374 CPL_FRAME_LEVEL_INTERMEDIATE));
3375
3376
3377 /* Define (possibly STD star dependent) arm dependent windows where the (either reference and observed)
3378 * STD star spectrum should not be sampled (these are usually narrow regions around line cores)
3379 * */
3380
3381
3383
3384 check(ipol_shift_std_star_frame=xsh_spectrum_interpolate_linear(shift_std_star_frame,wstep,wmin,wmax));
3385
3386 check( shift_std_star_list = xsh_star_flux_list_load( ipol_shift_std_star_frame ) ) ;
3387 xsh_free_frame(&ipol_shift_std_star_frame);
3388 xsh_free_frame(&shift_std_star_frame);
3389
3390 //xsh_star_flux_list_save( shift_std_star_list,"shift_std_star_list.fits", "TEST" ) ;
3391
3392 /* median-average over few pix (half-box of 2 pix radii, ie the number of pixels 'around'
3393 * the central pixel which define the neighbourhood of that pixel=> filter size is 2*radii+1)
3394 * the observed STD spectrum to remove residual CRH/BP.
3395 * DONE WITHIN xsh_obs_std_correct
3396 */
3397
3398 /*
3399 * FOR VIS,NIR that are affected by telluric lines:
3400 * Then filter-max over half-box of 20 pix (to remove isolated telluric lines)
3401 * Then filter smooth over 50 pix, for smoothing. */
3402 /* TODO: for the moment not implemented also to be able to check how much bad pixels affects result */
3403 //xsh_star_flux_list * obs_std_star_list = NULL;
3404
3405 /* correct observed spectrum for atmospheric absorbtion and airmass dimming effects, wavelength direction
3406 * bin size, gain, exptime */
3407
3408 check( corr_obs_std_star_list = xsh_obs_std_correct(obs_std_star_resp, shift_std_star_list, atmos_ext, phigh,instrument ) ) ;
3409 xsh_free_frame(&obs_std_star_resp);
3410 //check(xsh_star_flux_list_save(corr_obs_std_star_list,"corr_obs_std_star_list.fits", "TEST" )) ;
3411
3412 /* divide observed (corrected) spectrum by reference one at the allowed sampling pixels
3413 * QC: verify that the resulting spectrum is smooth */
3414
3415
3416 check(response=xsh_star_flux_list_duplicate(shift_std_star_list));
3417 //check(xsh_star_flux_list_fill_null_end(response));
3418 //check(xsh_star_flux_list_save(response,"dup_obs_std_star_list.fits", "TEST" )) ;
3419
3420 //xsh_star_flux_list_filter_median(response,2);
3421 check(xsh_star_flux_list_divide(response,corr_obs_std_star_list));
3422 //check(xsh_star_flux_list_save(response,"std_div_obs_star.fits", "TEST" )) ;
3423
3424 /* smooth over a pixel radii window equivalent to 5nm the resulting ration to get the response
3425 * QC: verify the resulting spectrum is smooth
3426 */
3428 //check(xsh_star_flux_list_save(response,"med_response.fits", "TEST" )) ;
3429 //int hsize=(int)(0.25/wstep+0.5);
3430 /*
3431 int hsize=(int)(1./wstep+0.5);
3432
3433 check(xsh_star_flux_list_filter_lowpass(response,CPL_LOWPASS_LINEAR, hsize ));
3434 */
3435 //check(frm_tmp=xsh_star_flux_list_save( response,"response_smooth.fits", "TEST" )) ;
3436 xsh_free_frame(&frm_tmp);
3437
3438 /* interpolate response over pre-defined windows */
3439 //check(xsh_interpolate_high_abs_regions2(ref_std_star_list,response,phigh));
3440 //check(xsh_star_flux_list_save( response,"response_window.fits", "TEST" )) ;
3441
3442 /* B-spline- fit response over flagging out pre-defined windows */
3443
3444 //PAPERO: here was set telluric correction.
3445 if(resp_fit_points!=NULL) {
3446 if (CPL_ERROR_NONE
3447 != xsh_parse_catalog_std_stars(resp_fit_points, dRA,
3448 dDEC, STAR_MATCH_DEPSILON,
3449 &resp_fit_points_tbl, &std_star_id)) {
3451 "Problem parsing input STD catalog. For robustness recipe goes on.");
3452 xsh_msg_warning("%s", cpl_error_get_message());
3453 cpl_error_reset();
3454 xsh_free_table(&resp_fit_points_tbl);
3455 return NULL ;
3456 }
3457 xsh_msg("Determine response by cubic spline fit interpolation of points defined in input RESP_FIT_POINTS_CAT_%s",
3459 //cpl_table_dump_structure(resp_fit_points_tbl,stdout);
3460 check(response_fit=xsh_bspline_fit_interpol(response,resp_fit_points_tbl,phigh,instrument));
3461 } else {
3462 xsh_msg("Determine response by cubic spline smooth interpolation of pipeline defined regions");
3463 response_fit=xsh_bspline_fit_smooth(response,phigh,instrument);
3464 }
3465
3466 //response_fit=xsh_bspline_interpol(response,phigh,instrument);
3467 //abort();
3468 /*
3469 double* spline_fit=NULL;
3470 int i=0;
3471 spline_fit=xsh_bspline_fit_smooth_data(response->lambda,response->flux,
3472 response->size,phigh,instrument,0);
3473
3474 for(i=0;i<response->size;i++) {
3475 ref_std_star_list->flux[i]=spline_fit[i];
3476 }
3477 */
3478 /* Final step: frame creation, merging info from star and object list */
3479 char tag[256];
3480 char fname[256];
3481
3482 sprintf(tag,"RESPONSE_MERGE1D_%s_%s",xsh_instrument_mode_tostring(instrument),
3484 sprintf(fname,"%s.fits",tag);
3485
3486 check( result = xsh_star_flux_list_save( response_fit, fname, tag ) ) ;
3487 check(xsh_response_merge_obj_std_info(result,shift_std_star_list, corr_obs_std_star_list));
3488
3489 cleanup:
3490 //if(phigh!=NULL) cpl_free(phigh);
3491 xsh_rv_ref_wave_param_destroy(rv_ref_wave);
3492 xsh_free_table(&tbl_ref_std_spectrum);
3493 xsh_free_table(&resp_fit_points_tbl);
3494 xsh_star_flux_list_free(&ref_std_star_list);
3495 xsh_star_flux_list_free(&obs_std_star_list);
3496 xsh_star_flux_list_free(&shift_std_star_list);
3497 xsh_star_flux_list_free(&corr_obs_std_star_list);
3498 xsh_star_flux_list_free(&response);
3499 xsh_star_flux_list_free(&response_fit);
3500
3501 return result;
3502}
3503
3504
3505
3506
3507
3523cpl_frame * xsh_compute_response( cpl_frame * spectrum_frame,
3524 cpl_frame * flux_std_star_cat_frame,
3525 cpl_frame * atmos_ext_frame,
3526 cpl_frame* high_abs_frame,
3528 double exptime )
3529{
3530 cpl_frame * result = NULL ;
3531 xsh_star_flux_list * star_list = NULL ;
3532 xsh_star_flux_list * obj_list = NULL ;
3533 xsh_spectrum * spectrum = NULL ;
3534 cpl_frame * tmp_spectrum_frame = NULL ;
3535 xsh_star_flux_list * resp_list = NULL ;
3536 xsh_atmos_ext_list * atmos_ext_list = NULL ;
3537 char tag[256];
3538 char fname[256];
3539
3540 cpl_frame* flux_std_star_frame=NULL;
3541 double dRA=0;
3542 double dDEC=0;
3543 cpl_table* tbl_ref_std_spectrum=NULL;
3544 const char* tbl_ref_std_fname="ref_flux_std_star.fits";
3545 cpl_frame* ipol_flux_std_star_frame=NULL;
3546 cpl_frame* resampl_flux_std_star_frame=NULL;
3547 //cpl_frame* smooth_flux_std_star_frame=NULL;
3548
3549 double wmin=0;
3550 double wmax=0;
3551 int naxis1=0;
3552 double cdelt1=0;
3553 const char* filename=NULL;
3554 cpl_propertylist* plist=NULL;
3555 char * name=NULL;
3556 char * pcatg=NULL;
3557 cpl_table* atmos_ext_tab=NULL;
3558 double airmass=0;
3559 double gain=1.;
3560 //int bin=1;
3561 HIGH_ABS_REGION * phigh=NULL;
3562
3563 XSH_ASSURE_NOT_NULL( spectrum_frame ) ;
3564 XSH_ASSURE_NOT_NULL( flux_std_star_cat_frame ) ;
3566
3567
3568 xsh_msg("Compute instrument response");
3569
3570 /* get RA DEC from observed object frame */
3571 xsh_frame_sci_get_ra_dec_airmass(spectrum_frame,&dRA,&dDEC,&airmass);
3572 /* extract matching ref STD star spectrum */
3573 xsh_std_star_id std_star_id=0;
3574
3575 if(CPL_ERROR_NONE != xsh_parse_catalog_std_stars(flux_std_star_cat_frame,
3576 dRA,dDEC,
3578 &tbl_ref_std_spectrum,&std_star_id)){
3579 xsh_msg_warning("Problem parsing input STD catalog. For robustness recipe goes on.");
3580 xsh_msg_warning("%s",cpl_error_get_message());
3581 cpl_error_reset();
3582 xsh_free_table(&tbl_ref_std_spectrum);
3583 return NULL;
3584 }
3585
3586 /* required for further data reduction ! */
3587 check(cpl_table_save(tbl_ref_std_spectrum,NULL,NULL,tbl_ref_std_fname,
3588 CPL_IO_DEFAULT));
3589 xsh_add_temporary_file(tbl_ref_std_fname);
3590 check(flux_std_star_frame=xsh_frame_product(tbl_ref_std_fname,"FLUX_STD_STAR",
3591 CPL_FRAME_TYPE_TABLE,
3592 CPL_FRAME_GROUP_PRODUCT,
3593 CPL_FRAME_LEVEL_INTERMEDIATE));
3594
3595 filename=cpl_frame_get_filename(spectrum_frame);
3596 plist=cpl_propertylist_load(filename,0);
3597 naxis1=xsh_pfits_get_naxis1(plist);
3598 cdelt1=xsh_pfits_get_cdelt1(plist);
3599 wmin=xsh_pfits_get_crval1(plist);
3600 /* we get the bin along the dispersion direction */
3601
3603 /* we assume gain in units of ADU/e- as ESO standard */
3604 gain=1./2.12;
3605 //bin=1;
3606 } else {
3607 check_msg( gain = xsh_pfits_get_gain(plist),
3608 "Could not read gain factor");
3609 //bin=xsh_pfits_get_biny(plist);
3610 }
3611
3612 xsh_free_propertylist(&plist);
3613 wmax=wmin+cdelt1*naxis1;
3614
3615 check(ipol_flux_std_star_frame=xsh_spectrum_interpolate(flux_std_star_frame,
3616 1,
3617 wmin,wmax));
3618
3619 /*
3620
3621 check(smooth_flux_std_star_frame=xsh_spectrum_resample(flux_std_star_frame,
3622 0.08,
3623 wmin,wmax,instrument));
3624
3625
3626 */
3627 check(resampl_flux_std_star_frame=xsh_spectrum_resample(ipol_flux_std_star_frame,
3629 wmin,wmax,instrument));
3630
3631 /* Load flux_std_star table */
3632 check( star_list = xsh_star_flux_list_load( resampl_flux_std_star_frame ) ) ;
3633
3634 /* Load rect_frame */
3635 check( spectrum = xsh_spectrum_load( spectrum_frame));
3636 pcatg=cpl_sprintf("SPECTRUM_%s",xsh_instrument_arm_tostring( instrument));
3637 name=cpl_sprintf("%s.fits",pcatg);
3638 tmp_spectrum_frame=xsh_spectrum_save( spectrum,name,pcatg);
3640 cpl_free(pcatg);
3641 cpl_free(name);
3642
3643 /* Load ATMOS EXT (if not NULL ) */
3644 if ( atmos_ext_frame != NULL ) {
3645 check( atmos_ext_list = xsh_atmos_ext_list_load( atmos_ext_frame ) ) ;
3646 xsh_msg( "ATMOS EXT Loaded" ) ;
3647 //check(xsh_atmos_ext_dump_ascii(atmos_ext_list,"pippo_atm_ext_list.asc"));
3648 check(filename=cpl_frame_get_filename(atmos_ext_frame));
3649 check(atmos_ext_tab=cpl_table_load(filename,1,0));
3650 } else {
3651 xsh_msg_warning("Missing input %s_%s frame. Skip response and efficiency computation",
3653 }
3654
3655 /* Compute */
3656 check(phigh=xsh_fill_high_abs_regions(instrument,high_abs_frame));
3657
3658 check( resp_list = do_compute( star_list, &obj_list, spectrum, atmos_ext_tab,
3659 phigh,airmass,exptime,gain,instrument ) ) ;
3660
3661 //check(xsh_star_flux_list_dump_ascii(resp_list,"pippo_resp_list.asc"));
3662
3663 /* Save the response frame */
3664 sprintf(tag,"RESPONSE_MERGE1D_%s_%s",xsh_instrument_mode_tostring(instrument),
3666 sprintf(fname,"%s.fits",tag);
3667 check( result = xsh_star_flux_list_save( resp_list, fname, tag ) ) ;
3668 xsh_msg("***********************************");
3669 check(xsh_response_merge_obj_std_info(result,star_list, obj_list));
3670
3671 cleanup:
3672 if(high_abs_frame!=NULL) {
3673 cpl_free(phigh);
3674 }
3675 xsh_spectrum_free( &spectrum ) ;
3676
3677 xsh_star_flux_list_free( &star_list ) ;
3678 xsh_star_flux_list_free( &obj_list ) ;
3679 xsh_star_flux_list_free( &resp_list ) ;
3680 xsh_free_table(&tbl_ref_std_spectrum);
3681 xsh_free_frame(&flux_std_star_frame);
3682 xsh_free_frame(&ipol_flux_std_star_frame);
3683 xsh_free_frame(&resampl_flux_std_star_frame);
3684 xsh_free_frame(&tmp_spectrum_frame);
3685
3686
3687 xsh_atmos_ext_list_free(&atmos_ext_list) ;
3688 xsh_free_propertylist(&plist);
3689 xsh_free_table(&atmos_ext_tab);
3690
3691 return result ;
3692}
3693
3709cpl_frame * xsh_compute_response_ord( cpl_frame * spectrum_frame,
3710 cpl_frame * flux_std_star_cat_frame,
3711 cpl_frame * atmos_ext_frame,
3712 cpl_frame * high_abs_win_frame,
3714 double exptime )
3715{
3716 cpl_frame * result = NULL ;
3717 xsh_star_flux_list * star_list = NULL ;
3718 xsh_star_flux_list * obj_list = NULL ;
3719 xsh_spectrum * spectrum = NULL ;
3720 cpl_frame * tmp_spectrum_frame = NULL ;
3721 xsh_star_flux_list * resp_list = NULL ;
3722 xsh_atmos_ext_list * atmos_ext_list = NULL ;
3723
3724 char tag[256];
3725 char fname[256];
3726 cpl_frame* flux_std_star_frame=NULL;
3727 double dRA=0;
3728 double dDEC=0;
3729 cpl_table* tbl_ref_std_spectrum=NULL;
3730 const char* tbl_ref_std_fname="ref_flux_std_star.fits";
3731 cpl_frame* ipol_flux_std_star_frame=NULL;
3732 double wmin=0;
3733 double wmax=0;
3734 int naxis1=0;
3735 double cdelt1=0;
3736 const char* filename=NULL;
3737 cpl_propertylist* plist=NULL;
3738 char * name=NULL;
3739 char * pcatg=NULL;
3740 cpl_table* atmos_ext_tab=NULL;
3741 double airmass=0;
3742 double gain=1.;
3743
3744 int next=0;
3745 //int nord=0;
3746 int ext=0;
3747 //int bin=0;
3748 HIGH_ABS_REGION * phigh=NULL;
3749 //XSH_ARM the_arm;
3750 xsh_std_star_id std_star_id=0;
3751
3752 XSH_ASSURE_NOT_NULL( spectrum_frame ) ;
3753 XSH_ASSURE_NOT_NULL( flux_std_star_cat_frame ) ;
3755 XSH_ASSURE_NOT_NULL( fname ) ;
3756
3757 xsh_msg("Compute instrument response");
3758 /* get RA DEC from observed object frame */
3759 xsh_frame_sci_get_ra_dec_airmass(spectrum_frame,&dRA,&dDEC,&airmass);
3760
3761 /* extract matching ref STD star spectrum */
3762 if(CPL_ERROR_NONE != xsh_parse_catalog_std_stars(flux_std_star_cat_frame,
3763 dRA,dDEC,
3765 &tbl_ref_std_spectrum,&std_star_id)){
3766 xsh_msg_warning("Problem parsing input STD catalog. For robustness recipe goes on.");
3767 xsh_msg_warning("%s",cpl_error_get_message());
3768 cpl_error_reset();
3769 xsh_free_table(&tbl_ref_std_spectrum);
3770 return NULL;
3771 }
3772
3773 /* required for further data reduction ! */
3774 check(cpl_table_save(tbl_ref_std_spectrum,NULL,NULL,tbl_ref_std_fname,
3775 CPL_IO_DEFAULT));
3776 xsh_add_temporary_file(tbl_ref_std_fname);
3777
3778 check(flux_std_star_frame=xsh_frame_product(tbl_ref_std_fname,"FLUX_STD_STAR",
3779 CPL_FRAME_TYPE_TABLE,
3780 CPL_FRAME_GROUP_PRODUCT,
3781 CPL_FRAME_LEVEL_INTERMEDIATE));
3782
3783 /* Load ATMOS EXT (if not NULL ) */
3784 if ( atmos_ext_frame != NULL ) {
3785 check( atmos_ext_list = xsh_atmos_ext_list_load( atmos_ext_frame ) ) ;
3786 xsh_msg( "ATMOS EXT Loaded" ) ;
3787 //check(xsh_atmos_ext_dump_ascii(atmos_ext_list,"pippo_atm_ext_list.asc"));
3788 check(filename=cpl_frame_get_filename(atmos_ext_frame));
3789 check(atmos_ext_tab=cpl_table_load(filename,1,0));
3790 }
3791 //the_arm=xsh_instrument_get_arm(instrument);
3792
3793 /* Load rect_frame */
3794 filename=cpl_frame_get_filename(spectrum_frame);
3795 next=cpl_frame_get_nextensions(spectrum_frame);
3796 //nord=next/3;
3797
3798 plist=cpl_propertylist_load(filename,0);
3800 /* we assume gain in units of ADU/e- as ESO standard */
3801 gain=1./2.12;
3802 //bin=1;
3803 } else {
3804 check_msg( gain = xsh_pfits_get_gain(plist),
3805 "Could not read gain factor");
3806 //bin=xsh_pfits_get_biny(plist);
3807 }
3808 xsh_free_propertylist(&plist);
3809
3810 check(phigh=xsh_fill_high_abs_regions(instrument,high_abs_win_frame));
3811
3812 for(ext=0;ext<next;ext+=3) {
3813
3814 xsh_free_propertylist(&plist);
3815 plist=cpl_propertylist_load(filename,ext);
3816 naxis1=xsh_pfits_get_naxis1(plist);
3817 cdelt1=xsh_pfits_get_cdelt1(plist);
3818 wmin=xsh_pfits_get_crval1(plist);
3819 wmax=wmin+cdelt1*naxis1;
3820
3821 xsh_free_frame(&ipol_flux_std_star_frame);
3822 check(ipol_flux_std_star_frame=xsh_spectrum_interpolate(flux_std_star_frame,
3824 wmin,wmax));
3825 /* Load flux_std_star table */
3826 xsh_star_flux_list_free( &star_list ) ;
3827 check( star_list = xsh_star_flux_list_load( ipol_flux_std_star_frame ) ) ;
3828
3829 xsh_spectrum_free( &spectrum ) ;
3830 check( spectrum=xsh_spectrum_load_order(spectrum_frame,instrument,ext)) ;
3831 pcatg=cpl_sprintf("SPECTRUM_%s",xsh_instrument_arm_tostring( instrument));
3832 name=cpl_sprintf("%s.fits",pcatg);
3833 xsh_free_frame(&tmp_spectrum_frame);
3834
3835 tmp_spectrum_frame=xsh_spectrum_save_order( spectrum,name,pcatg,ext);
3837
3838 cpl_free(pcatg);
3839 cpl_free(name);
3840
3841 /* Compute */
3842 xsh_star_flux_list_free( &resp_list ) ;
3843 xsh_star_flux_list_free( &obj_list ) ;
3844 check(resp_list=do_compute( star_list, &obj_list, spectrum, atmos_ext_tab,
3845 phigh,airmass, exptime, gain, instrument ) ) ;
3846
3847
3848 //check(xsh_star_flux_list_dump_ascii(resp_list,"pippo_resp_list.asc"));
3849
3850 /* Save the response frame */
3851 sprintf(tag,"RESPONSE_ORDER1D_%s_%s",xsh_instrument_mode_tostring(instrument),
3853 sprintf(fname,"%s.fits",tag);
3854 xsh_free_frame(&result);
3855
3856 check(result=xsh_star_flux_list_save_order(resp_list,fname,tag,ext)) ;
3857
3858 }
3859
3860 cleanup:
3861
3862 if(high_abs_win_frame!=NULL) {
3863 cpl_free(phigh);
3864 }
3865 xsh_spectrum_free( &spectrum ) ;
3866 xsh_star_flux_list_free( &star_list ) ;
3867 xsh_star_flux_list_free( &resp_list ) ;
3868 xsh_star_flux_list_free( &obj_list ) ;
3869
3870 xsh_free_table(&tbl_ref_std_spectrum);
3871 xsh_free_frame(&flux_std_star_frame);
3872 xsh_free_frame(&ipol_flux_std_star_frame);
3873 xsh_free_frame(&tmp_spectrum_frame);
3874
3875 xsh_atmos_ext_list_free(&atmos_ext_list) ;
3876 xsh_free_propertylist(&plist);
3877 xsh_free_table(&atmos_ext_tab);
3878
3879 return result ;
3880}
3881
static double exptime
static const double step
static double sigma
static xsh_instrument * instrument
int binx
int biny
double xsh_spectrum_get_lambda_min(xsh_spectrum *s)
Get minimum lambda of spectrum.
xsh_spectrum * xsh_spectrum_load(cpl_frame *s1d_frame)
Load a 1D spectrum structure.
double xsh_spectrum_get_lambda_step(xsh_spectrum *s)
Get bin in lambda of spectrum.
xsh_spectrum * xsh_spectrum_load_order(cpl_frame *s1d_frame, xsh_instrument *instr, const int order)
Load a 1D spectrum structure.
int * xsh_spectrum_get_qual(xsh_spectrum *s)
Get qual of spectrum.
int xsh_spectrum_get_size(xsh_spectrum *s)
Get size of spectrum.
cpl_frame * xsh_spectrum_save(xsh_spectrum *s, const char *filename, const char *tag)
save a spectrum
cpl_frame * xsh_spectrum_save_order(xsh_spectrum *s, const char *filename, const char *tag, const int order)
save a spectrum
double * xsh_spectrum_get_flux(xsh_spectrum *s)
Get flux of spectrum.
double xsh_spectrum_get_lambda_max(xsh_spectrum *s)
Get maximum lambda of spectrum.
void xsh_spectrum_free(xsh_spectrum **s)
free memory associated to an 1D spectrum
#define XSH_ASSURE_NOT_NULL_MSG(pointer, msg)
Definition: xsh_error.h:103
#define check(COMMAND)
Definition: xsh_error.h:71
#define check_msg(COMMAND,...)
Definition: xsh_error.h:62
#define XSH_ASSURE_NOT_NULL(pointer)
Definition: xsh_error.h:99
const char * xsh_instrument_mode_tostring(xsh_instrument *i)
Get the string associated with a mode.
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 size
int * y
int * x
#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_debug(...)
Print a debug message.
Definition: xsh_msg.h:99
#define xsh_msg(...)
Print a message on info level.
Definition: xsh_msg.h:121
#define xsh_msg_dbg_low(...)
Definition: xsh_msg.h:48
#define xsh_msg_dbg_high(...)
Definition: xsh_msg.h:40
int xsh_pfits_get_binx(const cpl_propertylist *plist)
find out the BINX value
Definition: xsh_pfits.c:289
double xsh_pfits_get_gain(const cpl_propertylist *plist)
find out the GAIN value
Definition: xsh_pfits.c:675
double xsh_pfits_get_cdelt1(const cpl_propertylist *plist)
find out the cdelt1
Definition: xsh_pfits.c:2196
int xsh_pfits_get_biny(const cpl_propertylist *plist)
find out the BINY value
Definition: xsh_pfits.c:306
double xsh_pfits_get_exptime(const cpl_propertylist *plist)
find out the exposure time
Definition: xsh_pfits.c:2254
double xsh_pfits_get_airm_mean(const cpl_propertylist *plist)
find out the mean airmass value
Definition: xsh_pfits.c:511
int xsh_pfits_get_naxis1(const cpl_propertylist *plist)
find out the NAXIS1 value
Definition: xsh_pfits.c:227
double xsh_pfits_get_crval1(const cpl_propertylist *plist)
find out the crval1
Definition: xsh_pfits.c:1907
cpl_table * xsh_telluric_model_eval(cpl_frame *frame_m, xsh_spectrum *s, xsh_instrument *instrument, cpl_size *model_idx)
void xsh_free_polynomial(cpl_polynomial **p)
Deallocate a polynomial and set the pointer to NULL.
Definition: xsh_utils.c:2194
void xsh_free_vector(cpl_vector **v)
Deallocate a vector and set the pointer to NULL.
Definition: xsh_utils.c:2284
int xsh_debug_level_get(void)
get debug level
Definition: xsh_utils.c:3142
cpl_frame * xsh_spectrum_interpolate_linear(cpl_frame *table_frame, const double wstep, const double wmin, const double wmax)
spectra interpolation
Definition: xsh_utils.c:6213
void xsh_free_frame(cpl_frame **f)
Deallocate a frame and set the pointer to NULL.
Definition: xsh_utils.c:2269
double xsh_data_interpolate(double wav, int nrow, double *pw, double *pe)
Interpolate data points.
char * xsh_get_basename(const char *filename)
Return base filename.
Definition: xsh_utils.c:1175
cpl_table * xsh_table_shift_rv(cpl_table *orig, const char *col_wave, const double offset)
cpl_frame * xsh_spectrum_resample(cpl_frame *frame_inp, const double wstep, const double wmin, const double wmax, xsh_instrument *instr)
resample a spectrum
Definition: xsh_utils.c:5336
void xsh_free_table(cpl_table **t)
Deallocate a table and set the pointer to NULL.
Definition: xsh_utils.c:2133
void xsh_free_propertylist(cpl_propertylist **p)
Deallocate a property list and set the pointer to NULL.
Definition: xsh_utils.c:2179
cpl_frame * xsh_spectrum_interpolate(cpl_frame *table_frame, const double wstep, const double wmin, const double wmax)
spectra interpolation
Definition: xsh_utils.c:6306
void xsh_frame_spectrum_save(cpl_frame *frm, const char *name_o)
save an spectrum frame
Definition: xsh_utils.c:3959
void xsh_add_temporary_file(const char *name)
Add temporary file to temprary files list.
Definition: xsh_utils.c:1432
cpl_propertylist * flux_header
cpl_propertylist * header
#define QFLAG_GOOD_PIXEL
double * xsh_bspline_fit_smooth_data(double *wave, double *flux, const int size, HIGH_ABS_REGION *phigh, xsh_instrument *inst, const int fit_region)
static cpl_error_code xsh_response_crea_ascii(xsh_star_flux_list *resp_list, xsh_star_flux_list *star_list, double *lambda_spectrum, double *flux_spectrum, double *flux_added)
static xsh_star_flux_list * xsh_response_calculate(xsh_star_flux_list *star_list, xsh_star_flux_list **obj_list, xsh_spectrum *spectrum, cpl_table *atmos_ext_tab, XSH_ARM the_arm, double *atmos_K, double airmass, double exptime, double gain)
static cpl_error_code xsh_std_star_spectra_to_vector_range(xsh_star_flux_list *obs_std_star_list, const double wmin, const double wmax, cpl_vector **vec_wave, cpl_vector **vec_flux)
#define FILTER_MEDIAN_HSIZE
static void find_lambda_idx_limit(double min, double max, double *spectrum, int from, int to, double step, int *if0, int *if1)
static xsh_star_flux_list * xsh_bspline_fit_smooth(xsh_star_flux_list *ref_std_star_list, HIGH_ABS_REGION *phigh, xsh_instrument *inst)
cpl_frame * xsh_compute_response(cpl_frame *spectrum_frame, cpl_frame *flux_std_star_cat_frame, cpl_frame *atmos_ext_frame, cpl_frame *high_abs_frame, xsh_instrument *instrument, double exptime)
cpl_error_code xsh_response_merge_obj_std_info(cpl_frame *result, xsh_star_flux_list *star_list, xsh_star_flux_list *obj_list)
static cpl_error_code xsh_select_line_core(cpl_vector *wave, cpl_vector *flux, const double wguess, const double wrange, cpl_vector **xfit, cpl_vector **yfit)
double * xsh_bspline_fit_smooth_data2(double *wave, double *flux, const int size, HIGH_ABS_REGION *phigh, xsh_instrument *inst, const int fit_region)
cpl_frame * xsh_compute_response_ord(cpl_frame *spectrum_frame, cpl_frame *flux_std_star_cat_frame, cpl_frame *atmos_ext_frame, cpl_frame *high_abs_win_frame, xsh_instrument *instrument, double exptime)
static xsh_star_flux_list * do_compute(xsh_star_flux_list *star_list, xsh_star_flux_list **obj_list, xsh_spectrum *spectrum, cpl_table *atmos_ext_tab, HIGH_ABS_REGION *phigh, double airmass, double exptime, double gain, xsh_instrument *instrument)
static cpl_error_code xsh_spectrum_correct(xsh_star_flux_list *star_list, xsh_spectrum *spectrum, double *atmos_K, XSH_ARM the_arm, double airmass, double exptime, double gain, xsh_star_flux_list **obj_list)
static cpl_error_code xsh_flux_integrate_and_corr_for_badpix(int npix_in_interval, double *flux_spectrum, int *qual_spectrum, int if0, int if1, int i, double **flux_added, int *npixels, int *nbad)
static cpl_error_code xsh_interpolate_atm_ext(xsh_star_flux_list *star_list, cpl_table *atmos_ext_tab, xsh_instrument *instrument, double **atmos_lambda, double **atmos_K)
static xsh_star_flux_list * xsh_obs_std_correct(cpl_frame *obs_std_star, xsh_star_flux_list *ref_std_star_list, cpl_frame *atmos_ext, HIGH_ABS_REGION *phigh, xsh_instrument *instrument)
static xsh_star_flux_list * xsh_bspline_fit_interpol(xsh_star_flux_list *ref_std_star_list, cpl_table *resp_fit_points, HIGH_ABS_REGION *phigh, xsh_instrument *inst)
static cpl_error_code xsh_interpolate_high_abs_regions(xsh_star_flux_list *star_list, xsh_star_flux_list *resp_list, HIGH_ABS_REGION *phigh)
cpl_error_code xsh_sort_double_pairs(double *u1, double *u2, cpl_size n)
Sort an array u1 of doubles, and permute an array u2 in the same way as u1 is permuted.
cpl_frame * xsh_compute_response2(cpl_frame *obs_std_star, cpl_frame *flux_std_star_cat, cpl_frame *atmos_ext, cpl_frame *high_abs, cpl_frame *resp_fit_points, cpl_frame *tell_mod_cat, xsh_instrument *instrument, double exptime, const int tell_corr)
double * xsh_bspline_interpolate_data_at_pos(double *w_data, double *f_data, const int n_data, double *w_pos, const int n_pos)
static int find_lambda_idx(double lambda, double *wave, int from, int to, double step)
#define INTERPOL_WSTEP_NM
static double xsh_std_star_spectra_correlate(xsh_star_flux_list *obs_std_star_list, xsh_star_flux_list *ref_std_star_list, xsh_rv_ref_wave_param *w)
xsh_atmos_ext_list * xsh_atmos_ext_list_load(cpl_frame *ext_frame)
void xsh_atmos_ext_list_free(xsh_atmos_ext_list **list)
#define XSH_ATMOS_EXT_LIST_COLNAME_OLD
#define XSH_ATMOS_EXT_LIST_COLNAME_K
@ XSH_ARM_UVB
@ XSH_ARM_NIR
@ XSH_ARM_VIS
double * xsh_star_flux_list_get_lambda(xsh_star_flux_list *list)
cpl_error_code xsh_star_flux_list_divide(xsh_star_flux_list *result, xsh_star_flux_list *factor)
void xsh_star_flux_list_extrapolate_wave_end(xsh_star_flux_list *list, const double wmax)
cpl_frame * xsh_star_flux_list_save_order(xsh_star_flux_list *list, const char *filename, const char *tag, const int order)
cpl_error_code xsh_star_flux_list_to_frame(xsh_star_flux_list *list, cpl_frame *frame)
void xsh_star_flux_list_free(xsh_star_flux_list **list)
xsh_star_flux_list * xsh_star_flux_list_load_spectrum(cpl_frame *star_frame)
xsh_star_flux_list * xsh_star_flux_list_load(cpl_frame *star_frame)
cpl_error_code xsh_star_flux_list_filter_median(xsh_star_flux_list *result, int hsize)
xsh_star_flux_list * xsh_star_flux_list_create(int size)
cpl_frame * xsh_star_flux_list_save(xsh_star_flux_list *list, const char *filename, const char *tag)
double * xsh_star_flux_list_get_flux(xsh_star_flux_list *list)
xsh_star_flux_list * xsh_star_flux_list_duplicate(xsh_star_flux_list *list)
int n
Definition: xsh_detmon_lg.c:92
int order
Definition: xsh_detmon_lg.c:80
cpl_frame * xsh_frame_product(const char *fname, const char *tag, cpl_frame_type type, cpl_frame_group group, cpl_frame_level level)
Creates a frame with given characteristics.
Definition: xsh_dfs.c:930
#define XSH_ATMOS_EXT
Definition: xsh_dfs.h:1191
HIGH_ABS_REGION * xsh_fill_high_abs_regions(xsh_instrument *instrument, cpl_frame *high_abs_frame)
static const double STAR_MATCH_DEPSILON
#define max(a, b)
#define XSH_FREE(POINTER)
Definition: xsh_utils.h:92
@ XSH_DEBUG_LEVEL_LOW
Definition: xsh_utils.h:137
#define XSH_CALLOC(POINTER, TYPE, SIZE)
Definition: xsh_utils.h:56
cpl_error_code xsh_rv_ref_wave_init(xsh_std_star_id std_star_id, XSH_ARM arm, xsh_rv_ref_wave_param *w)
void xsh_rv_ref_wave_param_destroy(xsh_rv_ref_wave_param *p)
void xsh_frame_sci_get_ra_dec_airmass(cpl_frame *frm_sci, double *ra, double *dec, double *airmass)
get RA, DEC, airmass (mean) of a frame
xsh_rv_ref_wave_param * xsh_rv_ref_wave_param_create(void)
cpl_error_code xsh_parse_catalog_std_stars(cpl_frame *cat, double dRA, double dDEC, double EPSILON, cpl_table **pptable, xsh_std_star_id *std_star_id)
parse referece std stars catalog
xsh_std_star_id
cpl_vector * xsh_vector_fit_slope(cpl_vector *vec_wave, cpl_vector *vec_flux, const double wmin_max, const double wmax_min, const int degree)
cpl_polynomial * xsh_polynomial_fit_1d_create(const cpl_vector *x_pos, const cpl_vector *values, int degree, double *mse)