Main Page   File List  

visir_util_spc_std_cat.c

00001 /* $Id: visir_util_spc_std_cat.c,v 1.30 2006/01/04 13:39:29 llundin Exp $
00002  *
00003  * This file is part of the VISIR 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., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2006/01/04 13:39:29 $
00024  * $Revision: 1.30 $
00025  * $Name:  $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include <assert.h>
00037 #include <cpl.h>
00038 
00039 /*********************************************************************/
00040 #include <qfits.h>      /* FIXME: NEEDED TILL CPL SUPPORTS 3D TABLES */
00041 /*********************************************************************/
00042 
00043 #include "visir_utils.h"
00044 #include "visir_pfits.h"
00045 #include "visir_dfs.h"
00046 #include "visir_inputs.h"
00047 
00048 /*-----------------------------------------------------------------------------
00049                                    Define
00050  -----------------------------------------------------------------------------*/
00051 
00052 #define RECIPENAME  "visir_util_spc_std_cat"
00053 
00054 /*-----------------------------------------------------------------------------
00055                             Functions prototypes
00056  -----------------------------------------------------------------------------*/
00057 
00058 static int visir_util_spc_std_cat_create(cpl_plugin *);
00059 static int visir_util_spc_std_cat_exec(cpl_plugin *);
00060 static int visir_util_spc_std_cat_destroy(cpl_plugin *);
00061 static int visir_util_spc_std_cat(const cpl_parameterlist *, cpl_frameset *);
00062 static int visir_util_spc_std_cat_save(void **, int, int, 
00063                                        const cpl_parameterlist *,
00064                                        cpl_frameset *);
00065 
00066 /*-----------------------------------------------------------------------------
00067                             Static variables
00068  -----------------------------------------------------------------------------*/
00069 
00070 static const char * recipename = RECIPENAME;
00071 
00072 static char visir_util_spc_std_cat_description[] =
00073 "This recipe generates a FITS standard star catalog for spectroscopy from \n"
00074 "a set of ASCII-files named <Star_Name>.txt, e.g. HD133165.txt.\n"
00075 "All input ASCII-files must comprise the same number of lines.\n"
00076 "The first line of the ASCII-file must have 6 fields separated by white-space.\n"
00077 "The first three fields are the RA (hh mm ss) which will be stored in degrees\n"
00078 "in a table column labeled 'RA' - all three are non-negative and hh and mm \n"
00079 "are integer.\n"
00080 "The 3 last fields are the DEC (dd mm ss) which will be stored in degrees in \n"
00081 "a table column labeled 'DEC' - all three are non-negative, dd and mm are \n"
00082 "integer, while dd has either a '+' or a '-' prepended (including -00).\n"
00083 "The remaining lines must all consist of two fields separated by white-space.\n"
00084 "The first field is the wavelength (in microns) and the second the (positive)\n"
00085 "model flux in W/m2/m. The wavelengths must be identical in all the input "
00086 "files.\n";
00087 
00088 const int starnamelen = 32;
00089 
00090 /*-----------------------------------------------------------------------------
00091                                 Functions code
00092  -----------------------------------------------------------------------------*/
00093 
00094 /*----------------------------------------------------------------------------*/
00103 /*----------------------------------------------------------------------------*/
00104 int cpl_plugin_get_info(cpl_pluginlist * list)
00105 {
00106     cpl_recipe  *   recipe = cpl_calloc(1, sizeof(*recipe));
00107     cpl_plugin  *   plugin = &recipe->interface;
00108 
00109 
00110     if (cpl_plugin_init(plugin,
00111                     CPL_PLUGIN_API,
00112                     VISIR_BINARY_VERSION,
00113                     CPL_PLUGIN_TYPE_RECIPE,
00114                     recipename,
00115                     "Convert a text file into a FITS standard star catalog",
00116                     visir_util_spc_std_cat_description,
00117                     "Lars Lundin",
00118                     PACKAGE_BUGREPORT,
00119                     visir_get_license(),
00120                     visir_util_spc_std_cat_create,
00121                     visir_util_spc_std_cat_exec,
00122                     visir_util_spc_std_cat_destroy)) return 1;
00123 
00124     if (cpl_pluginlist_append(list, plugin)) return 1;
00125     
00126     return 0;
00127 }
00128 
00129 /*----------------------------------------------------------------------------*/
00138 /*----------------------------------------------------------------------------*/
00139 static int visir_util_spc_std_cat_create(cpl_plugin * plugin)
00140 {
00141     cpl_recipe * recipe = (cpl_recipe *)plugin;
00142 
00143     /* Verify plugin type */
00144     if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00145 
00146     /* Create the parameters list in the cpl_recipe object */
00147     recipe->parameters = cpl_parameterlist_new();
00148 
00149     return 0;
00150 }
00151 
00152 /*----------------------------------------------------------------------------*/
00158 /*----------------------------------------------------------------------------*/
00159 static int visir_util_spc_std_cat_exec(cpl_plugin * plugin)
00160 {
00161     cpl_recipe * recipe = (cpl_recipe *)plugin;
00162 
00163     /* Verify plugin type */
00164     if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00165 
00166     return visir_util_spc_std_cat(recipe->parameters, recipe->frames);
00167 }
00168 
00169 /*----------------------------------------------------------------------------*/
00175 /*----------------------------------------------------------------------------*/
00176 static int visir_util_spc_std_cat_destroy(cpl_plugin * plugin)
00177 {
00178     cpl_recipe  *   recipe = (cpl_recipe *)plugin;
00179 
00180     /* Verify plugin type */
00181     if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00182     cpl_parameterlist_delete(recipe->parameters);
00183     return  0;
00184 }
00185 
00186 /*----------------------------------------------------------------------------*/
00197 /*----------------------------------------------------------------------------*/
00198 static int visir_util_spc_std_cat(
00199         const cpl_parameterlist * parlist,
00200         cpl_frameset            * framelist)
00201 {
00202     int                 nfiles;
00203     const cpl_frame *   frame;
00204     char            *   starnames = NULL;
00205     double          *   ras = NULL;       /* RAs */
00206     double          *   decs = NULL;      /* DECs */
00207     double          *   wls = NULL;       /* Wavelengths */
00208     double          *   vals = NULL;      /* Flux model */
00209     cpl_bivector    *   spectrum = NULL;  /* Flux model for one star */
00210     void            **  data = NULL;
00211     FILE            *   in = NULL;
00212     char                line[1024];
00213     const double        max_radius = VISIR_STAR_MAX_RADIUS;
00214     double              mindist;
00215     int                 iloc1, iloc2;
00216     int                 nvals;
00217     int                 i;
00218     
00219 
00220     if (cpl_error_get_code()) return cpl_error_get_code();
00221 
00222     /* Get the number of files */
00223     nfiles = cpl_frameset_get_size(framelist);
00224 
00225     skip_if (nfiles < 1);
00226     
00227     /* Allocate the data container */
00228     starnames = cpl_malloc(nfiles * starnamelen);
00229     ras  = cpl_malloc(nfiles * sizeof(double));
00230     decs = cpl_malloc(nfiles * sizeof(double));
00231 
00232     nvals = 2300; /* 1st guess at length of spectra */
00233 
00234     /* Loop on all input frames */
00235     for (i=0, frame = cpl_frameset_get_first(framelist); frame != NULL ;
00236          i++, frame = cpl_frameset_get_next(framelist)) {
00237         int ra1, ra2, dec1, dec2;
00238         double ra3, dec3;
00239         int nlen;
00240         char isign;
00241         /* Get file name */
00242         const char * filename = cpl_frame_get_filename(frame);
00243 
00244         skip_if (filename == NULL);
00245 
00246         /* Open the file */
00247         if ((in = fopen(filename, "r")) == NULL) {
00248             cpl_msg_error(__func__, "Could not open file number %d (%s)", i+1,
00249                           filename);
00250             skip_if (1);
00251         }
00252 
00253         /* Read header */
00254         /* Get RA and DEC */
00255         fgets(line, 1024, in);
00256 
00257         if (sscanf(line, "%d %d %lg %c%d %d %lg ", &ra1, &ra2, &ra3, &isign,
00258                     &dec1,  &dec2, &dec3) != 7) {
00259             cpl_msg_error(__func__, "Invalid first line in file number %d (%s)",
00260                           i+1, filename);
00261             skip_if (1);
00262         }
00263 
00264         /* Get the flux model */
00265         spectrum = cpl_bivector_new(nvals); /* Not much resizing needed */
00266         skip_if (visir_bivector_load(spectrum, in));
00267 
00268         fclose(in);
00269         in = NULL;
00270     
00271         if (i == 0) {
00272             nvals = cpl_bivector_get_size(spectrum); /* Get actual length */
00273             /* Allocate the data container */
00274             wls  = cpl_malloc(nfiles * nvals * sizeof(double));
00275             vals = cpl_malloc(nfiles * nvals * sizeof(double));
00276         } else if (nvals != cpl_bivector_get_size(spectrum)) {
00277             /* The number of vals must be the same in all files */
00278             cpl_msg_error(__func__, "Length of spectrum in file number %d (%s) is "
00279                           "different from the previous (with length %d)", i+1,
00280                           filename, nvals);
00281             skip_if (1);
00282         }
00283 
00284        skip_if (visir_star_convert(line, ra1, ra2, ra3, isign, dec1, dec2,
00285                                    dec3, cpl_bivector_get_y_data(spectrum),
00286                                    nvals, &(ras[i]), &(decs[i])));
00287 
00288         /* Get the star name. FIXME: Remove cast */
00289         nlen = snprintf(starnames+i*starnamelen, starnamelen,
00290                      qfits_get_base_name(qfits_get_root_name((char*)filename)));
00291         skip_if (nlen < 1);
00292         if (nlen >= starnamelen) {
00293             cpl_msg_error(__func__, "File number %d (%s) has too long (%d) "
00294                           "basename for the FITS table (max=%d)", i+1, filename,
00295                           nlen, starnamelen);
00296             skip_if(1);
00297         }
00298 
00299         memcpy(wls +i*nvals, cpl_bivector_get_x_data(spectrum),
00300                sizeof(double)*nvals);
00301         memcpy(vals+i*nvals, cpl_bivector_get_y_data(spectrum),
00302                sizeof(double)*nvals);
00303 
00304         cpl_bivector_delete(spectrum);
00305         spectrum = NULL;
00306 
00307     }
00308 
00309     skip_if (i != nfiles);
00310 
00311     /* Create the data section */
00312     data = cpl_malloc(5*sizeof(void*));
00313     data[0] = starnames;
00314     data[1] = ras;
00315     data[2] = decs;
00316     data[3] = wls;
00317     data[4] = vals;
00318 
00319     mindist = visir_star_dist_min(ras, decs, nfiles, &iloc1, &iloc2);
00320 
00321     if (mindist < max_radius)
00322         cpl_msg_warning(__func__, "The pair of closest stars is %s (%d) and %s "
00323                         "(%d) with the distance: %g",
00324                         cpl_frame_get_filename(cpl_frameset_get_frame(framelist,
00325                                                                  iloc1)), iloc1,
00326                         cpl_frame_get_filename(cpl_frameset_get_frame(framelist,
00327                                                                  iloc2)), iloc2,
00328                         mindist);
00329 
00330 
00331     else
00332         cpl_msg_info(__func__, "The pair of closest stars is %s (%d) and %s "
00333                      "(%d) with the distance: %g",
00334                      cpl_frame_get_filename(cpl_frameset_get_frame(framelist,
00335                                                                  iloc1)), iloc1,
00336                      cpl_frame_get_filename(cpl_frameset_get_frame(framelist,
00337                                                                  iloc2)), iloc2,
00338                      mindist);
00339     
00340     /* Save the table */
00341     cpl_msg_info(__func__, "Saving the table with %d rows each with a spectrum "
00342                  "length of %d", nfiles, nvals);
00343     if (visir_util_spc_std_cat_save(data, nvals, nfiles, parlist, framelist)) {
00344         cpl_msg_error(__func__, "Could not save products");
00345         skip_if (1);
00346     }
00347 
00348     end_skip;
00349 
00350     cpl_free(data);
00351     cpl_free(starnames);
00352     cpl_free(ras);
00353     cpl_free(decs);
00354     cpl_free(wls);
00355     cpl_free(vals);
00356 
00357     cpl_bivector_delete(spectrum);
00358     if (in) fclose(in);
00359 
00360     return cpl_error_get_code();
00361 }
00362 
00363 /*----------------------------------------------------------------------------*/
00376 /*----------------------------------------------------------------------------*/
00377 static int visir_util_spc_std_cat_save(
00378         void                **  data,
00379         int                     nvals,
00380         int                     nfiles,
00381         const cpl_parameterlist * parlist,
00382         cpl_frameset        *   set)
00383 {
00384     const char   * file = RECIPENAME ".fits";
00385     cpl_frame    * product_frame;
00386     qfits_header * qheader;
00387     qfits_table  * table;
00388     qfits_col    * col;
00389 
00390 
00391     visir_assure_code(data,    CPL_ERROR_NULL_INPUT);
00392     visir_assure_code(parlist, CPL_ERROR_NULL_INPUT);
00393     visir_assure_code(set,     CPL_ERROR_NULL_INPUT);
00394 
00395     visir_assure_code(cpl_parameterlist_get_size(parlist) == 0,
00396                     CPL_ERROR_UNSUPPORTED_MODE);
00397 
00398     /* SAVE THE TABLE */
00399     cpl_msg_info(__func__, "Writing %s" , file);
00400     
00401     /* Create the FITS header */
00402     qheader = qfits_table_prim_header_default();
00403     qfits_header_add(qheader, "INSTRUME", "VISIR", NULL, NULL);
00404     qfits_header_add(qheader, "PIPEFILE", (char*)file, NULL, NULL);
00405     qfits_header_add(qheader, "HIERARCH ESO PRO TYPE", "REDUCED", NULL, NULL);
00406     qfits_header_add(qheader, "HIERARCH ESO PRO CATG",
00407                      VISIR_SPEC_STD_CAT_PROCATG, NULL, NULL);
00408     qfits_header_add(qheader, "HIERARCH ESO PRO STATUS", "Ok", NULL, NULL);
00409     qfits_header_add(qheader, "HIERARCH ESO PRO REC1 ID",
00410                      (char*)recipename, NULL, NULL);
00411     qfits_header_add(qheader, "HIERARCH ESO PRO REC1 DRS ID", "CPL", NULL,NULL);
00412     qfits_header_add(qheader, "HIERARCH ESO PRO DATE",
00413                      qfits_get_date_iso8601(), NULL, NULL);
00414 
00415     /* Create the qfits table */
00416     table = qfits_table_new((char*)file, QFITS_BINTABLE, -1, 5, nfiles);
00417     col = table->col;
00418     qfits_col_fill(col, starnamelen, 0, sizeof(char), TFITS_BIN_TYPE_A, "STARS",
00419                    " ", " ", " ", 0, 0.0, 0, 1.0, 0);
00420     col++;
00421     qfits_col_fill(col, 1, 0, sizeof(double), TFITS_BIN_TYPE_D, "RA", " ",
00422                    " ", " ", 0, 0.0, 0, 1.0, starnamelen);
00423     col++;
00424     qfits_col_fill(col, 1, 0, sizeof(double), TFITS_BIN_TYPE_D, "DEC", " ",
00425                    " ", " ", 0, 0.0, 0, 1.0, starnamelen+sizeof(double));
00426     col++;
00427     qfits_col_fill(col, nvals, 0, sizeof(double), TFITS_BIN_TYPE_D, 
00428                    "WAVELENGTHS", " ", " ", " ", 0, 0.0, 0, 1.0,
00429                    starnamelen+2*sizeof(double));
00430     col++;
00431     qfits_col_fill(col, nvals, 0, sizeof(double), TFITS_BIN_TYPE_D, 
00432                    "MODEL_FLUX", " ", " ", " ", 0, 0.0, 0, 1.0,
00433                    starnamelen+2*sizeof(double)+nvals*sizeof(double));
00434     
00435     /* Save the file - data should be (const void **) ? */
00436     if (qfits_save_table_hdrdump((void**)data, table, qheader) == -1) {
00437         cpl_msg_error(__func__, "Could save the FITS file %s", file);
00438         qfits_header_destroy(qheader);
00439         qfits_table_close(table);
00440         visir_assure_code(0, CPL_ERROR_FILE_IO);
00441     }
00442     qfits_header_destroy(qheader);
00443     qfits_table_close(table);
00444  
00445     /* Create product frame */
00446     product_frame = cpl_frame_new();
00447     cpl_frame_set_filename(product_frame, file);
00448     cpl_frame_set_tag(product_frame, VISIR_SPEC_STD_CAT_PROCATG);
00449     cpl_frame_set_type(product_frame, CPL_FRAME_TYPE_TABLE);
00450     cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
00451     cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
00452 
00453     /* Log the saved file in the input frameset */
00454     cpl_frameset_insert(set, product_frame);
00455     
00456     return cpl_error_get_code();
00457 }

Generated on Mon Jan 23 12:16:37 2006 for VISIR Pipeline Reference Manual by doxygen1.2.18