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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifdef HAVE_CONFIG_H
00044 #include <config.h>
00045 #endif
00046
00047
00054
00057
00058
00059
00060
00061 #include <math.h>
00062 #include <xsh_drl.h>
00063
00064 #include <xsh_data_rec.h>
00065 #include <xsh_data_localization.h>
00066 #include <xsh_data_pre.h>
00067 #include <xsh_data_order.h>
00068 #include <xsh_dfs.h>
00069 #include <xsh_pfits.h>
00070 #include <xsh_error.h>
00071 #include <xsh_msg.h>
00072 #include <xsh_fit.h>
00073 #include <xsh_ifu_defs.h>
00074 #include <xsh_data_slice_offset.h>
00075 #include <xsh_data_atmos_ext.h>
00076 #include <cpl.h>
00077 #include <xsh_utils.h>
00078 #include <gsl/gsl_integration.h>
00079 #include <xsh_data_star_flux.h>
00080 #include <xsh_data_spectrum.h>
00081
00082 #define USE_SPLINE
00083 #if defined(USE_SPLINE)
00084 #include <gsl/gsl_spline.h>
00085 #endif
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 #if defined(USE_SPLINE)
00097 static gsl_interp_accel * AcceleratorResp, * AcceleratorAtmos ;
00098 static gsl_spline * SplineResp, * SplineAtmos ;
00099
00100 static void init_interpolate( double * x, double * yf, int nb,
00101 gsl_spline ** spline,
00102 gsl_interp_accel ** accel)
00103 {
00104 int ok ;
00105
00106
00107
00108 *accel = gsl_interp_accel_alloc();
00109 if ( *accel == NULL ) xsh_msg( "Accelerator = NULL" ) ;
00110
00111 *spline = gsl_spline_alloc( gsl_interp_cspline, nb);
00112
00113 if ( *spline == NULL ) xsh_msg( "Spline = NULL" ) ;
00114
00115 ok = gsl_spline_init( *spline, x, yf, nb ) ;
00116
00117 xsh_msg( "gsl_spline_init --> %d", ok ) ;
00118
00119 return ;
00120 }
00121
00122 static double do_interpolation( double x, gsl_spline * spline,
00123 gsl_interp_accel * accel )
00124 {
00125 double y =0;
00126
00127 y = gsl_spline_eval( spline, x, accel );
00128
00129 return y ;
00130 }
00131
00132 static void clear_interpolate( void )
00133 {
00134 gsl_spline_free( SplineResp ) ;
00135 gsl_spline_free( SplineAtmos ) ;
00136 gsl_interp_accel_free( AcceleratorResp ) ;
00137 gsl_interp_accel_free( AcceleratorAtmos ) ;
00138
00139 }
00140 #else
00141
00142 static int get_idx_by_lambda( double lambda, double * a_lambda, int from,
00143 int to, double step )
00144 {
00145 int idx =0;
00146 double * plambda=NULL ;
00147
00148 for( idx = from, plambda = a_lambda+from ; idx<to ; idx++, plambda++ ) {
00149 if ( lambda >= (*plambda - step/2) &&
00150 lambda < (*plambda + step/2) ) {
00151 return idx ;
00152 }
00153 }
00154
00155 return -1 ;
00156 }
00157
00158 #endif
00159
00160 static double myfunc (double x, void * params) {
00161 double alpha = *(double *) params;
00162 double thefunc = exp(alpha*x*x) ;
00163
00164 return thefunc ;
00165 }
00166
00167 static double compute_Lx( double slit_width, double seeing )
00168 {
00169 gsl_integration_workspace * w
00170 = gsl_integration_workspace_alloc (10000);
00171
00172 double result, error;
00173 double alpha = -1.0;
00174
00175 gsl_function F;
00176 double limit ;
00177
00178 double Lx ;
00179
00180 F.function = &myfunc ;
00181 F.params = α
00182 limit = (slit_width/2.)/((seeing*sqrt(2.))/2.35482) ;
00183
00184 gsl_integration_qags (&F, 0, limit, 0, 1e-7, 10000,
00185 w, &result, &error);
00186
00187
00188 Lx = 1- (2/sqrt(M_PI))*result ;
00189
00190 return Lx ;
00191 }
00192
00193 static xsh_spectrum * do_calib_spectrum( xsh_spectrum * spectrum_in,
00194 xsh_star_flux_list * response_list,
00195 xsh_atmos_ext_list * atmos_ext_list,
00196 double airmass_ratio,
00197 double Lx )
00198 {
00199 xsh_spectrum * spectrum ;
00200 double * spectrum_flux = NULL ;
00201 int * spectrum_qual = NULL ;
00202 double spectrum_lambda_min, spectrum_lambda_max ;
00203 int spectrum_nlambda, spectrum_nslit ;
00204 double lambda ;
00205 double lambda_step ;
00206
00207 double * atmos_lambda = NULL ;
00208 double * atmos_K = NULL ;
00209 double atmos_step ;
00210 int atmos_size ;
00211
00212 double * response_lambda = NULL ;
00213 double * response_flux = NULL ;
00214 double response_step ;
00215 int response_size ;
00216 int ipix ;
00217 #if !defined(USE_SPLINE)
00218 int atmidx = 0, respidx = 0 ;
00219 #endif
00220
00221 check( spectrum = xsh_spectrum_duplicate( spectrum_in ) ) ;
00222
00223 check( spectrum_nlambda = xsh_spectrum_get_size_lambda( spectrum ) ) ;
00224 check( spectrum_nslit = xsh_spectrum_get_size_slit( spectrum ) ) ;
00225 if ( spectrum_nslit > 1 ) {
00226 xsh_msg( "2D Spectrum" ) ;
00227 }
00228 else {
00229 xsh_msg( "1D Spectrum" ) ;
00230 }
00231
00232 check( spectrum_flux = xsh_spectrum_get_flux( spectrum ) ) ;
00233 check( spectrum_qual = xsh_spectrum_get_qual( spectrum ) ) ;
00234 check( spectrum_lambda_min = xsh_spectrum_get_lambda_min( spectrum ) ) ;
00235 check( spectrum_lambda_max = xsh_spectrum_get_lambda_max( spectrum ) ) ;
00236 check( lambda_step = xsh_spectrum_get_lambda_step( spectrum ) ) ;
00237
00238 check( atmos_lambda = xsh_atmos_ext_list_get_lambda( atmos_ext_list ) ) ;
00239 check( atmos_K = xsh_atmos_ext_list_get_K( atmos_ext_list ) ) ;
00240 atmos_size = atmos_ext_list->size ;
00241 atmos_step = *(atmos_lambda+atmos_size-1) - *atmos_lambda ;
00242 #if defined(USE_SPLINE)
00243 check( init_interpolate( atmos_lambda, atmos_K, atmos_size, &SplineAtmos,
00244 &AcceleratorAtmos ) ) ;
00245 #endif
00246
00247 check( response_lambda = xsh_star_flux_list_get_lambda( response_list ) ) ;
00248 check( response_flux = xsh_star_flux_list_get_flux( response_list ) ) ;
00249 response_size = response_list->size ;
00250 response_step = *(response_lambda+response_size-1) - *response_lambda ;
00251 #if defined(USE_SPLINE)
00252 check( init_interpolate( response_lambda, response_flux, response_size,
00253 &SplineResp,
00254 &AcceleratorResp ) ) ;
00255 #endif
00256
00257 lambda = spectrum_lambda_min ;
00258
00259 for( ipix = 0 ; ipix < spectrum_nlambda ; ipix++, lambda += lambda_step ) {
00260 double kvalue, vresp ;
00261 int islit ;
00262
00263
00264
00265 if ( atmos_ext_list != NULL ) {
00266 #if defined(USE_SPLINE)
00267 double inter_k ;
00268
00269 inter_k = do_interpolation( lambda, SplineAtmos, AcceleratorAtmos ) ;
00270 kvalue = pow( 10., -inter_k*0.4 ) ;
00271 #else
00272
00273 atmidx = get_idx_by_lambda( lambda, atmos_lambda, atmidx, atmos_size,
00274 atmos_step ) ;
00275 kvalue = pow(10., -atmos_K[atmidx]*0.4 ) ;
00276 #endif
00277 }
00278 else kvalue = 1. ;
00279
00280
00281
00282 #if defined(USE_SPLINE)
00283 vresp = do_interpolation( lambda, SplineResp, AcceleratorResp ) ;
00284 #else
00285
00286 respidx = get_idx_by_lambda( lambda, response_lambda, respidx,
00287 response_size, response_step ) ;
00288 vresp = response_flux[respidx] ;
00289 #endif
00290
00291 for( islit = 0 ; islit < spectrum_nslit ; islit++ ) {
00292 int idx=0 ;
00293
00294 if ( spectrum_qual[idx] != QFLAG_GOOD_PIXEL )
00295 continue ;
00296 idx = ipix + islit*spectrum_nlambda ;
00297 spectrum_flux[idx] *= (airmass_ratio*kvalue*vresp)/Lx ;
00298 }
00299 }
00300
00301 clear_interpolate() ;
00302
00303 cleanup:
00304 return spectrum ;
00305 }
00306
00307 cpl_frame * xsh_calibrate_flux( cpl_frame * spectrum_frame,
00308 cpl_frame * respon_frame,
00309 cpl_frame * atmos_ext_frame,
00310 const char * fname,
00311 xsh_instrument * instrument )
00312 {
00313 cpl_frame * result = NULL ;
00314 double s_airm_start, s_airm_end, r_airm_start, r_airm_end ;
00315 double s_airmass = 1., r_airmass = 1., airmass_ratio = 1. ;
00316 double slit_width, seeing_start, seeing_end, seeing ;
00317 cpl_propertylist * s_header = NULL, * r_header = NULL ;
00318 xsh_spectrum * spectrum = NULL;
00319 xsh_star_flux_list * response_list = NULL ;
00320 xsh_atmos_ext_list * atmos_ext_list = NULL ;
00321 double Lx ;
00322
00323 XSH_ASSURE_NOT_NULL( spectrum_frame ) ;
00324 XSH_ASSURE_NOT_NULL( respon_frame ) ;
00325 XSH_ASSURE_NOT_NULL( instrument ) ;
00326
00327
00328 check( spectrum = xsh_spectrum_load( spectrum_frame)) ;
00329 check( s_header = spectrum->flux_header ) ;
00330 s_airm_start = xsh_pfits_get_airm_start( s_header ) ;
00331 s_airm_end = xsh_pfits_get_airm_end( s_header ) ;
00332 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
00333 cpl_error_reset() ;
00334 s_airmass = 1. ;
00335 }
00336 else s_airmass = (s_airm_start + s_airm_end)/2. ;
00337
00338 check( response_list = xsh_star_flux_list_load( respon_frame ) ) ;
00339 check( r_header = response_list->header ) ;
00340 r_airm_start = xsh_pfits_get_airm_start( r_header ) ;
00341 r_airm_end = xsh_pfits_get_airm_end( r_header ) ;
00342 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
00343 cpl_error_reset() ;
00344 r_airmass = 1. ;
00345 }
00346 else r_airmass = (r_airm_start + r_airm_end)/2. ;
00347 airmass_ratio = s_airmass/r_airmass ;
00348
00349
00350 if ( xsh_instrument_get_mode( instrument ) == XSH_MODE_IFU ) {
00351 slit_width = WIDTH_SLIT_IFU ;
00352 xsh_msg( "IFU Mode Slit width: %.2lf", slit_width ) ;
00353 }
00354 else {
00355 check( slit_width = xsh_pfits_get_slit_width( s_header, instrument ) ) ;
00356 xsh_msg( "SLIT Mode Slit width: %.2lf", slit_width ) ;
00357 }
00358 check( seeing_start = xsh_pfits_get_seeing_start( s_header ) ) ;
00359 check( seeing_end = xsh_pfits_get_seeing_end( s_header ) ) ;
00360 seeing = (seeing_start + seeing_end)/2. ;
00361 xsh_msg_warning("SEEING=%g",seeing);
00362
00363 Lx = compute_Lx( slit_width, seeing ) ;
00364
00365
00366 if ( atmos_ext_frame != NULL ) {
00367 check( atmos_ext_list = xsh_atmos_ext_list_load( atmos_ext_frame ) ) ;
00368 xsh_msg( "ATMOS EXT Loaded" ) ;
00369 }
00370
00371
00372 check( do_calib_spectrum( spectrum, response_list, atmos_ext_list,
00373 airmass_ratio, Lx ) ) ;
00374
00375
00376 check( result = xsh_phys_spectrum_save( spectrum, fname, instrument )) ;
00377
00378 cleanup:
00379
00380 return result ;
00381 }