00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifdef HAVE_CONFIG_H
00028 #include <config.h>
00029 #endif
00030
00031
00037
00038
00039
00040
00041
00042
00043 #include <gsl/gsl_spline.h>
00044 #include <gsl/gsl_errno.h>
00045
00046 #include <gsl/gsl_bspline.h>
00047 #include <gsl/gsl_multifit.h>
00048 #include <gsl/gsl_rng.h>
00049 #include <gsl/gsl_randist.h>
00050 #include <gsl/gsl_statistics.h>
00051
00052
00053
00054 #include <xsh_dfs.h>
00055 #include <xsh_error.h>
00056 #include <xsh_msg.h>
00057 #include <cpl.h>
00058 #include <string.h>
00059 #include <time.h>
00060 #include <xsh_utils_table.h>
00061 #include <xsh_data_star_flux.h>
00062 #include <xsh_data_atmos_ext.h>
00063 #include <xsh_data_spectrum.h>
00064 #include <xsh_pfits.h>
00065 #include <xsh_utils.h>
00066 #include <xsh_utils_wrappers.h>
00067 #include <xsh_drl.h>
00068 #include <xsh_utils_efficiency.h>
00069 #include <xsh_efficiency_response.h>
00070 #include <xsh_utils_response.h>
00071 #include <xsh_utils_vector.h>
00072
00073
00074
00075
00076
00077
00078
00079
00080 #define INTERPOL_WSTEP_NM 2
00081 #define FILTER_MEDIAN_HSIZE 3
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 static int
00096 find_lambda_idx( double lambda, double * wave, int from, int to,
00097 double step )
00098 {
00099 int idx ;
00100 double * pwave ;
00101
00102 for( idx = from, pwave = wave+from ; idx < to ; pwave++, idx++ ) {
00103 if ( *pwave >= (lambda-step/2) && *pwave < (lambda+step/2) ) {
00104 return idx ;
00105 }
00106 }
00107
00108 return -1 ;
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 static int
00143 find_lambda_idx_min( double lambda, double * wave, int from, int to,
00144 double step )
00145 {
00146 int idx ;
00147 double * pwave ;
00148
00149 for( idx = from, pwave = wave+from ; idx < to ; pwave++, idx++ ) {
00150
00151
00152
00153
00154 if ( *pwave > (lambda-step/2) ) {
00155
00156
00157
00158
00159 return idx ;
00160 }
00161 }
00162
00163 return -1 ;
00164 }
00165
00166
00167
00168 static int
00169 find_lambda_idx_max( double lambda, double * wave, int from, int to,
00170 double step )
00171 {
00172 int idx ;
00173 double * pwave ;
00174
00175 for( idx = from, pwave = wave+from ; idx >= to ; pwave--, idx-- ) {
00176
00177
00178
00179
00180 if ( *pwave < (lambda+step/2) ) {
00181
00182
00183
00184
00185 return idx ;
00186 }
00187 }
00188
00189 return -1 ;
00190 }
00191
00192 static void
00193 find_lambda_idx_limit( double min, double max, double * spectrum,
00194 int from, int to, double step,
00195 int * if0, int * if1 )
00196 {
00197 int idx ;
00198 double *pspec ;
00199
00200 xsh_msg_dbg_high( "From: %d, To: %d, step: %lf, min: %lf, max: %lf",
00201 from, to, step, min, max ) ;
00202
00203 for( idx = from, pspec = spectrum+from ; idx < to ; pspec++, idx++ ) {
00204 xsh_msg_dbg_high( " Search Min - Spectrum_lambda: %lf (%lf)", *pspec,
00205 min-(step/2.) ) ;
00206 if ( *pspec >= (min-(step/2.)) ) break ;
00207 }
00208 *if0 = idx ;
00209 for( ; idx < to ; pspec++, idx++ ) {
00210 xsh_msg_dbg_high( " Search Max - Spectrum_lambda: %lf", *pspec ) ;
00211 if ( *pspec > (max+(step/2.)) ) break ;
00212 }
00213 *if1 = idx-1 ;
00214
00215 xsh_msg_dbg_low( "Lambda Min: %lf, Max: %lf (in [%lf,%lf[",
00216 spectrum[*if0], spectrum[*if1], min, max ) ;
00217 if ( *if1 > to ) *if1 = to ;
00218
00219 return ;
00220 }
00221
00232 static cpl_error_code
00233 xsh_interpolate_atm_ext(xsh_star_flux_list * star_list,
00234 cpl_table*atmos_ext_tab,
00235 xsh_instrument* instrument,
00236 double** atmos_lambda,
00237 double** atmos_K)
00238 {
00239
00240 int nrow=0;
00241 double* pk=0;
00242 double* pw=0;
00243 int j=0 ;
00244 int nlambda_star=0 ;
00245 double * lambda_star = NULL;
00246
00247 XSH_ASSURE_NOT_NULL_MSG (star_list,"null input ref std flux table!");
00248 XSH_ASSURE_NOT_NULL_MSG (atmos_ext_tab,"null input atm ext table!");
00249
00250 nlambda_star = star_list->size ;
00251 lambda_star = star_list->lambda ;
00252
00253
00254
00255 XSH_CALLOC( *atmos_lambda, double, nlambda_star ) ;
00256 XSH_CALLOC( *atmos_K, double, nlambda_star ) ;
00257 if(!cpl_table_has_column(atmos_ext_tab,XSH_ATMOS_EXT_LIST_COLNAME_K)){
00258 xsh_msg_warning("You are using an obsolete atm extinction line table");
00259 cpl_table_duplicate_column(atmos_ext_tab,XSH_ATMOS_EXT_LIST_COLNAME_K,
00260 atmos_ext_tab,XSH_ATMOS_EXT_LIST_COLNAME_OLD);
00261 }
00262 cpl_table_cast_column(atmos_ext_tab,XSH_ATMOS_EXT_LIST_COLNAME_K,"K",CPL_TYPE_DOUBLE);
00263 cpl_table_cast_column(atmos_ext_tab,"LAMBDA","WAVE",CPL_TYPE_DOUBLE);
00264
00265 nrow=cpl_table_get_nrow(atmos_ext_tab);
00266 pw=cpl_table_get_data_double(atmos_ext_tab,"WAVE");
00267 pk=cpl_table_get_data_double(atmos_ext_tab,"K");
00268
00269 if( xsh_instrument_get_arm(instrument) != XSH_ARM_NIR){
00270 for( j = 0 ; j<nlambda_star ; j++) {
00271
00272 (*atmos_lambda)[j] = lambda_star[j] ;
00273 (*atmos_K)[j] = xsh_data_interpolate((*atmos_lambda)[j],nrow,pw,pk);
00274
00275
00276 }
00277 } else {
00278 for( j = 0 ; j<nlambda_star ; j++) {
00279
00280 (*atmos_lambda)[j] = lambda_star[j] ;
00281 (*atmos_K)[j] = 0;
00282
00283
00284 }
00285 }
00286
00287 cpl_table_erase_column(atmos_ext_tab,"WAVE");
00288 cpl_table_erase_column(atmos_ext_tab,"K");
00289
00290
00291 cleanup:
00292 return cpl_error_get_code();
00293 }
00294
00303 static cpl_error_code
00304 xsh_interpolate_high_abs_regions(xsh_star_flux_list * star_list,
00305 xsh_star_flux_list * resp_list,
00306 HIGH_ABS_REGION * phigh)
00307
00308 {
00309 int kh=0;
00310 int min_idx=0;
00311 int max_idx=0;
00312 int start_idx=0;
00313 double min_flux=0;
00314 double max_flux=0;
00315 double delta_flux=0;
00316 double cur_flux=0;
00317 int ll=0;
00318 int min_step=5;
00319 int nlambda_star=0;
00320 double step_star=0;
00321 double * lambda_star = NULL;
00322 double lambda_star_min=0;
00323 double lambda_star_max=0;
00324
00325 XSH_ASSURE_NOT_NULL_MSG (star_list,"null input ref std flux table!");
00326 XSH_ASSURE_NOT_NULL_MSG (resp_list,"null input response table!");
00327
00328 nlambda_star = star_list->size ;
00329 lambda_star = star_list->lambda ;
00330 lambda_star_min = *lambda_star ;
00331 lambda_star_max = *(lambda_star+nlambda_star-1) ;
00332 step_star = (lambda_star_max-lambda_star_min)/(nlambda_star-1) ;
00333
00334 if ( phigh != NULL ) {
00335
00336 xsh_msg_dbg_medium( "Interpolate in High Absorption Regions" ) ;
00337 for( kh = 0 ; phigh->lambda_min != 0. ; kh++, phigh++ ) {
00338 start_idx=0;
00339 min_idx = find_lambda_idx( phigh->lambda_min, resp_list->lambda,
00340 start_idx, nlambda_star, step_star ) ;
00341 if(min_idx>=0) {
00342 start_idx=min_idx;
00343 }
00344 max_idx = find_lambda_idx( phigh->lambda_max, resp_list->lambda,
00345 start_idx, nlambda_star, step_star ) ;
00346 xsh_msg_dbg_medium( "Indexes[%d]: %d (lambda=%lf), %d (lambda=%lf)",
00347 kh,min_idx, phigh->lambda_min, max_idx,
00348 phigh->lambda_max ) ;
00349
00350
00351
00352
00353
00354 xsh_msg_dbg_low( "Indexes[%d]: %d (lambda=%lf), %d (lambda=%lf)",
00355 kh,min_idx, phigh->lambda_min, max_idx,
00356 phigh->lambda_max ) ;
00357
00358
00359 if(min_idx>=resp_list->size || max_idx>=resp_list->size) {
00360 xsh_msg("min_idx=%d max_idx=%d size=%d",
00361 min_idx,max_idx,resp_list->size);
00362 }
00363
00364
00365
00366
00367
00368
00369
00370 if( (min_idx==-1) && (max_idx == -1) ) {
00371 xsh_msg_debug("The high abs region is longer than the order length");
00372 return cpl_error_get_code();
00373 } else if(min_idx==-1) {
00374 min_idx=0;
00375 min_flux = resp_list->flux[max_idx] ;
00376 max_flux = resp_list->flux[max_idx+min_step] ;
00377 } else if (max_idx == -1) {
00378 max_idx=nlambda_star;
00379 min_flux = resp_list->flux[min_idx-min_step] ;
00380 max_flux = resp_list->flux[min_idx] ;
00381 } else {
00382
00383 min_flux = resp_list->flux[min_idx] ;
00384 max_flux = resp_list->flux[max_idx] ;
00385 }
00386
00387 xsh_msg_dbg_medium( "Min Flux: %le, Max Flux: %le",
00388 min_flux, max_flux ) ;
00389 delta_flux = (max_flux-min_flux)/(min_step) ;
00390
00391 for ( ll = min_idx+1 ; ll < max_idx ; ll++ ) {
00392 cur_flux=min_flux+delta_flux*(ll-min_idx);
00393 xsh_msg_dbg_low( " ==> Interpolate at %lf: %le replaced by %le",
00394 resp_list->lambda[ll],
00395 resp_list->flux[ll], cur_flux ) ;
00396 resp_list->flux[ll] = cur_flux ;
00397 }
00398 }
00399 }
00400
00401 cleanup:
00402
00403
00404 return cpl_error_get_code();
00405 }
00406
00407
00408
00409
00410
00411 static cpl_error_code
00412 xsh_interpolate_high_abs_regions2(xsh_star_flux_list * star_list,
00413 xsh_star_flux_list * resp_list,
00414 HIGH_ABS_REGION * phigh)
00415
00416 {
00417 int kh=0;
00418 int min_idx=0;
00419 int max_idx=0;
00420 double min_flux=0;
00421 double max_flux=0;
00422 double delta_flux=0;
00423 double cur_flux=0;
00424 int ll=0;
00425 int nlambda_star=0;
00426 double step_star=0;
00427 double * lambda_star = NULL;
00428 double lambda_star_min=0;
00429 double lambda_star_max=0;
00430
00431 XSH_ASSURE_NOT_NULL_MSG (star_list,"null input ref std flux table!");
00432 XSH_ASSURE_NOT_NULL_MSG (resp_list,"null input response table!");
00433
00434 nlambda_star = star_list->size ;
00435 lambda_star = star_list->lambda ;
00436 lambda_star_min = *lambda_star ;
00437 lambda_star_max = *(lambda_star+nlambda_star-1) ;
00438 step_star = (lambda_star_max-lambda_star_min)/(nlambda_star-1) ;
00439
00440 if ( phigh != NULL ) {
00441 int i=0;
00442 const int nsampl=5;
00443 cpl_vector* wave=cpl_vector_new(2*nsampl);
00444 cpl_vector* flux=cpl_vector_new(2*nsampl);
00445 cpl_polynomial * poly=NULL;
00446 double mse=0;
00447 const int deg=4;
00448 double flux_interpol=0;
00449 xsh_msg_dbg_medium( "Interpolate in High Absorption Regions" ) ;
00450 for( kh = 0 ; phigh->lambda_min != 0. ; kh++, phigh++ ) {
00451 min_idx = find_lambda_idx_min( phigh->lambda_min, resp_list->lambda,
00452 max_idx, nlambda_star, step_star ) ;
00453 max_idx = find_lambda_idx_max( phigh->lambda_max, resp_list->lambda,
00454 nlambda_star-1, min_idx, step_star ) ;
00455 xsh_msg_dbg_medium( "Indexes[%d]: %d (lambda=%lf), %d (lambda=%lf)",
00456 kh,min_idx, phigh->lambda_min, max_idx,
00457 phigh->lambda_max ) ;
00458
00459
00460
00461
00462
00463 if(min_idx>=resp_list->size || max_idx>=resp_list->size) {
00464 xsh_msg("min_idx=%d max_idx=%d size=%d",
00465 min_idx,max_idx,resp_list->size);
00466 }
00467 for(i=0;i<nsampl;i++) {
00468 cpl_vector_set(wave,i,resp_list->lambda[min_idx+i-nsampl]);
00469 cpl_vector_set(wave,i+nsampl,resp_list->lambda[max_idx+i]);
00470 cpl_vector_set(flux,i,resp_list->flux[min_idx+i-nsampl]);
00471 cpl_vector_set(flux,i+nsampl,resp_list->flux[max_idx+i]);
00472 }
00473
00474
00475
00476
00477
00478 poly=xsh_polynomial_fit_1d_create(wave,flux,deg,&mse);
00479 for(i=min_idx;i<=max_idx;i++) {
00480
00481 flux_interpol=cpl_polynomial_eval_1d(poly,resp_list->lambda[i],NULL);
00482
00483 resp_list->flux[i]=flux_interpol;
00484 }
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 min_flux = resp_list->flux[min_idx] ;
00499 max_flux = resp_list->flux[max_idx] ;
00500 xsh_msg_dbg_medium( "Min Flux: %le, Max Flux: %le",
00501 min_flux, max_flux ) ;
00502 delta_flux = (max_flux-min_flux)/(max_idx-min_idx) ;
00503
00504 cur_flux = min_flux ;
00505 for ( ll = min_idx+1 ; ll < max_idx ; ll++ ) {
00506 cur_flux += delta_flux ;
00507 xsh_msg_dbg_medium( " ==> InSterpolate at %lf: %le replaced by %le",
00508 resp_list->lambda[ll],
00509 resp_list->flux[ll], cur_flux ) ;
00510 resp_list->flux[ll] = cur_flux ;
00511 }
00512 }
00513 xsh_free_vector(&wave);
00514 xsh_free_vector(&flux);
00515
00516 }
00517
00518 cleanup:
00519
00520
00521 return cpl_error_get_code();
00522 }
00523
00537 static cpl_error_code
00538 xsh_response_crea_ascii(xsh_star_flux_list * resp_list,
00539 xsh_star_flux_list * star_list,
00540 double * lambda_spectrum,
00541 double * flux_spectrum,
00542 double * flux_added)
00543 {
00544
00545 FILE * fout ;
00546 int i=0;
00547 int nlambda_star=0;
00548 int nlambda_spectrum=0;
00549 double * lambda_star = NULL;
00550 double * flux_star = NULL ;
00551
00552 XSH_ASSURE_NOT_NULL_MSG (star_list,"null input ref std flux table!");
00553 XSH_ASSURE_NOT_NULL_MSG (resp_list,"null input response table!");
00554
00555 nlambda_star = star_list->size ;
00556 lambda_star = star_list->lambda ;
00557 flux_star = star_list->flux ;
00558
00559 fout = fopen( "summed.dat", "w" ) ;
00560 for( i = 0 ; i < nlambda_star ; i++ ) {
00561 fprintf( fout, "%lf %le\n", resp_list->lambda[i],
00562 flux_added[i] ) ;
00563 }
00564 fclose( fout ) ;
00565
00566 fout = fopen( "response.dat", "w" ) ;
00567 for( i = 0 ; i < nlambda_star ; i++ ) {
00568 fprintf( fout, "%lf %le\n", resp_list->lambda[i],
00569 resp_list->flux[i] ) ;
00570 }
00571 fclose( fout ) ;
00572
00573 fout = fopen( "spectrum.dat", "w" ) ;
00574 for ( i = 0 ; i < nlambda_spectrum ; i++ )
00575 fprintf( fout, "%lf %lf\n", lambda_spectrum[i], flux_spectrum[i] ) ;
00576 fclose( fout ) ;
00577
00578 fout = fopen( "star.dat", "w" ) ;
00579 for ( i = 0 ; i < nlambda_star ; i++ )
00580 fprintf( fout, "%lf %le\n", lambda_star[i], flux_star[i] ) ;
00581 fclose( fout ) ;
00582
00583 cleanup:
00584 return cpl_error_get_code();
00585 }
00586
00587
00588
00589 static cpl_error_code
00590 xsh_flux_integrate_and_corr_for_badpix(int npix_in_interval,
00591 double * flux_spectrum,
00592 int * qual_spectrum,
00593 int if0,int if1,
00594 int i,double** flux_added,int* npixels,int* nbad)
00595
00596 {
00597
00598 double * pf0=NULL;
00599 double * pf1=NULL;
00600 double * pf=NULL;
00601
00602 int * qf0=NULL;
00603 int * qf=NULL;
00604 int i_dif=if1-if0;
00605 XSH_ASSURE_NOT_NULL_MSG (flux_spectrum,"null flux_spectrum !");
00606 XSH_ASSURE_NOT_NULL_MSG (qual_spectrum,"null qual_spectrum !");
00607
00608 if ( (npix_in_interval - i_dif)>0.9 ) {
00609 *nbad = npix_in_interval -i_dif ;
00610 }
00611 pf0 = flux_spectrum + if0 ;
00612 pf1 = flux_spectrum + if1 ;
00613 qf0 = qual_spectrum + if0 ;
00614 for( pf = pf0, qf = qf0 ; pf < pf1 ; pf++, qf++ ) {
00615
00616
00617
00618
00619 (*npixels)++ ;
00620 if ( *qf != QFLAG_GOOD_PIXEL ) {
00621 (*nbad)++ ;
00622 }
00623 else (*flux_added)[i] += *pf;
00624 }
00625
00626 if ( nbad != 0 && (npix_in_interval-*nbad) > 0 ) {
00627 (*flux_added)[i] /= (double)(npix_in_interval-*nbad)/
00628 (double)npix_in_interval ;
00629 }
00630
00631
00632
00633
00634
00635 cleanup:
00636 return cpl_error_get_code();
00637 }
00638
00639
00640 static cpl_error_code
00641 xsh_spectrum_correct(
00642 xsh_star_flux_list * star_list,
00643 xsh_star_flux_list ** obj_list,
00644 xsh_spectrum * spectrum,
00645 cpl_table * atmos_ext_tab,
00646 XSH_ARM the_arm,
00647 double * atmos_K,
00648 double airmass,
00649 double exptime,
00650 double gain)
00651 {
00652
00653 double lambda=0;
00654 double kvalue=0;
00655
00656
00657 double * flux_added = NULL ;
00658 double * lambda_star = NULL;
00659 double * flux_star = NULL ;
00660
00661 double * lambda_spectrum = NULL;
00662 double * plambda=NULL ;
00663 double * flux_spectrum = NULL ;
00664
00665
00666 int i=0;
00667 int size=0;
00668 int nlambda_spectrum=0;
00669 double lambda_spectrum_min=0;
00670 double lambda_spectrum_max=0;
00671 double lambda_star_min=0;
00672 double lambda_star_max=0;
00673 double step_spectrum=0 ;
00674 double step_star=0 ;
00675 int npix_in_interval=0 ;
00676 int bin=1;
00677 int binx=1;
00678 int biny=1;
00679 cpl_frame* obj_integrated=NULL;
00680
00681 check( nlambda_spectrum = xsh_spectrum_get_size( spectrum ) ) ;
00682 check( flux_spectrum = xsh_spectrum_get_flux( spectrum ) ) ;
00683
00684 check( lambda_spectrum_min = xsh_spectrum_get_lambda_min( spectrum ) ) ;
00685 check( lambda_spectrum_max = xsh_spectrum_get_lambda_max( spectrum ) ) ;
00686 check( step_spectrum = xsh_spectrum_get_lambda_step( spectrum ) ) ;
00687
00688
00689 if ( the_arm != XSH_ARM_NIR ) {
00690
00691 check(bin = xsh_pfits_get_biny( spectrum->flux_header )) ;
00692 check(binx = xsh_pfits_get_binx( spectrum->flux_header )) ;
00693 check(biny = xsh_pfits_get_biny( spectrum->flux_header )) ;
00694 }
00695 else {
00696 bin = 1 ;
00697 binx=1;
00698 biny=1;
00699
00700 }
00701
00702 flux_star = star_list->flux ;
00703 size = star_list->size ;
00704 lambda_star = star_list->lambda ;
00705
00706
00707 lambda_star_min = *lambda_star ;
00708 lambda_star_max = *(lambda_star+size-1) ;
00709 step_star = (lambda_star_max-lambda_star_min)/(size-1) ;
00710
00711 xsh_msg( "Spectrum - size %d Nlambda: %d, Min: %lf, Max: %lf, Step: %lf",
00712 size,nlambda_spectrum, lambda_spectrum_min, lambda_spectrum_max,
00713 step_spectrum ) ;
00714 xsh_msg_dbg_low( " - BinX: %d, BinY: %d", binx, biny ) ;
00715
00716
00717 XSH_CALLOC( flux_added, double, size ) ;
00718
00719
00720
00721
00722
00723
00724
00725
00726 XSH_CALLOC( lambda_spectrum, double, nlambda_spectrum ) ;
00727
00728 for( lambda = lambda_spectrum_min, plambda = lambda_spectrum, i = 0 ;
00729 i<nlambda_spectrum ;
00730 i++, plambda++, lambda += step_spectrum )
00731 {
00732 *plambda = lambda ;
00733 }
00734
00735
00736
00737
00738 npix_in_interval = step_star/step_spectrum ;
00739 xsh_msg_dbg_low( "Nb of pixels max in interval: %d", npix_in_interval ) ;
00740
00741
00742 cpl_table* debug = NULL;
00743 double* pwav = NULL;
00744 double* pflux_obs = NULL;
00745 double* pflux_ref = NULL;
00746 double* pflux_corr=NULL;
00747 double* pkavalue = NULL;
00748 double* pobj_atm_corr = NULL;
00749 double* pobj_bin_cor = NULL;
00750 double cor_fct = 0;
00751 debug = cpl_table_new(size);
00752
00753 cpl_table_new_column(debug, "wavelength", CPL_TYPE_DOUBLE);
00754 cpl_table_new_column(debug, "flux_obs", CPL_TYPE_DOUBLE);
00755 cpl_table_new_column(debug, "flux_ref", CPL_TYPE_DOUBLE);
00756 cpl_table_new_column(debug, "flux_obs_cor_gain_bin_exptime", CPL_TYPE_DOUBLE);
00757
00758 cpl_table_new_column(debug, "kvalue", CPL_TYPE_DOUBLE);
00759 cpl_table_new_column(debug, "flux_obs_cor_atm", CPL_TYPE_DOUBLE);
00760 cpl_table_new_column(debug, "flux_obs_cor_obs2ref_bin_size", CPL_TYPE_DOUBLE);
00761
00762 cpl_table_fill_column_window_double(debug, "wavelength", 0, size, 0.);
00763 cpl_table_fill_column_window_double(debug, "flux_obs", 0, size,0.);
00764 cpl_table_fill_column_window_double(debug, "flux_obs_cor_gain_bin_exptime", 0,size, 0.);
00765 cpl_table_fill_column_window_double(debug, "flux_ref", 0, size, 0.);
00766 cpl_table_fill_column_window_double(debug, "kvalue", 0, size, 0.);
00767 cpl_table_fill_column_window_double(debug, "flux_obs_cor_atm", 0, size,0.);
00768 cpl_table_fill_column_window_double(debug, "flux_obs_cor_obs2ref_bin_size", 0, size,0.);
00769
00770 pwav = cpl_table_get_data_double(debug, "wavelength");
00771 pflux_obs = cpl_table_get_data_double(debug, "flux_obs");
00772 pflux_corr = cpl_table_get_data_double(debug, "flux_obs_cor_gain_bin_exptime");
00773 pflux_ref = cpl_table_get_data_double(debug, "flux_ref");
00774 pkavalue = cpl_table_get_data_double(debug, "kvalue");
00775 pobj_atm_corr = cpl_table_get_data_double(debug, "flux_obs_cor_atm");
00776 pobj_bin_cor = cpl_table_get_data_double(debug, "flux_obs_cor_obs2ref_bin_size");
00777 check(*obj_list = xsh_star_flux_list_create( size ));
00778
00779 cor_fct = gain * bin * exptime;
00780
00781
00782
00783 for ( i = 0 ; i < size ; i++ ) {
00784
00785
00786 (*obj_list)->flux[i] = flux_spectrum[i]/cor_fct ;
00787 (*obj_list)->lambda[i] = lambda_star[i] ;
00788
00789 pwav[i]=lambda_star[i];
00790 pflux_corr[i]=(*obj_list)->flux[i];
00791 pflux_obs[i]=flux_spectrum[i];
00792 pflux_ref[i]=flux_star[i];
00793
00794
00795 if ( atmos_ext_tab != NULL ) {
00796 kvalue = pow(10., -airmass*atmos_K[i]*0.4 ) ;
00797 (*obj_list)->flux[i] /= kvalue ;
00798 pobj_atm_corr[i]=(*obj_list)->flux[i];
00799 pkavalue[i]=kvalue;
00800
00801 }
00802
00803
00804 (*obj_list)->flux[i] *= step_star/step_spectrum ;
00805 pobj_bin_cor[i]=(*obj_list)->flux[i];
00806
00807 }
00808
00809 check(cpl_table_duplicate_column(debug,"response",debug,"flux_ref"));
00810
00811 check(cpl_table_divide_columns(debug,"response","flux_obs_cor_obs2ref_bin_size"));
00812
00813 xsh_free_table(&debug);
00814
00815 check(obj_integrated=xsh_star_flux_list_save(*obj_list,"obj_list_corrected.fits","TEST")) ;
00816 xsh_add_temporary_file("obj_list_corrected.fits");
00817
00818 cleanup:
00819
00820 XSH_FREE( lambda_spectrum ) ;
00821 XSH_FREE( flux_added ) ;
00822 xsh_free_frame(&obj_integrated);
00823 xsh_free_table(&debug);
00824 return cpl_error_get_code();
00825
00826 }
00827
00828 static xsh_star_flux_list *
00829 xsh_response_calculate(
00830 xsh_star_flux_list * star_list,
00831 xsh_star_flux_list ** obj_list,
00832 xsh_spectrum * spectrum,
00833 cpl_table * atmos_ext_tab,
00834 XSH_ARM the_arm,
00835 double * atmos_K,
00836 double airmass,
00837 double exptime,
00838 double gain)
00839 {
00840 xsh_star_flux_list * resp_list=NULL;
00841 int npixels = 0;
00842 int nbad = 0 ;
00843
00844 double lambda=0;
00845 double min=0;
00846 double max=0;
00847 double kvalue=0;
00848
00849
00850 double * lambda_resp = NULL ;
00851 double * flux_resp = NULL ;
00852 double * flux_added = NULL ;
00853 double * lambda_star = NULL;
00854 double * flux_star = NULL ;
00855
00856 double * lambda_spectrum = NULL;
00857 double * plambda=NULL ;
00858 double * flux_spectrum = NULL ;
00859 int * qual_spectrum = NULL ;
00860
00861 int i=0;
00862 int if0=0;
00863 int if1=0;
00864 int nlambda_star=0;
00865 int nlambda_spectrum=0;
00866 double lambda_spectrum_min=0;
00867 double lambda_spectrum_max=0;
00868 double lambda_star_min=0;
00869 double lambda_star_max=0;
00870 double step_spectrum=0 ;
00871 double step_star=0 ;
00872 int npix_in_interval=0 ;
00873 int bin=1;
00874 int binx=1;
00875 int biny=1;
00876 cpl_frame* resp_integrated=NULL;
00877 cpl_frame* obj_integrated=NULL;
00878
00879 check( nlambda_spectrum = xsh_spectrum_get_size( spectrum ) ) ;
00880 check( flux_spectrum = xsh_spectrum_get_flux( spectrum ) ) ;
00881 check( qual_spectrum = xsh_spectrum_get_qual( spectrum ) ) ;
00882 check( lambda_spectrum_min = xsh_spectrum_get_lambda_min( spectrum ) ) ;
00883 check( lambda_spectrum_max = xsh_spectrum_get_lambda_max( spectrum ) ) ;
00884 check( step_spectrum = xsh_spectrum_get_lambda_step( spectrum ) ) ;
00885
00886
00887 if ( the_arm != XSH_ARM_NIR ) {
00888
00889 bin = xsh_pfits_get_biny( spectrum->flux_header ) ;
00890 binx = xsh_pfits_get_binx( spectrum->flux_header ) ;
00891 biny = xsh_pfits_get_biny( spectrum->flux_header ) ;
00892 }
00893 else {
00894 bin = 1 ;
00895 binx=1;
00896 biny=1;
00897
00898 }
00899
00900 flux_star = star_list->flux ;
00901 nlambda_star = star_list->size ;
00902 lambda_star = star_list->lambda ;
00903 lambda_star_min = *lambda_star ;
00904 lambda_star_max = *(lambda_star+nlambda_star-1) ;
00905 step_star = (lambda_star_max-lambda_star_min)/(nlambda_star-1) ;
00906
00907 xsh_msg_dbg_low( "Spectrum - Nlambda: %d, Min: %lf, Max: %lf, Step: %lf",
00908 nlambda_spectrum, lambda_spectrum_min, lambda_spectrum_max,
00909 step_spectrum ) ;
00910 xsh_msg_dbg_low( " - BinX: %d, BinY: %d", binx, biny ) ;
00911
00912 XSH_CALLOC( lambda_resp, double, nlambda_star ) ;
00913 XSH_CALLOC( flux_resp, double, nlambda_star ) ;
00914 XSH_CALLOC( flux_added, double, nlambda_star ) ;
00915
00916
00917
00918
00919
00920
00921
00922
00923 XSH_CALLOC( lambda_spectrum, double, nlambda_spectrum ) ;
00924
00925
00926
00927 for( lambda = lambda_spectrum_min, plambda = lambda_spectrum, i = 0 ;
00928 i<nlambda_spectrum ;
00929 i++, plambda++, lambda += step_spectrum )
00930 {
00931 *plambda = lambda ;
00932 }
00933
00934
00935 check( resp_list = xsh_star_flux_list_create( nlambda_star ) ) ;
00936 check( *obj_list = xsh_star_flux_list_create( nlambda_star ) ) ;
00937
00938
00939 npix_in_interval = step_star/step_spectrum ;
00940 xsh_msg_dbg_low( "Nb of pixels max in interval: %d", npix_in_interval ) ;
00941
00942
00943
00944 cpl_table* debug = NULL;
00945 double* pwav = NULL;
00946 double* pflux_spectrum = NULL;
00947 double* pflux_added = NULL;
00948 double* pflux_star = NULL;
00949 double* presp = NULL;
00950 double* pkavalue = NULL;
00951 double* presp_atm_corr = NULL;
00952 double* presp_bin_cor = NULL;
00953 double cor_fct=0;
00954 debug=cpl_table_new(nlambda_star);
00955
00956 cpl_table_new_column(debug, "wavelength", CPL_TYPE_DOUBLE);
00957 cpl_table_new_column(debug, "flux_spectrum", CPL_TYPE_DOUBLE);
00958 cpl_table_new_column(debug, "flux_added", CPL_TYPE_DOUBLE);
00959 cpl_table_new_column(debug, "flux_star", CPL_TYPE_DOUBLE);
00960 cpl_table_new_column(debug, "resp", CPL_TYPE_DOUBLE);
00961 cpl_table_new_column(debug, "kvalue", CPL_TYPE_DOUBLE);
00962 cpl_table_new_column(debug, "resp_atm_corr", CPL_TYPE_DOUBLE);
00963 cpl_table_new_column(debug, "resp_bin_corr", CPL_TYPE_DOUBLE);
00964
00965 cpl_table_fill_column_window_double(debug, "wavelength", 0, nlambda_star, 0.);
00966 cpl_table_fill_column_window_double(debug, "flux_spectrum", 0, nlambda_star,0.);
00967 cpl_table_fill_column_window_double(debug, "flux_added", 0, nlambda_star, 0.);
00968 cpl_table_fill_column_window_double(debug, "flux_star", 0, nlambda_star, 0.);
00969 cpl_table_fill_column_window_double(debug, "resp", 0, nlambda_star, 0.);
00970 cpl_table_fill_column_window_double(debug, "kvalue", 0, nlambda_star, 0.);
00971 cpl_table_fill_column_window_double(debug, "resp_atm_corr", 0, nlambda_star,0.);
00972 cpl_table_fill_column_window_double(debug, "resp_bin_corr", 0, nlambda_star,0.);
00973
00974 pwav = cpl_table_get_data_double(debug,"wavelength");
00975 pflux_spectrum = cpl_table_get_data_double(debug,"flux_spectrum");
00976 pflux_added = cpl_table_get_data_double(debug,"flux_added");
00977 pflux_star = cpl_table_get_data_double(debug,"flux_star");
00978 presp = cpl_table_get_data_double(debug,"resp");
00979 pkavalue = cpl_table_get_data_double(debug,"kvalue");
00980 presp_atm_corr = cpl_table_get_data_double(debug,"resp_atm_corr");
00981 presp_bin_cor = cpl_table_get_data_double(debug,"resp_bin_corr");
00982
00983
00984 cor_fct=gain*bin*exptime;
00985
00986 for ( i = 0 ; i < nlambda_star ; i++ ) {
00987
00988
00989 flux_added[i] = 0. ;
00990 min = lambda_star[i] - step_star/2 ;
00991 max = lambda_star[i] + step_star/2 ;
00992
00993 xsh_msg_dbg_medium( "Lambda_star[%d] = %lf, Min = %lf, Max = %lf", i,
00994 lambda_star[i], min, max ) ;
00995
00996 find_lambda_idx_limit( min, max, lambda_spectrum, if0, nlambda_spectrum,
00997 step_spectrum, &if0, &if1 ) ;
00998
00999 xsh_msg_dbg_low( " Actual nb of pixels in interval: %d/%d", if1-if0,
01000 npix_in_interval ) ;
01001
01002
01003
01004 nbad=0;
01005 xsh_flux_integrate_and_corr_for_badpix(npix_in_interval,flux_spectrum,
01006 qual_spectrum,if0,if1,i,
01007 &flux_added,&npixels,&nbad);
01008
01009
01010 resp_list->flux[i] = flux_star[i]/(flux_added[i]/cor_fct) ;
01011 resp_list->lambda[i] = lambda_star[i] ;
01012
01013
01014 (*obj_list)->flux[i] = flux_added[i] ;
01015 (*obj_list)->lambda[i] = lambda_star[i] ;
01016
01017 pwav[i]=resp_list->lambda[i];
01018 pflux_spectrum[i]=flux_spectrum[i];
01019 pflux_added[i]=flux_added[i];
01020 pflux_star[i]=flux_star[i];
01021 presp[i]=resp_list->flux[i];
01022
01023 xsh_msg_dbg_low(" Flux Star = %le, Integrated = %lf (%d pixels, %d bad)",
01024 flux_star[i], flux_added[i], npixels, nbad ) ;
01025 xsh_msg_dbg_low(" =====> Response at Lambda=%lf: %le",
01026 lambda_star[i], resp_list->flux[i] ) ;
01027
01028
01029
01030
01031
01032
01033 if ( atmos_ext_tab != NULL ) {
01034 kvalue = pow(10., -airmass*atmos_K[i]*0.4 ) ;
01035 resp_list->flux[i] *= kvalue ;
01036 presp_atm_corr[i]=resp_list->flux[i];
01037 pkavalue[i]=kvalue;
01038
01039 }
01040
01041
01042 resp_list->flux[i] *= step_star/step_spectrum ;
01043 presp_bin_cor[i]=resp_list->flux[i];
01044 if0 = if1 ;
01045 }
01046
01047 xsh_free_table(&debug);
01048
01049
01050 if(resp_list->size > 2*FILTER_MEDIAN_HSIZE) {
01051 xsh_star_flux_list_filter_median(resp_list,FILTER_MEDIAN_HSIZE);
01052 }
01053
01054 resp_integrated=xsh_star_flux_list_save(resp_list,"resp_list_integrated.fits","TEST") ;
01055 xsh_add_temporary_file("resp_list_integrated.fits");
01056 obj_integrated=xsh_star_flux_list_save(*obj_list,"obj_list_integrated.fits","TEST") ;
01057 xsh_add_temporary_file("obj_list_integrated.fits");
01058
01059 if ( xsh_debug_level_get() >= XSH_DEBUG_LEVEL_LOW ) {
01060 check(xsh_response_crea_ascii(resp_list,star_list,lambda_spectrum,
01061 flux_spectrum,flux_added));
01062 }
01063
01064 cleanup:
01065
01066 XSH_FREE( lambda_spectrum ) ;
01067 XSH_FREE( lambda_resp ) ;
01068 XSH_FREE( lambda_resp ) ;
01069 XSH_FREE( flux_resp ) ;
01070 XSH_FREE( flux_added ) ;
01071 xsh_free_frame(&resp_integrated);
01072 xsh_free_frame(&obj_integrated);
01073 xsh_free_table(&debug);
01074
01075 if(cpl_error_get_code() == CPL_ERROR_NONE) {
01076 return resp_list;
01077 } else {
01078 return NULL;
01079 }
01080 }
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01264 static xsh_star_flux_list *
01265 do_compute(
01266 xsh_star_flux_list * star_list,
01267 xsh_star_flux_list ** obj_list,
01268 xsh_spectrum * spectrum,
01269 cpl_table * atmos_ext_tab,
01270 HIGH_ABS_REGION * phigh,
01271 double airmass,
01272 double exptime,
01273 double gain,
01274 xsh_instrument * instrument )
01275 {
01276 xsh_star_flux_list * resp_list = NULL ;
01277
01278 int nlambda_star ;
01279
01280 double step_star ;
01281 double * lambda_star = NULL;
01282
01283 double lambda_star_min, lambda_star_max ;
01284
01285
01286
01287 double * atmos_lambda = NULL ;
01288 double * atmos_K = NULL ;
01289 XSH_ARM the_arm ;
01290
01291 XSH_ASSURE_NOT_NULL( star_list ) ;
01292 XSH_ASSURE_NOT_NULL( spectrum ) ;
01293
01294
01295
01296
01297
01298
01299
01300
01301 the_arm=xsh_instrument_get_arm(instrument);
01302
01303
01304
01305 nlambda_star = star_list->size ;
01306 lambda_star = star_list->lambda ;
01307
01308 lambda_star_min = *lambda_star ;
01309 lambda_star_max = *(lambda_star+nlambda_star-1) ;
01310 step_star = (lambda_star_max-lambda_star_min)/(nlambda_star-1) ;
01311 xsh_msg_dbg_low( "Star - Nlambda: %d, Min: %le, Max: %le, Step: %lf",
01312 nlambda_star,
01313 lambda_star_min, lambda_star_max, step_star ) ;
01314
01315 check(xsh_interpolate_atm_ext(star_list,atmos_ext_tab,instrument,
01316 &atmos_lambda,&atmos_K));
01317
01318 check(resp_list=xsh_response_calculate(star_list,obj_list,spectrum,
01319 atmos_ext_tab,the_arm,atmos_K,
01320 airmass,exptime,gain));
01321
01322
01323
01324
01325 for( ; phigh->lambda_min != 0. ; phigh++ ) {
01326
01327 if(phigh->lambda_min < lambda_star_max &&
01328 phigh->lambda_max > lambda_star_min) {
01329
01330
01331
01332 check(xsh_interpolate_high_abs_regions(star_list,resp_list,phigh));
01333 }
01334 }
01335 cleanup:
01336 xsh_msg_dbg_medium( "End compute_response" ) ;
01337 XSH_FREE( atmos_lambda ) ;
01338 XSH_FREE( atmos_K ) ;
01339
01340 return resp_list ;
01341
01342 }
01343
01344
01345
01346 cpl_error_code
01347 xsh_response_merge_obj_std_info(cpl_frame* result,
01348 xsh_star_flux_list * star_list,
01349 xsh_star_flux_list * obj_list)
01350 {
01351
01352 cpl_table* table=NULL;
01353 const char* name=NULL;
01354 cpl_propertylist* plist=NULL;
01355 int nrow=0;
01356 int i=0;
01357
01358 double* pobj=NULL;
01359 double* pref=NULL;
01360 double* pdiv=NULL;
01361
01362 name=cpl_frame_get_filename(result);
01363 plist=cpl_propertylist_load(name,0);
01364 table=cpl_table_load(name,1,0);
01365 nrow=cpl_table_get_nrow(table);
01366
01367 check(cpl_table_name_column(table,"FLUX", "RESPONSE"));
01368 cpl_table_new_column(table,"OBS",CPL_TYPE_DOUBLE);
01369 cpl_table_new_column(table,"REF",CPL_TYPE_DOUBLE);
01370 cpl_table_new_column(table,"REF_DIV_OBS",CPL_TYPE_DOUBLE);
01371 cpl_table_fill_column_window_double(table,"OBS",0,nrow,0);
01372 cpl_table_fill_column_window_double(table,"REF",0,nrow,0);
01373 cpl_table_fill_column_window_double(table,"REF_DIV_OBS",0,nrow,0);
01374
01375 pobj=cpl_table_get_data_double(table,"OBS");
01376 pref=cpl_table_get_data_double(table,"REF");
01377 pdiv=cpl_table_get_data_double(table,"REF_DIV_OBS");
01378
01379 for(i=0;i<nrow;i++) {
01380 pobj[i]=obj_list->flux[i];
01381 pref[i]=star_list->flux[i];
01382 pdiv[i]=pref[i]/pobj[i];
01383 }
01384
01385 cpl_table_save(table,plist,NULL,name,CPL_IO_DEFAULT);
01386
01387 cleanup:
01388 xsh_free_table(&table);
01389 xsh_free_propertylist(&plist);
01390
01391 return cpl_error_get_code();
01392 }
01393
01394
01407 static xsh_star_flux_list *
01408 xsh_obs_std_correct(cpl_frame* obs_std_star, xsh_star_flux_list * ref_std_star_list,
01409 cpl_frame* atmos_ext, HIGH_ABS_REGION * phigh,xsh_instrument* instrument )
01410 {
01411
01412 xsh_star_flux_list * corr_obs_std_star_list=NULL;
01413 double dRA = 0;
01414 double dDEC = 0;
01415 double airmass = 0;
01416 double exptime=0;
01417
01418
01419 check(xsh_frame_sci_get_ra_dec_airmass(obs_std_star, &dRA, &dDEC,&airmass));
01420
01421 const char* filename = NULL;
01422 cpl_propertylist* plist = NULL;
01423
01424 double gain = 0;
01425
01426
01427
01428 check(filename = cpl_frame_get_filename(obs_std_star));
01429 check(plist = cpl_propertylist_load(filename, 0));
01430
01431 airmass=xsh_pfits_get_airm_mean(plist);
01432
01433 if (xsh_instrument_get_arm(instrument) == XSH_ARM_NIR) {
01434
01435 gain = 1. / 2.12;
01436
01437 } else {
01438 check_msg( gain = xsh_pfits_get_gain(plist), "Could not read gain factor");
01439
01440 }
01441 check(exptime=xsh_pfits_get_exptime(plist));
01442
01443
01444
01445 xsh_atmos_ext_list * atmos_ext_list = NULL;
01446 cpl_table* atmos_ext_tab = NULL;
01447
01448 if (atmos_ext != NULL) {
01449 check( atmos_ext_list = xsh_atmos_ext_list_load( atmos_ext) );
01450 filename=cpl_frame_get_filename(atmos_ext);
01451 atmos_ext_tab=cpl_table_load(filename,1,0);
01452 } else {
01453 xsh_msg_warning(
01454 "Missing input %s_%s frame. Skip response and efficiency computation", XSH_ATMOS_EXT, xsh_instrument_arm_tostring(instrument));
01455 }
01456
01457
01458 double * atmos_lambda = NULL ;
01459 double * atmos_K = NULL ;
01460
01461 check(xsh_interpolate_atm_ext(ref_std_star_list,atmos_ext_tab,instrument, &atmos_lambda,&atmos_K));
01462
01463 XSH_ARM the_arm=xsh_instrument_get_arm(instrument);
01464
01465 xsh_spectrum * obs_std_spectrum = NULL ;
01466 check( obs_std_spectrum = xsh_spectrum_load( obs_std_star));
01467 check(xsh_spectrum_correct(ref_std_star_list,&corr_obs_std_star_list,
01468 obs_std_spectrum,atmos_ext_tab,the_arm,
01469 atmos_K,airmass,exptime,gain));
01470
01471
01472 cleanup:
01473 xsh_free_table(&atmos_ext_tab);
01474 xsh_atmos_ext_list_free(&atmos_ext_list);
01475 xsh_free_propertylist(&plist);
01476 XSH_FREE( atmos_lambda ) ;
01477 XSH_FREE( atmos_K ) ;
01478
01479 xsh_spectrum_free( &obs_std_spectrum ) ;
01480 return corr_obs_std_star_list;
01481 }
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580 static cpl_error_code
01581 xsh_std_star_spectra_to_vector_range(xsh_star_flux_list * obs_std_star_list,
01582 const double wmin,
01583 const double wmax,
01584 cpl_vector** vec_wave,
01585 cpl_vector** vec_flux)
01586 {
01587 double* pwave_in=NULL;
01588 double* pflux_in=NULL;
01589
01590 double* pwave_ou=NULL;
01591 double* pflux_ou=NULL;
01592
01593 int size=0;
01594 int i=0;
01595 int k=0;
01596
01597 pwave_in=obs_std_star_list->lambda;
01598 pflux_in=obs_std_star_list->flux;
01599 size=obs_std_star_list->size;
01600
01601 *vec_wave=cpl_vector_new(size);
01602 *vec_flux=cpl_vector_new(size);
01603 pwave_ou=cpl_vector_get_data(*vec_wave);
01604 pflux_ou=cpl_vector_get_data(*vec_flux);
01605
01606 for(i=0;i<size;i++) {
01607 if(pwave_in[i]>=wmin && pwave_in[i]<= wmax) {
01608 pwave_ou[k]=pwave_in[i];
01609 pflux_ou[k]=pflux_in[i];
01610 k++;
01611 }
01612 }
01613 cpl_vector_set_size(*vec_wave,k);
01614 cpl_vector_set_size(*vec_flux,k);
01615
01616 return cpl_error_get_code();
01617 }
01618
01619
01630
01631 cpl_error_code xsh_sort_double_pairs(double *u1, double *u2, cpl_size n)
01632 {
01633 cpl_vector * biu1=NULL;
01634 cpl_vector * biu2=NULL;
01635 cpl_bivector * bi_all=NULL;
01636
01637 if (n < 1)
01638 return cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
01639 cpl_ensure_code(u1 != NULL, CPL_ERROR_NULL_INPUT);
01640 cpl_ensure_code(u2 != NULL, CPL_ERROR_NULL_INPUT);
01641
01642
01643 biu1=cpl_vector_wrap(n,u1);
01644 biu2=cpl_vector_wrap(n,u2);
01645
01646 bi_all=cpl_bivector_wrap_vectors(biu1, biu2);
01647 cpl_bivector_sort(bi_all,bi_all, CPL_SORT_ASCENDING,CPL_SORT_BY_X);
01648
01649
01650
01651
01652 cpl_bivector_unwrap_vectors(bi_all);
01653 cpl_vector_unwrap(biu1);
01654 cpl_vector_unwrap(biu2);
01655
01656 return CPL_ERROR_NONE;
01657 }
01658
01659
01660 static cpl_error_code
01661 xsh_select_line_core(cpl_vector* wave,cpl_vector* flux,const double wguess,const double wrange,cpl_vector** xfit,cpl_vector** yfit)
01662 {
01663
01664 int size=0;
01665 double* pxfit=NULL;
01666 double* pyfit=NULL;
01667 double* pwave=NULL;
01668 double* pflux=NULL;
01669 int i=0;
01670 int k=0;
01671
01672 size=cpl_vector_get_size(wave);
01673 *xfit=cpl_vector_new(size);
01674 *yfit=cpl_vector_new(size);
01675 pxfit=cpl_vector_get_data(*xfit);
01676 pyfit=cpl_vector_get_data(*yfit);
01677
01678 pwave=cpl_vector_get_data(wave);
01679 pflux=cpl_vector_get_data(flux);
01680
01681 k=0;
01682 for(i=0;i<size;i++) {
01683 if(pwave[i]>=(wguess-wrange) &&
01684 pwave[i]<=(wguess+wrange) ) {
01685
01686 pxfit[k]=pwave[i];
01687 pyfit[k]=pflux[i];
01688 k++;
01689 }
01690 }
01691 check(cpl_vector_set_size(*xfit,k));
01692 check(cpl_vector_set_size(*yfit,k));
01693
01694 cleanup:
01695 return cpl_error_get_code();
01696 }
01697
01698 static cpl_error_code
01699 xsh_line_balance(cpl_vector** x,cpl_vector** y,const double ymax)
01700 {
01701
01702 double* px=NULL;
01703 double* py=NULL;
01704 int k=0;
01705 int size=0;
01706 int i=0;
01707
01708 px=cpl_vector_get_data(*x);
01709 py=cpl_vector_get_data(*y);
01710
01711 size=cpl_vector_get_size(*x);
01712
01713 for(i=0;i<size;i++) {
01714 if(py[i] <= ymax) {
01715
01716 px[k]=px[i];
01717 py[k]=py[i];
01718 k++;
01719 }
01720 }
01721 cpl_vector_set_size(*x,k);
01722 cpl_vector_set_size(*y,k);
01723
01724 cleanup:
01725 return cpl_error_get_code();
01726 }
01727
01728
01729 static double
01730 xsh_std_star_spectra_correlate(xsh_star_flux_list * obs_std_star_list,
01731 xsh_star_flux_list * ref_std_star_list,xsh_rv_ref_wave_param* w)
01732
01733 {
01734
01735 double wave_shift = 0;
01736 int naxis1 = 0;
01737 double wstep = 0;
01738 double wmin = 0;
01739 double wmax = 0;
01740
01741
01742 double* prw = 0;
01743 double* prf = 0;
01744 double* pow = 0;
01745 double* pof = 0;
01746
01747
01748 double* pvrf = 0;
01749
01750 double* pvof = 0;
01751 double hbox_wave=0.5;
01752 int hbox = (int)(hbox_wave/wstep+0.5);
01753
01754 int size=0;
01755 int k=0;
01756 int i=0;
01757 int box=2*hbox+1;
01758
01759
01760 naxis1 = xsh_pfits_get_naxis1(obs_std_star_list->header);
01761 wstep = xsh_pfits_get_cdelt1(obs_std_star_list->header);
01762 wmin = xsh_pfits_get_crval1(obs_std_star_list->header);
01763 wmax = wmin + naxis1 * wstep;
01764
01765
01766
01767 wmin=w->wguess-hbox*wstep;
01768 wmax=w->wguess+(hbox+1)*wstep;
01769
01770
01771
01772 cpl_vector* vec_wave_obs = NULL;
01773 cpl_vector* vec_flux_obs = NULL;
01774 cpl_vector* vec_wave_ref=NULL;
01775 cpl_vector* vec_flux_ref=NULL;
01776 cpl_vector* vec_slope_obs=NULL;
01777 cpl_vector* vec_slope_ref=NULL;
01778 cpl_vector* correl=NULL;
01779
01780
01781 wmin=w->range_wmin;
01782 wmax=w->range_wmax;
01783
01784 xsh_std_star_spectra_to_vector_range(obs_std_star_list,wmin,wmax,&vec_wave_obs,&vec_flux_obs);
01785 xsh_std_star_spectra_to_vector_range(ref_std_star_list,wmin,wmax,&vec_wave_ref,&vec_flux_ref);
01786
01787
01788
01789
01790
01791
01792
01793 double wmin_max=w->ipol_wmin_max;
01794 double wmax_min=w->ipol_wmax_min;
01795
01796 vec_slope_obs=xsh_vector_fit_slope(vec_wave_obs,vec_flux_obs,wmin_max,wmax_min,2);
01797 vec_slope_ref=xsh_vector_fit_slope(vec_wave_ref,vec_flux_ref,wmin_max,wmax_min,2);
01798
01799
01800
01801
01802
01803
01804
01805 cpl_vector_divide(vec_flux_obs,vec_slope_obs);
01806 cpl_vector_divide(vec_flux_ref,vec_slope_ref);
01807 xsh_free_vector(&vec_slope_obs);
01808 xsh_free_vector(&vec_slope_ref);
01809
01810 cpl_vector_add_scalar(vec_flux_obs,2);
01811 cpl_vector_add_scalar(vec_flux_ref,2);
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824 double wave_range=w->ipol_hbox;
01825 cpl_vector* xfit_obs=NULL;
01826 cpl_vector* yfit_obs=NULL;
01827 cpl_vector* xfit_ref=NULL;
01828 cpl_vector* yfit_ref=NULL;
01829 double* pxfit=NULL;
01830 double* pyfit=NULL;
01831 double* pwave=NULL;
01832 double* pflux=NULL;
01833
01834
01835 xsh_select_line_core(vec_wave_obs,vec_flux_obs,w->wguess,wave_range,&xfit_obs,&yfit_obs);
01836
01837
01838
01839
01840 xsh_select_line_core(vec_wave_ref,vec_flux_ref,w->wguess,wave_range,&xfit_ref,&yfit_ref);
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863 int size_x=k;
01864 int size_x_obs=0;
01865 int size_x_ref=0;
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910 hbox=cpl_vector_get_size(vec_flux_ref);
01911
01912
01913
01914 cpl_polynomial* poly_fit_obs=NULL;
01915
01916
01917 double mse=0;
01918 double* pindex=NULL;
01919 poly_fit_obs=xsh_polynomial_fit_1d_create(xfit_obs,yfit_obs,4,&mse);
01920
01921 cpl_vector* yfit_pol_obs=NULL;
01922 cpl_vector* yfit_index=NULL;
01923 size_x_obs=cpl_vector_get_size(xfit_obs);
01924 yfit_pol_obs=cpl_vector_new(size_x_obs);
01925 yfit_index=cpl_vector_new(size_x_obs);
01926 check(pyfit=cpl_vector_get_data(yfit_pol_obs));
01927 check(pxfit=cpl_vector_get_data(xfit_obs));
01928 check(pindex=cpl_vector_get_data(yfit_index));
01929
01930 for(i=0;i<size_x_obs;i++) {
01931 pyfit[i]=cpl_polynomial_eval_1d(poly_fit_obs,pxfit[i],NULL);
01932 pindex[i]=i;
01933 }
01934 xsh_free_polynomial(&poly_fit_obs);
01935
01936 double ymin=0;
01937 double xmin=0;
01938
01939
01940 xsh_sort_double_pairs(pyfit,pindex,size_x_obs);
01941
01942
01943 xmin=pxfit[(int)pindex[0]];
01944 ymin=pyfit[0];
01945 xsh_free_vector(&yfit_index);
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970 double peakpos_obs=xmin;
01971 double peakpos_ref=w->wguess;
01972 xsh_msg("Pos guess: %g obs: %10.8g Pos ref: %10.8g diff=%10.8g",
01973 w->wguess,peakpos_obs,peakpos_ref,peakpos_obs-peakpos_ref);
01974
01975
01976 xsh_msg("Now compute shift by spectra correlation");
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042 wave_shift=peakpos_obs-peakpos_ref;
02043
02044
02045 cleanup:
02046
02047 xsh_free_vector(&yfit_pol_obs);
02048 xsh_free_vector(&xfit_obs);
02049 xsh_free_vector(&yfit_obs);
02050 xsh_free_vector(&xfit_ref);
02051 xsh_free_vector(&yfit_ref);
02052 xsh_free_vector(&vec_wave_obs);
02053 xsh_free_vector(&vec_flux_obs);
02054 xsh_free_vector(&vec_wave_ref);
02055 xsh_free_vector(&vec_flux_ref);
02056 xsh_free_vector(&correl);
02057
02058 return wave_shift;
02059 }
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230 static xsh_star_flux_list *
02231 xsh_bspline_fit(xsh_star_flux_list * ref_std_star_list,HIGH_ABS_REGION * phigh,xsh_instrument* inst)
02232 {
02233 xsh_star_flux_list * result=NULL;
02234 size_t n = 0;
02235 size_t order = 4;
02236 size_t ncoeffs = 0;
02237 size_t nbreak = 0;
02238
02239 size_t i, j;
02240 gsl_bspline_workspace *bw;
02241 gsl_vector *B;
02242 double dy;
02243 gsl_rng *r;
02244 gsl_vector *c, *w;
02245 gsl_vector * x, *y;
02246 gsl_matrix *X, *cov;
02247 gsl_multifit_linear_workspace *mw;
02248 double chisq=0, Rsq=0, dof=0;
02249
02250
02251
02252
02253 double* wave = NULL;
02254 double* response = NULL;
02255 double* pwav = NULL;
02256 double* pfit = NULL;
02257
02258 double dump_factor = 1.e10;
02259
02260 cpl_table* tab_resp_fit = NULL;
02261
02262
02263
02264 if (xsh_instrument_get_arm(inst) == XSH_ARM_UVB) {
02265 ncoeffs = 21;
02266 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_VIS) {
02267 ncoeffs = 16;
02268 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_NIR) {
02269 ncoeffs = 6;
02270 }
02271 nbreak = ncoeffs + 2 - order;
02272
02273 n = ref_std_star_list->size ;
02274 wave = ref_std_star_list->lambda ;
02275 response = ref_std_star_list->flux ;
02276
02277
02278
02279
02280 gsl_rng_env_setup();
02281 r = gsl_rng_alloc(gsl_rng_default);
02282
02283
02284 bw = gsl_bspline_alloc(order, nbreak);
02285 B = gsl_vector_alloc(ncoeffs);
02286
02287 x = gsl_vector_alloc(n);
02288 y = gsl_vector_alloc(n);
02289 X = gsl_matrix_alloc(n, ncoeffs);
02290 c = gsl_vector_alloc(ncoeffs);
02291 w = gsl_vector_alloc(n);
02292 cov = gsl_matrix_alloc(ncoeffs, ncoeffs);
02293 mw = gsl_multifit_linear_alloc(n, ncoeffs);
02294
02295
02296
02297 for (i = 0; i < n; ++i) {
02298 double sigma;
02299 double xi = (double) wave[i];
02300 double yi = (double) response[i];
02301
02302 sigma = 0.001 * yi;
02303 dy = gsl_ran_gaussian(r, sigma);
02304 yi += dy;
02305
02306 gsl_vector_set(x, i, xi);
02307
02308 if(isnan(yi) || isinf(yi)) {
02309 gsl_vector_set(y, i, 0);
02310 gsl_vector_set(w, i, 1.0 / dump_factor);
02311
02312 } else {
02313 gsl_vector_set(y, i, yi);
02314 gsl_vector_set(w, i, 1.0 / (sigma * sigma));
02315
02316 }
02317
02318 }
02319
02320 if (phigh != NULL) {
02321
02322 xsh_msg("Flag High Absorption Regions" );
02323 for (; phigh->lambda_min != 0.; phigh++) {
02324 xsh_msg("Flag [%g,%g]",phigh->lambda_min,phigh->lambda_max);
02325 for (i = 0; i < n; i++) {
02326 if (wave[i] >= phigh->lambda_min && wave[i] <= phigh->lambda_max) {
02327
02328 gsl_vector_set(w, i, 1.0 / dump_factor);
02329
02330 }
02331 }
02332 }
02333 }
02334
02335
02336 gsl_bspline_knots_uniform(wave[0], wave[n - 1], bw);
02337
02338
02339 for (i = 0; i < n; ++i) {
02340 double xi = gsl_vector_get(x, i);
02341
02342
02343 gsl_bspline_eval(xi, B, bw);
02344
02345
02346 for (j = 0; j < ncoeffs; ++j) {
02347 double Bj = gsl_vector_get(B, j);
02348 gsl_matrix_set(X, i, j, Bj);
02349 }
02350 }
02351
02352
02353 gsl_multifit_wlinear(X, w, y, c, cov, &chisq, mw);
02354
02355 dof = n - ncoeffs;
02356
02357
02358
02359
02360 printf("chisq/dof = %e, Rsq = %f\n", chisq / dof, Rsq);
02361
02362 tab_resp_fit = cpl_table_new(n);
02363 cpl_table_new_column(tab_resp_fit, "wave", CPL_TYPE_DOUBLE);
02364 cpl_table_new_column(tab_resp_fit, "fit", CPL_TYPE_DOUBLE);
02365 cpl_table_fill_column_window_double(tab_resp_fit, "wave", 0, n, 0);
02366 cpl_table_fill_column_window_double(tab_resp_fit, "fit", 0, n, 0);
02367 pwav = cpl_table_get_data_double(tab_resp_fit, "wave");
02368 pfit = cpl_table_get_data_double(tab_resp_fit, "fit");
02369 result=xsh_star_flux_list_create(n);
02370
02371 {
02372 double xi, yi, yerr;
02373
02374 for (i = 0; i < n; i++) {
02375 xi = (double) wave[i];
02376 gsl_bspline_eval(xi, B, bw);
02377 gsl_multifit_linear_est(B, c, cov, &yi, &yerr);
02378
02379 pwav[i] = xi;
02380 pfit[i] = yi;
02381 result->lambda[i]=xi;
02382 result->flux[i]=yi;
02383 }
02384 }
02385
02386
02387
02388
02389 gsl_rng_free(r);
02390 gsl_bspline_free(bw);
02391 gsl_vector_free(B);
02392 gsl_vector_free(x);
02393 gsl_vector_free(y);
02394 gsl_matrix_free(X);
02395 gsl_vector_free(c);
02396 gsl_vector_free(w);
02397 gsl_matrix_free(cov);
02398 gsl_multifit_linear_free(mw);
02399 xsh_free_table(&tab_resp_fit);
02400
02401 return result;
02402 }
02403
02404
02405
02406 double *
02407 xsh_bspline_interpolate_data_at_pos(double* wave, double* flux,const int size,
02408 double* pos, const int size_pos)
02409 {
02410 double * result=NULL;
02411 double xi, yi;
02412 gsl_interp_accel *acc = gsl_interp_accel_alloc ();
02413 int i=0;
02414
02415 gsl_spline *spline = gsl_spline_alloc (gsl_interp_cspline, size);
02416
02417 gsl_spline_init (spline, wave, flux, size);
02418
02419
02420 result=cpl_calloc(size_pos, sizeof(double));
02421
02422
02423 for (i = 0; i < size_pos; i ++) {
02424 xi = pos[i];
02425
02426
02427 yi = gsl_spline_eval (spline, xi, acc);
02428 result[i]=yi;
02429
02430 }
02431
02432 gsl_spline_free (spline);
02433 gsl_interp_accel_free (acc);
02434
02435 return result;
02436 }
02437
02438
02439
02440
02441
02442
02443 double *
02444 xsh_bspline_fit_data(double* wave, double* flux,const int size,
02445 HIGH_ABS_REGION * phigh,xsh_instrument* inst, const int fit_region)
02446 {
02447 double * result=NULL;
02448 size_t n = 0;
02449 size_t order = 4;
02450 size_t ncoeffs = 0;
02451 size_t nbreak = 0;
02452
02453 size_t i, j;
02454 gsl_bspline_workspace *bw;
02455 gsl_vector *B;
02456 double dy;
02457 gsl_rng *r;
02458 gsl_vector *c, *w;
02459 gsl_vector * x, *y;
02460 gsl_matrix *X, *cov;
02461 gsl_multifit_linear_workspace *mw;
02462 double chisq=0, Rsq=0, dof=0;
02463
02464
02465
02466
02467
02468
02469 double* pwav = NULL;
02470 double* pfit = NULL;
02471
02472 double dump_factor_in = 1.e10;
02473 double dump_factor_ou = 1.e10;
02474
02475 cpl_table* tab_resp_fit = NULL;
02476
02477 double dump_factor=1.e10;
02478
02479 if(fit_region){
02480 dump_factor_in = 1.;
02481 dump_factor_ou = 1.e10;
02482 } else {
02483 dump_factor_in = 1.e10;
02484 dump_factor_ou = 1;
02485 }
02486
02487 if (xsh_instrument_get_arm(inst) == XSH_ARM_UVB) {
02488 ncoeffs = 21;
02489 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_VIS) {
02490 ncoeffs = 16;
02491 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_NIR) {
02492 ncoeffs = 6;
02493 }
02494 nbreak = ncoeffs + 2 - order;
02495
02496 n = size ;
02497
02498
02499
02500
02501
02502
02503 gsl_rng_env_setup();
02504 r = gsl_rng_alloc(gsl_rng_default);
02505
02506
02507 bw = gsl_bspline_alloc(order, nbreak);
02508 B = gsl_vector_alloc(ncoeffs);
02509
02510 x = gsl_vector_alloc(n);
02511 y = gsl_vector_alloc(n);
02512 X = gsl_matrix_alloc(n, ncoeffs);
02513 c = gsl_vector_alloc(ncoeffs);
02514 w = gsl_vector_alloc(n);
02515 cov = gsl_matrix_alloc(ncoeffs, ncoeffs);
02516 mw = gsl_multifit_linear_alloc(n, ncoeffs);
02517
02518
02519
02520 for (i = 0; i < n; ++i) {
02521 double sigma;
02522 double xi = wave[i];
02523 double yi = flux[i];
02524 sigma = 0.001 * yi;
02525
02526 dy = gsl_ran_gaussian(r, sigma);
02527 yi += dy;
02528
02529 gsl_vector_set(x, i, xi);
02530
02531 if(isnan(yi) || isinf(yi)) {
02532 gsl_vector_set(y, i, 0);
02533 gsl_vector_set(w, i, 1.0 / dump_factor);
02534
02535 } else {
02536 gsl_vector_set(y, i, yi);
02537 gsl_vector_set(w, i, 1.0 / (sigma * sigma));
02538
02539 }
02540
02541
02542 }
02543 printf("Dump factor in %g out %g\n", dump_factor_in, dump_factor_ou);
02544 if (phigh != NULL) {
02545
02546 xsh_msg("Flag High Absorption Regions" );
02547 for (; phigh->lambda_min != 0.; phigh++) {
02548 xsh_msg("Flag [%g,%g]",phigh->lambda_min,phigh->lambda_max);
02549 for (i = 0; i < n; i++) {
02550
02551 if (wave[i] >= phigh->lambda_min && wave[i] <= phigh->lambda_max) {
02552
02553 gsl_vector_set(w, i, gsl_vector_get(w, i) / dump_factor_in);
02554
02555 } else {
02556
02557 gsl_vector_set(w, i, gsl_vector_get(w, i) / dump_factor_ou);
02558
02559 }
02560 }
02561 }
02562 }
02563
02564
02565 gsl_bspline_knots_uniform(wave[0], wave[n - 1], bw);
02566
02567
02568 for (i = 0; i < n; ++i) {
02569 double xi = gsl_vector_get(x, i);
02570
02571
02572 gsl_bspline_eval(xi, B, bw);
02573
02574
02575 for (j = 0; j < ncoeffs; ++j) {
02576 double Bj = gsl_vector_get(B, j);
02577 gsl_matrix_set(X, i, j, Bj);
02578 }
02579 }
02580
02581
02582 gsl_multifit_wlinear(X, w, y, c, cov, &chisq, mw);
02583
02584 dof = n - ncoeffs;
02585
02586
02587
02588
02589 printf("chisq/dof = %e, Rsq = %f\n", chisq / dof, Rsq);
02590
02591 tab_resp_fit = cpl_table_new(n);
02592 cpl_table_new_column(tab_resp_fit, "wave", CPL_TYPE_DOUBLE);
02593 cpl_table_new_column(tab_resp_fit, "fit", CPL_TYPE_DOUBLE);
02594 cpl_table_fill_column_window_double(tab_resp_fit, "wave", 0, n, 0);
02595 cpl_table_fill_column_window_double(tab_resp_fit, "fit", 0, n, 0);
02596 pwav = cpl_table_get_data_double(tab_resp_fit, "wave");
02597 pfit = cpl_table_get_data_double(tab_resp_fit, "fit");
02598 result=cpl_calloc(n, sizeof(double));
02599
02600 {
02601 double xi, yi, yerr;
02602
02603 for (i = 0; i < n; i++) {
02604 xi = (double) wave[i];
02605 gsl_bspline_eval(xi, B, bw);
02606 gsl_multifit_linear_est(B, c, cov, &yi, &yerr);
02607
02608 pwav[i] = xi;
02609 pfit[i] = yi;
02610
02611 result[i]=yi;
02612 }
02613 }
02614
02615
02616
02617
02618 xsh_free_table(&tab_resp_fit);
02619 gsl_rng_free(r);
02620 gsl_bspline_free(bw);
02621 gsl_vector_free(B);
02622 gsl_vector_free(x);
02623 gsl_vector_free(y);
02624 gsl_matrix_free(X);
02625 gsl_vector_free(c);
02626 gsl_vector_free(w);
02627 gsl_matrix_free(cov);
02628 gsl_multifit_linear_free(mw);
02629
02630
02631 return result;
02632 }
02633
02634
02635
02636
02637
02638
02639 double *
02640 xsh_bspline_fit_data2(double* wave, double* flux,const int size,
02641 HIGH_ABS_REGION * phigh,xsh_instrument* inst, const int fit_region)
02642 {
02643 double * result=NULL;
02644 size_t n = 0;
02645 size_t order = 4;
02646 size_t ncoeffs = 0;
02647 size_t nbreak = 0;
02648
02649 size_t i, j;
02650 gsl_bspline_workspace *bw;
02651 gsl_vector *B;
02652 gsl_vector *Bkpts;
02653 double dy;
02654 gsl_rng *r;
02655 gsl_vector *c, *w;
02656 gsl_vector * x, *y;
02657 gsl_matrix *X, *cov;
02658 gsl_multifit_linear_workspace *mw;
02659 double chisq=0, Rsq=0, dof=0;
02660
02661
02662
02663
02664
02665
02666 double* pwav = NULL;
02667 double* pfit = NULL;
02668
02669
02670
02671
02672 cpl_table* tab_resp_fit = NULL;
02673
02674 double dump_factor=1.e10;
02675 double *Bkpts_ptr;
02676
02677
02678 if (xsh_instrument_get_arm(inst) == XSH_ARM_UVB) {
02679 ncoeffs = 21;
02680 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_VIS) {
02681 ncoeffs = 16;
02682 } else if (xsh_instrument_get_arm(inst) == XSH_ARM_NIR) {
02683 ncoeffs = 12;
02684 } else {
02685 xsh_msg("instrument arm not set");
02686 exit(0);
02687 }
02688 nbreak = ncoeffs + 2 - order;
02689
02690 n = size ;
02691
02692
02693
02694
02695
02696 gsl_rng_env_setup();
02697 r = gsl_rng_alloc(gsl_rng_default);
02698
02699
02700 bw = gsl_bspline_alloc(order, nbreak);
02701
02702 B = gsl_vector_alloc(ncoeffs);
02703
02704 Bkpts = gsl_vector_alloc(nbreak);
02705
02706
02707 x = gsl_vector_alloc(n);
02708 y = gsl_vector_alloc(n);
02709 X = gsl_matrix_alloc(n, ncoeffs);
02710 c = gsl_vector_alloc(ncoeffs);
02711 w = gsl_vector_alloc(n);
02712
02713 cov = gsl_matrix_alloc(ncoeffs, ncoeffs);
02714
02715 mw = gsl_multifit_linear_alloc(n, ncoeffs);
02716
02717
02718
02719
02720 for (i = 0; i < n; ++i) {
02721 double sigma;
02722 double xi = wave[i];
02723 double yi = flux[i];
02724
02725
02726 sigma = 0.001 * yi;
02727 dy = gsl_ran_gaussian(r, sigma);
02728 yi += dy;
02729
02730 gsl_vector_set(x, i, xi);
02731 if(isnan(yi) || isinf(yi)) {
02732 gsl_vector_set(y, i, 0);
02733 gsl_vector_set(w, i, 1.0 / dump_factor);
02734
02735 } else {
02736 gsl_vector_set(y, i, yi);
02737 gsl_vector_set(w, i, 1.0 / (sigma * sigma));
02738
02739 }
02740
02741
02742
02743
02744
02745 }
02746
02747
02748
02749
02750
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771 Bkpts_ptr=gsl_vector_ptr(Bkpts,0);
02772 int nfit_div_nbreak=n/nbreak;
02773
02774
02775 for(i=0;i<nbreak;i++) {
02776 Bkpts_ptr[i]=wave[i*nfit_div_nbreak];
02777
02778
02779
02780
02781 }
02782 Bkpts_ptr[0]=wave[0];
02783 Bkpts_ptr[nbreak-1]=wave[n-1];
02784 gsl_bspline_knots(Bkpts, bw);
02785
02786
02787
02788 for (i = 0; i < n; ++i) {
02789 double xi = gsl_vector_get(x, i);
02790
02791
02792 gsl_bspline_eval(xi, B, bw);
02793
02794
02795 for (j = 0; j < ncoeffs; ++j) {
02796 double Bj = gsl_vector_get(B, j);
02797 gsl_matrix_set(X, i, j, Bj);
02798 }
02799 }
02800
02801
02802
02803 gsl_multifit_wlinear(X, w, y, c, cov, &chisq, mw);
02804
02805 dof = n - ncoeffs;
02806
02807
02808
02809
02810 printf("chisq/dof = %e, Rsq = %f\n", chisq / dof, Rsq);
02811
02812 tab_resp_fit = cpl_table_new(n);
02813 cpl_table_new_column(tab_resp_fit, "wave", CPL_TYPE_DOUBLE);
02814 cpl_table_new_column(tab_resp_fit, "fit", CPL_TYPE_DOUBLE);
02815 cpl_table_fill_column_window_double(tab_resp_fit, "wave", 0, n, 0);
02816 cpl_table_fill_column_window_double(tab_resp_fit, "fit", 0, n, 0);
02817 pwav = cpl_table_get_data_double(tab_resp_fit, "wave");
02818 pfit = cpl_table_get_data_double(tab_resp_fit, "fit");
02819 result=cpl_calloc(n, sizeof(double));
02820
02821 {
02822 double xi, yi, yerr;
02823
02824 for (i = 0; i < n; i++) {
02825 xi = (double) wave[i];
02826 gsl_bspline_eval(xi, B, bw);
02827 gsl_multifit_linear_est(B, c, cov, &yi, &yerr);
02828
02829 pwav[i] = xi;
02830 pfit[i] = yi;
02831
02832 result[i]=yi;
02833 }
02834 }
02835
02836
02837
02838
02839
02840 xsh_free_table(&tab_resp_fit);
02841 gsl_rng_free(r);
02842 gsl_bspline_free(bw);
02843 gsl_vector_free(B);
02844 gsl_vector_free(Bkpts);
02845 gsl_vector_free(x);
02846 gsl_vector_free(y);
02847 gsl_matrix_free(X);
02848 gsl_vector_free(c);
02849 gsl_vector_free(w);
02850 gsl_matrix_free(cov);
02851 gsl_multifit_linear_free(mw);
02852
02853
02854 return result;
02855 }
02856
02857
02874 cpl_frame * xsh_compute_response2( cpl_frame * obs_std_star,
02875 cpl_frame * flux_std_star_cat,
02876 cpl_frame * atmos_ext,
02877 cpl_frame* high_abs,
02878 cpl_frame* tell_mod_cat,
02879 xsh_instrument * instrument,
02880 double exptime,
02881 const int tell_corr )
02882 {
02883
02884 cpl_frame* result = NULL;
02885
02886 XSH_ASSURE_NOT_NULL( obs_std_star ) ;
02887 XSH_ASSURE_NOT_NULL( flux_std_star_cat ) ;
02888 XSH_ASSURE_NOT_NULL( instrument ) ;
02889
02890 double dRA = 0;
02891 double dDEC = 0;
02892 double airmass = 0;
02893
02894 double wmin = 0;
02895 double wmax = 0;
02896 double wstep = 0;
02897 int naxis1 = 0;
02898 double cdelt1 = 0;
02899 const char* filename = NULL;
02900 cpl_propertylist* plist = NULL;
02901 int is_complete=0;
02902 cpl_frame* ipol_ref_std_star_frame=NULL;
02903 xsh_star_flux_list * ref_std_star_list = NULL;
02904 cpl_frame* frm_tmp=NULL;
02905 xsh_star_flux_list * obs_std_star_list = NULL;
02906 xsh_spectrum* obs_spectrum;
02907 cpl_table* tbl_shift_std_spectrum=NULL;
02908 cpl_frame* shift_std_star_frame=NULL;
02909 const char* tbl_shift_std_fname="shift_flux_std_star.fits";
02910 HIGH_ABS_REGION * phigh = NULL;
02911 cpl_frame* ipol_shift_std_star_frame=NULL;
02912 xsh_star_flux_list * shift_std_star_list = NULL;
02913 xsh_star_flux_list * corr_obs_std_star_list = NULL;
02914 xsh_star_flux_list * response =NULL;
02915 xsh_star_flux_list * response_fit =NULL;
02916 xsh_rv_ref_wave_param* rv_ref_wave=NULL;
02917
02918
02919
02920 filename = cpl_frame_get_filename(obs_std_star);
02921 check(plist = cpl_propertylist_load(filename, 0));
02922
02923 naxis1 = xsh_pfits_get_naxis1(plist);
02924 cdelt1 = xsh_pfits_get_cdelt1(plist);
02925 wstep=cdelt1;
02926 wmin = xsh_pfits_get_crval1(plist);
02927 xsh_free_propertylist(&plist);
02928
02929
02930 filename=cpl_frame_get_filename(flux_std_star_cat);
02931 plist=cpl_propertylist_load(filename,0);
02932 is_complete=cpl_propertylist_has(plist,"WRANGE");
02933 xsh_free_propertylist(&plist);
02934
02935
02936 wmax = wmin + cdelt1 * naxis1;
02937
02938
02939 cpl_table* tbl_ref_std_spectrum = NULL;
02940
02941
02942 xsh_frame_sci_get_ra_dec_airmass(obs_std_star,&dRA,&dDEC,&airmass);
02943 xsh_std_star_id std_star_id=0;
02944
02945
02946 if (CPL_ERROR_NONE
02947 != xsh_parse_catalog_std_stars(flux_std_star_cat, dRA, dDEC,
02948 STAR_MATCH_DEPSILON, &tbl_ref_std_spectrum,&std_star_id)) {
02949 xsh_msg_warning(
02950 "Problem parsing input STD catalog. For robustness recipe goes on.");
02951 xsh_msg_warning("%s", cpl_error_get_message());
02952 cpl_error_reset();
02953 xsh_free_table(&tbl_ref_std_spectrum);
02954 return NULL;
02955 }
02956
02957
02958
02959 cpl_frame* ref_std_star_frame=NULL;
02960 const char* tbl_ref_std_fname="ref_flux_std_star.fits";
02961 check(cpl_table_save(tbl_ref_std_spectrum,NULL,NULL,tbl_ref_std_fname,
02962 CPL_IO_DEFAULT));
02963 xsh_add_temporary_file(tbl_ref_std_fname);
02964
02965 check(ref_std_star_frame=xsh_frame_product(tbl_ref_std_fname,"FLUX_STD_STAR",
02966 CPL_FRAME_TYPE_TABLE,
02967 CPL_FRAME_GROUP_PRODUCT,
02968 CPL_FRAME_LEVEL_INTERMEDIATE));
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978 check(ipol_ref_std_star_frame=xsh_spectrum_interpolate_linear(ref_std_star_frame,wstep,wmin,wmax));
02979 check( ref_std_star_list = xsh_star_flux_list_load( ipol_ref_std_star_frame ) ) ;
02980 xsh_free_frame(&ipol_ref_std_star_frame);
02981 xsh_free_frame(&ref_std_star_frame);
02982
02983
02984 if( xsh_instrument_get_arm(instrument) == XSH_ARM_UVB && is_complete!=0){
02985 check(xsh_star_flux_list_extrapolate_wave_end(ref_std_star_list,545.));
02986 frm_tmp=xsh_star_flux_list_save( ref_std_star_list,"extrapol_ref_std_star_list.fits", "TEST" ) ;
02987 xsh_free_frame(&frm_tmp);
02988 }
02989
02990
02991 if(xsh_instrument_get_arm(instrument) == XSH_ARM_NIR && tell_corr == 1 && tell_mod_cat!= NULL) {
02992 xsh_msg("Telluric correction");
02993 cpl_table* tab_res=NULL;
02994
02995 cpl_size model_idx=0;
02996
02997 check(obs_std_star_list = xsh_star_flux_list_load_spectrum(obs_std_star)) ;
02998
02999 check( obs_spectrum = xsh_spectrum_load( obs_std_star));
03000 check(tab_res=xsh_telluric_model_eval(tell_mod_cat,obs_spectrum,instrument,
03001 &model_idx));
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013 double* pwav=NULL;
03014 double* pflx=NULL;
03015 int i=0;
03016
03017 check(pwav = cpl_table_get_data_double(tab_res, "wavelength"));
03018
03019 check(pflx = cpl_table_get_data_double(tab_res, "ratio"));
03020
03021
03022
03023
03024 for(i=0;i<obs_std_star_list->size;i++) {
03025 obs_std_star_list->lambda[i]=pwav[i];
03026 obs_std_star_list->flux[i]=pflx[i];
03027 }
03028
03029 xsh_free_table(&tab_res);
03030
03031 xsh_free_frame(&frm_tmp);
03032 check(xsh_star_flux_list_to_frame(obs_std_star_list,obs_std_star));
03033
03034 } else {
03035 check(obs_std_star_list = xsh_star_flux_list_load_spectrum(obs_std_star)) ;
03036
03037 xsh_free_frame(&frm_tmp);
03038
03039 }
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049 rv_ref_wave=xsh_rv_ref_wave_param_create();
03050
03051
03052
03053 xsh_rv_ref_wave_init(std_star_id ,xsh_instrument_get_arm(instrument),rv_ref_wave);
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073 frm_tmp=xsh_star_flux_list_save( ref_std_star_list,"ref_flux_std_star.fits", "TEST" ) ;
03074 xsh_free_frame(&frm_tmp);
03075 double wave_shift=0;
03076
03077 wave_shift=xsh_std_star_spectra_correlate(obs_std_star_list,ref_std_star_list,rv_ref_wave);
03078
03079
03080 double offset=(wave_shift)/rv_ref_wave->wguess;
03081 xsh_msg("wave: guess[nm] %g RV shift[nm] %g offset[unitless]=%g",rv_ref_wave->wguess,wave_shift,offset);
03082
03083 tbl_shift_std_spectrum=xsh_table_shift_rv(tbl_ref_std_spectrum,"LAMBDA",offset);
03084
03085 xsh_free_table(&tbl_ref_std_spectrum);
03086
03087 check(cpl_table_save(tbl_shift_std_spectrum,NULL,NULL,tbl_shift_std_fname,
03088 CPL_IO_DEFAULT));
03089
03090
03091 xsh_add_temporary_file(tbl_shift_std_fname);
03092 xsh_free_table(& tbl_shift_std_spectrum);
03093 check(shift_std_star_frame=xsh_frame_product(tbl_shift_std_fname,"FLUX_STD_STAR",
03094 CPL_FRAME_TYPE_TABLE,
03095 CPL_FRAME_GROUP_PRODUCT,
03096 CPL_FRAME_LEVEL_INTERMEDIATE));
03097
03098
03099
03100
03101
03102
03103
03104 check(phigh=xsh_fill_high_abs_regions(instrument,high_abs));
03105
03106 check(ipol_shift_std_star_frame=xsh_spectrum_interpolate_linear(shift_std_star_frame,wstep,wmin,wmax));
03107
03108 check( shift_std_star_list = xsh_star_flux_list_load( ipol_shift_std_star_frame ) ) ;
03109 xsh_free_frame(&ipol_shift_std_star_frame);
03110 xsh_free_frame(&shift_std_star_frame);
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130 check( corr_obs_std_star_list = xsh_obs_std_correct(obs_std_star, shift_std_star_list, atmos_ext, phigh,instrument ) ) ;
03131
03132
03133
03134
03135
03136
03137 check(response=xsh_star_flux_list_duplicate(ref_std_star_list));
03138
03139
03140
03141
03142 check(xsh_star_flux_list_divide(response,corr_obs_std_star_list));
03143
03144
03145
03146
03147
03148 check(xsh_star_flux_list_filter_median(response, 7 ));
03149
03150
03151 int hsize=(int)(1./wstep+0.5);
03152
03153 check(xsh_star_flux_list_filter_lowpass(response,CPL_LOWPASS_LINEAR, hsize ));
03154
03155 xsh_free_frame(&frm_tmp);
03156
03157
03158
03159
03160
03161
03162
03163
03164 response_fit=xsh_bspline_fit(response,phigh,instrument);
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179 char tag[256];
03180 char fname[256];
03181
03182 sprintf(tag,"RESPONSE_MERGE1D_%s_%s",xsh_instrument_mode_tostring(instrument),
03183 xsh_instrument_arm_tostring(instrument));
03184 sprintf(fname,"%s.fits",tag);
03185
03186 check( result = xsh_star_flux_list_save( response_fit, fname, tag ) ) ;
03187 check(xsh_response_merge_obj_std_info(result,ref_std_star_list, corr_obs_std_star_list));
03188
03189 cleanup:
03190
03191 xsh_rv_ref_wave_param_destroy(rv_ref_wave);
03192 xsh_free_table(&tbl_ref_std_spectrum);
03193 xsh_star_flux_list_free(&ref_std_star_list);
03194 xsh_star_flux_list_free(&obs_std_star_list);
03195 xsh_star_flux_list_free(&shift_std_star_list);
03196 xsh_star_flux_list_free(&corr_obs_std_star_list);
03197 xsh_star_flux_list_free(&response);
03198 xsh_star_flux_list_free(&response_fit);
03199
03200 return result;
03201 }
03202
03203
03204
03205
03206
03222 cpl_frame * xsh_compute_response( cpl_frame * spectrum_frame,
03223 cpl_frame * flux_std_star_cat_frame,
03224 cpl_frame * atmos_ext_frame,
03225 cpl_frame* high_abs_frame,
03226 xsh_instrument * instrument,
03227 double exptime )
03228 {
03229 cpl_frame * result = NULL ;
03230 xsh_star_flux_list * star_list = NULL ;
03231 xsh_star_flux_list * obj_list = NULL ;
03232 xsh_spectrum * spectrum = NULL ;
03233 cpl_frame * tmp_spectrum_frame = NULL ;
03234 xsh_star_flux_list * resp_list = NULL ;
03235 xsh_atmos_ext_list * atmos_ext_list = NULL ;
03236 char tag[256];
03237 char fname[256];
03238
03239 cpl_frame* flux_std_star_frame=NULL;
03240 double dRA=0;
03241 double dDEC=0;
03242 cpl_table* tbl_ref_std_spectrum=NULL;
03243 const char* tbl_ref_std_fname="ref_flux_std_star.fits";
03244 cpl_frame* ipol_flux_std_star_frame=NULL;
03245 cpl_frame* resampl_flux_std_star_frame=NULL;
03246
03247
03248 double wmin=0;
03249 double wmax=0;
03250 int naxis1=0;
03251 double cdelt1=0;
03252 const char* filename=NULL;
03253 cpl_propertylist* plist=NULL;
03254 char * name=NULL;
03255 char * pcatg=NULL;
03256 cpl_table* atmos_ext_tab=NULL;
03257 double airmass=0;
03258 double gain=1.;
03259
03260 HIGH_ABS_REGION * phigh=NULL;
03261
03262 XSH_ASSURE_NOT_NULL( spectrum_frame ) ;
03263 XSH_ASSURE_NOT_NULL( flux_std_star_cat_frame ) ;
03264 XSH_ASSURE_NOT_NULL( instrument ) ;
03265
03266
03267 xsh_msg("Compute instrument response");
03268
03269
03270 xsh_frame_sci_get_ra_dec_airmass(spectrum_frame,&dRA,&dDEC,&airmass);
03271
03272 xsh_std_star_id std_star_id=0;
03273
03274 if(CPL_ERROR_NONE != xsh_parse_catalog_std_stars(flux_std_star_cat_frame,
03275 dRA,dDEC,
03276 STAR_MATCH_DEPSILON,
03277 &tbl_ref_std_spectrum,&std_star_id)){
03278 xsh_msg_warning("Problem parsing input STD catalog. For robustness recipe goes on.");
03279 xsh_msg_warning("%s",cpl_error_get_message());
03280 cpl_error_reset();
03281 xsh_free_table(&tbl_ref_std_spectrum);
03282 return NULL;
03283 }
03284
03285
03286 check(cpl_table_save(tbl_ref_std_spectrum,NULL,NULL,tbl_ref_std_fname,
03287 CPL_IO_DEFAULT));
03288 xsh_add_temporary_file(tbl_ref_std_fname);
03289 check(flux_std_star_frame=xsh_frame_product(tbl_ref_std_fname,"FLUX_STD_STAR",
03290 CPL_FRAME_TYPE_TABLE,
03291 CPL_FRAME_GROUP_PRODUCT,
03292 CPL_FRAME_LEVEL_INTERMEDIATE));
03293
03294 filename=cpl_frame_get_filename(spectrum_frame);
03295 plist=cpl_propertylist_load(filename,0);
03296 naxis1=xsh_pfits_get_naxis1(plist);
03297 cdelt1=xsh_pfits_get_cdelt1(plist);
03298 wmin=xsh_pfits_get_crval1(plist);
03299
03300
03301 if( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
03302
03303 gain=1./2.12;
03304
03305 } else {
03306 check_msg( gain = xsh_pfits_get_gain(plist),
03307 "Could not read gain factor");
03308
03309 }
03310
03311 xsh_free_propertylist(&plist);
03312 wmax=wmin+cdelt1*naxis1;
03313
03314 check(ipol_flux_std_star_frame=xsh_spectrum_interpolate(flux_std_star_frame,
03315 1,
03316 wmin,wmax));
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326 check(resampl_flux_std_star_frame=xsh_spectrum_resample(ipol_flux_std_star_frame,
03327 INTERPOL_WSTEP_NM,
03328 wmin,wmax,instrument));
03329
03330
03331 check( star_list = xsh_star_flux_list_load( resampl_flux_std_star_frame ) ) ;
03332
03333
03334 check( spectrum = xsh_spectrum_load( spectrum_frame));
03335 pcatg=cpl_sprintf("SPECTRUM_%s",xsh_instrument_arm_tostring( instrument));
03336 name=cpl_sprintf("%s.fits",pcatg);
03337 tmp_spectrum_frame=xsh_spectrum_save( spectrum,name,pcatg);
03338 xsh_add_temporary_file(name);
03339 cpl_free(pcatg);
03340 cpl_free(name);
03341
03342
03343 if ( atmos_ext_frame != NULL ) {
03344 check( atmos_ext_list = xsh_atmos_ext_list_load( atmos_ext_frame ) ) ;
03345 xsh_msg( "ATMOS EXT Loaded" ) ;
03346
03347 check(filename=cpl_frame_get_filename(atmos_ext_frame));
03348 check(atmos_ext_tab=cpl_table_load(filename,1,0));
03349 } else {
03350 xsh_msg_warning("Missing input %s_%s frame. Skip response and efficiency computation",
03351 XSH_ATMOS_EXT,xsh_instrument_arm_tostring(instrument));
03352 }
03353
03354
03355 check(phigh=xsh_fill_high_abs_regions(instrument,high_abs_frame));
03356
03357 check( resp_list = do_compute( star_list, &obj_list, spectrum, atmos_ext_tab,
03358 phigh,airmass,exptime,gain,instrument ) ) ;
03359
03360
03361
03362
03363 sprintf(tag,"RESPONSE_MERGE1D_%s_%s",xsh_instrument_mode_tostring(instrument),
03364 xsh_instrument_arm_tostring(instrument));
03365 sprintf(fname,"%s.fits",tag);
03366 check( result = xsh_star_flux_list_save( resp_list, fname, tag ) ) ;
03367 xsh_msg("***********************************");
03368 check(xsh_response_merge_obj_std_info(result,star_list, obj_list));
03369
03370 cleanup:
03371 if(high_abs_frame!=NULL) {
03372 cpl_free(phigh);
03373 }
03374 xsh_spectrum_free( &spectrum ) ;
03375
03376 xsh_star_flux_list_free( &star_list ) ;
03377 xsh_star_flux_list_free( &obj_list ) ;
03378 xsh_star_flux_list_free( &resp_list ) ;
03379 xsh_free_table(&tbl_ref_std_spectrum);
03380 xsh_free_frame(&flux_std_star_frame);
03381 xsh_free_frame(&ipol_flux_std_star_frame);
03382 xsh_free_frame(&resampl_flux_std_star_frame);
03383 xsh_free_frame(&tmp_spectrum_frame);
03384
03385
03386 xsh_atmos_ext_list_free(&atmos_ext_list) ;
03387 xsh_free_propertylist(&plist);
03388 xsh_free_table(&atmos_ext_tab);
03389
03390 return result ;
03391 }
03392
03408 cpl_frame * xsh_compute_response_ord( cpl_frame * spectrum_frame,
03409 cpl_frame * flux_std_star_cat_frame,
03410 cpl_frame * atmos_ext_frame,
03411 cpl_frame * high_abs_win_frame,
03412 xsh_instrument * instrument,
03413 double exptime )
03414 {
03415 cpl_frame * result = NULL ;
03416 xsh_star_flux_list * star_list = NULL ;
03417 xsh_star_flux_list * obj_list = NULL ;
03418 xsh_spectrum * spectrum = NULL ;
03419 cpl_frame * tmp_spectrum_frame = NULL ;
03420 xsh_star_flux_list * resp_list = NULL ;
03421 xsh_atmos_ext_list * atmos_ext_list = NULL ;
03422
03423 char tag[256];
03424 char fname[256];
03425 cpl_frame* flux_std_star_frame=NULL;
03426 double dRA=0;
03427 double dDEC=0;
03428 cpl_table* tbl_ref_std_spectrum=NULL;
03429 const char* tbl_ref_std_fname="ref_flux_std_star.fits";
03430 cpl_frame* ipol_flux_std_star_frame=NULL;
03431 double wmin=0;
03432 double wmax=0;
03433 int naxis1=0;
03434 double cdelt1=0;
03435 const char* filename=NULL;
03436 cpl_propertylist* plist=NULL;
03437 char * name=NULL;
03438 char * pcatg=NULL;
03439 cpl_table* atmos_ext_tab=NULL;
03440 double airmass=0;
03441 double gain=1.;
03442
03443 int next=0;
03444
03445 int ext=0;
03446
03447 HIGH_ABS_REGION * phigh=NULL;
03448
03449 xsh_std_star_id std_star_id=0;
03450
03451 XSH_ASSURE_NOT_NULL( spectrum_frame ) ;
03452 XSH_ASSURE_NOT_NULL( flux_std_star_cat_frame ) ;
03453 XSH_ASSURE_NOT_NULL( instrument ) ;
03454 XSH_ASSURE_NOT_NULL( fname ) ;
03455
03456 xsh_msg("Compute instrument response");
03457
03458 xsh_frame_sci_get_ra_dec_airmass(spectrum_frame,&dRA,&dDEC,&airmass);
03459
03460
03461 if(CPL_ERROR_NONE != xsh_parse_catalog_std_stars(flux_std_star_cat_frame,
03462 dRA,dDEC,
03463 STAR_MATCH_DEPSILON,
03464 &tbl_ref_std_spectrum,&std_star_id)){
03465 xsh_msg_warning("Problem parsing input STD catalog. For robustness recipe goes on.");
03466 xsh_msg_warning("%s",cpl_error_get_message());
03467 cpl_error_reset();
03468 xsh_free_table(&tbl_ref_std_spectrum);
03469 return NULL;
03470 }
03471
03472
03473 check(cpl_table_save(tbl_ref_std_spectrum,NULL,NULL,tbl_ref_std_fname,
03474 CPL_IO_DEFAULT));
03475 xsh_add_temporary_file(tbl_ref_std_fname);
03476
03477 check(flux_std_star_frame=xsh_frame_product(tbl_ref_std_fname,"FLUX_STD_STAR",
03478 CPL_FRAME_TYPE_TABLE,
03479 CPL_FRAME_GROUP_PRODUCT,
03480 CPL_FRAME_LEVEL_INTERMEDIATE));
03481
03482
03483 if ( atmos_ext_frame != NULL ) {
03484 check( atmos_ext_list = xsh_atmos_ext_list_load( atmos_ext_frame ) ) ;
03485 xsh_msg( "ATMOS EXT Loaded" ) ;
03486
03487 check(filename=cpl_frame_get_filename(atmos_ext_frame));
03488 check(atmos_ext_tab=cpl_table_load(filename,1,0));
03489 }
03490
03491
03492
03493 filename=cpl_frame_get_filename(spectrum_frame);
03494 next=cpl_frame_get_nextensions(spectrum_frame);
03495
03496
03497 plist=cpl_propertylist_load(filename,0);
03498 if( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
03499
03500 gain=1./2.12;
03501
03502 } else {
03503 check_msg( gain = xsh_pfits_get_gain(plist),
03504 "Could not read gain factor");
03505
03506 }
03507 xsh_free_propertylist(&plist);
03508
03509 check(phigh=xsh_fill_high_abs_regions(instrument,high_abs_win_frame));
03510
03511 for(ext=0;ext<next;ext+=3) {
03512
03513 xsh_free_propertylist(&plist);
03514 plist=cpl_propertylist_load(filename,ext);
03515 naxis1=xsh_pfits_get_naxis1(plist);
03516 cdelt1=xsh_pfits_get_cdelt1(plist);
03517 wmin=xsh_pfits_get_crval1(plist);
03518 wmax=wmin+cdelt1*naxis1;
03519
03520 xsh_free_frame(&ipol_flux_std_star_frame);
03521 check(ipol_flux_std_star_frame=xsh_spectrum_interpolate(flux_std_star_frame,
03522 INTERPOL_WSTEP_NM,
03523 wmin,wmax));
03524
03525 xsh_star_flux_list_free( &star_list ) ;
03526 check( star_list = xsh_star_flux_list_load( ipol_flux_std_star_frame ) ) ;
03527
03528 xsh_spectrum_free( &spectrum ) ;
03529 check( spectrum=xsh_spectrum_load_order(spectrum_frame,instrument,ext)) ;
03530 pcatg=cpl_sprintf("SPECTRUM_%s",xsh_instrument_arm_tostring( instrument));
03531 name=cpl_sprintf("%s.fits",pcatg);
03532 xsh_free_frame(&tmp_spectrum_frame);
03533
03534 tmp_spectrum_frame=xsh_spectrum_save_order( spectrum,name,pcatg,ext);
03535 xsh_add_temporary_file(name);
03536
03537 cpl_free(pcatg);
03538 cpl_free(name);
03539
03540
03541 xsh_star_flux_list_free( &resp_list ) ;
03542 xsh_star_flux_list_free( &obj_list ) ;
03543 check(resp_list=do_compute( star_list, &obj_list, spectrum, atmos_ext_tab,
03544 phigh,airmass, exptime, gain, instrument ) ) ;
03545
03546
03547
03548
03549
03550 sprintf(tag,"RESPONSE_ORDER1D_%s_%s",xsh_instrument_mode_tostring(instrument),
03551 xsh_instrument_arm_tostring(instrument));
03552 sprintf(fname,"%s.fits",tag);
03553 xsh_free_frame(&result);
03554
03555 check(result=xsh_star_flux_list_save_order(resp_list,fname,tag,ext)) ;
03556
03557 }
03558
03559 cleanup:
03560
03561 if(high_abs_win_frame!=NULL) {
03562 cpl_free(phigh);
03563 }
03564 xsh_spectrum_free( &spectrum ) ;
03565 xsh_star_flux_list_free( &star_list ) ;
03566 xsh_star_flux_list_free( &resp_list ) ;
03567 xsh_star_flux_list_free( &obj_list ) ;
03568
03569 xsh_free_table(&tbl_ref_std_spectrum);
03570 xsh_free_frame(&flux_std_star_frame);
03571 xsh_free_frame(&ipol_flux_std_star_frame);
03572 xsh_free_frame(&tmp_spectrum_frame);
03573
03574 xsh_atmos_ext_list_free(&atmos_ext_list) ;
03575 xsh_free_propertylist(&plist);
03576 xsh_free_table(&atmos_ext_tab);
03577
03578 return result ;
03579 }
03580