naco_util_img_std_cat.c

00001 /* $Id: naco_util_img_std_cat.c,v 1.10 2008/04/15 15:31:58 llundin Exp $
00002  *
00003  * This file is part of the NACO Pipeline
00004  * Copyright (C) 2002,2003 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2008/04/15 15:31:58 $
00024  * $Revision: 1.10 $
00025  * $Name: naco-4_1_2 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include <string.h>
00037 
00038 #include "naco_recipe.h"
00039 
00040 #include <irplib_stdstar.h>
00041 
00042 /*-----------------------------------------------------------------------------
00043                             Defines
00044  -----------------------------------------------------------------------------*/
00045 
00046 #define NFILTERS 8
00047 
00048 #define RECIPE_STRING "naco_util_img_std_cat"
00049 
00050 /* Largest seen so far is 74 */
00051 #ifndef NACO_ASCII_MAXLINELEN
00052 #define NACO_ASCII_MAXLINELEN 1024
00053 #endif
00054 
00055 /*-----------------------------------------------------------------------------
00056                             Private Functions prototypes
00057  -----------------------------------------------------------------------------*/
00058 
00059 NACO_RECIPE_DEFINE(naco_util_img_std_cat,
00060                    0,
00061                    "Standard star catalog creation",
00062                    RECIPE_STRING " -- Standard star catalog creation.\n"
00063                    "Convert ASCII-file(s) to a FITS standard star catalog.\n"
00064                    "This recipe generates a FITS standard star catalog for "
00065                    "imaging from one or more ASCII-files.\n"
00066                    "Each line in the text file must have "
00067                    "4+" IRPLIB_STRINGIFY(NFILTERS) " fields "
00068                    "separated by white-space.\n"
00069                    "The first field is the star name, e.g. 'HD108903' which "
00070                    "will be stored in a "
00071                    "table column labeled '" IRPLIB_STDSTAR_STAR_COL "'.\n"
00072                    "The next field is the Right Ascension [degrees] which will "
00073                    "be stored in a table column labeled '" IRPLIB_STDSTAR_RA_COL
00074                    "'.\n"
00075                    "The Right Ascension must be non-negative and less than "
00076                    "360.\n"
00077                    "The next field is the Declination [degrees] which will be "
00078                    "stored in a table column labeled '" IRPLIB_STDSTAR_DEC_COL
00079                    "'.\n"
00080                    "The Declination must be within the range -90 to 90.\n"
00081                    "The next field is the spectral type which will be "
00082                    "stored in a table column labeled '" IRPLIB_STDSTAR_TYPE_COL
00083                    "'.\n"
00084                    "The " IRPLIB_STRINGIFY(NFILTERS) " next fields are the "
00085                    "magnitudes for the " IRPLIB_STRINGIFY(NFILTERS) " supported "
00086                    "image filters.\n"
00087                    "Unknown magnitudes must be indicated by the "
00088                    "value " IRPLIB_STRINGIFY(IRPLIB_STDSTAR_NOMAG) ".\n"
00089                    "The filename (without path) of the ASCII file will for "
00090                    "each star be added in a table column labeled 'CAT_NAME'.\n"
00091                    "The " IRPLIB_STRINGIFY(NFILTERS) " filter names are "
00092                    "hard-coded in the recipe.\n"
00093                    "\n"
00094                    "Lines beginning with a hash (#) are treated as comments.\n"
00095                    "\n"
00096                    "The files listed in the Set Of Frames (sof-file) "
00097                    "must be tagged:\n" 
00098                    "NACO-ASCII-file " NACO_IMG_STD_ASCII "\n");
00099 
00100 static IRPLIB_UTIL_SET_ROW(naco_util_img_std_set_row);
00101 static IRPLIB_UTIL_CHECK(naco_util_img_std_check);
00102 
00103 static cpl_error_code naco_util_img_std_cat_cmp(const cpl_table *,
00104                                                 cpl_boolean *,
00105                                                 double, double,
00106                                                 const char *,
00107                                                 const char *,
00108                                                 const char *,
00109                                                 int,
00110                                                 const double *, double, double);
00111 
00112 static double magmin = IRPLIB_STDSTAR_NOMAG;
00113 static double magmax = -30.0;
00114 static const char * filters[] = {"J","H", "K", "Ks", "L", "M", "Lp", "Mp"};
00115 
00116 /*-----------------------------------------------------------------------------
00117                                 Functions code
00118  -----------------------------------------------------------------------------*/
00119 
00120 /*----------------------------------------------------------------------------*/
00127 /*----------------------------------------------------------------------------*/
00128 static int naco_util_img_std_cat(cpl_frameset            * framelist,
00129                                  const cpl_parameterlist * parlist)
00130 {
00131     irplib_framelist * allframes = NULL;
00132     irplib_framelist * rawframes = NULL;
00133     cpl_frameset     * useframes = NULL;
00134     cpl_table        * self      = NULL;
00135     int                ifilt;
00136 
00137 
00138     bug_if(sizeof(filters) != NFILTERS * sizeof(char*));
00139 
00140     /* Identify the RAW and CALIB frames in the input frameset */
00141     skip_if (naco_dfs_set_groups(framelist));
00142 
00143     /* FIXME: Using framelists is the simplest way to extract the relevant
00144        frames :-( */
00145     allframes = irplib_framelist_cast(framelist);
00146     bug_if(allframes == NULL);
00147 
00148     rawframes = irplib_framelist_extract(allframes, NACO_IMG_STD_ASCII);
00149     skip_if(rawframes == NULL);
00150 
00151     irplib_framelist_empty(allframes);
00152 
00153     useframes = irplib_frameset_cast(rawframes);
00154     bug_if(allframes == NULL);
00155 
00156     /* At least one row per file */
00157     self = cpl_table_new(irplib_framelist_get_size(rawframes));
00158 
00159     irplib_framelist_empty(rawframes);
00160 
00161 
00162     /* Create the table columns - with units */
00163     bug_if (cpl_table_new_column(self, IRPLIB_STDSTAR_STAR_COL,
00164                                  CPL_TYPE_STRING));
00165     bug_if (cpl_table_new_column(self, IRPLIB_STDSTAR_TYPE_COL,
00166                                  CPL_TYPE_STRING));
00167     bug_if (cpl_table_new_column(self, "CAT_NAME", CPL_TYPE_STRING));
00168     bug_if (cpl_table_new_column(self, IRPLIB_STDSTAR_RA_COL,
00169                                  CPL_TYPE_DOUBLE));
00170     bug_if (cpl_table_new_column(self, IRPLIB_STDSTAR_DEC_COL,
00171                                  CPL_TYPE_DOUBLE));
00172 
00173     bug_if(cpl_table_set_column_unit(self, IRPLIB_STDSTAR_RA_COL,
00174                                      "Degrees"));
00175     bug_if(cpl_table_set_column_unit(self, IRPLIB_STDSTAR_DEC_COL,
00176                                      "Degrees"));
00177     for (ifilt=0 ; ifilt < NFILTERS ; ifilt++) {
00178         bug_if (cpl_table_new_column(self, filters[ifilt], CPL_TYPE_DOUBLE));
00179         bug_if(cpl_table_set_column_unit(self, filters[ifilt], "Magnitude"));
00180     }
00181 
00182     skip_if(irplib_dfs_table_convert(self, framelist, useframes, 
00183                                      NACO_ASCII_MAXLINELEN, '#', NULL,
00184                                      NACO_IMG_STD_CAT, parlist, RECIPE_STRING,
00185                                      NULL, NULL, NULL, "NACO", naco_pipe_id,
00186                                      naco_util_img_std_set_row,
00187                                      naco_util_img_std_check));
00188 
00189     end_skip;
00190 
00191     cpl_table_delete(self);
00192     cpl_frameset_delete(useframes);
00193     irplib_framelist_delete(allframes);
00194     irplib_framelist_delete(rawframes);
00195 
00196     return cpl_error_get_code();
00197 }
00198 
00199 /*----------------------------------------------------------------------------*/
00219 /*----------------------------------------------------------------------------*/
00220 static cpl_error_code naco_util_img_std_cat_cmp(const cpl_table * self,
00221                                                 cpl_boolean     * puse,
00222                                                 double            ra,
00223                                                 double            dec,
00224                                                 const char      * sname,
00225                                                 const char      * stype,
00226                                                 const char      * cat_name,
00227                                                 int               irow,
00228                                                 const double    * mags,
00229                                                 double            dist_max,
00230                                                 double            mag_tol)
00231 {
00232 
00233     const int nfilters = NFILTERS;
00234     int j;
00235 
00236     *puse = CPL_FALSE;
00237 
00238     bug_if(self     == NULL);
00239     bug_if(filters  == NULL);
00240     bug_if(mags     == NULL);
00241     bug_if(sname    == NULL);
00242     bug_if(stype    == NULL);
00243     bug_if(cat_name == NULL);
00244 
00245     for (j = 0; j < irow; j++) {
00246         const double raj
00247             = cpl_table_get_double(self, IRPLIB_STDSTAR_RA_COL, j, NULL);
00248         const double decj
00249             = cpl_table_get_double(self, IRPLIB_STDSTAR_DEC_COL, j, NULL);
00250         double dist;
00251         double mag_max_found = 0;
00252         int i;
00253 
00254         if (fabs(decj - dec) > dist_max) continue;
00255 
00256         dist = irplib_stdstar_great_circle_dist(ra, dec, raj, decj);
00257 
00258         if (dist > dist_max) continue;
00259 
00260         for (i=0 ; i < nfilters ; i++) {
00261             const double mag
00262                 = cpl_table_get_double(self, filters[i], j, NULL);
00263             double mag_dif;
00264 
00265             if (mags[i] > IRPLIB_STDSTAR_LIMIT) continue;
00266 
00267             if (mag > IRPLIB_STDSTAR_LIMIT) break;
00268 
00269             mag_dif = fabs(mags[i] - mag);
00270 
00271             if (mag_dif > mag_tol) break;
00272 
00273             if (mag_dif > mag_max_found) mag_max_found = mag_dif;
00274         }
00275 
00276 
00277         if (i == nfilters) {
00278             cpl_msg_debug(cpl_func, "Skipping star: '%s' at table row %d in "
00279                          "catalogue '%s' and the star %d have identical "
00280                          "magnitudes (within %g <= %g) and a distance: "
00281                           "%g <= %g", sname, 1+irow, cat_name, j+1,
00282                           mag_max_found, mag_tol, dist, dist_max);
00283             if (cpl_msg_get_level() <= CPL_MSG_DEBUG)
00284                 cpl_table_dump(self, j, 1, stdout);
00285             break;
00286         }
00287         if (dist > 0.0) {
00288             cpl_msg_info(cpl_func, "The stars at rows %d and %d ('%s' in "
00289                          "catalogue '%s') have different magnitudes, but a "
00290                          "distance: %g <= %g",
00291                          1+j, 1+irow, sname, cat_name, dist, dist_max);
00292         } else {
00293             cpl_msg_info(cpl_func, "The stars at rows %d and %d ('%s' in "
00294                          "catalogue '%s') have different magnitudes, but "
00295                          "identical coordinates",
00296                          1+j, 1+irow, sname, cat_name);
00297         }
00298 #if 0
00299         cpl_table_dump(self, j, 1, stderr);
00300         for (i=0 ; i < nfilters ; i++) {
00301             const double mag
00302                 = cpl_table_get_double(self, filters[i], j, NULL);
00303             const double mag_dif = fabs(mags[i] - mag);
00304 
00305             if (mag_dif > mag_tol) 
00306                 cpl_msg_warning(cpl_func, "%s(%d): |%g - %g| = %g > %g",
00307                                 filters[i], i, mag, mags[i], mag_dif, mag_tol);
00308         }
00309 #endif
00310     }
00311 
00312     if (j == irow) *puse = CPL_TRUE;
00313 
00314     end_skip;
00315 
00316     return CPL_ERROR_NONE;
00317 
00318 }
00319 
00320 
00321 /*----------------------------------------------------------------------------*/
00330 /*----------------------------------------------------------------------------*/
00331 static
00332 cpl_error_code naco_util_img_std_check(cpl_table * self,
00333                                        const cpl_frameset * useframes,
00334                                        const cpl_parameterlist * parlist)
00335 {
00336 
00337     bug_if(0);
00338     bug_if(self     == NULL);
00339     bug_if(parlist  == NULL);
00340 
00341     cpl_msg_info(cpl_func, "Created table of %d stars with "
00342                  "magnitudes from %g to %g from %d catalogues",
00343                  cpl_table_get_nrow(self),
00344                  magmin, magmax, cpl_frameset_get_size(useframes));
00345 
00346     end_skip;
00347 
00348     return cpl_error_get_code();
00349 }
00350 
00351 
00352 /*----------------------------------------------------------------------------*/
00375 /*----------------------------------------------------------------------------*/
00376 static cpl_boolean naco_util_img_std_set_row(cpl_table * self,
00377                                              const char * line,
00378                                              int irow,
00379                                              const cpl_frame * rawframe,
00380                                              const cpl_parameterlist * parlist)
00381 {
00382 
00383     /* gcc can only check sscanf()s format when it is a string literal */
00384 #define FORMAT "%s %lg %lg %s %lg %lg %lg %lg %lg %lg %lg %lg"
00385 
00386     char         sname[NACO_ASCII_MAXLINELEN];
00387     char         stype[NACO_ASCII_MAXLINELEN];
00388     double       mags[NFILTERS];
00389     double       ra, dec;
00390     int          nvals;
00391     int          ifilt;
00392     cpl_boolean  use = CPL_FALSE;
00393 
00394     bug_if(0);
00395     bug_if(self     == NULL);
00396     bug_if(line     == NULL);
00397     bug_if(irow   <  0);
00398     bug_if(rawframe == NULL);
00399     bug_if(parlist  == NULL);
00400 
00401     nvals = sscanf(line, FORMAT,
00402                    sname, &ra, &dec, stype, &(mags[0]), &(mags[1]), &(mags[2]),
00403                    &(mags[3]), &(mags[4]), &(mags[5]), &(mags[6]), &(mags[7]));
00404 
00405     error_if (nvals != NFILTERS+4, CPL_ERROR_BAD_FILE_FORMAT,
00406               "Line with length=%u has %d not 4+" IRPLIB_STRINGIFY(NFILTERS)
00407               " items formatted: %s", (unsigned)strlen(line), nvals, FORMAT);
00408 
00409     error_if (ra < 0.0, CPL_ERROR_BAD_FILE_FORMAT,
00410               "Negative RA=%g in line %s", ra, line);
00411 
00412     error_if (ra >=360.0, CPL_ERROR_BAD_FILE_FORMAT,
00413               "RA=%g is not less than 360 in line %s", ra, line);
00414 
00415     error_if (dec < -90.0, CPL_ERROR_BAD_FILE_FORMAT,
00416               "DEC=%g is not at least -90 in line %s", dec, line);
00417 
00418     error_if (dec > 90.0, CPL_ERROR_BAD_FILE_FORMAT,
00419               "DEC=%g is not at most 90 in line %s", dec, line);
00420 
00421     for (ifilt=0 ; ifilt < NFILTERS; ifilt++) {
00422         if (mags[ifilt] < IRPLIB_STDSTAR_LIMIT) break;
00423     }
00424 
00425     if (ifilt == NFILTERS) {
00426         cpl_msg_debug(cpl_func, "Not setting row without a valid magnitude: "
00427                       "(%d)", 1+irow);
00428     } else {
00429         const char * rawfile = cpl_frame_get_filename(rawframe);
00430         /* Skip path, if any */
00431         const char * cat_name = strrchr(rawfile, '/');
00432 
00433         cat_name = cat_name ? 1+cat_name : rawfile;
00434 
00435         bug_if(cat_name == NULL);
00436 
00437         skip_if(naco_util_img_std_cat_cmp(self, &use, ra, dec, sname,
00438                                           stype, cat_name, irow,
00439                                           mags, 0.25e-4, 1e-6));
00440 
00441         if (use) {
00442             bug_if (cpl_table_set_string(self, IRPLIB_STDSTAR_STAR_COL, irow,
00443                                          sname));
00444 
00445             bug_if (cpl_table_set_string(self, "CAT_NAME", irow, cat_name));
00446 
00447             bug_if (cpl_table_set_string(self, IRPLIB_STDSTAR_TYPE_COL, irow,
00448                                          stype));
00449 
00450             bug_if (cpl_table_set_double(self, IRPLIB_STDSTAR_RA_COL, irow,
00451                                          ra));
00452 
00453             bug_if (cpl_table_set_double(self, IRPLIB_STDSTAR_DEC_COL, irow,
00454                                          dec));
00455 
00456             for (ifilt=0 ; ifilt < NFILTERS; ifilt++) {
00457                 if (mags[ifilt] > 27.0 && mags[ifilt] < IRPLIB_STDSTAR_LIMIT) {
00458                     /* 27 is about the limit of the UT */
00459                     cpl_msg_warning(cpl_func, "Setting faint (mag=%g) object "
00460                                     "(Filter-%s) in table row %d", mags[ifilt],
00461                                     filters[ifilt], 1+irow);
00462                 }
00463                 if (mags[ifilt] > magmax && mags[ifilt] < IRPLIB_STDSTAR_LIMIT)
00464                     magmax = mags[ifilt];
00465                 if (mags[ifilt] < magmin) magmin = mags[ifilt];
00466                 bug_if(cpl_table_set_double(self, filters[ifilt], irow,
00467                                             mags[ifilt]));
00468             }
00469         }
00470     }
00471 
00472     end_skip;
00473 
00474     return use;
00475 
00476 }

Generated on Fri Jul 3 11:23:59 2009 for NACO Pipeline Reference Manual by  doxygen 1.5.8