HAWKI Pipeline Reference Manual 1.8.12
hawki_step_apply_dist.c
00001 /* $Id: hawki_step_apply_dist.c,v 1.10 2011/03/09 10:48:38 cgarcia Exp $
00002  *
00003  * This file is part of the HAWKI 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: cgarcia $
00023  * $Date: 2011/03/09 10:48:38 $
00024  * $Revision: 1.10 $
00025  * $Name: hawki-1_8_12 $
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 <cpl.h>
00038 
00039 #include "irplib_utils.h"
00040 
00041 #include "hawki_utils.h"
00042 #include "hawki_pfits.h"
00043 #include "hawki_dfs.h"
00044 #include "hawki_load.h"
00045 #include "hawki_save.h"
00046 #include "hawki_distortion.h"
00047 
00048 /*-----------------------------------------------------------------------------
00049                             Functions prototypes
00050  -----------------------------------------------------------------------------*/
00051 
00052 static int hawki_step_apply_dist_create(cpl_plugin *) ;
00053 static int hawki_step_apply_dist_exec(cpl_plugin *) ;
00054 static int hawki_step_apply_dist_destroy(cpl_plugin *) ;
00055 static int hawki_step_apply_dist(cpl_parameterlist *, cpl_frameset *) ;
00056 static int hawki_step_apply_dist_save
00057 (cpl_imagelist      *   images,
00058  int                    iserie,
00059  cpl_parameterlist  *   recipe_parlist,
00060  cpl_frameset       *   used_frameset,
00061  cpl_frameset       *   recipe_frameset);
00062 
00063 int hawki_step_apply_dist_compute_and_save
00064 (cpl_frameset      * objects,
00065  cpl_frameset      * distortion_x,
00066  cpl_frameset      * distortion_y,
00067  cpl_parameterlist * parlist,
00068  cpl_frameset      * recipe_frameset);
00069 
00070 /*-----------------------------------------------------------------------------
00071                             Static variables
00072  -----------------------------------------------------------------------------*/
00073 
00074 static char hawki_step_apply_dist_description[] =
00075 "hawki_step_apply_dist -- Distortion correction utility\n"
00076 "This recipe accepts three types of frames:\n"
00077 "object.fits  Images to correct (PRO.CATG = "HAWKI_CALPRO_BKG_SUBTRACTED")\n"
00078 "distmap_x.fits The image with the distortion in X.\n"
00079 "                   (PRO CATG = "HAWKI_CALPRO_DISTORTION_X")\n"
00080 "distmap_y.fits The image with the distortion in Y.\n"
00081 "                   (PRO CATG = "HAWKI_CALPRO_DISTORTION_Y")\n"
00082 "\n"
00083 "This recipe produces:\n"
00084 "hawki_step_apply_dist.fits:     the corrected image.\n"
00085 "                   (PRO CATG = "HAWKI_CALPRO_DIST_CORRECTED")\n" ;
00086 
00087 /*-----------------------------------------------------------------------------
00088                                 Functions code
00089  -----------------------------------------------------------------------------*/
00090 
00091 /*----------------------------------------------------------------------------*/
00100 /*----------------------------------------------------------------------------*/
00101 int cpl_plugin_get_info(cpl_pluginlist * list)
00102 {
00103     cpl_recipe  *   recipe = cpl_calloc(1, sizeof *recipe ) ;
00104     cpl_plugin  *   plugin = &recipe->interface ;
00105 
00106     cpl_plugin_init(plugin,
00107                     CPL_PLUGIN_API,
00108                     HAWKI_BINARY_VERSION,
00109                     CPL_PLUGIN_TYPE_RECIPE,
00110                     "hawki_step_apply_dist",
00111                     "Distortion correction utility",
00112                     hawki_step_apply_dist_description,
00113                     "Cesar Enrique Garcia Dabo",
00114                     PACKAGE_BUGREPORT,  
00115                     hawki_get_license(),
00116                     hawki_step_apply_dist_create,
00117                     hawki_step_apply_dist_exec,
00118                     hawki_step_apply_dist_destroy) ;
00119 
00120     cpl_pluginlist_append(list, plugin) ;
00121     
00122     return 0;
00123 }
00124 
00125 /*----------------------------------------------------------------------------*/
00133 /*----------------------------------------------------------------------------*/
00134 static int hawki_step_apply_dist_create(cpl_plugin * plugin)
00135 {
00136     cpl_recipe      *   recipe ;
00137         
00138     /* Check that the plugin is part of a valid recipe */
00139     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00140         recipe = (cpl_recipe *)plugin ;
00141     else return -1 ;
00142 
00143     /* Create the parameters list in the cpl_recipe object */
00144     recipe->parameters = cpl_parameterlist_new() ; 
00145 
00146     /* Return */
00147     return 0;
00148 }
00149 
00150 /*----------------------------------------------------------------------------*/
00156 /*----------------------------------------------------------------------------*/
00157 static int hawki_step_apply_dist_exec(cpl_plugin * plugin)
00158 {
00159     cpl_recipe  *   recipe ;
00160     
00161     /* Get the recipe out of the plugin */
00162     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00163         recipe = (cpl_recipe *)plugin ;
00164     else return -1 ;
00165 
00166     /* Issue a banner */
00167     hawki_print_banner();
00168 
00169     return hawki_step_apply_dist(recipe->parameters, recipe->frames) ;
00170 }
00171 
00172 /*----------------------------------------------------------------------------*/
00178 /*----------------------------------------------------------------------------*/
00179 static int hawki_step_apply_dist_destroy(cpl_plugin * plugin)
00180 {
00181     cpl_recipe  *   recipe ;
00182     
00183     /* Get the recipe out of the plugin */
00184     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00185         recipe = (cpl_recipe *)plugin ;
00186     else return -1 ;
00187 
00188     cpl_parameterlist_delete(recipe->parameters) ; 
00189     return 0 ;
00190 }
00191 
00192 /*----------------------------------------------------------------------------*/
00199 /*----------------------------------------------------------------------------*/
00200 static int hawki_step_apply_dist(
00201         cpl_parameterlist   *   parlist,
00202         cpl_frameset        *   frameset)
00203 {
00204     cpl_frameset *   objframes;
00205     cpl_frameset *   distortion_x;
00206     cpl_frameset *   distortion_y;
00207     
00208     /* Retrieve input parameters */
00209  
00210     /* Identify the RAW and CALIB frames in the input frameset */
00211     if (hawki_dfs_set_groups(frameset)) {
00212         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00213         return -1 ;
00214     }
00215 
00216     /* Identifying objects frames */
00217     cpl_msg_info(__func__, "Identifying objects");
00218     objframes = hawki_extract_frameset
00219         (frameset, HAWKI_CALPRO_BKG_SUBTRACTED);
00220     if (objframes == NULL)
00221     {
00222         cpl_msg_error(__func__, "No object frames provided (%s)",
00223                       HAWKI_CALPRO_BKG_SUBTRACTED);
00224         return -1 ;
00225     }
00226     
00227     /* Identifying distortion frames */
00228     cpl_msg_info(__func__, "Identifying distortion maps");
00229     distortion_x = hawki_extract_frameset
00230         (frameset, HAWKI_CALPRO_DISTORTION_X);
00231     distortion_y = hawki_extract_frameset
00232         (frameset, HAWKI_CALPRO_DISTORTION_Y);
00233     if(cpl_frameset_get_size(distortion_x) != 1 && 
00234        cpl_frameset_get_size(distortion_y) != 1 )
00235     {
00236         cpl_msg_error(__func__, "One X-distortion frame and one Y-distortion "
00237                       "must be provided (%s, %s)",
00238                       HAWKI_CALPRO_DISTORTION_X, HAWKI_CALPRO_DISTORTION_Y);
00239         cpl_frameset_delete(objframes);
00240         cpl_frameset_delete(distortion_x);
00241         cpl_frameset_delete(distortion_y);
00242         return -1 ;
00243     }
00244     
00245     /* Apply the correction and save */
00246     if(hawki_step_apply_dist_compute_and_save
00247         (objframes, distortion_x, distortion_y, parlist, frameset) == -1)
00248     {
00249         cpl_msg_error(__func__,"Could not correct the frames"); 
00250         cpl_frameset_delete(objframes);
00251         cpl_frameset_delete(distortion_x);
00252         cpl_frameset_delete(distortion_y);
00253         return -1;
00254     }
00255     
00256     /* Free and return */
00257     cpl_frameset_delete(objframes);
00258     cpl_frameset_delete(distortion_x);
00259     cpl_frameset_delete(distortion_y);
00260     
00261     /* Return */
00262     if (cpl_error_get_code())
00263     {
00264         cpl_msg_error(__func__,
00265                       "HAWK-I pipeline could not recover from previous errors");
00266         return -1 ;
00267     }
00268     else return 0 ;
00269 }
00270 
00271 /*----------------------------------------------------------------------------*/
00280 /*----------------------------------------------------------------------------*/
00281 int hawki_step_apply_dist_compute_and_save
00282 (cpl_frameset      * objects,
00283  cpl_frameset      * distortion_x,
00284  cpl_frameset      * distortion_y,
00285  cpl_parameterlist * parlist,
00286  cpl_frameset      * recipe_frameset)
00287 {
00288     const cpl_frame   *  distframe_x;
00289     const cpl_frame   *  distframe_y;
00290     cpl_image        **  dist_x;
00291     cpl_image        **  dist_y;
00292     cpl_image         *  first_image;
00293     int                  nx;
00294     int                  ny;
00295     int                  iframe;
00296     int                  nframes;
00297     int                  idet;
00298     int                  jdet;
00299     cpl_errorstate       error_prevstate = cpl_errorstate_get();
00300 
00301     /* Get the distortion filename and distortion maps */
00302     cpl_msg_info(__func__,"Creating the distortion maps");
00303     distframe_x = cpl_frameset_get_first_const(distortion_x);
00304     distframe_y = cpl_frameset_get_first_const(distortion_y);
00305     first_image = hawki_load_image(objects, 0, 1, CPL_TYPE_FLOAT);
00306     nx = cpl_image_get_size_x(first_image);
00307     ny = cpl_image_get_size_y(first_image);
00308     cpl_image_delete(first_image);
00309     dist_x = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_image *));
00310     dist_y = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_image *));
00311     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00312     {
00313         hawki_distortion * distortion;
00314         dist_x[idet] = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
00315         dist_y[idet] = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE) ;
00316         
00317         /* Load the distortion */
00318         if ((distortion = hawki_distortion_load
00319                 (distframe_x, distframe_y , idet+1)) == NULL) 
00320         {
00321             cpl_msg_error(__func__, "Cannot load the distortion for chip %d: %s", 
00322                     idet+1, cpl_error_get_message());
00323             for (jdet=0 ; jdet<=idet; jdet++)
00324             {
00325                 cpl_image_delete(dist_x[jdet]);
00326                 cpl_image_delete(dist_y[jdet]);
00327             }
00328             cpl_free(dist_x);
00329             cpl_free(dist_y);
00330             return -1 ;
00331         }
00332         if (hawki_distortion_create_maps_detector
00333                 (distortion, dist_x[idet], dist_y[idet]))
00334         {
00335             cpl_msg_error(__func__, "Cannot create the distortion maps") ;
00336             for (jdet=0 ; jdet<=idet; jdet++)
00337             {
00338                 cpl_image_delete(dist_x[jdet]);
00339                 cpl_image_delete(dist_y[jdet]);
00340             }
00341             cpl_free(dist_x);
00342             cpl_free(dist_y);
00343             hawki_distortion_delete(distortion);
00344             return -1;
00345         }
00346         hawki_distortion_delete(distortion);
00347     }
00348     
00349     /* Loop on frames */
00350     nframes = cpl_frameset_get_size(objects);
00351     cpl_msg_info(__func__,"Number of frames to process: %d", nframes);
00352     cpl_msg_indent_more();
00353     for(iframe = 0 ; iframe < nframes; ++iframe)
00354     {
00355         cpl_imagelist * object_images;
00356         cpl_frame     * this_frame;
00357         cpl_frameset  * used_frameset;
00358     
00359         /* Msg */
00360         cpl_msg_info(__func__,"Correcting distortion in frame %d",iframe+1);
00361         
00362         /* Load the HAWKI images */
00363         this_frame = cpl_frameset_get_frame(objects, iframe);
00364         if((object_images = hawki_load_frame(this_frame, CPL_TYPE_FLOAT)) == NULL)
00365         {
00366             cpl_msg_error(__func__,"Could not load input object images");
00367             cpl_msg_indent_less();
00368             for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00369             {
00370                 cpl_image_delete(dist_x[idet]);
00371                 cpl_image_delete(dist_y[idet]);
00372             }
00373             cpl_free(dist_x);
00374             cpl_free(dist_y);
00375             return -1;
00376         }
00377 
00378         /* Apply the correction on the current image */
00379         if (hawki_distortion_apply_maps(object_images, dist_x, dist_y) == -1) 
00380         {
00381             cpl_msg_error(__func__, "Cannot correct distortion") ;
00382             cpl_msg_indent_less();
00383             cpl_imagelist_delete(object_images);
00384             for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00385             {
00386                 cpl_image_delete(dist_x[idet]);
00387                 cpl_image_delete(dist_y[idet]);
00388             }
00389             cpl_free(dist_x);
00390             cpl_free(dist_y);
00391             return -1 ;
00392         }
00393 
00394         /* Set the used frameset */
00395         used_frameset = cpl_frameset_new(); 
00396         cpl_frameset_insert(used_frameset, cpl_frame_duplicate(this_frame));
00397         cpl_frameset_insert
00398             (used_frameset,cpl_frame_duplicate
00399                  (cpl_frameset_get_first_const((distortion_x))));
00400         cpl_frameset_insert
00401             (used_frameset,cpl_frame_duplicate
00402                  (cpl_frameset_get_first_const((distortion_y))));
00403             
00404         /* Save the corrected image */
00405         if (hawki_step_apply_dist_save
00406                 (object_images, iframe, 
00407                  parlist, used_frameset, recipe_frameset) == -1)
00408         {
00409             cpl_errorstate_set(CPL_ERROR_NONE);
00410         }
00411         
00412         /* Free resources */
00413         cpl_frameset_delete(used_frameset);
00414         cpl_imagelist_delete(object_images);
00415         
00416     }
00417     cpl_msg_indent_less();
00418     
00419     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00420     {
00421         cpl_image_delete(dist_x[idet]);
00422         cpl_image_delete(dist_y[idet]);
00423     }
00424     cpl_free(dist_x);
00425     cpl_free(dist_y);
00426     if(!cpl_errorstate_is_equal(error_prevstate))
00427     {
00428         cpl_msg_warning(__func__,"Probably some data could not be saved. "
00429                         "Check permisions or disk space");
00430     }                           
00431     return 0;
00432 }
00433 
00434 /*----------------------------------------------------------------------------*/
00443 /*----------------------------------------------------------------------------*/
00444 static int hawki_step_apply_dist_save
00445 (cpl_imagelist      *   images,
00446  int                    iserie,
00447  cpl_parameterlist  *   recipe_parlist,
00448  cpl_frameset       *   used_frameset,
00449  cpl_frameset       *   recipe_frameset)
00450 {
00451     const cpl_frame     *   raw_reference;
00452     cpl_propertylist    **  extproplists;
00453     char                    filename[256] ;
00454     cpl_propertylist    *   inputlist ;
00455     int                     ext_nb ;
00456     const char          *   recipe_name = "hawki_step_apply_dist";
00457     int                     idet;
00458 
00459     /* Get the reference frame (the raw frame) */
00460     raw_reference = irplib_frameset_get_first_from_group
00461         (used_frameset, CPL_FRAME_GROUP_RAW);
00462     
00463     /* Create the prop lists */
00464     cpl_msg_indent_more();
00465     extproplists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*));
00466     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00467     {
00468         /* Get the extension number */
00469         ext_nb=hawki_get_ext_from_detector
00470             (cpl_frame_get_filename(raw_reference), idet+1);
00471 
00472         /* Allocate this property list */
00473         extproplists[idet] = cpl_propertylist_new();
00474 
00475         /* Propagate some keywords from input raw frame extensions */
00476         inputlist = cpl_propertylist_load_regexp(
00477                 cpl_frame_get_filename(raw_reference), ext_nb,
00478                 HAWKI_HEADER_EXT_FORWARD, 0);
00479         cpl_propertylist_append(extproplists[idet], inputlist);
00480         cpl_propertylist_delete(inputlist);
00481         inputlist = cpl_propertylist_load_regexp(
00482                 cpl_frame_get_filename(raw_reference), ext_nb,
00483                 HAWKI_HEADER_WCS, 0);
00484         cpl_propertylist_append(extproplists[idet], inputlist);
00485         cpl_propertylist_delete(inputlist);
00486     }
00487     
00488     /* Write the image */
00489     snprintf(filename, 256, "hawki_step_apply_dist_%03d.fits", iserie+1);
00490     if(hawki_imagelist_save
00491         (recipe_frameset,
00492          recipe_parlist,
00493          used_frameset,
00494          images,
00495          recipe_name,
00496          HAWKI_CALPRO_DIST_CORRECTED,
00497          HAWKI_PROTYPE_DIST_CORRECTED,
00498          NULL,
00499          (const cpl_propertylist**)extproplists,
00500          filename) != 0)
00501     {
00502         for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00503             cpl_propertylist_delete(extproplists[idet]) ;
00504         cpl_free(extproplists) ;
00505         cpl_msg_indent_less();
00506         return -1;
00507     }
00508     
00509     /* Free and return */
00510     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) {
00511         cpl_propertylist_delete(extproplists[idet]) ;
00512     }
00513     cpl_free(extproplists) ;
00514     cpl_msg_indent_less();
00515     return  0;
00516 }
00517