FORS Pipeline Reference Manual 4.9.20
|
00001 /* $Id: fors_std_cat.c,v 1.19 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.19 $ 00025 * $Name: fors-4_9_20 $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 #include <fors_std_star.h> 00033 #include <fors_utils.h> 00034 #include <fors_instrument.h> 00035 00036 #include <math.h> 00037 #include <stdbool.h> 00038 #include <string.h> 00039 00040 const char *const FORS_STD_CAT_COLUMN_RA = "RA"; 00041 const char *const FORS_STD_CAT_COLUMN_DEC = "DEC"; 00042 const char *const FORS_STD_CAT_COLUMN_NAME = "OBJECT"; 00043 00044 typedef struct band_jacobian { 00045 char band; 00046 double mag[6]; /* 5 inputs, 1 constant */ 00047 double col[6]; /* 5 inputs, 1 constant */ 00048 } band_jacobian; 00049 00050 static void 00051 fors_std_cat_propagate_uncorrelated_inputs( const double *in, 00052 const double *din, 00053 const double *jacobi_A, 00054 const double *jacobi_B, 00055 int size, 00056 double *out_A, 00057 double *out_B, 00058 double *dout_A, 00059 double *dout_B, 00060 double *cov_AB); 00061 00062 static cpl_error_code 00063 fors_std_cat_import_generic_star( const double *band_values, 00064 const double *band_errors, 00065 const band_jacobian *jacobians, 00066 int nband_values, 00067 int nbands, 00068 char band, 00069 double *cat_mag, 00070 double *dcat_mag, 00071 double *color, 00072 double *dcolor, 00073 double *cov_catmag_color); 00074 00075 static bool 00076 fors_std_cat_check_band_support( cpl_error_code (*import_func)( 00077 double *values, 00078 double *errors, 00079 char band, 00080 double *out_A, 00081 double *dout_A, 00082 double *out_B, 00083 double *dout_B, 00084 double *out_cov), 00085 int nvalues, 00086 char band); 00087 00088 static bool* 00089 fors_std_cat_determine_required_columns( cpl_error_code (*import_func)( 00090 double *values, 00091 double *errors, 00092 char band, 00093 double *out_A, 00094 double *dout_A, 00095 double *out_B, 00096 double *dout_B, 00097 double *out_cov), 00098 int nvalues, 00099 char band); 00100 00101 static cpl_error_code 00102 fors_std_cat_reject_not_required_columns( cpl_array *column_names, 00103 cpl_error_code (*import_func)( 00104 double *values, 00105 double *errors, 00106 char band, 00107 double *out_A, 00108 double *dout_A, 00109 double *out_B, 00110 double *dout_B, 00111 double *out_cov), 00112 char band); 00113 00114 static bool 00115 fors_std_cat_table_check_columns( const cpl_table *cat_table, 00116 const cpl_array *columns); 00117 00118 static cpl_array * 00119 fors_std_cat_create_error_column_names( const cpl_array *colnames); 00120 00121 static cpl_error_code 00122 fors_std_cat_landolt_star_import( double v_bv_ub_vr_vi[5], 00123 double ERR_v_bv_ub_vr_vi[5], 00124 char band, 00125 double *cat_mag, 00126 double *dcat_mag, 00127 double *color, 00128 double *dcolor, 00129 double *cov_catmag_color); 00130 00131 static cpl_array * 00132 fors_std_cat_landolt_get_column_names( void); 00133 00134 static cpl_error_code 00135 fors_std_cat_stetson_star_import( double u_b_v_r_i[5], 00136 double ERR_u_b_v_r_i[5], 00137 char band, 00138 double *cat_mag, 00139 double *dcat_mag, 00140 double *color, 00141 double *dcolor, 00142 double *cov_catmag_color); 00143 00144 static cpl_array * 00145 fors_std_cat_stetson_get_column_names( void); 00146 00147 static bool 00148 fors_std_cat_check_method_and_columns( cpl_table *catalogue, 00149 cpl_array *colnames, 00150 cpl_error_code (*import_func)( 00151 double *values, 00152 double *errors, 00153 char band, 00154 double *out_A, 00155 double *dout_A, 00156 double *out_B, 00157 double *dout_B, 00158 double *out_cov), 00159 char band, 00160 const char *method, 00161 cpl_array **err_colnames, 00162 bool *method_supports_band); 00163 00164 #undef cleanup 00165 #define cleanup 00166 00180 static void 00181 fors_std_cat_propagate_uncorrelated_inputs( const double *in, 00182 const double *din, 00183 const double *jacobi_A, 00184 const double *jacobi_B, 00185 int size, 00186 double *out_A, 00187 double *out_B, 00188 double *dout_A, 00189 double *dout_B, 00190 double *cov_AB) 00191 { 00192 int n; 00193 00194 *out_A = 0; 00195 *out_B = 0; 00196 *dout_A = 0; 00197 *dout_B = 0; 00198 *cov_AB = 0; 00199 00200 for (n = 0; n < size; n++) 00201 { 00202 /* uncorrelated inputs are assumed! */ 00203 *out_A += (*jacobi_A) * (*in); 00204 *out_B += (*jacobi_B) * (*in); 00205 *dout_A += (*jacobi_A)*(*jacobi_A) * (*din)*(*din); 00206 *dout_B += (*jacobi_B)*(*jacobi_B) * (*din)*(*din); 00207 *cov_AB += (*jacobi_A)*(*jacobi_B) * (*din)*(*din); 00208 jacobi_A++; 00209 jacobi_B++; 00210 in++; 00211 din++; 00212 } 00213 00214 *dout_A = sqrt(*dout_A); 00215 *dout_B = sqrt(*dout_B); 00216 } 00217 00218 #undef cleanup 00219 #define cleanup 00220 00247 static cpl_error_code 00248 fors_std_cat_import_generic_star( const double *band_values, 00249 const double *band_errors, 00250 const band_jacobian *jacobians, 00251 int nband_values, 00252 int nbands, 00253 char band, 00254 double *cat_mag, 00255 double *dcat_mag, 00256 double *color, 00257 double *dcolor, 00258 double *cov_catmag_color) 00259 { 00260 int ib; 00261 for (ib = 0; ib <= nbands; ib++) 00262 { 00263 if (jacobians[ib].band == band) 00264 { 00265 fors_std_cat_propagate_uncorrelated_inputs( 00266 band_values, 00267 band_errors, 00268 jacobians[ib].mag, 00269 jacobians[ib].col, 00270 nband_values, 00271 cat_mag, 00272 color, 00273 dcat_mag, 00274 dcolor, 00275 cov_catmag_color); 00276 /* constant term */ 00277 *cat_mag += jacobians[ib].mag[nband_values]; 00278 *color += jacobians[ib].col[nband_values]; 00279 00280 return CPL_ERROR_NONE; 00281 } 00282 } 00283 00284 cpl_error_set_message( cpl_func, 00285 CPL_ERROR_UNSUPPORTED_MODE, 00286 "unknown band \'%c\'", 00287 band); 00288 return cpl_error_get_code(); 00289 } 00290 00291 #undef cleanup 00292 #define cleanup \ 00293 do { \ 00294 cpl_free(values); values = NULL; \ 00295 cpl_free(errors); errors = NULL; \ 00296 } while (0) 00297 00304 static bool 00305 fors_std_cat_check_band_support( cpl_error_code (*import_func)( 00306 double *values, 00307 double *errors, 00308 char band, 00309 double *out_A, 00310 double *dout_A, 00311 double *out_B, 00312 double *dout_B, 00313 double *out_cov), 00314 int nvalues, 00315 char band) 00316 { 00317 double *values = NULL, 00318 *errors = NULL; 00319 double out[5]; 00320 cpl_errorstate errstat = cpl_errorstate_get(); 00321 00322 00323 values = cpl_calloc(nvalues, sizeof(*values)); 00324 errors = cpl_calloc(nvalues, sizeof(*errors)); 00325 (*import_func)( values, errors, band, 00326 out + 0, out + 1, out + 2, out + 3, out + 4); 00327 cpl_free(values); 00328 cpl_free(errors); 00329 00330 if (!cpl_errorstate_is_equal(errstat)) 00331 { 00332 if (cpl_error_get_code() == CPL_ERROR_UNSUPPORTED_MODE) 00333 { 00334 cpl_errorstate_set(errstat); /* reset error */ 00335 } 00336 else 00337 { 00338 cpl_error_set_where(cpl_func); 00339 } 00340 return false; 00341 } 00342 else 00343 return true; 00344 } 00345 00346 #undef cleanup 00347 #define cleanup \ 00348 do { \ 00349 cpl_free(required); required = NULL; \ 00350 cpl_free(values); values = NULL; \ 00351 cpl_free(errors); errors = NULL; \ 00352 } while (0) 00353 00364 static bool* 00365 fors_std_cat_determine_required_columns( cpl_error_code (*import_func)( 00366 double *values, 00367 double *errors, 00368 char band, 00369 double *out_A, 00370 double *dout_A, 00371 double *out_B, 00372 double *dout_B, 00373 double *out_cov), 00374 int nvalues, 00375 char band) 00376 { 00377 bool *required = NULL; 00378 double *values = NULL, 00379 *errors = NULL; 00380 double out_offset[5]; 00381 int n; 00382 cpl_errorstate errstat = cpl_errorstate_get(); 00383 00384 values = cpl_calloc(nvalues, sizeof(*values)); 00385 errors = cpl_calloc(nvalues, sizeof(*errors)); 00386 required = cpl_calloc(nvalues, sizeof(*required)); 00387 00388 /* get offset output values @ all inputs = 0.0 */ 00389 (*import_func)( values, 00390 errors, 00391 band, 00392 out_offset + 0, 00393 out_offset + 1, 00394 out_offset + 2, 00395 out_offset + 3, 00396 out_offset + 4); 00397 00398 /* successively switch on inputs 00399 * (here we assume of course that they contribute independently) */ 00400 for (n = 0; n < nvalues; n++) 00401 { 00402 double out[5]; 00403 int i; 00404 00405 values[n] = 1; 00406 errors[n] = 1; 00407 if (n > 0) 00408 { 00409 values[n-1] = 0; 00410 errors[n-1] = 0; 00411 } 00412 00413 (*import_func)( values, 00414 errors, 00415 band, 00416 out + 0, 00417 out + 1, 00418 out + 2, 00419 out + 3, 00420 out + 4); 00421 if (!cpl_errorstate_is_equal(errstat)) 00422 { 00423 cpl_error_set_where(cpl_func); 00424 cleanup; 00425 return required; 00426 } 00427 00428 for (i = 0; i < 5; i++) 00429 if (fabs(out[i] - out_offset[i]) > 10*DBL_EPSILON) 00430 required[n] = true; 00431 } 00432 00433 cpl_free(values); 00434 cpl_free(errors); 00435 00436 return required; 00437 } 00438 00439 #undef cleanup 00440 #define cleanup \ 00441 do { \ 00442 cpl_free(required); required = NULL; \ 00443 } while (0) 00444 00451 static cpl_error_code 00452 fors_std_cat_reject_not_required_columns( cpl_array *column_names, 00453 cpl_error_code (*import_func)( 00454 double *values, 00455 double *errors, 00456 char band, 00457 double *out_A, 00458 double *dout_A, 00459 double *out_B, 00460 double *dout_B, 00461 double *out_cov), 00462 char band) 00463 { 00464 bool *required = NULL; 00465 int ncolumns, 00466 n; 00467 cpl_errorstate errstat = cpl_errorstate_get(); 00468 00469 cassure_automsg( import_func != NULL, 00470 CPL_ERROR_NULL_INPUT, 00471 return cpl_error_get_code()); 00472 cassure_automsg( column_names != NULL, 00473 CPL_ERROR_NULL_INPUT, 00474 return cpl_error_get_code()); 00475 cassure_automsg( cpl_array_get_type(column_names) 00476 == CPL_TYPE_STRING, 00477 CPL_ERROR_NULL_INPUT, 00478 return cpl_error_get_code()); 00479 00480 ncolumns = cpl_array_get_size(column_names); 00481 required = fors_std_cat_determine_required_columns( 00482 import_func, 00483 ncolumns, 00484 band); 00485 assure( cpl_errorstate_is_equal(errstat), 00486 return cpl_error_get_code(), 00487 NULL); 00488 00489 for (n = 0; n < ncolumns; n++) 00490 { 00491 if (!required[n]) 00492 { 00493 cpl_array_set_invalid(column_names, n); 00494 } 00495 else 00496 { 00497 const char *name; 00498 name = cpl_array_get_string(column_names, n); 00499 if (name == NULL || name[0] == '\0') 00500 { 00501 cpl_error_set_message( cpl_func, 00502 CPL_ERROR_DATA_NOT_FOUND, 00503 "column %d required, but name not " 00504 "specified", 00505 n); 00506 cleanup; 00507 return cpl_error_get_code(); 00508 } 00509 } 00510 } 00511 cpl_free(required); 00512 00513 return (cpl_errorstate_is_equal(errstat) ? 00514 CPL_ERROR_NONE : 00515 cpl_error_get_code()); 00516 } 00517 00518 #undef cleanup 00519 #define cleanup 00520 00528 static bool 00529 fors_std_cat_table_check_columns( const cpl_table *cat_table, 00530 const cpl_array *columns) 00531 { 00532 int ncols, 00533 n; 00534 cassure_automsg( cat_table != NULL, 00535 CPL_ERROR_NULL_INPUT, 00536 return false); 00537 cassure_automsg( columns != NULL, 00538 CPL_ERROR_NULL_INPUT, 00539 return false); 00540 cassure_automsg( cpl_array_get_type(columns) 00541 == CPL_TYPE_STRING, 00542 CPL_ERROR_NULL_INPUT, 00543 return false); 00544 00545 ncols = cpl_array_get_size(columns); 00546 for (n = 0; n < ncols; n++) 00547 { 00548 const char *cs; 00549 cs = cpl_array_get_string(columns, n); 00550 if (cs != NULL 00551 && (!cpl_table_has_column(cat_table, cs))) 00552 { 00553 return false; 00554 } 00555 } 00556 return true; 00557 } 00558 00559 #undef cleanup 00560 #define cleanup \ 00561 do { \ 00562 cpl_array_delete(errcolnames); errcolnames = NULL; \ 00563 } while (0) 00564 00571 static cpl_array * 00572 fors_std_cat_create_error_column_names( const cpl_array *colnames) 00573 { 00574 cpl_array *errcolnames = NULL; 00575 int size, 00576 n; 00577 00578 cassure_automsg( colnames != NULL, 00579 CPL_ERROR_NULL_INPUT, 00580 return errcolnames); 00581 cassure_automsg( cpl_array_get_type(colnames) 00582 == CPL_TYPE_STRING, 00583 CPL_ERROR_NULL_INPUT, 00584 return errcolnames); 00585 00586 size = cpl_array_get_size(colnames); 00587 00588 errcolnames = cpl_array_new(size, CPL_TYPE_STRING); 00589 for (n = 0; n < size; n++) 00590 { 00591 char estr[10]; 00592 const char *cs; 00593 cs = cpl_array_get_string(colnames, n); 00594 if (cs != NULL) 00595 { 00596 snprintf(estr, 9, "ERR_%s", cs); 00597 cpl_array_set_string(errcolnames, n, estr); 00598 } 00599 } 00600 return errcolnames; 00601 } 00602 00603 #undef cleanup 00604 #define cleanup 00605 00621 static cpl_error_code 00622 fors_std_cat_landolt_star_import( double v_bv_ub_vr_vi[5], 00623 double ERR_v_bv_ub_vr_vi[5], 00624 char band, 00625 double *cat_mag, 00626 double *dcat_mag, 00627 double *color, 00628 double *dcolor, 00629 double *cov_catmag_color) 00630 { 00631 cpl_error_code errc; 00632 00633 static const band_jacobian jacobians[6] = 00634 { /* V B-V U-B V-R V-I 1(const) */ 00635 { 'U', { 1, 1, 1, 0, 0, 0,}, 00636 { 0, 0, 1, 0, 0, 0,}, }, 00637 { 'B', { 1, 1, 0, 0, 0, 0,}, 00638 { 0, 1, 0, 0, 0, 0,}, }, 00639 /*(Fukugita et al. 1996, AJ 111, p1748)*/ 00640 { 'G', { 1, 0.56, 0, 0, 0,-0.12,}, 00641 { 0, 1, 0, 0, 0, 0,}, }, 00642 { 'V', { 1, 0, 0, 0, 0, 0,}, 00643 { 0, 1, 0, 0, 0, 0,}, }, 00644 { 'R', { 1, 0, 0, -1, 0, 0,}, 00645 { 0, 0, 0, 1, 0, 0,}, }, 00646 { 'I', { 1, 0, 0, 0, -1, 0,}, 00647 { 0, 0, 0, 1, 0, 0,}, }, 00648 }; 00649 00650 errc = fors_std_cat_import_generic_star(v_bv_ub_vr_vi, 00651 ERR_v_bv_ub_vr_vi, 00652 jacobians, 00653 5, /* jac. columns without const */ 00654 6, /* n bands (U, B, G, ...) */ 00655 band, 00656 cat_mag, 00657 dcat_mag, 00658 color, 00659 dcolor, 00660 cov_catmag_color); 00661 if (errc != CPL_ERROR_NONE) 00662 cpl_error_set_where(cpl_func); 00663 return errc; 00664 } 00665 00666 #undef cleanup 00667 #define cleanup 00668 00675 static cpl_array * 00676 fors_std_cat_landolt_get_column_names( void) 00677 { 00678 const char landolt_columns[5][4] = { "V", "B_V", "U_B", "V_R", "V_I" }; 00679 cpl_array *columns = NULL; 00680 int c; 00681 00682 columns = cpl_array_new(5, CPL_TYPE_STRING); 00683 00684 for (c = 0; c < 5; c++) 00685 cpl_array_set_string(columns, c, landolt_columns[c]); 00686 00687 return columns; 00688 } 00689 00690 #undef cleanup 00691 #define cleanup 00692 00708 static cpl_error_code 00709 fors_std_cat_stetson_star_import( double u_b_v_r_i[5], 00710 double ERR_u_b_v_r_i[5], 00711 char band, 00712 double *cat_mag, 00713 double *dcat_mag, 00714 double *color, 00715 double *dcolor, 00716 double *cov_catmag_color) 00717 { 00718 cpl_error_code errc; 00719 00720 static const band_jacobian jacobians[6] = 00721 { /* U B V R I 1(const) */ 00722 { 'U', { 1, 0, 0, 0, 0, 0,}, 00723 { 1, -1, 0, 0, 0, 0,}, }, 00724 { 'B', { 0, 1, 0, 0, 0, 0,}, 00725 { 0, 1, -1, 0, 0, 0,}, }, 00726 /*(Fukugita et al. 1996, AJ 111, p1748)*/ 00727 { 'G', { 0, 0.56,(1.0-0.56),0, 0,-0.12,}, 00728 { 0, 1, -1, 0, 0, 0,}, }, 00729 { 'V', { 0, 0, 1, 0, 0, 0,}, 00730 { 0, 1, -1, 0, 0, 0,}, }, 00731 { 'R', { 0, 0, 0, 1, 0, 0,}, 00732 { 0, 0, 1, -1, 0, 0,}, }, 00733 { 'I', { 0, 0, 0, 0, 1, 0,}, 00734 { 0, 0, 1, -1, 0, 0,}, }, 00735 }; 00736 00737 errc = fors_std_cat_import_generic_star(u_b_v_r_i, 00738 ERR_u_b_v_r_i, 00739 jacobians, 00740 5, /* jac. columns without const */ 00741 6, /* n bands (U, B, G, ...) */ 00742 band, 00743 cat_mag, 00744 dcat_mag, 00745 color, 00746 dcolor, 00747 cov_catmag_color); 00748 if (errc != CPL_ERROR_NONE) 00749 cpl_error_set_where(cpl_func); 00750 return errc; 00751 } 00752 00753 #undef cleanup 00754 #define cleanup 00755 00762 static cpl_array * 00763 fors_std_cat_stetson_get_column_names( void) 00764 { 00765 const char stetson_columns[5][2] = { "U", "B", "V", "R", "I" }; 00766 cpl_array *columns = NULL; 00767 int c; 00768 00769 columns = cpl_array_new(5, CPL_TYPE_STRING); 00770 00771 for (c = 0; c < 5; c++) 00772 cpl_array_set_string(columns, c, stetson_columns[c]); 00773 00774 return columns; 00775 } 00776 00777 #undef cleanup 00778 #define cleanup \ 00779 do { \ 00780 if (err_colnames != NULL) \ 00781 { cpl_array_delete(*err_colnames); *err_colnames = NULL; } \ 00782 cat_type_detected = false; \ 00783 } while (0) 00784 00799 static bool 00800 fors_std_cat_check_method_and_columns( cpl_table *catalogue, 00801 cpl_array *colnames, 00802 cpl_error_code (*import_func)( 00803 double *values, 00804 double *errors, 00805 char band, 00806 double *out_A, 00807 double *dout_A, 00808 double *out_B, 00809 double *dout_B, 00810 double *out_cov), 00811 char band, 00812 const char *method, 00813 cpl_array **err_colnames, 00814 bool *method_supports_band) 00815 { 00816 bool band_supported = false, 00817 cat_type_detected = false; 00818 int ncols; 00819 cpl_errorstate errstat = cpl_errorstate_get(); 00820 00821 cassure_automsg( catalogue != NULL, 00822 CPL_ERROR_NULL_INPUT, 00823 return cat_type_detected); 00824 cassure_automsg( colnames != NULL, 00825 CPL_ERROR_NULL_INPUT, 00826 return cat_type_detected); 00827 cassure_automsg( cpl_array_get_type(colnames) 00828 == CPL_TYPE_STRING, 00829 CPL_ERROR_NULL_INPUT, 00830 return cat_type_detected); 00831 cassure_automsg( import_func != NULL, 00832 CPL_ERROR_NULL_INPUT, 00833 return cat_type_detected); 00834 cassure_automsg( method != NULL, 00835 CPL_ERROR_NULL_INPUT, 00836 return cat_type_detected); 00837 cassure_automsg( err_colnames != NULL, 00838 CPL_ERROR_NULL_INPUT, 00839 return cat_type_detected); 00840 00841 cleanup; 00842 00843 ncols = cpl_array_get_size(colnames); 00844 band_supported = fors_std_cat_check_band_support( 00845 import_func, 00846 ncols, 00847 band); 00848 if (band_supported) 00849 { 00850 int n; 00851 /* determine the required values for the import function, 00852 * and set other column names to NULL */ 00853 fors_std_cat_reject_not_required_columns( 00854 colnames, 00855 import_func, 00856 band); 00857 00858 /* for column names != NULL, prepend "ERR_" */ 00859 *err_colnames = fors_std_cat_create_error_column_names(colnames); 00860 00861 for (n = 0; n < ncols; n++) 00862 { 00863 const char *s[2]; 00864 int i; 00865 s[0] = cpl_array_get_string(colnames, n); 00866 s[1] = cpl_array_get_string(*err_colnames, n); 00867 if (s[0] != NULL) 00868 for (i = 0; i < 2; i++) 00869 { 00870 cpl_msg_debug(cpl_func, "Required %s column for band %c: " 00871 "%s (%sfound)", 00872 method, band, s[i], 00873 ( cpl_table_has_column( 00874 catalogue, s[i]) ? 00875 "" : "not ") 00876 ); 00877 } 00878 } 00879 00880 /* check presence of column names != NULL */ 00881 cat_type_detected = ( fors_std_cat_table_check_columns( 00882 catalogue, 00883 colnames) 00884 && fors_std_cat_table_check_columns( 00885 catalogue, 00886 *err_colnames)); 00887 } 00888 if (method_supports_band != NULL) 00889 *method_supports_band = band_supported; 00890 00891 assure(cpl_errorstate_is_equal(errstat), return cat_type_detected, NULL); 00892 00893 return cat_type_detected; 00894 } 00895 00896 #undef cleanup 00897 #define cleanup \ 00898 do { \ 00899 fors_std_star_list_delete(&stdlist, fors_std_star_delete); \ 00900 fors_std_star_delete(&std_star); \ 00901 cpl_array_delete(columns); columns = NULL; \ 00902 cpl_array_delete(err_columns); err_columns = NULL; \ 00903 cpl_array_delete(frame_error_messages); frame_error_messages = NULL; \ 00904 cpl_table_delete(cat_table); cat_table = NULL; \ 00905 cpl_free(band_values); band_values = NULL; \ 00906 cpl_free(band_errors); band_errors = NULL; \ 00907 } while (0) 00908 00915 fors_std_star_list * 00916 fors_std_cat_load( const cpl_frameset *cat_frames, 00917 char band, 00918 bool require_all_frames, 00919 double color_term, 00920 double dcolor_term) 00921 { 00922 fors_std_star_list *stdlist = NULL; 00923 fors_std_star *std_star = NULL; 00924 cpl_array *columns = NULL, 00925 *err_columns = NULL, 00926 *frame_error_messages = NULL; 00927 char **frame_error_strings = NULL; 00928 cpl_table *cat_table = NULL; 00929 const cpl_frame *cat_frame; 00930 double *band_values = NULL, 00931 *band_errors = NULL; 00932 int iframe, 00933 last_imethod = -1, 00934 n_cat_entries = 0; 00935 bool printed_warning = false, 00936 checked_support = false, 00937 printed_supported = false; 00938 cpl_errorstate errstat = cpl_errorstate_get(); 00939 00940 struct method { 00941 cpl_array* (*get_column_names_func)(void); 00942 cpl_error_code (*star_import_func)( 00943 double *values, 00944 double *errors, 00945 char band, 00946 double *cat_mag, 00947 double *dcat_mag, 00948 double *color, 00949 double *dcolor, 00950 double *cov_catmag_color); 00951 const char name[10]; 00952 bool band_supported; 00953 } methods[2] = { { fors_std_cat_landolt_get_column_names, 00954 fors_std_cat_landolt_star_import, 00955 "Landolt", 00956 false}, 00957 { fors_std_cat_stetson_get_column_names, 00958 fors_std_cat_stetson_star_import, 00959 "Stetson", 00960 false} 00961 }; 00962 00963 /* check input */ 00964 cassure_automsg( cat_frames != NULL, 00965 CPL_ERROR_NULL_INPUT, 00966 return stdlist); 00967 00968 cassure( !fors_instrument_filterband_is_none( 00969 band), 00970 CPL_ERROR_ILLEGAL_INPUT, 00971 return stdlist, 00972 "no optical/filter band specified"); 00973 cassure( !fors_instrument_filterband_is_unknown( 00974 band), 00975 CPL_ERROR_ILLEGAL_INPUT, 00976 return stdlist, 00977 "optical/filter band is unknown"); 00978 00979 stdlist = fors_std_star_list_new(); 00980 /* error message container, don't abuse the error history for that since 00981 * its size is limited */ 00982 frame_error_messages = cpl_array_new( cpl_frameset_get_size(cat_frames), 00983 CPL_TYPE_STRING); 00984 frame_error_strings = cpl_array_get_data_string(frame_error_messages); 00985 00986 /* import all frames */ 00987 for (cat_frame = cpl_frameset_get_first_const(cat_frames), iframe = 0; 00988 cat_frame != NULL; 00989 cat_frame = cpl_frameset_get_next_const(cat_frames), iframe++) 00990 { 00991 int ncolumns, 00992 row, 00993 nrows, 00994 imethod, 00995 nmethods; 00996 const char **column_value_names, 00997 **column_error_names; 00998 const char *filename; 00999 bool cat_type_detected = false; 01000 01001 filename = cpl_frame_get_filename(cat_frame); 01002 cassure( filename != NULL, 01003 CPL_ERROR_NULL_INPUT, 01004 return stdlist, 01005 "filename of frame %d is NULL", 01006 iframe); 01007 01008 cpl_table_delete(cat_table); 01009 cat_table = cpl_table_load(filename, 1, 1); 01010 if (!cpl_errorstate_is_equal(errstat)) 01011 { 01012 frame_error_strings[iframe] = cpl_sprintf( 01013 "could not load FITS table"); 01014 if (require_all_frames) 01015 { 01016 cassure( 0, 01017 CPL_ERROR_DATA_NOT_FOUND, 01018 return stdlist, 01019 "%s: %s", 01020 filename, 01021 frame_error_strings[iframe]); 01022 } 01023 else 01024 { 01025 /* reset last error */ 01026 cpl_errorstate_set(errstat); 01027 cpl_msg_warning( cpl_func, "Skipping %s (%s)", 01028 filename, 01029 frame_error_strings[iframe]); 01030 continue; /* skip this frame */ 01031 } 01032 } 01033 01034 /* determine the type of the catalogue, and 01035 * accordingly get the names of the required columns. 01036 * For the import functions, we keep the array with the correct 01037 * order of the input column names, but we just invalidate the 01038 * non-required column names. */ 01039 nmethods = sizeof(methods)/sizeof(*methods); 01040 for (imethod = 0; imethod < nmethods; imethod++) 01041 { 01042 cpl_array_delete(columns); 01043 columns = methods[imethod].get_column_names_func(); 01044 01045 cat_type_detected = fors_std_cat_check_method_and_columns( 01046 cat_table, 01047 columns, /* is modified */ 01048 methods[imethod].star_import_func, 01049 band, 01050 methods[imethod].name, 01051 &err_columns, 01052 &(methods[imethod].band_supported)); 01053 passure(cpl_errorstate_is_equal(errstat), return stdlist); 01054 if (cat_type_detected) 01055 break; 01056 } 01057 if (!cat_type_detected) 01058 { 01059 if (!checked_support) /* FIXME: this should be checked in another 01060 function, called before looping over 01061 frames */ 01062 { 01063 bool band_generally_supported = false; 01064 for (imethod = 0; imethod < nmethods; imethod++) 01065 { 01066 band_generally_supported |= methods[imethod].band_supported; 01067 } 01068 if (!band_generally_supported) 01069 { 01070 cpl_error_set_message( cpl_func, 01071 CPL_ERROR_UNSUPPORTED_MODE, 01072 "Optical band %c not supported", 01073 band); 01074 cleanup; 01075 return stdlist; 01076 } 01077 checked_support = true; 01078 } 01079 01080 /* create an error message for this frame */ 01081 if (!printed_supported) 01082 { 01083 char *supported_methods = NULL; 01084 for (imethod = 0; imethod < nmethods; imethod++) 01085 { 01086 if (methods[imethod].band_supported) 01087 { 01088 if (supported_methods == NULL) 01089 { 01090 supported_methods = cpl_sprintf( 01091 "%s", 01092 methods[imethod].name); 01093 } 01094 else /* strcat... */ 01095 { 01096 char *s; 01097 s = cpl_sprintf("%s, %s", 01098 supported_methods, 01099 methods[imethod].name); 01100 cpl_free(supported_methods); 01101 supported_methods = s; 01102 } 01103 } 01104 } 01105 cpl_msg_warning( cpl_func, 01106 "Import of band %c supported for: " 01107 "%s", 01108 band, 01109 supported_methods); 01110 cpl_free(supported_methods); 01111 printed_supported = true; 01112 } 01113 01114 frame_error_strings[iframe] = cpl_sprintf( 01115 "no cat. data for band %c found", 01116 band); 01117 if (require_all_frames) 01118 { 01119 cpl_error_set_message( cpl_func, 01120 CPL_ERROR_DATA_NOT_FOUND, 01121 "%s: %s", 01122 filename, 01123 frame_error_strings[iframe]); 01124 cleanup; 01125 return stdlist; 01126 } 01127 else 01128 { 01129 cpl_msg_warning( cpl_func, "Skipping %s (%s)", 01130 filename, 01131 frame_error_strings[iframe]); 01132 continue; /* skip this frame */ 01133 } 01134 } 01135 else 01136 { 01137 cpl_msg_info( cpl_func, 01138 "Loading %s catalogue from %s", 01139 methods[imethod].name, 01140 filename); 01141 } 01142 if (last_imethod >= 0 && last_imethod != imethod && !printed_warning) 01143 { 01144 cpl_msg_warning( cpl_func, 01145 "Merging different types of " 01146 "catalogues"); 01147 printed_warning = true; 01148 } 01149 last_imethod = imethod; 01150 01151 /* prepare the actual import of catalogue values */ 01152 ncolumns = cpl_array_get_size(columns); 01153 01154 cpl_free(band_values); 01155 band_values = cpl_calloc(ncolumns, sizeof(*band_values)); 01156 cpl_free(band_errors); 01157 band_errors = cpl_calloc(ncolumns, sizeof(*band_errors)); 01158 01159 column_value_names = cpl_array_get_data_string_const(columns); 01160 column_error_names = cpl_array_get_data_string_const(err_columns); 01161 passure(cpl_errorstate_is_equal(errstat), return stdlist); 01162 01163 /* done with preparation, import stars from table rows */ 01164 nrows = cpl_table_get_nrow(cat_table); 01165 n_cat_entries += nrows; 01166 for (row = 0; row < nrows; row++) 01167 { 01168 int ib, 01169 isnull; 01170 bool valid; 01171 01172 /* read all required values from table, ignore others to: 01173 * a) save time, and 01174 * b) use stars that were observed in the required bands but not 01175 * in others */ 01176 valid = true; 01177 for (ib = 0; ib < ncolumns; ib++) 01178 { 01179 if (column_value_names[ib] != NULL) /* if required */ 01180 { 01181 band_values[ib] = cpl_table_get( 01182 cat_table, 01183 column_value_names[ib], 01184 row, 01185 &isnull); 01186 valid &= (isnull == 0); 01187 01188 passure(column_error_names[ib] != NULL, return stdlist); 01189 band_errors[ib] = cpl_table_get( 01190 cat_table, 01191 column_error_names[ib], 01192 row, 01193 &isnull); 01194 valid &= (isnull == 0); 01195 } 01196 } 01197 01198 if (!valid) 01199 continue; 01200 01201 std_star = fors_std_star_new_from_table( 01202 cat_table, 01203 row, 01204 FORS_STD_CAT_COLUMN_RA, 01205 FORS_STD_CAT_COLUMN_DEC, 01206 NULL, NULL, /* corrected mag */ 01207 NULL, NULL, /* catalogue mag */ 01208 NULL, NULL, /* color */ 01209 NULL, /* covariance */ 01210 NULL, NULL, /* x, y */ 01211 FORS_STD_CAT_COLUMN_NAME); 01212 assure( std_star != NULL, 01213 return stdlist, 01214 NULL); 01215 01216 methods[imethod].star_import_func( 01217 band_values, 01218 band_errors, 01219 band, 01220 &(std_star->cat_magnitude), 01221 &(std_star->dcat_magnitude), 01222 &(std_star->color), 01223 &(std_star->dcolor), 01224 &(std_star->cov_catm_color)); 01225 assure( cpl_errorstate_is_equal(errstat), 01226 return stdlist, 01227 NULL); 01228 01229 fors_std_star_compute_corrected_mag( 01230 std_star, 01231 color_term, 01232 dcolor_term); 01233 01234 fors_std_star_list_insert(stdlist, std_star); 01235 std_star = NULL; 01236 } 01237 } 01238 01239 if (!require_all_frames) 01240 { 01241 cassure( cpl_array_has_invalid( 01242 frame_error_messages), 01243 CPL_ERROR_DATA_NOT_FOUND, 01244 return stdlist, 01245 "No valid catalogue frame found"); 01246 } 01247 01248 /* Fixing the fact that the list object supports no "append" */ 01249 /*fors_std_star_list_reverse(stdlist);*/ 01250 01251 cpl_msg_info( cpl_func, 01252 "Found %d catalogue standard stars " 01253 "for band %c (of %d catalogue " 01254 "entries)", 01255 fors_std_star_list_size(stdlist), 01256 band, 01257 n_cat_entries); 01258 01259 fors_std_star_list *retval = stdlist; 01260 stdlist = NULL; 01261 cleanup; 01262 return retval; 01263 } 01264 01265 /*#undef cleanup 01266 #define cleanup \ 01267 do { \ 01268 cpl_array_delete(stetson_columns); stetson_columns = NULL; \ 01269 cpl_frame_delete(cat_frame); cat_frame = NULL; \ 01270 } while (0) 01271 */ 01278 /*cpl_frame * 01279 fors_std_cat_test_create_stetson_format( const fors_std_star_list *stdl, 01280 char band) 01281 { 01282 cpl_array *stetson_columns = NULL; 01283 cpl_frame *cat_frame = NULL; 01284 cpl_errorstate errstat = cpl_errorstate_get(); 01285 01286 stetson_columns = fors_std_cat_stetson_get_column_names(); 01287 assure(cpl_errorstate_is_equal(errstat), return cat_frame, NULL); 01288 fors_std_cat_reject_not_required_columns( 01289 stetson_columns, 01290 fors_std_cat_stetson_star_import, 01291 band); 01292 assure(cpl_errorstate_is_equal(errstat), return cat_frame, NULL); 01293 ... 01294 01295 }*/ 01296 01297 /*----------------------------------------------------------------------------*/ 01298 /* old deprecated code, kept for safety */ 01299 /*----------------------------------------------------------------------------*/ 01300 01301 const char *const FORS_DATA_STD_MAG[FORS_NUM_FILTER] = 01302 {"U", 01303 "B", 01304 //"G", 01305 "V", /* G uses V */ 01306 "V", 01307 "R", 01308 "I", 01309 "Z"}; 01310 01311 const char *const FORS_DATA_STD_DMAG[FORS_NUM_FILTER] = 01312 {"ERR_U", 01313 "ERR_B", 01314 //"ERR_G", 01315 "ERR_V", /* G uses V */ 01316 "ERR_V", 01317 "ERR_R", 01318 "ERR_I", 01319 "ERR_Z"}; 01320 01321 const char *const FORS_DATA_STD_COL[FORS_NUM_FILTER] = 01322 {"U_B", 01323 "B_V", 01324 "B_V", 01325 "B_V", 01326 "V_R", 01327 "V_R", 01328 "?Z?"}; 01329 01330 const char *const FORS_DATA_STD_RA = "RA"; 01331 const char *const FORS_DATA_STD_DEC = "DEC"; 01332 const char *const FORS_DATA_STD_NAME = "OBJECT"; 01333 01334 #undef cleanup 01335 #define cleanup \ 01336 do { \ 01337 cpl_table_delete(t); \ 01338 cpl_free((void *)ERR_B1); \ 01339 cpl_free((void *)ERR_C1); \ 01340 cpl_free((void *)ERR_C2); \ 01341 } while(0) 01342 01354 fors_std_star_list * 01355 fors_std_cat_load_old(const cpl_frameset *cat_frames, 01356 /*const fors_setting *setting,*/ 01357 char optical_band, 01358 double color_term, double dcolor_term) 01359 { 01360 fors_std_star_list *c = NULL; 01361 cpl_table *t = NULL; 01362 const char *filename; 01363 const char *ERR_B1 = NULL; 01364 const char *ERR_C1 = NULL; 01365 const char *ERR_C2 = NULL; 01366 01367 assure( cat_frames != NULL, return c, NULL ); 01368 /*assure( setting != NULL, return c, NULL );*/ 01369 01370 /* For each input table 01371 if it contains the required column, then load 01372 */ 01373 c = fors_std_star_list_new(); 01374 01375 const cpl_frame *cat_frame; 01376 01377 for (cat_frame = cpl_frameset_get_first_const(cat_frames); 01378 cat_frame != NULL; 01379 cat_frame = cpl_frameset_get_next_const(cat_frames)) { 01380 01381 01382 filename = cpl_frame_get_filename(cat_frame); 01383 assure( filename != NULL, return c, NULL ); 01384 01385 cpl_table_delete(t); 01386 t = cpl_table_load(filename, 1, 1); 01387 assure( !cpl_error_get_code(), return c, "Could not load FITS catalogue %s", 01388 filename); 01389 01390 assure( cpl_table_has_column(t, FORS_DATA_STD_RA), return c, 01391 "%s: Missing column %s", filename, FORS_DATA_STD_RA); 01392 01393 assure( cpl_table_get_column_type(t, FORS_DATA_STD_RA) == CPL_TYPE_DOUBLE, 01394 return c, 01395 "%s: Column %s type is %s, double expected", filename, FORS_DATA_STD_RA, 01396 fors_type_get_string(cpl_table_get_column_type(t, FORS_DATA_STD_RA))); 01397 01398 01399 assure( cpl_table_has_column(t, FORS_DATA_STD_DEC), return c, 01400 "%s: Missing column %s", filename, FORS_DATA_STD_DEC); 01401 01402 assure( cpl_table_get_column_type(t, FORS_DATA_STD_DEC) == CPL_TYPE_DOUBLE, 01403 return c, 01404 "%s: Column %s type is %s, double expected", filename, FORS_DATA_STD_DEC, 01405 fors_type_get_string(cpl_table_get_column_type(t, FORS_DATA_STD_DEC))); 01406 01407 01408 assure( cpl_table_has_column(t, FORS_DATA_STD_NAME), return c, 01409 "%s: Missing column %s", filename, FORS_DATA_STD_NAME); 01410 01411 assure( cpl_table_get_column_type(t, FORS_DATA_STD_NAME) == CPL_TYPE_STRING, 01412 return c, 01413 "%s: Column %s type is %s, string expected", filename, 01414 FORS_DATA_STD_NAME, 01415 fors_type_get_string(cpl_table_get_column_type(t, FORS_DATA_STD_NAME))); 01416 01417 01418 /*const char *B1 = FORS_DATA_STD_MAG[setting->filter]; 01419 assure( B1 != NULL, return c, NULL );*/ 01420 char B1[2] = {'\0', '\0'}; 01421 /* *B1 = fors_instrument_filterband_get_by_setting(setting);*/ 01422 *B1 = optical_band; 01423 01424 if ( cpl_table_has_column(t, B1) ) { 01425 01426 /* 01427 The error propagation depends on which 01428 error bars are available, which are assumed to be 01429 uncorrelated 01430 01431 Pseudo code: 01432 01433 given band B1 and color term C1-C2 01434 01435 If have ERR_B1 and ERR_C1 and ERR_C2 01436 // Stetson like 01437 B1 + c(C1 - B1) = (1-c)B1 + c C1 01438 (1-c)^2errB1^2 + c^2 errC1^2 01439 +errc^2 * (C1-B1)^2 01440 01441 B1 + c(B1 - C2) = (1+c)B1 - c C2 01442 01443 (1+c)^2errB1^2 + c^2 errC2^2 01444 +errc^2 (B1-C2)^2 01445 01446 B1 + c(C1 - C2) 01447 errB1^2 + c^2 errC1^2 + c^2 errC2^2 01448 +errc^2 (C1-C2)^2 01449 01450 Special case: 01451 G = V + 0.56*(B-V) - 0.12 (Fukugita et al. 1996, AJ 111, p1748) 01452 01453 magG = G + c*(B-V) = V + (0.56+c)*(B-V) - 0.12 01454 = (1 - 0.56 - c)*V + (0.56+c)*B - 0.12 01455 01456 errG^2 = (1 - 0.56 - c)^2*errV^2 + (0.56+c)^2*errB^2 01457 +errc^2 (B-V)^2 01458 else 01459 // Landolt like 01460 magU = V + (B-V) + (U-B) + c(U-B) 01461 err^2 = errV^2 + err(B-V)^2 + (1+c)^2 err(U-B)^2 01462 + errc^2 (U-B)^2 01463 01464 magB = V + (B-V) + c(B-V) 01465 err^2 = errV^2 + (1+c)^2 err(B-V)^2 01466 + errc^2 (B-V)^2 01467 01468 magG = V + (0.56+c)*(B-V) - 0.12 (Fukugita et al. 1996, AJ 111, p1748) 01469 err^2 = errV^2 + (0.56+c)^2*err(B-V)^2 01470 + errc^2 (B-V)^2 01471 01472 magV = V + c(B-V) 01473 err^2 = errV^2 + c^2 err(B-V)^2 01474 + errc^2 (B-V)^2 01475 01476 magR = V - (V-R) + c (V-R) = V + (c-1)(V-R) 01477 err^2 = errV^2 + (c-1)^2 err(V-R)^2 01478 + errc^2 (V-R)^2 01479 01480 magI = V - (V-I) + c (V-R) 01481 err^2 = errV^2 + err(V-I)^2 + c^2 err(V-R)^2 01482 + errc^2 (V-R)^2 01483 */ 01484 01485 /* Find other bands, C1, C2 */ 01486 const char *col;/* = FORS_DATA_STD_COL[setting->filter];*/ 01487 switch (*B1) 01488 { 01489 case 'U': col = "U_B"; break; 01490 case 'B': col = "B_V"; break; 01491 case 'G': col = "B_V"; break; 01492 case 'V': col = "B_V"; break; 01493 case 'R': col = "V_R"; break; 01494 case 'I': col = "V_R"; break; 01495 case 'Z': col = "?Z?"; break; 01496 default: col = ""; 01497 } 01498 double coeff = -color_term; /* per convention */ 01499 double dcoeff = dcolor_term; 01500 01501 assure( strlen(col) == strlen("X_Y"), return c, 01502 "Color term column must have format 'X_Y', is '%s'", 01503 col ); 01504 01505 assure( col[1] == '_', return c, 01506 "Color term column must have format 'X_Y', is '%s'", 01507 col ); 01508 01509 char C1[2] = {'\0', '\0'}; 01510 char C2[2] = {'\0', '\0'}; 01511 01512 *C1 = col[0]; 01513 *C2 = col[2]; 01514 01515 ERR_B1 = cpl_sprintf("ERR_%s", B1); 01516 ERR_C1 = cpl_sprintf("ERR_%s", C1); 01517 ERR_C2 = cpl_sprintf("ERR_%s", C2); 01518 01519 /* Catalog data */ 01520 double cat_mag, dcat_mag, color; 01521 01522 /* Color corrected magnitude */ 01523 double mag, dmag; 01524 01525 int i; 01526 for (i = 0; i < cpl_table_get_nrow(t); i++) { 01527 if (cpl_table_has_column(t, ERR_B1) && 01528 cpl_table_has_column(t, ERR_C1) && 01529 cpl_table_has_column(t, ERR_C2)) { 01530 01531 /* Stetson, four cases */ 01532 /* if (setting->filter == FILTER_G) {*/ 01533 if (*B1 == 'G') { 01534 if (cpl_table_is_valid(t, "V", i) && 01535 cpl_table_is_valid(t, "B", i) && 01536 cpl_table_is_valid(t, "ERR_B", i) && 01537 cpl_table_is_valid(t, "ERR_V", i)) { 01538 double v = cpl_table_get_float(t, "V", i, NULL); 01539 double b = cpl_table_get_float(t, "B", i, NULL); 01540 double err_b = cpl_table_get_float(t, "ERR_B", i, NULL); 01541 double err_v = cpl_table_get_float(t, "ERR_V", i, NULL); 01542 01543 color = b-v; 01544 mag = (1-0.56-coeff) * v + (0.56+coeff)*b - 0.12; 01545 cat_mag = (1-0.56 ) * v + (0.56 )*b - 0.12; 01546 01547 dmag = 01548 sqrt( 01549 (1-0.56-coeff)*(1-0.56-coeff)*err_v*err_v + 01550 (0.56 +coeff)*(0.56 +coeff)*err_b*err_b + 01551 + 01552 dcoeff*dcoeff*color*color); 01553 01554 dcat_mag = sqrt( 01555 (1-0.56-0)*(1-0.56-0)*err_v*err_v + 01556 (0.56 +0)*(0.56 +0)*err_b*err_b); 01557 } 01558 } 01559 else if (*B1 == *C2) { 01560 if (cpl_table_is_valid(t, B1, i) && 01561 cpl_table_is_valid(t, C1, i) && 01562 cpl_table_is_valid(t, ERR_B1, i) && 01563 cpl_table_is_valid(t, ERR_C1, i)) { 01564 double b1 = cpl_table_get_float(t, B1, i, NULL); 01565 double c1 = cpl_table_get_float(t, C1, i, NULL); 01566 double err_b1 = cpl_table_get_float(t, ERR_B1, i, NULL); 01567 double err_c1 = cpl_table_get_float(t, ERR_C1, i, NULL); 01568 01569 color = c1-b1; 01570 01571 cat_mag = b1; 01572 dcat_mag = err_b1; 01573 01574 mag = 01575 (1-coeff) * b1 01576 + coeff * c1; 01577 dmag = 01578 sqrt( 01579 (1-coeff)*(1-coeff)*err_b1*err_b1 + 01580 coeff*coeff *err_c1*err_c1 01581 + 01582 dcoeff*dcoeff*color*color); 01583 } 01584 else continue; 01585 } 01586 else if (*B1 == *C1) { 01587 if (cpl_table_is_valid(t, B1, i) && 01588 cpl_table_is_valid(t, C2, i) && 01589 cpl_table_is_valid(t, ERR_B1, i) && 01590 cpl_table_is_valid(t, ERR_C2, i)) { 01591 double b1 = cpl_table_get_float(t, B1, i, NULL); 01592 double c2 = cpl_table_get_float(t, C2, i, NULL); 01593 double err_b1 = cpl_table_get_float(t, ERR_B1, i, NULL); 01594 double err_c2 = cpl_table_get_float(t, ERR_C2, i, NULL); 01595 01596 color = b1-c2; 01597 01598 cat_mag = b1; 01599 dcat_mag = err_b1; 01600 01601 mag = 01602 (1+coeff) * b1 01603 - coeff * c2; 01604 dmag = 01605 sqrt( 01606 (1+coeff)*(1+coeff)*err_b1*err_b1 + 01607 coeff*coeff *err_c2*err_c2 01608 + 01609 dcoeff*dcoeff*color*color); 01610 01611 } 01612 else continue; 01613 } 01614 else { 01615 /* All different */ 01616 if (cpl_table_is_valid(t, B1, i) && 01617 cpl_table_is_valid(t, C1, i) && 01618 cpl_table_is_valid(t, C2, i) && 01619 cpl_table_is_valid(t, ERR_B1, i) && 01620 cpl_table_is_valid(t, ERR_C1, i) && 01621 cpl_table_is_valid(t, ERR_C2, i)) { 01622 double b1 = cpl_table_get_float(t, B1, i, NULL); 01623 double c1 = cpl_table_get_float(t, C1, i, NULL); 01624 double c2 = cpl_table_get_float(t, C2, i, NULL); 01625 double err_b1 = cpl_table_get_float(t, ERR_B1, i, NULL); 01626 double err_c1 = cpl_table_get_float(t, ERR_C1, i, NULL); 01627 double err_c2 = cpl_table_get_float(t, ERR_C2, i, NULL); 01628 01629 color = c1-c2; 01630 01631 cat_mag = b1; 01632 dcat_mag = err_b1; 01633 01634 mag = b1 01635 + coeff * c1 01636 - coeff * c2; 01637 dmag = sqrt( 01638 err_b1*err_b1 + 01639 coeff*coeff * err_c1*err_c1 + 01640 coeff*coeff * err_c2*err_c2 + 01641 dcoeff*dcoeff * color*color); 01642 } 01643 else continue; 01644 } 01645 } /* If stetson, else */ 01646 /* else if (setting->filter == FILTER_G) {*/ 01647 else if (*B1 == 'G') { 01648 if (cpl_table_is_valid(t, "V", i) && 01649 cpl_table_is_valid(t, "B_V", i) && 01650 cpl_table_is_valid(t, "ERR_V", i) && 01651 cpl_table_is_valid(t, "ERR_B_V", i)) { 01652 double v = cpl_table_get_float(t, "V", i, NULL); 01653 double bv = cpl_table_get_float(t, "B_V", i, NULL); 01654 double err_v = cpl_table_get_float(t, "ERR_V", i, NULL); 01655 double err_b_v = cpl_table_get_float(t, "ERR_B_V", i, NULL); 01656 01657 color = bv; 01658 01659 cat_mag = v + (0.56)*(bv) - 0.12; 01660 01661 mag = v + (0.56+coeff)*(bv) - 0.12; 01662 dmag = 01663 sqrt( 01664 err_v*err_v + 01665 (0.56+coeff)*(0.56+coeff)*err_b_v*err_b_v + 01666 + 01667 dcoeff*dcoeff*bv*bv); 01668 dcat_mag = 01669 sqrt( 01670 err_v*err_v + 01671 (0.56)*(0.56)*err_b_v*err_b_v); 01672 } 01673 } 01674 else switch (*B1) { 01675 /* Landolt, every band is a special case */ 01676 case 'U': 01677 if (cpl_table_is_valid(t, "U", i) && 01678 cpl_table_is_valid(t, "U_B", i) && 01679 cpl_table_is_valid(t, "ERR_V", i) && 01680 cpl_table_is_valid(t, "ERR_B_V", i) && 01681 cpl_table_is_valid(t, "ERR_U_B", i)) { 01682 01683 double err_v = cpl_table_get_float(t, "ERR_V", i, NULL); 01684 double err_bv = cpl_table_get_float(t, "ERR_B_V", i, NULL); 01685 double err_ub = cpl_table_get_float(t, "ERR_U_B", i, NULL); 01686 double ub = cpl_table_get_float(t, "U_B", i, NULL); 01687 01688 color = ub; 01689 01690 cat_mag = cpl_table_get_float(t, "U", i, NULL); 01691 01692 mag = cat_mag + coeff * ub; 01693 dmag = sqrt(err_v*err_v + err_bv*err_bv+ 01694 (1+coeff)*(1+coeff)*err_ub*err_ub + 01695 dcoeff*dcoeff*ub*ub); 01696 01697 dcat_mag = sqrt(err_v*err_v + err_bv*err_bv+ 01698 err_ub*err_ub); 01699 } 01700 else continue; /* to next for(...) iteration */ 01701 break; /* out of switch */ 01702 case 'B': 01703 if (cpl_table_is_valid(t, "B", i) && 01704 cpl_table_is_valid(t, "B_V", i) && 01705 cpl_table_is_valid(t, "ERR_V", i) && 01706 cpl_table_is_valid(t, "ERR_B_V", i)) { 01707 01708 double err_v = cpl_table_get_float(t, "ERR_V", i, NULL); 01709 double err_bv = cpl_table_get_float(t, "ERR_B_V", i, NULL); 01710 double bv = cpl_table_get_float(t, "B_V", i, NULL); 01711 01712 color = bv; 01713 cat_mag = cpl_table_get_float(t, "B", i, NULL); 01714 01715 mag = cat_mag + 01716 coeff * bv; 01717 dmag = sqrt(err_v*err_v + 01718 (1+coeff)*(1+coeff)*err_bv*err_bv + 01719 dcoeff*dcoeff*bv*bv); 01720 dcat_mag = sqrt(err_v*err_v + 01721 err_bv*err_bv); 01722 } 01723 else continue; 01724 break; 01725 case 'V': 01726 if (cpl_table_is_valid(t, "V", i) && 01727 cpl_table_is_valid(t, "B_V", i) && 01728 cpl_table_is_valid(t, "ERR_V", i) && 01729 cpl_table_is_valid(t, "ERR_B_V", i)) { 01730 01731 double err_v = cpl_table_get_float(t, "ERR_V", i, NULL); 01732 double err_bv = cpl_table_get_float(t, "ERR_B_V", i, NULL); 01733 double bv = cpl_table_get_float(t, "B_V", i, NULL); 01734 01735 color = bv; 01736 cat_mag = cpl_table_get_float(t, "V", i, NULL); 01737 dcat_mag = err_v; 01738 01739 mag = cat_mag + coeff * bv; 01740 dmag = sqrt(err_v*err_v + 01741 coeff*coeff*err_bv*err_bv + 01742 dcoeff*dcoeff*bv*bv); 01743 } 01744 else continue; 01745 break; 01746 case 'R': 01747 if (cpl_table_is_valid(t, "R", i) && 01748 cpl_table_is_valid(t, "V_R", i) && 01749 cpl_table_is_valid(t, "ERR_V", i) && 01750 cpl_table_is_valid(t, "ERR_V_R", i)) { 01751 01752 double err_v = cpl_table_get_float(t, "ERR_V", i, NULL); 01753 double err_vr = cpl_table_get_float(t, "ERR_V_R", i, NULL); 01754 double vr = cpl_table_get_float(t, "V_R", i, NULL); 01755 01756 color = vr; 01757 cat_mag = cpl_table_get_float(t, "R", i, NULL); 01758 mag = cat_mag + coeff * vr; 01759 dmag = sqrt(err_v*err_v + 01760 (1-coeff)*(1-coeff)*err_vr*err_vr + 01761 dcoeff*dcoeff*vr*vr); 01762 dcat_mag = sqrt(err_v*err_v + err_vr*err_vr); 01763 } 01764 else continue; 01765 break; 01766 case 'I': 01767 if (cpl_table_is_valid(t, "I", i) && 01768 cpl_table_is_valid(t, "V_R", i) && 01769 cpl_table_is_valid(t, "ERR_V", i) && 01770 cpl_table_is_valid(t, "ERR_V_I", i) && 01771 cpl_table_is_valid(t, "ERR_V_R", i)) { 01772 01773 double err_v = cpl_table_get_float(t, "ERR_V", i, NULL); 01774 double err_vi = cpl_table_get_float(t, "ERR_V_I", i, NULL); 01775 double err_vr = cpl_table_get_float(t, "ERR_V_R", i, NULL); 01776 double vr = cpl_table_get_float(t, "V_R", i, NULL); 01777 01778 color = vr; 01779 cat_mag = cpl_table_get_float(t, "I", i, NULL); 01780 mag = cat_mag + coeff * vr; 01781 dmag = sqrt(err_v*err_v + err_vi*err_vi+ 01782 coeff*coeff*err_vr*err_vr + 01783 dcoeff*dcoeff*vr*vr); 01784 dcat_mag = sqrt(err_v*err_v + err_vi*err_vi); 01785 } 01786 else continue; 01787 break; 01788 default: 01789 assure( false, return c, 01790 "Unknown filter: %s", B1); 01791 break; 01792 } 01793 01794 double ra = cpl_table_get_double(t, FORS_DATA_STD_RA, 01795 i, NULL); 01796 double dec = cpl_table_get_double(t, FORS_DATA_STD_DEC, 01797 i, NULL); 01798 01799 const char *std_name = cpl_table_get_string(t, FORS_DATA_STD_NAME, 01800 i); 01801 01802 fors_std_star_list_insert( 01803 c, fors_std_star_new(ra, dec, mag, dmag, 01804 cat_mag, dcat_mag, 01805 color, -1, -1, std_name)); 01806 01807 } /* for each table row */ 01808 01809 #if 0 /* This is old code which removes doublets but is slow (O(n^2)), 01810 * Doublets will be removed during identification, after 01811 * selecting the (relatively few) stars that fall inside the CCD 01812 */ 01813 double nearest_dist; 01814 if (fors_std_star_list_size(c) > 0) { 01815 fors_std_star *nearest = fors_std_star_list_min_val( 01816 c, 01817 (fors_std_star_list_func_eval) 01818 fors_std_star_dist_arcsec, 01819 std); 01820 01821 nearest_dist = fors_std_star_dist_arcsec(std, nearest); 01822 cpl_msg_debug(cpl_func, "min dist = %f arcseconds", 01823 nearest_dist); 01824 } 01825 01826 if (fors_std_star_list_size(c) == 0 || nearest_dist > 5) { 01827 fors_std_star_list_insert(c, std); 01828 } 01829 else { 01830 fors_std_star_delete(&std); 01831 } 01832 #endif 01833 } /* if has column B1 */ 01834 else { 01835 cpl_msg_info(cpl_func, "Skipping catalog %s, no column %s", 01836 filename, B1); 01837 } 01838 } /* for each frame */ 01839 01840 cpl_msg_info(cpl_func, "Found %d catalogue standards", 01841 fors_std_star_list_size(c)); 01842 01843 /* fors_std_cat_print(c); */ 01844 01845 cleanup; 01846 return c; 01847 }