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