00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include <math.h>
00037 #include <float.h>
00038 #include <assert.h>
00039 #include <cpl.h>
00040
00041 #include "irplib_utils.h"
00042
00043 #include "visir_utils.h"
00044 #include "visir_pfits.h"
00045 #include "visir_dfs.h"
00046 #include "visir_inputs.h"
00047
00048
00049
00050
00051
00052 static int visir_img_focfwhm_create(cpl_plugin *);
00053 static int visir_img_focfwhm_exec(cpl_plugin *);
00054 static int visir_img_focfwhm_destroy(cpl_plugin *);
00055 static int visir_img_focfwhm(cpl_parameterlist *, cpl_frameset *);
00056 static cpl_table * visir_img_focfwhm_detect(const cpl_imagelist *,
00057 const cpl_frameset *);
00058 static double visir_img_focfwhm_best_focus(const cpl_table *);
00059 static int visir_img_focfwhm_save(const cpl_table *, const cpl_parameterlist *,
00060 cpl_frameset *);
00061
00062
00063
00064
00065
00066 static const char * recipename = "visir_img_focfwhm";
00067
00068 static struct {
00069
00070 char nodding[512];
00071 int auto_bpm;
00072 int rem_glitch;
00073 int purge_bad;
00074
00075
00076 double focus;
00077 } visir_img_focfwhm_config;
00078
00079 static char visir_img_focfwhm_description[] =
00080 "This recipe finds out what is the best focus of the telescope\n"
00081 "by analysing the evolution of the FWHM for different focii.\n"
00082 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00083 "VISIR-focus-file.fits IM_TEC_FOCUS\n";
00084
00085
00086
00087
00088
00089
00098
00099 int cpl_plugin_get_info(cpl_pluginlist * list)
00100 {
00101 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe));
00102 cpl_plugin * plugin = &recipe->interface;
00103
00104
00105 if (cpl_plugin_init(plugin,
00106 CPL_PLUGIN_API,
00107 VISIR_BINARY_VERSION,
00108 CPL_PLUGIN_TYPE_RECIPE,
00109 recipename,
00110 "Focus recipe",
00111 visir_img_focfwhm_description,
00112 "Lars Lundin",
00113 PACKAGE_BUGREPORT,
00114 visir_get_license(),
00115 visir_img_focfwhm_create,
00116 visir_img_focfwhm_exec,
00117 visir_img_focfwhm_destroy)) return 1;
00118
00119 if (cpl_pluginlist_append(list, plugin)) return 1;
00120
00121 return 0;
00122 }
00123
00124
00133
00134 static int visir_img_focfwhm_create(cpl_plugin * plugin)
00135 {
00136 cpl_recipe * recipe = (cpl_recipe *)plugin;
00137
00138
00139 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00140
00141
00142 recipe->parameters = cpl_parameterlist_new();
00143
00144
00145 return visir_parameter_set(recipe->parameters, recipename,
00146 VISIR_PARAM_NODPOS | VISIR_PARAM_AUTOBPM |
00147 VISIR_PARAM_GLITCH | VISIR_PARAM_PURGE );
00148
00149 }
00150
00151
00157
00158 static int visir_img_focfwhm_exec(cpl_plugin * plugin)
00159 {
00160 cpl_recipe * recipe = (cpl_recipe *)plugin;
00161
00162
00163 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00164
00165 return visir_img_focfwhm(recipe->parameters, recipe->frames);
00166 }
00167
00168
00174
00175 static int visir_img_focfwhm_destroy(cpl_plugin * plugin)
00176 {
00177 cpl_recipe * recipe = (cpl_recipe *)plugin;
00178
00179
00180 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00181 cpl_parameterlist_delete(recipe->parameters);
00182 return 0;
00183 }
00184
00185
00192
00193 static int visir_img_focfwhm(
00194 cpl_parameterlist * parlist,
00195 cpl_frameset * framelist)
00196 {
00197 cpl_parameter * par;
00198 const char * badpix;
00199 const char * flat;
00200 cpl_frameset * rawframes = NULL;
00201 cpl_imagelist * nodded = NULL;
00202 cpl_table * tab = NULL;
00203
00204
00205 if (cpl_error_get_code()) return cpl_error_get_code();
00206
00207
00208 par = cpl_parameterlist_find(parlist, "visir.visir_img_focfwhm.nodding");
00209 strcpy(visir_img_focfwhm_config.nodding, cpl_parameter_get_string(par));
00210 par = cpl_parameterlist_find(parlist, "visir.visir_img_focfwhm.auto_bpm");
00211 visir_img_focfwhm_config.auto_bpm = cpl_parameter_get_bool(par);
00212 par = cpl_parameterlist_find(parlist, "visir.visir_img_focfwhm.rem_glitch");
00213 visir_img_focfwhm_config.rem_glitch = cpl_parameter_get_bool(par);
00214 par = cpl_parameterlist_find(parlist, "visir.visir_img_focfwhm.purge_bad");
00215 visir_img_focfwhm_config.purge_bad = cpl_parameter_get_bool(par);
00216
00217
00218 skip_if (visir_dfs_set_groups(framelist));
00219
00220
00221 rawframes = irplib_frameset_extract(framelist, VISIR_IMG_FOCFWHM_RAW);
00222 skip_if (rawframes == NULL);
00223
00224 skip_if(visir_dfs_check_frameset_tag(rawframes));
00225
00226
00227 badpix = irplib_frameset_find_file(framelist, VISIR_CALIB_BPM);
00228
00229
00230 flat = irplib_frameset_find_file(framelist, VISIR_CALIB_FLAT);
00231
00232
00233
00234 cpl_msg_info(__func__, "Construct the nodded images");
00235 nodded = visir_inputs_combine(rawframes, badpix, flat,
00236 visir_img_focfwhm_config.nodding,
00237 visir_img_focfwhm_config.auto_bpm,
00238 visir_img_focfwhm_config.rem_glitch,
00239 visir_img_focfwhm_config.purge_bad,
00240 NULL,
00241 CPL_FALSE, 0,0, 0,0,0,0);
00242 if (nodded == NULL) {
00243 cpl_msg_error(__func__, "Cannot combine the input frames");
00244 skip_if(1);
00245 }
00246
00247
00248 cpl_msg_info(__func__, "Get positions/FWHMs/FOCUSs");
00249 if ((tab = visir_img_focfwhm_detect(nodded, rawframes)) == NULL) {
00250 cpl_msg_error(__func__, "Cannot detect apertures");
00251 skip_if(1);
00252 }
00253
00254 cpl_msg_info(__func__, "Compute the best focus");
00255 visir_img_focfwhm_config.focus = visir_img_focfwhm_best_focus(tab);
00256 if (visir_img_focfwhm_config.focus < 0) {
00257 cpl_msg_error(__func__, "Cannot compute the best focus(%g): '%s' in %s",
00258 visir_img_focfwhm_config.focus, cpl_error_get_message(),
00259 cpl_error_get_where());
00260 skip_if(1);
00261 }
00262
00263 cpl_msg_info(__func__, "Save the produced combined image");
00264 if (visir_img_focfwhm_save(tab, parlist, framelist)) {
00265 cpl_msg_error(__func__, "Cannot save products");
00266 skip_if(1);
00267 }
00268
00269 end_skip;
00270
00271 cpl_imagelist_delete(nodded);
00272 cpl_table_delete(tab);
00273 cpl_frameset_delete(rawframes);
00274
00275 return cpl_error_get_code();
00276 }
00277
00278
00290
00291 static cpl_table * visir_img_focfwhm_detect(const cpl_imagelist * nodded,
00292 const cpl_frameset * rawframes)
00293 {
00294 const cpl_frame * frame;
00295 cpl_table * tab = NULL;
00296 cpl_propertylist * plist = NULL;
00297 const int nfiles = cpl_imagelist_get_size(nodded);
00298 int i;
00299
00300
00301
00302 skip_if (cpl_error_get_code());
00303 skip_if (rawframes == NULL);
00304
00305
00306 tab = visir_table_new_xypos(nodded, "FWHM");
00307 skip_if (tab == NULL);
00308
00309 skip_if (cpl_table_new_column(tab, "FOCUS", CPL_TYPE_DOUBLE));
00310
00311
00312 for (i=0, frame = cpl_frameset_get_first(rawframes); i < nfiles ;
00313 i++, frame = cpl_frameset_get_next(rawframes),
00314 frame = cpl_frameset_get_next(rawframes)) {
00315
00316
00317
00318 plist = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
00319 skip_if (cpl_error_get_code());
00320
00321 skip_if(cpl_table_set_double(tab, "FOCUS", i,
00322 visir_pfits_get_focus(plist)));
00323
00324 cpl_propertylist_delete(plist);
00325 plist = NULL;
00326
00327 }
00328
00329 end_skip;
00330
00331 if (tab != NULL && cpl_error_get_code()) {
00332 cpl_table_delete(tab);
00333 tab = NULL;
00334 }
00335
00336 cpl_propertylist_delete(plist);
00337
00338 return tab;
00339 }
00340
00341
00350
00351 static double visir_img_focfwhm_best_focus(const cpl_table * tab)
00352 {
00353 const int nrow = cpl_table_get_nrow(tab);
00354 int ngood = 0;
00355 cpl_vector * x_to_fit;
00356 cpl_vector * y_to_fit;
00357 cpl_polynomial * pol;
00358 double fwhm_x, fwhm_y, focus;
00359 double b, c;
00360 double mse = -1;
00361 int i;
00362
00363
00364
00365 visir_assure(!cpl_error_get_code(), cpl_error_get_code(), -1);
00366
00367
00368 for (i=0 ; i < nrow ; i++)
00369 if (cpl_table_get_double(tab, "X_FWHM", i, NULL) > 0 &&
00370 cpl_table_get_double(tab, "Y_FWHM", i, NULL) > 0)
00371 ngood++;
00372
00373 assert(!cpl_error_get_code());
00374
00375
00376 visir_assure(ngood >= 3, CPL_ERROR_DATA_NOT_FOUND, -2);
00377
00378
00379 x_to_fit = cpl_vector_new(ngood);
00380 y_to_fit = cpl_vector_new(ngood);
00381 ngood = 0;
00382 for (i=0 ; i < nrow ; i++) {
00383 fwhm_x = cpl_table_get_double(tab, "X_FWHM", i, NULL);
00384 if (fwhm_x <= 0) continue;
00385
00386 fwhm_y = cpl_table_get_double(tab, "Y_FWHM", i, NULL);
00387 if (fwhm_y <= 0) continue;
00388
00389 focus = cpl_table_get_double(tab, "FOCUS", i, NULL);
00390
00391 cpl_vector_set(x_to_fit, ngood, focus);
00392 cpl_vector_set(y_to_fit, ngood, (fwhm_x+fwhm_y)*0.5);
00393 ngood++;
00394 }
00395
00396 assert( ngood == cpl_vector_get_size(x_to_fit) );
00397
00398
00399 pol = cpl_polynomial_fit_1d_create(x_to_fit, y_to_fit, 2, &mse);
00400
00401 cpl_msg_info(__func__, "Mean Squared Error(%d): %g", ngood, mse);
00402
00403 cpl_vector_delete(x_to_fit);
00404 cpl_vector_delete(y_to_fit);
00405
00406 visir_assure(pol != NULL, cpl_error_get_code(), -3);
00407
00408
00409
00410
00411 i = 1;
00412 b = cpl_polynomial_get_coeff(pol, &i);
00413 i = 2;
00414 c = cpl_polynomial_get_coeff(pol, &i);
00415 cpl_polynomial_delete(pol);
00416
00417 visir_assure(b >= 0.0, CPL_ERROR_DATA_NOT_FOUND, -4);
00418
00419 visir_assure(b < -2.0 * c * FLT_MAX, CPL_ERROR_DIVISION_BY_ZERO, -5);
00420
00421 cpl_msg_info(__func__, "Optimal focus (%g:%g): %g ", b, c , b/(-2.0*c));
00422
00423
00424 return b/(-2.0*c);
00425 }
00426
00427
00435
00436 static int visir_img_focfwhm_save(
00437 const cpl_table * tab,
00438 const cpl_parameterlist * parlist,
00439 cpl_frameset * set)
00440 {
00441
00442 return visir_table_save(parlist, set, tab, recipename,
00443 VISIR_IMG_FOCFWHM_TAB_PROCATG, NULL, NULL);
00444
00445 }