FORS Pipeline Reference Manual 4.9.20
|
00001 /* $Id: fors_data.c,v 1.43 2010/09/14 07:49:30 cizzo Exp $ 00002 * 00003 * This file is part of the FORS Library 00004 * Copyright (C) 2002-2010 European Southern Observatory 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 /* 00022 * $Author: cizzo $ 00023 * $Date: 2010/09/14 07:49:30 $ 00024 * $Revision: 1.43 $ 00025 * $Name: fors-4_9_20 $ 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 /* The WCSLIB call sometimes fails with the error message 00112 "WCSLIB One or more input coordinates invalid", 00113 while all status flags are 0. 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 /* pre WCSLIB code */ 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 assure( setting->filter_name != NULL, return, "No filter name provided"); 00206 */ 00207 assure( phot_table_frame != NULL, return, NULL ); 00208 /* color_term may be NULL */ 00209 /* assure( ext_coeff != NULL, return, NULL ); it may also be NULL (Carlo) */ 00210 /* expected_zeropoint may be NULL */ 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 /* Verify instrument setting */ 00239 //fixme: for user-friendliness we should verify the setting, except the filter 00240 // (because this table contains data for all filters) 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]; /* same # of elements as above */ 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 /* Input validation done */ 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 assure( found, return, "%s: Missing entry for filter '%s'", 00359 cpl_frame_get_filename(phot_table_frame), setting->filter_name); 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 * Create only the necessary columns for the new table 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 }