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 <xsh_irplib_utils.h>
00034
00035
00036 #include <xsh_pfits.h>
00037 #include <xsh_msg.h>
00038 #include <xsh_dfs.h>
00039 #include <xsh_error.h>
00040 #include <xsh_utils.h>
00041 #include <xsh_utils_table.h>
00042 #include <xsh_utils_wrappers.h>
00043 #include <xsh_utils_efficiency.h>
00044 #include <xsh_efficiency_response.h>
00045 #include <xsh_star_index.h>
00046 #include <xsh_irplib_utils.h>
00047 #include <xsh_data_atmos_ext.h>
00048
00049 #define PRO_STD_STAR_SPECTRA "STD_STAR_SPECTRA"
00050 static const char COL_NAME_HIGH_ABS[] = "HIGH_ABS";
00051 static const char COL_NAME_WAVELENGTH[] = "WAVELENGTH";
00052 static const char COL_NAME_WAVELENGTH_C[] = "WAVELENGTH";
00053 static const char COL_NAME_WAVE_ATMDISP[] = "LAMBDA";
00054 static const char COL_NAME_ABS_ATMDISP[] = XSH_ATMOS_EXT_LIST_COLNAME_K;
00055
00056 static const char COL_NAME_REF[] = "REF";
00057 static const char COL_NAME_COR[] = "COR";
00058 static const char COL_NAME_SRC_COR[] = "SRC_COR";
00059
00060 static const char COL_NAME_WAVE_OBJ[] = "WAVELENGTH";
00061 static const char COL_NAME_INT_OBJ[] = "INT_OBJ";
00062 static const char COL_NAME_ORD_OBJ[] = "ORD";
00063 static const char COL_NAME_WAVE_REF[] = "LAMBDA";
00064 static const char COL_NAME_FLUX_REF[] = "FLUX";
00065 static const char COL_NAME_BINWIDTH_REF[] = "BIN_WIDTH";
00066 static const char COL_NAME_EPHOT[] = "EPHOT";
00067 static const char COL_NAME_EXT[] = "EXT";
00068 static const char COL_NAME_SRC_EFF[] = "EFF";
00069 static const char PAR_NAME_DIT[] = "ESO DET DIT";
00070 static const double UVES_flux_factor =1.e16;
00071
00072 static char FRM_EXTCOEFF_TAB[] = XSH_EXTCOEFF_TAB;
00073
00074 static int
00075 xsh_column_to_double(cpl_table* ptable, const char* column);
00076
00077
00078 static double*
00079 xsh_create_column_double(cpl_table* tbl, const char* col_name, int nrow);
00080
00081
00082
00083 static cpl_error_code
00084 xsh_get_std_obs_values(cpl_propertylist* plist,
00085 double* exptime,
00086 double* airmass,
00087 double* dRA,
00088 double* dDEC);
00089
00090
00093
00105
00106
00107 void
00108 xsh_load_ref_table(cpl_frameset* frames,
00109 double dRA,
00110 double dDEC,
00111 double EPSILON,
00112 xsh_instrument* instrument,
00113 cpl_table** pptable)
00114 {
00115 const char* name = NULL;
00116 cpl_frame* frm_ref = NULL;
00117
00118
00119 check(frm_ref=xsh_find_frame_with_tag(frames,XSH_FLUX_STD_TAB,instrument));
00120 if (!frm_ref)
00121 {
00122 xsh_msg("REF frame is not found, trying to get REF from the catalog");
00123
00124
00125 check(frm_ref=xsh_find_frame_with_tag(frames,XSH_FLUX_STD_CAT,instrument));
00126 if (frm_ref)
00127 {
00128 check(name=cpl_frame_get_filename(frm_ref));
00129 if (name)
00130 {
00131 star_index* pstarindex = star_index_load(name);
00132 if (pstarindex)
00133 {
00134 const char* star_name = 0;
00135 xsh_msg("Searching std RA[%f] DEC[%f] with tolerance[%f] in star catalog", dRA, dDEC, EPSILON);
00136 *pptable = star_index_get(pstarindex, dRA, dDEC, EPSILON, EPSILON, &star_name);
00137 if (*pptable && star_name)
00138 {
00139 xsh_msg("Found STD star: %s", star_name);
00140 }
00141 else
00142 {
00143 xsh_msg("ERROR - REF star %s could not be found in the catalog",star_name);
00144 }
00145 }
00146 else
00147 {
00148 xsh_msg("ERROR - could not load the catalog");
00149 }
00150 }
00151 }
00152 }
00153 else
00154 {
00155 xsh_msg("REF frame is found");
00156 check(name=cpl_frame_get_filename(frm_ref));
00157 check(*pptable=cpl_table_load(name,1,0));
00158 }
00159 return;
00160 cleanup:
00161 return;
00162 }
00163
00164
00165
00166
00167
00178
00179
00180 cpl_error_code
00181 xsh_parse_catalog_std_stars(cpl_frame* cat,
00182 double dRA,
00183 double dDEC,
00184 double EPSILON,
00185 cpl_table** pptable)
00186 {
00187 const char* name = NULL;
00188 XSH_ASSURE_NOT_NULL_MSG(cat,"Provide input catalog");
00189 if (cat) {
00190 check(name=cpl_frame_get_filename(cat));
00191 if (name) {
00192 star_index* pstarindex = star_index_load(name);
00193 if (pstarindex) {
00194 const char* star_name = 0;
00195 xsh_msg("Searching std RA[%f] DEC[%f] with tolerance[%f] in star catalog", dRA, dDEC, EPSILON);
00196 *pptable = star_index_get(pstarindex, dRA, dDEC, EPSILON, EPSILON, &star_name);
00197 if (*pptable && star_name) {
00198 xsh_msg("Found STD star: %s", star_name);
00199 }
00200 else {
00201 xsh_msg("ERROR - REF star %s could not be found in the catalog",star_name);
00202 }
00203 }
00204 else {
00205 xsh_msg("ERROR - could not load the catalog");
00206 }
00207 star_index_delete(pstarindex);
00208 }
00209 }
00210
00211 cleanup:
00212 return cpl_error_get_code();
00213 }
00214
00215
00216
00217
00218
00219 static double*
00220 xsh_create_column_double(cpl_table* tbl, const char* col_name, int nrow)
00221 {
00222 double* retval = 0;
00223 check(cpl_table_new_column(tbl, col_name, CPL_TYPE_DOUBLE));
00224 check(cpl_table_fill_column_window_double(tbl, col_name, 0, nrow, -1));
00225 check(retval = cpl_table_get_data_double(tbl,col_name));
00226 return retval;
00227 cleanup:
00228 return retval;
00229 }
00230
00231
00232
00242
00243
00244 cpl_error_code
00245 xsh_get_std_obs_values(cpl_propertylist* plist,
00246 double* exptime,
00247 double* airmass,
00248 double* dRA,
00249 double* dDEC)
00250 {
00251
00252 *airmass=xsh_pfits_get_airm_mean(plist) ;
00253 *dDEC=xsh_pfits_get_dec(plist);
00254 *dRA=xsh_pfits_get_ra(plist);
00255 *exptime=xsh_pfits_get_exptime(plist);
00256
00257 return cpl_error_get_code();
00258
00259 }
00260
00261 cpl_error_code
00262 xsh_efficiency_add_high_abs_regions(cpl_table** eff,HIGH_ABS_REGION * phigh)
00263 {
00264 int nrow=cpl_table_get_nrow(*eff);
00265 double* pwav=NULL;
00266 int* phigh_abs=NULL;
00267 int k=0;
00268 int i=0;
00269 cpl_table_new_column(*eff,COL_NAME_HIGH_ABS,CPL_TYPE_INT);
00270 cpl_table_fill_column_window_int(*eff,COL_NAME_HIGH_ABS,0,nrow,0);
00271 pwav=cpl_table_get_data_double(*eff,COL_NAME_WAVELENGTH);
00272 phigh_abs=cpl_table_get_data_int(*eff,COL_NAME_HIGH_ABS);
00273 if ( phigh != NULL ) {
00274 for( k = 0 ; phigh->lambda_min != 0. ; k++, phigh++ ) {
00275 for(i=0;i<nrow;i++) {
00276 if(pwav[i]>=phigh->lambda_min && pwav[i]<=phigh->lambda_max) {
00277 phigh_abs[i]=1;
00278 }
00279 }
00280 }
00281 }
00282
00283 return cpl_error_get_code();
00284
00285 }
00286
00287
00305
00306
00307 cpl_frame*
00308 xsh_utils_efficiency(
00309 cpl_frameset * frames,
00310 double dGain,
00311 double dEpsilon,
00312 double aimprim,
00313 xsh_instrument* inst,
00314 const char* col_name_atm_wave,
00315 const char* col_name_atm_abs,
00316 const char* col_name_ref_wave,
00317 const char* col_name_ref_flux,
00318 const char* col_name_ref_bin,
00319 const char* col_name_obj_wave,
00320 const char* col_name_obj_flux
00321 )
00322 {
00323 cpl_frame* frm_sci = NULL;
00324 cpl_frame* frm_atmext = NULL;
00325 cpl_table* tbl_obj_spectrum = NULL;
00326 cpl_table* tbl_atmext = NULL;
00327 double exptime = 600;
00328
00329 cpl_propertylist* plist = NULL;
00330 cpl_table* tbl_ref = NULL;
00331 cpl_frame* result=NULL;
00332
00333 const char* name=NULL;
00334 double dRA = 0;
00335 double dDEC = 0;
00336 char prod_name[80];
00337 char prod_tag[80];
00338 double airmass=0;
00339 const double mk2AA=1E4;
00340 int nclip=0;
00341 int ntot=0;
00342 cpl_table* tbl_result = NULL;
00343
00344
00345
00346
00347
00348 check(frm_sci=xsh_find_frame_with_tag(frames,XSH_STD_FLUX_SLIT_STARE_ORDER1D, inst));
00349 check(name=cpl_frame_get_filename(frm_sci));
00350
00351 check(tbl_obj_spectrum=cpl_table_load(name,1,0));
00352 check(plist=cpl_propertylist_load(name,0));
00353
00354 xsh_get_std_obs_values(plist,&exptime,&airmass,&dRA,&dDEC);
00355
00356
00357 xsh_load_ref_table(frames, dRA, dDEC, dEpsilon, inst, &tbl_ref);
00358 if (tbl_ref)
00359 {
00360
00361 check(frm_atmext=cpl_frameset_find(frames,FRM_EXTCOEFF_TAB));
00362 check(name=cpl_frame_get_filename(frm_atmext));
00363 check(tbl_atmext=cpl_table_load(name,1,0));
00364
00365 tbl_result = xsh_utils_efficiency_internal(
00366 tbl_obj_spectrum,
00367 tbl_atmext,
00368 tbl_ref,
00369 exptime,
00370 airmass,
00371 aimprim,
00372 dGain,
00373 1,
00374 mk2AA,
00375 col_name_atm_wave,
00376 col_name_atm_abs,
00377 col_name_ref_wave,
00378 col_name_ref_flux,
00379 col_name_ref_bin,
00380 col_name_obj_wave,
00381 col_name_obj_flux,
00382 &ntot,&nclip);
00383 if (tbl_result)
00384 {
00385 HIGH_ABS_REGION * phigh=NULL;
00386 check(xsh_efficiency_add_high_abs_regions(&tbl_result,phigh));
00387 sprintf(prod_tag,"EFFICIENCY_%s",xsh_instrument_arm_tostring(inst));
00388 sprintf(prod_name,"%s.fits",prod_tag);
00389
00390 result=xsh_frame_product(prod_name,prod_tag,CPL_FRAME_TYPE_TABLE,
00391 CPL_FRAME_GROUP_CALIB,CPL_FRAME_LEVEL_FINAL);
00392 cpl_table_save(tbl_result, plist, NULL,prod_name, CPL_IO_DEFAULT);
00393
00394 xsh_free_table(&tbl_result);
00395 }
00396
00397 }
00398
00399 cleanup:
00400 xsh_free_propertylist(&plist);
00401 xsh_free_table(&tbl_atmext);
00402 xsh_free_table(&tbl_obj_spectrum);
00403 xsh_free_table(&tbl_ref);
00404 return result;
00405 }
00406
00407 static int
00408 xsh_column_to_double(cpl_table* ptable, const char* column)
00409 {
00410 const char* TEMP = "_temp_";
00411 check(cpl_table_duplicate_column(ptable, TEMP, ptable, column));
00412 check(cpl_table_erase_column(ptable, column));
00413 check(cpl_table_cast_column(ptable, TEMP, column, CPL_TYPE_DOUBLE));
00414 check(cpl_table_erase_column(ptable, TEMP ));
00415 return 0;
00416 cleanup:
00417 xsh_msg(" error column to double [%s]", column);
00418 return -1;
00419 }
00420
00421
00422
00444
00445
00446 cpl_table*
00447 xsh_utils_efficiency_internal(cpl_table* tbl_obj_spectrum,
00448 cpl_table* tbl_atmext,
00449 cpl_table* tbl_ref,
00450 double exptime,
00451 double airmass,
00452 double aimprim,
00453 double gain,
00454 int biny,
00455 double src2ref_wave_sampling,
00456 const char* col_name_atm_wave,
00457 const char* col_name_atm_abs,
00458 const char* col_name_ref_wave,
00459 const char* col_name_ref_flux,
00460 const char* col_name_ref_bin,
00461 const char* col_name_obj_wave,
00462 const char* col_name_obj_flux,
00463 int* ntot,
00464 int* nclip
00465 )
00466 {
00467
00468 const double TEL_AREA = 51.2e4;
00469 double cdelta1 = 0;
00470 int i = 0;
00471 cpl_table* tbl_sel = NULL;
00472
00473
00474
00475
00476
00477
00478 cpl_table* tbl_result = NULL;
00479
00480
00481
00482
00483
00484
00485
00486
00487 double* pref = NULL;
00488 double* pext = NULL;
00489 double* pcor = NULL;
00490 double* peph = NULL;
00491
00492 double* pw = NULL;
00493 int nrow = 0;
00494 double ref_bin_size=0;
00495 double um2nm=0.001;
00496 double eff_med=0.;
00497 double eff_rms=0.;
00498 double eff_thresh=0.;
00499
00500 double kappa=5;
00501 double nm2AA=10.;
00502 int nsel=0;
00503 double eff=0;
00504 nrow = cpl_table_get_nrow(tbl_obj_spectrum);
00505 xsh_msg_dbg_medium("Starting efficiency calculation: exptime[%f] airmass[%f] nrow[%d]",
00506 exptime, airmass, nrow);
00507
00508
00509
00510
00511
00512 xsh_column_to_double(tbl_obj_spectrum,col_name_obj_wave);
00513 xsh_column_to_double(tbl_obj_spectrum,col_name_obj_flux);
00514
00515 check(xsh_column_to_double(tbl_atmext,col_name_atm_wave ));
00516 check(xsh_column_to_double(tbl_atmext,col_name_atm_abs ));
00517 check(xsh_column_to_double(tbl_ref,col_name_ref_wave ));
00518 check(xsh_column_to_double(tbl_ref,col_name_ref_flux ));
00519 check(xsh_column_to_double(tbl_ref,col_name_ref_bin ));
00520
00521
00522
00523
00524
00525
00526
00527 ref_bin_size=cpl_table_get_double(tbl_ref,col_name_ref_bin,0,NULL);
00528 xsh_msg_dbg_medium("ref_bin_size[nm]=%g",ref_bin_size);
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 check(cpl_table_multiply_scalar(tbl_obj_spectrum,col_name_obj_wave,
00542 src2ref_wave_sampling));
00543
00544
00545
00546
00547
00548
00549
00550
00551 xsh_msg_dbg_medium("object 2 src std wave factor %g",src2ref_wave_sampling);
00552 check(pw=cpl_table_get_data_double(tbl_obj_spectrum,col_name_obj_wave));
00553
00554
00555 check(tbl_result=cpl_table_new(nrow));
00556 check(pref=xsh_create_column_double(tbl_result, COL_NAME_REF, nrow));
00557 check(pext=xsh_create_column_double(tbl_result, COL_NAME_EXT, nrow));
00558 check(pcor=xsh_create_column_double(tbl_result, COL_NAME_COR, nrow));
00559 check(peph=xsh_create_column_double(tbl_result, COL_NAME_EPHOT, nrow));
00560 xsh_msg_dbg_medium("wave range: [%g,%g] nm",pw[0],pw[nrow-1]);
00561 xsh_msg_dbg_medium("src_bin_size[nm]=%g",pw[1] - pw[0]);
00562
00563 cdelta1 = (pw[1] - pw[0]) / src2ref_wave_sampling ;
00564 xsh_msg_dbg_medium("nrow=%d cdelta1=%g",nrow,cdelta1);
00565 for (i = 0; i < nrow; i++)
00566 {
00567 check(pext[i] = xsh_table_interpolate(tbl_atmext, pw[i],col_name_atm_wave, col_name_atm_abs));
00568 check(pref[i] = xsh_table_interpolate(tbl_ref, pw[i], col_name_ref_wave,col_name_ref_flux));
00569 pcor[i] = pow(10,(0.4*pext[i] * (aimprim - airmass)));
00570 eff = 1.e7*1.986e-19/(pw[i]*um2nm);
00571 if(!isnan(eff)) {
00572 peph[i]=eff;
00573 } else {
00574
00575
00576
00577
00578 cpl_table_set_invalid(tbl_result,COL_NAME_EPHOT,i);
00579 }
00580
00581
00582
00583
00584
00585
00586
00587
00588 }
00589 cpl_table_erase_invalid(tbl_result);
00590
00591
00592
00593
00594
00595
00596
00597
00598 check(cpl_table_duplicate_column(tbl_result,"ORDER",
00599 tbl_obj_spectrum,COL_NAME_ORD_OBJ ));
00600 check(cpl_table_duplicate_column(tbl_result,COL_NAME_SRC_COR,
00601 tbl_obj_spectrum, col_name_obj_flux));
00602 check(cpl_table_duplicate_column(tbl_result,col_name_obj_wave,
00603 tbl_obj_spectrum,col_name_obj_wave));
00604
00605
00606
00607 check(cpl_table_multiply_columns(tbl_result,COL_NAME_SRC_COR,COL_NAME_COR));
00608
00609
00610
00611
00612
00613
00614 cpl_table_divide_scalar(tbl_result, COL_NAME_SRC_COR, src2ref_wave_sampling);
00615 cpl_table_divide_scalar(tbl_result, COL_NAME_SRC_COR, cdelta1);
00616 cpl_table_divide_scalar(tbl_result, COL_NAME_SRC_COR, nm2AA);
00617
00618 cpl_table_divide_scalar(tbl_result,COL_NAME_SRC_COR,biny);
00619
00620
00621
00622
00623 check(cpl_table_divide_scalar(tbl_result,COL_NAME_REF,ref_bin_size));
00624
00625
00626
00627 check(cpl_table_duplicate_column(tbl_result,COL_NAME_SRC_EFF,
00628 tbl_result,COL_NAME_SRC_COR));
00629
00630
00631
00632
00633 check(cpl_table_multiply_scalar(tbl_result,COL_NAME_SRC_EFF,
00634 gain / (exptime * TEL_AREA)));
00635
00636
00637 check(cpl_table_multiply_columns(tbl_result,COL_NAME_SRC_EFF,
00638 COL_NAME_EPHOT));
00639
00640
00641
00642
00643
00644 check(cpl_table_divide_columns(tbl_result,COL_NAME_SRC_EFF,COL_NAME_REF));
00645
00646
00647
00648
00649
00650 eff_med=cpl_table_get_column_median(tbl_result,COL_NAME_SRC_EFF);
00651 eff_rms=cpl_table_get_column_stdev(tbl_result,COL_NAME_SRC_EFF);
00652
00653 eff_thresh=(eff_med+kappa*eff_rms<10.) ? eff_med+kappa*eff_rms:10.;
00654 if(irplib_isinf(eff_thresh)) eff_thresh=10.;
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664 *ntot=cpl_table_get_nrow(tbl_result);
00665 cpl_table_and_selected_double(tbl_result,COL_NAME_SRC_EFF,
00666 CPL_GREATER_THAN,1.e-5);
00667
00668 cpl_table_and_selected_double(tbl_result,COL_NAME_SRC_EFF,
00669 CPL_LESS_THAN,eff_thresh);
00670
00671 eff_med=cpl_table_get_column_median(tbl_result,COL_NAME_SRC_EFF);
00672 eff_rms=cpl_table_get_column_stdev(tbl_result,COL_NAME_SRC_EFF);
00673
00674 eff_thresh=(eff_med+kappa*eff_rms<10.) ? eff_med+kappa*eff_rms:10.;
00675 if(irplib_isinf(eff_thresh)) eff_thresh=10.;
00676
00677
00678
00679
00680 cpl_table_and_selected_double(tbl_result,COL_NAME_SRC_EFF,
00681 CPL_LESS_THAN,eff_thresh);
00682
00683 nsel=cpl_table_and_selected_double(tbl_result,COL_NAME_SRC_EFF,
00684 CPL_LESS_THAN,1);
00685
00686 *nclip=(*ntot)-nsel;
00687 tbl_sel=cpl_table_extract_selected(tbl_result);
00688
00689
00690 cleanup:
00691 xsh_free_table(&tbl_result);
00692 return tbl_sel;
00693 }
00694
00703 void
00704 xsh_frame_sci_get_ra_dec_airmass(cpl_frame* frm_sci,
00705 double* ra,
00706 double* dec,
00707 double* airmass)
00708 {
00709
00710 const char* name_sci=NULL;
00711 cpl_propertylist* plist=NULL;
00712
00713 name_sci=cpl_frame_get_filename(frm_sci);
00714 check(plist=cpl_propertylist_load(name_sci,0));
00715 *ra=xsh_pfits_get_ra(plist);
00716 *dec=xsh_pfits_get_dec(plist);
00717 *airmass=xsh_pfits_get_airm_mean(plist);
00718
00719 cleanup:
00720
00721 xsh_free_propertylist(&plist);
00722 return;
00723 }
00724
00725
00726
00727 static void
00728 xsh_frame_sci_get_gain_airmass_exptime_naxis1_biny(cpl_frame* frm_sci,
00729 xsh_instrument* instrument,
00730 double* gain,
00731 double* airmass,
00732 double* exptime,
00733 int* naxis1,
00734 int* biny)
00735 {
00736
00737 const char* name_sci=NULL;
00738 cpl_propertylist* plist=NULL;
00739
00740 name_sci=cpl_frame_get_filename(frm_sci);
00741 check(plist=cpl_propertylist_load(name_sci,0));
00742 check(*naxis1=xsh_pfits_get_naxis1(plist));
00743 *airmass=xsh_pfits_get_airm_mean(plist);
00744
00745 if( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
00746 *gain=2.12;
00747 *biny=1;
00748 check(*exptime=xsh_pfits_get_dit(plist));
00749 } else {
00750 check(*gain=xsh_pfits_get_conad(plist));
00751 check(*biny=xsh_pfits_get_biny(plist));
00752 check(*exptime=xsh_pfits_get_win1_dit1(plist));
00753 }
00754
00755 cleanup:
00756 xsh_free_propertylist(&plist);
00757
00758 return;
00759 }
00760
00766 cpl_frame*
00767 xsh_catalog_extract_spectrum_frame(cpl_frame* frm_cat,
00768 cpl_frame* frm_sci)
00769 {
00770 cpl_frame* result=NULL;
00771 double dRA=0;
00772 double dDEC=0;
00773
00774 double nm2nm=1.;
00775 cpl_table* tbl_ref=NULL;
00776 char fname[80];
00777 char ftag[80];
00778 double airmass=0;
00779
00780 XSH_ASSURE_NOT_NULL_MSG(frm_sci,"Null input sci frame set!Exit");
00781 XSH_ASSURE_NOT_NULL_MSG(frm_cat,"Null input std star cat frame set!Exit");
00782 xsh_frame_sci_get_ra_dec_airmass(frm_sci,&dRA,&dDEC,&airmass);
00783 check(xsh_parse_catalog_std_stars(frm_cat,dRA,dDEC,STAR_MATCH_DEPSILON,&tbl_ref));
00784
00785
00786 cpl_table_divide_scalar(tbl_ref,COL_NAME_WAVE_REF,nm2nm);
00787 cpl_table_multiply_scalar(tbl_ref,COL_NAME_FLUX_REF,nm2nm);
00788 check(cpl_table_divide_columns(tbl_ref,COL_NAME_FLUX_REF,COL_NAME_BINWIDTH_REF));
00789
00790 sprintf(fname,"ref_std_star_spectrum.fits");
00791 sprintf(ftag,"STD_STAR_FLUX");
00792
00793 check(cpl_table_save(tbl_ref,NULL,NULL,fname,CPL_IO_DEFAULT));
00794 result=xsh_frame_product(fname,ftag,CPL_FRAME_TYPE_TABLE,
00795 CPL_FRAME_GROUP_CALIB,CPL_FRAME_LEVEL_INTERMEDIATE);
00796 cleanup:
00797 return result;
00798 }
00799
00807 cpl_frame*
00808 xsh_efficiency_compute(cpl_frame* frm_sci,
00809 cpl_frame* frm_cat,
00810 cpl_frame* frm_atmext,
00811 cpl_frame* high_abs_win,
00812 xsh_instrument* instrument)
00813
00814 {
00815
00816 cpl_image* ima_sci=NULL;
00817 cpl_image* ima_ord=NULL;
00818 cpl_image* ima_obj=NULL;
00819 cpl_table* obj_tab=NULL;
00820
00821 const char* name_sci=NULL;
00822 const char* name_atm=NULL;
00823 cpl_propertylist* plist=NULL;
00824 cpl_propertylist* x_plist=NULL;
00825
00826
00827 cpl_table* tbl_ord=NULL;
00828 cpl_table* tot_eff=NULL;
00829 cpl_table* tbl_eff=NULL;
00830 cpl_table* tbl_ref=NULL;
00831 cpl_table* tbl_atmext=NULL;
00832
00833 double * pobj=NULL;
00834 double * pw=NULL;
00835 double * pf=NULL;
00836 int * po=NULL;
00837
00838 cpl_frame* frm_eff=NULL;
00839
00840 char name_eff[80];
00841
00842 double crval1=0;
00843 double cdelt1=0;
00844 int naxis1=0;
00845 int nrow=0;
00846
00847
00848 double exptime=600;
00849 cpl_vector* rec_profile=NULL;
00850 int i=0;
00851 double airmass=0;
00852 double dRA=0;
00853 double dDEC=0;
00854 char key_name[40];
00855 int next=0;
00856 int nord=0;
00857
00858
00859
00860 int j=0;
00861 double wav=0;
00862 double gain=0;
00863 int biny=1;
00864 double aimprim=0;
00865 int ord=0;
00866
00867 double nm2nm=1.;
00868
00869 char fname[80];
00870 char tag[80];
00871 double emax=0;
00872 double emed=0;
00873 int nclip=0;
00874 int ntot=0;
00875
00876 int nclip_tot=0;
00877 int neff_tot=0;
00878 double fclip=0;
00879
00880 XSH_ASSURE_NOT_NULL_MSG(frm_sci,"Null input sci frame set!Exit");
00881 XSH_ASSURE_NOT_NULL_MSG(frm_cat,"Null input std star cat frame set!Exit");
00882 XSH_ASSURE_NOT_NULL_MSG(frm_atmext,"Null input atmospheric ext frame set!Exit");
00883
00884 check(next = cpl_frame_get_nextensions(frm_sci));
00885
00886 nord=(next+1)/3;
00887
00888 xsh_frame_sci_get_ra_dec_airmass(frm_sci,&dRA,&dDEC,&airmass);
00889 name_sci=cpl_frame_get_filename(frm_sci);
00890 plist=cpl_propertylist_load(name_sci,0);
00891 xsh_frame_sci_get_gain_airmass_exptime_naxis1_biny(frm_sci,instrument,
00892 &gain,&airmass,&exptime,
00893 &naxis1,&biny);
00894
00895 check(xsh_parse_catalog_std_stars(frm_cat,dRA,dDEC,STAR_MATCH_DEPSILON,
00896 &tbl_ref));
00897
00898
00899 xsh_msg_dbg_medium("gain=%g airm=%g exptime=%g airmass=%g ra=%g dec=%g",
00900 gain,airmass,exptime,airmass,dRA,dDEC);
00901
00902 xsh_msg_dbg_medium("name_sci=%s",name_sci);
00903 nrow=naxis1*nord;
00904
00905
00906
00907
00908 obj_tab=cpl_table_new(nrow);
00909
00910 cpl_table_new_column(obj_tab,COL_NAME_ORD_OBJ,CPL_TYPE_INT);
00911 cpl_table_new_column(obj_tab,COL_NAME_WAVE_OBJ,CPL_TYPE_DOUBLE);
00912 cpl_table_new_column(obj_tab,COL_NAME_INT_OBJ,CPL_TYPE_DOUBLE);
00913
00914 check(cpl_table_fill_column_window_int(obj_tab,COL_NAME_ORD_OBJ,0,nrow,-1));
00915 check(cpl_table_fill_column_window_double(obj_tab,COL_NAME_WAVE_OBJ,0,nrow,-1));
00916 check(cpl_table_fill_column_window_double(obj_tab,COL_NAME_INT_OBJ,0,nrow,-1));
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927 check(name_atm=cpl_frame_get_filename(frm_atmext));
00928 xsh_msg_dbg_medium("name_atm=%s",name_atm);
00929 check(tbl_atmext=cpl_table_load(name_atm,1,0));
00930
00931 if(!cpl_table_has_column(tbl_atmext,XSH_ATMOS_EXT_LIST_COLNAME_K)){
00932 xsh_msg_warning("You are using an obsolete atm extinction line table");
00933 cpl_table_duplicate_column(tbl_atmext,XSH_ATMOS_EXT_LIST_COLNAME_K,
00934 tbl_atmext,XSH_ATMOS_EXT_LIST_COLNAME_OLD);
00935 }
00936
00937 if(tbl_ref == NULL) {
00938 xsh_msg_error("Provide std sar catalog frame");
00939 return NULL;
00940
00941 }
00942
00943 for(i=0;i<next;i+=3) {
00944
00945
00946
00947 xsh_free_image(&ima_ord);
00948 pobj=NULL;
00949 xsh_free_propertylist(&x_plist);
00950 check(ima_ord=cpl_image_load(name_sci,CPL_TYPE_DOUBLE,0,i));
00951 check(x_plist=cpl_propertylist_load(name_sci,i));
00952
00953 check(pobj=cpl_image_get_data_double(ima_ord));
00954 check(crval1=xsh_pfits_get_crval1(x_plist));
00955 check(cdelt1=xsh_pfits_get_cdelt1(x_plist));
00956 xsh_free_table(&tbl_ord);
00957 tbl_ord=cpl_table_new(naxis1);
00958 check(cpl_table_copy_structure(tbl_ord,obj_tab));
00959 check(cpl_table_fill_column_window_int(tbl_ord,COL_NAME_ORD_OBJ,0,naxis1,-1));
00960 check(cpl_table_fill_column_window_double(tbl_ord,COL_NAME_WAVE_OBJ,0,naxis1,-1));
00961 check(cpl_table_fill_column_window_double(tbl_ord,COL_NAME_INT_OBJ,0,naxis1,-1));
00962
00963 check(po=cpl_table_get_data_int(tbl_ord,COL_NAME_ORD_OBJ));
00964 check(pw=cpl_table_get_data_double(tbl_ord,COL_NAME_WAVE_OBJ));
00965 check(pf=cpl_table_get_data_double(tbl_ord,COL_NAME_INT_OBJ));
00966
00967
00968
00969 ord=i/3;
00970 for(j=0;j<naxis1;j++) {
00971 po[j]=ord;
00972 wav=crval1+cdelt1*j;
00973 pw[j]=wav;
00974 pf[j]=pobj[j];
00975
00976 }
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987 xsh_free_table(&tbl_eff);
00988 check(tbl_eff=xsh_utils_efficiency_internal(tbl_ord,tbl_atmext,tbl_ref,
00989 exptime,airmass,aimprim,gain,
00990 biny,nm2nm,
00991 COL_NAME_WAVE_ATMDISP,
00992 COL_NAME_ABS_ATMDISP,
00993 COL_NAME_WAVE_REF,
00994 COL_NAME_FLUX_REF,
00995 COL_NAME_BINWIDTH_REF,
00996 COL_NAME_WAVE_OBJ,
00997 COL_NAME_INT_OBJ,
00998 &ntot,&nclip));
00999 xsh_free_table(&tbl_ord);
01000
01001 nrow=cpl_table_get_nrow(tbl_eff);
01002 if(nrow>0) {
01003 check(emax=cpl_table_get_column_max(tbl_eff,"EFF"));
01004 } else {
01005 emax=-999;
01006 }
01007 sprintf(key_name,"%s%2d", XSH_QC_EFF_PEAK_ORD,ord);
01008 cpl_propertylist_append_double(plist,key_name,emax);
01009 cpl_propertylist_set_comment(plist,key_name,"Peak efficiency");
01010 if(nrow>0) {
01011 check(emed=cpl_table_get_column_median(tbl_eff,"EFF"));
01012 } else {
01013 emed=-999;
01014 }
01015 sprintf(key_name,"%s%2d", XSH_QC_EFF_MED_ORD,ord);
01016 cpl_propertylist_append_double(plist,key_name,emed);
01017 cpl_propertylist_set_comment(plist,key_name,"Median efficiency");
01018
01019
01020 if(ord==0) {
01021 tot_eff=cpl_table_duplicate(tbl_eff);
01022 } else {
01023 cpl_table_insert(tot_eff,tbl_eff,naxis1*i);
01024 }
01025 neff_tot+=ntot;
01026 if(!isnan(nclip)) {
01027 nclip_tot+=nclip;
01028 }
01029 sprintf(name_eff,"eff_ord%d.fits",ord);
01030
01031 }
01032 xsh_msg("nclip_tot=%d",nclip_tot);
01033 HIGH_ABS_REGION * phigh=NULL;
01034 phigh=xsh_fill_high_abs_regions(instrument,high_abs_win);
01035 check(xsh_efficiency_add_high_abs_regions(&tot_eff,phigh));
01036 sprintf(tag,"EFFICIENCY_%s_%s",xsh_instrument_mode_tostring(instrument),
01037 xsh_instrument_arm_tostring(instrument));
01038 sprintf(fname,"%s.fits",tag);
01039 nrow=cpl_table_get_nrow(tot_eff);
01040 fclip=nclip_tot;
01041 if(neff_tot > 0) {
01042 fclip/=neff_tot;
01043 } else {
01044 fclip=-999;
01045 }
01046 xsh_msg("nclip_tot =%d neff_tot=%d fclip=%g",nclip_tot,neff_tot,fclip);
01047 xsh_pfits_set_qc_eff_fclip(plist,fclip);
01048 xsh_pfits_set_qc_eff_nclip(plist,nclip_tot);
01049
01050 check(cpl_table_save(tot_eff,plist, x_plist,fname, CPL_IO_DEFAULT));
01051 xsh_free_table(&obj_tab);
01052 check(frm_eff=xsh_frame_product(fname,tag,CPL_FRAME_TYPE_TABLE,
01053 CPL_FRAME_GROUP_CALIB,
01054 CPL_FRAME_LEVEL_FINAL));
01055
01056 cleanup:
01057
01058 xsh_free_table(&tot_eff);
01059 xsh_free_table(&tbl_ref);
01060 xsh_free_table(&tbl_atmext);
01061 xsh_free_table(&obj_tab);
01062 xsh_free_table(&tbl_ord);
01063 xsh_free_table(&tbl_eff);
01064
01065 xsh_free_image(&ima_sci);
01066 xsh_free_vector(&rec_profile);
01067 xsh_free_image(&ima_ord);
01068 xsh_free_image(&ima_obj);
01069 xsh_free_propertylist(&plist);
01070 xsh_free_propertylist(&x_plist);
01071
01072 return frm_eff;
01073
01074 }
01075
01076
01077
01078 static double slaAirmas ( double zd )
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125 {
01126 double w, seczm1;
01127
01128 w = fabs ( zd );
01129
01130
01131
01132
01133
01134
01135
01136 w = (1.52 > w) ? w : 1.52;
01137 seczm1 = 1.0 / ( cos ( w ) ) - 1.0;
01138 return 1.0 + seczm1 * ( 0.9981833
01139 - seczm1 * ( 0.002875 + 0.0008083 * seczm1 ) );
01140 }
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158 void slaAoppat ( double date, double aoprms[14] )
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190 {
01191
01192
01193
01194 }
01195
01196 static double
01197 xsh_utils_get_airm(cpl_propertylist* plist)
01198 {
01199
01200 double airmass=0;
01201
01202 double azimuth=0;
01203
01204 double altitude=0;
01205
01206 double declination=0;
01207 double RA=0;
01208
01209 double hour_angle=0;
01210
01211
01212 const char* telescope_id=NULL;
01213 int tel_id=0;
01214 double latitude=0;
01215 double lat_sig=-1;
01216 double lat_deg=24;
01217 double lat_min=37;
01218 double lat_sec=30;
01219 int len=0;
01220 double exptime_sec=0;
01221 double exptime_hms=0;
01222 double exptime_deg=0;
01223 double LST=0;
01224
01225 declination=xsh_pfits_get_dec(plist);
01226 RA=xsh_pfits_get_ra(plist);
01227 LST=xsh_pfits_get_lst(plist);
01228 hour_angle=LST-RA;
01229
01230
01231
01232
01233
01234
01235
01236
01237 telescope_id=xsh_pfits_get_telescop(plist);
01238 exptime_sec=xsh_pfits_get_exptime(plist);
01239 exptime_hms=exptime_sec/3600;
01240
01241
01242 exptime_deg=xsh_hms2deg(exptime_hms);
01243 xsh_msg("exptime=%g [deg]",exptime_deg);
01244
01245
01246
01247
01248 len=strlen(telescope_id);
01249
01250 tel_id=telescope_id[len-1]-48;
01251
01252
01253
01254 switch ( tel_id ) {
01255 case 1: lat_sec=33.117;
01256 break;
01257 case 2: lat_sec=31.465;
01258 break;
01259 case 3: lat_sec=30.300;
01260 break;
01261 case 4: lat_sec=31.000;
01262 break;
01263 }
01264
01265
01266 latitude=lat_sig*(lat_deg+lat_min/60+lat_sec/3600);
01267
01268
01269 double c1=0;
01270 double c2=0;
01271 double c3=0;
01272
01273 c1=sin(latitude)*sin(declination)+cos(latitude)*cos(declination)*cos(hour_angle);
01274 c2=cos(latitude)*sin(declination)-sin(latitude)*cos(declination)*cos(hour_angle);
01275 c3=-cos(latitude)*sin(hour_angle);
01276
01277 azimuth=atan(c3/c2);
01278 altitude=atan(c1/c2*cos(azimuth));
01279
01280 xsh_msg("altitude=%g",altitude);
01281
01282
01283
01284
01285
01286 airmass=1/sin(altitude+244/(165+47*pow(altitude,1.1)));
01287
01288
01289 return airmass;
01290
01291
01292 }
01293
01294
01295 double
01296 xsh_utils_compute_airm_eff(cpl_frameset* raws)
01297 {
01298
01299 int i=0;
01300 int size=0;
01301 cpl_frame* frm=NULL;
01302 cpl_propertylist* plist=NULL;
01303 const char* name=NULL;
01304 double airm_start=0;
01305 double airm_end=0;
01306 double airm_med=0;
01307 double airm_eff=0;
01308
01309 double exptime=0;
01310 double area=0;
01311 double sum_area=0;
01312 double sum_time=0;
01313
01314 XSH_ASSURE_NOT_NULL_MSG(raws,"raws frameset null pointer");
01315
01316 size=cpl_frameset_get_size(raws);
01317 for(i=0;i<size;i++){
01318
01319 frm=cpl_frameset_get_frame(raws,i);
01320 name=cpl_frame_get_filename(frm);
01321 plist=cpl_propertylist_load(name,0);
01322
01323 airm_med=xsh_utils_get_airm(plist);
01324 airm_start=xsh_pfits_get_airm_start(plist);
01325 airm_end=xsh_pfits_get_airm_end(plist);
01326 exptime=xsh_pfits_get_exptime(plist);
01327
01328 area=(exptime/6)*(airm_start+4*airm_med+airm_end);
01329
01330
01331
01332 sum_area+=area;
01333 sum_time+=exptime;
01334 xsh_free_propertylist(&plist);
01335
01336 }
01337
01338 airm_eff=sum_area/sum_time;
01339
01340 cleanup:
01341 xsh_free_propertylist(&plist);
01342 xsh_msg("airmass eff=%g",airm_eff);
01343
01344 return airm_eff;
01345
01346 }
01347
01348 double
01349 xsh_utils_compute_airm(cpl_frameset* raws)
01350 {
01351
01352 cpl_frame* frm=NULL;
01353 cpl_propertylist* plist=NULL;
01354 const char* name=NULL;
01355 int i=0;
01356 int size=0;
01357 double airm=0;
01358 double airm_eff=0;
01359 double exptime=0;
01360 double time_tot=0;
01361 double* pairm=NULL;
01362 double* pprod=NULL;
01363 double* ptime=NULL;
01364
01365 cpl_array* time_array=NULL;
01366 cpl_array* airm_array=NULL;
01367 cpl_array* prod_array=NULL;
01368
01369 XSH_ASSURE_NOT_NULL_MSG(raws,"raws frameset null pointer");
01370
01371 size=cpl_frameset_get_size(raws);
01372 airm_array=cpl_array_new(size,CPL_TYPE_DOUBLE);
01373 time_array=cpl_array_new(size,CPL_TYPE_DOUBLE);
01374 prod_array=cpl_array_new(size,CPL_TYPE_DOUBLE);
01375 pairm=cpl_array_get_data_double(airm_array);
01376 ptime=cpl_array_get_data_double(time_array);
01377 pprod=cpl_array_get_data_double(time_array);
01378
01379 if(size>2) {
01380 for(i=0;i<size;i++){
01381
01382 frm=cpl_frameset_get_frame(raws,i);
01383 name=cpl_frame_get_filename(frm);
01384 plist=cpl_propertylist_load(name,0);
01385 airm=xsh_pfits_get_airm_mean(plist);
01386 exptime=xsh_pfits_get_exptime(plist);
01387 ptime[i]=exptime;
01388 pairm[i]=airm;
01389 pprod[i]=airm*exptime;
01390
01391 }
01392 airm_eff=(pprod[0]+pprod[size-1])/(ptime[0]+ptime[size-1]);
01393
01394 } else if (size == 2) {
01395 frm=cpl_frameset_get_frame(raws,0);
01396 name=cpl_frame_get_filename(frm);
01397 plist=cpl_propertylist_load(name,0);
01398
01399 airm=xsh_pfits_get_airm_mean(plist);
01400 exptime=xsh_pfits_get_exptime(plist);
01401
01402 airm_eff=airm*exptime;
01403 time_tot=exptime;
01404
01405 frm=cpl_frameset_get_frame(raws,1);
01406 name=cpl_frame_get_filename(frm);
01407 plist=cpl_propertylist_load(name,0);
01408
01409
01410 airm_eff+=airm*exptime;
01411 time_tot+=exptime;
01412
01413 airm_eff/=time_tot;
01414 } else {
01415
01416 frm=cpl_frameset_get_frame(raws,0);
01417 name=cpl_frame_get_filename(frm);
01418 plist=cpl_propertylist_load(name,0);
01419
01420 airm=xsh_pfits_get_airm_mean(plist);
01421 exptime=xsh_pfits_get_exptime(plist);
01422
01423 airm_eff=airm;
01424 }
01425
01426 cleanup:
01427 return airm_eff;
01428
01429 }
01430
01431