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
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 typedef struct {
00072 double lambda_min ;
00073 double lambda_max ;
00074 } HIGH_ABS_REGION ;
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 HIGH_ABS_REGION NirHighAbsRegions[] = {
00086 {1060.0, 1232.9},
00087 {1247.4, 1500.0},
00088 {1549.0, 1588.5},
00089 {1595.0, 1625.0},
00090 {1630.0, 1983.5},
00091 {1984.2, 1988.1},
00092 {1988.9, 1991.1},
00093 {1991.7, 2138.0},
00094 {2145.0, 2191.0},
00095 {2218.0, 2271.0},
00096 {2351.0, 2431.0},
00097 {0., 0.}
00098 } ;
00099
00100
00101
00102
00103
00104
00105
00106
00107 HIGH_ABS_REGION VisHighAbsRegions[] = {
00108 {585.0, 604.0},
00109 {684.5, 746.0},
00110 {755.5, 775.5},
00111 {783.7, 856.0},
00112 {887.5, 993.4},
00113 {0., 0.}
00114 } ;
00115
00116 #define INTERPOL_WSTEP_NM 2
00117
00118 static int
00119 find_lambda_idx( double lambda, double * wave, int from, int to,
00120 double step )
00121 {
00122 int idx ;
00123 double * pwave ;
00124
00125 for( idx = from, pwave = wave+from ; idx < to ; pwave++, idx++ ) {
00126 if ( *pwave >= (lambda-step/2) && *pwave < (lambda+step/2) ) return idx ;
00127 }
00128
00129 return -1 ;
00130 }
00131
00132 static void
00133 find_lambda_idx_limit( double min, double max, double * spectrum,
00134 int from, int to, double step,
00135 int * if0, int * if1 )
00136 {
00137 int idx ;
00138 double *pspec ;
00139
00140 xsh_msg_dbg_high( "From: %d, To: %d, step: %lf, min: %lf, max: %lf",
00141 from, to, step, min, max ) ;
00142
00143 for( idx = from, pspec = spectrum+from ; idx < to ; pspec++, idx++ ) {
00144 xsh_msg_dbg_high( " Search Min - Spectrum_lambda: %lf (%lf)", *pspec,
00145 min-(step/2.) ) ;
00146 if ( *pspec >= (min-(step/2.)) ) break ;
00147 }
00148 *if0 = idx ;
00149 for( ; idx < to ; pspec++, idx++ ) {
00150 xsh_msg_dbg_high( " Search Max - Spectrum_lambda: %lf", *pspec ) ;
00151 if ( *pspec > (max+(step/2.)) ) break ;
00152 }
00153 *if1 = idx-1 ;
00154
00155 xsh_msg_dbg_low( "Lambda Min: %lf, Max: %lf (in [%lf,%lf[",
00156 spectrum[*if0], spectrum[*if1], min, max ) ;
00157 if ( *if1 > to ) *if1 = to ;
00158
00159 return ;
00160 }
00161
00172 static cpl_error_code
00173 xsh_interpolate_atm_ext(xsh_star_flux_list * star_list,
00174 cpl_table*atmos_ext_tab,
00175 xsh_instrument* instrument,
00176 double** atmos_lambda,
00177 double** atmos_K)
00178 {
00179
00180 int nrow=0;
00181 double* pk=0;
00182 double* pw=0;
00183 int j=0 ;
00184 int nlambda_star=0 ;
00185 double * lambda_star = NULL;
00186
00187 XSH_ASSURE_NOT_NULL_MSG (star_list,"null input ref std flux table!");
00188 XSH_ASSURE_NOT_NULL_MSG (atmos_ext_tab,"null input atm ext table!");
00189
00190 nlambda_star = star_list->size ;
00191 lambda_star = star_list->lambda ;
00192
00193
00194
00195 XSH_CALLOC( *atmos_lambda, double, nlambda_star ) ;
00196 XSH_CALLOC( *atmos_K, double, nlambda_star ) ;
00197
00198 cpl_table_cast_column(atmos_ext_tab,"LA_SILLA","K",CPL_TYPE_DOUBLE);
00199 cpl_table_cast_column(atmos_ext_tab,"LAMBDA","WAVE",CPL_TYPE_DOUBLE);
00200
00201 nrow=cpl_table_get_nrow(atmos_ext_tab);
00202 pw=cpl_table_get_data_double(atmos_ext_tab,"WAVE");
00203 pk=cpl_table_get_data_double(atmos_ext_tab,"K");
00204
00205 if( xsh_instrument_get_arm(instrument) != XSH_ARM_NIR){
00206 for( j = 0 ; j<nlambda_star ; j++) {
00207
00208 (*atmos_lambda)[j] = lambda_star[j] ;
00209 (*atmos_K)[j] = xsh_data_interpolate((*atmos_lambda)[j],nrow,pw,pk);
00210
00211
00212 }
00213 } else {
00214 for( j = 0 ; j<nlambda_star ; j++) {
00215
00216 (*atmos_lambda)[j] = lambda_star[j] ;
00217 (*atmos_K)[j] = 0;
00218
00219
00220 }
00221 }
00222
00223 cpl_table_erase_column(atmos_ext_tab,"WAVE");
00224 cpl_table_erase_column(atmos_ext_tab,"K");
00225
00226
00227 cleanup:
00228 return cpl_error_get_code();
00229 }
00230
00239 static cpl_error_code
00240 xsh_interpolate_high_abs_regions(xsh_star_flux_list * star_list,
00241 xsh_star_flux_list * resp_list,
00242 HIGH_ABS_REGION * phigh,
00243 XSH_ARM the_arm)
00244
00245 {
00246 int kh=0;
00247 int min_idx=0;
00248 int max_idx=0;
00249 double min_flux=0;
00250 double max_flux=0;
00251 double delta_flux=0;
00252 double cur_flux=0;
00253 int ll=0;
00254 int nlambda_star=0;
00255 double step_star=0;
00256 double * lambda_star = NULL;
00257 double lambda_star_min=0;
00258 double lambda_star_max=0;
00259
00260
00261
00262
00263 XSH_ASSURE_NOT_NULL_MSG (star_list,"null input ref std flux table!");
00264 XSH_ASSURE_NOT_NULL_MSG (resp_list,"null input response table!");
00265
00266 nlambda_star = star_list->size ;
00267 lambda_star = star_list->lambda ;
00268 lambda_star_min = *lambda_star ;
00269 lambda_star_max = *(lambda_star+nlambda_star-1) ;
00270 step_star = (lambda_star_max-lambda_star_min)/(nlambda_star-1) ;
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 if ( phigh != NULL ) {
00303
00304 xsh_msg_dbg_medium( "Interpolate in High Absorption Regions" ) ;
00305 for( kh = 0 ; phigh->lambda_min != 0. ; kh++, phigh++ ) {
00306
00307 min_idx = find_lambda_idx( phigh->lambda_min, resp_list->lambda,
00308 0, nlambda_star, step_star ) ;
00309 max_idx = find_lambda_idx( phigh->lambda_max, resp_list->lambda,
00310 min_idx, nlambda_star, step_star ) ;
00311 xsh_msg_dbg_medium( "Indexes[%d]: %d (lambda=%lf), %d (lambda=%lf)",
00312 kh,min_idx, phigh->lambda_min, max_idx,
00313 phigh->lambda_max ) ;
00314
00315 if(min_idx>=resp_list->size || max_idx>=resp_list->size) {
00316 xsh_msg("min_idx=%d max_idx=%d size=%d",
00317 min_idx,max_idx,resp_list->size);
00318 }
00319
00320 min_flux = resp_list->flux[min_idx] ;
00321 max_flux = resp_list->flux[max_idx] ;
00322 xsh_msg_dbg_medium( "Min Flux: %le, Max Flux: %le",
00323 min_flux, max_flux ) ;
00324 delta_flux = (max_flux-min_flux)/(max_idx-min_idx) ;
00325
00326 cur_flux = min_flux ;
00327 for ( ll = min_idx+1 ; ll < max_idx ; ll++ ) {
00328 cur_flux += delta_flux ;
00329 xsh_msg_dbg_medium( " ==> Interpolate at %lf: %le replaced by %le",
00330 resp_list->lambda[ll],
00331 resp_list->flux[ll], cur_flux ) ;
00332 resp_list->flux[ll] = cur_flux ;
00333 }
00334 }
00335 }
00336
00337 cleanup:
00338
00339
00340 return cpl_error_get_code();
00341 }
00342
00356 static cpl_error_code
00357 xsh_response_crea_ascii(xsh_star_flux_list * resp_list,
00358 xsh_star_flux_list * star_list,
00359 double * lambda_spectrum,
00360 double * flux_spectrum,
00361 double * flux_added)
00362 {
00363
00364 FILE * fout ;
00365 int i=0;
00366 int nlambda_star=0;
00367 int nlambda_spectrum=0;
00368 double * lambda_star = NULL;
00369 double * flux_star = NULL ;
00370
00371 XSH_ASSURE_NOT_NULL_MSG (star_list,"null input ref std flux table!");
00372 XSH_ASSURE_NOT_NULL_MSG (resp_list,"null input response table!");
00373
00374 nlambda_star = star_list->size ;
00375 lambda_star = star_list->lambda ;
00376 flux_star = star_list->flux ;
00377
00378 fout = fopen( "summed.dat", "w" ) ;
00379 for( i = 0 ; i < nlambda_star ; i++ ) {
00380 fprintf( fout, "%lf %le\n", resp_list->lambda[i],
00381 flux_added[i] ) ;
00382 }
00383 fclose( fout ) ;
00384
00385 fout = fopen( "response.dat", "w" ) ;
00386 for( i = 0 ; i < nlambda_star ; i++ ) {
00387 fprintf( fout, "%lf %le\n", resp_list->lambda[i],
00388 resp_list->flux[i] ) ;
00389 }
00390 fclose( fout ) ;
00391
00392 fout = fopen( "spectrum.dat", "w" ) ;
00393 for ( i = 0 ; i < nlambda_spectrum ; i++ )
00394 fprintf( fout, "%lf %lf\n", lambda_spectrum[i], flux_spectrum[i] ) ;
00395 fclose( fout ) ;
00396
00397 fout = fopen( "star.dat", "w" ) ;
00398 for ( i = 0 ; i < nlambda_star ; i++ )
00399 fprintf( fout, "%lf %le\n", lambda_star[i], flux_star[i] ) ;
00400 fclose( fout ) ;
00401
00402 cleanup:
00403 return cpl_error_get_code();
00404 }
00405
00406
00407
00408
00409 static cpl_error_code
00410 xsh_correct_flux_for_badpix(int npix_in_interval,
00411 double * flux_spectrum,
00412 int * qual_spectrum,
00413 int if0,int if1,double exptime,
00414 int i,double** flux_added,int* npixels,int* nbad)
00415
00416 {
00417
00418 double * pf0=NULL;
00419 double * pf1=NULL;
00420 double * pf=NULL;
00421
00422 int * qf0=NULL;
00423 int * qf=NULL;
00424
00425 XSH_ASSURE_NOT_NULL_MSG (flux_spectrum,"null flux_spectrum !");
00426 XSH_ASSURE_NOT_NULL_MSG (qual_spectrum,"null qual_spectrum !");
00427
00428 if ( npix_in_interval != if1-if0 ) *nbad = npix_in_interval -(if1-if0) ;
00429
00430 pf0 = flux_spectrum + if0 ;
00431 pf1 = flux_spectrum + if1 ;
00432 qf0 = qual_spectrum + if0 ;
00433 for( pf = pf0, qf = qf0 ; pf < pf1 ; pf++, qf++ ) {
00434
00435
00436
00437
00438 (*npixels)++ ;
00439 if ( *qf != QFLAG_GOOD_PIXEL ) {
00440 (*nbad)++ ;
00441 }
00442 else (*flux_added)[i] += *pf/exptime ;
00443 }
00444
00445 if ( nbad != 0 )
00446 (*flux_added)[i] /= (double)(npix_in_interval-*nbad)/
00447 (double)npix_in_interval ;
00448
00449 cleanup:
00450 return cpl_error_get_code();
00451 }
00452
00453 static xsh_star_flux_list *
00454 xsh_response_calculate(
00455 xsh_star_flux_list * star_list,
00456 xsh_spectrum * spectrum,
00457 cpl_table * atmos_ext_tab,
00458 XSH_ARM the_arm,
00459 double * atmos_K,
00460 double airmass,
00461 double exptime,
00462 double gain)
00463 {
00464 xsh_star_flux_list * resp_list=NULL;
00465 int npixels = 0;
00466 int nbad = 0 ;
00467
00468 double lambda=0;
00469 double min=0;
00470 double max=0;
00471 double kvalue=0;
00472
00473
00474 double * lambda_resp = NULL ;
00475 double * flux_resp = NULL ;
00476 double * flux_added = NULL ;
00477 double * lambda_star = NULL;
00478 double * flux_star = NULL ;
00479
00480 double * lambda_spectrum = NULL;
00481 double * plambda=NULL ;
00482 double * flux_spectrum = NULL ;
00483 int * qual_spectrum = NULL ;
00484
00485 int i=0;
00486 int if0=0;
00487 int if1=0;
00488 int nlambda_star=0;
00489 int nlambda_spectrum=0;
00490 double lambda_spectrum_min=0;
00491 double lambda_spectrum_max=0;
00492 double lambda_star_min=0;
00493 double lambda_star_max=0;
00494 double step_spectrum=0 ;
00495 double step_star=0 ;
00496 int npix_in_interval=0 ;
00497 int binx, biny ;
00498 cpl_frame* resp_integrated=NULL;
00499
00500 check( nlambda_spectrum = xsh_spectrum_get_size( spectrum ) ) ;
00501 check( flux_spectrum = xsh_spectrum_get_flux( spectrum ) ) ;
00502 check( qual_spectrum = xsh_spectrum_get_qual( spectrum ) ) ;
00503 check( lambda_spectrum_min = xsh_spectrum_get_lambda_min( spectrum ) ) ;
00504 check( lambda_spectrum_max = xsh_spectrum_get_lambda_max( spectrum ) ) ;
00505 check( step_spectrum = xsh_spectrum_get_lambda_step( spectrum ) ) ;
00506
00507
00508 if ( the_arm != XSH_ARM_NIR ) {
00509 binx = xsh_pfits_get_binx( spectrum->flux_header ) ;
00510 biny = xsh_pfits_get_biny( spectrum->flux_header ) ;
00511 }
00512 else {
00513 binx = 1 ;
00514 biny = 1 ;
00515 }
00516
00517 flux_star = star_list->flux ;
00518 nlambda_star = star_list->size ;
00519 lambda_star = star_list->lambda ;
00520 lambda_star_min = *lambda_star ;
00521 lambda_star_max = *(lambda_star+nlambda_star-1) ;
00522 step_star = (lambda_star_max-lambda_star_min)/(nlambda_star-1) ;
00523
00524 xsh_msg_dbg_low( "Spectrum - Nlambda: %d, Min: %lf, Max: %lf, Step: %lf",
00525 nlambda_spectrum, lambda_spectrum_min, lambda_spectrum_max,
00526 step_spectrum ) ;
00527 xsh_msg_dbg_low( " - BinX: %d, BinY: %d", binx, biny ) ;
00528
00529 XSH_CALLOC( lambda_resp, double, nlambda_star ) ;
00530 XSH_CALLOC( flux_resp, double, nlambda_star ) ;
00531 XSH_CALLOC( flux_added, double, nlambda_star ) ;
00532
00533
00534
00535
00536
00537
00538
00539
00540 XSH_CALLOC( lambda_spectrum, double, nlambda_spectrum ) ;
00541
00542
00543
00544 for( lambda = lambda_spectrum_min, plambda = lambda_spectrum, i = 0 ;
00545 i<nlambda_spectrum ;
00546 i++, plambda++, lambda += step_spectrum )
00547 {
00548 *plambda = lambda ;
00549 }
00550
00551
00552 check( resp_list = xsh_star_flux_list_create( nlambda_star ) ) ;
00553
00554
00555 npix_in_interval = step_star/step_spectrum ;
00556 xsh_msg_dbg_low( "Nb of pixels max in interval: %d", npix_in_interval ) ;
00557 xsh_print_rec_status(0);
00558
00559
00560 for ( i = 0 ; i < nlambda_star ; i++ ) {
00561
00562
00563 flux_added[i] = 0. ;
00564 min = lambda_star[i] - step_star/2 ;
00565 max = lambda_star[i] + step_star/2 ;
00566
00567 xsh_msg_dbg_medium( "Lambda_star[%d] = %lf, Min = %lf, Max = %lf", i,
00568 lambda_star[i], min, max ) ;
00569
00570 find_lambda_idx_limit( min, max, lambda_spectrum, if0, nlambda_spectrum,
00571 step_spectrum, &if0, &if1 ) ;
00572
00573 xsh_msg_dbg_low( " Actual nb of pixels in interval: %d/%d", if1-if0,
00574 npix_in_interval ) ;
00575
00576
00577 xsh_correct_flux_for_badpix(npix_in_interval,flux_spectrum,qual_spectrum,
00578 if0,if1,exptime,i,&flux_added,&npixels,&nbad);
00579
00580
00581 resp_list->flux[i] = flux_star[i]/(flux_added[i]/gain) ;
00582 resp_list->lambda[i] = lambda_star[i] ;
00583 xsh_msg_dbg_low(" Flux Star = %le, Integrated = %lf (%d pixels, %d bad)",
00584 flux_star[i], flux_added[i], npixels, nbad ) ;
00585 xsh_msg_dbg_low(" =====> Response at Lambda=%lf: %le",
00586 lambda_star[i], resp_list->flux[i] ) ;
00587
00588
00589 if ( atmos_ext_tab != NULL ) {
00590 kvalue = pow(10., -airmass*atmos_K[i]*0.4 ) ;
00591 resp_list->flux[i] *= kvalue ;
00592
00593 }
00594
00595
00596 resp_list->flux[i] *= step_star/step_spectrum ;
00597
00598 if0 = if1 ;
00599 }
00600
00601 xsh_star_flux_list_filter_median(resp_list,3);
00602
00603 resp_integrated=xsh_star_flux_list_save(resp_list,"resp_list_integrated.fits","TEST") ;
00604 xsh_free_frame(&resp_integrated);
00605
00606 if ( xsh_debug_level_get() >= XSH_DEBUG_LEVEL_LOW ) {
00607 check(xsh_response_crea_ascii(resp_list,star_list,lambda_spectrum,
00608 flux_spectrum,flux_added));
00609 }
00610
00611 cleanup:
00612
00613 XSH_FREE( lambda_spectrum ) ;
00614 XSH_FREE( lambda_resp ) ;
00615 XSH_FREE( lambda_resp ) ;
00616 XSH_FREE( flux_resp ) ;
00617 XSH_FREE( flux_added ) ;
00618
00619 if(cpl_error_get_code() == CPL_ERROR_NONE) {
00620 return resp_list;
00621 } else {
00622 return NULL;
00623 }
00624 }
00625
00626
00627
00628
00629
00630
00631
00632
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
00808 static xsh_star_flux_list *
00809 do_compute( xsh_star_flux_list * star_list,
00810 xsh_spectrum * spectrum,
00811 cpl_table * atmos_ext_tab,
00812 HIGH_ABS_REGION * phigh,
00813 double airmass,
00814 double exptime,
00815 double gain,
00816 xsh_instrument * instrument )
00817 {
00818 xsh_star_flux_list * resp_list = NULL ;
00819
00820 int nlambda_star ;
00821 double step_spectrum ;
00822 double step_star ;
00823 double * lambda_star = NULL, * flux_star = NULL ;
00824 double lambda_star_min, lambda_star_max ;
00825 double * flux_spectrum = NULL ;
00826 int * qual_spectrum = NULL ;
00827 double lambda_spectrum_min, lambda_spectrum_max ;
00828 double * atmos_lambda = NULL ;
00829 double * atmos_K = NULL ;
00830 XSH_ARM the_arm ;
00831
00832 XSH_ASSURE_NOT_NULL( star_list ) ;
00833 XSH_ASSURE_NOT_NULL( spectrum ) ;
00834
00835
00836
00837 check( flux_spectrum = xsh_spectrum_get_flux( spectrum ) ) ;
00838 check( qual_spectrum = xsh_spectrum_get_qual( spectrum ) ) ;
00839 check( lambda_spectrum_min = xsh_spectrum_get_lambda_min( spectrum ) ) ;
00840 check( lambda_spectrum_max = xsh_spectrum_get_lambda_max( spectrum ) ) ;
00841 check( step_spectrum = xsh_spectrum_get_lambda_step( spectrum ) ) ;
00842 the_arm=xsh_instrument_get_arm(instrument);
00843
00844
00845
00846 nlambda_star = star_list->size ;
00847 lambda_star = star_list->lambda ;
00848 flux_star = star_list->flux ;
00849 lambda_star_min = *lambda_star ;
00850 lambda_star_max = *(lambda_star+nlambda_star-1) ;
00851 step_star = (lambda_star_max-lambda_star_min)/(nlambda_star-1) ;
00852 xsh_msg_dbg_low( "Star - Nlambda: %d, Min: %le, Max: %le, Step: %lf",
00853 nlambda_star,
00854 lambda_star_min, lambda_star_max, step_star ) ;
00855
00856 check(xsh_interpolate_atm_ext(star_list,atmos_ext_tab,instrument,
00857 &atmos_lambda,&atmos_K));
00858
00859 check(resp_list=xsh_response_calculate(star_list,spectrum,atmos_ext_tab,
00860 the_arm,atmos_K,airmass,
00861 exptime,gain));
00862
00863
00864 check(xsh_interpolate_high_abs_regions(star_list,resp_list,phigh,the_arm));
00865
00866 cleanup:
00867 xsh_msg_dbg_medium( "End compute_response" ) ;
00868 XSH_FREE( atmos_lambda ) ;
00869 XSH_FREE( atmos_K ) ;
00870
00871 return resp_list ;
00872
00873 }
00874
00875
00876 static HIGH_ABS_REGION *
00877 xsh_fill_high_abs_regions(
00878 xsh_instrument* instrument,
00879 cpl_frame* high_abs_frame)
00880 {
00881 HIGH_ABS_REGION * phigh=NULL;
00882 int nrow=0;
00883 double* pwmin=0;
00884 double* pwmax=0;
00885 int i=0;
00886 cpl_table* high_abs_tab=NULL;
00887 XSH_ARM the_arm;
00888
00889 if(high_abs_frame !=NULL) {
00890 high_abs_tab=cpl_table_load(cpl_frame_get_filename(high_abs_frame),1,0);
00891 }
00892 the_arm=xsh_instrument_get_arm(instrument);
00893
00894
00895
00896 if(high_abs_tab!=NULL) {
00897 nrow=cpl_table_get_nrow(high_abs_tab);
00898 check(pwmin=cpl_table_get_data_double(high_abs_tab,"LAMBDA_MIN"));
00899 check(pwmax=cpl_table_get_data_double(high_abs_tab,"LAMBDA_MAX"));
00900
00901 phigh = (HIGH_ABS_REGION *) cpl_calloc(nrow + 1, sizeof(HIGH_ABS_REGION));
00902 for(i=0;i<nrow;i++) {
00903 phigh[i].lambda_min=pwmin[i];
00904 phigh[i].lambda_max=pwmax[i];
00905 }
00906 phigh[nrow].lambda_min=0;
00907 phigh[nrow].lambda_max=0;
00908
00909 } else {
00910
00911
00912
00913
00914 if ( the_arm == XSH_ARM_VIS ) {
00915
00916 phigh = VisHighAbsRegions ;
00917 }
00918 else if ( the_arm == XSH_ARM_NIR ) {
00919
00920 phigh = NirHighAbsRegions ;
00921 }
00922
00923 }
00924 cleanup:
00925 xsh_free_table(&high_abs_tab);
00926 return phigh;
00927 }
00928
00929
00945 cpl_frame * xsh_compute_response( cpl_frame * spectrum_frame,
00946 cpl_frame * flux_std_star_cat_frame,
00947 cpl_frame * atmos_ext_frame,
00948 cpl_frame* high_abs_frame,
00949 xsh_instrument * instrument,
00950 double exptime )
00951 {
00952 cpl_frame * result = NULL ;
00953 xsh_star_flux_list * star_list = NULL ;
00954 xsh_spectrum * spectrum = NULL ;
00955 cpl_frame * tmp_spectrum_frame = NULL ;
00956 xsh_star_flux_list * resp_list = NULL ;
00957 xsh_atmos_ext_list * atmos_ext_list = NULL ;
00958 char tag[80];
00959 char fname[80];
00960
00961 cpl_frame* flux_std_star_frame=NULL;
00962 double dRA=0;
00963 double dDEC=0;
00964 cpl_table* tbl_ref_std_spectrum=NULL;
00965 const char* tbl_ref_std_fname="ref_flux_std_star.fits";
00966 cpl_frame* ipol_flux_std_star_frame=NULL;
00967 cpl_frame* resampl_flux_std_star_frame=NULL;
00968 cpl_frame* smooth_flux_std_star_frame=NULL;
00969
00970 double wmin=0;
00971 double wmax=0;
00972 int naxis1=0;
00973 double cdelt1=0;
00974 const char* filename=NULL;
00975 cpl_propertylist* plist=NULL;
00976 char * name=NULL;
00977 char * pcatg=NULL;
00978 cpl_table* atmos_ext_tab=NULL;
00979 double airmass=0;
00980 double gain=1.;
00981 HIGH_ABS_REGION * phigh=NULL;
00982
00983 XSH_ASSURE_NOT_NULL( spectrum_frame ) ;
00984 XSH_ASSURE_NOT_NULL( flux_std_star_cat_frame ) ;
00985 XSH_ASSURE_NOT_NULL( instrument ) ;
00986
00987
00988 xsh_msg("Compute instrument response");
00989
00990
00991 xsh_frame_sci_get_ra_dec_airmass(spectrum_frame,&dRA,&dDEC,&airmass);
00992
00993
00994 if(CPL_ERROR_NONE != xsh_parse_catalog_std_stars(flux_std_star_cat_frame,
00995 dRA,dDEC,
00996 STAR_MATCH_DEPSILON,
00997 &tbl_ref_std_spectrum)){
00998 cpl_error_reset();
00999 xsh_free_table(&tbl_ref_std_spectrum);
01000 return NULL;
01001 }
01002
01003 check(cpl_table_save(tbl_ref_std_spectrum,NULL,NULL,tbl_ref_std_fname,
01004 CPL_IO_DEFAULT));
01005
01006 check(flux_std_star_frame=xsh_frame_product(tbl_ref_std_fname,"FLUX_STD_STAR",
01007 CPL_FRAME_TYPE_TABLE,
01008 CPL_FRAME_GROUP_PRODUCT,
01009 CPL_FRAME_LEVEL_INTERMEDIATE));
01010
01011
01012 filename=cpl_frame_get_filename(spectrum_frame);
01013 plist=cpl_propertylist_load(filename,0);
01014 naxis1=xsh_pfits_get_naxis1(plist);
01015 cdelt1=xsh_pfits_get_cdelt1(plist);
01016 wmin=xsh_pfits_get_crval1(plist);
01017
01018 if( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
01019
01020 gain=1./2.12;
01021 } else {
01022 check_msg( gain = xsh_pfits_get_gain(plist),
01023 "Could not read gain factor");
01024 }
01025
01026
01027
01028 xsh_free_propertylist(&plist);
01029 wmax=wmin+cdelt1*naxis1;
01030
01031
01032 check(ipol_flux_std_star_frame=xsh_spectrum_interpolate_linear(flux_std_star_frame,
01033 1,
01034 wmin,wmax));
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044 check(resampl_flux_std_star_frame=xsh_spectrum_resample(ipol_flux_std_star_frame,
01045 INTERPOL_WSTEP_NM,
01046 wmin,wmax,instrument));
01047
01048
01049
01050 check( star_list = xsh_star_flux_list_load( resampl_flux_std_star_frame ) ) ;
01051
01052
01053
01054
01055 check( spectrum = xsh_spectrum_load( spectrum_frame, instrument ) ) ;
01056 pcatg=cpl_sprintf("SPECTRUM_%s",xsh_instrument_arm_tostring( instrument));
01057 name=cpl_sprintf("%s.fits",pcatg);
01058 tmp_spectrum_frame=xsh_spectrum_save( spectrum,name,pcatg);
01059 cpl_free(pcatg);
01060 cpl_free(name);
01061
01062
01063 if ( atmos_ext_frame != NULL ) {
01064 check( atmos_ext_list = xsh_atmos_ext_list_load( atmos_ext_frame ) ) ;
01065 xsh_msg( "ATMOS EXT Loaded" ) ;
01066
01067 check(filename=cpl_frame_get_filename(atmos_ext_frame));
01068 check(atmos_ext_tab=cpl_table_load(filename,1,0));
01069 }
01070
01071
01072
01073 check(phigh=xsh_fill_high_abs_regions(instrument,high_abs_frame));
01074
01075 check( resp_list = do_compute( star_list, spectrum, atmos_ext_tab,
01076 phigh,airmass,exptime, gain, instrument ) ) ;
01077
01078
01079
01080
01081 sprintf(tag,"RESPONSE_MERGE1D_%s_%s",xsh_instrument_mode_tostring(instrument),
01082 xsh_instrument_arm_tostring(instrument));
01083 sprintf(fname,"%s.fits",tag);
01084 check( result = xsh_star_flux_list_save( resp_list, fname, tag ) ) ;
01085
01086
01087 cleanup:
01088
01089 if(high_abs_frame!=NULL) {
01090 cpl_free(phigh);
01091 }
01092 xsh_spectrum_free( &spectrum ) ;
01093
01094 xsh_star_flux_list_free( &star_list ) ;
01095 xsh_star_flux_list_free( &resp_list ) ;
01096 xsh_free_table(&tbl_ref_std_spectrum);
01097 xsh_free_frame(&flux_std_star_frame);
01098 xsh_free_frame(&ipol_flux_std_star_frame);
01099 xsh_free_frame(&resampl_flux_std_star_frame);
01100 xsh_free_frame(&tmp_spectrum_frame);
01101
01102 xsh_atmos_ext_list_free(&atmos_ext_list) ;
01103 xsh_free_propertylist(&plist);
01104 xsh_free_table(&atmos_ext_tab);
01105
01106 return result ;
01107 }
01108
01124 cpl_frame * xsh_compute_response_ord( cpl_frame * spectrum_frame,
01125 cpl_frame * flux_std_star_cat_frame,
01126 cpl_frame * atmos_ext_frame,
01127 cpl_frame * high_abs_win_frame,
01128 xsh_instrument * instrument,
01129 double exptime )
01130 {
01131 cpl_frame * result = NULL ;
01132 xsh_star_flux_list * star_list = NULL ;
01133 xsh_spectrum * spectrum = NULL ;
01134 cpl_frame * tmp_spectrum_frame = NULL ;
01135 xsh_star_flux_list * resp_list = NULL ;
01136 xsh_atmos_ext_list * atmos_ext_list = NULL ;
01137
01138 char tag[80];
01139 char fname[80];
01140 cpl_frame* flux_std_star_frame=NULL;
01141 double dRA=0;
01142 double dDEC=0;
01143 cpl_table* tbl_ref_std_spectrum=NULL;
01144 const char* tbl_ref_std_fname="ref_flux_std_star.fits";
01145 cpl_frame* ipol_flux_std_star_frame=NULL;
01146 double wmin=0;
01147 double wmax=0;
01148 int naxis1=0;
01149 double cdelt1=0;
01150 const char* filename=NULL;
01151 cpl_propertylist* plist=NULL;
01152 char * name=NULL;
01153 char * pcatg=NULL;
01154 cpl_table* atmos_ext_tab=NULL;
01155 double airmass=0;
01156 double gain=1.;
01157
01158 int next=0;
01159 int nord=0;
01160 int ext=0;
01161 HIGH_ABS_REGION * phigh=NULL;
01162 XSH_ARM the_arm;
01163
01164
01165 XSH_ASSURE_NOT_NULL( spectrum_frame ) ;
01166 XSH_ASSURE_NOT_NULL( flux_std_star_cat_frame ) ;
01167 XSH_ASSURE_NOT_NULL( instrument ) ;
01168 XSH_ASSURE_NOT_NULL( fname ) ;
01169
01170 xsh_msg("Compute instrument response");
01171
01172
01173 xsh_frame_sci_get_ra_dec_airmass(spectrum_frame,&dRA,&dDEC,&airmass);
01174
01175
01176 if(CPL_ERROR_NONE != xsh_parse_catalog_std_stars(flux_std_star_cat_frame,
01177 dRA,dDEC,
01178 STAR_MATCH_DEPSILON,
01179 &tbl_ref_std_spectrum)){
01180 cpl_error_reset();
01181 xsh_free_table(&tbl_ref_std_spectrum);
01182 return NULL;
01183 }
01184
01185 check(cpl_table_save(tbl_ref_std_spectrum,NULL,NULL,tbl_ref_std_fname,
01186 CPL_IO_DEFAULT));
01187
01188 check(flux_std_star_frame=xsh_frame_product(tbl_ref_std_fname,"FLUX_STD_STAR",
01189 CPL_FRAME_TYPE_TABLE,
01190 CPL_FRAME_GROUP_PRODUCT,
01191 CPL_FRAME_LEVEL_INTERMEDIATE));
01192
01193
01194 if ( atmos_ext_frame != NULL ) {
01195 check( atmos_ext_list = xsh_atmos_ext_list_load( atmos_ext_frame ) ) ;
01196 xsh_msg( "ATMOS EXT Loaded" ) ;
01197
01198 check(filename=cpl_frame_get_filename(atmos_ext_frame));
01199 check(atmos_ext_tab=cpl_table_load(filename,1,0));
01200 }
01201 the_arm=xsh_instrument_get_arm(instrument);
01202
01203
01204
01205
01206 filename=cpl_frame_get_filename(spectrum_frame);
01207 next=cpl_frame_get_nextensions(spectrum_frame);
01208 nord=next/3;
01209
01210 plist=cpl_propertylist_load(filename,0);
01211 if( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
01212
01213 gain=1./2.12;
01214 } else {
01215 check_msg( gain = xsh_pfits_get_gain(plist),
01216 "Could not read gain factor");
01217 }
01218 xsh_free_propertylist(&plist);
01219
01220 check(phigh=xsh_fill_high_abs_regions(instrument,high_abs_win_frame));
01221
01222 for(ext=0;ext<next;ext+=3) {
01223
01224 xsh_free_propertylist(&plist);
01225 plist=cpl_propertylist_load(filename,ext);
01226 naxis1=xsh_pfits_get_naxis1(plist);
01227 cdelt1=xsh_pfits_get_cdelt1(plist);
01228 wmin=xsh_pfits_get_crval1(plist);
01229 wmax=wmin+cdelt1*naxis1;
01230
01231 xsh_free_frame(&ipol_flux_std_star_frame);
01232 check(ipol_flux_std_star_frame=xsh_spectrum_interpolate(flux_std_star_frame,
01233 INTERPOL_WSTEP_NM,
01234 wmin,wmax));
01235
01236 xsh_star_flux_list_free( &star_list ) ;
01237 check( star_list = xsh_star_flux_list_load( ipol_flux_std_star_frame ) ) ;
01238
01239 xsh_spectrum_free( &spectrum ) ;
01240 check( spectrum=xsh_spectrum_load_order(spectrum_frame,instrument,ext)) ;
01241 pcatg=cpl_sprintf("SPECTRUM_%s",xsh_instrument_arm_tostring( instrument));
01242 name=cpl_sprintf("%s.fits",pcatg);
01243 xsh_free_frame(&tmp_spectrum_frame);
01244 tmp_spectrum_frame=xsh_spectrum_save_order( spectrum,name,pcatg,ext);
01245 cpl_free(pcatg);
01246 cpl_free(name);
01247
01248
01249 xsh_star_flux_list_free( &resp_list ) ;
01250
01251
01252 check(resp_list=do_compute( star_list, spectrum, atmos_ext_tab,
01253 phigh,airmass, exptime, gain, instrument ) ) ;
01254
01255
01256
01257
01258 sprintf(tag,"RESPONSE_ORDER1D_%s_%s",xsh_instrument_mode_tostring(instrument),
01259 xsh_instrument_arm_tostring(instrument));
01260 sprintf(fname,"%s.fits",tag);
01261 xsh_free_frame(&result);
01262 check(result=xsh_star_flux_list_save_order(resp_list,fname,tag,ext)) ;
01263 }
01264
01265 cleanup:
01266
01267 if(high_abs_win_frame!=NULL) {
01268 cpl_free(phigh);
01269 }
01270 xsh_spectrum_free( &spectrum ) ;
01271 xsh_star_flux_list_free( &star_list ) ;
01272 xsh_star_flux_list_free( &resp_list ) ;
01273 xsh_free_table(&tbl_ref_std_spectrum);
01274 xsh_free_frame(&flux_std_star_frame);
01275 xsh_free_frame(&ipol_flux_std_star_frame);
01276 xsh_free_frame(&tmp_spectrum_frame);
01277
01278 xsh_atmos_ext_list_free(&atmos_ext_list) ;
01279 xsh_free_propertylist(&plist);
01280 xsh_free_table(&atmos_ext_tab);
01281
01282 return result ;
01283 }
01284