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 <assert.h>
00038 #include <cpl.h>
00039
00040 #include "irplib_utils.h"
00041
00042 #include "visir_utils.h"
00043 #include "visir_pfits.h"
00044 #include "visir_dfs.h"
00045 #include "visir_inputs.h"
00046
00047
00048
00049
00050
00051 static int visir_img_illu_create(cpl_plugin *);
00052 static int visir_img_illu_exec(cpl_plugin *);
00053 static int visir_img_illu_destroy(cpl_plugin *);
00054 static int visir_img_illu(cpl_parameterlist *, cpl_frameset *);
00055 static cpl_image * visir_img_illu_fit(const cpl_table *, int, int);
00056 static int visir_img_illu_save(const cpl_table *, const cpl_image *,
00057 const cpl_parameterlist *, cpl_frameset *);
00058
00059
00060
00061
00062
00063 static const char * recipename = "visir_img_illu";
00064
00065 static struct {
00066
00067 char nodding[512];
00068 int auto_bpm;
00069 int rem_glitch;
00070 int purge_bad;
00071
00072
00073 double fit_mse;
00074 } visir_img_illu_config;
00075
00076 static char visir_img_illu_description[] =
00077 "This recipe compares the illumination of a bright star at different\n"
00078 "positions on the detector. It produces a normalised illumination map.\n"
00079 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00080 "VISIR-illumination-file.fits IM_CAL_ILLU\n";
00081
00082
00083
00084
00085
00086
00095
00096 int cpl_plugin_get_info(cpl_pluginlist * list)
00097 {
00098 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe));
00099 cpl_plugin * plugin = &recipe->interface;
00100
00101
00102 if (cpl_plugin_init(plugin,
00103 CPL_PLUGIN_API,
00104 VISIR_BINARY_VERSION,
00105 CPL_PLUGIN_TYPE_RECIPE,
00106 recipename,
00107 "Illumination recipe",
00108 visir_img_illu_description,
00109 "Lars Lundin",
00110 PACKAGE_BUGREPORT,
00111 visir_get_license(),
00112 visir_img_illu_create,
00113 visir_img_illu_exec,
00114 visir_img_illu_destroy)) return 1;
00115
00116 if (cpl_pluginlist_append(list, plugin)) return 1;
00117
00118 return 0;
00119 }
00120
00121
00130
00131 static int visir_img_illu_create(cpl_plugin * plugin)
00132 {
00133 cpl_recipe * recipe = (cpl_recipe *)plugin;
00134
00135
00136 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00137
00138
00139 recipe->parameters = cpl_parameterlist_new();
00140
00141
00142 return visir_parameter_set(recipe->parameters, recipename,
00143 VISIR_PARAM_NODPOS | VISIR_PARAM_AUTOBPM |
00144 VISIR_PARAM_GLITCH | VISIR_PARAM_PURGE );
00145 }
00146
00147
00153
00154 static int visir_img_illu_exec(cpl_plugin * plugin)
00155 {
00156 cpl_recipe * recipe = (cpl_recipe *)plugin;
00157
00158
00159 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00160
00161 return visir_img_illu(recipe->parameters, recipe->frames);
00162 }
00163
00164
00170
00171 static int visir_img_illu_destroy(cpl_plugin * plugin)
00172 {
00173 cpl_recipe * recipe = (cpl_recipe *)plugin;
00174
00175
00176 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00177 cpl_parameterlist_delete(recipe->parameters);
00178 return 0;
00179 }
00180
00181
00188
00189 static int visir_img_illu(
00190 cpl_parameterlist * parlist,
00191 cpl_frameset * framelist)
00192 {
00193 cpl_parameter * par;
00194 const char * badpix;
00195 const char * flat;
00196 cpl_frameset * rawframes = NULL;
00197 cpl_imagelist * nodded = NULL;
00198 cpl_table * tab = NULL;
00199 cpl_image * fitted = NULL;
00200 int nx, ny;
00201 int nfiles;
00202
00203
00204 if (cpl_error_get_code()) return cpl_error_get_code();
00205
00206
00207 par = cpl_parameterlist_find(parlist, "visir.visir_img_illu.nodding");
00208 strcpy(visir_img_illu_config.nodding, cpl_parameter_get_string(par));
00209 par = cpl_parameterlist_find(parlist, "visir.visir_img_illu.auto_bpm");
00210 visir_img_illu_config.auto_bpm = cpl_parameter_get_bool(par);
00211 par = cpl_parameterlist_find(parlist, "visir.visir_img_illu.rem_glitch");
00212 visir_img_illu_config.rem_glitch = cpl_parameter_get_bool(par);
00213 par = cpl_parameterlist_find(parlist, "visir.visir_img_illu.purge_bad");
00214 visir_img_illu_config.purge_bad = cpl_parameter_get_bool(par);
00215
00216
00217
00218 skip_if (visir_dfs_set_groups(framelist));
00219
00220
00221 rawframes = irplib_frameset_extract(framelist, VISIR_IMG_ILLU_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_illu_config.nodding,
00237 visir_img_illu_config.auto_bpm,
00238 visir_img_illu_config.rem_glitch,
00239 visir_img_illu_config.purge_bad,
00240 NULL,
00241 CPL_FALSE, 0,0, 0,0,0,0);
00242 if (nodded == NULL) {
00243 cpl_msg_error(__func__, "Could not combine the input frames");
00244 skip_if(1);
00245 }
00246
00247 nfiles = cpl_imagelist_get_size(nodded);
00248 nx = cpl_image_get_size_x(cpl_imagelist_get(nodded, 0));
00249 ny = cpl_image_get_size_y(cpl_imagelist_get(nodded, 0));
00250 skip_if (cpl_error_get_code());
00251
00252
00253 tab = visir_table_new_xypos(nodded, "FLUX");
00254 skip_if (tab == NULL);
00255
00256
00257 cpl_msg_info(__func__, "Detect the objects and compute the flux");
00258
00259
00260 cpl_msg_info(__func__, "Fit a 2d polynomial on the flux");
00261 if ((fitted = visir_img_illu_fit(tab, nx, ny)) == NULL) {
00262 cpl_msg_error(__func__, "Could not compute the fit: '%s' in %s",
00263 cpl_error_get_message(), cpl_error_get_where());
00264 skip_if(1);
00265 }
00266
00267
00268 cpl_msg_info(__func__, "Saving products");
00269 if (visir_img_illu_save(tab, fitted, parlist, framelist)) {
00270 cpl_msg_error(__func__, "Could not save products: '%s' in %s",
00271 cpl_error_get_message(), cpl_error_get_where());
00272 skip_if(1);
00273 }
00274
00275 end_skip;
00276
00277 cpl_imagelist_delete(nodded);
00278 cpl_frameset_delete(rawframes);
00279 cpl_image_delete(fitted);
00280 cpl_table_delete(tab);
00281
00282 return cpl_error_get_code();
00283 }
00284
00285
00293
00294 static cpl_image * visir_img_illu_fit(
00295 const cpl_table * tab,
00296 int nx,
00297 int ny)
00298 {
00299 const int nrow = cpl_table_get_nrow(tab);
00300 cpl_polynomial * pol;
00301 cpl_bivector * surface;
00302 cpl_vector * x_pos;
00303 cpl_vector * y_pos;
00304 cpl_vector * values;
00305 double norm;
00306 cpl_image * fitted;
00307 double xpos, ypos, flux;
00308 double mse = -1;
00309 int npoints = 0;
00310 int i;
00311
00312
00313
00314 visir_assure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
00315
00316
00317
00318 for (i=0 ; i < nrow ; i++)
00319 if (cpl_table_get_double(tab, "X_POS", i, NULL) > 0 &&
00320 cpl_table_get_double(tab, "Y_POS", i, NULL) > 0)
00321 npoints++;
00322
00323 assert(!cpl_error_get_code());
00324
00325
00326 visir_assure(npoints >= 6, CPL_ERROR_DATA_NOT_FOUND, NULL);
00327
00328
00329 surface = cpl_bivector_new(npoints);
00330 x_pos = cpl_bivector_get_x(surface);
00331 y_pos = cpl_bivector_get_y(surface);
00332 values = cpl_vector_new(npoints);
00333 npoints = 0;
00334 for (i=0 ; i < nrow ; i++) {
00335 xpos = cpl_table_get_double(tab, "X_POS", i, NULL);
00336 if (xpos <= 0) continue;
00337 ypos = cpl_table_get_double(tab, "Y_POS", i, NULL);
00338 if (ypos <= 0) continue;
00339
00340 flux = cpl_table_get_double(tab, "FLUX", i, NULL);
00341
00342
00343 cpl_vector_set(x_pos, npoints, xpos);
00344 cpl_vector_set(y_pos, npoints, ypos);
00345 cpl_vector_set(values, npoints, flux);
00346 npoints++;
00347 }
00348
00349
00350 norm = cpl_vector_get(values, npoints/2 );
00351 cpl_vector_divide_scalar(values, norm);
00352
00353 if (cpl_error_get_code()) {
00354 cpl_bivector_delete(surface);
00355 cpl_vector_delete(values);
00356 return NULL;
00357 }
00358
00359
00360 pol = cpl_polynomial_fit_2d_create(surface, values, 2, &mse);
00361 cpl_msg_info(__func__, "Mean Squared Error(%d): %g", npoints, mse);
00362 visir_img_illu_config.fit_mse = mse;
00363
00364 cpl_bivector_delete(surface);
00365 cpl_vector_delete(values);
00366
00367 if (pol == NULL) return NULL;
00368
00369
00370 fitted = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
00371 if (cpl_image_fill_polynomial(fitted, pol, 1.0, 1.0, 1.0, 1.0)) {
00372 cpl_image_delete(fitted);
00373 cpl_polynomial_delete(pol);
00374 return NULL;
00375 }
00376 cpl_polynomial_delete(pol);
00377
00378 return fitted;
00379 }
00380
00381
00390
00391 static int visir_img_illu_save(
00392 const cpl_table * tab,
00393 const cpl_image * fitted,
00394 const cpl_parameterlist * parlist,
00395 cpl_frameset * set)
00396 {
00397
00398 if (cpl_error_get_code()) return cpl_error_get_code();
00399
00400
00401 if (fitted && visir_image_save(parlist, set, fitted, recipename,
00402 VISIR_IMG_ILLU_FITTED_PROCATG, NULL, NULL))
00403 return cpl_error_get_code();
00404
00405 if (visir_table_save(parlist, set, tab, recipename,
00406 VISIR_IMG_ILLU_TAB_PROCATG, NULL, NULL))
00407 return cpl_error_get_code();
00408
00409 return CPL_ERROR_NONE;
00410 }