hawki_step_combine.c

00001 /* $Id: hawki_step_combine.c,v 1.18 2010/06/10 12:00:42 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: 2010/06/10 12:00:42 $
00024  * $Revision: 1.18 $
00025  * $Name: hawki-1_7_2 $
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 #include <string.h>
00039 
00040 #include "irplib_utils.h"
00041 #include "irplib_calib.h"
00042 
00043 #include "hawki_utils.h"
00044 #include "hawki_calib.h"
00045 #include "hawki_load.h"
00046 #include "hawki_save.h"
00047 #include "hawki_pfits.h"
00048 #include "hawki_dfs.h"
00049 #include "hawki_saa.h"
00050 #include "hawki_geom_img.h"
00051 #include "hawki_bkg.h"
00052 #include "hawki_distortion.h"
00053 #include "hawki_properties_tel.h"
00054 #include "hawki_image_stats.h"
00055 
00056 /*-----------------------------------------------------------------------------
00057                             Functions prototypes
00058  -----------------------------------------------------------------------------*/
00059 
00060 static int hawki_step_combine_create(cpl_plugin *) ;
00061 static int hawki_step_combine_exec(cpl_plugin *) ;
00062 static int hawki_step_combine_destroy(cpl_plugin *) ;
00063 static int hawki_step_combine(cpl_parameterlist *, cpl_frameset *) ;
00064 
00065 static int hawki_step_combine_retrieve_input_param
00066 (cpl_parameterlist  *  parlist);
00067 static cpl_image ** hawki_step_combine_apply_comb
00068 (cpl_frameset    * obj,
00069  cpl_frameset    * offsets,
00070  cpl_frameset    * bpm,
00071  cpl_frameset    * bkg_bpm_frames);
00072 static cpl_image *  hawki_step_combine_chip
00073 (cpl_imagelist   * in,
00074  cpl_bivector    * offsets,
00075  double          * pos_x,
00076  double          * pos_y);
00077 static int hawki_step_combine_save
00078 (cpl_image           ** combined,
00079  cpl_frameset        *  used_frames,
00080  cpl_parameterlist   *  parlist,
00081  cpl_frameset        *  recipe_frameset);
00082 
00083 /*-----------------------------------------------------------------------------
00084                             Static variables
00085  -----------------------------------------------------------------------------*/
00086 
00087 static struct 
00088 {
00089     /* Inputs */
00090     int                 offset_max ;
00091     int                 borders ;
00092     cpl_geom_combine    comb_meth ;
00093     int                 rej_low;
00094     int                 rej_high;
00095     cpl_kernel          resamp_kernel;
00096 } hawki_step_combine_config;
00097 
00098 static struct 
00099 {
00100     /* Outputs */
00101     double  mean_airmass;
00102     double  combined_pos_x[HAWKI_NB_DETECTORS];
00103     double  combined_pos_y[HAWKI_NB_DETECTORS];
00104     double  combined_cumoffset_x[HAWKI_NB_DETECTORS];
00105     double  combined_cumoffset_y[HAWKI_NB_DETECTORS];
00106 } hawki_step_combine_output;
00107 
00108 static char hawki_step_combine_description[] =
00109 "hawki_step_combine -- hawki combine jitter images.\n"
00110 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00111 "science-file.fits "HAWKI_CALPRO_DIST_CORRECTED" or\n"
00112 "science-file.fits "HAWKI_CALPRO_BKG_SUBTRACTED" or\n"
00113 "bpm-file.fits "HAWKI_CALPRO_BPM" (optional) \n"
00114 "bkg_bpm-file.fits "HAWKI_CALPRO_BKGBPM" (optional) \n"
00115 "offsets-file.fits "HAWKI_CALPRO_OFFSETS" (optional) \n"
00116 "The recipe creates as an output:\n"
00117 "hawki_step_combine.fits ("HAWKI_CALPRO_COMBINED"): \n"
00118 "The recipe does the following steps:\n"
00119 "-Allocate an image with the proper combined size \n"
00120 "   (depends on parameters --comb_meth and --borders)\n"
00121 "-Retrieve the offsets either from the offsets-file.fits or from the header\n"
00122 "-For each combined pixel, the contribution of each individual frame \n"
00123 "   is added using a resampling kernel. If any of the pixels involved in\n"
00124 "   the resampling is a bad pixel (defined in bpm-file.fits), it is not\n"
00125 "   taken into account.\n"
00126 "   With the remaining pixels a minmax rejection is performed\n"
00127 "Return code:\n"
00128 "esorex exits with an error code of 0 if the recipe completes successfully\n"
00129 "or 1 otherwise";
00130 
00131 /*-----------------------------------------------------------------------------
00132                                 Functions code
00133  -----------------------------------------------------------------------------*/
00134 
00135 /*----------------------------------------------------------------------------*/
00143 /*----------------------------------------------------------------------------*/
00144 int cpl_plugin_get_info(cpl_pluginlist * list)
00145 {
00146     cpl_recipe  *   recipe = cpl_calloc(1, sizeof(*recipe)) ;
00147     cpl_plugin  *   plugin = &recipe->interface ;
00148 
00149     cpl_plugin_init(plugin,
00150                     CPL_PLUGIN_API,
00151                     HAWKI_BINARY_VERSION,
00152                     CPL_PLUGIN_TYPE_RECIPE,
00153                     "hawki_step_combine",
00154                     "Jitter image combination recipe",
00155                     hawki_step_combine_description,
00156                     "Cesar Enrique Garcia Dabo",
00157                     PACKAGE_BUGREPORT,  
00158                     hawki_get_license(),
00159                     hawki_step_combine_create,
00160                     hawki_step_combine_exec,
00161                     hawki_step_combine_destroy) ;
00162 
00163     cpl_pluginlist_append(list, plugin) ;
00164     
00165     return 0;
00166 }
00167 
00168 /*----------------------------------------------------------------------------*/
00177 /*----------------------------------------------------------------------------*/
00178 static int hawki_step_combine_create(cpl_plugin * plugin)
00179 {
00180     cpl_recipe      * recipe ;
00181     cpl_parameter   * p ;
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     /* Create the parameters list in the cpl_recipe object */
00189     recipe->parameters = cpl_parameterlist_new() ;
00190 
00191     /* Fill the parameters list */
00192     /* --offset_max */
00193     p = cpl_parameter_new_value("hawki.hawki_step_combine.offset_max",
00194                                 CPL_TYPE_INT,
00195                                 "Maximum offset allowed",
00196                                 "hawki.hawki_step_combine",
00197                                 1500) ;
00198     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "offset_max") ;
00199     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00200     cpl_parameterlist_append(recipe->parameters, p) ;
00201 
00202     /* --comb_meth */
00203     p = cpl_parameter_new_value("hawki.hawki_step_combine.comb_meth",
00204                                 CPL_TYPE_STRING,
00205                                 "Final size of combination (union / inter / first)",
00206                                 "hawki.hawki_step_combine",
00207                                 "union") ;
00208     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "comb_meth") ;
00209     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00210     cpl_parameterlist_append(recipe->parameters, p) ;
00211   
00212     /* --rej */
00213     p = cpl_parameter_new_value("hawki.hawki_step_combine.rej",
00214                                 CPL_TYPE_STRING,
00215                                 "Low and high number of rejected values",
00216                                 "hawki.hawki_step_combine",
00217                                 "1,1") ;
00218     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "rej") ;
00219     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00220     cpl_parameterlist_append(recipe->parameters, p) ;
00221 
00222     /* --borders */
00223     p = cpl_parameter_new_value("hawki.hawki_step_combine.borders",
00224                                 CPL_TYPE_INT,
00225                                 "Border pixels trimmed",
00226                                 "hawki.hawki_step_combine",
00227                                 4) ;
00228     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "borders") ;
00229     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00230     cpl_parameterlist_append(recipe->parameters, p) ;
00231 
00232     /* --resamp_kernel */
00233     p = cpl_parameter_new_value("hawki.hawki_step_combine.resamp_kernel",
00234                                 CPL_TYPE_STRING,
00235                                 "Resampling kernel (default/tanh/sinc/sinc2/lanczos/hamming/hann)",
00236                                 "hawki.hawki_step_combine",
00237                                 "default") ;
00238     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "resamp_kernel") ;
00239     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00240     cpl_parameterlist_append(recipe->parameters, p) ;
00241 
00242     /* Return */
00243     return 0;
00244 }
00245 
00246 /*----------------------------------------------------------------------------*/
00252 /*----------------------------------------------------------------------------*/
00253 static int hawki_step_combine_exec(cpl_plugin * plugin)
00254 {
00255     cpl_recipe  *   recipe ;
00256 
00257     /* Get the recipe out of the plugin */
00258     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00259         recipe = (cpl_recipe *)plugin ;
00260     else return -1 ;
00261 
00262     /* Issue a banner */
00263     hawki_print_banner();
00264 
00265     return hawki_step_combine(recipe->parameters, recipe->frames) ;
00266 }
00267 
00268 /*----------------------------------------------------------------------------*/
00274 /*----------------------------------------------------------------------------*/
00275 static int hawki_step_combine_destroy(cpl_plugin * plugin)
00276 {
00277     cpl_recipe  *   recipe ;
00278 
00279     /* Get the recipe out of the plugin */
00280     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00281         recipe = (cpl_recipe *)plugin ;
00282     else return -1 ;
00283 
00284     cpl_parameterlist_delete(recipe->parameters) ;
00285     return 0 ;
00286 }
00287 
00288 /*----------------------------------------------------------------------------*/
00295 /*----------------------------------------------------------------------------*/
00296 static int hawki_step_combine(
00297         cpl_parameterlist   *   parlist, 
00298         cpl_frameset        *   framelist)
00299 {
00300     cpl_frameset    *  objframes ;
00301     cpl_frameset    *  offsets;
00302     cpl_frameset    *  bpm;
00303     cpl_frameset    *  bpmbkg;
00304     cpl_frameset    *  used_frames;
00305     cpl_image       ** combined;
00306     int                idet;
00307 
00308     /* Retrieve input parameters */
00309     if(hawki_step_combine_retrieve_input_param(parlist))
00310     {
00311         cpl_msg_error(__func__, "Wrong parameters");
00312         return -1;
00313     }
00314 
00315     /* Identify the RAW and CALIB frames in the input frameset */
00316     if (hawki_dfs_set_groups(framelist)) {
00317         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00318         return -1 ;
00319     }
00320 
00321     /* Retrieve raw frames */
00322     objframes = hawki_extract_frameset(framelist, HAWKI_CALPRO_DIST_CORRECTED);
00323     if (objframes == NULL) 
00324     {
00325         objframes = hawki_extract_frameset
00326             (framelist, HAWKI_CALPRO_BKG_SUBTRACTED);
00327         if (objframes == NULL) 
00328         {
00329             cpl_msg_error(__func__,"Cannot find objs frames in the input list (%s or %s)",
00330                     HAWKI_CALPRO_DIST_CORRECTED, HAWKI_CALPRO_BKG_SUBTRACTED);
00331             return -1 ;
00332         }
00333     }
00334     used_frames = cpl_frameset_duplicate(objframes);
00335     
00336     /* Retrieve the refined offsets, if provided */
00337     offsets = hawki_extract_frameset(framelist, HAWKI_CALPRO_OFFSETS);
00338     if(offsets)
00339         cpl_frameset_insert(used_frames, cpl_frame_duplicate(
00340                 cpl_frameset_get_first(offsets)));
00341     
00342     /* Retrieve the general bad pixel mask, if provided */
00343     bpm = hawki_extract_frameset(framelist, HAWKI_CALPRO_BPM);
00344     if(bpm)
00345         cpl_frameset_insert(used_frames, cpl_frame_duplicate(
00346                 cpl_frameset_get_first(bpm)));
00347 
00348     /* Retrieve the background bad pixel masks, if provided */
00349     bpmbkg = hawki_extract_frameset(framelist, HAWKI_CALPRO_BKGBPM);
00350     if(bpmbkg)
00351     {
00352         int iframe;
00353         for(iframe=0; iframe < cpl_frameset_get_size(bpmbkg); iframe++)
00354             cpl_frameset_insert(used_frames, cpl_frame_duplicate(
00355                     cpl_frameset_get_frame(bpmbkg,iframe)));
00356         if(cpl_frameset_get_size(bpmbkg) != cpl_frameset_get_size(objframes))
00357         {
00358             cpl_msg_error(__func__,"Incompatible number of science and bad bkg"
00359                                    " images.");
00360             cpl_msg_error(__func__,"Supply as many bad bkg images as objects");
00361             cpl_frameset_delete(objframes);
00362             cpl_frameset_delete(used_frames);
00363             cpl_frameset_delete(offsets);
00364             cpl_frameset_delete(bpm);
00365             cpl_frameset_delete(bpmbkg);
00366             return -1;
00367         }
00368     }
00369     
00370     /* Apply the combination */
00371     cpl_msg_info(__func__, "Apply the data recombination") ;
00372     cpl_msg_indent_more() ;
00373     if ((combined = hawki_step_combine_apply_comb
00374              (objframes, offsets, bpm, bpmbkg)) == NULL)
00375     {
00376         cpl_msg_error(__func__, "Cannot combine the data") ;
00377         cpl_frameset_delete(objframes);
00378         cpl_frameset_delete(used_frames);
00379         if(offsets != NULL)
00380             cpl_frameset_delete(offsets);
00381         if(bpm != NULL)
00382             cpl_frameset_delete(bpm);
00383         cpl_msg_indent_less() ;
00384         return -1 ;
00385     }
00386     cpl_msg_indent_less() ;
00387     cpl_frameset_delete(objframes);
00388     if(offsets != NULL)
00389         cpl_frameset_delete(offsets);
00390     if(bpm != NULL)
00391         cpl_frameset_delete(bpm);
00392     if(bpmbkg != NULL)
00393         cpl_frameset_delete(bpmbkg);
00394     
00395     /* Save the products */
00396     cpl_msg_info(__func__, "Save the products") ;
00397     cpl_msg_indent_more() ;
00398     if (hawki_step_combine_save(combined, used_frames, parlist, framelist) != 0)
00399     {
00400         cpl_msg_warning(__func__, "Some error happened saving the data. "
00401                         "Check permisions or disk space") ;
00402         for(idet=0; idet< HAWKI_NB_DETECTORS; ++idet)
00403             cpl_image_delete(combined[idet]);
00404         cpl_frameset_delete(used_frames);
00405         cpl_free(combined);
00406         cpl_msg_indent_less() ;
00407         return -1 ;
00408     }
00409     cpl_msg_indent_less() ;
00410     
00411     /* Return */
00412     for(idet=0; idet< HAWKI_NB_DETECTORS; ++idet)
00413         cpl_image_delete(combined[idet]);
00414     cpl_free(combined);
00415     cpl_frameset_delete(used_frames);
00416 
00417     if (cpl_error_get_code()) return -1 ;
00418     else return 0 ;
00419 }
00420 
00421 int hawki_step_combine_retrieve_input_param
00422 (cpl_parameterlist  *  parlist)
00423 {
00424     cpl_parameter   *   par ;
00425     const char      *   sval ;
00426     par = NULL ;
00427     par = cpl_parameterlist_find(parlist,
00428             "hawki.hawki_step_combine.offset_max");
00429     hawki_step_combine_config.offset_max = cpl_parameter_get_int(par);
00430     par = cpl_parameterlist_find(parlist,
00431             "hawki.hawki_step_combine.comb_meth");
00432     sval = cpl_parameter_get_string(par);
00433     if (!strcmp(sval, "union"))
00434         hawki_step_combine_config.comb_meth = CPL_GEOM_UNION;
00435     else if (!strcmp(sval, "inter"))
00436         hawki_step_combine_config.comb_meth = CPL_GEOM_INTERSECT;
00437     else if (!strcmp(sval, "first"))
00438         hawki_step_combine_config.comb_meth = CPL_GEOM_FIRST;
00439     else
00440     {
00441         cpl_msg_error(__func__, "Invalid combine method specified");
00442         return -1;
00443     }
00444     par = cpl_parameterlist_find(parlist,
00445             "hawki.hawki_step_combine.borders");
00446     hawki_step_combine_config.borders = cpl_parameter_get_int(par);
00447     if(hawki_step_combine_config.borders < 0 )
00448     {
00449         cpl_msg_error(__func__, "Borders cannot be less than zero");
00450         return -1;
00451     }
00452     par = cpl_parameterlist_find(parlist, 
00453             "hawki.hawki_step_combine.rej");
00454     sval = cpl_parameter_get_string(par);
00455     if (sscanf(sval, "%d,%d",
00456                &hawki_step_combine_config.rej_low,
00457                &hawki_step_combine_config.rej_high)!=2)
00458     {
00459         return -1;
00460     }
00461     par = cpl_parameterlist_find(parlist, 
00462             "hawki.hawki_step_combine.resamp_kernel");
00463     sval = cpl_parameter_get_string(par);
00464     if (!strcmp(sval, "tanh"))
00465         hawki_step_combine_config.resamp_kernel = CPL_KERNEL_TANH;
00466     else if (!strcmp(sval, "sinc"))
00467         hawki_step_combine_config.resamp_kernel = CPL_KERNEL_SINC;
00468     else if (!strcmp(sval, "sinc2"))
00469         hawki_step_combine_config.resamp_kernel = CPL_KERNEL_SINC2;
00470     else if (!strcmp(sval, "lanczos"))
00471         hawki_step_combine_config.resamp_kernel = CPL_KERNEL_LANCZOS;
00472     else if (!strcmp(sval, "hamming"))
00473         hawki_step_combine_config.resamp_kernel = CPL_KERNEL_HAMMING;
00474     else if (!strcmp(sval, "hann"))
00475         hawki_step_combine_config.resamp_kernel = CPL_KERNEL_HANN;
00476     else if (!strcmp(sval, "default"))
00477         hawki_step_combine_config.resamp_kernel = CPL_KERNEL_DEFAULT;
00478     else
00479     {
00480         cpl_msg_error(__func__, "Invalid resampling kernel specified");
00481         return -1;
00482     }
00483 
00484     return 0;
00485 }
00486 
00487 
00488 
00489 /*----------------------------------------------------------------------------*/
00495 /*----------------------------------------------------------------------------*/
00496 static cpl_image ** hawki_step_combine_apply_comb
00497 (cpl_frameset    * obj,
00498  cpl_frameset    * offsets_frames,
00499  cpl_frameset    * bpm_frames,
00500  cpl_frameset    * bkg_bpm_frames)
00501 {
00502     cpl_image           **  combined ;
00503     cpl_bivector        **  offsets;
00504     cpl_mask             *  bpm_masks[HAWKI_NB_DETECTORS];
00505     int                     idet;
00506     int                     ioff;
00507 
00508     if(offsets_frames == NULL)
00509     {
00510         cpl_bivector        *   offsets_single_chip;
00511         if ((offsets_single_chip = hawki_get_header_tel_offsets(obj)) == NULL) 
00512         {
00513             cpl_msg_error(__func__, "Cannot load the header offsets");
00514             return NULL;
00515         }
00516         offsets = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_bivector *));
00517         for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00518             offsets[idet] =  cpl_bivector_duplicate(offsets_single_chip);
00519         cpl_bivector_delete(offsets_single_chip);
00520     }
00521     else
00522     {
00523         offsets = hawki_load_refined_offsets
00524             (cpl_frameset_get_first(offsets_frames));
00525         if(offsets == NULL)
00526         {
00527             cpl_msg_error(__func__, "Cannot load the refined offsets");
00528             return NULL;
00529         }
00530     }
00531     /* Get the oposite offsets. This is to change from 
00532      * telescope convention to cpl convention 
00533      * WARNING: It may appear that the img_jitter function 
00534      * does not apply the multiplication by -1, but it really does it in 
00535      * hawki_img_jitter_saa instead of when it reads the offsets */
00536     for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00537     {
00538         cpl_vector_multiply_scalar(cpl_bivector_get_x(offsets[idet]), -1.0);
00539         cpl_vector_multiply_scalar(cpl_bivector_get_y(offsets[idet]), -1.0);
00540     }
00541     
00542     /* Load the bpm */
00543     if(bpm_frames != NULL)
00544     {
00545         cpl_imagelist *  bpm_images = NULL;
00546         bpm_images = hawki_load_frame
00547             (cpl_frameset_get_first(bpm_frames), CPL_TYPE_INT);
00548         if(bpm_images == NULL)
00549         {
00550             cpl_msg_error(__func__, "Cannot load the bad pixel mask");
00551             return NULL;
00552         }
00553         for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00554         {
00555             bpm_masks[idet] = cpl_mask_threshold_image_create
00556                 (cpl_imagelist_get(bpm_images, idet), 0.5, 1.5);
00557         }
00558         cpl_imagelist_delete(bpm_images);
00559     }
00560 
00561     /* Create output object */
00562     combined = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_image *));
00563  
00564     /* Loop on the detectors */
00565     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00566     {
00567         cpl_imagelist   * in ;
00568         cpl_imagelist   * bpm_bkg_im;
00569         cpl_image       * comb_chip ;
00570         double          * offs_est_x ;
00571         double          * offs_est_y ;
00572         double            max_x, max_y ;
00573         double            off_0_x;
00574         double            off_0_y;
00575         int               jdet;
00576         int               iframe;
00577 
00578         cpl_msg_info(__func__, "Combine chip number %d", idet+1) ;
00579         cpl_msg_indent_more() ;
00580         
00581         /* Print the offsets */
00582         offs_est_x = cpl_bivector_get_x_data(offsets[idet]) ;
00583         offs_est_y = cpl_bivector_get_y_data(offsets[idet]) ;
00584         for (ioff=0 ; ioff<cpl_bivector_get_size(offsets[idet]) ; ioff++) {
00585             cpl_msg_info(__func__,"Telescope offsets (Frame %d): %g %g", ioff+1,
00586                     -offs_est_x[ioff], -offs_est_y[ioff]) ;
00587         }
00588 
00589         /* Subtract the first offset to all offsets */
00590         max_x = max_y = 0.0 ;
00591         off_0_x = offs_est_x[0];
00592         off_0_y = offs_est_y[0];
00593         for (ioff=1 ; ioff<cpl_bivector_get_size(offsets[idet]) ; ioff++) 
00594         {
00595             offs_est_x[ioff] -= offs_est_x[0] ;
00596             offs_est_y[ioff] -= offs_est_y[0] ;
00597             if (fabs(offs_est_x[ioff]) > max_x) max_x = fabs(offs_est_x[ioff]);
00598             if (fabs(offs_est_y[ioff]) > max_y) max_y = fabs(offs_est_y[ioff]);
00599         }
00600         offs_est_x[0] = offs_est_y[0] = 0.00 ;
00601 
00602         /* Check if the max offset is not too big */
00603         if (max_x > hawki_step_combine_config.offset_max || 
00604                 max_y > hawki_step_combine_config.offset_max) 
00605         {
00606             cpl_msg_error(__func__,"Sorry, no support for offsets larger than %d",
00607                           hawki_step_combine_config.offset_max);
00608             for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00609             {
00610                 cpl_bivector_delete(offsets[idet]);
00611                 if(bpm_frames != NULL)
00612                     cpl_mask_delete(bpm_masks[idet]);
00613             }
00614             for(jdet = 0; jdet < idet; ++jdet)
00615                 cpl_image_delete(combined[idet]);
00616             cpl_free(combined);
00617             return NULL ;
00618         }
00619 
00620         /* Load the input data */
00621         cpl_msg_info(__func__, "Load the input data") ;
00622         cpl_msg_indent_more() ;
00623         if ((in = hawki_load_detector(obj, idet+1, CPL_TYPE_FLOAT)) == NULL) {
00624             cpl_msg_error(__func__, "Cannot load chip %d",idet+1);
00625             //TODO: there is probably a memory leak here. It should be checked.
00626             for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00627             {
00628                 cpl_bivector_delete(offsets[idet]);
00629                 if(bpm_frames != NULL)
00630                     cpl_mask_delete(bpm_masks[idet]);
00631             }
00632             for(jdet = 0; jdet < idet; ++jdet)
00633                 cpl_image_delete(combined[idet]);
00634             cpl_free(combined);
00635             cpl_free(offsets);
00636             cpl_msg_indent_less() ;
00637             cpl_msg_indent_less() ;
00638             return NULL ;
00639         }
00640         cpl_msg_indent_less() ;
00641 
00642         /* Load the bad bkg images */
00643         if(bkg_bpm_frames != NULL)
00644         {
00645             cpl_msg_info(__func__, "Load the bad bkg images");
00646             cpl_msg_indent_more() ;
00647             if ((bpm_bkg_im = hawki_load_detector(bkg_bpm_frames, idet+1,
00648                               CPL_TYPE_FLOAT)) == NULL)
00649             {
00650                 cpl_msg_error(__func__, "Cannot load chip %d",idet+1);
00651                 for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00652                 {
00653                     cpl_bivector_delete(offsets[idet]);
00654                     if(bpm_frames != NULL)
00655                         cpl_mask_delete(bpm_masks[idet]);
00656                 }
00657                 for(jdet = 0; jdet < idet; ++jdet)
00658                     cpl_image_delete(combined[idet]);
00659                 cpl_imagelist_delete(in);
00660                 cpl_free(combined);
00661                 cpl_free(offsets);
00662                 cpl_msg_indent_less() ;
00663                 cpl_msg_indent_less() ;
00664                 return NULL ;
00665             }
00666         }
00667         cpl_msg_indent_less() ;
00668         
00669         /* Add the bpms in case they were specified */
00670         if(bpm_frames != NULL || bkg_bpm_frames != NULL)
00671         {
00672             for(iframe = 0 ; iframe <cpl_imagelist_get_size(in) ; ++iframe)
00673             {
00674                 cpl_mask  * final_mask;
00675                 cpl_image * target_image =  cpl_imagelist_get(in, iframe);
00676                 final_mask = cpl_mask_new(cpl_image_get_size_x(target_image),
00677                                           cpl_image_get_size_y(target_image));
00678                 //Add the common bpm
00679                 cpl_mask_or(final_mask, bpm_masks[idet]);
00680                 //Add the background mask if provided
00681                 if(bkg_bpm_frames != NULL)
00682                 {
00683                     cpl_mask * bpm_bkg_mask = 
00684                         cpl_mask_threshold_image_create
00685                           (target_image, 0.5, FLT_MAX);
00686                     cpl_mask_or(final_mask, bpm_bkg_mask);
00687                     cpl_mask_delete(bpm_bkg_mask);
00688                 }
00689                 cpl_image_reject_from_mask(target_image, final_mask);
00690                 cpl_mask_delete(final_mask);
00691             }
00692         }
00693         
00694         if(bkg_bpm_frames != NULL)
00695             cpl_imagelist_delete(bpm_bkg_im);
00696 
00697         /* Apply the shift and add */
00698         cpl_msg_info(__func__, "Shift and add") ;
00699         cpl_msg_indent_more() ;
00700         comb_chip = hawki_step_combine_chip(in, offsets[idet], 
00701                 &(hawki_step_combine_output.combined_pos_x[idet]),
00702                 &(hawki_step_combine_output.combined_pos_y[idet])) ;
00703         if (comb_chip == NULL) {
00704             cpl_msg_error(__func__, "Cannot apply the shift and add") ;
00705             cpl_imagelist_delete(in) ;
00706             for(jdet = 0; jdet < HAWKI_NB_DETECTORS; ++jdet)
00707                 cpl_bivector_delete(offsets[jdet]);
00708             for(jdet = 0; jdet < idet; ++jdet)
00709                 cpl_image_delete(combined[jdet]);
00710             cpl_free(combined);
00711             cpl_free(offsets);
00712             cpl_msg_indent_less() ;
00713             cpl_msg_indent_less() ;
00714             return NULL ;
00715         }
00716         /* The cumoffset have the opposite criteria as cpl */
00717         hawki_step_combine_output.combined_cumoffset_x[idet] = 
00718             hawki_step_combine_output.combined_pos_x[idet] - off_0_x;
00719         hawki_step_combine_output.combined_cumoffset_y[idet] = 
00720             hawki_step_combine_output.combined_pos_y[idet] - off_0_y;
00721         cpl_imagelist_delete(in) ;
00722         cpl_msg_indent_less() ;
00723 
00724         /* Put the results in the image list */
00725         combined[idet] = comb_chip;
00726         cpl_msg_indent_less() ;
00727     }
00728     
00729     /* Compute the mean airmass */
00730     hawki_step_combine_output.mean_airmass = hawki_get_mean_airmass(obj);
00731     
00732     for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00733     {
00734         cpl_bivector_delete(offsets[idet]);
00735         if(bpm_frames != NULL)
00736             cpl_mask_delete(bpm_masks[idet]);
00737     }
00738     cpl_free(offsets);
00739     return combined;
00740 }
00741 
00742 /*----------------------------------------------------------------------------*/
00751 /*----------------------------------------------------------------------------*/
00752 static cpl_image * hawki_step_combine_chip(
00753         cpl_imagelist   *  in,
00754         cpl_bivector    *  offsets,
00755         double          *  pos_x,
00756         double          *  pos_y)
00757 {
00758     cpl_image        **  combined_contrib;
00759     cpl_image        *   comb;
00760     cpl_imagelist    *   in_ext ;
00761     cpl_image        *   tmp1 ;
00762     cpl_image        *   tmp2 ;
00763     int                  nfiles, nx, ny ;
00764     int                  i;
00765 
00766     /* Check entries */
00767     if (pos_x == NULL || pos_y == NULL) return NULL ;
00768     if (offsets == NULL) return NULL ;
00769 
00770     /* Get the number of images */
00771     nfiles = cpl_imagelist_get_size(in) ;
00772     if (cpl_bivector_get_size(offsets) != nfiles) {
00773         cpl_msg_error(__func__, "Number of refined offsets in table """
00774                       "is different than number of frames to combine"); 
00775         return NULL ;
00776     }
00777     
00778     /* Discard the pixels on the sides */
00779     if (hawki_step_combine_config.borders > 0) {
00780         nx = cpl_image_get_size_x(cpl_imagelist_get(in, 0)) ;
00781         ny = cpl_image_get_size_y(cpl_imagelist_get(in, 0)) ;
00782         in_ext = cpl_imagelist_new() ;
00783         for (i=0 ; i<cpl_imagelist_get_size(in) ; i++) {
00784             tmp1 = cpl_imagelist_get(in, i) ;
00785             tmp2 = cpl_image_extract(tmp1, 
00786                     hawki_step_combine_config.borders+1, 
00787                     hawki_step_combine_config.borders+1, 
00788                     nx-hawki_step_combine_config.borders, 
00789                     ny-hawki_step_combine_config.borders) ;
00790             cpl_imagelist_set(in_ext, tmp2, i) ;
00791         }
00792     }
00793     else
00794     {
00795         in_ext = cpl_imagelist_duplicate(in);
00796     }
00797 
00798     /* Apply the shift & add */
00799     cpl_msg_info(__func__, "Recombine the images set") ;
00800     cpl_msg_indent_more() ;
00801     if ((combined_contrib=cpl_geom_img_offset_saa(in_ext, offsets,
00802             hawki_step_combine_config.resamp_kernel, 
00803             hawki_step_combine_config.rej_low,
00804             hawki_step_combine_config.rej_high,
00805             hawki_step_combine_config.comb_meth,
00806             pos_x, pos_y)) == NULL) {
00807         cpl_msg_error(cpl_func, "Cannot apply the shift and add") ;
00808         cpl_msg_indent_less() ;
00809         return NULL ;
00810     }
00811     cpl_msg_indent_less() ;
00812     *pos_x -= hawki_step_combine_config.borders ;
00813     *pos_y -= hawki_step_combine_config.borders ;
00814 
00815     /* Free and return */
00816     comb = combined_contrib[0];
00817     cpl_image_delete(combined_contrib[1]);
00818     cpl_free(combined_contrib);
00819     cpl_imagelist_delete(in_ext);
00820     return comb;
00821 }
00822         
00823 /*----------------------------------------------------------------------------*/
00832 /*----------------------------------------------------------------------------*/
00833 static int hawki_step_combine_save
00834 (cpl_image           ** combined,
00835  cpl_frameset        *  used_frames,
00836  cpl_parameterlist   *  parlist,
00837  cpl_frameset        *  recipe_frameset)
00838 {
00839     cpl_propertylist    **  extproplists ;
00840     const cpl_frame     *   ref_frame ;
00841     cpl_propertylist    *   wcslist ;
00842     cpl_propertylist    *   inputlist ;
00843     double                  crpix1, crpix2 ;
00844     int                     ext_nb ;
00845     const char          *   recipe_name = "hawki_step_combine" ;
00846     int                     idet;
00847     cpl_errorstate          error_prevstate = cpl_errorstate_get();
00848 
00849     /* Get a reference frame for the WCS keys */
00850     ref_frame = irplib_frameset_get_first_from_group
00851         (recipe_frameset, CPL_FRAME_GROUP_RAW) ;
00852     
00853     if(ref_frame == NULL)
00854     {
00855         cpl_msg_error(__func__, "Cannot get a reference frame");
00856         return -1;
00857     }
00858 
00859     /* Create the QC lists */
00860     extproplists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
00861     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 
00862     {
00863 
00864         /* Initialize qclists */
00865         extproplists[idet] = cpl_propertylist_new() ;
00866 
00867         /* Get the extension number */
00868         ext_nb=hawki_get_ext_from_detector(cpl_frame_get_filename(ref_frame), idet+1);
00869 
00870         /* Handle WCS keys */
00871         wcslist = cpl_propertylist_load_regexp(
00872                 cpl_frame_get_filename(ref_frame), ext_nb, HAWKI_HEADER_WCS, 0);
00873 
00874         /* Update WCS and write them */
00875         crpix1 = cpl_propertylist_get_double(wcslist, "CRPIX1"); 
00876         crpix1 += hawki_step_combine_output.combined_pos_x[idet];
00877         cpl_propertylist_update_double(wcslist, "CRPIX1", crpix1) ;
00878         crpix2 = cpl_propertylist_get_double(wcslist, "CRPIX2"); 
00879         crpix2 += hawki_step_combine_output.combined_pos_y[idet] ;
00880         cpl_propertylist_update_double(wcslist, "CRPIX2", crpix2) ;
00881         cpl_propertylist_copy_property_regexp
00882             (extproplists[idet], wcslist, HAWKI_HEADER_WCS, 0);
00883         cpl_propertylist_delete(wcslist) ;
00884         
00885         /* Keywords for the relative position of the combined image */
00886         cpl_propertylist_append_double
00887             (extproplists[idet], "ESO QC COMBINED CUMOFFSETX",
00888              hawki_step_combine_output.combined_cumoffset_x[idet]);
00889         cpl_propertylist_append_double
00890             (extproplists[idet], "ESO QC COMBINED CUMOFFSETY",
00891              hawki_step_combine_output.combined_cumoffset_y[idet]);
00892         cpl_propertylist_append_double
00893             (extproplists[idet], "ESO QC COMBINED POSX",
00894              hawki_step_combine_output.combined_pos_x[idet]);
00895         cpl_propertylist_append_double
00896             (extproplists[idet], "ESO QC COMBINED POSY",
00897              hawki_step_combine_output.combined_pos_y[idet]);
00898         cpl_propertylist_append_double
00899             (extproplists[idet], "ESO QC AIRMASS MEAN",
00900              hawki_step_combine_output.mean_airmass);
00901 
00902         /* Propagate some keywords from input raw frame extensions */
00903         inputlist = cpl_propertylist_load_regexp(
00904                 cpl_frame_get_filename(ref_frame), ext_nb,
00905                 HAWKI_HEADER_EXT_FORWARD, 0) ;
00906         cpl_propertylist_append(extproplists[idet], inputlist);
00907         cpl_propertylist_delete(inputlist) ;
00908     }
00909 
00910     /* Write the combined image */
00911     if(hawki_images_save(recipe_frameset,
00912                          parlist,
00913                          used_frames,
00914                          (const cpl_image **)combined,
00915                          recipe_name,
00916                          HAWKI_CALPRO_COMBINED,
00917                          HAWKI_PROTYPE_COMBINED, 
00918                          NULL,
00919                          (const cpl_propertylist**)extproplists,
00920                          "hawki_step_combine.fits")  != 0)
00921     {
00922         for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) {
00923             cpl_propertylist_delete(extproplists[idet]) ;
00924         }
00925         cpl_free(extproplists) ;
00926         return -1;
00927     }
00928 
00929     /* Free and return */
00930     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) {
00931         cpl_propertylist_delete(extproplists[idet]) ;
00932     }
00933     cpl_free(extproplists) ;
00934 
00935     if(!cpl_errorstate_is_equal(error_prevstate))
00936     {
00937         cpl_errorstate_set(CPL_ERROR_NONE);
00938         return 1;
00939     }
00940 
00941     return  0;
00942 }
00943  

Generated on 10 Jun 2010 for HAWKI Pipeline Reference Manual by  doxygen 1.6.1