hawki_step_compute_bkg.c

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

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