IIINSTRUMENT Pipeline Reference Manual 4.4.12
naco_util_spc_model.c
1/* $Id: naco_util_spc_model.c,v 1.10 2011-12-22 11:21:03 llundin Exp $
2 *
3 * This file is part of the NACO Pipeline
4 * Copyright (C) 2002,2003 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * $Author: llundin $
23 * $Date: 2011-12-22 11:21:03 $
24 * $Revision: 1.10 $
25 * $Name: not supported by cvs2svn $
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32/*-----------------------------------------------------------------------------
33 Includes
34 -----------------------------------------------------------------------------*/
35
36#include <string.h>
37
38#include "naco_recipe.h"
39
40#include "naco_spc.h"
41
42/*-----------------------------------------------------------------------------
43 Recipe defines
44 -----------------------------------------------------------------------------*/
45
46#define RECIPE_STRING "naco_util_spc_model"
47
48#ifndef NACO_SPC_MODEL_SIZE
49#define NACO_SPC_MODEL_SIZE 1024
50#endif
51
52/*-----------------------------------------------------------------------------
53 Private Functions prototypes
54 -----------------------------------------------------------------------------*/
55
56NACO_RECIPE_DEFINE(naco_util_spc_model, 0,
57 "Generate FITS table with physical spectro model",
58 "The sof file shall consist of 1 line with the name of an "
59 "ASCII-file\n"
60 "currently tagged with " NACO_SPC_MODEL_ASCII ".\n"
61 "The file must comprise these "
62 IRPLIB_STRINGIFY(NACO_SPC_MODEL_COLS) " columns:\n"
63 NACO_SPC_LAB_MODE
64 " (with a value found in " NACO_PFITS_STRING_SPECMODE ")\n"
65 NACO_SPC_LAB_RESID
66 " (with fitting residual, currently ignored)\n"
67 NACO_SPC_LAB_ORDER
68 " (with the number of fitted coefficients in the "
69 "Legendre polynomial)\n"
70 NACO_SPC_LAB_XMIN
71 " (with the minimum pixel value used for the fit)\n"
72 NACO_SPC_LAB_XMAX
73 " (with the maximum pixel value used for the fit)\n"
74 NACO_SPC_LAB_C1
75 " (with the coefficient of the 1st Legendre term)\n"
76 NACO_SPC_LAB_C2
77 " (with the coefficient of the 2nd Legendre term)\n"
78 NACO_SPC_LAB_C3
79 " (with the coefficient of the 3rd Legendre term)\n"
80 NACO_SPC_LAB_C4
81 " (with the coefficient of the 4th Legendre term)\n"
82 "\n"
83 "The default input ASCII-file is in the catalogs/ "
84 "directory of the NACO source-code distribution.");
85
86static IRPLIB_UTIL_SET_ROW(naco_util_spc_model_set_row);
87static IRPLIB_UTIL_CHECK(naco_util_spc_model_check);
88
89static double naco_util_spc_model_eval(double, double *, double, double,
90 double, double, double, double);
91
92/*----------------------------------------------------------------------------*/
96/*----------------------------------------------------------------------------*/
97
98/*-----------------------------------------------------------------------------
99
100 Functions code
101 -----------------------------------------------------------------------------*/
102
103/*----------------------------------------------------------------------------*/
110/*----------------------------------------------------------------------------*/
111static int naco_util_spc_model(cpl_frameset * framelist,
112 const cpl_parameterlist * parlist)
113{
114 irplib_framelist * allframes = NULL;
115 irplib_framelist * rawframes = NULL;
116 cpl_frameset * useframes = NULL;
117 cpl_table * self = NULL;
118
119
120 if (cpl_error_get_code()) return cpl_error_get_code();
121
122 /* Identify the RAW frames in the input frameset */
123 skip_if (naco_dfs_set_groups(framelist));
124
125 /* FIXME: Using framelists is the simplest way to extract the relevant
126 frames :-( */
127
128 allframes = irplib_framelist_cast(framelist);
129 bug_if(allframes == NULL);
130
131 rawframes = irplib_framelist_extract(allframes, NACO_SPC_MODEL_ASCII);
132 skip_if (rawframes == NULL);
133
134 irplib_framelist_empty(allframes);
135
136 useframes = irplib_frameset_cast(rawframes);
137 bug_if(allframes == NULL);
138
139 /* At least one row per file */
140 self = cpl_table_new(irplib_framelist_get_size(rawframes));
141
142 irplib_framelist_empty(rawframes);
143
144
145 /* Create the table columns - with units */
146 bug_if (cpl_table_new_column(self, NACO_SPC_LAB_MODE, CPL_TYPE_STRING));
147 bug_if (cpl_table_new_column(self, NACO_SPC_LAB_ORDER, CPL_TYPE_INT));
148 bug_if (cpl_table_new_column(self, NACO_SPC_LAB_RESID, CPL_TYPE_DOUBLE));
149 bug_if (cpl_table_new_column(self, NACO_SPC_LAB_XMIN, CPL_TYPE_DOUBLE));
150 bug_if (cpl_table_new_column(self, NACO_SPC_LAB_XMAX, CPL_TYPE_DOUBLE));
151 bug_if (cpl_table_new_column(self, NACO_SPC_LAB_C1, CPL_TYPE_DOUBLE));
152 bug_if (cpl_table_new_column(self, NACO_SPC_LAB_C2, CPL_TYPE_DOUBLE));
153 bug_if (cpl_table_new_column(self, NACO_SPC_LAB_C3, CPL_TYPE_DOUBLE));
154 bug_if (cpl_table_new_column(self, NACO_SPC_LAB_C4, CPL_TYPE_DOUBLE));
155
156 bug_if(cpl_table_set_column_unit(self, NACO_SPC_LAB_XMIN, "pixel"));
157 bug_if(cpl_table_set_column_unit(self, NACO_SPC_LAB_XMAX, "pixel"));
158 bug_if(cpl_table_set_column_unit(self, NACO_SPC_LAB_C1, "Angstrom"));
159 bug_if(cpl_table_set_column_unit(self, NACO_SPC_LAB_C2, "Angstrom"));
160 bug_if(cpl_table_set_column_unit(self, NACO_SPC_LAB_C3, "Angstrom"));
161 bug_if(cpl_table_set_column_unit(self, NACO_SPC_LAB_C4, "Angstrom"));
162
163
164 skip_if(irplib_dfs_table_convert(self, framelist, useframes,
165 NACO_SPC_MODEL_SIZE, '#', NULL,
166 NACO_SPC_MODEL, parlist, RECIPE_STRING,
167 NULL, NULL, NULL, "NACO", naco_pipe_id,
168 naco_util_spc_model_set_row,
169 naco_util_spc_model_check));
170 end_skip;
171
172 cpl_table_delete(self);
173 cpl_frameset_delete(useframes);
174 irplib_framelist_delete(allframes);
175 irplib_framelist_delete(rawframes);
176
177 return cpl_error_get_code();
178}
179
180/*----------------------------------------------------------------------------*/
192/*----------------------------------------------------------------------------*/
193static
194cpl_boolean naco_util_spc_model_set_row(cpl_table * self,
195 const char * line,
196 int irow,
197 const cpl_frame * rawframe,
198 const cpl_parameterlist * parlist)
199{
200
201
202 /* gcc can only check sscanf()s format when it is a string literal */
203#define FORMAT "%" CPL_STRINGIFY(NACO_SPC_MODEL_SIZE) \
204 "s %lg %d %lg %lg %lg %lg %lg %lg"
205
206 int nvals;
207 char mode[NACO_SPC_MODEL_SIZE + 1];
208 double resid, xmin, xmax;
209 double c1, c2, c3, c4;
210 int order;
211
212 double wlmin, wlmax;
213 double nf, wlf, pposf;
214 double nc, wlc, pposc;
215 double nl, wll, pposl;
216
217
218 bug_if(0);
219 bug_if(self == NULL);
220 bug_if(line == NULL);
221 bug_if(irow < 0);
222 bug_if(rawframe == NULL);
223 bug_if(parlist == NULL);
224
225 nvals = sscanf(line, FORMAT, mode, &resid, &order, &xmin, &xmax,
226 &c1, &c2, &c3, &c4);
227
228 error_if (nvals != NACO_SPC_MODEL_COLS, CPL_ERROR_BAD_FILE_FORMAT,
229 "Line with length=%u has %d not "
230 IRPLIB_STRINGIFY(NACO_SPC_MODEL_COLS) " items formatted: %s",
231 (unsigned)strlen(line), nvals, FORMAT);
232
233 error_if (order > NACO_SPC_MODEL_COEFFS, CPL_ERROR_BAD_FILE_FORMAT,
234 "Too high fit order=%d > " IRPLIB_STRINGIFY(NACO_SPC_MODEL_COEFFS)
235 " in line %s", order, line);
236
237 error_if (order < 2, CPL_ERROR_BAD_FILE_FORMAT,
238 "Too low fit order=%d < 2 in line %s", order, line);
239
240 error_if (xmin < 0.0, CPL_ERROR_BAD_FILE_FORMAT,
241 "Negative XMin=%g in line %s", xmin, line);
242
243 error_if (xmax <= xmin, CPL_ERROR_BAD_FILE_FORMAT,
244 "XMax=%g is not greater than XMin=%g in line %s", xmax,
245 xmin, line);
246
247
248 bug_if(cpl_table_set_string(self, NACO_SPC_LAB_MODE, irow, mode));
249 bug_if(cpl_table_set_double(self, NACO_SPC_LAB_RESID, irow, resid));
250 bug_if(cpl_table_set_int (self, NACO_SPC_LAB_ORDER, irow, order));
251 bug_if(cpl_table_set_double(self, NACO_SPC_LAB_XMIN, irow, xmin));
252 bug_if(cpl_table_set_double(self, NACO_SPC_LAB_XMAX, irow, xmax));
253 bug_if(cpl_table_set_double(self, NACO_SPC_LAB_C1, irow, c1));
254 bug_if(cpl_table_set_double(self, NACO_SPC_LAB_C2, irow, c2));
255 bug_if(cpl_table_set_double(self, NACO_SPC_LAB_C3, irow, c3));
256 bug_if(cpl_table_set_double(self, NACO_SPC_LAB_C4, irow, c4));
257
258 wlmin = naco_util_spc_model_eval(-1.0, NULL, xmin, xmax, c1, c2, c3, c4);
259 wlmax = naco_util_spc_model_eval( 1.0, NULL, xmin, xmax, c1, c2, c3, c4);
260
261 cpl_msg_info(cpl_func, "%-10s has range [Angstrom @ pixel]: "
262 "%8.2f @ %6.2f => %8.2f @ %6.2f", mode, wlmin, xmin, wlmax, xmax);
263
264 /* Pixel position 1, 512.5 and 1024 */
265 nf = (2.0 * 1.0 - (xmax + xmin)) / (xmax - xmin);
266 wlf = naco_util_spc_model_eval(nf, &pposf, xmin, xmax, c1, c2, c3, c4);
267
268 nc = (2.0 * 512.5 - (xmax + xmin)) / (xmax - xmin);
269 wlc = naco_util_spc_model_eval(nc, &pposc, xmin, xmax, c1, c2, c3, c4);
270
271 nl = (2.0 * 1024.0 - (xmax + xmin)) / (xmax - xmin);
272 wll = naco_util_spc_model_eval(nl, &pposl, xmin, xmax, c1, c2, c3, c4);
273
274 cpl_msg_info(cpl_func, "%-10s detector full range [Angstrom @ pixel]: "
275 "%8.2f @ %6.2f => %8.2f @ %6.2f => %8.2f @ %6.2f", mode, wlf, pposf, wlc, pposc, wll, pposl);
276
277
278 end_skip;
279
280 return CPL_TRUE;
281
282}
283
284
285/*----------------------------------------------------------------------------*/
294/*----------------------------------------------------------------------------*/
295static
296cpl_error_code naco_util_spc_model_check(cpl_table * self,
297 const cpl_frameset * useframes,
298 const cpl_parameterlist * parlist)
299{
300
301 bug_if(0);
302 bug_if(self == NULL);
303 bug_if(parlist == NULL);
304
305 cpl_msg_info(cpl_func, "Created table of %d spectrum modes from %d file(s)",
306 (int)cpl_table_get_nrow(self),
307 (int)cpl_frameset_get_size(useframes));
308
309 end_skip;
310
311 return cpl_error_get_code();
312}
313
314/*----------------------------------------------------------------------------*/
338/*----------------------------------------------------------------------------*/
339static double naco_util_spc_model_eval(double x, double * pp, double pmin,
340 double pmax,
341 double c1, double c2,
342 double c3, double c4)
343{
344
345 const double value
346 = c1 - 0.5*c3 + x*( c2 - 1.5 * c4 + x*( 1.5 * c3 + x*( 2.5 * c4 )));
347
348 if (pp != NULL) *pp = 0.5 * ( (pmax + pmin) + x * (pmax - pmin) );
349
350 return value;
351
352}
int naco_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: naco_dfs.c:62