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
00044 #include <xsh_dfs.h>
00045 #include <xsh_error.h>
00046 #include <xsh_msg.h>
00047 #include <cpl.h>
00048 #include <string.h>
00049 #include <time.h>
00050 #include <xsh_utils_table.h>
00051 #include <xsh_data_star_flux.h>
00052 #include <xsh_data_atmos_ext.h>
00053 #include <xsh_data_spectrum.h>
00054 #include <xsh_pfits.h>
00055 #include <xsh_utils.h>
00056 #include <xsh_drl.h>
00057 #include <xsh_utils_efficiency.h>
00058 #include <xsh_efficiency_response.h>
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #define INTERPOL_WSTEP_NM 2
00069 #define FILTER_MEDIAN_HSIZE 3
00070
00071 static int
00072 find_lambda_idx( double lambda, double * wave, int from, int to,
00073 double step )
00074 {
00075 int idx ;
00076 double * pwave ;
00077
00078 for( idx = from, pwave = wave+from ; idx < to ; pwave++, idx++ ) {
00079 if ( *pwave >= (lambda-step/2) && *pwave < (lambda+step/2) ) return idx ;
00080 }
00081
00082 return -1 ;
00083 }
00084
00085 static void
00086 find_lambda_idx_limit( double min, double max, double * spectrum,
00087 int from, int to, double step,
00088 int * if0, int * if1 )
00089 {
00090 int idx ;
00091 double *pspec ;
00092
00093 xsh_msg_dbg_high( "From: %d, To: %d, step: %lf, min: %lf, max: %lf",
00094 from, to, step, min, max ) ;
00095
00096 for( idx = from, pspec = spectrum+from ; idx < to ; pspec++, idx++ ) {
00097 xsh_msg_dbg_high( " Search Min - Spectrum_lambda: %lf (%lf)", *pspec,
00098 min-(step/2.) ) ;
00099 if ( *pspec >= (min-(step/2.)) ) break ;
00100 }
00101 *if0 = idx ;
00102 for( ; idx < to ; pspec++, idx++ ) {
00103 xsh_msg_dbg_high( " Search Max - Spectrum_lambda: %lf", *pspec ) ;
00104 if ( *pspec > (max+(step/2.)) ) break ;
00105 }
00106 *if1 = idx-1 ;
00107
00108 xsh_msg_dbg_low( "Lambda Min: %lf, Max: %lf (in [%lf,%lf[",
00109 spectrum[*if0], spectrum[*if1], min, max ) ;
00110 if ( *if1 > to ) *if1 = to ;
00111
00112 return ;
00113 }
00114
00125 static cpl_error_code
00126 xsh_interpolate_atm_ext(xsh_star_flux_list * star_list,
00127 cpl_table*atmos_ext_tab,
00128 xsh_instrument* instrument,
00129 double** atmos_lambda,
00130 double** atmos_K)
00131 {
00132
00133 int nrow=0;
00134 double* pk=0;
00135 double* pw=0;
00136 int j=0 ;
00137 int nlambda_star=0 ;
00138 double * lambda_star = NULL;
00139
00140 XSH_ASSURE_NOT_NULL_MSG (star_list,"null input ref std flux table!");
00141 XSH_ASSURE_NOT_NULL_MSG (atmos_ext_tab,"null input atm ext table!");
00142
00143 nlambda_star = star_list->size ;
00144 lambda_star = star_list->lambda ;
00145
00146
00147
00148 XSH_CALLOC( *atmos_lambda, double, nlambda_star ) ;
00149 XSH_CALLOC( *atmos_K, double, nlambda_star ) ;
00150 if(!cpl_table_has_column(atmos_ext_tab,XSH_ATMOS_EXT_LIST_COLNAME_K)){
00151 xsh_msg_warning("You are using an obsolete atm extinction line table");
00152 cpl_table_duplicate_column(atmos_ext_tab,XSH_ATMOS_EXT_LIST_COLNAME_K,
00153 atmos_ext_tab,XSH_ATMOS_EXT_LIST_COLNAME_OLD);
00154 }
00155 cpl_table_cast_column(atmos_ext_tab,XSH_ATMOS_EXT_LIST_COLNAME_K,"K",CPL_TYPE_DOUBLE);
00156 cpl_table_cast_column(atmos_ext_tab,"LAMBDA","WAVE",CPL_TYPE_DOUBLE);
00157
00158 nrow=cpl_table_get_nrow(atmos_ext_tab);
00159 pw=cpl_table_get_data_double(atmos_ext_tab,"WAVE");
00160 pk=cpl_table_get_data_double(atmos_ext_tab,"K");
00161
00162 if( xsh_instrument_get_arm(instrument) != XSH_ARM_NIR){
00163 for( j = 0 ; j<nlambda_star ; j++) {
00164
00165 (*atmos_lambda)[j] = lambda_star[j] ;
00166 (*atmos_K)[j] = xsh_data_interpolate((*atmos_lambda)[j],nrow,pw,pk);
00167
00168
00169 }
00170 } else {
00171 for( j = 0 ; j<nlambda_star ; j++) {
00172
00173 (*atmos_lambda)[j] = lambda_star[j] ;
00174 (*atmos_K)[j] = 0;
00175
00176
00177 }
00178 }
00179
00180 cpl_table_erase_column(atmos_ext_tab,"WAVE");
00181 cpl_table_erase_column(atmos_ext_tab,"K");
00182
00183
00184 cleanup:
00185 return cpl_error_get_code();
00186 }
00187
00196 static cpl_error_code
00197 xsh_interpolate_high_abs_regions(xsh_star_flux_list * star_list,
00198 xsh_star_flux_list * resp_list,
00199 HIGH_ABS_REGION * phigh)
00200
00201 {
00202 int kh=0;
00203 int min_idx=0;
00204 int max_idx=0;
00205 double min_flux=0;
00206 double max_flux=0;
00207 double delta_flux=0;
00208 double cur_flux=0;
00209 int ll=0;
00210 int nlambda_star=0;
00211 double step_star=0;
00212 double * lambda_star = NULL;
00213 double lambda_star_min=0;
00214 double lambda_star_max=0;
00215
00216 XSH_ASSURE_NOT_NULL_MSG (star_list,"null input ref std flux table!");
00217 XSH_ASSURE_NOT_NULL_MSG (resp_list,"null input response table!");
00218
00219 nlambda_star = star_list->size ;
00220 lambda_star = star_list->lambda ;
00221 lambda_star_min = *lambda_star ;
00222 lambda_star_max = *(lambda_star+nlambda_star-1) ;
00223 step_star = (lambda_star_max-lambda_star_min)/(nlambda_star-1) ;
00224
00225 if ( phigh != NULL ) {
00226
00227 xsh_msg_dbg_medium( "Interpolate in High Absorption Regions" ) ;
00228 for( kh = 0 ; phigh->lambda_min != 0. ; kh++, phigh++ ) {
00229
00230 min_idx = find_lambda_idx( phigh->lambda_min, resp_list->lambda,
00231 0, nlambda_star, step_star ) ;
00232 max_idx = find_lambda_idx( phigh->lambda_max, resp_list->lambda,
00233 min_idx, nlambda_star, step_star ) ;
00234 xsh_msg_dbg_medium( "Indexes[%d]: %d (lambda=%lf), %d (lambda=%lf)",
00235 kh,min_idx, phigh->lambda_min, max_idx,
00236 phigh->lambda_max ) ;
00237
00238 if(min_idx>=resp_list->size || max_idx>=resp_list->size) {
00239 xsh_msg("min_idx=%d max_idx=%d size=%d",
00240 min_idx,max_idx,resp_list->size);
00241 }
00242
00243 min_flux = resp_list->flux[min_idx] ;
00244 max_flux = resp_list->flux[max_idx] ;
00245 xsh_msg_dbg_medium( "Min Flux: %le, Max Flux: %le",
00246 min_flux, max_flux ) ;
00247 delta_flux = (max_flux-min_flux)/(max_idx-min_idx) ;
00248
00249 cur_flux = min_flux ;
00250 for ( ll = min_idx+1 ; ll < max_idx ; ll++ ) {
00251 cur_flux += delta_flux ;
00252 xsh_msg_dbg_medium( " ==> InSterpolate at %lf: %le replaced by %le",
00253 resp_list->lambda[ll],
00254 resp_list->flux[ll], cur_flux ) ;
00255 resp_list->flux[ll] = cur_flux ;
00256 }
00257 }
00258 }
00259
00260 cleanup:
00261
00262
00263 return cpl_error_get_code();
00264 }
00265
00279 static cpl_error_code
00280 xsh_response_crea_ascii(xsh_star_flux_list * resp_list,
00281 xsh_star_flux_list * star_list,
00282 double * lambda_spectrum,
00283 double * flux_spectrum,
00284 double * flux_added)
00285 {
00286
00287 FILE * fout ;
00288 int i=0;
00289 int nlambda_star=0;
00290 int nlambda_spectrum=0;
00291 double * lambda_star = NULL;
00292 double * flux_star = NULL ;
00293
00294 XSH_ASSURE_NOT_NULL_MSG (star_list,"null input ref std flux table!");
00295 XSH_ASSURE_NOT_NULL_MSG (resp_list,"null input response table!");
00296
00297 nlambda_star = star_list->size ;
00298 lambda_star = star_list->lambda ;
00299 flux_star = star_list->flux ;
00300
00301 fout = fopen( "summed.dat", "w" ) ;
00302 for( i = 0 ; i < nlambda_star ; i++ ) {
00303 fprintf( fout, "%lf %le\n", resp_list->lambda[i],
00304 flux_added[i] ) ;
00305 }
00306 fclose( fout ) ;
00307
00308 fout = fopen( "response.dat", "w" ) ;
00309 for( i = 0 ; i < nlambda_star ; i++ ) {
00310 fprintf( fout, "%lf %le\n", resp_list->lambda[i],
00311 resp_list->flux[i] ) ;
00312 }
00313 fclose( fout ) ;
00314
00315 fout = fopen( "spectrum.dat", "w" ) ;
00316 for ( i = 0 ; i < nlambda_spectrum ; i++ )
00317 fprintf( fout, "%lf %lf\n", lambda_spectrum[i], flux_spectrum[i] ) ;
00318 fclose( fout ) ;
00319
00320 fout = fopen( "star.dat", "w" ) ;
00321 for ( i = 0 ; i < nlambda_star ; i++ )
00322 fprintf( fout, "%lf %le\n", lambda_star[i], flux_star[i] ) ;
00323 fclose( fout ) ;
00324
00325 cleanup:
00326 return cpl_error_get_code();
00327 }
00328
00329
00330
00331 static cpl_error_code
00332 xsh_flux_integrate_and_corr_for_badpix(int npix_in_interval,
00333 double * flux_spectrum,
00334 int * qual_spectrum,
00335 int if0,int if1,
00336 int i,double** flux_added,int* npixels,int* nbad)
00337
00338 {
00339
00340 double * pf0=NULL;
00341 double * pf1=NULL;
00342 double * pf=NULL;
00343
00344 int * qf0=NULL;
00345 int * qf=NULL;
00346 int i_dif=if1-if0;
00347 XSH_ASSURE_NOT_NULL_MSG (flux_spectrum,"null flux_spectrum !");
00348 XSH_ASSURE_NOT_NULL_MSG (qual_spectrum,"null qual_spectrum !");
00349
00350 if ( (npix_in_interval - i_dif)>0.9 ) {
00351 *nbad = npix_in_interval -i_dif ;
00352 }
00353 pf0 = flux_spectrum + if0 ;
00354 pf1 = flux_spectrum + if1 ;
00355 qf0 = qual_spectrum + if0 ;
00356 for( pf = pf0, qf = qf0 ; pf < pf1 ; pf++, qf++ ) {
00357
00358
00359
00360
00361 (*npixels)++ ;
00362 if ( *qf != QFLAG_GOOD_PIXEL ) {
00363 (*nbad)++ ;
00364 }
00365 else (*flux_added)[i] += *pf;
00366 }
00367
00368 if ( nbad != 0 && (npix_in_interval-*nbad) > 0 ) {
00369 (*flux_added)[i] /= (double)(npix_in_interval-*nbad)/
00370 (double)npix_in_interval ;
00371 }
00372
00373
00374
00375
00376
00377 cleanup:
00378 return cpl_error_get_code();
00379 }
00380
00381
00382 static xsh_star_flux_list *
00383 xsh_response_calculate(
00384 xsh_star_flux_list * star_list,
00385 xsh_star_flux_list ** obj_list,
00386 xsh_spectrum * spectrum,
00387 cpl_table * atmos_ext_tab,
00388 XSH_ARM the_arm,
00389 double * atmos_K,
00390 double airmass,
00391 double exptime,
00392 double gain)
00393 {
00394 xsh_star_flux_list * resp_list=NULL;
00395 int npixels = 0;
00396 int nbad = 0 ;
00397
00398 double lambda=0;
00399 double min=0;
00400 double max=0;
00401 double kvalue=0;
00402
00403
00404 double * lambda_resp = NULL ;
00405 double * flux_resp = NULL ;
00406 double * flux_added = NULL ;
00407 double * lambda_star = NULL;
00408 double * flux_star = NULL ;
00409
00410 double * lambda_spectrum = NULL;
00411 double * plambda=NULL ;
00412 double * flux_spectrum = NULL ;
00413 int * qual_spectrum = NULL ;
00414
00415 int i=0;
00416 int if0=0;
00417 int if1=0;
00418 int nlambda_star=0;
00419 int nlambda_spectrum=0;
00420 double lambda_spectrum_min=0;
00421 double lambda_spectrum_max=0;
00422 double lambda_star_min=0;
00423 double lambda_star_max=0;
00424 double step_spectrum=0 ;
00425 double step_star=0 ;
00426 int npix_in_interval=0 ;
00427 int bin=1;
00428 int binx=1;
00429 int biny=1;
00430 cpl_frame* resp_integrated=NULL;
00431 cpl_frame* obj_integrated=NULL;
00432
00433 check( nlambda_spectrum = xsh_spectrum_get_size( spectrum ) ) ;
00434 check( flux_spectrum = xsh_spectrum_get_flux( spectrum ) ) ;
00435 check( qual_spectrum = xsh_spectrum_get_qual( spectrum ) ) ;
00436 check( lambda_spectrum_min = xsh_spectrum_get_lambda_min( spectrum ) ) ;
00437 check( lambda_spectrum_max = xsh_spectrum_get_lambda_max( spectrum ) ) ;
00438 check( step_spectrum = xsh_spectrum_get_lambda_step( spectrum ) ) ;
00439
00440
00441 if ( the_arm != XSH_ARM_NIR ) {
00442
00443 bin = xsh_pfits_get_biny( spectrum->flux_header ) ;
00444 binx = xsh_pfits_get_binx( spectrum->flux_header ) ;
00445 biny = xsh_pfits_get_biny( spectrum->flux_header ) ;
00446 }
00447 else {
00448 bin = 1 ;
00449 binx=1;
00450 biny=1;
00451
00452 }
00453
00454 flux_star = star_list->flux ;
00455 nlambda_star = star_list->size ;
00456 lambda_star = star_list->lambda ;
00457 lambda_star_min = *lambda_star ;
00458 lambda_star_max = *(lambda_star+nlambda_star-1) ;
00459 step_star = (lambda_star_max-lambda_star_min)/(nlambda_star-1) ;
00460
00461 xsh_msg_dbg_low( "Spectrum - Nlambda: %d, Min: %lf, Max: %lf, Step: %lf",
00462 nlambda_spectrum, lambda_spectrum_min, lambda_spectrum_max,
00463 step_spectrum ) ;
00464 xsh_msg_dbg_low( " - BinX: %d, BinY: %d", binx, biny ) ;
00465
00466 XSH_CALLOC( lambda_resp, double, nlambda_star ) ;
00467 XSH_CALLOC( flux_resp, double, nlambda_star ) ;
00468 XSH_CALLOC( flux_added, double, nlambda_star ) ;
00469
00470
00471
00472
00473
00474
00475
00476
00477 XSH_CALLOC( lambda_spectrum, double, nlambda_spectrum ) ;
00478
00479
00480
00481 for( lambda = lambda_spectrum_min, plambda = lambda_spectrum, i = 0 ;
00482 i<nlambda_spectrum ;
00483 i++, plambda++, lambda += step_spectrum )
00484 {
00485 *plambda = lambda ;
00486 }
00487
00488
00489 check( resp_list = xsh_star_flux_list_create( nlambda_star ) ) ;
00490 check( *obj_list = xsh_star_flux_list_create( nlambda_star ) ) ;
00491
00492
00493 npix_in_interval = step_star/step_spectrum ;
00494 xsh_msg_dbg_low( "Nb of pixels max in interval: %d", npix_in_interval ) ;
00495
00496
00497
00498 cpl_table* debug = NULL;
00499 double* pwav = NULL;
00500 double* pflux_spectrum = NULL;
00501 double* pflux_added = NULL;
00502 double* pflux_star = NULL;
00503 double* presp = NULL;
00504 double* pkavalue = NULL;
00505 double* presp_atm_corr = NULL;
00506 double* presp_bin_cor = NULL;
00507 double cor_fct=0;
00508 debug=cpl_table_new(nlambda_star);
00509
00510 cpl_table_new_column(debug, "wavelength", CPL_TYPE_DOUBLE);
00511 cpl_table_new_column(debug, "flux_spectrum", CPL_TYPE_DOUBLE);
00512 cpl_table_new_column(debug, "flux_added", CPL_TYPE_DOUBLE);
00513 cpl_table_new_column(debug, "flux_star", CPL_TYPE_DOUBLE);
00514 cpl_table_new_column(debug, "resp", CPL_TYPE_DOUBLE);
00515 cpl_table_new_column(debug, "kvalue", CPL_TYPE_DOUBLE);
00516 cpl_table_new_column(debug, "resp_atm_corr", CPL_TYPE_DOUBLE);
00517 cpl_table_new_column(debug, "resp_bin_corr", CPL_TYPE_DOUBLE);
00518
00519 cpl_table_fill_column_window_double(debug, "wavelength", 0, nlambda_star, 0.);
00520 cpl_table_fill_column_window_double(debug, "flux_spectrum", 0, nlambda_star,0.);
00521 cpl_table_fill_column_window_double(debug, "flux_added", 0, nlambda_star, 0.);
00522 cpl_table_fill_column_window_double(debug, "flux_star", 0, nlambda_star, 0.);
00523 cpl_table_fill_column_window_double(debug, "resp", 0, nlambda_star, 0.);
00524 cpl_table_fill_column_window_double(debug, "kvalue", 0, nlambda_star, 0.);
00525 cpl_table_fill_column_window_double(debug, "resp_atm_corr", 0, nlambda_star,0.);
00526 cpl_table_fill_column_window_double(debug, "resp_bin_corr", 0, nlambda_star,0.);
00527
00528 pwav = cpl_table_get_data_double(debug,"wavelength");
00529 pflux_spectrum = cpl_table_get_data_double(debug,"flux_spectrum");
00530 pflux_added = cpl_table_get_data_double(debug,"flux_added");
00531 pflux_star = cpl_table_get_data_double(debug,"flux_star");
00532 presp = cpl_table_get_data_double(debug,"resp");
00533 pkavalue = cpl_table_get_data_double(debug,"kvalue");
00534 presp_atm_corr = cpl_table_get_data_double(debug,"resp_atm_corr");
00535 presp_bin_cor = cpl_table_get_data_double(debug,"resp_bin_corr");
00536
00537
00538 cor_fct=gain*bin*exptime;
00539
00540 for ( i = 0 ; i < nlambda_star ; i++ ) {
00541
00542
00543 flux_added[i] = 0. ;
00544 min = lambda_star[i] - step_star/2 ;
00545 max = lambda_star[i] + step_star/2 ;
00546
00547 xsh_msg_dbg_medium( "Lambda_star[%d] = %lf, Min = %lf, Max = %lf", i,
00548 lambda_star[i], min, max ) ;
00549
00550 find_lambda_idx_limit( min, max, lambda_spectrum, if0, nlambda_spectrum,
00551 step_spectrum, &if0, &if1 ) ;
00552
00553 xsh_msg_dbg_low( " Actual nb of pixels in interval: %d/%d", if1-if0,
00554 npix_in_interval ) ;
00555
00556
00557
00558 nbad=0;
00559 xsh_flux_integrate_and_corr_for_badpix(npix_in_interval,flux_spectrum,
00560 qual_spectrum,if0,if1,i,
00561 &flux_added,&npixels,&nbad);
00562
00563
00564 resp_list->flux[i] = flux_star[i]/(flux_added[i]/cor_fct) ;
00565 resp_list->lambda[i] = lambda_star[i] ;
00566
00567
00568 (*obj_list)->flux[i] = flux_added[i] ;
00569 (*obj_list)->lambda[i] = lambda_star[i] ;
00570
00571 pwav[i]=resp_list->lambda[i];
00572 pflux_spectrum[i]=flux_spectrum[i];
00573 pflux_added[i]=flux_added[i];
00574 pflux_star[i]=flux_star[i];
00575 presp[i]=resp_list->flux[i];
00576
00577 xsh_msg_dbg_low(" Flux Star = %le, Integrated = %lf (%d pixels, %d bad)",
00578 flux_star[i], flux_added[i], npixels, nbad ) ;
00579 xsh_msg_dbg_low(" =====> Response at Lambda=%lf: %le",
00580 lambda_star[i], resp_list->flux[i] ) ;
00581
00582
00583
00584
00585
00586
00587 if ( atmos_ext_tab != NULL ) {
00588 kvalue = pow(10., -airmass*atmos_K[i]*0.4 ) ;
00589 resp_list->flux[i] *= kvalue ;
00590 presp_atm_corr[i]=resp_list->flux[i];
00591 pkavalue[i]=kvalue;
00592
00593 }
00594
00595
00596 resp_list->flux[i] *= step_star/step_spectrum ;
00597 presp_bin_cor[i]=resp_list->flux[i];
00598 if0 = if1 ;
00599 }
00600
00601 xsh_free_table(&debug);
00602
00603
00604 if(resp_list->size > 2*FILTER_MEDIAN_HSIZE) {
00605 xsh_star_flux_list_filter_median(resp_list,FILTER_MEDIAN_HSIZE);
00606 }
00607
00608 resp_integrated=xsh_star_flux_list_save(resp_list,"resp_list_integrated.fits","TEST") ;
00609 xsh_add_temporary_file("resp_list_integrated.fits");
00610 obj_integrated=xsh_star_flux_list_save(*obj_list,"obj_list_integrated.fits","TEST") ;
00611 xsh_add_temporary_file("obj_list_integrated.fits");
00612
00613 if ( xsh_debug_level_get() >= XSH_DEBUG_LEVEL_LOW ) {
00614 check(xsh_response_crea_ascii(resp_list,star_list,lambda_spectrum,
00615 flux_spectrum,flux_added));
00616 }
00617
00618 cleanup:
00619
00620 XSH_FREE( lambda_spectrum ) ;
00621 XSH_FREE( lambda_resp ) ;
00622 XSH_FREE( lambda_resp ) ;
00623 XSH_FREE( flux_resp ) ;
00624 XSH_FREE( flux_added ) ;
00625 xsh_free_frame(&resp_integrated);
00626 xsh_free_frame(&obj_integrated);
00627 xsh_free_table(&debug);
00628
00629 if(cpl_error_get_code() == CPL_ERROR_NONE) {
00630 return resp_list;
00631 } else {
00632 return NULL;
00633 }
00634 }
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00819 static xsh_star_flux_list *
00820 do_compute(
00821 xsh_star_flux_list * star_list,
00822 xsh_star_flux_list ** obj_list,
00823 xsh_spectrum * spectrum,
00824 cpl_table * atmos_ext_tab,
00825 HIGH_ABS_REGION * phigh,
00826 double airmass,
00827 double exptime,
00828 double gain,
00829 xsh_instrument * instrument )
00830 {
00831 xsh_star_flux_list * resp_list = NULL ;
00832
00833 int nlambda_star ;
00834 double step_spectrum ;
00835 double step_star ;
00836 double * lambda_star = NULL, * flux_star = NULL ;
00837 double lambda_star_min, lambda_star_max ;
00838 double * flux_spectrum = NULL ;
00839 int * qual_spectrum = NULL ;
00840 double lambda_spectrum_min, lambda_spectrum_max ;
00841 double * atmos_lambda = NULL ;
00842 double * atmos_K = NULL ;
00843 XSH_ARM the_arm ;
00844
00845 XSH_ASSURE_NOT_NULL( star_list ) ;
00846 XSH_ASSURE_NOT_NULL( spectrum ) ;
00847
00848
00849
00850 check( flux_spectrum = xsh_spectrum_get_flux( spectrum ) ) ;
00851 check( qual_spectrum = xsh_spectrum_get_qual( spectrum ) ) ;
00852 check( lambda_spectrum_min = xsh_spectrum_get_lambda_min( spectrum ) ) ;
00853 check( lambda_spectrum_max = xsh_spectrum_get_lambda_max( spectrum ) ) ;
00854 check( step_spectrum = xsh_spectrum_get_lambda_step( spectrum ) ) ;
00855 the_arm=xsh_instrument_get_arm(instrument);
00856
00857
00858
00859 nlambda_star = star_list->size ;
00860 lambda_star = star_list->lambda ;
00861 flux_star = star_list->flux ;
00862 lambda_star_min = *lambda_star ;
00863 lambda_star_max = *(lambda_star+nlambda_star-1) ;
00864 step_star = (lambda_star_max-lambda_star_min)/(nlambda_star-1) ;
00865 xsh_msg_dbg_low( "Star - Nlambda: %d, Min: %le, Max: %le, Step: %lf",
00866 nlambda_star,
00867 lambda_star_min, lambda_star_max, step_star ) ;
00868
00869 check(xsh_interpolate_atm_ext(star_list,atmos_ext_tab,instrument,
00870 &atmos_lambda,&atmos_K));
00871
00872 check(resp_list=xsh_response_calculate(star_list,obj_list,spectrum,
00873 atmos_ext_tab,the_arm,atmos_K,
00874 airmass,exptime,gain));
00875
00876
00877 check(xsh_interpolate_high_abs_regions(star_list,resp_list,phigh));
00878
00879 cleanup:
00880 xsh_msg_dbg_medium( "End compute_response" ) ;
00881 XSH_FREE( atmos_lambda ) ;
00882 XSH_FREE( atmos_K ) ;
00883
00884 return resp_list ;
00885
00886 }
00887
00888
00889
00890 cpl_error_code
00891 xsh_response_merge_obj_std_info(cpl_frame* result,
00892 xsh_star_flux_list * star_list,
00893 xsh_star_flux_list * obj_list)
00894 {
00895
00896 cpl_table* table=NULL;
00897 const char* name=NULL;
00898 cpl_propertylist* plist=NULL;
00899 int nrow=0;
00900 int i=0;
00901
00902 double* pobj=NULL;
00903 double* pref=NULL;
00904
00905 name=cpl_frame_get_filename(result);
00906 plist=cpl_propertylist_load(name,0);
00907 table=cpl_table_load(name,1,0);
00908 nrow=cpl_table_get_nrow(table);
00909
00910 check(cpl_table_name_column(table,"FLUX", "RESPONSE"));
00911 cpl_table_new_column(table,"OBS",CPL_TYPE_DOUBLE);
00912 cpl_table_new_column(table,"REF",CPL_TYPE_DOUBLE);
00913
00914 cpl_table_fill_column_window_double(table,"OBS",0,nrow,0);
00915 cpl_table_fill_column_window_double(table,"REF",0,nrow,0);
00916
00917
00918 pobj=cpl_table_get_data_double(table,"OBS");
00919 pref=cpl_table_get_data_double(table,"REF");
00920
00921
00922 for(i=0;i<nrow;i++) {
00923 pobj[i]=obj_list->flux[i];
00924 pref[i]=star_list->flux[i];
00925 }
00926
00927 cpl_table_save(table,plist,NULL,name,CPL_IO_DEFAULT);
00928
00929 cleanup:
00930 xsh_free_table(&table);
00931 xsh_free_propertylist(&plist);
00932
00933 return cpl_error_get_code();
00934 }
00935
00951 cpl_frame * xsh_compute_response( cpl_frame * spectrum_frame,
00952 cpl_frame * flux_std_star_cat_frame,
00953 cpl_frame * atmos_ext_frame,
00954 cpl_frame* high_abs_frame,
00955 xsh_instrument * instrument,
00956 double exptime )
00957 {
00958 cpl_frame * result = NULL ;
00959 xsh_star_flux_list * star_list = NULL ;
00960 xsh_star_flux_list * obj_list = NULL ;
00961 xsh_spectrum * spectrum = NULL ;
00962 cpl_frame * tmp_spectrum_frame = NULL ;
00963 xsh_star_flux_list * resp_list = NULL ;
00964 xsh_atmos_ext_list * atmos_ext_list = NULL ;
00965 char tag[80];
00966 char fname[80];
00967
00968 cpl_frame* flux_std_star_frame=NULL;
00969 double dRA=0;
00970 double dDEC=0;
00971 cpl_table* tbl_ref_std_spectrum=NULL;
00972 const char* tbl_ref_std_fname="ref_flux_std_star.fits";
00973 cpl_frame* ipol_flux_std_star_frame=NULL;
00974 cpl_frame* resampl_flux_std_star_frame=NULL;
00975
00976
00977 double wmin=0;
00978 double wmax=0;
00979 int naxis1=0;
00980 double cdelt1=0;
00981 const char* filename=NULL;
00982 cpl_propertylist* plist=NULL;
00983 char * name=NULL;
00984 char * pcatg=NULL;
00985 cpl_table* atmos_ext_tab=NULL;
00986 double airmass=0;
00987 double gain=1.;
00988 int bin=1;
00989 HIGH_ABS_REGION * phigh=NULL;
00990
00991 XSH_ASSURE_NOT_NULL( spectrum_frame ) ;
00992 XSH_ASSURE_NOT_NULL( flux_std_star_cat_frame ) ;
00993 XSH_ASSURE_NOT_NULL( instrument ) ;
00994
00995
00996 xsh_msg("Compute instrument response");
00997
00998
00999 xsh_frame_sci_get_ra_dec_airmass(spectrum_frame,&dRA,&dDEC,&airmass);
01000
01001 if(CPL_ERROR_NONE != xsh_parse_catalog_std_stars(flux_std_star_cat_frame,
01002 dRA,dDEC,
01003 STAR_MATCH_DEPSILON,
01004 &tbl_ref_std_spectrum)){
01005 xsh_msg_warning("Problem parsing input STD catalog. For robustness recipe goes on.");
01006 xsh_msg_warning("%s",cpl_error_get_message());
01007 cpl_error_reset();
01008 xsh_free_table(&tbl_ref_std_spectrum);
01009 return NULL;
01010 }
01011
01012
01013 check(cpl_table_save(tbl_ref_std_spectrum,NULL,NULL,tbl_ref_std_fname,
01014 CPL_IO_DEFAULT));
01015 xsh_add_temporary_file(tbl_ref_std_fname);
01016 check(flux_std_star_frame=xsh_frame_product(tbl_ref_std_fname,"FLUX_STD_STAR",
01017 CPL_FRAME_TYPE_TABLE,
01018 CPL_FRAME_GROUP_PRODUCT,
01019 CPL_FRAME_LEVEL_INTERMEDIATE));
01020
01021
01022 filename=cpl_frame_get_filename(spectrum_frame);
01023 plist=cpl_propertylist_load(filename,0);
01024 naxis1=xsh_pfits_get_naxis1(plist);
01025 cdelt1=xsh_pfits_get_cdelt1(plist);
01026 wmin=xsh_pfits_get_crval1(plist);
01027
01028
01029 if( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
01030
01031 gain=1./2.12;
01032 bin=1;
01033 } else {
01034 check_msg( gain = xsh_pfits_get_gain(plist),
01035 "Could not read gain factor");
01036 bin=xsh_pfits_get_biny(plist);
01037 }
01038
01039 xsh_free_propertylist(&plist);
01040 wmax=wmin+cdelt1*naxis1;
01041
01042
01043 check(ipol_flux_std_star_frame=xsh_spectrum_interpolate(flux_std_star_frame,
01044 1,
01045 wmin,wmax));
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055 check(resampl_flux_std_star_frame=xsh_spectrum_resample(ipol_flux_std_star_frame,
01056 INTERPOL_WSTEP_NM,
01057 wmin,wmax,instrument));
01058
01059
01060 check( star_list = xsh_star_flux_list_load( resampl_flux_std_star_frame ) ) ;
01061
01062
01063 check( spectrum = xsh_spectrum_load( spectrum_frame));
01064 pcatg=cpl_sprintf("SPECTRUM_%s",xsh_instrument_arm_tostring( instrument));
01065 name=cpl_sprintf("%s.fits",pcatg);
01066 tmp_spectrum_frame=xsh_spectrum_save( spectrum,name,pcatg);
01067 xsh_add_temporary_file(name);
01068 cpl_free(pcatg);
01069 cpl_free(name);
01070
01071
01072 if ( atmos_ext_frame != NULL ) {
01073 check( atmos_ext_list = xsh_atmos_ext_list_load( atmos_ext_frame ) ) ;
01074 xsh_msg( "ATMOS EXT Loaded" ) ;
01075
01076 check(filename=cpl_frame_get_filename(atmos_ext_frame));
01077 check(atmos_ext_tab=cpl_table_load(filename,1,0));
01078 } else {
01079 xsh_msg_warning("Missing input %s_%s frame. Skip response and efficiency computation",
01080 XSH_ATMOS_EXT,xsh_instrument_arm_tostring(instrument));
01081 }
01082
01083
01084 check(phigh=xsh_fill_high_abs_regions(instrument,high_abs_frame));
01085
01086 check( resp_list = do_compute( star_list, &obj_list, spectrum, atmos_ext_tab,
01087 phigh,airmass,exptime,gain,instrument ) ) ;
01088
01089
01090
01091
01092 sprintf(tag,"RESPONSE_MERGE1D_%s_%s",xsh_instrument_mode_tostring(instrument),
01093 xsh_instrument_arm_tostring(instrument));
01094 sprintf(fname,"%s.fits",tag);
01095 check( result = xsh_star_flux_list_save( resp_list, fname, tag ) ) ;
01096 xsh_msg("***********************************");
01097 xsh_response_merge_obj_std_info(result,star_list, obj_list);
01098
01099 cleanup:
01100 if(high_abs_frame!=NULL) {
01101 cpl_free(phigh);
01102 }
01103 xsh_spectrum_free( &spectrum ) ;
01104
01105 xsh_star_flux_list_free( &star_list ) ;
01106 xsh_star_flux_list_free( &resp_list ) ;
01107 xsh_free_table(&tbl_ref_std_spectrum);
01108 xsh_free_frame(&flux_std_star_frame);
01109 xsh_free_frame(&ipol_flux_std_star_frame);
01110 xsh_free_frame(&resampl_flux_std_star_frame);
01111 xsh_free_frame(&tmp_spectrum_frame);
01112
01113
01114 xsh_atmos_ext_list_free(&atmos_ext_list) ;
01115 xsh_free_propertylist(&plist);
01116 xsh_free_table(&atmos_ext_tab);
01117
01118 return result ;
01119 }
01120
01136 cpl_frame * xsh_compute_response_ord( cpl_frame * spectrum_frame,
01137 cpl_frame * flux_std_star_cat_frame,
01138 cpl_frame * atmos_ext_frame,
01139 cpl_frame * high_abs_win_frame,
01140 xsh_instrument * instrument,
01141 double exptime )
01142 {
01143 cpl_frame * result = NULL ;
01144 xsh_star_flux_list * star_list = NULL ;
01145 xsh_star_flux_list * obj_list = NULL ;
01146 xsh_spectrum * spectrum = NULL ;
01147 cpl_frame * tmp_spectrum_frame = NULL ;
01148 xsh_star_flux_list * resp_list = NULL ;
01149 xsh_atmos_ext_list * atmos_ext_list = NULL ;
01150
01151 char tag[80];
01152 char fname[80];
01153 cpl_frame* flux_std_star_frame=NULL;
01154 double dRA=0;
01155 double dDEC=0;
01156 cpl_table* tbl_ref_std_spectrum=NULL;
01157 const char* tbl_ref_std_fname="ref_flux_std_star.fits";
01158 cpl_frame* ipol_flux_std_star_frame=NULL;
01159 double wmin=0;
01160 double wmax=0;
01161 int naxis1=0;
01162 double cdelt1=0;
01163 const char* filename=NULL;
01164 cpl_propertylist* plist=NULL;
01165 char * name=NULL;
01166 char * pcatg=NULL;
01167 cpl_table* atmos_ext_tab=NULL;
01168 double airmass=0;
01169 double gain=1.;
01170
01171 int next=0;
01172 int nord=0;
01173 int ext=0;
01174 int bin=0;
01175 HIGH_ABS_REGION * phigh=NULL;
01176 XSH_ARM the_arm;
01177
01178
01179 XSH_ASSURE_NOT_NULL( spectrum_frame ) ;
01180 XSH_ASSURE_NOT_NULL( flux_std_star_cat_frame ) ;
01181 XSH_ASSURE_NOT_NULL( instrument ) ;
01182 XSH_ASSURE_NOT_NULL( fname ) ;
01183
01184 xsh_msg("Compute instrument response");
01185
01186
01187 xsh_frame_sci_get_ra_dec_airmass(spectrum_frame,&dRA,&dDEC,&airmass);
01188
01189
01190 if(CPL_ERROR_NONE != xsh_parse_catalog_std_stars(flux_std_star_cat_frame,
01191 dRA,dDEC,
01192 STAR_MATCH_DEPSILON,
01193 &tbl_ref_std_spectrum)){
01194 xsh_msg_warning("Problem parsing input STD catalog. For robustness recipe goes on.");
01195 xsh_msg_warning("%s",cpl_error_get_message());
01196 cpl_error_reset();
01197 xsh_free_table(&tbl_ref_std_spectrum);
01198 return NULL;
01199 }
01200
01201 check(cpl_table_save(tbl_ref_std_spectrum,NULL,NULL,tbl_ref_std_fname,
01202 CPL_IO_DEFAULT));
01203 xsh_add_temporary_file(tbl_ref_std_fname);
01204
01205 check(flux_std_star_frame=xsh_frame_product(tbl_ref_std_fname,"FLUX_STD_STAR",
01206 CPL_FRAME_TYPE_TABLE,
01207 CPL_FRAME_GROUP_PRODUCT,
01208 CPL_FRAME_LEVEL_INTERMEDIATE));
01209
01210 if ( atmos_ext_frame != NULL ) {
01211 check( atmos_ext_list = xsh_atmos_ext_list_load( atmos_ext_frame ) ) ;
01212 xsh_msg( "ATMOS EXT Loaded" ) ;
01213
01214 check(filename=cpl_frame_get_filename(atmos_ext_frame));
01215 check(atmos_ext_tab=cpl_table_load(filename,1,0));
01216 }
01217 the_arm=xsh_instrument_get_arm(instrument);
01218
01219
01220 filename=cpl_frame_get_filename(spectrum_frame);
01221 next=cpl_frame_get_nextensions(spectrum_frame);
01222 nord=next/3;
01223
01224 plist=cpl_propertylist_load(filename,0);
01225 if( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
01226
01227 gain=1./2.12;
01228 bin=1;
01229 } else {
01230 check_msg( gain = xsh_pfits_get_gain(plist),
01231 "Could not read gain factor");
01232 bin=xsh_pfits_get_biny(plist);
01233 }
01234 xsh_free_propertylist(&plist);
01235
01236 check(phigh=xsh_fill_high_abs_regions(instrument,high_abs_win_frame));
01237
01238 for(ext=0;ext<next;ext+=3) {
01239
01240 xsh_free_propertylist(&plist);
01241 plist=cpl_propertylist_load(filename,ext);
01242 naxis1=xsh_pfits_get_naxis1(plist);
01243 cdelt1=xsh_pfits_get_cdelt1(plist);
01244 wmin=xsh_pfits_get_crval1(plist);
01245 wmax=wmin+cdelt1*naxis1;
01246
01247 xsh_free_frame(&ipol_flux_std_star_frame);
01248 check(ipol_flux_std_star_frame=xsh_spectrum_interpolate(flux_std_star_frame,
01249 INTERPOL_WSTEP_NM,
01250 wmin,wmax));
01251
01252 xsh_star_flux_list_free( &star_list ) ;
01253 check( star_list = xsh_star_flux_list_load( ipol_flux_std_star_frame ) ) ;
01254
01255 xsh_spectrum_free( &spectrum ) ;
01256 check( spectrum=xsh_spectrum_load_order(spectrum_frame,instrument,ext)) ;
01257 pcatg=cpl_sprintf("SPECTRUM_%s",xsh_instrument_arm_tostring( instrument));
01258 name=cpl_sprintf("%s.fits",pcatg);
01259 xsh_free_frame(&tmp_spectrum_frame);
01260
01261 tmp_spectrum_frame=xsh_spectrum_save_order( spectrum,name,pcatg,ext);
01262 xsh_add_temporary_file(name);
01263
01264 cpl_free(pcatg);
01265 cpl_free(name);
01266
01267
01268 xsh_star_flux_list_free( &resp_list ) ;
01269
01270
01271 check(resp_list=do_compute( star_list, &obj_list, spectrum, atmos_ext_tab,
01272 phigh,airmass, exptime, gain, instrument ) ) ;
01273
01274
01275
01276
01277 sprintf(tag,"RESPONSE_ORDER1D_%s_%s",xsh_instrument_mode_tostring(instrument),
01278 xsh_instrument_arm_tostring(instrument));
01279 sprintf(fname,"%s.fits",tag);
01280 xsh_free_frame(&result);
01281
01282 check(result=xsh_star_flux_list_save_order(resp_list,fname,tag,ext)) ;
01283
01284 }
01285
01286 cleanup:
01287
01288 if(high_abs_win_frame!=NULL) {
01289 cpl_free(phigh);
01290 }
01291 xsh_spectrum_free( &spectrum ) ;
01292 xsh_star_flux_list_free( &star_list ) ;
01293 xsh_star_flux_list_free( &resp_list ) ;
01294 xsh_star_flux_list_free( &obj_list ) ;
01295
01296 xsh_free_table(&tbl_ref_std_spectrum);
01297 xsh_free_frame(&flux_std_star_frame);
01298 xsh_free_frame(&ipol_flux_std_star_frame);
01299 xsh_free_frame(&tmp_spectrum_frame);
01300
01301 xsh_atmos_ext_list_free(&atmos_ext_list) ;
01302 xsh_free_propertylist(&plist);
01303 xsh_free_table(&atmos_ext_tab);
01304
01305 return result ;
01306 }
01307