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