hawki_step_compute_bkg.c

00001 /* $Id: hawki_step_compute_bkg.c,v 1.13 2010/06/09 16:13:06 cgarcia Exp $
00002  *
00003  * This file is part of the HAWKI Pipeline
00004  * Copyright (C) 2008 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/09 16:13:06 $
00024  * $Revision: 1.13 $
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 <string.h>
00037 #include <math.h>
00038 #include <cpl.h>
00039 
00040 #include "hawki_utils.h"
00041 #include "hawki_distortion.h"
00042 #include "hawki_load.h"
00043 #include "hawki_save.h"
00044 #include "hawki_pfits.h"
00045 #include "hawki_dfs.h"
00046 #include "hawki_bkg.h"
00047 #include "hawki_calib.h"
00048 
00049 /*-----------------------------------------------------------------------------
00050                                 Structs
00051  -----------------------------------------------------------------------------*/
00052 
00053 static struct 
00054 {
00055     /* Configuration values */
00056     int      nmin_comb;
00057     int      nhalf_window;
00058     int      rejlow;
00059     int      rejhigh;
00060     
00061 } hawki_step_compute_bkg_config;
00062 
00063 /*-----------------------------------------------------------------------------
00064                             Functions prototypes
00065  -----------------------------------------------------------------------------*/
00066 
00067 static int hawki_step_compute_bkg_create(cpl_plugin *) ;
00068 static int hawki_step_compute_bkg_exec(cpl_plugin *) ;
00069 static int hawki_step_compute_bkg_destroy(cpl_plugin *) ;
00070 static int hawki_step_compute_bkg(cpl_parameterlist *, cpl_frameset *) ;
00071 
00072 static int hawki_step_compute_bkg_from_objects_qc_save
00073 (cpl_frameset        *  objframes,
00074  cpl_frameset        *  maskframes,
00075  cpl_frameset        *  offsetsframes,
00076  cpl_frameset        *  x_distortionframes,
00077  cpl_frameset        *  y_distortionframes,
00078  cpl_parameterlist   *  parlist, 
00079  cpl_frameset        *  recipe_framelist);
00080 static int hawki_step_compute_bkg_from_objects_median_save
00081 (cpl_frameset        *  objframes,
00082  cpl_parameterlist   *  recipe_parlist, 
00083  cpl_frameset        *  recipe_framelist);
00084 static int hawki_step_compute_bkg_from_sky_median_save
00085 (cpl_frameset        *  objframes,
00086  cpl_frameset        *  skyframes,
00087  cpl_parameterlist   *  recipe_parlist, 
00088  cpl_frameset        *  recipe_framelist);
00089 static int hawki_step_compute_bkg_interpolate_badpix
00090 (cpl_image           *  image);
00091 static int hawki_step_compute_bkg_from_objects_running_median_save
00092 (cpl_frameset        *  objframes,
00093  cpl_frameset        *  maskframes,
00094  cpl_frameset        *  offsetframes,
00095  cpl_frameset        *  x_distortionframes,
00096  cpl_frameset        *  y_distortionframes,
00097  cpl_parameterlist   *  recipe_parlist, 
00098  cpl_frameset        *  recipe_framelist);
00099 static int hawki_step_compute_bkg_from_running_median_nonmasked_save
00100 (const cpl_frameset  *  objframes,
00101  int                    nhalf_window,
00102  int                    rejlow,
00103  int                    rejhigh,
00104  cpl_frameset        *  recipe_framelist,
00105  cpl_parameterlist   *  recipe_parlist);
00106 static int hawki_step_compute_bkg_from_running_median_masked_save
00107 (const cpl_frameset  *  objframes,
00108  cpl_frame           *  maskframe,
00109  cpl_bivector        ** offsets,
00110  cpl_frame           *  x_distortionframe,
00111  cpl_frame           *  y_distortionframe,
00112  int                    nhalf_window,
00113  int                    rejlow,
00114  int                    rejhigh,
00115  cpl_frameset        *  recipe_framelist,
00116  cpl_parameterlist   *  recipe_parlist);
00117 
00118 
00119 int hawki_step_compute_bkg_retrieve_input_param
00120 (cpl_parameterlist  *  parlist);
00121 
00122 /*-----------------------------------------------------------------------------
00123                             Static variables
00124  -----------------------------------------------------------------------------*/
00125 
00126 static char hawki_step_compute_bkg_description[] =
00127 "hawki_step_compute_bkg -- hawki background computation utility.\n"
00128 "This recipe will create the associated background images\n"
00129 "for a given set of object images. If there are sky images, these will\n"
00130 "be used to compute the background, otherwise, the background is computed\n"
00131 "using a running mean on the object images. An optional mask can be supplied\n"
00132 "for the running mean.\n"
00133 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00134 "obj_basic_cal-file.fits "HAWKI_CALPRO_BASICCALIBRATED" or\n"
00135 "sky_basic_cal-file.fits "HAWKI_CALPRO_SKY_BASICCALIBRATED" \n"
00136 "and optionally for object masking:\n"
00137 "object_mask-file.fits "HAWKI_CALPRO_OBJ_MASK" \n"
00138 "offsets.fits "HAWKI_CALPRO_OFFSETS" \n"
00139 "distortion_x.fits "HAWKI_CALPRO_DISTORTION_X" \n"
00140 "distortion_y.fits "HAWKI_CALPRO_DISTORTION_Y" \n";
00141 
00142 /*-----------------------------------------------------------------------------
00143                                 Functions code
00144  -----------------------------------------------------------------------------*/
00145 
00146 /*----------------------------------------------------------------------------*/
00154 /*----------------------------------------------------------------------------*/
00155 int cpl_plugin_get_info(cpl_pluginlist * list)
00156 {
00157     cpl_recipe  *   recipe = cpl_calloc(1, sizeof(*recipe)) ;
00158     cpl_plugin  *   plugin = &recipe->interface ;
00159 
00160     cpl_plugin_init(plugin,
00161                     CPL_PLUGIN_API,
00162                     HAWKI_BINARY_VERSION,
00163                     CPL_PLUGIN_TYPE_RECIPE,
00164                     "hawki_step_compute_bkg",
00165                     "Background computing utility",
00166                     hawki_step_compute_bkg_description,
00167                     "Cesar Enrique Garcia Dabo",
00168                     PACKAGE_BUGREPORT,  
00169                     hawki_get_license(),
00170                     hawki_step_compute_bkg_create,
00171                     hawki_step_compute_bkg_exec,
00172                     hawki_step_compute_bkg_destroy);
00173 
00174     cpl_pluginlist_append(list, plugin);
00175     
00176     return 0;
00177 }
00178 
00179 /*----------------------------------------------------------------------------*/
00188 /*----------------------------------------------------------------------------*/
00189 static int hawki_step_compute_bkg_create(cpl_plugin * plugin)
00190 {
00191     cpl_recipe      * recipe;
00192     cpl_parameter   * p; 
00193 
00194     /* Get the recipe out of the plugin */
00195     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00196         recipe = (cpl_recipe *)plugin ;
00197     else return -1 ;
00198 
00199     /* Create the parameters list in the cpl_recipe object */
00200     recipe->parameters = cpl_parameterlist_new() ;
00201 
00202     /* Fill the parameters list */
00203     /* --nmin_comb */
00204     p = cpl_parameter_new_value
00205             ("hawki.hawki_step_compute_bkg.nmin_comb",
00206              CPL_TYPE_INT,
00207              "Minimum number of jitter frames to use the running median",
00208              "hawki.hawki_step_compute_bkg",
00209              10) ;
00210     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nmin_comb") ;
00211     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00212     cpl_parameterlist_append(recipe->parameters, p) ;
00213 
00214     /* --nhalf_window */
00215     p = cpl_parameter_new_value
00216             ("hawki.hawki_step_compute_bkg.nhalf_window",
00217              CPL_TYPE_INT,
00218              "Number of images at both sides of the current ima to use for bkg in running median",
00219              "hawki.hawki_step_compute_bkg",
00220              7);
00221     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nhalf_window") ;
00222     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00223     cpl_parameterlist_append(recipe->parameters, p) ;
00224 
00225     /* --rejlow */
00226     p = cpl_parameter_new_value
00227             ("hawki.hawki_step_compute_bkg.rejlow",
00228              CPL_TYPE_INT,
00229              "The number of frames with low level to reject",
00230              "hawki.hawki_step_compute_bkg",
00231              3) ;
00232     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "rejlow") ;
00233     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00234     cpl_parameterlist_append(recipe->parameters, p) ;
00235 
00236     /* --rejhigh */
00237     p = cpl_parameter_new_value
00238             ("hawki.hawki_step_compute_bkg.rejhigh",
00239              CPL_TYPE_INT,
00240              "The number of frames with high level to reject",
00241              "hawki.hawki_step_compute_bkg",
00242              3) ;
00243     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "rejhigh") ;
00244     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00245     cpl_parameterlist_append(recipe->parameters, p) ;
00246 
00247     /* Return */
00248     return 0;
00249 }
00250 
00251 /*----------------------------------------------------------------------------*/
00257 /*----------------------------------------------------------------------------*/
00258 static int hawki_step_compute_bkg_exec(cpl_plugin * plugin)
00259 {
00260     cpl_recipe  *   recipe ;
00261 
00262     /* Get the recipe out of the plugin */
00263     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00264         recipe = (cpl_recipe *)plugin ;
00265     else return -1 ;
00266 
00267     /* Issue a banner */
00268     hawki_print_banner();
00269 
00270     return hawki_step_compute_bkg(recipe->parameters, recipe->frames) ;
00271 }
00272 
00273 /*----------------------------------------------------------------------------*/
00279 /*----------------------------------------------------------------------------*/
00280 static int hawki_step_compute_bkg_destroy(cpl_plugin * plugin)
00281 {
00282     cpl_recipe  *   recipe ;
00283 
00284     /* Get the recipe out of the plugin */
00285     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00286         recipe = (cpl_recipe *)plugin ;
00287     else return -1 ;
00288 
00289     cpl_parameterlist_delete(recipe->parameters) ;
00290     return 0 ;
00291 }
00292 
00293 /*----------------------------------------------------------------------------*/
00300 /*----------------------------------------------------------------------------*/
00301 static int hawki_step_compute_bkg(
00302         cpl_parameterlist   *   parlist, 
00303         cpl_frameset        *   framelist)
00304 {
00305     cpl_frameset    *   objframes = NULL;
00306     cpl_frameset    *   skyframes;
00307     cpl_frameset    *   maskframes;
00308     cpl_frameset    *   x_distortionframes;
00309     cpl_frameset    *   y_distortionframes;
00310     cpl_frameset    *   offsetsframes = NULL;
00311 
00312     /* Get the recipe parameters */
00313     hawki_step_compute_bkg_retrieve_input_param(parlist);
00314 
00315     /* Identify the RAW and CALIB frames in the input frameset */
00316     if (hawki_dfs_set_groups(framelist)) 
00317     {
00318         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00319         return -1 ;
00320     }
00321     
00322     /* Identifying objects and sky data frames */
00323     cpl_msg_info(__func__, "Identifying objects and sky data");
00324     objframes = hawki_extract_frameset
00325         (framelist, HAWKI_CALPRO_BASICCALIBRATED);
00326     if (objframes == NULL)
00327     {
00328         cpl_msg_error(__func__, "No object frames provided (%s)",
00329                 HAWKI_CALPRO_BASICCALIBRATED);
00330         return -1 ;
00331     }
00332     
00333     /* Retrieve sky frames */
00334     skyframes = hawki_extract_frameset
00335         (framelist, HAWKI_CALPRO_SKY_BASICCALIBRATED);
00336     /* Retrieve the mask */
00337     maskframes = hawki_extract_frameset
00338         (framelist, HAWKI_CALPRO_OBJ_MASK);
00339     if(maskframes != NULL)
00340     {
00341         offsetsframes = hawki_extract_frameset
00342             (framelist, HAWKI_CALPRO_OFFSETS);
00343         x_distortionframes = hawki_extract_frameset
00344             (framelist, HAWKI_CALPRO_DISTORTION_X);
00345         y_distortionframes =  hawki_extract_frameset
00346             (framelist, HAWKI_CALPRO_DISTORTION_Y);
00347         if((x_distortionframes == NULL && y_distortionframes != NULL) ||
00348            (x_distortionframes != NULL && y_distortionframes == NULL))
00349         {
00350             cpl_msg_error(__func__, "One X-distortion frame (%s) and one Y-distortion (%s)"
00351                           "must be provided", HAWKI_CALPRO_DISTORTION_X, HAWKI_CALPRO_DISTORTION_Y);
00352             cpl_frameset_delete(skyframes);
00353             cpl_frameset_delete(maskframes);
00354             cpl_frameset_delete(x_distortionframes);
00355             cpl_frameset_delete(y_distortionframes);
00356             return -1 ;
00357         }
00358     }
00359     
00360     /* Compute the background */
00361     if(skyframes == NULL)
00362         hawki_step_compute_bkg_from_objects_qc_save
00363             (objframes,
00364              maskframes, offsetsframes, x_distortionframes, y_distortionframes,
00365              parlist, framelist);
00366     else
00367         hawki_step_compute_bkg_from_sky_median_save
00368             (objframes, skyframes, 
00369              parlist, framelist);
00370 
00371     /* Free resources */
00372     if(skyframes != NULL)
00373         cpl_frameset_delete(skyframes);
00374     cpl_frameset_delete(objframes);
00375     if(maskframes != NULL)
00376     {
00377         cpl_frameset_delete(maskframes);
00378         if(x_distortionframes != NULL)
00379             cpl_frameset_delete(x_distortionframes);
00380         if(y_distortionframes != NULL)
00381             cpl_frameset_delete(y_distortionframes);
00382         if(offsetsframes != NULL)
00383             cpl_frameset_delete(offsetsframes);
00384     }
00385     
00386     /* return */
00387     if (cpl_error_get_code()) return -1 ;
00388     else return 0 ;
00389 }
00390 
00391 /*----------------------------------------------------------------------------*/
00401 /*----------------------------------------------------------------------------*/
00402 static int hawki_step_compute_bkg_from_objects_qc_save
00403 (cpl_frameset        *  objframes,
00404  cpl_frameset        *  maskframes,
00405  cpl_frameset        *  offsetsframes,
00406  cpl_frameset        *  x_distortionframes,
00407  cpl_frameset        *  y_distortionframes,
00408  cpl_parameterlist   *  parlist, 
00409  cpl_frameset        *  recipe_framelist)
00410 {
00411     int nobjs;
00412     
00413     /* Select the algorithm based on the number of frames */
00414     nobjs = cpl_frameset_get_size(objframes);
00415     cpl_msg_info(__func__,"Number of object frames: %d",nobjs);
00416     if (hawki_step_compute_bkg_config.nmin_comb > nobjs)
00417     {
00418         /* TODO: Support for masks in this case?? */
00419         cpl_msg_info(__func__, 
00420                      "Number of obj frames min required for running median");
00421         cpl_msg_info(__func__, "Using simple median of object images");
00422         hawki_step_compute_bkg_from_objects_median_save
00423             (objframes, parlist, recipe_framelist);
00424     }
00425     else
00426     {
00427         cpl_msg_info(__func__, "Using running median of object images");
00428         hawki_step_compute_bkg_from_objects_running_median_save
00429             (objframes, maskframes, offsetsframes, 
00430              x_distortionframes, y_distortionframes,
00431              parlist, recipe_framelist);
00432     }
00433     if (cpl_error_get_code()) return -1 ;
00434     return 0;
00435 }
00436 
00437 /*----------------------------------------------------------------------------*/
00447 /*----------------------------------------------------------------------------*/
00448 static int hawki_step_compute_bkg_from_objects_median_save
00449 (cpl_frameset        *  objframes,
00450  cpl_parameterlist   *  recipe_parlist, 
00451  cpl_frameset        *  recipe_framelist)
00452 {
00453     cpl_imagelist    * bkg;
00454     const char       * recipe_name = "hawki_step_compute_bkg";
00455     
00456 
00457     /* Logging */
00458     cpl_msg_info(__func__,"Computing background from median of object images");
00459 
00460     /* Allocating for the background image */
00461     bkg = cpl_imagelist_new();
00462     
00463     /* Computing the background */
00464     if(hawki_bkg_from_objects_median(objframes, bkg) != 0)
00465     {
00466         cpl_msg_error(__func__,"Could not compute the median of objects");
00467         cpl_imagelist_delete(bkg);
00468         return -1;
00469     }
00470     
00471     /* Save the products */
00472     cpl_msg_info(__func__, "Saving the products") ;
00473     if(hawki_imagelist_save(recipe_framelist,
00474                             recipe_parlist,
00475                             objframes,
00476                             (const cpl_imagelist *)bkg,
00477                             recipe_name,
00478                             HAWKI_CALPRO_BKGIMAGE, 
00479                             HAWKI_PROTYPE_BKGIMAGE, 
00480                             NULL,
00481                             NULL,
00482                             "hawki_step_compute_bkg_01.fits") != CPL_ERROR_NONE)
00483     {
00484         cpl_msg_warning(__func__,"Some data could not be saved. "
00485                                  "Check permisions or disk space");
00486     }
00487 
00488     /* Free and return */
00489     cpl_imagelist_delete(bkg);
00490     return 0;
00491 }
00492 
00493 /*----------------------------------------------------------------------------*/
00503 /*----------------------------------------------------------------------------*/
00504 static int hawki_step_compute_bkg_from_sky_median_save
00505 (cpl_frameset        *  objframes,
00506  cpl_frameset        *  skyframes,
00507  cpl_parameterlist   *  recipe_parlist, 
00508  cpl_frameset        *  recipe_framelist)
00509 {
00510     cpl_imagelist    * bkg;
00511     const char       * recipe_name = "hawki_step_compute_bkg";
00512     
00513     /* Logging */
00514     cpl_msg_info(__func__,"Computing background from sky images");
00515 
00516     /* Allocating for the background image */
00517     bkg = cpl_imagelist_new();
00518     
00519     /* Computing the background */
00520     if(hawki_bkg_from_sky_median(objframes, bkg)!= 0)
00521     {
00522         cpl_msg_error(__func__,"Could not compute the median of sky images");
00523         cpl_imagelist_delete(bkg);
00524         return -1;
00525     }
00526     
00527     /* Save the products */
00528     cpl_msg_info(__func__, "Saving the products") ;
00529     if(hawki_imagelist_save(recipe_framelist,
00530                             recipe_parlist,
00531                             skyframes,
00532                             (const cpl_imagelist *)bkg,
00533                             recipe_name,
00534                             HAWKI_CALPRO_BKGIMAGE, 
00535                             HAWKI_PROTYPE_BKGIMAGE, 
00536                             NULL,
00537                             NULL,
00538                             "hawki_step_compute_bkg_01.fits") != CPL_ERROR_NONE)
00539     {
00540         cpl_msg_warning(__func__,"Some data could not be saved. "
00541                                  "Check permisions or disk space");
00542     }
00543     
00544     /* Free and return */
00545     cpl_imagelist_delete(bkg);
00546     return 0;
00547 }
00548 
00549 static int hawki_step_compute_bkg_from_objects_running_median_save
00550 (cpl_frameset        *  objframes,
00551  cpl_frameset        *  maskframes,
00552  cpl_frameset        *  offsetframes,
00553  cpl_frameset        *  x_distortionframes,
00554  cpl_frameset        *  y_distortionframes,
00555  cpl_parameterlist   *  recipe_parlist, 
00556  cpl_frameset        *  recipe_framelist)
00557 {
00558 
00559     /* Logging */
00560     cpl_msg_info(__func__,"Computing background from running mean of objects");
00561     cpl_msg_indent_more();
00562 
00563     /* Actually calling the functions that computes all the background */
00564     if(maskframes == NULL)
00565     {
00566         cpl_msg_info(__func__,"Not using masked objects");
00567         if(hawki_step_compute_bkg_from_running_median_nonmasked_save
00568                 (objframes,
00569                  hawki_step_compute_bkg_config.nhalf_window,
00570                  hawki_step_compute_bkg_config.rejlow,
00571                  hawki_step_compute_bkg_config.rejhigh,
00572                  recipe_framelist,
00573                  recipe_parlist) !=0)
00574         {
00575             cpl_msg_error(__func__,"Could not compute objects running median");
00576             return -1;
00577         }
00578     }
00579     else
00580     {
00581         cpl_frame    *  maskframe;
00582         cpl_bivector ** offsets; /* Detector order */
00583         cpl_frame    *  x_distortionframe;
00584         cpl_frame    *  y_distortionframe;
00585         int             idet;
00586         
00587         cpl_msg_info(__func__,"Using masked objects");
00588 
00589         maskframe = cpl_frameset_get_first(maskframes);
00590         if(x_distortionframes == NULL && y_distortionframes == NULL )
00591         {
00592             x_distortionframe = NULL;
00593             y_distortionframe = NULL;
00594         }
00595         else
00596         {
00597             x_distortionframe = cpl_frameset_get_first(x_distortionframes);
00598             y_distortionframe = cpl_frameset_get_first(y_distortionframes);
00599         }
00600         
00601         /* Get the offsets */
00602         if(offsetframes == NULL)
00603         {
00604             cpl_bivector * offsets_all_chips;
00605 
00606             cpl_msg_info(__func__,"Using header nominal offsets");
00607             offsets_all_chips = hawki_get_header_tel_offsets(objframes); 
00608             if (offsets_all_chips == NULL) 
00609             {
00610                 cpl_msg_error(__func__, "Cannot load the header offsets");
00611                 return -1;
00612             }
00613             offsets = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_bivector *));
00614             for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00615             {
00616                 offsets[idet] =  cpl_bivector_duplicate(offsets_all_chips);
00617                 /* Get the oposite offsets. This is to change from 
00618                  * telescope convention to cpl convention */
00619                 cpl_vector_multiply_scalar
00620                     (cpl_bivector_get_x(offsets[idet]), -1.0);
00621                 cpl_vector_multiply_scalar
00622                     (cpl_bivector_get_y(offsets[idet]), -1.0);
00623             }
00624             cpl_bivector_delete(offsets_all_chips);
00625         }
00626         else
00627         {
00628             cpl_msg_info(__func__,"Using refined offsets");
00629             offsets = hawki_load_refined_offsets
00630                 (cpl_frameset_get_first(offsetframes));
00631             if(offsets == NULL)
00632             {
00633                 cpl_msg_error(__func__, "Cannot load the refined offsets");
00634                 return -1;
00635             }
00636         }
00637            
00638         if(hawki_step_compute_bkg_from_running_median_masked_save
00639                 (objframes,
00640                  maskframe,
00641                  offsets,
00642                  x_distortionframe,
00643                  y_distortionframe,
00644                  hawki_step_compute_bkg_config.nhalf_window,
00645                  hawki_step_compute_bkg_config.rejlow,
00646                  hawki_step_compute_bkg_config.rejhigh,
00647                  recipe_framelist,
00648                  recipe_parlist) !=0)
00649         {
00650             cpl_msg_error(__func__,"Could not compute objects running median");
00651             for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00652                 cpl_bivector_delete(offsets[idet]);
00653             cpl_free(offsets);
00654             return -1;
00655         }
00656         
00657         /* Free */
00658         for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00659             cpl_bivector_delete(offsets[idet]);
00660         cpl_free(offsets);
00661     }
00662     cpl_msg_indent_less();
00663 
00664     
00665     /* Freeing and exit */
00666     return 0;
00667 }
00668 
00669 int hawki_step_compute_bkg_from_running_median_nonmasked_save
00670 (const cpl_frameset  *  objframes,
00671  int                    nhalf_window,
00672  int                    rejlow,
00673  int                    rejhigh,
00674  cpl_frameset        *  recipe_framelist,
00675  cpl_parameterlist   *  recipe_parlist)
00676 {
00677     int              iext;
00678     int              iobj;
00679     int              nobj;
00680     const char     * recipe_name = "hawki_step_compute_bkg";
00681     cpl_errorstate   error_prevstate = cpl_errorstate_get();
00682     
00683     /* Preparing the files to save */
00684     cpl_msg_info(__func__,"Preparing the output files");
00685     nobj = cpl_frameset_get_size(objframes); 
00686     for (iobj=0 ; iobj<nobj ; ++iobj)
00687     {
00688         char filename[256];
00689         snprintf(filename, 256, "hawki_step_compute_bkg_%03d.fits", iobj + 1);
00690         hawki_main_header_save(recipe_framelist,
00691                                recipe_parlist,
00692                                objframes,
00693                                recipe_name,
00694                                HAWKI_CALPRO_BKGIMAGE, 
00695                                HAWKI_PROTYPE_BKGIMAGE, 
00696                                NULL,
00697                                filename);
00698         snprintf(filename, 256, "hawki_step_compute_bkg_bpm_%03d.fits", iobj + 1);
00699         hawki_main_header_save(recipe_framelist,
00700                                recipe_parlist,
00701                                objframes,
00702                                recipe_name,
00703                                HAWKI_CALPRO_BKGBPM, 
00704                                HAWKI_PROTYPE_BKGBPM, 
00705                                NULL,
00706                                filename);
00707     }
00708     
00709     /* Loop on extensions */
00710     cpl_msg_indent_more();
00711     for(iext = 0; iext < HAWKI_NB_DETECTORS; ++iext)
00712     {
00713         cpl_imagelist * img_serie;
00714         cpl_vector    * medians;
00715         
00716         /* Info message */
00717         cpl_msg_info(__func__,"Working on extension %d", iext + 1);
00718         
00719         /* Loading the object frame */
00720         img_serie = hawki_load_extensions(objframes, iext + 1, CPL_TYPE_FLOAT);
00721         if(img_serie== NULL)
00722         {
00723             cpl_msg_error(__func__, "Error reading object image") ;
00724             return -1;
00725         }
00726         
00727         /* Pre-compute median value in each plane */
00728         medians = cpl_vector_new(nobj);
00729         for (iobj=0 ; iobj<nobj ; iobj++) 
00730         {
00731             cpl_vector_set
00732                 (medians, 
00733                  iobj,
00734                  cpl_image_get_median(cpl_imagelist_get(img_serie, iobj))) ;
00735         }
00736 
00737         cpl_msg_indent_more();
00738         for(iobj = 0 ; iobj < nobj ; ++iobj)
00739         {
00740             int             nx;
00741             int             ny;
00742             cpl_image     * this_bkg_image;
00743             cpl_image     * this_bkg_image_mask;
00744             char            filename[256];
00745 
00746             /* Info message */
00747             cpl_msg_info(__func__,"Computing bkg for image %d", iobj + 1);
00748 
00749             /* Creates the background image */
00750             nx = cpl_image_get_size_x(cpl_imagelist_get(img_serie, 0));
00751             ny = cpl_image_get_size_y(cpl_imagelist_get(img_serie, 0));
00752             this_bkg_image = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00753             
00754             /* Actually computing the running mean */ 
00755             if(hawki_bkg_from_running_mean_detector
00756                     (img_serie,
00757                      medians,
00758                      iobj,
00759                      nhalf_window,
00760                      rejlow,
00761                      rejhigh,
00762                      this_bkg_image) != 0)
00763              {
00764                 cpl_msg_error(__func__, "Cannot compute bkg");
00765                 cpl_vector_delete(medians);
00766                 cpl_imagelist_delete(img_serie);
00767                 cpl_image_delete(this_bkg_image);
00768                 return -1;
00769              }
00770             
00771             /* Save the extension bad pixel mask */
00772             this_bkg_image_mask = 
00773                 cpl_image_new_from_mask(cpl_image_get_bpm(this_bkg_image));
00774             snprintf(filename, 256, "hawki_step_compute_bkg_bpm_%03d.fits",iobj +1);
00775             hawki_image_ext_save
00776                 (objframes,
00777                  this_bkg_image_mask,
00778                  iext + 1,
00779                  NULL,
00780                  filename);
00781             
00782             /* Interpolate bad pixels */
00783             hawki_step_compute_bkg_interpolate_badpix(this_bkg_image);
00784 
00785             /* Save this extension */
00786             snprintf(filename, 256, "hawki_step_compute_bkg_%03d.fits",iobj +1);
00787             hawki_image_ext_save
00788                 (objframes,
00789                  this_bkg_image,
00790                  iext + 1,
00791                  NULL,
00792                  filename);
00793             
00794             /* Free */
00795             cpl_image_delete(this_bkg_image);
00796             cpl_image_delete(this_bkg_image_mask);
00797         }
00798         cpl_msg_indent_less();
00799         
00800         /* Freeing */
00801         cpl_vector_delete(medians);
00802         cpl_imagelist_delete(img_serie);
00803     }
00804     cpl_msg_indent_less();
00805     if(!cpl_errorstate_is_equal(error_prevstate))
00806     {
00807         cpl_msg_warning(__func__,"Probably some data could not be saved. "
00808                                  "Check permisions or disk space");
00809         cpl_errorstate_set(CPL_ERROR_NONE);
00810         return 1;
00811     }
00812     return 0;
00813 }
00814 
00815 int hawki_step_compute_bkg_from_running_median_masked_save
00816 (const cpl_frameset  *  objframes,
00817  cpl_frame           *  maskframe,
00818  cpl_bivector        ** offsets,
00819  cpl_frame           *  x_distortionframe,  
00820  cpl_frame           *  y_distortionframe,  
00821  int                    nhalf_window,
00822  int                    rejlow,
00823  int                    rejhigh,
00824  cpl_frameset        *  recipe_framelist,
00825  cpl_parameterlist   *  recipe_parlist)
00826 {
00827     int              iext;   /* 0 to HAWKI_NB_DETECTORS-1 */
00828     int              idet;  /* 1 to HAWKI_NB_DETECTORS */
00829     int              iobj;   /* 0 to obj-1 */
00830     int              nobj;
00831     const char     * recipe_name = "hawki_step_compute_bkg";
00832     cpl_errorstate   error_prevstate = cpl_errorstate_get();
00833     cpl_frameset   * used_frameset; //Add the mask and distortion frames (and the objframes of course).
00834     
00835 
00836     //Add all the used frames
00837     used_frameset = cpl_frameset_duplicate(objframes);
00838     cpl_frameset_insert(used_frameset, cpl_frame_duplicate(maskframe));
00839     if(x_distortionframe != NULL)
00840         cpl_frameset_insert(used_frameset, cpl_frame_duplicate(x_distortionframe));
00841     if(y_distortionframe != NULL)
00842         cpl_frameset_insert(used_frameset, cpl_frame_duplicate(y_distortionframe));
00843     
00844     /* Preparing the files to save */
00845     cpl_msg_info(__func__,"Preparing the final files");
00846     nobj = cpl_frameset_get_size(objframes); 
00847     for (iobj=0 ; iobj<nobj ; ++iobj)
00848     {
00849         char filename[256];
00850         snprintf(filename, 256, "hawki_step_compute_bkg_%03d.fits", iobj + 1);
00851         hawki_main_header_save(recipe_framelist,
00852                                recipe_parlist,
00853                                used_frameset,
00854                                recipe_name,
00855                                HAWKI_CALPRO_BKGIMAGE, 
00856                                HAWKI_PROTYPE_BKGIMAGE, 
00857                                NULL,
00858                                filename);
00859         snprintf(filename, 256, "hawki_step_compute_bkg_bpm_%03d.fits", iobj + 1);
00860         hawki_main_header_save(recipe_framelist,
00861                                recipe_parlist,
00862                                used_frameset,
00863                                recipe_name,
00864                                HAWKI_CALPRO_BKGBPM, 
00865                                HAWKI_PROTYPE_BKGBPM, 
00866                                NULL,
00867                                filename);
00868     }
00869     cpl_frameset_delete(used_frameset);
00870     
00871     /* Loop on extensions */
00872     cpl_msg_indent_more();
00873     for(iext = 0; iext < HAWKI_NB_DETECTORS; ++iext)
00874     {
00875         cpl_imagelist    * img_serie;
00876         cpl_vector       * medians;
00877         cpl_image        * mask;
00878         hawki_distortion * inv_distortion = NULL;
00879         cpl_propertylist * prop_list; 
00880         cpl_image        * dist_x = NULL;
00881         cpl_image        * dist_y = NULL;
00882         double             mask_off_x;
00883         double             mask_off_y;
00884         
00885         cpl_msg_info(__func__,"Working on extension %d", iext + 1);
00886         cpl_msg_indent_more();
00887         
00888         /* Loading the object frames */
00889         img_serie = hawki_load_extensions(objframes, iext + 1, CPL_TYPE_FLOAT);
00890         if(img_serie== NULL)
00891         {
00892             cpl_msg_error(__func__, "Error reading object image") ;
00893             return -1;
00894         }
00895         nobj = cpl_imagelist_get_size(img_serie);
00896         
00897         /* Loading the mask frame */
00898         mask = hawki_load_frame_extension(maskframe, iext + 1, CPL_TYPE_FLOAT);
00899         if(mask == NULL)
00900         {
00901             cpl_msg_error(__func__, "Error reading mask image");
00902             return -1;
00903         }
00904         idet = 
00905             hawki_get_detector_from_ext(cpl_frame_get_filename(maskframe), iext+1);
00906         prop_list =
00907             cpl_propertylist_load(cpl_frame_get_filename(maskframe), iext + 1);
00908         mask_off_x = hawki_pfits_get_comb_cumoffsetx(prop_list);
00909         mask_off_y = hawki_pfits_get_comb_cumoffsety(prop_list);
00910         /* Change the offsets to cpl convention */
00911         mask_off_x *= -1; 
00912         mask_off_y *= -1; 
00913         if(!cpl_errorstate_is_equal(CPL_ERROR_NONE))
00914         {
00915             cpl_msg_error(__func__,"Could not get the mask offsets");
00916             cpl_imagelist_delete(img_serie);
00917             cpl_image_delete(mask);
00918             cpl_propertylist_delete(prop_list);
00919             return -1;
00920         }
00921         cpl_msg_info(__func__,"Mask offsets: %f %f", mask_off_x, mask_off_y);
00922 
00923         if(x_distortionframe != NULL && y_distortionframe != NULL)
00924         {
00925             int                nx;
00926             int                ny;
00927             
00928             /* Load the distortion */
00929             if ((inv_distortion = hawki_distortion_load
00930                     (x_distortionframe, y_distortionframe, idet)) == NULL)
00931             {
00932                 cpl_imagelist_delete(img_serie);
00933                 cpl_propertylist_delete(prop_list);
00934                 cpl_image_delete(mask);
00935                 cpl_msg_error(__func__,
00936                               "Cannot load distortion for chip %d",idet);
00937                 return -1 ;
00938             }
00939             /* Multiply distortion by -1, to get the inverse distortion */
00940             cpl_image_multiply_scalar(inv_distortion->dist_x, -1.);
00941             cpl_image_multiply_scalar(inv_distortion->dist_y, -1.);
00942             /* Create the distortion maps */
00943             nx = cpl_image_get_size_x(mask);
00944             ny = cpl_image_get_size_y(mask);
00945             dist_x = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
00946             dist_y = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
00947             if (hawki_distortion_create_maps_detector
00948                     (inv_distortion, dist_x, dist_y))
00949             {
00950                 cpl_msg_error(__func__, "Cannot create the distortion maps") ;
00951                 cpl_imagelist_delete(img_serie);
00952                 cpl_propertylist_delete(prop_list);
00953                 cpl_image_delete(mask);
00954                 cpl_image_delete(dist_x);
00955                 cpl_image_delete(dist_y);
00956                 hawki_distortion_delete(inv_distortion);
00957                 return -1;
00958             }
00959 
00960         }
00961         
00962         /* Creating a different mask for each object, using the offsets 
00963          * and the distortion (if applies) */
00964         cpl_msg_info(__func__,"Constructing the masks");
00965         for (iobj=0 ; iobj<nobj ; iobj++)
00966         {
00967             cpl_image  * mask_shifted;
00968             cpl_image  * mask_trim;
00969             cpl_mask   * mask_final;
00970             cpl_image  * target_image;
00971             cpl_vector * off_x;
00972             cpl_vector * off_y;
00973             
00974             /* Retrieve the offsets. Warning, it is in chip order */
00975             off_x = cpl_bivector_get_x(offsets[idet-1]);
00976             off_y = cpl_bivector_get_y(offsets[idet-1]);
00977             
00978             target_image = cpl_imagelist_get(img_serie, iobj);
00979             mask_shifted = cpl_image_duplicate(mask); 
00980             cpl_image_shift(mask_shifted,
00981                             -(int)(cpl_vector_get(off_x, iobj) - mask_off_x),
00982                             -(int)(cpl_vector_get(off_y, iobj) - mask_off_y));
00983             if(x_distortionframe != NULL && y_distortionframe != NULL)
00984             {
00985                 cpl_image * mask_distcorr;
00986 
00987                 /* Dedistort the mask */
00988                 mask_distcorr = hawki_distortion_correct_detector
00989                     (mask_shifted, dist_x, dist_y);
00990                 if(mask_distcorr == NULL)
00991                 {
00992                     cpl_msg_error(__func__, "Cannot correct the distortion") ;
00993                     cpl_image_delete(dist_x);
00994                     cpl_image_delete(dist_y);
00995                     cpl_image_delete(mask_shifted);
00996                     cpl_imagelist_delete(img_serie);
00997                     cpl_image_delete(mask);
00998                     cpl_propertylist_delete(prop_list);
00999                     hawki_distortion_delete(inv_distortion);
01000                     return -1 ;
01001                 }
01002                 mask_trim = cpl_image_extract
01003                     (mask_distcorr, 1, 1,
01004                      cpl_image_get_size_x(target_image),
01005                      cpl_image_get_size_y(target_image));
01006                 cpl_image_delete(mask_distcorr);
01007             }
01008             else
01009             {
01010                 mask_trim = cpl_image_extract
01011                     (mask_shifted, 1, 1,
01012                      cpl_image_get_size_x(target_image),
01013                      cpl_image_get_size_y(target_image));
01014             }
01015             mask_final = 
01016                 cpl_mask_threshold_image_create(mask_trim, 0.5, FLT_MAX);
01017             /* TODO: Add the current bpm to this mask? */
01018             cpl_image_reject_from_mask
01019                 (target_image, mask_final);
01020             cpl_image_delete(mask_shifted);
01021             cpl_image_delete(mask_trim);
01022             cpl_mask_delete(mask_final);
01023         }
01024         
01025         /* Pre-compute median value in each plane */
01026         cpl_msg_info(__func__,"Computing the medians");
01027         medians = cpl_vector_new(nobj);
01028         for (iobj=0 ; iobj<nobj ; iobj++)
01029         {
01030             cpl_vector_set
01031                 (medians, 
01032                  iobj,
01033                  cpl_image_get_median(cpl_imagelist_get(img_serie, iobj))) ;
01034         }
01035 
01036         /* Object loop to get the bkg */
01037         cpl_msg_info(__func__,"Computing backgrounds");
01038         cpl_msg_indent_more();
01039         for(iobj = 0 ; iobj < nobj ; ++iobj)
01040         {
01041             int             nx;
01042             int             ny;
01043             cpl_image     * this_bkg_image;
01044             cpl_image     * this_bkg_image_mask;
01045             char            filename[256];
01046 
01047             /* Creates the background image */
01048             cpl_msg_info(__func__,"Computing bkg for image %d", iobj + 1);
01049             nx = cpl_image_get_size_x(cpl_imagelist_get(img_serie, 0));
01050             ny = cpl_image_get_size_y(cpl_imagelist_get(img_serie, 0));
01051             this_bkg_image = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
01052             
01053             /* Actually computing the running mean */ 
01054             if(hawki_bkg_from_running_mean_detector
01055                     (img_serie,
01056                      medians,
01057                      iobj,
01058                      nhalf_window,
01059                      rejlow,
01060                      rejhigh,
01061                      this_bkg_image) != 0)
01062             {
01063                 cpl_msg_error(__func__, "Cannot compute bkg");
01064                 cpl_image_delete(this_bkg_image);
01065                 cpl_vector_delete(medians);
01066                 cpl_imagelist_delete(img_serie);
01067                 cpl_image_delete(mask);
01068                 cpl_propertylist_delete(prop_list);
01069                 if(x_distortionframe != NULL && y_distortionframe != NULL)
01070                 {
01071                     hawki_distortion_delete(inv_distortion);
01072                     cpl_image_delete(dist_x);
01073                     cpl_image_delete(dist_y);
01074                 }
01075                 cpl_msg_indent_less();
01076                 cpl_msg_indent_less();
01077                 return -1;
01078             }
01079             
01080             /* Save the extension bad pixel mask */
01081             this_bkg_image_mask = 
01082                 cpl_image_new_from_mask(cpl_image_get_bpm(this_bkg_image));
01083             snprintf(filename, 256, "hawki_step_compute_bkg_bpm_%03d.fits",iobj +1);
01084             hawki_image_ext_save
01085                 (objframes,
01086                  this_bkg_image_mask,
01087                  iext + 1,
01088                  NULL,
01089                  filename);
01090 
01091             /* Interpolate bad pixels */
01092             hawki_step_compute_bkg_interpolate_badpix(this_bkg_image);
01093 
01094             /* Save this extension */
01095             snprintf(filename, 256, "hawki_step_compute_bkg_%03d.fits",iobj +1);
01096             hawki_image_ext_save
01097                 (objframes,
01098                  this_bkg_image,
01099                  iext + 1,
01100                  NULL,
01101                  filename);
01102 
01103             /* Free */
01104             cpl_image_delete(this_bkg_image);
01105             cpl_image_delete(this_bkg_image_mask);
01106         }
01107         cpl_msg_indent_less();
01108 
01109         /* Freeing */
01110         cpl_vector_delete(medians);
01111         cpl_imagelist_delete(img_serie);
01112         cpl_image_delete(mask);
01113         cpl_propertylist_delete(prop_list);
01114         if(x_distortionframe != NULL && y_distortionframe != NULL)
01115         {
01116             hawki_distortion_delete(inv_distortion);
01117             cpl_image_delete(dist_x);
01118             cpl_image_delete(dist_y);
01119         }
01120         cpl_msg_indent_less();
01121     }
01122     cpl_msg_indent_less();
01123     if(!cpl_errorstate_is_equal(error_prevstate))
01124     {
01125         cpl_msg_warning(__func__,"Probably some data could not be saved. "
01126                                  "Check permisions or disk space");
01127         cpl_errorstate_set(CPL_ERROR_NONE);
01128         return 1;
01129     }
01130     return 0;
01131 }
01132 
01133 static int hawki_step_compute_bkg_interpolate_badpix
01134 (cpl_image           *  image)
01135 {
01136     int nbadpixels = cpl_image_count_rejected(image); 
01137     if(nbadpixels !=0)
01138         cpl_msg_info(__func__,"Number of pixels with no background available %d: ",
01139                      nbadpixels);
01140     if(cpl_image_count_rejected(image) > 0)
01141     {
01142         int ipix,npix;
01143         double median = cpl_image_get_median(image);
01144         const cpl_binary * bpm = cpl_mask_get_data_const
01145             (cpl_image_get_bpm(image));
01146         float * image_p = (float*)cpl_image_get_data(image);
01147         cpl_msg_warning(__func__,"Substituting pixels with no bkg with median of image %f",median);
01148         npix = cpl_image_get_size_x(image) * cpl_image_get_size_y(image);
01149         for(ipix = 0; ipix < npix; ipix++)
01150         {
01151             if (bpm[ipix])
01152             {
01153                 image_p[ipix] = median;
01154             }
01155         }
01156         //This cannot be used until DFS08929 is solved
01157         //cpl_detector_interpolate_rejected(image);
01158     }
01159     return 0;
01160 }
01161 
01162 int hawki_step_compute_bkg_retrieve_input_param
01163 (cpl_parameterlist  *  parlist)
01164 {
01165     cpl_parameter   *   par ;
01166 
01167     par = NULL ;
01168     par = cpl_parameterlist_find
01169         (parlist, "hawki.hawki_step_compute_bkg.nmin_comb");
01170     hawki_step_compute_bkg_config.nmin_comb = cpl_parameter_get_int(par);
01171 
01172     par = cpl_parameterlist_find
01173         (parlist, "hawki.hawki_step_compute_bkg.nhalf_window");
01174     hawki_step_compute_bkg_config.nhalf_window = cpl_parameter_get_int(par);
01175 
01176     par = cpl_parameterlist_find
01177         (parlist, "hawki.hawki_step_compute_bkg.rejlow");
01178     hawki_step_compute_bkg_config.rejlow = cpl_parameter_get_int(par);
01179 
01180     par = cpl_parameterlist_find
01181         (parlist, "hawki.hawki_step_compute_bkg.rejhigh");
01182     hawki_step_compute_bkg_config.rejhigh = cpl_parameter_get_int(par);
01183 
01184     return 0;
01185 }

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