IIINSTRUMENT Pipeline Reference Manual 4.4.3
visir_img_illu.c
1/* $Id: visir_img_illu.c,v 1.84 2009-02-27 10:43:29 llundin Exp $
2 *
3 * This file is part of the VISIR 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: 2009-02-27 10:43:29 $
24 * $Revision: 1.84 $
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 "visir_recipe.h"
37
38/*-----------------------------------------------------------------------------
39 Defines
40-----------------------------------------------------------------------------*/
41
42#define RECIPE_STRING "visir_img_illu"
43
44/*-----------------------------------------------------------------------------
45 Private Functions prototypes
46 -----------------------------------------------------------------------------*/
47static cpl_image * visir_img_illu_fit(const cpl_table *, int, int);
48static cpl_error_code visir_img_illu_save(cpl_frameset *,
49 const cpl_parameterlist *,
50 const cpl_table *,
51 const cpl_image *);
52
53VISIR_RECIPE_DEFINE(visir_img_illu,
54 VISIR_PARAM_NODPOS | VISIR_PARAM_AUTOBPM |
55 VISIR_PARAM_STRIPITE | VISIR_PARAM_STRIPMOR |
56 VISIR_PARAM_STRIPNON |
57 VISIR_PARAM_GLITCH | VISIR_PARAM_PURGE,
58 "Illumination recipe",
59 "This recipe compares the illumination of a bright star "
60 "at different\n"
61 "positions on the detector. It produces a normalised "
62 "illumination map.\n"
63 "The files listed in the Set Of Frames (sof-file) "
64 "must be tagged:\n"
65 "VISIR-illumination-file.fits " VISIR_IMG_ILLU_RAW "\n"
66 MAN_VISIR_CALIB_BPM_IMG);
67
68/*----------------------------------------------------------------------------*/
72/*----------------------------------------------------------------------------*/
73
74/*-----------------------------------------------------------------------------
75 Functions code
76 -----------------------------------------------------------------------------*/
77
78/*----------------------------------------------------------------------------*/
85/*----------------------------------------------------------------------------*/
86static int visir_img_illu(cpl_frameset * framelist,
87 const cpl_parameterlist * parlist)
88{
89 irplib_framelist * allframes = NULL;
90 irplib_framelist * rawframes = NULL;
91 const char * badpix;
92 const char * flat;
93 cpl_imagelist * nodded = NULL;
94 cpl_table * tab = NULL;
95 cpl_image * fitted = NULL;
96 int nx, ny;
97 int nfiles;
98
99
100 /* Identify the RAW and CALIB frames in the input frameset */
101 skip_if (visir_dfs_set_groups(framelist));
102
103 /* Objects observation */
104 allframes = irplib_framelist_cast(framelist);
105 skip_if(allframes == NULL);
106 rawframes = irplib_framelist_extract(allframes, VISIR_IMG_ILLU_RAW);
107 skip_if (rawframes == NULL);
108
109 skip_if(irplib_framelist_load_propertylist_all(rawframes, 0,
110 visir_property_regexp,
111 CPL_FALSE));
112
113 skip_if(visir_dfs_check_framelist_tag(rawframes));
114
115 /* Bad pixels calibration file */
116 badpix = irplib_frameset_find_file(framelist, VISIR_CALIB_BPM);
117
118 /* Flatfield calibration file */
119 flat = irplib_frameset_find_file(framelist, VISIR_CALIB_FLAT);
120
121 /* Combine the frames */
122 cpl_msg_info(cpl_func, "Construct the nodded images");
123 nodded = visir_inputs_combine(RECIPE_STRING, parlist, rawframes, badpix, flat,
124 NULL, CPL_FALSE, 0.0,0);
125 if (nodded == NULL) {
126 cpl_msg_error(cpl_func, "Could not combine the input frames");
127 skip_if(1);
128 }
129
130 nfiles = cpl_imagelist_get_size(nodded);
131 nx = cpl_image_get_size_x(cpl_imagelist_get(nodded, 0));
132 ny = cpl_image_get_size_y(cpl_imagelist_get(nodded, 0));
133 skip_if (0);
134
135 /* Allocate and initialise arrays */
136 tab = visir_table_new_xypos(nodded, "FLUX");
137 skip_if (tab == NULL);
138
139 /* Get the illumination */
140 cpl_msg_info(cpl_func, "Detect the objects and compute the flux");
141
142 /* Fit the polynomial */
143 cpl_msg_info(cpl_func, "Fit a 2d polynomial on the flux");
144 if ((fitted = visir_img_illu_fit(tab, nx, ny)) == NULL) {
145 cpl_msg_error(cpl_func, "Could not compute the fit: '%s' in %s",
146 cpl_error_get_message(), cpl_error_get_where());
147 skip_if(1);
148 }
149
150 /* Save the products */
151 cpl_msg_info(cpl_func, "Saving products");
152 skip_if (visir_img_illu_save(framelist, parlist, tab, fitted));
153
154 end_skip;
155
156 irplib_framelist_delete(allframes);
157 irplib_framelist_delete(rawframes);
158 cpl_imagelist_delete(nodded);
159 cpl_image_delete(fitted);
160 cpl_table_delete(tab);
161
162 return cpl_error_get_code();
163}
164
165/*----------------------------------------------------------------------------*/
173/*----------------------------------------------------------------------------*/
174static cpl_image * visir_img_illu_fit(
175 const cpl_table * tab,
176 int nx,
177 int ny)
178{
179 const int nrow = cpl_table_get_nrow(tab);
180 cpl_polynomial * pol;
181 cpl_bivector * surface;
182 cpl_vector * x_pos;
183 cpl_vector * y_pos;
184 cpl_vector * values;
185 double norm;
186 cpl_image * fitted;
187 double xpos, ypos, flux;
188 double mse = -1;
189 int npoints = 0;
190 int i;
191
192
193 /* This will catch tab == NULL */
194 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
195
196
197 /* Count the number of valid FWHMs values */
198 for (i=0 ; i < nrow ; i++)
199 if (cpl_table_get_double(tab, "X_POS", i, NULL) > 0 &&
200 cpl_table_get_double(tab, "Y_POS", i, NULL) > 0)
201 npoints++;
202
203 assert(!cpl_error_get_code());
204
205 /* Need at least six data-points to fit a 2nd degree 2D-polynomial */
206 cpl_ensure(npoints >= 6, CPL_ERROR_DATA_NOT_FOUND, NULL);
207
208 /* Fill the grid to fit */
209 surface = cpl_bivector_new(npoints);
210 x_pos = cpl_bivector_get_x(surface);
211 y_pos = cpl_bivector_get_y(surface);
212 values = cpl_vector_new(npoints);
213 npoints = 0;
214 for (i=0 ; i < nrow ; i++) {
215 xpos = cpl_table_get_double(tab, "X_POS", i, NULL);
216 if (xpos <= 0) continue;
217 ypos = cpl_table_get_double(tab, "Y_POS", i, NULL);
218 if (ypos <= 0) continue;
219
220 flux = cpl_table_get_double(tab, "FLUX", i, NULL);
221
222
223 cpl_vector_set(x_pos, npoints, xpos);
224 cpl_vector_set(y_pos, npoints, ypos);
225 cpl_vector_set(values, npoints, flux);
226 npoints++;
227 }
228
229 /* Normalise the grid */
230 norm = cpl_vector_get(values, npoints/2 );
231 cpl_vector_divide_scalar(values, norm);
232
233 if (cpl_error_get_code()) {
234 cpl_bivector_delete(surface);
235 cpl_vector_delete(values);
236 return NULL;
237 }
238
239 /* Apply the fit */
240 pol = cpl_polynomial_fit_2d_create(surface, values, 2, &mse);
241 cpl_msg_info(cpl_func, "Mean Squared Error(%d): %g", npoints, mse);
242
243 cpl_bivector_delete(surface);
244 cpl_vector_delete(values);
245
246 if (pol == NULL) return NULL;
247
248 /* Generate the polynomial image */
249 fitted = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
250 if (cpl_image_fill_polynomial(fitted, pol, 1.0, 1.0, 1.0, 1.0)) {
251 cpl_image_delete(fitted);
252 cpl_polynomial_delete(pol);
253 return NULL;
254 }
255 cpl_polynomial_delete(pol);
256
257 return fitted;
258}
259
260/*----------------------------------------------------------------------------*/
269/*----------------------------------------------------------------------------*/
270static cpl_error_code visir_img_illu_save(cpl_frameset * set,
271 const cpl_parameterlist * parlist,
272 const cpl_table * tab,
273 const cpl_image * fitted)
274{
275
276
277 bug_if(0);
278
279 /* SAVE THE TABLE - and THE IMAGE */
280 skip_if (irplib_dfs_save_table(set, parlist, set, tab, NULL, RECIPE_STRING,
281 VISIR_IMG_ILLU_TAB_PROCATG, NULL, NULL,
282 visir_pipe_id,
283 RECIPE_STRING "_tab" CPL_DFS_FITS));
284
285 if (fitted)
286 skip_if(irplib_dfs_save_image(set, parlist, set, fitted, CPL_BPP_IEEE_FLOAT,
287 RECIPE_STRING, VISIR_IMG_ILLU_FITTED_PROCATG,
288 NULL, NULL, visir_pipe_id,
289 RECIPE_STRING CPL_DFS_FITS));
290
291 end_skip;
292
293 return cpl_error_get_code();
294}
cpl_error_code visir_dfs_check_framelist_tag(const irplib_framelist *self)
Check the tags in a frameset (group raw only)
Definition: visir_dfs.c:234
int visir_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: visir_dfs.c:72
cpl_imagelist * visir_inputs_combine(const char *recipename, const cpl_parameterlist *parlist, const irplib_framelist *rawframes, const char *badpix, const char *flat, int *nodding_p, cpl_boolean do_spc_fix, double wlen, visir_spc_resol resol)
The VISIR input data re-combination is performed here.
Definition: visir_inputs.c:808