fors_data.c

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_8_6 $
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 }

Generated on Fri Mar 4 09:46:00 2011 for FORS Pipeline Reference Manual by  doxygen 1.4.7