naco_util_img_std_cat.c

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

Generated on Mon Feb 6 14:42:07 2012 for NACO Pipeline Reference Manual by  doxygen 1.5.8