visir_img_focfwhm.c

00001 /* $Id: visir_img_focfwhm.c,v 1.78 2009/02/27 10:37:28 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: 2009/02/27 10:37:28 $
00024  * $Revision: 1.78 $
00025  * $Name: visir-3_5_0 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 
00033 
00034 /*-----------------------------------------------------------------------------
00035                                 Includes
00036  -----------------------------------------------------------------------------*/
00037 
00038 #include "visir_recipe.h"
00039 
00040 /*-----------------------------------------------------------------------------
00041                             Defines
00042  -----------------------------------------------------------------------------*/
00043 
00044 #define RECIPE_STRING "visir_img_focfwhm"
00045 
00046 /*-----------------------------------------------------------------------------
00047                             Private Functions prototypes
00048  -----------------------------------------------------------------------------*/
00049 static cpl_table * visir_img_focfwhm_detect(const cpl_imagelist *,
00050                                             const irplib_framelist *);
00051 static double visir_img_focfwhm_best_focus(const cpl_table *);
00052 static cpl_error_code visir_img_focfwhm_save(cpl_frameset *,
00053                                              const cpl_parameterlist *,
00054                                              const cpl_table *);
00055 
00056 VISIR_RECIPE_DEFINE(visir_img_focfwhm,
00057                     VISIR_PARAM_NODPOS | VISIR_PARAM_AUTOBPM |
00058                     VISIR_PARAM_STRIPITE | VISIR_PARAM_STRIPMOR |
00059                     VISIR_PARAM_STRIPNON |
00060                     VISIR_PARAM_GLITCH | VISIR_PARAM_PURGE,
00061                     "Focus recipe",
00062                     "This recipe finds out what is the best focus of the "
00063                     "telescope\n"
00064                     "by analysing the evolution of the FWHM for different "
00065                     "focii.\n"
00066                     "The files listed in the Set Of Frames (sof-file) must be "
00067                     "tagged:\n"
00068                     "VISIR-focus-file.fits " VISIR_IMG_FOCFWHM_RAW "\n"
00069                     MAN_VISIR_CALIB_BPM_IMG);
00070 
00071 /*----------------------------------------------------------------------------*/
00075 /*----------------------------------------------------------------------------*/
00076 
00077 /*-----------------------------------------------------------------------------
00078                                 Functions code
00079  -----------------------------------------------------------------------------*/
00080 
00081 /*----------------------------------------------------------------------------*/
00088 /*----------------------------------------------------------------------------*/
00089 static int visir_img_focfwhm(cpl_frameset            * framelist,
00090                              const cpl_parameterlist * parlist)
00091 {
00092     irplib_framelist * allframes = NULL;
00093     irplib_framelist * rawframes = NULL;
00094     const char       * badpix;
00095     const char       * flat;
00096     cpl_imagelist    * nodded = NULL;
00097     cpl_table        * tab = NULL;
00098     double             focus;
00099 
00100 
00101     /* Identify the RAW and CALIB frames in the input frameset */
00102     skip_if (visir_dfs_set_groups(framelist));
00103 
00104     /* Objects observation */
00105     allframes = irplib_framelist_cast(framelist);
00106     skip_if(allframes == NULL);
00107     rawframes = irplib_framelist_extract(allframes, VISIR_IMG_FOCFWHM_RAW);
00108     skip_if (rawframes == NULL);
00109 
00110     skip_if(irplib_framelist_load_propertylist_all(rawframes, 0,
00111                                                    visir_property_regexp,
00112                                                    CPL_FALSE));
00113 
00114     skip_if(visir_dfs_check_framelist_tag(rawframes));
00115 
00116     /* Bad pixels calibration file */
00117     badpix = irplib_frameset_find_file(framelist, VISIR_CALIB_BPM);
00118 
00119     /* Flatfield calibration file */
00120     flat = irplib_frameset_find_file(framelist, VISIR_CALIB_FLAT);
00121 
00122     /* Combine the frames */
00123     cpl_msg_info(cpl_func, "Construct the nodded images");
00124     nodded = visir_inputs_combine(RECIPE_STRING, parlist, rawframes, badpix, flat,
00125                                   NULL, CPL_FALSE, 0,0);
00126     if (nodded == NULL) {
00127         cpl_msg_error(cpl_func, "Cannot combine the input frames");
00128         skip_if(1);
00129     }
00130 
00131     /* Get apertures positions - FWHMs - FOCUS in a table */
00132     cpl_msg_info(cpl_func, "Get positions/FWHMs/FOCUSs");
00133     if ((tab = visir_img_focfwhm_detect(nodded, rawframes)) == NULL) {
00134         cpl_msg_error(cpl_func, "Cannot detect apertures");
00135         skip_if(1);
00136     }
00137    /* Compute the best FOCUS */
00138     cpl_msg_info(cpl_func, "Compute the best focus");
00139     focus = visir_img_focfwhm_best_focus(tab);
00140     if (focus < 0) {
00141         cpl_msg_error(cpl_func, "Cannot compute the best focus(%g): '%s' in %s",
00142                       focus, cpl_error_get_message(),
00143                       cpl_error_get_where());
00144         skip_if(1);
00145     }
00146     /* Save the combined image */
00147     cpl_msg_info(cpl_func, "Save the produced combined image");
00148     skip_if (visir_img_focfwhm_save(framelist, parlist, tab));
00149 
00150     end_skip;
00151 
00152     irplib_framelist_delete(allframes);
00153     irplib_framelist_delete(rawframes);
00154     cpl_imagelist_delete(nodded);
00155     cpl_table_delete(tab);
00156 
00157     return cpl_error_get_code();
00158 }
00159  
00160 /*----------------------------------------------------------------------------*/
00172 /*----------------------------------------------------------------------------*/
00173 static cpl_table * visir_img_focfwhm_detect(const cpl_imagelist * nodded,
00174                                             const irplib_framelist * rawframes)
00175 {
00176     cpl_table * tab = NULL;
00177     const int   nfiles = cpl_imagelist_get_size(nodded);
00178     int         i;
00179 
00180 
00181     /* Catch also empty imagelist */    
00182     skip_if (0);
00183     skip_if (rawframes == NULL);
00184     
00185     /* Allocate and initialise arrays */
00186     tab = visir_table_new_xypos(nodded, "FWHM");
00187     skip_if (tab == NULL);
00188 
00189     skip_if (cpl_table_new_column(tab, "FOCUS",  CPL_TYPE_DOUBLE));
00190 
00191     /* Get infos on nodded images */
00192     for (i=0; i < nfiles ; i++) {
00193         const cpl_propertylist * plist
00194             = irplib_framelist_get_propertylist_const(rawframes, 2*i);
00195 
00196         /* Get the FOCUS from the header */
00197         skip_if(cpl_table_set_double(tab, "FOCUS", i,
00198                                      visir_pfits_get_focus(plist)));
00199 
00200     }
00201 
00202     end_skip;
00203 
00204     if (cpl_error_get_code()) {
00205         cpl_table_delete(tab);
00206         tab = NULL;
00207     }
00208 
00209     return tab;
00210 }
00211    
00212 /*----------------------------------------------------------------------------*/
00221 /*----------------------------------------------------------------------------*/
00222 static double visir_img_focfwhm_best_focus(const cpl_table * tab)
00223 {
00224     const int           nrow = cpl_table_get_nrow(tab);
00225     int                 ngood = 0;
00226     cpl_vector      *   x_to_fit;
00227     cpl_vector      *   y_to_fit;
00228     cpl_polynomial  *   pol;
00229     double              fwhm_x, fwhm_y, focus;
00230     double              b, c;
00231     double              mse = -1;
00232     int                 i;
00233 
00234 
00235     /* This will catch tab == NULL */
00236     cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), -1);
00237 
00238     /* Count the number of valid FWHMs values */
00239     for (i=0 ; i < nrow ; i++)
00240         if (cpl_table_get_double(tab, "X_FWHM", i, NULL) > 0 &&
00241             cpl_table_get_double(tab, "Y_FWHM", i, NULL) > 0)
00242             ngood++;
00243 
00244     assert(!cpl_error_get_code());
00245 
00246     /* Need at least three data-points to fit a 2nd degree polynomial */
00247     cpl_ensure(ngood >= 3, CPL_ERROR_DATA_NOT_FOUND, -2);
00248     
00249     /* Create the vectors for the fitting */
00250     x_to_fit = cpl_vector_new(ngood);
00251     y_to_fit = cpl_vector_new(ngood);
00252     ngood = 0;
00253     for (i=0 ; i < nrow ; i++) {
00254         fwhm_x = cpl_table_get_double(tab, "X_FWHM", i, NULL);
00255         if (fwhm_x <= 0) continue;
00256 
00257         fwhm_y = cpl_table_get_double(tab, "Y_FWHM", i, NULL);
00258         if (fwhm_y <= 0) continue;
00259 
00260         focus  = cpl_table_get_double(tab, "FOCUS",  i, NULL);
00261 
00262         cpl_vector_set(x_to_fit, ngood, focus);
00263         cpl_vector_set(y_to_fit, ngood, (fwhm_x+fwhm_y)*0.5);
00264         ngood++;
00265     }
00266 
00267     assert( ngood == cpl_vector_get_size(x_to_fit) );
00268     
00269     /* Apply the fit */
00270     pol = cpl_polynomial_fit_1d_create(x_to_fit, y_to_fit, 2, &mse);
00271     
00272     cpl_msg_info(cpl_func, "Mean Squared Error(%d): %g", ngood, mse);
00273 
00274     cpl_vector_delete(x_to_fit);
00275     cpl_vector_delete(y_to_fit);
00276     
00277     cpl_ensure(pol != NULL, cpl_error_get_code(), -3);
00278 
00279     /* Get the focus for which the FWHM is minimal */
00280     /* fwhm(foc) = a + b*foc + c*foc*foc */
00281     /* Verify that b>=0 and c<0 */
00282     i = 1;
00283     b = cpl_polynomial_get_coeff(pol, &i);
00284     i = 2;
00285     c = cpl_polynomial_get_coeff(pol, &i);
00286     cpl_polynomial_delete(pol);
00287 
00288     cpl_ensure(b >= 0.0, CPL_ERROR_DATA_NOT_FOUND, -4);
00289 
00290     cpl_ensure(b < -2.0 * c * FLT_MAX, CPL_ERROR_DIVISION_BY_ZERO, -5);
00291 
00292     cpl_msg_info(cpl_func, "Optimal focus (%g:%g): %g ", b, c , b/(-2.0*c));
00293 
00294     /* Return the focus where fwhm has its minimum */
00295     return b/(-2.0*c);
00296 }    
00297 
00298 /*----------------------------------------------------------------------------*/
00306 /*----------------------------------------------------------------------------*/
00307 static cpl_error_code visir_img_focfwhm_save(cpl_frameset            * set,
00308                                              const cpl_parameterlist * parlist,
00309                                              const cpl_table         * tab)
00310 {
00311 
00312     skip_if(irplib_dfs_save_table(set, parlist, set, tab, NULL, RECIPE_STRING,
00313                               VISIR_IMG_FOCFWHM_TAB_PROCATG, NULL, NULL,
00314                               visir_pipe_id, RECIPE_STRING CPL_DFS_FITS));
00315     end_skip;
00316 
00317     return cpl_error_get_code();
00318 }

Generated on Mon Feb 6 15:23:49 2012 for VISIR Pipeline Reference Manual by  doxygen 1.5.8