00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include <string.h>
00037 #include <math.h>
00038 #include <float.h>
00039
00040 #include <cpl.h>
00041
00042 #include "irplib_stdstar.h"
00043 #include "irplib_utils.h"
00044
00045
00049
00052
00053
00054
00055
00056
00075
00076 int irplib_stdstar_write_catalogs(
00077 cpl_frameset * set_in,
00078 const cpl_frameset * set_raw,
00079 const char * recipe_name,
00080 const char * pro_cat,
00081 const char * pro_type,
00082 const char * package_name,
00083 const char * ins_name,
00084 cpl_table * (*convert_ascii_table)(const char *))
00085 {
00086 cpl_table * out ;
00087 cpl_propertylist * plist ;
00088 cpl_propertylist * plist_ext ;
00089 cpl_parameterlist * parlist ;
00090 const char * cat_name ;
00091 char * out_name ;
00092 int nb_catalogs ;
00093 const cpl_frame * cur_frame ;
00094 int i ;
00095
00096
00097 if (set_in == NULL) return -1 ;
00098 if (set_raw == NULL) return -1 ;
00099 if (recipe_name == NULL) return -1 ;
00100 if (pro_cat == NULL) return -1 ;
00101 if (ins_name == NULL) return -1 ;
00102
00103
00104 out_name = irplib_sprintf("%s.fits", recipe_name) ;
00105
00106
00107 nb_catalogs = cpl_frameset_get_size(set_raw) ;
00108
00109
00110 cur_frame = cpl_frameset_get_frame_const(set_raw, 0) ;
00111 cat_name = cpl_frame_get_filename(cur_frame) ;
00112
00113
00114 if ((out = convert_ascii_table(cat_name)) == NULL) {
00115 cpl_free(out_name) ;
00116 return -1 ;
00117 }
00118
00119
00120 plist = cpl_propertylist_new() ;
00121 cpl_propertylist_append_string(plist, "INSTRUME", ins_name) ;
00122 if (pro_type != NULL) {
00123 cpl_propertylist_append_string(plist, "ESO PRO TYPE", pro_type) ;
00124 }
00125 plist_ext = cpl_propertylist_new() ;
00126 cpl_propertylist_append_string(plist_ext, "EXTNAME", cat_name) ;
00127
00128
00129 parlist = cpl_parameterlist_new() ;
00130 cpl_dfs_save_table(set_in,
00131 parlist,
00132 set_raw,
00133 out,
00134 plist_ext,
00135 recipe_name,
00136 pro_cat,
00137 plist,
00138 NULL,
00139 package_name,
00140 out_name) ;
00141 cpl_parameterlist_delete(parlist) ;
00142 cpl_propertylist_delete(plist) ;
00143 cpl_propertylist_delete(plist_ext) ;
00144 cpl_table_delete(out) ;
00145
00146
00147 for (i=1 ; i<nb_catalogs ; i++) {
00148
00149 cur_frame = cpl_frameset_get_frame_const(set_raw, i) ;
00150 cat_name = cpl_frame_get_filename(cur_frame) ;
00151
00152
00153 if ((out = convert_ascii_table(cat_name)) == NULL) {
00154 cpl_free(out_name) ;
00155 return -1 ;
00156 }
00157
00158 plist_ext = cpl_propertylist_new() ;
00159 cpl_propertylist_append_string(plist_ext, "EXTNAME", cat_name) ;
00160 cpl_table_save(out, NULL, plist_ext, out_name, CPL_IO_EXTEND) ;
00161 cpl_table_delete(out) ;
00162 cpl_propertylist_delete(plist_ext) ;
00163 }
00164 cpl_free(out_name) ;
00165 return 0 ;
00166 }
00167
00168
00181
00182 cpl_table * irplib_stdstar_load_catalog(
00183 const char * filename,
00184 const char * ext_name)
00185 {
00186 int next ;
00187 cpl_propertylist * plist ;
00188 const char * cur_name ;
00189 cpl_table * out ;
00190 cpl_table * out_cur ;
00191 cpl_frame * cur_frame ;
00192 int i ;
00193
00194
00195 if (filename == NULL) return NULL ;
00196 if (ext_name == NULL) return NULL ;
00197
00198
00199 out = NULL ;
00200
00201
00202 cur_frame = cpl_frame_new() ;
00203 cpl_frame_set_filename(cur_frame, filename) ;
00204 next = cpl_frame_get_nextensions(cur_frame) ;
00205 cpl_frame_delete(cur_frame) ;
00206
00207
00208 for (i=0 ; i<next ; i++) {
00209
00210 if ((plist = cpl_propertylist_load_regexp(filename, i+1, "EXTNAME",
00211 0)) == NULL) {
00212 cpl_msg_error(cpl_func, "Cannot load header of %d th extension",
00213 i+1) ;
00214 return NULL ;
00215 }
00216 cur_name = cpl_propertylist_get_string(plist, "EXTNAME") ;
00217
00218
00219 if (!strcmp(cur_name, ext_name)) {
00220
00221 if (out == NULL) {
00222 out = cpl_table_load(filename, i+1, 0) ;
00223 if (out == NULL) {
00224 cpl_msg_error(cpl_func, "Cannot load extension %d", i+1) ;
00225 cpl_propertylist_delete(plist) ;
00226 return NULL ;
00227 }
00228 }
00229 } else if (!strcmp(ext_name, "all")) {
00230
00231 if (i==0) {
00232
00233 out = cpl_table_load(filename, i+1, 0) ;
00234 if (out == NULL) {
00235 cpl_msg_error(cpl_func, "Cannot load extension %d", i+1) ;
00236 cpl_propertylist_delete(plist) ;
00237 return NULL ;
00238 }
00239 } else {
00240
00241 out_cur = cpl_table_load(filename, i+1, 0) ;
00242 if (out_cur == NULL) {
00243 cpl_msg_error(cpl_func, "Cannot load extension %d", i+1) ;
00244 cpl_table_delete(out) ;
00245 cpl_propertylist_delete(plist) ;
00246 return NULL ;
00247 }
00248
00249 if (cpl_table_insert(out, out_cur,
00250 cpl_table_get_nrow(out)) != CPL_ERROR_NONE) {
00251 cpl_msg_error(cpl_func, "Cannot merge table %d", i+1) ;
00252 cpl_table_delete(out) ;
00253 cpl_table_delete(out_cur) ;
00254 cpl_propertylist_delete(plist) ;
00255 return NULL ;
00256 }
00257 cpl_table_delete(out_cur) ;
00258 }
00259 }
00260 cpl_propertylist_delete(plist) ;
00261 }
00262 return out ;
00263 }
00264
00265
00277
00278 int irplib_stdstar_select_stars_dist(
00279 cpl_table * cat,
00280 double ra,
00281 double dec,
00282 double dist)
00283 {
00284 double distance ;
00285 int nrows ;
00286 int i ;
00287
00288
00289 if (cat == NULL) return -1 ;
00290
00291
00292 nrows = cpl_table_get_nrow(cat) ;
00293
00294
00295 if (!cpl_table_has_column(cat, IRPLIB_STDSTAR_RA_COL)) {
00296 cpl_msg_error(cpl_func, "Missing %s column", IRPLIB_STDSTAR_RA_COL) ;
00297 return -1 ;
00298 }
00299 if (!cpl_table_has_column(cat, IRPLIB_STDSTAR_DEC_COL)) {
00300 cpl_msg_error(cpl_func, "Missing %s column", IRPLIB_STDSTAR_DEC_COL) ;
00301 return -1 ;
00302 }
00303
00304
00305 for (i=0 ; i<nrows ; i++) {
00306 if (cpl_table_is_selected(cat, i)) {
00307
00308 distance = irplib_stdstar_great_circle_dist(ra, dec,
00309 cpl_table_get_double(cat, IRPLIB_STDSTAR_RA_COL, i, NULL),
00310 cpl_table_get_double(cat, IRPLIB_STDSTAR_DEC_COL, i, NULL));
00311 if (distance > dist) cpl_table_unselect_row(cat, i) ;
00312 }
00313 }
00314 return 0 ;
00315 }
00316
00317
00326
00327 int irplib_stdstar_select_stars_mag(
00328 cpl_table * cat,
00329 const char * mag)
00330 {
00331
00332 if (cat == NULL) return -1 ;
00333 if (mag == NULL) return -1 ;
00334
00335
00336 if (!cpl_table_has_column(cat, mag)) {
00337 cpl_msg_error(cpl_func, "Column %s does not exist in the catalog",
00338 mag) ;
00339 return -1 ;
00340 }
00341
00342
00343 if (cpl_table_and_selected_double(cat, mag, CPL_NOT_GREATER_THAN,
00344 98.0) <= 0) {
00345 cpl_msg_error(cpl_func, "Column %s does not exist in the catalog",
00346 mag) ;
00347 return -1 ;
00348 }
00349 return 0 ;
00350 }
00351
00352
00362
00363 int irplib_stdstar_find_closest(
00364 const cpl_table * cat,
00365 double ra,
00366 double dec)
00367 {
00368 double min_dist, distance ;
00369 int nrows ;
00370 int ind ;
00371 int i ;
00372
00373
00374 if (cat == NULL) return -1 ;
00375
00376
00377 min_dist = 1000.0 ;
00378 ind = -1 ;
00379
00380
00381 nrows = cpl_table_get_nrow(cat) ;
00382
00383
00384 if (!cpl_table_has_column(cat, IRPLIB_STDSTAR_RA_COL)) {
00385 cpl_msg_error(cpl_func, "Missing %s column", IRPLIB_STDSTAR_RA_COL) ;
00386 return -1 ;
00387 }
00388 if (!cpl_table_has_column(cat, IRPLIB_STDSTAR_DEC_COL)) {
00389 cpl_msg_error(cpl_func, "Missing %s column", IRPLIB_STDSTAR_DEC_COL) ;
00390 return -1 ;
00391 }
00392
00393
00394 for (i=0 ; i<nrows ; i++) {
00395 if (cpl_table_is_selected(cat, i)) {
00396
00397 distance = irplib_stdstar_great_circle_dist(ra, dec,
00398 cpl_table_get_double(cat, IRPLIB_STDSTAR_RA_COL, i, NULL),
00399 cpl_table_get_double(cat, IRPLIB_STDSTAR_DEC_COL, i, NULL));
00400 if (distance <= min_dist) {
00401 min_dist = distance ;
00402 ind = i ;
00403 }
00404 }
00405 }
00406 return ind ;
00407 }
00408
00409
00425
00426 int irplib_stdstar_get_mag(
00427 const char * catfile,
00428 double ra,
00429 double dec,
00430 const char * band,
00431 const char * catname,
00432 double * mag,
00433 char * name,
00434 char * type,
00435 double dist_am)
00436 {
00437 cpl_table * catal ;
00438 double dist = dist_am / 60.0 ;
00439 int ind ;
00440
00441
00442 if (catfile == NULL) return -1 ;
00443 if (band == NULL) return -1 ;
00444 if (catname == NULL) return -1 ;
00445 if (mag == NULL) return -1 ;
00446 if (name == NULL) return -1 ;
00447 if (type == NULL) return -1 ;
00448
00449
00450 if ((catal = irplib_stdstar_load_catalog(catfile, catname)) == NULL) {
00451 cpl_msg_error(cpl_func, "Cannot load the catalog %s from %s",
00452 catname, catfile) ;
00453 return -1 ;
00454 }
00455
00456
00457 cpl_msg_info(cpl_func, "Select stars with a known magnitude in band %s",
00458 band) ;
00459 if (irplib_stdstar_select_stars_mag(catal, band) == -1) {
00460 cpl_msg_error(cpl_func, "Cannot select stars") ;
00461 cpl_table_delete(catal) ;
00462 return -1 ;
00463 }
00464
00465
00466 cpl_msg_info(cpl_func, "Select stars within %g arc minutes", dist_am) ;
00467 if (irplib_stdstar_select_stars_dist(catal, ra, dec, dist) == -1) {
00468 cpl_msg_error(cpl_func, "Cannot select stars") ;
00469 cpl_table_delete(catal) ;
00470 return -1 ;
00471 }
00472 cpl_msg_info(cpl_func, "%d stars found in the area",
00473 cpl_table_count_selected(catal)) ;
00474
00475
00476 cpl_msg_info(cpl_func, "Select the closest") ;
00477 if ((ind=irplib_stdstar_find_closest(catal, ra, dec)) < 0) {
00478 cpl_msg_error(cpl_func, "Cannot select the closest star") ;
00479 cpl_table_delete(catal) ;
00480 return -1 ;
00481 }
00482
00483 *mag = cpl_table_get_double(catal, band, ind, NULL) ;
00484 if (!cpl_table_has_column(catal, IRPLIB_STDSTAR_STAR_COL)) {
00485 cpl_msg_error(cpl_func, "Missing %s column",
00486 IRPLIB_STDSTAR_STAR_COL) ;
00487 cpl_table_delete(catal) ;
00488 return -1 ;
00489 }
00490 if (!cpl_table_has_column(catal, IRPLIB_STDSTAR_TYPE_COL)) {
00491 cpl_msg_error(cpl_func, "Missing %s column",
00492 IRPLIB_STDSTAR_TYPE_COL) ;
00493 cpl_table_delete(catal) ;
00494 return -1 ;
00495 }
00496
00497
00498 strcpy(name, cpl_table_get_string(catal, IRPLIB_STDSTAR_STAR_COL, ind)) ;
00499 strcpy(type, cpl_table_get_string(catal, IRPLIB_STDSTAR_TYPE_COL, ind)) ;
00500 cpl_table_delete(catal) ;
00501 return 0 ;
00502 }
00503
00504
00517
00518 cpl_vector * irplib_stdstar_get_conversion(
00519 const cpl_bivector * spec,
00520 double dit,
00521 double surface,
00522 double gain,
00523 double mag)
00524 {
00525 double h = 6.62e-27 ;
00526 double c = 3e18 ;
00527 const cpl_vector * wave ;
00528 const cpl_vector * extr ;
00529 cpl_vector * out ;
00530 double factor ;
00531
00532
00533 if (spec == NULL) return NULL ;
00534 if (dit <= 0.0) return NULL ;
00535
00536
00537 wave = cpl_bivector_get_x_const(spec) ;
00538 extr = cpl_bivector_get_y_const(spec) ;
00539
00540
00541 out = cpl_vector_duplicate(extr) ;
00542
00543
00544 cpl_vector_divide_scalar(out, dit) ;
00545
00546
00547 cpl_vector_divide_scalar(out, surface) ;
00548
00549
00550 cpl_vector_multiply_scalar(out, gain) ;
00551
00552
00553 factor = pow(10, mag/2.5) ;
00554 cpl_vector_multiply_scalar(out, factor) ;
00555
00556
00557 factor = (cpl_vector_get(wave, cpl_vector_get_size(wave)-1) -
00558 cpl_vector_get(wave, 0)) / cpl_vector_get_size(wave) ;
00559 cpl_vector_divide_scalar(out, factor) ;
00560
00561
00562 cpl_vector_multiply_scalar(out, h*c) ;
00563 cpl_vector_divide(out, wave) ;
00564
00565 return out ;
00566 }
00567
00568
00576
00577 cpl_vector * irplib_stdstar_get_mag_zero(
00578 const cpl_bivector * sed,
00579 const cpl_vector * waves,
00580 double cent_wl)
00581 {
00582 double wmin, wmax, wstep ;
00583 int nb_sed ;
00584 const double * sed_x ;
00585 const double * sed_y ;
00586 cpl_bivector * sed_loc ;
00587 double * sed_loc_x ;
00588 double * sed_loc_y ;
00589 cpl_vector * out ;
00590 cpl_bivector * out_biv ;
00591 double f0_jan, f0_erg, cent_val ;
00592 int i ;
00593
00594
00595 if (sed == NULL) return NULL ;
00596 if (waves == NULL) return NULL ;
00597
00598
00599 nb_sed = cpl_bivector_get_size(sed) ;
00600 sed_x = cpl_bivector_get_x_data_const(sed) ;
00601 sed_y = cpl_bivector_get_y_data_const(sed) ;
00602 wstep = sed_x[1] - sed_x[0] ;
00603 wmin = cpl_vector_get(waves, 0) ;
00604 wmax = cpl_vector_get(waves, cpl_vector_get_size(waves)-1) ;
00605
00606
00607 sed_loc = cpl_bivector_new(nb_sed + 4) ;
00608 sed_loc_x = cpl_bivector_get_x_data(sed_loc) ;
00609 sed_loc_y = cpl_bivector_get_y_data(sed_loc) ;
00610 for (i=0 ; i<nb_sed ; i++) {
00611 sed_loc_x[i+2] = sed_x[i] ;
00612 sed_loc_y[i+2] = sed_y[i] ;
00613 }
00614
00615
00616 sed_loc_x[1] = sed_loc_x[2] - wstep ;
00617 if (sed_loc_x[2] < wmin) {
00618 sed_loc_x[0] = sed_loc_x[1] - wstep ;
00619 } else {
00620 sed_loc_x[0] = wmin - wstep ;
00621 }
00622 sed_loc_y[0] = 1e-20 ;
00623 sed_loc_y[1] = 1e-20 ;
00624
00625
00626 sed_loc_x[nb_sed+2] = sed_loc_x[nb_sed+1] + wstep ;
00627 if (sed_loc_x[nb_sed+1] > wmax) {
00628 sed_loc_x[nb_sed+3] = sed_loc_x[nb_sed+2] + wstep ;
00629 } else {
00630 sed_loc_x[nb_sed+3] = wmax + wstep ;
00631 }
00632 sed_loc_y[nb_sed+2] = 1e-20 ;
00633 sed_loc_y[nb_sed+3] = 1e-20 ;
00634
00635
00636 out = cpl_vector_duplicate(waves) ;
00637 out_biv = cpl_bivector_wrap_vectors((cpl_vector*)waves, out) ;
00638
00639
00640 if (cpl_bivector_interpolate_linear(out_biv, sed_loc) != CPL_ERROR_NONE) {
00641 cpl_msg_error(cpl_func, "Cannot interpolate the wavelength") ;
00642 cpl_bivector_unwrap_vectors(out_biv) ;
00643 cpl_vector_delete(out) ;
00644 cpl_bivector_delete(sed_loc) ;
00645 return NULL ;
00646 }
00647 cpl_bivector_unwrap_vectors(out_biv) ;
00648 cpl_bivector_delete(sed_loc) ;
00649
00650
00651 f0_jan = 5513.15 / ( pow(cent_wl,3) * (exp(1.2848/cent_wl)-1) ) ;
00652
00653
00654 f0_erg = f0_jan * 1e-26 * 1e7 * 3e18 / (1e4 * cent_wl*cent_wl*1e4*1e4) ;
00655
00656
00657 cent_val = cpl_vector_get(out, cpl_vector_get_size(out)/2) ;
00658 if (cent_val <= 0.0) {
00659 cpl_msg_error(cpl_func, "Negative or 0 central value") ;
00660 cpl_vector_delete(out) ;
00661 return NULL ;
00662 }
00663 cpl_vector_multiply_scalar(out, f0_erg/cent_val) ;
00664
00665
00666 return out ;
00667 }
00668
00669
00679
00680 cpl_bivector * irplib_stdstar_get_sed(
00681 const char * seds_file,
00682 const char * sptype)
00683 {
00684 cpl_table * seds ;
00685 cpl_bivector * out ;
00686 cpl_vector * wave ;
00687 cpl_vector * sed ;
00688 cpl_bivector * tmp ;
00689 int nlines ;
00690
00691
00692 if (seds_file == NULL) return NULL ;
00693 if (sptype == NULL) return NULL ;
00694
00695
00696 if ((seds = cpl_table_load(seds_file, 1, 0)) == NULL) {
00697 cpl_msg_error(cpl_func, "Cannot load the table") ;
00698 return NULL ;
00699 }
00700
00701
00702 if (!cpl_table_has_column(seds, sptype)) {
00703 cpl_msg_error(cpl_func, "SED of the requested star not available") ;
00704 cpl_table_delete(seds) ;
00705 return NULL ;
00706 }
00707
00708
00709 nlines = cpl_table_get_nrow(seds) ;
00710
00711
00712 if ((wave = cpl_vector_wrap(nlines,
00713 cpl_table_get_data_double(seds, "Wavelength"))) == NULL) {
00714 cpl_msg_error(cpl_func, "Cannot get the Wavelength column") ;
00715 cpl_table_delete(seds) ;
00716 return NULL ;
00717 }
00718
00719
00720 if ((sed = cpl_vector_wrap(nlines,
00721 cpl_table_get_data_double(seds, sptype))) == NULL) {
00722 cpl_msg_error(cpl_func, "Cannot get the SED column") ;
00723 cpl_table_delete(seds) ;
00724 cpl_vector_unwrap(wave) ;
00725 return NULL ;
00726 }
00727 tmp = cpl_bivector_wrap_vectors(wave, sed) ;
00728
00729
00730 out = cpl_bivector_duplicate(tmp) ;
00731
00732
00733 cpl_bivector_unwrap_vectors(tmp) ;
00734 cpl_vector_unwrap(wave) ;
00735 cpl_vector_unwrap(sed) ;
00736 cpl_table_delete(seds) ;
00737
00738
00739 return out ;
00740 }
00741
00742
00752
00753 double irplib_stdstar_great_circle_dist(double ra1,
00754 double dec1,
00755 double ra2,
00756 double dec2)
00757 {
00758
00759
00760 const double dra = sin( CPL_MATH_RAD_DEG * (ra2 - ra1 )/2.0 );
00761 const double ddec = sin( CPL_MATH_RAD_DEG * (dec2 - dec1)/2.0 );
00762
00763 dec1 *= CPL_MATH_RAD_DEG;
00764 dec2 *= CPL_MATH_RAD_DEG;
00765
00766 return 2.0 * asin(sqrt( ddec*ddec + cos(dec1)*cos(dec2)*dra*dra))
00767 * CPL_MATH_DEG_RAD;
00768 }