fors_std_cat.c

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

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