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 #ifdef HAVE_CONFIG_H
00027 #include <config.h>
00028 #endif
00029 #include <string.h>
00030 #include <math.h>
00031 #include <cpl.h>
00032
00033 #include <irplib_utils.h>
00034
00035 #include <sinfo_pfits.h>
00036 #include <sinfo_msg.h>
00037 #include <sinfo_dfs.h>
00038 #include <sinfo_error.h>
00039 #include <sinfo_utils_wrappers.h>
00040 #include "sinfo_utl_efficiency.h"
00041 #include <sinfo_star_index.h>
00042
00043 #define PRO_STD_STAR_SPECTRA "STD_STAR_SPECTRA"
00044 static const char COL_NAME_WAVELENGTH[] = "WAVELENGTH";
00045 static const char COL_NAME_WAVELENGTH_C[] = "WAVELENGTH";
00046 static const char COL_NAME_LAMBDA[] = "LAMBDA";
00047 static const char COL_NAME_LA_SILLA[] = "LA_SILLA";
00048 static const char COL_NAME_REF[] = "REF";
00049 static const char COL_NAME_COR[] = "COR";
00050 static const char COL_NAME_SRC_COR[] = "SRC_COR";
00051 static const char COL_NAME_COUNTS_BKG[] = "INT_OBJ";
00052 static const char COL_NAME_FLUX[] = "FLUX";
00053 static const char COL_NAME_EPHOT[] = "EPHOT";
00054 static const char COL_NAME_EXT[] = "EXT";
00055 static const char COL_NAME_SRC_EFF[] = "EFF";
00056 static const char PAR_NAME_DIT[] = "ESO DET DIT";
00057
00058 static char FRM_RAW_IMA_SLIT[] = PRO_STD_STAR_SPECTRA;
00059 static char FRM_FLUX_STD_TAB[] = FLUX_STD_TABLE;
00060 static char FRM_FLUX_STD_CAT[] = FLUX_STD_CATALOG;
00061 static char FRM_EXTCOEFF_TAB[] = EXTCOEFF_TABLE;
00062
00063 static int
00064 sinfo_column_to_double(cpl_table* ptable, const char* column);
00065
00066 static double
00067 sinfo_table_interpolate(cpl_table* tbl,
00068 double wav,
00069 const char* colx,
00070 const char* coly);
00071 static double*
00072 sinfo_create_column_double(cpl_table* tbl, const char* col_name, int nrow);
00073
00074
00075
00076 cpl_error_code
00077 sinfo_get_std_obs_values(cpl_propertylist* plist,
00078 double* exptime,
00079 double* airmass,
00080 double* dRA,
00081 double* dDEC);
00082
00083
00084
00085
00086
00097
00098
00099 void
00100 sinfo_load_ref_table(cpl_frameset* frames,
00101 double dRA,
00102 double dDEC,
00103 double EPSILON,
00104 cpl_table** pptable)
00105 {
00106 const char* name = NULL;
00107 cpl_frame* frm_ref = NULL;
00108
00109
00110 frm_ref=cpl_frameset_find(frames,FRM_FLUX_STD_TAB);
00111 if (!frm_ref)
00112 {
00113 sinfo_msg("REF frame is not found, trying to get REF from the catalog");
00114
00115
00116 check_nomsg(frm_ref=cpl_frameset_find(frames,FRM_FLUX_STD_CAT));
00117 if (frm_ref)
00118 {
00119 check_nomsg(name=cpl_frame_get_filename(frm_ref));
00120 if (name)
00121 {
00122 star_index* pstarindex = star_index_load(name);
00123 if (pstarindex)
00124 {
00125 const char* star_name = 0;
00126 sinfo_msg("The catalog is loaded, looking for star in RA[%f] DEC[%f] tolerance[%f]", dRA, dDEC, EPSILON);
00127 *pptable = star_index_get(pstarindex, dRA, dDEC, EPSILON, EPSILON, &star_name);
00128 if (*pptable && star_name)
00129 {
00130 sinfo_msg("REF table is found in the catalog, star name is [%s]", star_name);
00131 }
00132 else
00133 {
00134 sinfo_msg("ERROR - REF table could not be found in the catalog");
00135 }
00136 }
00137 else
00138 {
00139 sinfo_msg("ERROR - could not load the catalog");
00140 }
00141 }
00142 }
00143 }
00144 else
00145 {
00146 sinfo_msg("REF frame is found");
00147 check_nomsg(name=cpl_frame_get_filename(frm_ref));
00148 check_nomsg(*pptable=cpl_table_load(name,1,0));
00149 }
00150 return;
00151 cleanup:
00152 return;
00153 }
00154
00155
00156
00157
00158
00169
00170
00171 static void
00172 sinfo_parse_catalog_std_stars(cpl_frame* cat,
00173 double dRA,
00174 double dDEC,
00175 double EPSILON,
00176 cpl_table** pptable)
00177 {
00178 const char* name = NULL;
00179
00180 if (cat) {
00181 check_nomsg(name=cpl_frame_get_filename(cat));
00182 if (name) {
00183 star_index* pstarindex = star_index_load(name);
00184 if (pstarindex) {
00185 const char* star_name = 0;
00186 sinfo_msg("The catalog is loaded, looking for star in RA[%f] DEC[%f] tolerance[%f]", dRA, dDEC, EPSILON);
00187 *pptable = star_index_get(pstarindex, dRA, dDEC, EPSILON, EPSILON, &star_name);
00188 if (*pptable && star_name) {
00189 sinfo_msg("REF table is found in the catalog, star name is [%s]", star_name);
00190 }
00191 else {
00192 sinfo_msg("ERROR - REF table could not be found in the catalog");
00193 }
00194 }
00195 else {
00196 sinfo_msg("ERROR - could not load the catalog");
00197 }
00198
00199 }
00200 }
00201
00202 cleanup:
00203 return;
00204 }
00205
00206
00207
00208
00209
00218
00219
00220
00221 double
00222 sinfo_data_interpolate(
00223 double wav,
00224 int nrow,
00225 double* pw,
00226 double* pe
00227 )
00228 {
00229 double y = 0;
00230 double w1=pw[0];
00231 double w2=pw[nrow-1];
00232 double y1_=pe[0];
00233 double y2=pe[nrow-1];
00234 if(wav < pw[0])
00235 {
00236 w1=pw[0];
00237 w2=pw[1];
00238 y1_=pe[0];
00239 y2=pe[1];
00240 }
00241 else if (wav > pw[nrow - 1])
00242 {
00243 w1=pw[nrow - 2];
00244 w2=pw[nrow - 1];
00245 y1_=pe[nrow - 2];
00246 y2=pe[nrow - 1];
00247 }
00248 else
00249 {
00250 int l = 0;
00251 int h = nrow - 1;
00252 int curr_row = 0;
00253 curr_row = (h-l) / 2;
00254 while( h-l >1 )
00255 {
00256 if(wav < pw[curr_row])
00257 {
00258 h = curr_row;
00259 }
00260 else
00261 {
00262 l = curr_row;
00263 }
00264 curr_row = (h-l) / 2 + l;
00265 }
00266 w1=pw[curr_row];
00267 w2=pw[curr_row + 1];
00268 y1_=pe[curr_row];
00269 y2=pe[curr_row + 1];
00270 }
00271 y=y1_+(y2-y1_)/(w2-w1)*(wav-w1);
00272 return y;
00273 }
00274 static double
00275 sinfo_table_interpolate(cpl_table* tbl,
00276 double wav,
00277 const char* colx,
00278 const char* coly)
00279 {
00280
00281 double y=0;
00282 double* pe=NULL;
00283 double* pw=NULL;
00284 int nrow=0;
00285
00286 check_nomsg(pw=cpl_table_get_data_double(tbl,colx));
00287 check_nomsg(pe=cpl_table_get_data_double(tbl,coly));
00288 check_nomsg(nrow=cpl_table_get_nrow(tbl));
00289
00290 y = sinfo_data_interpolate(wav, nrow, pw, pe);
00291 cleanup:
00292 return y;
00293
00294 }
00295
00296 static double*
00297 sinfo_create_column_double(cpl_table* tbl, const char* col_name, int nrow)
00298 {
00299 double* retval = 0;
00300 check_nomsg(cpl_table_new_column(tbl, col_name, CPL_TYPE_DOUBLE));
00301 check_nomsg(cpl_table_fill_column_window_double(tbl, col_name, 0, nrow, -1));
00302 check_nomsg(retval = cpl_table_get_data_double(tbl,col_name));
00303 return retval;
00304 cleanup:
00305 return retval;
00306 }
00307
00308
00309
00319
00320
00321 cpl_error_code
00322 sinfo_get_std_obs_values(cpl_propertylist* plist,
00323 double* exptime,
00324 double* airmass,
00325 double* dRA,
00326 double* dDEC)
00327 {
00328 double airmass_start=0;
00329 double airmass_end=0;
00330
00331 check_nomsg(*exptime=sinfo_pfits_get_exp_time(plist));
00332 airmass_start=sinfo_pfits_get_airmass_start(plist);
00333 airmass_end=sinfo_pfits_get_airmass_end(plist);
00334 *dRA=sinfo_pfits_get_ra(plist);
00335 *dDEC=sinfo_pfits_get_dec(plist);
00336 *airmass=0.5*(airmass_start+airmass_end);
00337
00338 cleanup:
00339 return cpl_error_get_code();
00340
00341 }
00342
00343
00360
00361
00362 cpl_table*
00363 sinfo_utl_efficiency(
00364 cpl_frameset * frames,
00365 double dGain,
00366 double dEpsilon,
00367 double aimprim,
00368 const char* col_name_atm_wave,
00369 const char* col_name_atm_abs,
00370 const char* col_name_ref_wave,
00371 const char* col_name_ref_flux,
00372 const char* col_name_ref_bin,
00373 const char* col_name_obj_wave,
00374 const char* col_name_obj_flux
00375 )
00376 {
00377 cpl_frame* frm_sci = NULL;
00378 cpl_frame* frm_atmext = NULL;
00379 cpl_table* tbl_obj_spectrum = NULL;
00380 cpl_table* tbl_atmext = NULL;
00381 double exptime = 600;
00382
00383 cpl_propertylist* plist = NULL;
00384 cpl_table* tbl_ref = NULL;
00385 cpl_table* tbl_result=NULL;
00386
00387 const char* name=NULL;
00388 double dRA = 0;
00389 double dDEC = 0;
00390
00391 double airmass=0;
00392 const double mk2AA=1E4;
00393
00394
00395
00396
00397
00398 check_nomsg(frm_sci=cpl_frameset_find(frames, FRM_RAW_IMA_SLIT));
00399 check_nomsg(name=cpl_frame_get_filename(frm_sci));
00400 sinfo_msg("name=%s",name);
00401 check_nomsg(tbl_obj_spectrum=cpl_table_load(name,1,0));
00402 check_nomsg(plist=cpl_propertylist_load(name,0));
00403
00404 sinfo_get_std_obs_values(plist,&exptime,&airmass,&dRA,&dDEC);
00405
00406
00407 sinfo_load_ref_table(frames, dRA, dDEC, dEpsilon, &tbl_ref);
00408 if (tbl_ref)
00409 {
00410
00411 check_nomsg(frm_atmext=cpl_frameset_find(frames,FRM_EXTCOEFF_TAB));
00412 check_nomsg(name=cpl_frame_get_filename(frm_atmext));
00413 check_nomsg(tbl_atmext=cpl_table_load(name,1,0));
00414
00415 tbl_result = sinfo_utl_efficiency_internal(
00416 tbl_obj_spectrum,
00417 tbl_atmext,
00418 tbl_ref,
00419 exptime,
00420 airmass,
00421 aimprim,
00422 dGain,
00423 1,
00424 mk2AA,
00425 col_name_atm_wave,
00426 col_name_atm_abs,
00427 col_name_ref_wave,
00428 col_name_ref_flux,
00429 col_name_ref_bin,
00430 col_name_obj_wave,
00431 col_name_obj_flux
00432 );
00433 }
00434
00435 cleanup:
00436 sinfo_free_propertylist(&plist);
00437 sinfo_free_table(&tbl_atmext);
00438 sinfo_free_table(&tbl_obj_spectrum);
00439 sinfo_free_table(&tbl_ref);
00440 return tbl_result;
00441 }
00442 static int
00443 sinfo_column_to_double(cpl_table* ptable, const char* column)
00444 {
00445 const char* TEMP = "_temp_";
00446 check_nomsg(cpl_table_duplicate_column(ptable, TEMP, ptable, column));
00447 check_nomsg(cpl_table_erase_column(ptable, column));
00448 check_nomsg(cpl_table_cast_column(ptable, TEMP, column, CPL_TYPE_DOUBLE));
00449 check_nomsg(cpl_table_erase_column(ptable, TEMP ));
00450 return 0;
00451 cleanup:
00452 sinfo_msg(" error column to double [%s]", column);
00453 return -1;
00454 }
00455
00456
00457
00478
00479
00480 cpl_table*
00481 sinfo_utl_efficiency_internal(
00482 cpl_table* tbl_obj_spectrum,
00483 cpl_table* tbl_atmext,
00484 cpl_table* tbl_ref,
00485 double exptime,
00486 double airmass,
00487 double aimprim,
00488 double gain,
00489 int biny,
00490 double src2ref_wave_sampling,
00491 const char* col_name_atm_wave,
00492 const char* col_name_atm_abs,
00493 const char* col_name_ref_wave,
00494 const char* col_name_ref_flux,
00495 const char* col_name_ref_bin,
00496 const char* col_name_obj_wave,
00497 const char* col_name_obj_flux
00498 )
00499 {
00500
00501 const double TEL_AREA = 51.2e4;
00502 double cdelta1 = 0;
00503 int i = 0;
00504 cpl_table* tbl_sel = NULL;
00505
00506
00507
00508
00509
00510
00511 cpl_table* tbl_result = NULL;
00512
00513
00514
00515
00516
00517
00518
00519
00520 double* pref = NULL;
00521 double* pext = NULL;
00522 double* pcor = NULL;
00523 double* peph = NULL;
00524
00525 double* pw = NULL;
00526 double* pf = NULL;
00527 int nrow = 0;
00528 double ref_bin_size=0;
00529
00530 nrow = cpl_table_get_nrow(tbl_obj_spectrum);
00531 sinfo_msg("Starting efficiency calculation: exptime[%f] airmass[%f] nrow[%d]",
00532 exptime, airmass, nrow);
00533
00534
00535
00536
00537
00538 sinfo_column_to_double(tbl_obj_spectrum,col_name_obj_wave);
00539 sinfo_column_to_double(tbl_obj_spectrum,col_name_obj_flux);
00540
00541 check_nomsg(sinfo_column_to_double(tbl_atmext,col_name_atm_wave ));
00542 check_nomsg(sinfo_column_to_double(tbl_atmext,col_name_atm_abs ));
00543 check_nomsg(sinfo_column_to_double(tbl_ref,col_name_ref_wave ));
00544 check_nomsg(sinfo_column_to_double(tbl_ref,col_name_ref_flux ));
00545 check_nomsg(sinfo_column_to_double(tbl_ref,col_name_ref_bin ));
00546
00547
00548 ref_bin_size=cpl_table_get_double(tbl_ref,col_name_ref_bin,0,NULL);
00549 sinfo_msg("ref_bin_size[AA]=%g",ref_bin_size);
00550
00551
00552
00553
00554
00555
00556 check_nomsg(cpl_table_multiply_scalar(tbl_obj_spectrum,col_name_obj_wave,
00557 src2ref_wave_sampling));
00558
00559 check_nomsg(cpl_table_save(tbl_ref,NULL,NULL,"ref2.fits",CPL_IO_DEFAULT));
00560 check_nomsg(cpl_table_save(tbl_atmext,NULL,NULL,"atm2.fits",CPL_IO_DEFAULT));
00561 check_nomsg(cpl_table_save(tbl_obj_spectrum,NULL,NULL,"sci2.fits",CPL_IO_DEFAULT));
00562 sinfo_msg("object 2 src std %g",src2ref_wave_sampling);
00563 check_nomsg(pw=cpl_table_get_data_double(tbl_obj_spectrum,col_name_obj_wave));
00564 check_nomsg(pf=cpl_table_get_data_double(tbl_obj_spectrum,col_name_obj_flux));
00565
00566
00567 check_nomsg(tbl_result=cpl_table_new(nrow));
00568 check_nomsg(pref=sinfo_create_column_double(tbl_result, COL_NAME_REF, nrow));
00569 check_nomsg(pext=sinfo_create_column_double(tbl_result, COL_NAME_EXT, nrow));
00570 check_nomsg(pcor=sinfo_create_column_double(tbl_result, COL_NAME_COR, nrow));
00571 check_nomsg(peph=sinfo_create_column_double(tbl_result, COL_NAME_EPHOT, nrow));
00572 sinfo_msg("wave range: [%g,%g]",pw[0],pw[nrow-1]);
00573 sinfo_msg("src_bin_size[AA]=%g",pw[1] - pw[0]);
00574
00575 cdelta1 = (pw[1] - pw[0]) / src2ref_wave_sampling ;
00576
00577 for (i = 0; i < nrow; i++)
00578 {
00579 check_nomsg(pext[i] = sinfo_table_interpolate(tbl_atmext, pw[i],col_name_atm_wave, col_name_atm_abs));
00580 check_nomsg(pref[i] = sinfo_table_interpolate(tbl_ref, pw[i], col_name_ref_wave,col_name_ref_flux));
00581 pcor[i] = pow(10,(0.4*pext[i] * (aimprim - airmass)));
00582 peph[i] = 1.e7*1.986e-19/(pw[i]*1e-4);
00583
00584
00585
00586
00587
00588
00589
00590
00591 }
00592
00593
00594
00595
00596
00597
00598
00599
00600 check_nomsg(cpl_table_duplicate_column(tbl_result,COL_NAME_SRC_COR,
00601 tbl_obj_spectrum, col_name_obj_flux));
00602 check_nomsg(cpl_table_duplicate_column(tbl_result,col_name_obj_wave,
00603 tbl_obj_spectrum,col_name_obj_wave));
00604
00605 check_nomsg(cpl_table_multiply_columns(tbl_result,COL_NAME_SRC_COR,COL_NAME_COR));
00606
00607
00608
00609
00610 cpl_table_divide_scalar(tbl_result, COL_NAME_SRC_COR, src2ref_wave_sampling);
00611
00612 cpl_table_divide_scalar(tbl_result, COL_NAME_SRC_COR, cdelta1);
00613
00614
00615 cpl_table_divide_scalar(tbl_result,COL_NAME_SRC_COR,biny);
00616
00617
00618
00619
00620 check_nomsg(cpl_table_divide_scalar(tbl_result,COL_NAME_REF,ref_bin_size));
00621
00622 check_nomsg(cpl_table_duplicate_column(tbl_result,COL_NAME_SRC_EFF,
00623 tbl_result,COL_NAME_SRC_COR));
00624
00625
00626
00627 check_nomsg(cpl_table_multiply_scalar(tbl_result,COL_NAME_SRC_EFF,
00628 gain / (exptime * TEL_AREA)));
00629
00630
00631 check_nomsg(cpl_table_multiply_columns(tbl_result,COL_NAME_SRC_EFF,
00632 COL_NAME_EPHOT));
00633
00634
00635 check_nomsg(cpl_table_divide_columns(tbl_result,COL_NAME_SRC_EFF,COL_NAME_REF));
00636
00637 check_nomsg(cpl_table_multiply_scalar(tbl_result,COL_NAME_SRC_EFF,1.e16));
00638
00639
00640 cpl_table_and_selected_double(tbl_result,COL_NAME_SRC_EFF,
00641 CPL_GREATER_THAN,1.e-5);
00642 cpl_table_and_selected_double(tbl_result,COL_NAME_SRC_EFF,
00643 CPL_LESS_THAN,100.);
00644 tbl_sel=cpl_table_extract_selected(tbl_result);
00645 check_nomsg(cpl_table_save(tbl_result,NULL,NULL,"result9.fits",CPL_IO_DEFAULT));
00646
00647 cleanup:
00648 sinfo_free_table(&tbl_result);
00649 return tbl_sel;
00650 }
00651
00652
00653 cpl_table*
00654 sinfo_efficiency_compute(cpl_frame* frm_sci,
00655 cpl_frame* frm_cat,
00656 cpl_frame* frm_atmext)
00657
00658 {
00659
00660 cpl_propertylist* plist=NULL;
00661
00662 cpl_table* tbl_eff=NULL;
00663 cpl_table* tbl_ref=NULL;
00664 cpl_table* tbl_atmext=NULL;
00665 cpl_table* tbl_sci=NULL;
00666
00667 double exptime=600;
00668 double airmass=0;
00669 double airmass_start=0;
00670 double airmass_end=0;
00671 double dRA=0;
00672 double dDEC=0;
00673 double gain=0;
00674 double aimprim=0;
00675 double dEpsilon=0.1;
00676 double um2AA=1.e4;
00677
00678 int nrow=0;
00679 int biny=1;
00680
00681 const char* name_sci=NULL;
00682 const char* name_atm=NULL;
00683
00684 name_sci=cpl_frame_get_filename(frm_sci);
00685 sinfo_msg("name_sci=%s",name_sci);
00686 check_nomsg(plist=cpl_propertylist_load(name_sci,0));
00687 check_nomsg(tbl_sci=cpl_table_load(name_sci,1,0));
00688 check_nomsg(dRA=sinfo_pfits_get_ra(plist));
00689 dDEC=sinfo_pfits_get_dec(plist);
00690 airmass_start=sinfo_pfits_get_airmass_end(plist);
00691 airmass_end=sinfo_pfits_get_airmass_end(plist);
00692 airmass=0.5*(airmass_start+airmass_end);
00693 gain=2.42;
00694 biny=1;
00695 check_nomsg(exptime=sinfo_pfits_get_dit(plist));
00696 sinfo_free_propertylist(&plist);
00697 sinfo_msg("gain=%g airm=%g exptime=%g airmass=%g ra=%g dec=%g",
00698 gain,airmass,exptime,airmass,dRA,dDEC);
00699
00700 sinfo_msg("table sci spectra=%s",name_sci);
00701 nrow=cpl_table_get_nrow(tbl_sci);
00702
00703 check_nomsg(name_atm=cpl_frame_get_filename(frm_atmext));
00704 check_nomsg(tbl_atmext=cpl_table_load(name_atm,1,0));
00705
00706 check_nomsg(sinfo_parse_catalog_std_stars(frm_cat,dRA,dDEC,dEpsilon,&tbl_ref));
00707
00708 if(tbl_ref == NULL) {
00709 sinfo_msg_error("Provide std sar catalog frame");
00710 return NULL;
00711
00712 }
00713
00714 check_nomsg(cpl_table_save(tbl_sci,NULL,NULL,"sci.fits",CPL_IO_DEFAULT));
00715 check_nomsg(tbl_eff=sinfo_utl_efficiency_internal(tbl_sci,tbl_atmext,tbl_ref,
00716 exptime,airmass,aimprim,gain,
00717 biny,um2AA,
00718 "LAMBDA",
00719 "LA_SILLA",
00720 "LAMBDA",
00721 "F_LAMBDA",
00722 "BIN_WIDTH",
00723 "wavelength",
00724 "counts_bkg"));
00725
00726 cleanup:
00727 sinfo_free_table(&tbl_ref);
00728 sinfo_free_table(&tbl_atmext);
00729 sinfo_free_propertylist(&plist);
00730
00731 return tbl_eff;
00732
00733 }