36 #include "irplib_stdstar.h"
37 #include "irplib_utils.h"
38 #include "irplib_wcs.h"
49 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(6, 3, 0)
50 #define IRPLIB_FRAMESET_GET_CONST cpl_frameset_get_position_const
53 #define IRPLIB_FRAMESET_GET_CONST cpl_frameset_get_frame_const
90 const cpl_frameset * set_raw,
91 const char * recipe_name,
93 const char * pro_type,
94 const char * package_name,
95 const char * ins_name,
96 cpl_table * (*convert_ascii_table)(
const char *))
99 const cpl_size nb_catalogs = cpl_frameset_get_size(set_raw);
100 cpl_propertylist * plist_ext;
102 cpl_error_code error = CPL_ERROR_NONE;
106 if (set_in == NULL)
return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
107 if (set_raw == NULL)
return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
108 if (recipe_name == NULL)
return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
109 if (pro_cat == NULL)
return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
110 if (ins_name == NULL)
return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
111 if (convert_ascii_table == NULL)
return
112 cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
115 out_name = cpl_sprintf(
"%s" CPL_DFS_FITS, recipe_name);
117 plist_ext = cpl_propertylist_new();
120 for (i = 0; i < nb_catalogs; i++) {
122 const cpl_frame * cur_frame = IRPLIB_FRAMESET_GET_CONST(set_raw, i);
123 const char * cat_name = cpl_frame_get_filename(cur_frame);
125 cpl_table * out = convert_ascii_table(cat_name);
129 error = cpl_error_get_code() ? cpl_error_set_where(cpl_func)
130 : cpl_error_set(cpl_func, CPL_ERROR_UNSPECIFIED);
134 if (cpl_table_get_nrow(out) == 0) {
135 cpl_table_delete(out);
136 error = cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
137 "Empty catalogue %d in '%s'",
142 cpl_propertylist_update_string(plist_ext,
"EXTNAME", cat_name);
146 cpl_parameterlist * parlist = cpl_parameterlist_new();
147 cpl_propertylist * plist = cpl_propertylist_new();
150 cpl_propertylist_append_string(plist,
"INSTRUME", ins_name);
151 cpl_propertylist_append_string(plist, CPL_DFS_PRO_CATG, pro_cat);
152 if (pro_type != NULL) {
153 cpl_propertylist_append_string(plist, CPL_DFS_PRO_TYPE,
157 error = cpl_dfs_save_table(set_in, NULL, parlist, set_raw, NULL,
158 out, plist_ext, recipe_name, plist,
159 NULL, package_name, out_name);
160 cpl_parameterlist_delete(parlist);
161 cpl_propertylist_delete(plist);
163 error = cpl_table_save(out, NULL, plist_ext, out_name,
167 cpl_table_delete(out);
170 (void)cpl_error_set_where(cpl_func);
175 cpl_propertylist_delete(plist_ext);
196 const char * filename,
197 const char * ext_name)
202 cpl_frame * cur_frame;
206 if (filename == NULL)
return NULL;
207 if (ext_name == NULL)
return NULL;
213 cur_frame = cpl_frame_new();
214 cpl_frame_set_filename(cur_frame, filename);
215 next = cpl_frame_get_nextensions(cur_frame);
216 cpl_frame_delete(cur_frame);
219 for (i=0; i<next; i++) {
220 cpl_propertylist * plist;
221 const char * cur_name;
224 if ((plist = cpl_propertylist_load_regexp(filename, i+1,
"EXTNAME",
226 cpl_msg_error(cpl_func,
"Cannot load header of %d th extension",
230 cur_name = cpl_propertylist_get_string(plist,
"EXTNAME");
233 if (!strcmp(cur_name, ext_name)) {
236 out = cpl_table_load(filename, i+1, 1);
237 cpl_table_new_column(out, IRPLIB_STDSTAR_CAT_COL, CPL_TYPE_STRING);
238 cpl_table_fill_column_window_string(out, IRPLIB_STDSTAR_CAT_COL,
239 0, cpl_table_get_nrow(out),
242 cpl_msg_error(cpl_func,
"Cannot load extension %d", i+1);
243 cpl_propertylist_delete(plist);
247 }
else if (!strcmp(ext_name,
"all")) {
251 out = cpl_table_load(filename, i+1, 1);
252 cpl_table_new_column(out, IRPLIB_STDSTAR_CAT_COL, CPL_TYPE_STRING);
253 cpl_table_fill_column_window_string(out, IRPLIB_STDSTAR_CAT_COL,
254 0, cpl_table_get_nrow(out),
257 cpl_msg_error(cpl_func,
"Cannot load extension %d", i+1);
258 cpl_propertylist_delete(plist);
263 out_cur = cpl_table_load(filename, i+1, 1);
264 if (out_cur == NULL) {
265 cpl_msg_error(cpl_func,
"Cannot load extension %d", i+1);
266 cpl_table_delete(out);
267 cpl_propertylist_delete(plist);
270 cpl_table_new_column(out_cur, IRPLIB_STDSTAR_CAT_COL, CPL_TYPE_STRING);
271 cpl_table_fill_column_window_string(out_cur, IRPLIB_STDSTAR_CAT_COL,
272 0, cpl_table_get_nrow(out_cur),
275 if (cpl_table_insert(out, out_cur,
276 cpl_table_get_nrow(out)) != CPL_ERROR_NONE) {
277 cpl_msg_error(cpl_func,
"Cannot merge table %d", i+1);
278 cpl_table_delete(out);
279 cpl_table_delete(out_cur);
280 cpl_propertylist_delete(plist);
283 cpl_table_delete(out_cur);
286 cpl_propertylist_delete(plist);
302 const cpl_table * catal)
305 if (!cpl_table_has_column(catal, IRPLIB_STDSTAR_STAR_COL)) {
306 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
307 "Missing column: %s",
308 IRPLIB_STDSTAR_STAR_COL);
310 if (!cpl_table_has_column(catal, IRPLIB_STDSTAR_TYPE_COL)) {
311 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
312 "Missing column: %s",
313 IRPLIB_STDSTAR_TYPE_COL);
315 if (!cpl_table_has_column(catal, IRPLIB_STDSTAR_CAT_COL)) {
316 return cpl_error_set_message(cpl_func,
317 CPL_ERROR_ILLEGAL_INPUT,
318 "Missing column: %s",
319 IRPLIB_STDSTAR_CAT_COL);
321 if (!cpl_table_has_column(catal, IRPLIB_STDSTAR_RA_COL)) {
322 return cpl_error_set_message(cpl_func,
323 CPL_ERROR_ILLEGAL_INPUT,
324 "Missing column: %s",
325 IRPLIB_STDSTAR_RA_COL);
327 if (!cpl_table_has_column(catal, IRPLIB_STDSTAR_DEC_COL)) {
328 return cpl_error_set_message(cpl_func,
329 CPL_ERROR_ILLEGAL_INPUT,
330 "Missing column: %s",
331 IRPLIB_STDSTAR_DEC_COL);
333 return CPL_ERROR_NONE;
360 if (cat == NULL)
return -1;
363 nrows = cpl_table_get_nrow(cat);
366 if (!cpl_table_has_column(cat, IRPLIB_STDSTAR_RA_COL)) {
367 cpl_msg_error(cpl_func,
"Missing %s column", IRPLIB_STDSTAR_RA_COL);
370 if (!cpl_table_has_column(cat, IRPLIB_STDSTAR_DEC_COL)) {
371 cpl_msg_error(cpl_func,
"Missing %s column", IRPLIB_STDSTAR_DEC_COL);
376 for (i=0; i<nrows; i++) {
377 if (cpl_table_is_selected(cat, i)) {
379 distance = irplib_wcs_great_circle_dist(ra, dec,
380 cpl_table_get_double(cat, IRPLIB_STDSTAR_RA_COL, i, NULL),
381 cpl_table_get_double(cat, IRPLIB_STDSTAR_DEC_COL, i, NULL));
382 if (distance > dist) cpl_table_unselect_row(cat, i);
400 const char * mag_colname)
403 if (cat == NULL)
return -1;
404 if (mag_colname == NULL)
return -1;
407 if (!cpl_table_has_column(cat, mag_colname)) {
408 cpl_msg_error(cpl_func,
"Column %s does not exist in the catalog",
414 if (cpl_table_and_selected_double(cat, mag_colname, CPL_NOT_GREATER_THAN,
416 cpl_msg_error(cpl_func,
"Column %s does not exist in the catalog",
435 const cpl_table * cat,
439 double min_dist, distance;
445 if (cat == NULL)
return -1;
452 nrows = cpl_table_get_nrow(cat);
455 if (!cpl_table_has_column(cat, IRPLIB_STDSTAR_RA_COL)) {
456 cpl_msg_error(cpl_func,
"Missing %s column", IRPLIB_STDSTAR_RA_COL);
459 if (!cpl_table_has_column(cat, IRPLIB_STDSTAR_DEC_COL)) {
460 cpl_msg_error(cpl_func,
"Missing %s column", IRPLIB_STDSTAR_DEC_COL);
465 for (i=0; i<nrows; i++) {
466 if (cpl_table_is_selected(cat, i)) {
468 distance = irplib_wcs_great_circle_dist(ra, dec,
469 cpl_table_get_double(cat, IRPLIB_STDSTAR_RA_COL, i, NULL),
470 cpl_table_get_double(cat, IRPLIB_STDSTAR_DEC_COL, i, NULL));
471 if (distance <= min_dist) {
503 const char * catfile,
507 const char * catname,
516 cpl_errorstate prestate = cpl_errorstate_get();
518 const double dist = dist_am / 60.0;
522 if (catfile == NULL)
return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
523 if (band == NULL)
return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
524 if (catname == NULL)
return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
528 return cpl_error_set_message(cpl_func, CPL_ERROR_FILE_NOT_FOUND,
529 "Cannot load the catalog %s from %s",
535 cpl_table_delete(catal);
536 return cpl_error_set_where(cpl_func);
541 cpl_table_delete(catal);
542 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
543 "Cannot select stars in that band");
548 cpl_table_delete(catal);
549 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
550 "Cannot select close stars");
555 cpl_table_delete(catal);
556 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
557 "Cannot get the closest star with "
558 "known %s magnitude",band);
562 *mag = cpl_table_get_double(catal, band, ind, NULL);
566 *name = cpl_strdup(cpl_table_get_string(catal,
567 IRPLIB_STDSTAR_STAR_COL, ind));
572 *type = cpl_strdup(cpl_table_get_string(catal, IRPLIB_STDSTAR_TYPE_COL,
575 if(usedcatname != NULL)
577 if(strcmp(catname,
"all"))
578 *usedcatname = cpl_strdup(catname);
581 *usedcatname = cpl_strdup(cpl_table_get_string
582 (catal, IRPLIB_STDSTAR_CAT_COL, ind));
586 *star_ra = cpl_table_get_double(catal, IRPLIB_STDSTAR_RA_COL, ind, NULL);
588 *star_dec = cpl_table_get_double(catal, IRPLIB_STDSTAR_DEC_COL, ind, NULL);
591 cpl_table_delete(catal);
592 return cpl_errorstate_is_equal(prestate) ? CPL_ERROR_NONE
593 : cpl_error_set_where(cpl_func);
611 const cpl_bivector * spec,
619 const cpl_vector * wave;
620 const cpl_vector * extr;
625 if (spec == NULL)
return NULL;
626 if (dit <= 0.0)
return NULL;
629 wave = cpl_bivector_get_x_const(spec);
630 extr = cpl_bivector_get_y_const(spec);
633 out = cpl_vector_duplicate(extr);
636 cpl_vector_divide_scalar(out, dit);
639 cpl_vector_divide_scalar(out, surface);
642 cpl_vector_multiply_scalar(out, gain);
645 factor = pow(10, mag/2.5);
646 cpl_vector_multiply_scalar(out, factor);
649 factor = (cpl_vector_get(wave, cpl_vector_get_size(wave)-1) -
650 cpl_vector_get(wave, 0)) / cpl_vector_get_size(wave);
651 cpl_vector_divide_scalar(out, factor);
654 cpl_vector_multiply_scalar(out, h*c);
655 cpl_vector_divide(out, wave);
670 const cpl_bivector * sed,
671 const cpl_vector * waves,
674 double wmin, wmax, wstep;
676 const double * sed_x;
677 const double * sed_y;
678 cpl_bivector * sed_loc;
682 cpl_bivector * out_biv;
683 double f0_jan, f0_erg, cent_val;
687 if (sed == NULL)
return NULL;
688 if (waves == NULL)
return NULL;
691 nb_sed = cpl_bivector_get_size(sed);
692 sed_x = cpl_bivector_get_x_data_const(sed);
693 sed_y = cpl_bivector_get_y_data_const(sed);
694 wstep = sed_x[1] - sed_x[0];
695 wmin = cpl_vector_get(waves, 0);
696 wmax = cpl_vector_get(waves, cpl_vector_get_size(waves)-1);
699 sed_loc = cpl_bivector_new(nb_sed + 4);
700 sed_loc_x = cpl_bivector_get_x_data(sed_loc);
701 sed_loc_y = cpl_bivector_get_y_data(sed_loc);
702 for (i=0; i<nb_sed; i++) {
703 sed_loc_x[i+2] = sed_x[i];
704 sed_loc_y[i+2] = sed_y[i];
708 sed_loc_x[1] = sed_loc_x[2] - wstep;
709 if (sed_loc_x[2] < wmin) {
710 sed_loc_x[0] = sed_loc_x[1] - wstep;
712 sed_loc_x[0] = wmin - wstep;
714 sed_loc_y[0] = 1e-20;
715 sed_loc_y[1] = 1e-20;
718 sed_loc_x[nb_sed+2] = sed_loc_x[nb_sed+1] + wstep;
719 if (sed_loc_x[nb_sed+1] > wmax) {
720 sed_loc_x[nb_sed+3] = sed_loc_x[nb_sed+2] + wstep;
722 sed_loc_x[nb_sed+3] = wmax + wstep;
724 sed_loc_y[nb_sed+2] = 1e-20;
725 sed_loc_y[nb_sed+3] = 1e-20;
728 out = cpl_vector_duplicate(waves);
729 IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
731 out_biv = cpl_bivector_wrap_vectors((cpl_vector*)waves, out);
732 IRPLIB_DIAG_PRAGMA_POP;
734 if (cpl_bivector_interpolate_linear(out_biv, sed_loc) != CPL_ERROR_NONE) {
735 cpl_msg_error(cpl_func,
"Cannot interpolate the wavelength");
736 cpl_bivector_unwrap_vectors(out_biv);
737 cpl_vector_delete(out);
738 cpl_bivector_delete(sed_loc);
741 cpl_bivector_unwrap_vectors(out_biv);
742 cpl_bivector_delete(sed_loc);
745 f0_jan = 5513.15 / ( pow(cent_wl,3) * (exp(1.2848/cent_wl)-1) );
748 f0_erg = f0_jan * 1e-26 * 1e7 * 3e18 / (1e4 * cent_wl*cent_wl*1e4*1e4);
751 cent_val = cpl_vector_get(out, cpl_vector_get_size(out)/2);
752 if (cent_val <= 0.0) {
753 cpl_msg_error(cpl_func,
"Negative or 0 central value");
754 cpl_vector_delete(out);
757 cpl_vector_multiply_scalar(out, f0_erg/cent_val);
775 const char * seds_file,
786 if (seds_file == NULL)
return NULL;
787 if (sptype == NULL)
return NULL;
790 if ((seds = cpl_table_load(seds_file, 1, 0)) == NULL) {
791 cpl_msg_error(cpl_func,
"Cannot load the table");
796 if (!cpl_table_has_column(seds, sptype)) {
797 cpl_msg_error(cpl_func,
"SED of the requested star not available");
798 cpl_table_delete(seds);
803 nlines = cpl_table_get_nrow(seds);
806 if ((wave = cpl_vector_wrap(nlines,
807 cpl_table_get_data_double(seds,
"Wavelength"))) == NULL) {
808 cpl_msg_error(cpl_func,
"Cannot get the Wavelength column");
809 cpl_table_delete(seds);
814 if ((sed = cpl_vector_wrap(nlines,
815 cpl_table_get_data_double(seds, sptype))) == NULL) {
816 cpl_msg_error(cpl_func,
"Cannot get the SED column");
817 cpl_table_delete(seds);
818 cpl_vector_unwrap(wave);
821 tmp = cpl_bivector_wrap_vectors(wave, sed);
824 out = cpl_bivector_duplicate(tmp);
827 cpl_bivector_unwrap_vectors(tmp);
828 cpl_vector_unwrap(wave);
829 cpl_vector_unwrap(sed);
830 cpl_table_delete(seds);
cpl_vector * irplib_stdstar_get_conversion(const cpl_bivector *spec, double dit, double surface, double gain, double mag)
Get the conversion.
cpl_error_code irplib_stdstar_check_columns_exist(const cpl_table *catal)
Check that the table has the relevant columns of a stdstar table.
int irplib_stdstar_select_stars_dist(cpl_table *cat, double ra, double dec, double dist)
Select the stars that are within a given distance.
int irplib_stdstar_find_closest(const cpl_table *cat, double ra, double dec)
Find the closest star.
cpl_vector * irplib_stdstar_get_mag_zero(const cpl_bivector *sed, const cpl_vector *waves, double cent_wl)
Get the 0 magnitude spectrum.
cpl_bivector * irplib_stdstar_get_sed(const char *seds_file, const char *sptype)
Get the SED.
int irplib_stdstar_select_stars_mag(cpl_table *cat, const char *mag_colname)
Select the stars that have a known magnitude.
cpl_error_code irplib_stdstar_write_catalogs(cpl_frameset *set_in, const cpl_frameset *set_raw, const char *recipe_name, const char *pro_cat, const char *pro_type, const char *package_name, const char *ins_name, cpl_table *(*convert_ascii_table)(const char *))
Write the ASCII catalogs as FITS files.
cpl_table * irplib_stdstar_load_catalog(const char *filename, const char *ext_name)
Load the FITS catalog in a table.
cpl_error_code irplib_stdstar_find_star(const char *catfile, double ra, double dec, const char *band, const char *catname, double *mag, char **name, char **type, char **usedcatname, double *star_ra, double *star_dec, double dist_am)
Find the closest star to ra, dec in the catalog.