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 #ifdef HAVE_CONFIG_H
00026 # include <config.h>
00027 #endif
00028
00029 #include <math.h>
00030 #include <xsh_utils_response.h>
00031 #include <xsh_efficiency_response.h>
00032 #include <xsh_dfs.h>
00033 #include <xsh_pfits_qc.h>
00034 #include <xsh_error.h>
00035
00041
00044
00045
00046
00047
00048 static double
00049 xsh_resample_double(double wout,double* pw1,double* pf1,double wmin,double wmax,int size_obs)
00050 {
00051
00052 double m=0;
00053 double w1=0;
00054 double w2=0;
00055 double f1=0;
00056 double f2=0;
00057 double fout=0;
00058
00059 int i=0;
00060
00061
00062 if( wout < wmin ) {
00063
00064 m=(pf1[1]-pf1[0])/(pw1[1]-pw1[0]);
00065 fout=m*(wout-wmin)+pf1[0];
00066 } else if ( wout > wmax ) {
00067
00068 m=(pf1[size_obs-1]-pf1[size_obs-2])/(pw1[size_obs-1]-pw1[size_obs-2]);
00069 fout=m*(wout-wmax)+pf1[size_obs-1];
00070
00071 } else {
00072
00073 for(i=0;i<size_obs;i++) {
00074 if(pw1[i]<wout) {
00075 w1=pw1[i];
00076 f1=pf1[i];
00077 } else {
00078 w2=pw1[i];
00079 f2=pf1[i];
00080 break;
00081 }
00082 }
00083 m=(f2-f1)/(w2-w1);
00084 fout=m*(wout-w1)+f1;
00085 }
00086 return fout;
00087 }
00088
00089 static cpl_table*
00090 xsh_table_resample_table(cpl_table* tinp,const char* cwinp, const char* cfinp,
00091 cpl_table* tref,const char* cwref, const char* cfref)
00092 {
00093
00094 cpl_table* tres=NULL;
00095 double* pwinp=NULL;
00096 double* pwref=NULL;
00097 double* pfinp=NULL;
00098 double* pfres=NULL;
00099 int size_inp=0;
00100 int size_ref=0;
00101 double wmin=0;
00102 double wmax=0;
00103 int i=0;
00104
00105 check(size_inp=cpl_table_get_nrow(tinp));
00106 check(size_ref=cpl_table_get_nrow(tref));
00107
00108 check(wmin=cpl_table_get_column_min(tinp,cwinp));
00109 check(wmax=cpl_table_get_column_max(tinp,cwinp));
00110
00111
00112
00113
00114 tres=cpl_table_duplicate(tref);
00115 check(pwinp=cpl_table_get_data_double(tinp,cwinp));
00116 check(pwref=cpl_table_get_data_double(tref,cwref));
00117
00118 check(pfinp=cpl_table_get_data_double(tinp,cfinp));
00119 check(pfres=cpl_table_get_data_double(tres,cfref));
00120
00121 for(i=0;i<size_ref;i++) {
00122 pfres[i]=xsh_resample_double(pwref[i],pwinp,pfinp,wmin,wmax,size_inp);
00123 }
00124
00125 cleanup:
00126 return tres;
00127 }
00128
00129
00130
00131
00132
00133 static cpl_table*
00134 xsh_table_downsample_table(cpl_table* tinp,const char* cwinp, const char* cfinp,
00135 cpl_table* tref,const char* cwref, const char* cfref)
00136 {
00137
00138 cpl_table* tres=NULL;
00139 double* pwinp=NULL;
00140 double* pwref=NULL;
00141 double* pwres=NULL;
00142
00143 double* pfinp=NULL;
00144 double* pfref=NULL;
00145 double* pfres=NULL;
00146
00147 int size_inp=0;
00148 int size_ref=0;
00149 double wmin=0;
00150 double wmax=0;
00151 int i=0;
00152
00153 check(size_inp=cpl_table_get_nrow(tinp));
00154 check(size_ref=cpl_table_get_nrow(tref));
00155
00156 check(wmin=cpl_table_get_column_min(tinp,cwinp));
00157 check(wmax=cpl_table_get_column_max(tinp,cwinp));
00158
00159
00160
00161 tres=cpl_table_new(size_ref);
00162
00163 cpl_table_new_column(tres,cwref,CPL_TYPE_DOUBLE);
00164 cpl_table_new_column(tres,cfref,CPL_TYPE_DOUBLE);
00165 cpl_table_fill_column_window_double(tres,cwref,0,size_ref,0.);
00166 cpl_table_fill_column_window_double(tres,cfref,0,size_ref,0.);
00167
00168
00169 check(pwinp=cpl_table_get_data_double(tinp,cwinp));
00170 check(pwref=cpl_table_get_data_double(tref,cwref));
00171
00172 check(pfinp=cpl_table_get_data_double(tinp,cfinp));
00173 check(pfres=cpl_table_get_data_double(tres,cfref));
00174
00175 check(pwres=cpl_table_get_data_double(tres,cwref));
00176 check(pfres=cpl_table_get_data_double(tres,cfref));
00177
00178 for(i=0;i<size_ref;i++) {
00179 pwres[i]=pwref[i];
00180 pfres[i]=xsh_resample_double(pwres[i],pwinp,pfinp,wmin,wmax,size_inp);
00181 }
00182
00183 cleanup:
00184 return tres;
00185 }
00186
00187
00188 cpl_table*
00189 xsh_table_resample_uniform(cpl_table* tinp,const char* cwinp, const char* cfinp,
00190 const double wstp)
00191 {
00192
00193 cpl_table* tres=NULL;
00194 double* pwinp=NULL;
00195 double* pwref=NULL;
00196 double* pfinp=NULL;
00197 double* pfres=NULL;
00198 int size_inp=0;
00199 double wmin=0;
00200 double wmax=0;
00201 int i=0;
00202 int size=0;
00203 check(size_inp=cpl_table_get_nrow(tinp));
00204
00205 check(wmin=cpl_table_get_column_min(tinp,cwinp));
00206 check(wmax=cpl_table_get_column_max(tinp,cwinp));
00207
00208 size=(int)((wmax-wmin)/wstp+0.5);
00209
00210
00211
00212 tres=cpl_table_new(size);
00213 cpl_table_new_column(tres,cwinp,CPL_TYPE_DOUBLE);
00214 cpl_table_new_column(tres,cfinp,CPL_TYPE_DOUBLE);
00215
00216 cpl_table_fill_column_window_double(tres,cwinp,0,size,0.);
00217 cpl_table_fill_column_window_double(tres,cfinp,0,size,0.);
00218 check(pwref=cpl_table_get_data_double(tres,cwinp));
00219 for(i=0;i<size;i++) {
00220 pwref[i]=wmin+i*wstp;
00221 }
00222 check(pwinp=cpl_table_get_data_double(tinp,cwinp));
00223 check(pfinp=cpl_table_get_data_double(tinp,cfinp));
00224 check(pfres=cpl_table_get_data_double(tres,cfinp));
00225
00226 for(i=0;i<size;i++) {
00227 pfres[i]=xsh_resample_double(pwref[i],pwinp,pfinp,wmin,wmax,size_inp);
00228 }
00229
00230 cleanup:
00231 return tres;
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 static cpl_table*
00249 xsh_spectrum_to_table(xsh_spectrum* s)
00250 {
00251
00252 cpl_table* table_s=NULL;
00253 int size=0;
00254 int i=0;
00255
00256 double wmin=0;
00257 double wstp=0;
00258 double* wave=NULL;
00259
00260 size=xsh_spectrum_get_size_lambda(s);
00261 wmin= xsh_spectrum_get_lambda_min(s);
00262 wstp= xsh_spectrum_get_lambda_step(s);
00263
00264
00265
00266 table_s=cpl_table_new(size);
00267 cpl_table_new_column(table_s,"wavelength",CPL_TYPE_DOUBLE);
00268 cpl_table_fill_column_window_double(table_s,"wavelength",0,size,0);
00269 wave=cpl_table_get_data_double(table_s,"wavelength");
00270 for(i=0;i<size;i++) {
00271 wave[i]=wmin+i*wstp;
00272 }
00273
00274 cpl_table_wrap_double(table_s,xsh_spectrum_get_flux(s),"flux");
00275 cpl_table_wrap_double(table_s,xsh_spectrum_get_errs(s),"errs");
00276
00277 cpl_table_wrap_int(table_s,xsh_spectrum_get_qual(s),"qual");
00278 cpl_table_duplicate_column(table_s,"logwave",table_s,"wavelength");
00279 cpl_table_logarithm_column(table_s,"logwave",CPL_MATH_E);
00280
00281 return table_s;
00282
00283 }
00284
00285 static cpl_error_code xsh_evaluate_tell_model(cpl_table* corr,
00286 xsh_instrument* instrument, const int ext, double* mean, double* rms) {
00287
00288 HIGH_ABS_REGION * phigh = NULL;
00289 int nsamples = 0;
00290 cpl_table* tab_tmp = NULL;
00291 cpl_table* tab_stack = NULL;
00292 char fname[256];
00293 phigh = xsh_fill_tell_compute_resid_regions(instrument, NULL);
00294
00295 if (phigh != NULL) {
00296 int counter = 0;
00297
00298 int nrow = 0;
00299
00300 for (; phigh->lambda_min != 0.; phigh++) {
00301
00302 nrow = cpl_table_and_selected_double(corr, "wave", CPL_NOT_LESS_THAN,
00303 phigh->lambda_min);
00304
00305 nrow = cpl_table_and_selected_double(corr, "wave", CPL_LESS_THAN,
00306 phigh->lambda_max);
00307
00308 tab_tmp = cpl_table_extract_selected(corr);
00309 cpl_table_select_all(corr);
00310 if (counter == 0) {
00311
00312 tab_stack = cpl_table_duplicate(tab_tmp);
00313 counter++;
00314 } else {
00315 nrow = cpl_table_get_nrow(tab_stack);
00316
00317 cpl_table_insert(tab_stack, tab_tmp, nrow);
00318 }
00319 xsh_free_table(&tab_tmp);
00320 nsamples++;
00321 }
00322
00323 }
00324 sprintf(fname, "tab_corr_sampl.fits");
00325
00326
00327 *mean = fabs( ( cpl_table_get_column_mean(tab_stack, "correction") - 1. ) );
00328 *rms = cpl_table_get_column_stdev(tab_stack, "correction");
00329
00330
00331 xsh_free_table(&tab_tmp);
00332 xsh_free_table(&tab_stack);
00333 return cpl_error_get_code();
00334
00335 }
00336
00337 static cpl_table*
00338 xsh_extract_ranges_to_fit(cpl_table* table_in,const char* cwav,xsh_instrument* instrument) {
00339
00340 cpl_table* stack = NULL;
00341 HIGH_ABS_REGION * phigh = NULL;
00342
00343 phigh = xsh_fill_tell_compute_resid_regions(instrument, NULL);
00344
00345 cpl_table* tab_tmp = NULL;
00346 int nsamples = 0;
00347
00348
00349
00350
00351
00352
00353
00354 if (phigh != NULL) {
00355 int counter = 0;
00356
00357 int nrow = 0;
00358
00359 for (; phigh->lambda_min != 0.; phigh++) {
00360
00361 check(nrow = cpl_table_and_selected_double(table_in, cwav, CPL_NOT_LESS_THAN,
00362 phigh->lambda_min));
00363
00364 check(nrow = cpl_table_and_selected_double(table_in,cwav, CPL_LESS_THAN,
00365 phigh->lambda_max));
00366
00367 check(tab_tmp = cpl_table_extract_selected(table_in));
00368 cpl_table_select_all(table_in);
00369 if (counter == 0) {
00370
00371 stack = cpl_table_duplicate(tab_tmp);
00372 counter++;
00373 } else {
00374 nrow=cpl_table_get_nrow(stack);
00375
00376 cpl_table_insert(stack, tab_tmp, nrow);
00377 }
00378 xsh_free_table(&tab_tmp);
00379 nsamples++;
00380 }
00381 }
00382 xsh_free_table(&tab_tmp);
00383
00384 cleanup:
00385 return stack;
00386 }
00387 static cpl_error_code
00388 xsh_extract_points_to_fit(cpl_table* table,const char* cwav,const char* cratio, const int nsamples, xsh_instrument* instrument,cpl_vector** vec_wave,cpl_vector** vec_flux)
00389 {
00390
00391
00392 double* pvec_wave = NULL;
00393 double* pvec_flux = NULL;
00394 int kh=0;
00395 HIGH_ABS_REGION * phigh = NULL;
00396 cpl_table* tab_tmp=NULL;
00397 double wmin=0;
00398 double wmax=0;
00399 double wstp=1.;
00400
00401 wmin=cpl_table_get_column_min(table,cwav);
00402 wmax=cpl_table_get_column_max(table,cwav);
00403
00404 *vec_wave = cpl_vector_new(nsamples+2);
00405 *vec_flux = cpl_vector_new(nsamples+2);
00406 pvec_wave = cpl_vector_get_data(*vec_wave);
00407 pvec_flux = cpl_vector_get_data(*vec_flux);
00408
00409
00410
00411 cpl_table_and_selected_double(table, cwav, CPL_LESS_THAN,wmin+wstp);
00412 tab_tmp = cpl_table_extract_selected(table);
00413 pvec_wave[0] = wmin;
00414 check(pvec_flux[0] = cpl_table_get_column_median(tab_tmp, cratio));
00415 cpl_table_select_all(table);
00416 xsh_free_table(&tab_tmp);
00417
00418 phigh=xsh_fill_tell_fit_regions(instrument,NULL);
00419 if (phigh != NULL) {
00420
00421
00422 for (kh = 0; phigh->lambda_min != 0.; phigh++) {
00423
00424 cpl_table_and_selected_double(table, cwav,
00425 CPL_NOT_LESS_THAN, phigh->lambda_min);
00426
00427 cpl_table_and_selected_double(table, cwav, CPL_LESS_THAN,
00428 phigh->lambda_max);
00429
00430 tab_tmp = cpl_table_extract_selected(table);
00431 cpl_table_select_all(table);
00432 pvec_wave[kh+1] = 0.5 * (phigh->lambda_max + phigh->lambda_min);
00433 pvec_flux[kh+1] = cpl_table_get_column_median(tab_tmp, cratio);
00434 kh++;
00435 xsh_free_table(&tab_tmp);
00436 }
00437 }
00438
00439 cpl_table_select_all(table);
00440 cpl_table_and_selected_double(table, cwav, CPL_NOT_LESS_THAN,wmax-wstp);
00441 tab_tmp = cpl_table_extract_selected(table);
00442
00443 pvec_wave[kh+1] = wmax;
00444 check(pvec_flux[kh+1] = cpl_table_get_column_median(tab_tmp, cratio));
00445 xsh_free_table(&tab_tmp);
00446
00447 cleanup:
00448
00449 return cpl_error_get_code();
00450 }
00451
00452 static cpl_error_code
00453 xsh_get_xcorrel_peak(cpl_vector* wcorr, cpl_vector* fcorr,XSH_GAUSSIAN_FIT* gfit,const double range,const int ext)
00454 {
00455 int size_x;
00456 cpl_table* tab = NULL;
00457 cpl_table* ext_tab;
00458 char fname[256];
00459 cpl_vector* wave=NULL;
00460 cpl_vector* flux=NULL;
00461
00462 size_x=cpl_vector_get_size(wcorr);
00463 tab = cpl_table_new(size_x);
00464 cpl_table_wrap_double(tab, cpl_vector_get_data(wcorr), "logwave");
00465 cpl_table_wrap_double(tab, cpl_vector_get_data(fcorr), "flux");
00466
00467 sprintf(fname, "fcorr_org.fits");
00468
00469 cpl_table_and_selected_double(tab, "logwave", CPL_GREATER_THAN,
00470 (*gfit).peakpos - range);
00471 cpl_table_and_selected_double(tab, "logwave", CPL_LESS_THAN,
00472 (*gfit).peakpos + range);
00473
00474 ext_tab = cpl_table_extract_selected(tab);
00475 xsh_free_table(&tab);
00476 sprintf(fname, "fcorr_ext.fits");
00477
00478 int next = 0;
00479 next = cpl_table_get_nrow(ext_tab);
00480 sprintf(fname, "fcorr_tab.fits");
00481
00482 double peakpos=0;
00483 double sigma=0;
00484 double area=0;
00485 double offset=0;
00486 double mse=0;
00487
00488 wave = cpl_vector_wrap(next, cpl_table_get_data_double(ext_tab, "logwave"));
00489 flux = cpl_vector_wrap(next, cpl_table_get_data_double(ext_tab, "flux"));
00490
00491
00492 cpl_vector_fit_gaussian( wave, NULL, flux,NULL, CPL_FIT_ALL,
00493 &peakpos, &sigma,&area, &offset, &mse,NULL,NULL);
00494
00495 cpl_vector_fit_gaussian( wave, NULL, flux,NULL, CPL_FIT_ALL,
00496 &gfit->peakpos, &gfit->sigma,&gfit->area, &gfit->offset, &gfit->mse,NULL,NULL);
00497
00498
00499
00500 cleanup:
00501 cpl_vector_unwrap(wave);
00502 cpl_vector_unwrap(flux);
00503
00504
00505
00506
00507 return cpl_error_get_code();
00508 }
00509
00510 static cpl_table*
00511 xsh_table_select_range(cpl_table* table_in,const char* col,const double wmin, const double wmax)
00512 {
00513 cpl_table* table_ext=NULL;
00514
00515 cpl_table_and_selected_double(table_in, col, CPL_NOT_LESS_THAN, wmin);
00516 cpl_table_and_selected_double(table_in, col, CPL_NOT_GREATER_THAN, wmax);
00517 table_ext=cpl_table_extract_selected(table_in);
00518
00519 return table_ext;
00520 }
00521
00522
00523
00524
00525
00526 cpl_error_code
00527 xsh_correl_spectra(double* flux_s, double* flux_m, const int size,const int hsearch,
00528 const double wlogstp,const double range, const int ext,XSH_GAUSSIAN_FIT* gfit)
00529 {
00530 double* xcorr = NULL;
00531 double* pwcorr = NULL;
00532 double corr = 0;
00533 double delta=0;
00534 char fname[256];
00535 int i=0;
00536 double size_corr = 2 * hsearch + 1;
00537 cpl_vector* f1=NULL;
00538 cpl_vector* f2=NULL;
00539 cpl_vector* correl=NULL;
00540 double shift=0;
00541 cpl_vector* fcorr = NULL;
00542 cpl_vector* wcorr = NULL;
00543
00544 check(xcorr = xsh_function1d_xcorrelate(flux_s, size, flux_m, size, hsearch,0,
00545 &corr, &delta));
00546
00547
00548 check(f1=cpl_vector_wrap(size, flux_s));
00549 f2=cpl_vector_wrap(size, flux_m);
00550
00551
00552
00553 correl=cpl_vector_new(size_corr);
00554 check(shift=cpl_vector_correlate(correl,f1,f2));
00555 cpl_vector_unwrap(f1);
00556 cpl_vector_unwrap(f2);
00557
00558
00559
00560
00561
00562 gfit->peakpos = (hsearch + delta)*wlogstp;
00563 gfit->sigma = wlogstp*10;
00564 gfit->area = 1.;
00565
00566 xsh_msg("gauss guess: peak: %12.8g sigma %g", gfit->peakpos, gfit->sigma);
00567
00568 check(fcorr = cpl_vector_wrap(size_corr, xcorr));
00569 wcorr = cpl_vector_new(size_corr);
00570 pwcorr = cpl_vector_get_data(wcorr);
00571 for (i = 0; i < size_corr; i++) {
00572 pwcorr[i] = i*wlogstp;
00573 }
00574
00575 sprintf(fname,"fcorr.fits");
00576
00577 sprintf(fname,"wcorr.fits");
00578
00579
00580
00581 check(xsh_get_xcorrel_peak(wcorr,fcorr,gfit,range,ext));
00582
00583
00584 xsh_msg("gauss fit: peak[lognm]: %12.8g sigma[lognm] %g peak[sampl_units]: %12.8g sigma[sampl_units] %g",
00585 gfit->peakpos, gfit->sigma,gfit->peakpos/wlogstp, gfit->sigma/wlogstp);
00586
00587
00588 cleanup:
00589 cpl_vector_unwrap(fcorr);
00590
00591
00592
00593 xsh_free_vector(&correl);
00594
00595 return cpl_error_get_code();
00596
00597 }
00598 static cpl_error_code
00599 xsh_align_model_to_spectrum(cpl_table* table_me,cpl_table* table_se,const int ext,cpl_table** table_mm)
00600 {
00601 cpl_table* table_rm = NULL;
00602 cpl_table* table_rs = NULL;
00603 char fname[256];
00604 double wlogstp = 0.00001;
00605 int i=0;
00606 int size_mm=cpl_table_get_nrow(*table_mm);
00607 cpl_lowpass filter_type = CPL_LOWPASS_LINEAR;
00608 cpl_vector* vfluxm = NULL;
00609 cpl_vector* vlowpass_fluxm = NULL;
00610
00611
00612 table_rm = xsh_table_resample_uniform(table_me, "logwave", "flux", wlogstp);
00613
00614 sprintf(fname, "model_selected_wrange_log_resampled_uniform.fits");
00615
00616
00617
00618 table_rs = xsh_table_downsample_table(table_se, "logwave", "flux", table_rm,
00619 "logwave", "flux");
00620
00621 sprintf(fname, "spectrum_resampled_used_in_correlation.fits");
00622
00623
00624
00625
00626
00627
00628
00629 double corr = 0;
00630 double* flux_s = NULL;
00631 double* flux_m = NULL;
00632 int size_s = 0;
00633 int size_m = 0;
00634 int hsearch = 500;
00635 double delta = 0;
00636 double size_x = 2 * hsearch + 1;
00637 double* xcorr = NULL;
00638 double* pwcorr = NULL;
00639 XSH_GAUSSIAN_FIT gfit;
00640 int size=0;
00641 double wrange=0.001;
00642 size=cpl_table_get_nrow(table_rs);
00643
00644 flux_s = cpl_table_get_data_double(table_rs, "flux");
00645 flux_m = cpl_table_get_data_double(table_rm, "flux");
00646 size_s = cpl_table_get_nrow(table_rs);
00647 size_m = cpl_table_get_nrow(table_me);
00648
00649 xsh_msg("hsearch=%d",hsearch);
00650 check(xsh_correl_spectra(flux_s,flux_m,size_s,hsearch,wlogstp,wrange,ext,&gfit));
00651
00652 xsh_msg("computed shift[lognm]=%g",(gfit.peakpos-hsearch*wlogstp));
00653 hsearch=(int)3.*CPL_MATH_FWHM_SIG * gfit.sigma/wlogstp;
00654 xsh_msg("hsearch=%d",hsearch);
00655 check(xsh_correl_spectra(flux_s,flux_m,size_s,hsearch,wlogstp,wrange,ext,&gfit));
00656
00657
00658
00659
00660 cpl_table_add_scalar(*table_mm, "logwave", (gfit.peakpos-hsearch*wlogstp));
00661 xsh_msg("computed shift[lognm]=%g",(gfit.peakpos-hsearch*wlogstp));
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 double* pvlowpass_fluxm = NULL;
00683 double* pflux_c = NULL;
00684 double fwhm = CPL_MATH_FWHM_SIG * gfit.sigma;
00685 double fwhm_nm = pow(CPL_MATH_E, fwhm);
00686 cpl_vector * conv_kernel =NULL;
00687 cpl_vector * spec_clean=NULL;
00688
00689 int fwhm_pix = (int) (fwhm / wlogstp + 0.5);
00690
00691 cpl_table_new_column(*table_mm, "flux_c", CPL_TYPE_DOUBLE);
00692 cpl_table_fill_column_window_double(*table_mm, "flux_c", 0, size_mm, 0);
00693 xsh_msg("fwhm_nm=%12.10g fwhm_pix=%d",fwhm_nm,fwhm_pix);
00694
00695 vfluxm = cpl_vector_wrap(size_mm,cpl_table_get_data_double(*table_mm, "flux"));
00696
00697
00698 conv_kernel = cpl_wlcalib_xc_convolve_create_kernel(fwhm_pix/CPL_MATH_FWHM_SIG,fwhm_pix/CPL_MATH_FWHM_SIG);
00699 vlowpass_fluxm=cpl_vector_duplicate(vfluxm);
00700 cpl_wlcalib_xc_convolve(vlowpass_fluxm, conv_kernel);
00701
00702
00703
00704 pvlowpass_fluxm = cpl_vector_get_data(vlowpass_fluxm);
00705 cpl_vector_unwrap(vfluxm);
00706
00707 pflux_c = cpl_table_get_data_double(*table_mm, "flux_c");
00708 for (i = 0; i < size_mm; i++) {
00709 pflux_c[i] = pvlowpass_fluxm[i];
00710 }
00711 sprintf(fname, "model_convolved.fits", ext);
00712
00713
00714 cleanup:
00715
00716 xsh_free_vector(&vlowpass_fluxm);
00717 xsh_free_table(&table_rs);
00718 xsh_free_table(&table_rm);
00719
00720 return cpl_error_get_code();
00721
00722 }
00723
00724 cpl_table*
00725 xsh_telluric_model_eval(cpl_frame* frame_m,xsh_spectrum* s,xsh_instrument* instrument,cpl_size* model_idx)
00726 {
00727
00728 cpl_table* tab_res=NULL;
00729 cpl_table* table_s=NULL;
00730 cpl_table* table_m=NULL;
00731 cpl_table* table_se=NULL;
00732 cpl_table* table_mm=NULL;
00733 cpl_table* table_rm = NULL;
00734 cpl_table* table_rs_div_mc=NULL;
00735 cpl_table* table_me=NULL;
00736 cpl_table* table_rs=NULL;
00737 const char* name_model=NULL;
00738
00739 double wmin=0;
00740 double wmax=0;
00741
00742 double lmin=7.0;
00743 double lmax=7.1;
00744 double um2nm=1000.;
00745
00746 int ext=0;
00747 int next=0;
00748 double mean=0;
00749 double rms=0;
00750
00751 int nsamples=0;
00752 char fname[256];
00753 cpl_table* tab_corr = NULL;
00754 cpl_table* tab_stack = NULL;
00755
00756 cpl_table* ext_tab = NULL;
00757 double* pmean=NULL;
00758 double* prms=NULL;
00759 int* pext=NULL;
00760
00761 HIGH_ABS_REGION * phigh = NULL;
00762 wmin= xsh_spectrum_get_lambda_min(s);
00763 wmax= xsh_spectrum_get_lambda_max(s);
00764
00765
00766 check(table_s=xsh_spectrum_to_table(s));
00767 sprintf(fname,"spectrum_obs.fits");
00768
00769 check(phigh=xsh_fill_tell_fit_regions(instrument,NULL));
00770
00771 for (; phigh->lambda_min != 0.; phigh++) {
00772 nsamples++;
00773 }
00774
00775 check(name_model=cpl_frame_get_filename(frame_m));
00776
00777 check(next=cpl_frame_get_nextensions(frame_m));
00778 check(tab_res=cpl_table_new(next));
00779 cpl_table_new_column(tab_res,"id",CPL_TYPE_INT);
00780 cpl_table_new_column(tab_res,"mean",CPL_TYPE_DOUBLE);
00781 cpl_table_new_column(tab_res,"rms",CPL_TYPE_DOUBLE);
00782
00783 cpl_table_fill_column_window_int(tab_res, "id", 0, next, 0);
00784 cpl_table_fill_column_window_double(tab_res, "mean", 0, next, 0);
00785 cpl_table_fill_column_window_double(tab_res, "rms", 0, next, 0);
00786 pext=cpl_table_get_data_int(tab_res,"id");
00787 pmean=cpl_table_get_data_double(tab_res,"mean");
00788 prms=cpl_table_get_data_double(tab_res,"rms");
00789 check(next=cpl_table_get_nrow(tab_res));
00790
00791
00792 for (ext = 0; ext < next; ext++) {
00793
00794
00795 check(table_m = cpl_table_load(name_model, ext+1, 1));
00796 sprintf(fname,"model_arm.fits");
00797
00798
00799 cpl_table_multiply_scalar(table_m, "lam", um2nm);
00800 cpl_table_duplicate_column(table_m, "logwave", table_m, "lam");
00801 cpl_table_logarithm_column(table_m, "logwave", CPL_MATH_E);
00802
00803
00804 table_mm=xsh_table_select_range(table_m,"lam",wmin, wmax);
00805
00806 sprintf(fname,"model_range_arm.fits");
00807
00808
00809
00810
00811 table_me=xsh_table_select_range(table_mm,"logwave",lmin, lmax);
00812
00813
00814
00815
00816
00817
00818
00819 sprintf(fname,"model_selected_wrange_log.fits");
00820
00821
00822
00823 table_se=xsh_table_select_range(table_s,"logwave",lmin, lmax);
00824 cpl_table_duplicate_column(table_se, "wav", table_se, "logwave");
00825 cpl_table_exponential_column(table_se, "wav", CPL_MATH_E);
00826 sprintf(fname,"spectrum_selected_wrange_log.fits");
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850 check(xsh_align_model_to_spectrum(table_me,table_se,ext,&table_mm));
00851 xsh_free_table(&table_me);
00852 xsh_free_table(&table_se);
00853
00854
00855
00856
00857
00858
00859 check(cpl_table_duplicate_column(table_mm,"wave",table_mm,"logwave"));
00860 check(cpl_table_exponential_column(table_mm,"wave",CPL_MATH_E));
00861 sprintf(fname,"model_aligned_to_obs.fits");
00862
00863
00864
00865
00866
00867
00868
00869 xsh_free_table(&table_rs);
00870
00871 xsh_free_table(&table_rm);
00872
00873
00874
00875
00876
00877
00878 check(table_rm = xsh_table_resample_table(table_mm,"wave","flux",table_s,"wavelength","flux"));
00879 sprintf(fname,"table_rm.fits");
00880
00881
00882
00883 check(
00884 table_rs=xsh_table_resample_table(table_s,"wavelength","flux",table_mm,"wave","flux"));
00885
00886
00887 sprintf(fname,"spectrum_resampled_to_model.fits");
00888
00889
00890 cpl_table_duplicate_column(table_rs, "flux_model_convolved", table_mm, "flux_c");
00891 cpl_table_duplicate_column(table_rs, "ratio", table_rs, "flux");
00892 xsh_free_table(&table_mm);
00893 check(cpl_table_divide_columns(table_rs,"ratio","flux_model_convolved"));
00894
00895
00896
00897
00898 sprintf(fname,"spectrum_observed_divided_by_model_convolved.fits");
00899 check(xsh_table_save(table_rs,NULL,NULL,fname,ext));
00900 table_rs_div_mc=cpl_table_duplicate(table_rs);
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914 check(tab_stack=xsh_extract_ranges_to_fit(table_rs,"wave",instrument));
00915 sprintf(fname,"tab_stack.fits");
00916
00917
00918
00919
00920
00921
00922
00923 cpl_vector* vec_wave = NULL;
00924 cpl_vector* vec_flux = NULL;
00925
00926 check(xsh_extract_points_to_fit(table_rs,"wave","ratio",nsamples,instrument,&vec_wave,&vec_flux));
00927
00928 double* sfit=NULL;
00929 double* pfit=NULL;
00930 double* pwave=NULL;
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941 int nsel = 0;
00942
00943 check(nsel=cpl_table_get_nrow(tab_stack));
00944 cpl_table_new_column(tab_stack, "fit", CPL_TYPE_DOUBLE);
00945 cpl_table_fill_column_window_double(tab_stack, "fit", 0, nsel, 0);
00946 pfit = cpl_table_get_data_double(tab_stack, "fit");
00947 pwave = cpl_table_get_data_double(tab_stack, "wave");
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970 double* pvec_wave=NULL;
00971 double* pvec_flux=NULL;
00972 pvec_wave=cpl_vector_get_data(vec_wave);
00973 pvec_flux=cpl_vector_get_data(vec_flux);
00974
00975
00976
00977 sfit = xsh_bspline_interpolate_data_at_pos(pvec_wave, pvec_flux, nsamples+2,
00978 pvec_wave,nsamples+2);
00979
00980
00981
00982
00983 int i=0;
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994 xsh_free_table(&tab_stack);
00995
00996 cpl_table* tab_med = cpl_table_new(nsamples+2);
00997
00998 check(cpl_table_wrap_double(tab_med,pvec_wave,"wave"));
00999 check(cpl_table_wrap_double(tab_med,pvec_flux,"ratio"));
01000 check(cpl_table_wrap_double(tab_med,sfit,"fit"));
01001 sprintf(fname,"ratio_med.fits");
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011 double* wave=NULL;
01012
01013 tab_corr=cpl_table_duplicate(table_rs);
01014 int nrow=cpl_table_get_nrow(tab_corr);
01015 cpl_table_new_column(tab_corr,"fit",CPL_TYPE_DOUBLE);
01016 cpl_table_fill_column_window_double(tab_corr, "fit", 0, nrow, 0);
01017
01018 check(pfit=cpl_table_get_data_double(tab_corr,"fit"));
01019 check(wave=cpl_table_get_data_double(tab_corr,"wave"));
01020
01021
01022 check(sfit = xsh_bspline_interpolate_data_at_pos(pvec_wave, pvec_flux,
01023 nsamples+2,wave,nrow));
01024 for (i = 0; i < nrow; i ++) {
01025 pfit[i]=sfit[i];
01026 }
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036 check(cpl_table_duplicate_column(tab_corr, "correction", table_rs, "ratio"));
01037 check(cpl_table_divide_columns(tab_corr, "correction", "fit"));
01038
01039
01040
01041 cpl_table_unwrap(tab_med,"fit");
01042 xsh_free_table(&table_rs);
01043 xsh_free_vector(&vec_wave);
01044 xsh_free_vector(&vec_flux);
01045
01046 cpl_free(sfit);
01047
01048
01049
01050
01051
01052
01053 check(xsh_evaluate_tell_model(tab_corr,instrument,ext,&mean,&rms));
01054 cpl_propertylist* qc_head=NULL;
01055 qc_head=cpl_propertylist_new();
01056 cpl_propertylist_append_double(qc_head,XSH_QC_TELLCORR_RATAVG,mean);
01057 cpl_propertylist_append_double(qc_head,XSH_QC_TELLCORR_RATRMS,rms);
01058
01059
01060 xsh_msg("ext=%d mean=%g rms=%g", ext,mean, rms);
01061 xsh_free_propertylist(&qc_head);
01062 xsh_free_table(&ext_tab);
01063 xsh_free_table(&tab_corr);
01064 pmean[ext]=mean;
01065 prms[ext]=rms;
01066 pext[ext]=ext;
01067 }
01068 double model_mean=0;
01069 double model_rms=0;
01070 int status=0;
01071 check(model_mean=cpl_table_get_column_min(tab_res,"mean"));
01072
01073
01074 cpl_table_get_column_minpos(tab_res,"mean",model_idx);
01075 check(model_rms=cpl_table_get_double(tab_res,"rms",*model_idx,&status));
01076 xsh_msg("optimal model: mean=%g rms=%g",model_mean,model_rms);
01077 xsh_msg("optimal model id %d mean %g rms %g",
01078 (int)(*model_idx),model_mean,model_rms);
01079
01080
01081
01082 sprintf(fname,"spectrum_observed_divided_by_model_convolved.fits");
01083 xsh_add_temporary_file(fname);
01084 ext=(int)(*model_idx);
01085 xsh_msg("fname=%s ext=%d",fname,ext);
01086 check(table_rs=cpl_table_load(fname,ext+1,0));
01087
01088 cpl_propertylist* qc_head=NULL;
01089 qc_head=cpl_propertylist_new();
01090 cpl_propertylist_append_double(qc_head,XSH_QC_TELLCORR_RATAVG,mean);
01091 cpl_propertylist_append_double(qc_head,XSH_QC_TELLCORR_RATRMS,rms);
01092 cpl_propertylist_append_int(qc_head,XSH_QC_TELLCORR_OPTEXTID,ext+1);
01093
01094
01095 check(xsh_table_save(table_rs,NULL,qc_head,fname,0));
01096
01097
01098
01099
01100
01101
01102
01103 check(tab_corr=xsh_table_downsample_table(table_rs,"wave","ratio",table_rm,"wavelength","ratio"));
01104
01105
01106
01107
01108 cleanup:
01109
01110 xsh_free_table(&table_rs_div_mc);
01111 xsh_free_table(&table_rs);
01112 xsh_free_table(&tab_res);
01113 xsh_free_table(&table_s);
01114 xsh_free_table(&table_rm);
01115
01116 return tab_corr;
01117
01118 }
01119
01120