IIINSTRUMENT Pipeline Reference Manual 4.5.1
visir_img_focfwhm.c
1/* $Id: visir_img_focfwhm.c,v 1.78 2009-02-27 10:37:28 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:37:28 $
24 * $Revision: 1.78 $
25 * $Name: not supported by cvs2svn $
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32
33
34/*-----------------------------------------------------------------------------
35 Includes
36 -----------------------------------------------------------------------------*/
37
38#include "visir_recipe.h"
39
40/*-----------------------------------------------------------------------------
41 Defines
42 -----------------------------------------------------------------------------*/
43
44#define RECIPE_STRING "visir_img_focfwhm"
45
46/*-----------------------------------------------------------------------------
47 Private Functions prototypes
48 -----------------------------------------------------------------------------*/
49static cpl_table * visir_img_focfwhm_detect(const cpl_imagelist *,
50 const irplib_framelist *);
51static double visir_img_focfwhm_best_focus(const cpl_table *);
52static cpl_error_code visir_img_focfwhm_save(cpl_frameset *,
53 const cpl_parameterlist *,
54 const cpl_table *);
55
56VISIR_RECIPE_DEFINE(visir_img_focfwhm,
57 VISIR_PARAM_NODPOS | VISIR_PARAM_AUTOBPM |
58 VISIR_PARAM_STRIPITE | VISIR_PARAM_STRIPMOR |
59 VISIR_PARAM_STRIPNON |
60 VISIR_PARAM_GLITCH | VISIR_PARAM_PURGE,
61 "Focus recipe",
62 "This recipe finds out what is the best focus of the "
63 "telescope\n"
64 "by analysing the evolution of the FWHM for different "
65 "focii.\n"
66 "The files listed in the Set Of Frames (sof-file) must be "
67 "tagged:\n"
68 "VISIR-focus-file.fits " VISIR_IMG_FOCFWHM_RAW "\n"
69 MAN_VISIR_CALIB_BPM_IMG);
70
71/*----------------------------------------------------------------------------*/
75/*----------------------------------------------------------------------------*/
76
77/*-----------------------------------------------------------------------------
78 Functions code
79 -----------------------------------------------------------------------------*/
80
81/*----------------------------------------------------------------------------*/
88/*----------------------------------------------------------------------------*/
89static int visir_img_focfwhm(cpl_frameset * framelist,
90 const cpl_parameterlist * parlist)
91{
92 irplib_framelist * allframes = NULL;
93 irplib_framelist * rawframes = NULL;
94 const char * badpix;
95 const char * flat;
96 cpl_imagelist * nodded = NULL;
97 cpl_table * tab = NULL;
98 double focus;
99
100
101 /* Identify the RAW and CALIB frames in the input frameset */
102 skip_if (visir_dfs_set_groups(framelist));
103
104 /* Objects observation */
105 allframes = irplib_framelist_cast(framelist);
106 skip_if(allframes == NULL);
107 rawframes = irplib_framelist_extract(allframes, VISIR_IMG_FOCFWHM_RAW);
108 skip_if (rawframes == NULL);
109
110 skip_if(irplib_framelist_load_propertylist_all(rawframes, 0,
111 visir_property_regexp,
112 CPL_FALSE));
113
114 skip_if(visir_dfs_check_framelist_tag(rawframes));
115
116 /* Bad pixels calibration file */
117 badpix = irplib_frameset_find_file(framelist, VISIR_CALIB_BPM);
118
119 /* Flatfield calibration file */
120 flat = irplib_frameset_find_file(framelist, VISIR_CALIB_FLAT);
121
122 /* Combine the frames */
123 cpl_msg_info(cpl_func, "Construct the nodded images");
124 nodded = visir_inputs_combine(RECIPE_STRING, parlist, rawframes, badpix, flat,
125 NULL, CPL_FALSE, 0,0);
126 if (nodded == NULL) {
127 cpl_msg_error(cpl_func, "Cannot combine the input frames");
128 skip_if(1);
129 }
130
131 /* Get apertures positions - FWHMs - FOCUS in a table */
132 cpl_msg_info(cpl_func, "Get positions/FWHMs/FOCUSs");
133 if ((tab = visir_img_focfwhm_detect(nodded, rawframes)) == NULL) {
134 cpl_msg_error(cpl_func, "Cannot detect apertures");
135 skip_if(1);
136 }
137 /* Compute the best FOCUS */
138 cpl_msg_info(cpl_func, "Compute the best focus");
139 focus = visir_img_focfwhm_best_focus(tab);
140 if (focus < 0) {
141 cpl_msg_error(cpl_func, "Cannot compute the best focus(%g): '%s' in %s",
142 focus, cpl_error_get_message(),
143 cpl_error_get_where());
144 skip_if(1);
145 }
146 /* Save the combined image */
147 cpl_msg_info(cpl_func, "Save the produced combined image");
148 skip_if (visir_img_focfwhm_save(framelist, parlist, tab));
149
150 end_skip;
151
152 irplib_framelist_delete(allframes);
153 irplib_framelist_delete(rawframes);
154 cpl_imagelist_delete(nodded);
155 cpl_table_delete(tab);
156
157 return cpl_error_get_code();
158}
159
160/*----------------------------------------------------------------------------*/
172/*----------------------------------------------------------------------------*/
173static cpl_table * visir_img_focfwhm_detect(const cpl_imagelist * nodded,
174 const irplib_framelist * rawframes)
175{
176 cpl_table * tab = NULL;
177 const int nfiles = cpl_imagelist_get_size(nodded);
178 int i;
179
180
181 /* Catch also empty imagelist */
182 skip_if (0);
183 skip_if (rawframes == NULL);
184
185 /* Allocate and initialise arrays */
186 tab = visir_table_new_xypos(nodded, "FWHM");
187 skip_if (tab == NULL);
188
189 skip_if (cpl_table_new_column(tab, "FOCUS", CPL_TYPE_DOUBLE));
190
191 /* Get infos on nodded images */
192 for (i=0; i < nfiles ; i++) {
193 const cpl_propertylist * plist
194 = irplib_framelist_get_propertylist_const(rawframes, 2*i);
195
196 /* Get the FOCUS from the header */
197 skip_if(cpl_table_set_double(tab, "FOCUS", i,
198 visir_pfits_get_focus(plist)));
199
200 }
201
202 end_skip;
203
204 if (cpl_error_get_code()) {
205 cpl_table_delete(tab);
206 tab = NULL;
207 }
208
209 return tab;
210}
211
212/*----------------------------------------------------------------------------*/
221/*----------------------------------------------------------------------------*/
222static double visir_img_focfwhm_best_focus(const cpl_table * tab)
223{
224 const int nrow = cpl_table_get_nrow(tab);
225 int ngood = 0;
226 cpl_vector * x_to_fit;
227 cpl_vector * y_to_fit;
228 cpl_polynomial * pol;
229 double fwhm_x, fwhm_y, focus;
230 double b, c;
231 double mse = -1;
232 int i;
233
234
235 /* This will catch tab == NULL */
236 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), -1);
237
238 /* Count the number of valid FWHMs values */
239 for (i=0 ; i < nrow ; i++)
240 if (cpl_table_get_double(tab, "X_FWHM", i, NULL) > 0 &&
241 cpl_table_get_double(tab, "Y_FWHM", i, NULL) > 0)
242 ngood++;
243
244 assert(!cpl_error_get_code());
245
246 /* Need at least three data-points to fit a 2nd degree polynomial */
247 cpl_ensure(ngood >= 3, CPL_ERROR_DATA_NOT_FOUND, -2);
248
249 /* Create the vectors for the fitting */
250 x_to_fit = cpl_vector_new(ngood);
251 y_to_fit = cpl_vector_new(ngood);
252 ngood = 0;
253 for (i=0 ; i < nrow ; i++) {
254 fwhm_x = cpl_table_get_double(tab, "X_FWHM", i, NULL);
255 if (fwhm_x <= 0) continue;
256
257 fwhm_y = cpl_table_get_double(tab, "Y_FWHM", i, NULL);
258 if (fwhm_y <= 0) continue;
259
260 focus = cpl_table_get_double(tab, "FOCUS", i, NULL);
261
262 cpl_vector_set(x_to_fit, ngood, focus);
263 cpl_vector_set(y_to_fit, ngood, (fwhm_x+fwhm_y)*0.5);
264 ngood++;
265 }
266
267 assert( ngood == cpl_vector_get_size(x_to_fit) );
268
269 /* Apply the fit */
270 pol = cpl_polynomial_fit_1d_create(x_to_fit, y_to_fit, 2, &mse);
271
272 cpl_msg_info(cpl_func, "Mean Squared Error(%d): %g", ngood, mse);
273
274 cpl_vector_delete(x_to_fit);
275 cpl_vector_delete(y_to_fit);
276
277 cpl_ensure(pol != NULL, cpl_error_get_code(), -3);
278
279 /* Get the focus for which the FWHM is minimal */
280 /* fwhm(foc) = a + b*foc + c*foc*foc */
281 /* Verify that b>=0 and c<0 */
282 i = 1;
283 b = cpl_polynomial_get_coeff(pol, &i);
284 i = 2;
285 c = cpl_polynomial_get_coeff(pol, &i);
286 cpl_polynomial_delete(pol);
287
288 cpl_ensure(b >= 0.0, CPL_ERROR_DATA_NOT_FOUND, -4);
289
290 cpl_ensure(b < -2.0 * c * FLT_MAX, CPL_ERROR_DIVISION_BY_ZERO, -5);
291
292 cpl_msg_info(cpl_func, "Optimal focus (%g:%g): %g ", b, c , b/(-2.0*c));
293
294 /* Return the focus where fwhm has its minimum */
295 return b/(-2.0*c);
296}
297
298/*----------------------------------------------------------------------------*/
306/*----------------------------------------------------------------------------*/
307static cpl_error_code visir_img_focfwhm_save(cpl_frameset * set,
308 const cpl_parameterlist * parlist,
309 const cpl_table * tab)
310{
311
312 skip_if(irplib_dfs_save_table(set, parlist, set, tab, NULL, RECIPE_STRING,
313 VISIR_IMG_FOCFWHM_TAB_PROCATG, NULL, NULL,
314 visir_pipe_id, RECIPE_STRING CPL_DFS_FITS));
315 end_skip;
316
317 return cpl_error_get_code();
318}
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:795
double visir_pfits_get_focus(const cpl_propertylist *self)
The focus.
Definition: visir_pfits.c:410