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 #include <fors_data.h>
00033
00034 #include <cpl_wcs.h>
00035 #include <fors_star.h>
00036 #include <fors_instrument.h>
00037 #include <fors_std_star.h>
00038 #include <fors_utils.h>
00039
00040 #include <math.h>
00041 #include <stdbool.h>
00042 #include <string.h>
00043
00044
00045 const char *const FORS_DATA_PHOT_FILTER = "FILTER";
00046 const char *const FORS_DATA_PHOT_EXTCOEFF = "EXT";
00047 const char *const FORS_DATA_PHOT_DEXTCOEFF = "DEXT";
00048 const char *const FORS_DATA_PHOT_ZEROPOINT = "ZPOINT";
00049 const char *const FORS_DATA_PHOT_DZEROPOINT = "DZPOINT";
00050 const char *const FORS_DATA_PHOT_COLORTERM = "COL";
00051 const char *const FORS_DATA_PHOT_DCOLORTERM = "DCOL";
00052
00053
00054 #undef cleanup
00055 #define cleanup \
00056 do { \
00057 cpl_wcs_delete(wcs); \
00058 cpl_matrix_delete(from); \
00059 cpl_matrix_delete(to); \
00060 cpl_array_delete(status); \
00061 } while(0)
00062
00067 void
00068 fors_std_star_list_apply_wcs( fors_std_star_list *stars,
00069 const cpl_propertylist *header)
00070 {
00071 cpl_wcs *wcs = NULL;
00072
00073 cpl_matrix *from = NULL;
00074 cpl_matrix *to = NULL;
00075 cpl_array *status = NULL;
00076
00077 cassure_automsg( stars != NULL,
00078 CPL_ERROR_NULL_INPUT,
00079 return);
00080 cassure_automsg( header != NULL,
00081 CPL_ERROR_NULL_INPUT,
00082 return);
00083
00084 if (fors_std_star_list_size(stars) == 0) {
00085 cleanup;
00086 return;
00087 }
00088
00089 wcs = cpl_wcs_new_from_propertylist(header);
00090 assure( !cpl_error_get_code(), return,
00091 "Failed to get WCS from header");
00092
00093 {
00094 fors_std_star *star;
00095 int i;
00096
00097 from = cpl_matrix_new(fors_std_star_list_size(stars), 2);
00098
00099 for (star = fors_std_star_list_first(stars), i = 0;
00100 star != NULL;
00101 star = fors_std_star_list_next(stars), i++) {
00102
00103 cpl_matrix_set(from, i, 0, star->ra);
00104 cpl_matrix_set(from, i, 1, star->dec);
00105 }
00106
00107 cpl_wcs_convert(wcs, from,
00108 &to, &status,
00109 CPL_WCS_WORLD2PHYS);
00110
00111
00112
00113
00114
00115 if (cpl_error_get_code() == CPL_ERROR_UNSPECIFIED) {
00116 cpl_msg_warning(cpl_func,
00117 "Ignoring WCSLIB unspecified error");
00118 cpl_error_reset();
00119 }
00120
00121 assure( !cpl_error_get_code(), return,
00122 "Failed to convert from world to physical coordinates");
00123
00124 assure( cpl_matrix_get_ncol(to) == 2,
00125 return, "%d columns, 2 expected",
00126 cpl_matrix_get_ncol(to));
00127
00128 assure( cpl_matrix_get_nrow(to) == fors_std_star_list_size(stars),
00129 return, "%d rows, %d expected",
00130 cpl_matrix_get_nrow(to), fors_std_star_list_size(stars));
00131
00132 assure( status != NULL, return, NULL );
00133
00134 assure( cpl_array_get_size(status) == fors_std_star_list_size(stars),
00135 return, "Status array size is %d, %d expected",
00136 cpl_array_get_size(status), fors_std_star_list_size(stars));
00137
00138 for (star = fors_std_star_list_first(stars), i = 0;
00139 star != NULL;
00140 star = fors_std_star_list_next(stars), i++) {
00141
00142 if (cpl_array_get_int(status, i, NULL) != 0) {
00143 cpl_msg_warning(cpl_func, "Catalogue star %d: "
00144 "non-zero status = %d from WCSLIB",
00145 i, cpl_array_get_int(status, i, NULL));
00146 }
00147 star->pixel->x = cpl_matrix_get(to, i, 0);
00148 star->pixel->y = cpl_matrix_get(to, i, 1);
00149 }
00150 }
00151
00152 #if 0
00153 double deg_pr_pixel = 0.1/3600;
00154 fors_std_star *star;
00155
00156 cpl_msg_warning(cpl_func,
00157 "WCSLIB not available, "
00158 "applying fake transformation");
00159
00160 for (star = fors_std_star_list_first(stars);
00161 star != NULL;
00162 star = fors_std_star_list_next(stars)) {
00163
00164 star->pixel->x = (star->ra / deg_pr_pixel - 293000)/10;
00165 star->pixel->y = (star->dec / deg_pr_pixel / 10 + 169800)/10;
00166 }
00167 #endif
00168
00169 cleanup;
00170 return;
00171 }
00172
00173
00174 #undef cleanup
00175 #define cleanup \
00176 do { \
00177 cpl_table_delete(t); \
00178 } while (0)
00179
00192 void fors_phot_table_load(const cpl_frame *phot_table_frame,
00193 const fors_setting *setting,
00194 double *color_term,
00195 double *dcolor_term,
00196 double *ext_coeff,
00197 double *dext_coeff,
00198 double *expected_zeropoint,
00199 double *dexpected_zeropoint)
00200 {
00201 cpl_table *t = NULL;
00202
00203 assure( setting != NULL, return, NULL );
00204
00205
00206
00207 assure( phot_table_frame != NULL, return, NULL );
00208
00209
00210
00211
00212 assure( (color_term == NULL) == (dcolor_term == NULL), return, NULL );
00213 assure( (ext_coeff == NULL) == (dext_coeff == NULL), return, NULL );
00214 assure( (expected_zeropoint == NULL) == (dexpected_zeropoint == NULL),
00215 return, NULL );
00216
00217 assure( cpl_frame_get_filename(phot_table_frame) != NULL, return, NULL );
00218
00219 if (color_term) {
00220 *color_term = 0.0;
00221 *dcolor_term = 0.0;
00222 }
00223 if (ext_coeff) {
00224 *ext_coeff = 0.0;
00225 *dext_coeff = 0.0;
00226 }
00227 if (expected_zeropoint) {
00228 *expected_zeropoint = 0.0;
00229 *dexpected_zeropoint = 0.0;
00230 }
00231
00232 if (setting->filter_name == NULL) {
00233 cpl_msg_warning(cpl_func, "Zeropoint computation is not supported "
00234 "for non-standard filters");
00235 return;
00236 }
00237
00238
00239
00240
00241 if (0) {
00242 fors_setting_verify(setting, phot_table_frame, NULL);
00243 assure( !cpl_error_get_code(), return,
00244 "Could not verify %s setting",
00245 cpl_frame_get_filename(phot_table_frame));
00246 }
00247
00248 t = cpl_table_load(cpl_frame_get_filename(phot_table_frame), 1, 1);
00249
00250 assure( !cpl_error_get_code(), return, "Could not load %s",
00251 cpl_frame_get_filename(phot_table_frame));
00252
00253 assure( cpl_table_get_nrow(t) > 0, return,
00254 "Empty table %s", cpl_frame_get_filename(phot_table_frame));
00255
00256 {
00257 const char *const colname[] = {
00258 FORS_DATA_PHOT_FILTER,
00259 FORS_DATA_PHOT_EXTCOEFF,
00260 FORS_DATA_PHOT_DEXTCOEFF,
00261 FORS_DATA_PHOT_ZEROPOINT,
00262 FORS_DATA_PHOT_DZEROPOINT,
00263 FORS_DATA_PHOT_COLORTERM,
00264 FORS_DATA_PHOT_DCOLORTERM};
00265
00266 const cpl_type coltype[] = {CPL_TYPE_STRING,
00267 CPL_TYPE_DOUBLE,
00268 CPL_TYPE_DOUBLE,
00269 CPL_TYPE_DOUBLE,
00270 CPL_TYPE_DOUBLE,
00271 CPL_TYPE_DOUBLE,
00272 CPL_TYPE_DOUBLE};
00273
00274 int colrequired[7];
00275
00276 colrequired[0] = 1;
00277 colrequired[1] = ext_coeff ? 1 : 0;
00278 colrequired[2] = ext_coeff ? 1 : 0;
00279 colrequired[3] = expected_zeropoint ? 1 : 0;
00280 colrequired[4] = expected_zeropoint ? 1 : 0;
00281 colrequired[5] = color_term ? 1 : 0;
00282 colrequired[6] = color_term ? 1 : 0;
00283
00284 unsigned i;
00285 for (i = 0; i < sizeof(colname) / sizeof(*colname); i++) {
00286
00287 if (colrequired[i]) {
00288 assure( cpl_table_has_column(t, colname[i]), return,
00289 "%s: Missing column %s",
00290 cpl_frame_get_filename(phot_table_frame), colname[i]);
00291
00292 assure( cpl_table_get_column_type(t, colname[i]) == coltype[i],
00293 return,
00294 "%s column %s type is %s, %s expected",
00295 cpl_frame_get_filename(phot_table_frame),
00296 colname[i],
00297 fors_type_get_string(cpl_table_get_column_type(t,
00298 colname[i])),
00299 fors_type_get_string(coltype[i]));
00300
00301 assure( cpl_table_count_invalid(t, colname[i]) == 0, return,
00302 "%s column %s has invalid values",
00303 cpl_frame_get_filename(phot_table_frame),
00304 colname[i]);
00305 }
00306 }
00307 }
00308
00309
00310 cpl_msg_debug(cpl_func, "Searching for filter: %s", setting->filter_name);
00311
00312 bool found = false;
00313 int i;
00314 for (i = 0; i < cpl_table_get_nrow(t) && !found; i++) {
00315 const char *phot_filter = cpl_table_get_string(t, FORS_DATA_PHOT_FILTER, i);
00316
00317 assure( phot_filter != NULL, return, "%s, row %d: Null %s",
00318 cpl_frame_get_filename(phot_table_frame), i+1, FORS_DATA_PHOT_FILTER);
00319
00320 if (strcmp(setting->filter_name, phot_filter) == 0) {
00321
00322 found = true;
00323
00324 if (color_term != NULL) {
00325 *color_term = cpl_table_get_double(t, FORS_DATA_PHOT_COLORTERM, i, NULL);
00326 *dcolor_term = cpl_table_get_double(t, FORS_DATA_PHOT_DCOLORTERM, i, NULL);
00327 }
00328
00329 if (ext_coeff != NULL) {
00330 *ext_coeff = cpl_table_get_double(t, FORS_DATA_PHOT_EXTCOEFF, i, NULL);
00331 *dext_coeff = cpl_table_get_double(t, FORS_DATA_PHOT_DEXTCOEFF, i, NULL);
00332 }
00333
00334 if (expected_zeropoint != NULL) {
00335 *expected_zeropoint =
00336 cpl_table_get_double(t, FORS_DATA_PHOT_ZEROPOINT, i, NULL);
00337 *dexpected_zeropoint =
00338 cpl_table_get_double(t, FORS_DATA_PHOT_DZEROPOINT, i, NULL);
00339 }
00340 }
00341 }
00342
00343 if (found == false) {
00344 cpl_msg_warning(cpl_func, "Entry for filter %s missing in input "
00345 "photometric table (%s): assuming all photometric "
00346 "coefficients Z, E, and color term, equal to zero.",
00347 setting->filter_name,
00348 cpl_frame_get_filename(phot_table_frame));
00349 *color_term = 0.0;
00350 *dcolor_term = 0.0;
00351 *ext_coeff = 0.0;
00352 *dext_coeff = 0.0;
00353 *expected_zeropoint = 0.0;
00354 *dexpected_zeropoint = 0.0;
00355 }
00356
00357
00358
00359
00360
00361
00362 cleanup;
00363 return;
00364 }
00365
00366
00367 #undef cleanup
00368 #define cleanup \
00369 do { \
00370 cpl_table_delete(table); \
00371 } while(0)
00372
00389 cpl_table *fors_phot_coeff_create(const fors_setting *setting,
00390 double color_term,
00391 double dcolor_term,
00392 double ext_coeff,
00393 double dext_coeff,
00394 double zeropoint,
00395 double dzeropoint)
00396 {
00397 cpl_table *table = cpl_table_new(1);
00398
00399 if (table == NULL) {
00400 return NULL;
00401 }
00402
00403 if (dcolor_term > 0.0 || dext_coeff > 0.0 || dzeropoint > 0.0) {
00404 cpl_table_new_column(table, FORS_DATA_PHOT_FILTER, CPL_TYPE_STRING);
00405 cpl_table_set_string(table, FORS_DATA_PHOT_FILTER,
00406 0, setting->filter_name);
00407 }
00408 else {
00409 cleanup;
00410 return NULL;
00411 }
00412
00413
00414
00415
00416
00417 if (dext_coeff > 0.0) {
00418 cpl_table_new_column(table, FORS_DATA_PHOT_EXTCOEFF, CPL_TYPE_DOUBLE);
00419 cpl_table_new_column(table, FORS_DATA_PHOT_DEXTCOEFF, CPL_TYPE_DOUBLE);
00420 cpl_table_set_double(table, FORS_DATA_PHOT_EXTCOEFF, 0, ext_coeff);
00421 cpl_table_set_double(table, FORS_DATA_PHOT_DEXTCOEFF, 0, dext_coeff);
00422 }
00423
00424 if (dzeropoint > 0.0) {
00425 cpl_table_new_column(table, FORS_DATA_PHOT_ZEROPOINT, CPL_TYPE_DOUBLE);
00426 cpl_table_new_column(table, FORS_DATA_PHOT_DZEROPOINT, CPL_TYPE_DOUBLE);
00427 cpl_table_set_double(table, FORS_DATA_PHOT_ZEROPOINT, 0, zeropoint);
00428 cpl_table_set_double(table, FORS_DATA_PHOT_DZEROPOINT, 0, dzeropoint);
00429 }
00430
00431 if (dcolor_term > 0.0) {
00432 cpl_table_new_column(table, FORS_DATA_PHOT_COLORTERM, CPL_TYPE_DOUBLE);
00433 cpl_table_new_column(table, FORS_DATA_PHOT_DCOLORTERM, CPL_TYPE_DOUBLE);
00434 cpl_table_set_double(table, FORS_DATA_PHOT_COLORTERM, 0, color_term);
00435 cpl_table_set_double(table, FORS_DATA_PHOT_DCOLORTERM, 0, dcolor_term);
00436 }
00437
00438 return table;
00439 }