hawki_step_combine.c

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

Generated on Thu Feb 17 17:13:07 2011 for HAWKI Pipeline Reference Manual by  doxygen 1.4.7