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 = NULL;
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
00138 if (*pptable && star_name)
00139 {
00140 xsh_msg("Found STD star: %s", star_name);
00141 }
00142 else
00143 {
00144 xsh_msg("ERROR - REF star %s could not be found in the catalog",star_name);
00145 }
00146 }
00147 else
00148 {
00149 xsh_msg("ERROR - could not load the catalog");
00150 }
00151 }
00152 }
00153 }
00154 else
00155 {
00156 xsh_msg("REF frame is found");
00157 check(name=cpl_frame_get_filename(frm_ref));
00158 check(*pptable=cpl_table_load(name,1,0));
00159 }
00160 return;
00161 cleanup:
00162 return;
00163 }
00164
00165
00166 cpl_error_code
00167 xsh_rv_ref_wave_init(xsh_std_star_id std_star_id ,XSH_ARM arm, xsh_rv_ref_wave_param* w){
00168
00169 switch (arm) {
00170
00171 case XSH_ARM_UVB:
00172 w->wguess = 486.1322;
00173 w->range_wmin=450;
00174 w->range_wmax=550;
00175 w->ipol_wmin_max=470;
00176 w->ipol_wmax_min=500;
00177 w->ipol_hbox=0.5;
00178
00179 break;
00180 case XSH_ARM_VIS:
00181 w->wguess= 656.2793;
00182 w->range_wmin=640;
00183 w->range_wmax=670;
00184 w->ipol_wmin_max=653;
00185 w->ipol_wmax_min=661;
00186 w->ipol_hbox=1.5;
00187
00188 break;
00189 case XSH_ARM_NIR:
00190 w->wguess= 1094.12;
00191 w->range_wmin=1000;
00192 w->range_wmax=1200;
00193 w->ipol_wmin_max=1090;
00194 w->ipol_wmax_min=1100;
00195 w->ipol_hbox=1.5;
00196
00197 break;
00198 case XSH_ARM_UNDEFINED:
00199
00200 w->wguess= 999;
00201 w->range_wmin=999;
00202 w->range_wmax=999;
00203 w->ipol_wmin_max=999;
00204 w->ipol_wmax_min=999;
00205 w->ipol_hbox=1.5;
00206 break;
00207 }
00208
00209 return cpl_error_get_code();
00210 }
00211
00212 xsh_rv_ref_wave_param * xsh_rv_ref_wave_param_create(void){
00213
00214 xsh_rv_ref_wave_param * self = cpl_malloc(sizeof(xsh_rv_ref_wave_param));
00215 self->wguess=999.;
00216 self->range_wmin=999.;
00217 self->range_wmax=999.;
00218 self->ipol_wmin_max=999.;
00219 self->ipol_wmax_min=999.;
00220
00221 return self;
00222 }
00223
00224 void xsh_rv_ref_wave_param_destroy(xsh_rv_ref_wave_param * p){
00225
00226 cpl_free(p); p=NULL;
00227
00228 return ;
00229 }
00230
00231
00242
00243
00244 cpl_error_code xsh_parse_catalog_std_stars(cpl_frame* cat, double dRA,
00245 double dDEC, double EPSILON, cpl_table** pptable,xsh_std_star_id* std_star_id) {
00246 const char* name = NULL;
00247 XSH_ASSURE_NOT_NULL_MSG(cat, "Provide input catalog");
00248 if (cat) {
00249 check(name=cpl_frame_get_filename(cat));
00250 if (name) {
00251 star_index* pstarindex = star_index_load(name);
00252 if (pstarindex) {
00253 const char* star_name = NULL;
00254 xsh_msg(
00255 "Searching std RA[%f] DEC[%f] with tolerance[%f] in star catalog", dRA, dDEC, EPSILON);
00256 *pptable = star_index_get(pstarindex, dRA, dDEC, EPSILON, EPSILON,
00257 &star_name);
00258 if(star_name != NULL) {
00259 if ( strcmp(star_name,"GD71") == 0 ) *std_star_id = XSH_GD71;
00260 else if ( strcmp(star_name,"Feige110") == 0 ) *std_star_id = XSH_Feige110;
00261 else if ( strcmp(star_name,"GD153") == 0 ) *std_star_id = XSH_GD153;
00262 else if ( strcmp(star_name,"LTT3218") == 0 ) *std_star_id = XSH_LTT3218;
00263 else if ( strcmp(star_name,"LTT7987") == 0 ) *std_star_id = XSH_LTT7987;
00264 else if ( strcmp(star_name,"BD17") == 0 ) *std_star_id = XSH_BD17;
00265 else if ( strcmp(star_name,"EG274") == 0 ) *std_star_id = XSH_EG274;
00266 }
00267 xsh_msg("star index=%d",*std_star_id);
00268 if (*pptable && star_name != NULL) {
00269 xsh_msg("Found STD star: %s", star_name);
00270
00271 } else {
00272 xsh_msg(
00273 "ERROR - REF star %s could not be found in the catalog", star_name);
00274 }
00275 } else {
00276 xsh_msg("ERROR - could not load the catalog");
00277 }
00278 star_index_delete(pstarindex);
00279 }
00280 }
00281 cleanup: return cpl_error_get_code();
00282 }
00283
00284
00285
00286
00287
00288 static double*
00289 xsh_create_column_double(cpl_table* tbl, const char* col_name, int nrow)
00290 {
00291 double* retval = 0;
00292 check(cpl_table_new_column(tbl, col_name, CPL_TYPE_DOUBLE));
00293 check(cpl_table_fill_column_window_double(tbl, col_name, 0, nrow, -1));
00294 check(retval = cpl_table_get_data_double(tbl,col_name));
00295 return retval;
00296 cleanup:
00297 return retval;
00298 }
00299
00300
00301
00311
00312
00313 cpl_error_code
00314 xsh_get_std_obs_values(cpl_propertylist* plist,
00315 double* exptime,
00316 double* airmass,
00317 double* dRA,
00318 double* dDEC)
00319 {
00320
00321 *airmass=xsh_pfits_get_airm_mean(plist) ;
00322 *dDEC=xsh_pfits_get_dec(plist);
00323 *dRA=xsh_pfits_get_ra(plist);
00324 *exptime=xsh_pfits_get_exptime(plist);
00325
00326 return cpl_error_get_code();
00327
00328 }
00329
00330 cpl_error_code
00331 xsh_efficiency_add_high_abs_regions(cpl_table** eff,HIGH_ABS_REGION * phigh)
00332 {
00333 int nrow=cpl_table_get_nrow(*eff);
00334 double* pwav=NULL;
00335 int* phigh_abs=NULL;
00336 int k=0;
00337 int i=0;
00338 cpl_table_new_column(*eff,COL_NAME_HIGH_ABS,CPL_TYPE_INT);
00339 cpl_table_fill_column_window_int(*eff,COL_NAME_HIGH_ABS,0,nrow,0);
00340 pwav=cpl_table_get_data_double(*eff,COL_NAME_WAVELENGTH);
00341 phigh_abs=cpl_table_get_data_int(*eff,COL_NAME_HIGH_ABS);
00342 if ( phigh != NULL ) {
00343 for( k = 0 ; phigh->lambda_min != 0. ; k++, phigh++ ) {
00344 for(i=0;i<nrow;i++) {
00345 if(pwav[i]>=phigh->lambda_min && pwav[i]<=phigh->lambda_max) {
00346 phigh_abs[i]=1;
00347 }
00348 }
00349 }
00350 }
00351
00352 return cpl_error_get_code();
00353
00354 }
00355
00356
00374
00375
00376 cpl_frame*
00377 xsh_utils_efficiency(
00378 cpl_frameset * frames,
00379 double dGain,
00380 double dEpsilon,
00381 double aimprim,
00382 xsh_instrument* inst,
00383 const char* col_name_atm_wave,
00384 const char* col_name_atm_abs,
00385 const char* col_name_ref_wave,
00386 const char* col_name_ref_flux,
00387 const char* col_name_ref_bin,
00388 const char* col_name_obj_wave,
00389 const char* col_name_obj_flux
00390 )
00391 {
00392 cpl_frame* frm_sci = NULL;
00393 cpl_frame* frm_atmext = NULL;
00394 cpl_table* tbl_obj_spectrum = NULL;
00395 cpl_table* tbl_atmext = NULL;
00396 double exptime = 600;
00397
00398 cpl_propertylist* plist = NULL;
00399 cpl_table* tbl_ref = NULL;
00400 cpl_frame* result=NULL;
00401
00402 const char* name=NULL;
00403 double dRA = 0;
00404 double dDEC = 0;
00405 char prod_name[256];
00406 char prod_tag[256];
00407 double airmass=0;
00408 const double mk2AA=1E4;
00409 int nclip=0;
00410 int ntot=0;
00411 cpl_table* tbl_result = NULL;
00412
00413
00414
00415
00416
00417 check(frm_sci=xsh_find_frame_with_tag(frames,XSH_STD_FLUX_SLIT_STARE_ORDER1D, inst));
00418 check(name=cpl_frame_get_filename(frm_sci));
00419
00420 check(tbl_obj_spectrum=cpl_table_load(name,1,0));
00421 check(plist=cpl_propertylist_load(name,0));
00422
00423 xsh_get_std_obs_values(plist,&exptime,&airmass,&dRA,&dDEC);
00424
00425
00426 xsh_load_ref_table(frames, dRA, dDEC, dEpsilon, inst, &tbl_ref);
00427 if (tbl_ref)
00428 {
00429
00430 check(frm_atmext=cpl_frameset_find(frames,FRM_EXTCOEFF_TAB));
00431 check(name=cpl_frame_get_filename(frm_atmext));
00432 check(tbl_atmext=cpl_table_load(name,1,0));
00433
00434 tbl_result = xsh_utils_efficiency_internal(
00435 tbl_obj_spectrum,
00436 tbl_atmext,
00437 tbl_ref,
00438 exptime,
00439 airmass,
00440 aimprim,
00441 dGain,
00442 1,
00443 mk2AA,
00444 col_name_atm_wave,
00445 col_name_atm_abs,
00446 col_name_ref_wave,
00447 col_name_ref_flux,
00448 col_name_ref_bin,
00449 col_name_obj_wave,
00450 col_name_obj_flux,
00451 &ntot,&nclip);
00452 if (tbl_result)
00453 {
00454 HIGH_ABS_REGION * phigh=NULL;
00455 check(xsh_efficiency_add_high_abs_regions(&tbl_result,phigh));
00456 sprintf(prod_tag,"EFFICIENCY_%s",xsh_instrument_arm_tostring(inst));
00457 sprintf(prod_name,"%s.fits",prod_tag);
00458
00459 result=xsh_frame_product(prod_name,prod_tag,CPL_FRAME_TYPE_TABLE,
00460 CPL_FRAME_GROUP_CALIB,CPL_FRAME_LEVEL_FINAL);
00461 cpl_table_save(tbl_result, plist, NULL,prod_name, CPL_IO_DEFAULT);
00462
00463 xsh_free_table(&tbl_result);
00464 }
00465
00466 }
00467
00468 cleanup:
00469 xsh_free_propertylist(&plist);
00470 xsh_free_table(&tbl_atmext);
00471 xsh_free_table(&tbl_obj_spectrum);
00472 xsh_free_table(&tbl_ref);
00473 return result;
00474 }
00475
00476 static int
00477 xsh_column_to_double(cpl_table* ptable, const char* column)
00478 {
00479 const char* TEMP = "_temp_";
00480 check(cpl_table_duplicate_column(ptable, TEMP, ptable, column));
00481 check(cpl_table_erase_column(ptable, column));
00482 check(cpl_table_cast_column(ptable, TEMP, column, CPL_TYPE_DOUBLE));
00483 check(cpl_table_erase_column(ptable, TEMP ));
00484 return 0;
00485 cleanup:
00486 xsh_msg(" error column to double [%s]", column);
00487 return -1;
00488 }
00489
00490
00491
00513
00514
00515 cpl_table*
00516 xsh_utils_efficiency_internal(cpl_table* tbl_obj_spectrum,
00517 cpl_table* tbl_atmext,
00518 cpl_table* tbl_ref,
00519 double exptime,
00520 double airmass,
00521 double aimprim,
00522 double gain,
00523 int biny,
00524 double src2ref_wave_sampling,
00525 const char* col_name_atm_wave,
00526 const char* col_name_atm_abs,
00527 const char* col_name_ref_wave,
00528 const char* col_name_ref_flux,
00529 const char* col_name_ref_bin,
00530 const char* col_name_obj_wave,
00531 const char* col_name_obj_flux,
00532 int* ntot,
00533 int* nclip
00534 )
00535 {
00536
00537 const double TEL_AREA = 51.2e4;
00538 double cdelta1 = 0;
00539 int i = 0;
00540 cpl_table* tbl_sel = NULL;
00541
00542
00543
00544
00545
00546
00547 cpl_table* tbl_result = NULL;
00548
00549
00550
00551
00552
00553
00554
00555
00556 double* pref = NULL;
00557 double* pext = NULL;
00558 double* pcor = NULL;
00559 double* peph = NULL;
00560
00561 double* pw = NULL;
00562 int nrow = 0;
00563 double ref_bin_size=0;
00564 double um2nm=0.001;
00565 double eff_med=0.;
00566 double eff_rms=0.;
00567 double eff_thresh=0.;
00568
00569 double kappa=5;
00570 double nm2AA=10.;
00571 int nsel=0;
00572 double eff=0;
00573 nrow = cpl_table_get_nrow(tbl_obj_spectrum);
00574 xsh_msg_dbg_medium("Starting efficiency calculation: exptime[%f] airmass[%f] nrow[%d]",
00575 exptime, airmass, nrow);
00576
00577
00578
00579
00580
00581 xsh_column_to_double(tbl_obj_spectrum,col_name_obj_wave);
00582 xsh_column_to_double(tbl_obj_spectrum,col_name_obj_flux);
00583
00584 check(xsh_column_to_double(tbl_atmext,col_name_atm_wave ));
00585 check(xsh_column_to_double(tbl_atmext,col_name_atm_abs ));
00586 check(xsh_column_to_double(tbl_ref,col_name_ref_wave ));
00587 check(xsh_column_to_double(tbl_ref,col_name_ref_flux ));
00588 check(xsh_column_to_double(tbl_ref,col_name_ref_bin ));
00589
00590
00591
00592
00593
00594
00595
00596 ref_bin_size=cpl_table_get_double(tbl_ref,col_name_ref_bin,0,NULL);
00597 xsh_msg_dbg_medium("ref_bin_size[nm]=%g",ref_bin_size);
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610 check(cpl_table_multiply_scalar(tbl_obj_spectrum,col_name_obj_wave,
00611 src2ref_wave_sampling));
00612
00613
00614
00615
00616
00617
00618
00619
00620 xsh_msg_dbg_medium("object 2 src std wave factor %g",src2ref_wave_sampling);
00621 check(pw=cpl_table_get_data_double(tbl_obj_spectrum,col_name_obj_wave));
00622
00623
00624 check(tbl_result=cpl_table_new(nrow));
00625 check(pref=xsh_create_column_double(tbl_result, COL_NAME_REF, nrow));
00626 check(pext=xsh_create_column_double(tbl_result, COL_NAME_EXT, nrow));
00627 check(pcor=xsh_create_column_double(tbl_result, COL_NAME_COR, nrow));
00628 check(peph=xsh_create_column_double(tbl_result, COL_NAME_EPHOT, nrow));
00629 xsh_msg_dbg_medium("wave range: [%g,%g] nm",pw[0],pw[nrow-1]);
00630 xsh_msg_dbg_medium("src_bin_size[nm]=%g",pw[1] - pw[0]);
00631
00632 cdelta1 = (pw[1] - pw[0]) / src2ref_wave_sampling ;
00633 xsh_msg_dbg_medium("nrow=%d cdelta1=%g",nrow,cdelta1);
00634 for (i = 0; i < nrow; i++)
00635 {
00636 check(pext[i] = xsh_table_interpolate(tbl_atmext, pw[i],col_name_atm_wave, col_name_atm_abs));
00637 check(pref[i] = xsh_table_interpolate(tbl_ref, pw[i], col_name_ref_wave,col_name_ref_flux));
00638 pcor[i] = pow(10,(0.4*pext[i] * (aimprim - airmass)));
00639 eff = 1.e7*1.986e-19/(pw[i]*um2nm);
00640 if(!isnan(eff)) {
00641 peph[i]=eff;
00642 } else {
00643
00644
00645
00646
00647 cpl_table_set_invalid(tbl_result,COL_NAME_EPHOT,i);
00648 }
00649
00650
00651
00652
00653
00654
00655
00656
00657 }
00658 cpl_table_erase_invalid(tbl_result);
00659
00660
00661
00662
00663
00664
00665
00666
00667 check(cpl_table_duplicate_column(tbl_result,"ORDER",
00668 tbl_obj_spectrum,COL_NAME_ORD_OBJ ));
00669 check(cpl_table_duplicate_column(tbl_result,COL_NAME_SRC_COR,
00670 tbl_obj_spectrum, col_name_obj_flux));
00671 check(cpl_table_duplicate_column(tbl_result,col_name_obj_wave,
00672 tbl_obj_spectrum,col_name_obj_wave));
00673
00674
00675
00676 check(cpl_table_multiply_columns(tbl_result,COL_NAME_SRC_COR,COL_NAME_COR));
00677
00678
00679
00680
00681
00682
00683 cpl_table_divide_scalar(tbl_result, COL_NAME_SRC_COR, src2ref_wave_sampling);
00684 cpl_table_divide_scalar(tbl_result, COL_NAME_SRC_COR, cdelta1);
00685 cpl_table_divide_scalar(tbl_result, COL_NAME_SRC_COR, nm2AA);
00686
00687 cpl_table_divide_scalar(tbl_result,COL_NAME_SRC_COR,biny);
00688
00689
00690
00691
00692 check(cpl_table_divide_scalar(tbl_result,COL_NAME_REF,ref_bin_size));
00693
00694
00695
00696 check(cpl_table_duplicate_column(tbl_result,COL_NAME_SRC_EFF,
00697 tbl_result,COL_NAME_SRC_COR));
00698
00699
00700
00701
00702 check(cpl_table_multiply_scalar(tbl_result,COL_NAME_SRC_EFF,
00703 gain / (exptime * TEL_AREA)));
00704
00705
00706 check(cpl_table_multiply_columns(tbl_result,COL_NAME_SRC_EFF,
00707 COL_NAME_EPHOT));
00708
00709
00710
00711
00712
00713 check(cpl_table_divide_columns(tbl_result,COL_NAME_SRC_EFF,COL_NAME_REF));
00714
00715
00716
00717
00718
00719 eff_med=cpl_table_get_column_median(tbl_result,COL_NAME_SRC_EFF);
00720 eff_rms=cpl_table_get_column_stdev(tbl_result,COL_NAME_SRC_EFF);
00721
00722 eff_thresh=(eff_med+kappa*eff_rms<10.) ? eff_med+kappa*eff_rms:10.;
00723 if(irplib_isinf(eff_thresh)) eff_thresh=10.;
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733 *ntot=cpl_table_get_nrow(tbl_result);
00734 cpl_table_and_selected_double(tbl_result,COL_NAME_SRC_EFF,
00735 CPL_GREATER_THAN,1.e-5);
00736
00737 cpl_table_and_selected_double(tbl_result,COL_NAME_SRC_EFF,
00738 CPL_LESS_THAN,eff_thresh);
00739
00740 eff_med=cpl_table_get_column_median(tbl_result,COL_NAME_SRC_EFF);
00741 eff_rms=cpl_table_get_column_stdev(tbl_result,COL_NAME_SRC_EFF);
00742
00743 eff_thresh=(eff_med+kappa*eff_rms<10.) ? eff_med+kappa*eff_rms:10.;
00744 if(irplib_isinf(eff_thresh)) eff_thresh=10.;
00745
00746
00747
00748
00749 cpl_table_and_selected_double(tbl_result,COL_NAME_SRC_EFF,
00750 CPL_LESS_THAN,eff_thresh);
00751
00752 nsel=cpl_table_and_selected_double(tbl_result,COL_NAME_SRC_EFF,
00753 CPL_LESS_THAN,1);
00754
00755 *nclip=(*ntot)-nsel;
00756 tbl_sel=cpl_table_extract_selected(tbl_result);
00757
00758
00759 cleanup:
00760 xsh_free_table(&tbl_result);
00761 return tbl_sel;
00762 }
00763
00772 void
00773 xsh_frame_sci_get_ra_dec_airmass(cpl_frame* frm_sci,
00774 double* ra,
00775 double* dec,
00776 double* airmass)
00777 {
00778
00779 const char* name_sci=NULL;
00780 cpl_propertylist* plist=NULL;
00781
00782 name_sci=cpl_frame_get_filename(frm_sci);
00783 check(plist=cpl_propertylist_load(name_sci,0));
00784 *ra=xsh_pfits_get_ra(plist);
00785 *dec=xsh_pfits_get_dec(plist);
00786 *airmass=xsh_pfits_get_airm_mean(plist);
00787
00788 cleanup:
00789
00790 xsh_free_propertylist(&plist);
00791 return;
00792 }
00793
00794
00795
00796 static void
00797 xsh_frame_sci_get_gain_airmass_exptime_naxis1_biny(cpl_frame* frm_sci,
00798 xsh_instrument* instrument,
00799 double* gain,
00800 double* airmass,
00801 double* exptime,
00802 int* naxis1,
00803 int* biny)
00804 {
00805
00806 const char* name_sci=NULL;
00807 cpl_propertylist* plist=NULL;
00808
00809 name_sci=cpl_frame_get_filename(frm_sci);
00810 check(plist=cpl_propertylist_load(name_sci,0));
00811 check(*naxis1=xsh_pfits_get_naxis1(plist));
00812 *airmass=xsh_pfits_get_airm_mean(plist);
00813
00814 if( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
00815 *gain=2.12;
00816 *biny=1;
00817 check(*exptime=xsh_pfits_get_dit(plist));
00818 } else {
00819 check(*gain=xsh_pfits_get_conad(plist));
00820 check(*biny=xsh_pfits_get_biny(plist));
00821 check(*exptime=xsh_pfits_get_win1_dit1(plist));
00822 }
00823
00824 cleanup:
00825 xsh_free_propertylist(&plist);
00826
00827 return;
00828 }
00829
00835 cpl_frame*
00836 xsh_catalog_extract_spectrum_frame(cpl_frame* frm_cat,
00837 cpl_frame* frm_sci)
00838 {
00839 cpl_frame* result=NULL;
00840 double dRA=0;
00841 double dDEC=0;
00842
00843 double nm2nm=1.;
00844 cpl_table* tbl_ref=NULL;
00845 char fname[256];
00846 char ftag[256];
00847 double airmass=0;
00848 xsh_std_star_id std_star_id=0;
00849
00850 XSH_ASSURE_NOT_NULL_MSG(frm_sci,"Null input sci frame set!Exit");
00851 XSH_ASSURE_NOT_NULL_MSG(frm_cat,"Null input std star cat frame set!Exit");
00852 xsh_frame_sci_get_ra_dec_airmass(frm_sci,&dRA,&dDEC,&airmass);
00853 check(xsh_parse_catalog_std_stars(frm_cat,dRA,dDEC,STAR_MATCH_DEPSILON,&tbl_ref,&std_star_id));
00854
00855
00856 cpl_table_divide_scalar(tbl_ref,COL_NAME_WAVE_REF,nm2nm);
00857 cpl_table_multiply_scalar(tbl_ref,COL_NAME_FLUX_REF,nm2nm);
00858 check(cpl_table_divide_columns(tbl_ref,COL_NAME_FLUX_REF,COL_NAME_BINWIDTH_REF));
00859
00860 sprintf(fname,"ref_std_star_spectrum.fits");
00861 sprintf(ftag,"STD_STAR_FLUX");
00862
00863 check(cpl_table_save(tbl_ref,NULL,NULL,fname,CPL_IO_DEFAULT));
00864 result=xsh_frame_product(fname,ftag,CPL_FRAME_TYPE_TABLE,
00865 CPL_FRAME_GROUP_CALIB,CPL_FRAME_LEVEL_INTERMEDIATE);
00866 cleanup:
00867 return result;
00868 }
00869
00877 cpl_frame*
00878 xsh_efficiency_compute(cpl_frame* frm_sci,
00879 cpl_frame* frm_cat,
00880 cpl_frame* frm_atmext,
00881 cpl_frame* high_abs_win,
00882 xsh_instrument* instrument)
00883
00884 {
00885
00886 cpl_image* ima_sci=NULL;
00887 cpl_image* ima_ord=NULL;
00888 cpl_image* ima_obj=NULL;
00889 cpl_table* obj_tab=NULL;
00890
00891 const char* name_sci=NULL;
00892 const char* name_atm=NULL;
00893 cpl_propertylist* plist=NULL;
00894 cpl_propertylist* x_plist=NULL;
00895
00896
00897 cpl_table* tbl_ord=NULL;
00898 cpl_table* tot_eff=NULL;
00899 cpl_table* tbl_eff=NULL;
00900 cpl_table* tbl_ref=NULL;
00901 cpl_table* tbl_atmext=NULL;
00902
00903 double * pobj=NULL;
00904 double * pw=NULL;
00905 double * pf=NULL;
00906 int * po=NULL;
00907
00908 cpl_frame* frm_eff=NULL;
00909
00910
00911
00912 double crval1=0;
00913 double cdelt1=0;
00914 int naxis1=0;
00915 int nrow=0;
00916
00917
00918 double exptime=600;
00919 cpl_vector* rec_profile=NULL;
00920 int i=0;
00921 double airmass=0;
00922 double dRA=0;
00923 double dDEC=0;
00924 char key_name[40];
00925 int next=0;
00926 int nord=0;
00927
00928
00929
00930 int j=0;
00931 double wav=0;
00932 double gain=0;
00933 int biny=1;
00934 double aimprim=0;
00935 int ord=0;
00936
00937 double nm2nm=1.;
00938
00939 char fname[256];
00940 char tag[256];
00941 double emax=0;
00942 double emed=0;
00943 int nclip=0;
00944 int ntot=0;
00945
00946 int nclip_tot=0;
00947 int neff_tot=0;
00948 double fclip=0;
00949 xsh_std_star_id std_star_id=0;
00950 int ima_size_x=0;
00951
00952 XSH_ASSURE_NOT_NULL_MSG(frm_sci,"Null input sci frame set!Exit");
00953 XSH_ASSURE_NOT_NULL_MSG(frm_cat,"Null input std star cat frame set!Exit");
00954 XSH_ASSURE_NOT_NULL_MSG(frm_atmext,"Null input atmospheric ext frame set!Exit");
00955
00956 check(next = cpl_frame_get_nextensions(frm_sci));
00957
00958 nord=(next+1)/3;
00959
00960 xsh_frame_sci_get_ra_dec_airmass(frm_sci,&dRA,&dDEC,&airmass);
00961 name_sci=cpl_frame_get_filename(frm_sci);
00962 plist=cpl_propertylist_load(name_sci,0);
00963 xsh_frame_sci_get_gain_airmass_exptime_naxis1_biny(frm_sci,instrument,
00964 &gain,&airmass,&exptime,
00965 &naxis1,&biny);
00966
00967
00968 check(xsh_parse_catalog_std_stars(frm_cat,dRA,dDEC,STAR_MATCH_DEPSILON,
00969 &tbl_ref,&std_star_id));
00970
00971
00972 xsh_msg_dbg_medium("gain=%g airm=%g exptime=%g airmass=%g ra=%g dec=%g",
00973 gain,airmass,exptime,airmass,dRA,dDEC);
00974
00975 xsh_msg_dbg_medium("name_sci=%s",name_sci);
00976 nrow=naxis1*nord;
00977
00978
00979
00980
00981 obj_tab=cpl_table_new(nrow);
00982
00983
00984 cpl_table_new_column(obj_tab,COL_NAME_ORD_OBJ,CPL_TYPE_INT);
00985 cpl_table_new_column(obj_tab,COL_NAME_WAVE_OBJ,CPL_TYPE_DOUBLE);
00986 cpl_table_new_column(obj_tab,COL_NAME_INT_OBJ,CPL_TYPE_DOUBLE);
00987
00988 check(cpl_table_fill_column_window_int(obj_tab,COL_NAME_ORD_OBJ,0,nrow,-1));
00989 check(cpl_table_fill_column_window_double(obj_tab,COL_NAME_WAVE_OBJ,0,nrow,-1));
00990 check(cpl_table_fill_column_window_double(obj_tab,COL_NAME_INT_OBJ,0,nrow,-1));
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001 check(name_atm=cpl_frame_get_filename(frm_atmext));
01002 xsh_msg_dbg_medium("name_atm=%s",name_atm);
01003 check(tbl_atmext=cpl_table_load(name_atm,1,0));
01004
01005 if(!cpl_table_has_column(tbl_atmext,XSH_ATMOS_EXT_LIST_COLNAME_K)){
01006 xsh_msg_warning("You are using an obsolete atm extinction line table");
01007 cpl_table_duplicate_column(tbl_atmext,XSH_ATMOS_EXT_LIST_COLNAME_K,
01008 tbl_atmext,XSH_ATMOS_EXT_LIST_COLNAME_OLD);
01009 }
01010
01011
01012 if(tbl_ref == NULL) {
01013 xsh_msg_error("Provide std sar catalog frame");
01014 return NULL;
01015
01016 }
01017
01018 for(i=0;i<next;i+=3) {
01019
01020
01021
01022 xsh_free_image(&ima_ord);
01023 pobj=NULL;
01024 xsh_free_propertylist(&x_plist);
01025 check(ima_ord=cpl_image_load(name_sci,CPL_TYPE_DOUBLE,0,i));
01026 check(x_plist=cpl_propertylist_load(name_sci,i));
01027 ima_size_x=cpl_image_get_size_x(ima_ord);
01028
01029
01030
01031 check(pobj=cpl_image_get_data_double(ima_ord));
01032 check(crval1=xsh_pfits_get_crval1(x_plist));
01033 check(cdelt1=xsh_pfits_get_cdelt1(x_plist));
01034 xsh_free_table(&tbl_ord);
01035 tbl_ord=cpl_table_new(ima_size_x);
01036 check(cpl_table_copy_structure(tbl_ord,obj_tab));
01037 check(cpl_table_fill_column_window_int(tbl_ord,COL_NAME_ORD_OBJ,0,ima_size_x,-1));
01038 check(cpl_table_fill_column_window_double(tbl_ord,COL_NAME_WAVE_OBJ,0,ima_size_x,-1));
01039 check(cpl_table_fill_column_window_double(tbl_ord,COL_NAME_INT_OBJ,0,ima_size_x,-1));
01040
01041 check(po=cpl_table_get_data_int(tbl_ord,COL_NAME_ORD_OBJ));
01042 check(pw=cpl_table_get_data_double(tbl_ord,COL_NAME_WAVE_OBJ));
01043 check(pf=cpl_table_get_data_double(tbl_ord,COL_NAME_INT_OBJ));
01044
01045
01046
01047 ord=i/3;
01048 for(j=0;j<ima_size_x;j++) {
01049 po[j]=ord;
01050 wav=crval1+cdelt1*j;
01051 pw[j]=wav;
01052 pf[j]=pobj[j];
01053
01054 }
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065 xsh_free_table(&tbl_eff);
01066 check(tbl_eff=xsh_utils_efficiency_internal(tbl_ord,tbl_atmext,tbl_ref,
01067 exptime,airmass,aimprim,gain,
01068 biny,nm2nm,
01069 COL_NAME_WAVE_ATMDISP,
01070 COL_NAME_ABS_ATMDISP,
01071 COL_NAME_WAVE_REF,
01072 COL_NAME_FLUX_REF,
01073 COL_NAME_BINWIDTH_REF,
01074 COL_NAME_WAVE_OBJ,
01075 COL_NAME_INT_OBJ,
01076 &ntot,&nclip));
01077 xsh_free_table(&tbl_ord);
01078
01079 nrow=cpl_table_get_nrow(tbl_eff);
01080 if(nrow>0) {
01081 check(emax=cpl_table_get_column_max(tbl_eff,"EFF"));
01082 } else {
01083 emax=-999;
01084 }
01085 sprintf(key_name,"%s%2d", XSH_QC_EFF_PEAK_ORD,ord);
01086 cpl_propertylist_append_double(plist,key_name,emax);
01087 cpl_propertylist_set_comment(plist,key_name,"Peak efficiency");
01088 if(nrow>0) {
01089 check(emed=cpl_table_get_column_median(tbl_eff,"EFF"));
01090 } else {
01091 emed=-999;
01092 }
01093 sprintf(key_name,"%s%2d", XSH_QC_EFF_MED_ORD,ord);
01094 cpl_propertylist_append_double(plist,key_name,emed);
01095 cpl_propertylist_set_comment(plist,key_name,"Median efficiency");
01096
01097
01098 neff_tot+=ntot;
01099
01100 if(ord==0) {
01101 tot_eff=cpl_table_duplicate(tbl_eff);
01102 } else {
01103 cpl_table_insert(tot_eff,tbl_eff,neff_tot);
01104 }
01105 if(!isnan(nclip)) {
01106 nclip_tot+=nclip;
01107 }
01108
01109
01110 }
01111
01112
01113
01114 xsh_msg("nclip_tot=%d",nclip_tot);
01115 HIGH_ABS_REGION * phigh=NULL;
01116 phigh=xsh_fill_high_abs_regions(instrument,high_abs_win);
01117
01118 check(xsh_efficiency_add_high_abs_regions(&tot_eff,phigh));
01119
01120 sprintf(tag,"EFFICIENCY_%s_%s",xsh_instrument_mode_tostring(instrument),
01121 xsh_instrument_arm_tostring(instrument));
01122 sprintf(fname,"%s.fits",tag);
01123
01124 nrow=cpl_table_get_nrow(tot_eff);
01125 fclip=nclip_tot;
01126
01127 if(neff_tot > 0) {
01128 fclip/=neff_tot;
01129 } else {
01130 fclip=-999;
01131 }
01132
01133 xsh_msg("nclip_tot =%d neff_tot=%d fclip=%g",nclip_tot,neff_tot,fclip);
01134 xsh_pfits_set_qc_eff_fclip(plist,fclip);
01135 xsh_pfits_set_qc_eff_nclip(plist,nclip_tot);
01136
01137
01138 check(cpl_table_save(tot_eff,plist, x_plist,fname, CPL_IO_DEFAULT));
01139
01140 xsh_free_table(&obj_tab);
01141
01142 check(frm_eff=xsh_frame_product(fname,tag,CPL_FRAME_TYPE_TABLE,
01143 CPL_FRAME_GROUP_CALIB,
01144 CPL_FRAME_LEVEL_FINAL));
01145
01146
01147
01148 cleanup:
01149
01150
01151
01152
01153 xsh_free_table(&tot_eff);
01154 xsh_free_table(&tbl_ref);
01155 xsh_free_table(&tbl_atmext);
01156 xsh_free_table(&obj_tab);
01157 xsh_free_table(&tbl_ord);
01158 xsh_free_table(&tbl_eff);
01159
01160 xsh_free_image(&ima_sci);
01161 xsh_free_vector(&rec_profile);
01162 xsh_free_image(&ima_ord);
01163 xsh_free_image(&ima_obj);
01164 xsh_free_propertylist(&plist);
01165 xsh_free_propertylist(&x_plist);
01166
01167 return frm_eff;
01168
01169 }
01170
01171
01172
01173 static double slaAirmas ( double zd )
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220 {
01221 double w, seczm1;
01222
01223 w = fabs ( zd );
01224
01225
01226
01227
01228
01229
01230
01231 w = (1.52 > w) ? w : 1.52;
01232 seczm1 = 1.0 / ( cos ( w ) ) - 1.0;
01233 return 1.0 + seczm1 * ( 0.9981833
01234 - seczm1 * ( 0.002875 + 0.0008083 * seczm1 ) );
01235 }
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253 void slaAoppat ( double date, double aoprms[14] )
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285 {
01286
01287
01288
01289 }
01290
01291 static double
01292 xsh_utils_get_airm(cpl_propertylist* plist)
01293 {
01294
01295 double airmass=0;
01296
01297 double azimuth=0;
01298
01299 double altitude=0;
01300
01301 double declination=0;
01302 double RA=0;
01303
01304 double hour_angle=0;
01305
01306
01307 const char* telescope_id=NULL;
01308 int tel_id=0;
01309 double latitude=0;
01310 double lat_sig=-1;
01311 double lat_deg=24;
01312 double lat_min=37;
01313 double lat_sec=30;
01314 int len=0;
01315
01316
01317
01318 double LST=0;
01319
01320 declination=xsh_pfits_get_dec(plist);
01321 RA=xsh_pfits_get_ra(plist);
01322 LST=xsh_pfits_get_lst(plist);
01323 hour_angle=LST-RA;
01324
01325
01326
01327
01328
01329
01330
01331
01332 telescope_id=xsh_pfits_get_telescop(plist);
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343 len=strlen(telescope_id);
01344
01345 tel_id=telescope_id[len-1]-48;
01346
01347
01348
01349 switch ( tel_id ) {
01350 case 1: lat_sec=33.117;
01351 break;
01352 case 2: lat_sec=31.465;
01353 break;
01354 case 3: lat_sec=30.300;
01355 break;
01356 case 4: lat_sec=31.000;
01357 break;
01358 }
01359
01360
01361 latitude=lat_sig*(lat_deg+lat_min/60+lat_sec/3600);
01362
01363
01364 double c1=0;
01365 double c2=0;
01366 double c3=0;
01367
01368 c1=sin(latitude)*sin(declination)+cos(latitude)*cos(declination)*cos(hour_angle);
01369 c2=cos(latitude)*sin(declination)-sin(latitude)*cos(declination)*cos(hour_angle);
01370 c3=-cos(latitude)*sin(hour_angle);
01371
01372 azimuth=atan(c3/c2);
01373 altitude=atan(c1/c2*cos(azimuth));
01374
01375 xsh_msg("altitude=%g",altitude);
01376
01377
01378
01379
01380
01381 airmass=1/sin(altitude+244/(165+47*pow(altitude,1.1)));
01382
01383
01384 return airmass;
01385
01386
01387 }
01388
01389
01390 double
01391 xsh_utils_compute_airm_eff(cpl_frameset* raws)
01392 {
01393
01394 int i=0;
01395 int size=0;
01396 cpl_frame* frm=NULL;
01397 cpl_propertylist* plist=NULL;
01398 const char* name=NULL;
01399 double airm_start=0;
01400 double airm_end=0;
01401 double airm_med=0;
01402 double airm_eff=0;
01403
01404 double exptime=0;
01405 double area=0;
01406 double sum_area=0;
01407 double sum_time=0;
01408
01409 XSH_ASSURE_NOT_NULL_MSG(raws,"raws frameset null pointer");
01410
01411 size=cpl_frameset_get_size(raws);
01412 for(i=0;i<size;i++){
01413
01414 frm=cpl_frameset_get_frame(raws,i);
01415 name=cpl_frame_get_filename(frm);
01416 plist=cpl_propertylist_load(name,0);
01417
01418 airm_med=xsh_utils_get_airm(plist);
01419 airm_start=xsh_pfits_get_airm_start(plist);
01420 airm_end=xsh_pfits_get_airm_end(plist);
01421 exptime=xsh_pfits_get_exptime(plist);
01422
01423 area=(exptime/6)*(airm_start+4*airm_med+airm_end);
01424
01425
01426
01427 sum_area+=area;
01428 sum_time+=exptime;
01429 xsh_free_propertylist(&plist);
01430
01431 }
01432
01433 airm_eff=sum_area/sum_time;
01434
01435 cleanup:
01436 xsh_free_propertylist(&plist);
01437 xsh_msg("airmass eff=%g",airm_eff);
01438
01439 return airm_eff;
01440
01441 }
01442
01443 double
01444 xsh_utils_compute_airm(cpl_frameset* raws)
01445 {
01446
01447 cpl_frame* frm=NULL;
01448 cpl_propertylist* plist=NULL;
01449 const char* name=NULL;
01450 int i=0;
01451 int size=0;
01452 double airm=0;
01453 double airm_eff=0;
01454 double exptime=0;
01455 double time_tot=0;
01456 double* pairm=NULL;
01457 double* pprod=NULL;
01458 double* ptime=NULL;
01459
01460 cpl_array* time_array=NULL;
01461 cpl_array* airm_array=NULL;
01462
01463
01464 XSH_ASSURE_NOT_NULL_MSG(raws,"raws frameset null pointer");
01465
01466 size=cpl_frameset_get_size(raws);
01467 airm_array=cpl_array_new(size,CPL_TYPE_DOUBLE);
01468 time_array=cpl_array_new(size,CPL_TYPE_DOUBLE);
01469
01470 pairm=cpl_array_get_data_double(airm_array);
01471 ptime=cpl_array_get_data_double(time_array);
01472 pprod=cpl_array_get_data_double(time_array);
01473
01474 if(size>2) {
01475 for(i=0;i<size;i++){
01476
01477 frm=cpl_frameset_get_frame(raws,i);
01478 name=cpl_frame_get_filename(frm);
01479 plist=cpl_propertylist_load(name,0);
01480 airm=xsh_pfits_get_airm_mean(plist);
01481 exptime=xsh_pfits_get_exptime(plist);
01482 ptime[i]=exptime;
01483 pairm[i]=airm;
01484 pprod[i]=airm*exptime;
01485
01486 }
01487 airm_eff=(pprod[0]+pprod[size-1])/(ptime[0]+ptime[size-1]);
01488
01489 } else if (size == 2) {
01490 frm=cpl_frameset_get_frame(raws,0);
01491 name=cpl_frame_get_filename(frm);
01492 plist=cpl_propertylist_load(name,0);
01493
01494 airm=xsh_pfits_get_airm_mean(plist);
01495 exptime=xsh_pfits_get_exptime(plist);
01496
01497 airm_eff=airm*exptime;
01498 time_tot=exptime;
01499
01500 frm=cpl_frameset_get_frame(raws,1);
01501 name=cpl_frame_get_filename(frm);
01502 plist=cpl_propertylist_load(name,0);
01503
01504
01505 airm_eff+=airm*exptime;
01506 time_tot+=exptime;
01507
01508 airm_eff/=time_tot;
01509 } else {
01510
01511 frm=cpl_frameset_get_frame(raws,0);
01512 name=cpl_frame_get_filename(frm);
01513 plist=cpl_propertylist_load(name,0);
01514
01515 airm=xsh_pfits_get_airm_mean(plist);
01516 exptime=xsh_pfits_get_exptime(plist);
01517
01518 airm_eff=airm;
01519 }
01520
01521 cleanup:
01522 return airm_eff;
01523
01524 }
01525
01526