Main Page   File List  

visir_img_focfwhm.c

00001 /* $Id: visir_img_focfwhm.c,v 1.49 2006/01/22 08:22:10 llundin Exp $
00002  *
00003  * This file is part of the VISIR Pipeline
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2006/01/22 08:22:10 $
00024  * $Revision: 1.49 $
00025  * $Name:  $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
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                             Functions prototypes
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                             Static variables
00064  -----------------------------------------------------------------------------*/
00065 
00066 static const char * recipename = "visir_img_focfwhm";
00067 
00068 static struct {
00069     /* Inputs */
00070     char        nodding[512];
00071     int         auto_bpm;
00072     int         rem_glitch;
00073     int         purge_bad;
00074 
00075     /* Outputs */
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                                 Functions code
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     /* Verify plugin type */
00139     if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00140 
00141     /* Create the parameters list in the cpl_recipe object */
00142     recipe->parameters = cpl_parameterlist_new();
00143 
00144     /* Fill the parameters list */
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     /* Verify plugin type */
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     /* Verify plugin type */
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     /* Retrieve input parameters */
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     /* Identify the RAW and CALIB frames in the input frameset */
00218     skip_if (visir_dfs_set_groups(framelist));
00219 
00220     /* Objects observation */
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     /* Bad pixels calibration file */
00227     badpix = irplib_frameset_find_file(framelist, VISIR_CALIB_BPM);
00228 
00229     /* Flatfield calibration file */
00230     flat = irplib_frameset_find_file(framelist, VISIR_CALIB_FLAT);
00231 
00232 
00233     /* Combine the frames */
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     /* Get apertures positions - FWHMs - FOCUS in a table */
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    /* Compute the best FOCUS */
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     /* Save the combined image */
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     /* Catch also empty imagelist */    
00302     skip_if (cpl_error_get_code());
00303     skip_if (rawframes == NULL);
00304     
00305     /* Allocate and initialise arrays */
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     /* Get infos on nodded images */
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         /* Get the FOCUS from the header */
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     /* This will catch tab == NULL */
00365     visir_assure(!cpl_error_get_code(), cpl_error_get_code(), -1);
00366 
00367     /* Count the number of valid FWHMs values */
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     /* Need at least three data-points to fit a 2nd degree polynomial */
00376     visir_assure(ngood >= 3, CPL_ERROR_DATA_NOT_FOUND, -2);
00377     
00378     /* Create the vectors for the fitting */
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     /* Apply the fit */
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     /* Get the focus for which the FWHM is minimal */
00409     /* fwhm(foc) = a + b*foc + c*foc*foc */
00410     /* Verify that b>=0 and c<0 */
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     /* Return the focus where fwhm has its minimum */
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 }

Generated on Mon Jan 23 12:16:36 2006 for VISIR Pipeline Reference Manual by doxygen1.2.18