naco_util_spc_model.c

00001 /* $Id: naco_util_spc_model.c,v 1.10 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., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2011-12-22 11:21:03 $
00024  * $Revision: 1.10 $
00025  * $Name: not supported by cvs2svn $
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 "naco_spc.h"
00041 
00042 /*-----------------------------------------------------------------------------
00043                             Recipe defines
00044  -----------------------------------------------------------------------------*/
00045 
00046 #define RECIPE_STRING "naco_util_spc_model"
00047 
00048 #ifndef NACO_SPC_MODEL_SIZE
00049 #define NACO_SPC_MODEL_SIZE 1024
00050 #endif
00051 
00052 /*-----------------------------------------------------------------------------
00053                             Private Functions prototypes
00054  -----------------------------------------------------------------------------*/
00055 
00056 NACO_RECIPE_DEFINE(naco_util_spc_model, 0,
00057                    "Generate FITS table with physical spectro model",
00058                    "The sof file shall consist of 1 line with the name of an "
00059                    "ASCII-file\n"
00060                    "currently tagged with " NACO_SPC_MODEL_ASCII ".\n"
00061                    "The file must comprise these "
00062                    IRPLIB_STRINGIFY(NACO_SPC_MODEL_COLS) " columns:\n"
00063                    NACO_SPC_LAB_MODE
00064                    " (with a value found in " NACO_PFITS_STRING_SPECMODE ")\n"
00065                    NACO_SPC_LAB_RESID
00066                    " (with fitting residual, currently ignored)\n"
00067                    NACO_SPC_LAB_ORDER
00068                    " (with the number of fitted coefficients in the "
00069                    "Legendre polynomial)\n"
00070                    NACO_SPC_LAB_XMIN
00071                    " (with the minimum pixel value used for the fit)\n"
00072                    NACO_SPC_LAB_XMAX
00073                    " (with the maximum pixel value used for the fit)\n"
00074                    NACO_SPC_LAB_C1
00075                    " (with the coefficient of the 1st Legendre term)\n"
00076                    NACO_SPC_LAB_C2
00077                    " (with the coefficient of the 2nd Legendre term)\n"
00078                    NACO_SPC_LAB_C3
00079                    " (with the coefficient of the 3rd Legendre term)\n"
00080                    NACO_SPC_LAB_C4
00081                    " (with the coefficient of the 4th Legendre term)\n"
00082                    "\n"
00083                    "The default input ASCII-file is in the catalogs/ "
00084                    "directory of the NACO source-code distribution.");
00085 
00086 static IRPLIB_UTIL_SET_ROW(naco_util_spc_model_set_row);
00087 static IRPLIB_UTIL_CHECK(naco_util_spc_model_check);
00088 
00089 static double naco_util_spc_model_eval(double, double *, double, double,
00090                                        double, double, double, double);
00091 
00092 /*----------------------------------------------------------------------------*/
00096 /*----------------------------------------------------------------------------*/
00097 
00098 /*-----------------------------------------------------------------------------
00099 
00100                                 Functions code
00101  -----------------------------------------------------------------------------*/
00102 
00103 /*----------------------------------------------------------------------------*/
00110 /*----------------------------------------------------------------------------*/
00111 static int naco_util_spc_model(cpl_frameset            * framelist,
00112                                const cpl_parameterlist * parlist)
00113 {
00114     irplib_framelist * allframes = NULL;
00115     irplib_framelist * rawframes = NULL;
00116     cpl_frameset     * useframes = NULL;
00117     cpl_table        * self      = NULL;
00118     
00119 
00120     if (cpl_error_get_code()) return cpl_error_get_code();
00121 
00122     /* Identify the RAW frames in the input frameset */
00123     skip_if (naco_dfs_set_groups(framelist));
00124 
00125     /* FIXME: Using framelists is the simplest way to extract the relevant
00126        frames :-( */
00127 
00128     allframes = irplib_framelist_cast(framelist);
00129     bug_if(allframes == NULL);
00130 
00131     rawframes = irplib_framelist_extract(allframes, NACO_SPC_MODEL_ASCII);
00132     skip_if (rawframes == NULL);
00133 
00134     irplib_framelist_empty(allframes);
00135 
00136     useframes = irplib_frameset_cast(rawframes);
00137     bug_if(allframes == NULL);
00138 
00139     /* At least one row per file */
00140     self = cpl_table_new(irplib_framelist_get_size(rawframes));
00141 
00142     irplib_framelist_empty(rawframes);
00143 
00144 
00145     /* Create the table columns - with units */
00146     bug_if (cpl_table_new_column(self, NACO_SPC_LAB_MODE,  CPL_TYPE_STRING));
00147     bug_if (cpl_table_new_column(self, NACO_SPC_LAB_ORDER, CPL_TYPE_INT));
00148     bug_if (cpl_table_new_column(self, NACO_SPC_LAB_RESID, CPL_TYPE_DOUBLE));
00149     bug_if (cpl_table_new_column(self, NACO_SPC_LAB_XMIN,  CPL_TYPE_DOUBLE));
00150     bug_if (cpl_table_new_column(self, NACO_SPC_LAB_XMAX,  CPL_TYPE_DOUBLE));
00151     bug_if (cpl_table_new_column(self, NACO_SPC_LAB_C1,    CPL_TYPE_DOUBLE));
00152     bug_if (cpl_table_new_column(self, NACO_SPC_LAB_C2,    CPL_TYPE_DOUBLE));
00153     bug_if (cpl_table_new_column(self, NACO_SPC_LAB_C3,    CPL_TYPE_DOUBLE));
00154     bug_if (cpl_table_new_column(self, NACO_SPC_LAB_C4,    CPL_TYPE_DOUBLE));
00155 
00156     bug_if(cpl_table_set_column_unit(self, NACO_SPC_LAB_XMIN, "pixel"));
00157     bug_if(cpl_table_set_column_unit(self, NACO_SPC_LAB_XMAX, "pixel"));
00158     bug_if(cpl_table_set_column_unit(self, NACO_SPC_LAB_C1,   "Angstrom"));
00159     bug_if(cpl_table_set_column_unit(self, NACO_SPC_LAB_C2,   "Angstrom"));
00160     bug_if(cpl_table_set_column_unit(self, NACO_SPC_LAB_C3,   "Angstrom"));
00161     bug_if(cpl_table_set_column_unit(self, NACO_SPC_LAB_C4,   "Angstrom"));
00162 
00163 
00164     skip_if(irplib_dfs_table_convert(self, framelist, useframes, 
00165                                      NACO_SPC_MODEL_SIZE, '#', NULL,
00166                                      NACO_SPC_MODEL, parlist, RECIPE_STRING,
00167                                      NULL, NULL, NULL, "NACO", naco_pipe_id,
00168                                      naco_util_spc_model_set_row,
00169                                      naco_util_spc_model_check));
00170     end_skip;
00171 
00172     cpl_table_delete(self);
00173     cpl_frameset_delete(useframes);
00174     irplib_framelist_delete(allframes);
00175     irplib_framelist_delete(rawframes);
00176 
00177     return cpl_error_get_code();
00178 }
00179 
00180 /*----------------------------------------------------------------------------*/
00192 /*----------------------------------------------------------------------------*/
00193 static
00194 cpl_boolean naco_util_spc_model_set_row(cpl_table * self,
00195                                         const char * line,
00196                                         int irow,
00197                                         const cpl_frame * rawframe,
00198                                         const cpl_parameterlist * parlist)
00199 {
00200 
00201 
00202     /* gcc can only check sscanf()s format when it is a string literal */
00203 #define FORMAT "%s %lg %d %lg %lg %lg %lg %lg %lg"
00204 
00205     int nvals;
00206     char mode[NACO_SPC_MODEL_SIZE];
00207     double resid, xmin, xmax;
00208     double c1, c2, c3, c4;
00209     int order;
00210 
00211     double wlmin, wlmax;
00212     double nf, wlf, pposf;
00213     double nc, wlc, pposc;
00214     double nl, wll, pposl;
00215 
00216 
00217     bug_if(0);
00218     bug_if(self     == NULL);
00219     bug_if(line     == NULL);
00220     bug_if(irow   <  0);
00221     bug_if(rawframe == NULL);
00222     bug_if(parlist  == NULL);
00223 
00224     nvals = sscanf(line, FORMAT, mode, &resid, &order, &xmin, &xmax,
00225                    &c1, &c2, &c3, &c4);
00226 
00227     error_if (nvals != NACO_SPC_MODEL_COLS, CPL_ERROR_BAD_FILE_FORMAT,
00228               "Line with length=%u has %d not "
00229               IRPLIB_STRINGIFY(NACO_SPC_MODEL_COLS) " items formatted: %s",
00230               (unsigned)strlen(line), nvals, FORMAT);
00231 
00232     error_if (order > NACO_SPC_MODEL_COEFFS, CPL_ERROR_BAD_FILE_FORMAT,
00233               "Too high fit order=%d > " IRPLIB_STRINGIFY(NACO_SPC_MODEL_COEFFS)
00234               " in line %s", order, line);
00235 
00236     error_if (order < 2, CPL_ERROR_BAD_FILE_FORMAT,
00237               "Too low fit order=%d < 2 in line %s", order, line);
00238 
00239     error_if (xmin < 0.0, CPL_ERROR_BAD_FILE_FORMAT,
00240               "Negative XMin=%g in line %s", xmin, line);
00241 
00242     error_if (xmax <= xmin, CPL_ERROR_BAD_FILE_FORMAT,
00243               "XMax=%g is not greater than XMin=%g in line %s", xmax,
00244               xmin, line);
00245 
00246 
00247     bug_if(cpl_table_set_string(self, NACO_SPC_LAB_MODE,  irow, mode));
00248     bug_if(cpl_table_set_double(self, NACO_SPC_LAB_RESID, irow, resid));
00249     bug_if(cpl_table_set_int   (self, NACO_SPC_LAB_ORDER, irow, order));
00250     bug_if(cpl_table_set_double(self, NACO_SPC_LAB_XMIN,  irow, xmin));
00251     bug_if(cpl_table_set_double(self, NACO_SPC_LAB_XMAX,  irow, xmax));
00252     bug_if(cpl_table_set_double(self, NACO_SPC_LAB_C1,    irow, c1));
00253     bug_if(cpl_table_set_double(self, NACO_SPC_LAB_C2,    irow, c2));
00254     bug_if(cpl_table_set_double(self, NACO_SPC_LAB_C3,    irow, c3));
00255     bug_if(cpl_table_set_double(self, NACO_SPC_LAB_C4,    irow, c4));
00256 
00257     wlmin = naco_util_spc_model_eval(-1.0, NULL, xmin, xmax, c1, c2, c3, c4);
00258     wlmax = naco_util_spc_model_eval( 1.0, NULL, xmin, xmax, c1, c2, c3, c4);
00259 
00260     cpl_msg_info(cpl_func, "%-10s has range [Angstrom @ pixel]: "
00261                  "%8.2f @ %6.2f => %8.2f @ %6.2f", mode, wlmin, xmin, wlmax, xmax);
00262 
00263     /* Pixel position 1, 512.5 and 1024 */
00264     nf = (2.0 * 1.0 - (xmax + xmin)) / (xmax - xmin);
00265     wlf = naco_util_spc_model_eval(nf, &pposf, xmin, xmax, c1, c2, c3, c4);
00266 
00267     nc = (2.0 * 512.5 - (xmax + xmin)) / (xmax - xmin);
00268     wlc = naco_util_spc_model_eval(nc, &pposc, xmin, xmax, c1, c2, c3, c4);
00269 
00270     nl = (2.0 * 1024.0 - (xmax + xmin)) / (xmax - xmin);
00271     wll = naco_util_spc_model_eval(nl, &pposl, xmin, xmax, c1, c2, c3, c4);
00272 
00273     cpl_msg_info(cpl_func, "%-10s detector full range [Angstrom @ pixel]: "
00274                  "%8.2f @ %6.2f => %8.2f @ %6.2f => %8.2f @ %6.2f", mode, wlf, pposf, wlc, pposc, wll, pposl);
00275 
00276 
00277     end_skip;
00278 
00279     return CPL_TRUE;
00280 
00281 }
00282 
00283 
00284 /*----------------------------------------------------------------------------*/
00293 /*----------------------------------------------------------------------------*/
00294 static
00295 cpl_error_code naco_util_spc_model_check(cpl_table * self,
00296                                          const cpl_frameset * useframes,
00297                                          const cpl_parameterlist * parlist)
00298 {
00299 
00300     bug_if(0);
00301     bug_if(self     == NULL);
00302     bug_if(parlist  == NULL);
00303 
00304     cpl_msg_info(cpl_func, "Created table of %d spectrum modes from %d file(s)",
00305                  (int)cpl_table_get_nrow(self),
00306                  (int)cpl_frameset_get_size(useframes));
00307 
00308     end_skip;
00309 
00310     return cpl_error_get_code();
00311 }
00312 
00313 /*----------------------------------------------------------------------------*/
00337 /*----------------------------------------------------------------------------*/
00338 static double naco_util_spc_model_eval(double x, double * pp, double pmin,
00339                                        double pmax,
00340                                        double c1, double c2,
00341                                        double c3, double c4)
00342 {
00343 
00344     const double value
00345         = c1 - 0.5*c3 + x*( c2 - 1.5 * c4 + x*( 1.5 * c3 + x*( 2.5 * c4 )));
00346 
00347     if (pp != NULL) *pp = 0.5 * ( (pmax + pmin) + x * (pmax - pmin) );
00348 
00349     return value;
00350 
00351 }
Generated on Mon Feb 17 15:01:45 2014 for NACO Pipeline Reference Manual by  doxygen 1.6.3