visir_img_burst.c

00001 /* $Id: visir_img_burst.c,v 1.59 2012/01/11 08:08:57 llundin Exp $
00002  *
00003  * This file is part of the VISIR Pipeline
00004  * Copyright (C) 2007 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: llundin $
00023  * $Date: 2012/01/11 08:08:57 $
00024  * $Revision: 1.59 $
00025  * $Name: visir-3_5_0 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include "visir_recipe.h"
00037 #include <math.h>
00038 
00039 /*-----------------------------------------------------------------------------
00040                             Defines
00041  -----------------------------------------------------------------------------*/
00042 
00043 #define RECIPE_STRING "visir_img_burst"
00044 
00045 #ifndef VISIR_IMG_BURST_SHIFT_FILE
00046 #define VISIR_IMG_BURST_SHIFT_FILE "shift.txt"
00047 #endif
00048 
00049 #define VISIR_PFITS_STRING_CHOP_START "ESO TEL CHOP START"
00050 #define VISIR_PFITS_STRING_OBS_START  "DATE-OBS"
00051 #define VISIR_PFITS_DOUBLE_CHOP_FREQ  "ESO TEL CHOP FREQ"
00052 
00053 #define VISIR_SECS_PER_DAY (24 * 3600)
00054 
00055 /*-----------------------------------------------------------------------------
00056                             Private Functions prototypes
00057  -----------------------------------------------------------------------------*/
00058 
00059 #include <visir_destripe.h>
00060 #include <irplib_wcs.h>
00061 
00062 static cpl_error_code visir_destripe_imagelist(cpl_imagelist *, int,
00063                                                cpl_boolean);
00064 
00065 static cpl_image * visir_chop_nod_burst(cpl_frameset *,
00066                                         const cpl_parameterlist *,
00067                                         int, int, int, int, int,
00068                                         double, double, double,
00069                                         cpl_boolean, cpl_boolean, cpl_boolean);
00070 static int visir_img_burst_get_index(cpl_frame *, cpl_frame *,
00071                                      const cpl_matrix *,
00072                                      int, int, int, int, int, double, double,
00073                                      int, int *, int *);
00074 static cpl_imagelist * visir_img_burst_create_chop_nod(cpl_frame *,
00075                                                        cpl_frame *, int, int,
00076                                                        int, int);
00077 static cpl_image * visir_img_burst_create_combined(cpl_frameset *,
00078                                                    const cpl_parameterlist *,
00079                                                    cpl_imagelist *,
00080                                                    const cpl_matrix *, double,
00081                                                    cpl_boolean);
00082 static int visir_img_burst_get_quadrant(double, double);
00083 static cpl_image * imagelist_combine(cpl_imagelist *);
00084 static int find_starting_index(cpl_frame *,cpl_frame * );
00085 static cpl_image * image_1d_poly_create(const cpl_image *);
00086 static cpl_apertures * visir_img_burst_extract(const cpl_image *, double);
00087 static cpl_image * cpl_image_get_median_choose(const cpl_image *, int);
00088 static cpl_bivector * visir_extract_4_sources_box(cpl_image *,
00089                                                   const cpl_matrix *,
00090                                                   double, int, cpl_boolean);
00091 
00092 static cpl_image * image_median_conv(const cpl_image *, const cpl_matrix *,
00093                                      int);
00094 static cpl_matrix * visir_img_burst_psf_create(int);
00095 
00096 cpl_recipe_define(visir_img_burst, VISIR_BINARY_VERSION,         
00097                   "Lars Lundin", PACKAGE_BUGREPORT, "2007",
00098                   "Images burst combination recipe",
00099                   RECIPE_STRING " -- VISIR burst mode recipe.\n"
00100                   "This recipe recombines data observed in chopping "
00101                   "and/or nodding mode into one combined image "
00102                   "using optionally cross-correlation methods\n");
00103 
00104 /*----------------------------------------------------------------------------*/
00108 /*----------------------------------------------------------------------------*/
00109 
00110 /*-----------------------------------------------------------------------------
00111                                 Functions code
00112  -----------------------------------------------------------------------------*/
00113 
00114 /*----------------------------------------------------------------------------*/
00122 /*----------------------------------------------------------------------------*/
00123 static
00124 cpl_error_code visir_img_burst_fill_parameterlist(cpl_parameterlist * self)
00125 {
00126     const char * context = PACKAGE "." RECIPE_STRING;
00127     cpl_error_code err;
00128 
00129     cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
00130 
00131     /* Fill the parameters list */
00132 
00133     /* --startindex */
00134     err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00135                                        "startindex", 1, "SI", context,
00136                                        "starting image where the noise level "
00137                                        "is ok - -1 for auto mode");
00138     cpl_ensure_code(!err, err);
00139 
00140     /*--indice_pos*/
00141     err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00142                                        "indice_pos", -1, "IPOS", context,
00143                                        "index where the pos source changes "
00144                                        "position in the nodded cube");
00145     cpl_ensure_code(!err, err);
00146 
00147     /*---indice_neg*/
00148     err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00149                                        "indice_neg", -1, "INEG", context,
00150                                        "index where the neg source changes "
00151                                        "position in the nodded cube");
00152     cpl_ensure_code(!err, err);
00153 
00154     /*left_chop:: positive position of the source in the chopping guess:
00155      * value of 1 if it is true(on the left),0 if it is false*/
00156     err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00157                                        "left_chop", -1, "left_chop", context,
00158                                        "tell if the source is in the left or "
00159                                        "right side in the chopped im");
00160     cpl_ensure_code(!err, err);
00161 
00162     /*left_nod: positive position of the source in the nodding guess:
00163      * value of 1 if it is true(on the left),0 if it is false*/
00164     err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00165                                        "left_nod", -1, "left_nod", context,
00166                                        "tell if the source is in the left or "
00167                                        "right side in the nodded im");
00168     cpl_ensure_code(!err, err);
00169 
00170     /*sigma_nod-->threshold= sigma * stdev  for the detection in the nodding
00171      * images*/
00172     err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
00173                                           "sigma_nod", 4.0, "sigma_nod",context,
00174                                           "threshold used for the detection of "
00175                                           "sources in the images nodded");
00176     cpl_ensure_code(!err, err);
00177 
00178     /*sigma_chop-->threshold= sigma * stdev  for the detection in the chopping
00179      * first guess:lots of noise fot the faint source (sigma should be 0.7)*/
00180     err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
00181                                           "sigma_chop", 4.0, "sigma_chop",
00182                                           context, "threshold used for the det."
00183                                           " of sources in the images chopped");
00184     cpl_ensure_code(!err, err);
00185 
00186     /*sigma_4sources-->threshold= sigma * stdev  for the detection
00187      * for the 4 sources in oder to have their position*/
00188     err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
00189                                           "sigma_4sources", 4.0,
00190                                           "sigma_4sources", context,
00191                                           "threshold used for the detection of "
00192                                           "the position of 4 sources");
00193     cpl_ensure_code(!err, err);
00194 
00195     /*destriping correction:put the keyword if correction needed
00196      * non correction by default*/
00197     err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
00198                                         "destriping", CPL_FALSE,
00199                                         "destripe", context,
00200                                         "Flag to use the destriping");
00201     cpl_ensure_code(!err, err);
00202 
00203     /* Morphological cleaning:put the keyword if cleaning needed
00204      * non correction by default*/
00205     err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
00206                                         "morpho", CPL_FALSE,
00207                                         "morpho", context,
00208                                         "Flag to use the morphological "
00209                                         "cleaning in the destriping");
00210     cpl_ensure_code(!err, err);
00211 
00212     /*DEBUG */
00213     err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
00214                                         "debug", CPL_FALSE,
00215                                         "debug", context,
00216                                         "Flag to make a debug computation "
00217                                         "and save files");
00218     cpl_ensure_code(!err, err);
00219 
00220     /*PATH for the file of the psf used for convolution*/
00221     /* FIXME: Replace with size param ? */
00222     err = irplib_parameterlist_set_string(self, PACKAGE, RECIPE_STRING,
00223                                           "psf", "/dev/null",
00224                                           "psf", context,
00225                                           "Ignored");
00226     cpl_ensure_code(!err, err);
00227 
00228     return CPL_ERROR_NONE;
00229 }
00230 
00231 /*----------------------------------------------------------------------------*/
00238 /*----------------------------------------------------------------------------*/
00239 static int visir_img_burst(cpl_frameset            * framelist,
00240                            const cpl_parameterlist * parlist)
00241 {
00242     cpl_image * combined = NULL;
00243     int         startindex;
00244     int         indice_pos;
00245     int         indice_neg;
00246     int         left_chop;
00247     int         left_nod;
00248     double      sigma_chop;
00249     double      sigma_nod;
00250     double      sigma_4sources;
00251     cpl_boolean destripe;
00252     cpl_boolean morpho;
00253     cpl_boolean debug;
00254 
00255     /* Remove the file of shifts if it already exists */
00256     (void)remove(VISIR_IMG_BURST_SHIFT_FILE);
00257 
00258     bug_if(0);
00259 
00260     startindex = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00261                                               "startindex");
00262 
00263     indice_pos = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00264                                               "indice_pos");
00265 
00266     indice_neg = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00267                                               "indice_neg");
00268 
00269     left_chop = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00270                                              "left_chop");
00271 
00272     left_nod = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00273                                              "left_nod");
00274 
00275     sigma_nod = irplib_parameterlist_get_double(parlist, PACKAGE, RECIPE_STRING,
00276                                                 "sigma_nod");
00277 
00278     sigma_chop = irplib_parameterlist_get_double(parlist, PACKAGE,
00279                                                  RECIPE_STRING, "sigma_chop");
00280 
00281     sigma_4sources = irplib_parameterlist_get_double(parlist, PACKAGE,
00282                                                      RECIPE_STRING,
00283                                                      "sigma_4sources");
00284 
00285     destripe = irplib_parameterlist_get_bool(parlist, PACKAGE, RECIPE_STRING,
00286                                              "destriping");
00287 
00288     morpho = irplib_parameterlist_get_bool(parlist, PACKAGE, RECIPE_STRING,
00289                                            "morpho");
00290 
00291     debug = irplib_parameterlist_get_bool(parlist, PACKAGE, RECIPE_STRING,
00292                                            "debug");
00293 
00294     bug_if(0);
00295 
00296     combined = visir_chop_nod_burst(framelist, parlist, startindex, indice_pos,
00297                                     indice_neg, left_chop, left_nod, sigma_nod,
00298                                     sigma_chop, sigma_4sources, destripe,
00299                                     morpho, debug);
00300     skip_if (combined == NULL);
00301 
00302     /* Create the product */
00303     skip_if(irplib_dfs_save_image(framelist, parlist, framelist, combined,
00304                                   CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
00305                                   "IMG_BURST_COMBINED", NULL, NULL,
00306                                   visir_pipe_id,
00307                                   RECIPE_STRING "_combined" CPL_DFS_FITS));
00308 
00309     end_skip;
00310 
00311     cpl_image_delete(combined);
00312 
00313     return cpl_error_get_code();
00314 }
00315 
00316 /*----------------------------------------------------------------------------*/
00355 /*----------------------------------------------------------------------------*/
00356 static cpl_image *
00357 visir_chop_nod_burst(cpl_frameset            * framelist,
00358                      const cpl_parameterlist * parlist,
00359                      int                       startindex,
00360                      int                       indice_pos,
00361                      int                       indice_neg,
00362                      int                       left_chop,
00363                      int                       left_nod,
00364                      double                    sigma_nod,
00365                      double                    sigma_chop,
00366                      double                    sigma_4sources,
00367                      cpl_boolean               destripe,
00368                      cpl_boolean               morpho,
00369                      cpl_boolean               debug)
00370 {
00371     /*
00372   @param    frame0      nodding position A
00373   @param    frame1      nodding position B
00374     */
00375     cpl_frame * frame0;
00376     cpl_frame * frame1;
00377 
00378     cpl_propertylist * plist = NULL;
00379     double             chop_freq, dit;
00380     const char       * filename;
00381     const char       * sval;
00382     cpl_matrix       * kernel = NULL;
00383     int                periode, nima;
00384     int                index_file1, index_file2;
00385     int                startindex_loc;
00386     cpl_imagelist    * cube_chop_nod = NULL;
00387     cpl_image        * final = NULL;
00388 
00389 
00390     bug_if(0);
00391 
00392     frame0 = cpl_frameset_get_frame(framelist, 0);
00393     frame1 = cpl_frameset_get_frame(framelist, 1);
00394 
00395     skip_if(0);
00396 
00397     cpl_frame_set_group(frame0, CPL_FRAME_GROUP_RAW);
00398     cpl_frame_set_group(frame1, CPL_FRAME_GROUP_RAW);
00399 
00400     bug_if(0);
00401 
00402     /* get the chopping frequency and the DIT of one image in burst mode
00403         to know how many images correspond to one position chopping */
00404     filename = cpl_frame_get_filename(frame1);
00405     skip_if(filename == NULL);
00406     plist = cpl_propertylist_load(filename, 0);
00407     irplib_ensure(plist != NULL, cpl_error_get_code(), "Could not load the "
00408                   "property list from %s", filename);
00409     dit       = visir_pfits_get_dit(plist);
00410     sval      = visir_pfits_get_filter(plist);
00411     chop_freq = cpl_propertylist_get_double(plist,
00412                                             VISIR_PFITS_DOUBLE_CHOP_FREQ);
00413     nima      = visir_pfits_get_naxis3(plist);
00414     skip_if(0);
00415     cpl_msg_info(cpl_func, "Burst integration time = %g s.", dit);
00416     cpl_msg_info(cpl_func, "chopping frequency = %g Hz", chop_freq);
00417     cpl_msg_info(cpl_func, "Filter = %s", sval);
00418     cpl_msg_info(cpl_func, "RA  = %g", visir_pfits_get_ra(plist));
00419     sval = cpl_propertylist_get_comment(plist, "RA");
00420     skip_if(0);
00421     cpl_msg_info(cpl_func, "RA  = %s", sval);
00422     cpl_msg_info(cpl_func, "DEC = %g", visir_pfits_get_dec(plist));
00423     sval = cpl_propertylist_get_comment(plist, "DEC");
00424     skip_if(0);
00425     cpl_msg_info(cpl_func, "DEC = %s", sval);
00426     cpl_msg_info(cpl_func, "AIRMASS = %g",
00427             cpl_propertylist_get_double(plist, "ESO TEL AIRM START"));
00428     cpl_msg_info(cpl_func, "SEEING START = %g",
00429             cpl_propertylist_get_double(plist, "ESO TEL AMBI FWHM START"));
00430     cpl_msg_info(cpl_func, "SEEING END = %g",
00431             cpl_propertylist_get_double(plist, "ESO TEL AMBI FWHM END"));
00432     cpl_msg_info(cpl_func, "HUMIDITY = %g",
00433             cpl_propertylist_get_double(plist, "ESO TEL AMBI RHUM"));
00434     cpl_msg_info(cpl_func, "Average Coherence time = %g",
00435             cpl_propertylist_get_double(plist, "ESO TEL AMBI TAU0"));
00436     cpl_msg_info(cpl_func, "Wind speed = %g",
00437             cpl_propertylist_get_double(plist, "ESO TEL AMBI WINDSP"));
00438     cpl_msg_info(cpl_func,"RA DEC = %g",
00439             cpl_propertylist_get_double(plist, "ESO ADA GUID RA"));
00440     sval = cpl_propertylist_get_comment(plist, "ESO ADA GUID RA");
00441     skip_if(0);
00442     cpl_msg_info(cpl_func,"RA GUID = %s", sval);
00443     cpl_msg_info(cpl_func,"DEC GUID = %g",
00444             cpl_propertylist_get_double(plist, "ESO ADA GUID DEC"));
00445     sval = cpl_propertylist_get_comment(plist, "ESO ADA GUID DEC");
00446     skip_if(0);
00447     cpl_msg_info(cpl_func,"DEC GUID = %s", sval);
00448 
00449     cpl_propertylist_delete(plist);
00450     plist = NULL;
00451 
00452     /*number of frames in one position chopping*/
00453     periode=(((1/chop_freq)/dit)/2)+0.5;
00454     cpl_msg_info(cpl_func, "Periode = %d", periode);
00455 
00456     /*define kernel as a gaussian 2d with sigma=1.*/
00457     kernel =  visir_img_burst_psf_create(9);
00458 
00459     cpl_ensure(kernel != NULL, cpl_error_get_code(), NULL);
00460 
00461     /* Make a statistic on the cube to measure the noise and
00462      * skip the first startindex file where the noise is too high
00463      * -> transient effect of the detector*/
00464     if (startindex == -1)   startindex_loc=find_starting_index(frame0, frame1);
00465     else                    startindex_loc=startindex;
00466     cpl_msg_info(cpl_func, "Start index = %d", startindex_loc);
00467 
00468     /* Get the index in the files */
00469     cpl_msg_info(cpl_func, "Get the index");
00470     if (visir_img_burst_get_index(frame0, frame1, kernel, periode,
00471                 startindex_loc, indice_pos, indice_neg, left_nod, sigma_nod,
00472                 sigma_chop, left_chop, &index_file1, &index_file2) == -1)
00473     {
00474         cpl_msg_error(cpl_func, "Cannot get the index");
00475         cpl_matrix_delete(kernel);
00476         return NULL;
00477     }
00478     cpl_msg_info(cpl_func,"Index 1st file = %d", index_file1);
00479     cpl_msg_info(cpl_func,"Index 2nd file = %d", index_file2);
00480 
00481     /* Create cube_chop_nod */
00482     cpl_msg_info(cpl_func, "Create cube_chop_nod");
00483     if ((cube_chop_nod = visir_img_burst_create_chop_nod(frame0, frame1, nima,
00484                     index_file1, index_file2, periode)) == NULL)
00485     {
00486         cpl_msg_error(cpl_func, "Cannot create cube_chop_nod");
00487         cpl_matrix_delete(kernel);
00488         return NULL;
00489     }
00490 
00491     if (debug)
00492     {
00493         cpl_imagelist_save(cube_chop_nod,
00494                            RECIPE_STRING "_cube_chop_nod" CPL_DFS_FITS,
00495                            CPL_BPP_IEEE_FLOAT, NULL, CPL_IO_DEFAULT);
00496     }
00497     /* Destripe if requested */
00498     if (destripe)
00499     {
00500         if (visir_destripe_imagelist(cube_chop_nod, 15, morpho)) {
00501             cpl_msg_error(cpl_func, "Could not destripe");
00502             cpl_matrix_delete(kernel);
00503             cpl_imagelist_delete(cube_chop_nod);
00504             return NULL;
00505         }
00506         cpl_imagelist_save(cube_chop_nod,
00507                            RECIPE_STRING "_cube_chop_nod_destriped" CPL_DFS_FITS,
00508                            CPL_BPP_IEEE_FLOAT, NULL, CPL_IO_DEFAULT);
00509 
00510     }
00511 
00512     /* Create the final image */
00513     cpl_msg_info(cpl_func, "Creating the final image");
00514     final = visir_img_burst_create_combined(framelist, parlist,
00515                                             cube_chop_nod, kernel,
00516                                             sigma_4sources, debug);
00517 
00518     if (final == NULL)
00519         cpl_msg_error(cpl_func, "Could not create the final image");
00520 
00521     end_skip;
00522 
00523     cpl_imagelist_delete(cube_chop_nod);
00524     cpl_matrix_delete(kernel);
00525     cpl_propertylist_delete(plist);
00526 
00527     return final;
00528 }
00529 
00530 
00531 /*
00532  * Take the cube of images of each file .fits of the framelist.
00533  * Subtract the 2 cubes (nod A - nod B) image by image.
00534  * It is not necessary to take all the 1000 images in account: need
00535  * to know the start point, when the 2 sources(pos and neg)
00536  * are moving.(need quantity of images less than the period) */
00537 static int visir_img_burst_get_index(cpl_frame        * frame0,
00538                                      cpl_frame        * frame1,
00539                                      const cpl_matrix * kernel,
00540                                      int             periode,
00541                                      int             startindex,
00542                                      int             indice_pos,
00543                                      int             indice_neg,
00544                                      int             left_nod,
00545                                      double          sigma_nod,
00546                                      double          sigma_chop,
00547                                      int             left_chop,
00548                                      int         *   index_file1,
00549                                      int         *   index_file2)
00550 {
00551     int                 *   quadrant_pos;
00552     int                 *   quadrant_neg;
00553     double              *   position_x_pos;
00554     double              *   position_x_neg;
00555     cpl_image           *   image;
00556     cpl_image           *   image_poly;
00557     cpl_image           *   tmp_image;
00558     cpl_image           *   image_conv;
00559     cpl_apertures       *   aperts;
00560     char                    position_pos;
00561     char                    position00 = '?';
00562     int                     quadrant00;
00563     int                     indice_pos_loc, indice_neg_loc;
00564     int                     i;
00565 
00566     /* Initialise */
00567     indice_pos_loc = indice_pos;
00568     indice_neg_loc = indice_neg;
00569 
00570     /* Allocate the quadrant array */
00571     quadrant_pos=cpl_malloc((periode+1)*(sizeof(int)));
00572     quadrant_neg=cpl_malloc((periode+1)*(sizeof(int)));
00573     position_x_pos=cpl_malloc((periode+1)*(sizeof(double)));
00574     position_x_neg=cpl_malloc((periode+1)*(sizeof(double)));
00575 
00576     if (indice_pos_loc == -1 || indice_neg_loc == -1 || left_nod == -1 )
00577     {
00578         for (i=startindex; i<startindex+periode+1; i++)
00579         {
00580             image = cpl_image_load(cpl_frame_get_filename(frame0),
00581                     CPL_TYPE_FLOAT,i,0);
00582             tmp_image = cpl_image_load(cpl_frame_get_filename(frame1),
00583                     CPL_TYPE_FLOAT,i,0);
00584             cpl_image_subtract(image, tmp_image);
00585             cpl_image_delete(tmp_image);
00586             if (image == NULL)
00587             {
00588                 cpl_msg_error(cpl_func, "Cannot subtract the images");
00589                 cpl_free(quadrant_pos);
00590                 cpl_free(quadrant_neg);
00591                 cpl_free(position_x_pos);
00592                 cpl_free(position_x_neg);
00593                 return -1;
00594             }
00595 
00596             /* Subtract a poly_1d fit of the image itself */
00597             if ((tmp_image = image_1d_poly_create(image)) == NULL)
00598             {
00599                 cpl_free(quadrant_pos);
00600                 cpl_free(quadrant_neg);
00601                 cpl_free(position_x_pos);
00602                 cpl_free(position_x_neg);
00603                 cpl_image_delete(image);
00604                 return -1;
00605             }
00606             cpl_image_subtract(image, tmp_image);
00607             cpl_image_delete(tmp_image);
00608 
00609             /* Make a median (5,5) and a convolution by gaussian 9x9 */
00610             if ((image_conv = image_median_conv(image, kernel, 3)) == NULL)
00611             {
00612                 cpl_msg_error(cpl_func, "Cannot do the convolution");
00613                 cpl_free(quadrant_pos);
00614                 cpl_free(quadrant_neg);
00615                 cpl_free(position_x_pos);
00616                 cpl_free(position_x_neg);
00617                 cpl_image_delete(image);
00618                 return -1;
00619             }
00620             cpl_image_delete(image);
00621 
00622             /* Detection of positiv source and put the localisation in a
00623              * quandrant number */
00624             if (indice_pos_loc == -1 || left_nod == -1)
00625             {
00626                 aperts = visir_img_burst_extract(image_conv, sigma_nod);
00627                 if (aperts == NULL)
00628                 {
00629                     cpl_msg_info(cpl_func, "Cannot detect positive source: i=%d",
00630                             i);
00631                     /*it means the chopper is changing position*/
00632                     quadrant_pos[i-startindex]=0;
00633                 }
00634                 else
00635                 {
00636                     position_x_pos[i-startindex] =
00637                         cpl_apertures_get_centroid_x(aperts, 1);
00638                     quadrant_pos[i-startindex] =
00639                         visir_img_burst_get_quadrant(
00640                                 cpl_apertures_get_centroid_x(aperts, 1),
00641                                 cpl_apertures_get_centroid_y(aperts, 1));
00642                 }
00643                 cpl_apertures_delete(aperts);
00644 
00645                 if (i-startindex != 0)
00646                 {
00647                     if (((quadrant_pos[i-startindex] !=
00648                                     quadrant_pos[i-startindex-1]) &&
00649                                 (fabs(position_x_pos[i-startindex]-
00650                                       position_x_pos[i-startindex-1]) < 10)) ||
00651                                 (quadrant_pos[i-startindex-1] == 0) )
00652                     {
00653                         indice_pos_loc = i;
00654                     }
00655                 }
00656             }
00657 
00658             /* detection of negativ source and put the localisation in a
00659              * quandrant number to detect the postion in order to make the
00660              * chopping substraction */
00661             if (indice_neg_loc == -1)
00662             {
00663                 cpl_image_multiply_scalar(image_conv, -1);
00664                 aperts = visir_img_burst_extract(image_conv, sigma_nod);
00665                 cpl_image_multiply_scalar(image_conv, -1);
00666                 if(aperts == NULL)
00667                 {
00668                     cpl_msg_info(cpl_func, "Cannot detect negative source: i=%d",
00669                             i);
00670                     /*it means the chopper is changing position*/
00671                     quadrant_neg[i-startindex]=0;
00672                 }
00673                 else
00674                 {
00675                     position_x_neg[i-startindex]=
00676                         cpl_apertures_get_centroid_x(aperts, 1);
00677                     quadrant_neg[i-startindex] =
00678                         visir_img_burst_get_quadrant(
00679                                 cpl_apertures_get_centroid_x(aperts, 1),
00680                                 cpl_apertures_get_centroid_y(aperts, 1));
00681                 }
00682                 cpl_apertures_delete(aperts);
00683 
00684                 if (i-startindex != 0)
00685                 {
00686                     if (((quadrant_neg[i-startindex] !=
00687                                     quadrant_neg[i-startindex-1]) &&
00688                                 (fabs(position_x_neg[i-startindex]-
00689                                       position_x_neg[i-startindex-1]) < 10)) ||
00690                             (quadrant_neg[i-startindex-1] == 0))
00691                     {
00692                         indice_neg_loc = i;
00693                     }
00694                 }
00695             }
00696             cpl_image_delete(image_conv);
00697         }
00698     }
00699     cpl_msg_info(cpl_func, "Index pos = %d ", indice_pos_loc);
00700     cpl_msg_info(cpl_func, "Index neg = %d ", indice_neg_loc);
00701 
00702     /*determination of the side of the positive source in the nodding guess*/
00703     if (quadrant_pos[0]==1 || quadrant_pos[0]==3)   position_pos='l';
00704     else                                            position_pos='r';
00705     if(left_nod == 0)                               position_pos='r';
00706     if(left_nod == 1)                               position_pos='l';
00707 
00708     cpl_msg_info(cpl_func, "Side of the positive source in nodding -> %c",
00709             position_pos);
00710 
00711     cpl_free(position_x_pos);
00712     cpl_free(position_x_neg);
00713     cpl_free(quadrant_neg);
00714     cpl_free(quadrant_pos);
00715 
00716     cpl_msg_info(cpl_func, "left_chop = %d", left_chop);
00717     if (left_chop == -1)
00718     {
00719         /* first guess: detection of the sources on the first chopping in the
00720          * first nodding position (first file) in order to know which file
00721          * corresponds to the source positiv or negativ; to know if the first
00722          * file corresponds to the left size or to the right size of the image
00723          */
00724         image=cpl_image_load(cpl_frame_get_filename(frame0),CPL_TYPE_FLOAT,
00725                startindex,0);
00726         tmp_image=cpl_image_load(cpl_frame_get_filename(frame0),
00727                CPL_TYPE_FLOAT,startindex+periode,0);
00728         cpl_image_subtract(image, tmp_image);
00729         cpl_image_delete(tmp_image);
00730         if(image == NULL)
00731         {
00732             cpl_msg_info(cpl_func,"Cannot subtract the chopping guess");
00733             return -1;
00734         }
00735         image_poly = image_1d_poly_create(image);
00736         cpl_image_subtract(image,image_poly);
00737         cpl_image_delete(image_poly);
00738 
00739         image_conv = image_median_conv(image, kernel, 5);
00740         cpl_image_delete(image);
00741         /* make the substraction of the file startindex minus
00742          * the file 'startindex+periode':
00743          * it is sure to have a position 1-position 2 in the chopping position*/
00744         aperts = visir_img_burst_extract(image_conv, sigma_chop);
00745         cpl_image_delete(image_conv);
00746         if(aperts == NULL)
00747         {
00748             cpl_msg_error(cpl_func,
00749                     "Cannot detect object in the 1st chopping guess");
00750             cpl_msg_error(cpl_func, "---> reduce sigma_chop");
00751             return -1;
00752         }
00753         else
00754         {
00755             quadrant00 = visir_img_burst_get_quadrant(
00756                     cpl_apertures_get_centroid_x(aperts,1),
00757                     cpl_apertures_get_centroid_y(aperts,1));
00758             cpl_apertures_delete(aperts);
00759         }
00760         if (quadrant00 == 1 || quadrant00 ==3) {position00='l';}
00761         if (quadrant00 == 2 || quadrant00 ==4) {position00='r';}
00762         cpl_msg_info(cpl_func, "Side of the positive source in chopping -> %c",
00763                 position00);
00764         cpl_msg_info(cpl_func, "Quadrant of the positive source in chopping = %d",
00765                 quadrant00);
00766     }
00767 
00768     /*determination of the side of the positive source in the chopping guess*/
00769     if (left_chop == 1) {position00='l';}
00770     if (left_chop == 0) {position00='r';}
00771     cpl_msg_info(cpl_func, "Side of the positive source in chopping -> %c",
00772             position00);
00773 
00774     /*determination if the first file correspond to the left or
00775      * right of the image*/
00776     if (position_pos == position00)
00777     {
00778         *index_file1 = indice_pos_loc;
00779         *index_file2 = indice_neg_loc;
00780     }
00781     else
00782     {
00783         *index_file1 = indice_neg_loc;
00784         *index_file2 = indice_pos_loc;
00785     }
00786     return 0;
00787 }
00788 
00789 static cpl_imagelist * visir_img_burst_create_chop_nod(
00790         cpl_frame   *   frame0,
00791         cpl_frame   *   frame1,
00792         int             nima,
00793         int             index_file1,
00794         int             index_file2,
00795         int             periode)
00796 {
00797     cpl_imagelist       *   cube_chop_pos;
00798     cpl_imagelist       *   cube_chop_neg;
00799     int                     max_index;
00800     int                     nchop_cycles;
00801     cpl_image           *   image1;
00802     cpl_image           *   image2;
00803     int                     i, k;
00804 
00805     /* Reload the raw image to make the chopping substraction in a fits file*/
00806     cube_chop_pos=cpl_imagelist_new();
00807     cube_chop_neg=cpl_imagelist_new();
00808 
00809    /* Calculate the maximum number of chopping cycle taking into account
00810     * the starting file*/
00811    if (index_file1 > index_file2)   max_index = index_file1;
00812    else                             max_index = index_file2;
00813 
00814    nchop_cycles = (nima-max_index) / (periode*2+1);
00815    cpl_msg_info(cpl_func, "Number of chopping cycles = %d", nchop_cycles);
00816 
00817    /*make the chopping subtraction in each fits file*/
00818    for (k=0; k<nchop_cycles; k++)
00819     {
00820         cpl_msg_info(cpl_func, "Chopping cycle number %d", k+1);
00821         /* for the first file */
00822         for (i=index_file1+1+(2*periode*k);
00823                 i <index_file1+1+(2*periode*k)+periode; i++)
00824             /*with the +1,the first file where the chopper stabilizes
00825              * is taken away*/
00826         {
00827             image1 = cpl_image_load(cpl_frame_get_filename(frame0),
00828                     CPL_TYPE_FLOAT,i+periode,0);
00829             image2 = cpl_image_load(cpl_frame_get_filename(frame0),
00830                     CPL_TYPE_FLOAT,i,0);
00831             cpl_image_subtract(image1,image2);
00832             cpl_image_delete(image2);
00833             nima = cpl_imagelist_get_size(cube_chop_pos);
00834             cpl_imagelist_set(cube_chop_pos, image1, nima);
00835         }
00836 
00837         /*for the second file*/
00838         for(i=index_file2+1+(2*periode*k);
00839                 i <index_file2+1+(2*periode*k)+periode; i++)
00840         {
00841             image1=cpl_image_load(cpl_frame_get_filename(frame1),
00842                     CPL_TYPE_FLOAT,i+periode,0);
00843             image2=cpl_image_load(cpl_frame_get_filename(frame1),
00844                     CPL_TYPE_FLOAT,i,0);
00845             cpl_image_subtract(image1,image2);
00846             cpl_image_delete(image2);
00847             nima = cpl_imagelist_get_size(cube_chop_neg);
00848             cpl_imagelist_set(cube_chop_neg,image1, nima);
00849         }
00850     }
00851 
00852     /*substraction to have the image chopped and nodded*/
00853     if (cpl_imagelist_subtract(cube_chop_pos,cube_chop_neg) != CPL_ERROR_NONE)
00854     {
00855         cpl_msg_error(cpl_func, "Cannot subtract image lists");
00856         cpl_imagelist_delete(cube_chop_neg);
00857         cpl_imagelist_delete(cube_chop_pos);
00858         return NULL;
00859     }
00860     cpl_imagelist_delete(cube_chop_neg);
00861     return cube_chop_pos;
00862 }
00863 
00864 
00865 /*---------------- method to sum all the sources-----------------------
00866  * detect the position of the 4 sources in an image and
00867  * take a box around them that we keep to take the sources in the
00868  * other images.
00869  * we make 4 shift and add with 4 quadrants in each image*/
00870 static cpl_image *
00871 visir_img_burst_create_combined(cpl_frameset            * framelist,
00872                                 const cpl_parameterlist * parlist,
00873                                 cpl_imagelist           * cube_chop_nod,
00874                                 const cpl_matrix        * kernel,
00875                                 double                    sigma_4sources,
00876                                 cpl_boolean               debug)
00877 {
00878     cpl_image           *   image;
00879     cpl_bivector        *   positions;
00880     int                     size;
00881     double                  x1, x2, x3, x4, y_1, y2, y3, y4;
00882     cpl_image           *   image_pos1,
00883                         *   image_pos2,
00884                         *   image_neg1,
00885                         *   image_neg2;
00886     cpl_imagelist       *   cube1,
00887                         *   cube2,
00888                         *   cube3,
00889                         *   cube4;
00890     cpl_image           *   combined_1,
00891                         *   combined_2,
00892                         *   combined_3,
00893                         *   combined_4;
00894     cpl_imagelist       *   cube_final;
00895     cpl_vector          *   taille_x,
00896                         *   taille_y;
00897     double                  min_x, min_y;
00898     cpl_image           *   combined = NULL;
00899     int                     j;
00900 
00901 
00902     /*take the image in the middle of the cube to be sure to have no noise*/
00903     image=cpl_imagelist_get(cube_chop_nod,cpl_imagelist_get_size
00904             (cube_chop_nod)/2);
00905     if (image == NULL)
00906     {
00907         cpl_msg_error(cpl_func, "Cannot get the first chopping guess");
00908         return NULL;
00909     }
00910 
00911     /*detect the position of the 4 sources in the first image*/
00912     /*the number after the kernel is the threshold for detection*/
00913     /*the last number is the size box of the median*/
00914     positions = visir_extract_4_sources_box(image, kernel, sigma_4sources, 3,
00915                                             debug);
00916     if (positions == NULL)
00917     {
00918         image=cpl_imagelist_get(cube_chop_nod,cpl_imagelist_get_size
00919                     (cube_chop_nod)/3);
00920         positions = visir_extract_4_sources_box(image, kernel, sigma_4sources,
00921                                                 3, debug);
00922     }
00923     if (positions == NULL)
00924     {
00925         cpl_msg_info(cpl_func, "Cannot detect -> reduce sigma_4sources");
00926         return NULL;
00927     }
00928 
00929     /* The box is a square */
00930     size = cpl_vector_get(cpl_bivector_get_x(positions),4);
00931     /* because in the extraction function,we start with (1,1) */
00932     size--;
00933 
00934     /* Get the coordinates of the 4 sources on the image */
00935     x1=cpl_vector_get(cpl_bivector_get_x(positions),0);
00936     x2=cpl_vector_get(cpl_bivector_get_x(positions),1);
00937     x3=cpl_vector_get(cpl_bivector_get_x(positions),2);
00938     x4=cpl_vector_get(cpl_bivector_get_x(positions),3);
00939 
00940     y_1=cpl_vector_get(cpl_bivector_get_y(positions),0);
00941     y2=cpl_vector_get(cpl_bivector_get_y(positions),1);
00942     y3=cpl_vector_get(cpl_bivector_get_y(positions),2);
00943     y4=cpl_vector_get(cpl_bivector_get_y(positions),3);
00944     cpl_bivector_delete(positions);
00945 
00946     cpl_msg_info(cpl_func,"Source 1 position : (%g, %g)", x1, y_1);
00947     cpl_msg_info(cpl_func,"Source 2 position : (%g, %g)", x2, y2);
00948     cpl_msg_info(cpl_func,"Source 3 position : (%g, %g)", x3, y3);
00949     cpl_msg_info(cpl_func,"Source 4 position : (%g, %g)", x4, y4);
00950 
00951     cube1=cpl_imagelist_new();
00952     cube2=cpl_imagelist_new();
00953     cube3=cpl_imagelist_new();
00954     cube4=cpl_imagelist_new();
00955     cpl_msg_info(cpl_func,"Extract the 4 sources in the chopped/nodded cube");
00956     for (j=0; j<cpl_imagelist_get_size(cube_chop_nod);j++)
00957     {
00958         image=cpl_imagelist_get(cube_chop_nod,j);
00959         /* made 4 box around each of the 4 sources*/
00960         if (x1 < 500 && y_1 < 500)
00961         {image_pos1=cpl_image_extract(image,x1-size,y_1-size,x1+size,y_1+size);}
00962         else {image_pos1=cpl_image_extract(image,1,1,2*size+1,2*size+1); }
00963         if (x2 < 500 && y2 < 500)
00964         {image_pos2=cpl_image_extract(image,x2-size,y2-size,x2+size,y2+size);}
00965         else {image_pos2=cpl_image_extract(image,1,1,2*size+1,2*size+1);}
00966         if(x3 < 500 && y3 < 500)
00967         {image_neg1=cpl_image_extract(image,x3-size,y3-size,x3+size,y3+size);}
00968         else {image_neg1=cpl_image_extract(image,1,1,2*size+1,2*size+1);}
00969         if(x4 < 500 && y4 < 500)
00970         {image_neg2=cpl_image_extract(image,x4-size,y4-size,x4+size,y4+size);}
00971         else {image_neg2=cpl_image_extract(image,1,1,2*size+1,2*size+1);}
00972 
00973         cpl_imagelist_set(cube1,image_pos1,j);
00974         cpl_imagelist_set(cube2,image_pos2,j);
00975         cpl_image_multiply_scalar(image_neg1,-1);
00976         cpl_image_multiply_scalar(image_neg2,-1);
00977         cpl_imagelist_set(cube3,image_neg1,j);
00978         cpl_imagelist_set(cube4,image_neg2,j);
00979     }
00980 
00981     if (cube1 == NULL || cube2 == NULL || cube3 == NULL || cube4 == NULL)
00982     {
00983         cpl_msg_error(cpl_func, "Cannot build the 4 cubes");
00984         if (cube1) cpl_imagelist_delete(cube1);
00985         if (cube2) cpl_imagelist_delete(cube2);
00986         if (cube3) cpl_imagelist_delete(cube3);
00987         if (cube4) cpl_imagelist_delete(cube4);
00988         return NULL;
00989     }
00990 
00991     /*combine the 4 cubes of the 4 quadrants of the cube_chop_nod*/
00992     combined_1=imagelist_combine(cube1);
00993     combined_2=imagelist_combine(cube2);
00994     combined_3=imagelist_combine(cube3);
00995     combined_4=imagelist_combine(cube4);
00996 
00997     cpl_imagelist_delete(cube1);
00998     cpl_imagelist_delete(cube2);
00999     cpl_imagelist_delete(cube3);
01000     cpl_imagelist_delete(cube4);
01001 
01002     if ((combined_1 == NULL) ||  (combined_2 == NULL) ||  (combined_3 == NULL)
01003             || (combined_4== NULL))
01004     {
01005         cpl_msg_error(cpl_func, "Cannot shift and add the 4 cubes");
01006         if (combined_1) cpl_image_delete(combined_1);
01007         if (combined_2) cpl_image_delete(combined_2);
01008         if (combined_3) cpl_image_delete(combined_3);
01009         if (combined_4) cpl_image_delete(combined_4);
01010         return NULL;
01011     }
01012 
01013     cube_final=cpl_imagelist_new();
01014     /*find the smallest box to make the shift and add on the 4 final images*/
01015     taille_x=cpl_vector_new(4);
01016     taille_y=cpl_vector_new(4);
01017 
01018     cpl_vector_set(taille_x,0,cpl_image_get_size_x(combined_1));
01019     cpl_vector_set(taille_x,1,cpl_image_get_size_x(combined_2));
01020     cpl_vector_set(taille_x,2,cpl_image_get_size_x(combined_3));
01021     cpl_vector_set(taille_x,3,cpl_image_get_size_x(combined_4));
01022 
01023     cpl_vector_set(taille_y,0,cpl_image_get_size_y(combined_1));
01024     cpl_vector_set(taille_y,1,cpl_image_get_size_y(combined_2));
01025     cpl_vector_set(taille_y,2,cpl_image_get_size_y(combined_3));
01026     cpl_vector_set(taille_y,3,cpl_image_get_size_y(combined_4));
01027 
01028     min_x=cpl_vector_get_min(taille_x);
01029     min_y=cpl_vector_get_min(taille_y);
01030     /*put all the image at the same size,the minimum one */
01031     cpl_imagelist_set(cube_final,cpl_image_extract(combined_1,
01032                 cpl_vector_get(taille_x,0)/2-(min_x/2)+1,
01033                 cpl_vector_get(taille_y,0)/2-(min_y/2)+1,
01034                 cpl_vector_get(taille_x,0)/2+(min_x/2),
01035                 cpl_vector_get(taille_y,0)/2+(min_y/2)),0);
01036     cpl_imagelist_set(cube_final,cpl_image_extract(combined_2,
01037                 cpl_vector_get(taille_x,1)/2-(min_x/2)+1,
01038                 cpl_vector_get(taille_y,1)/2-(min_y/2)+1,
01039                 cpl_vector_get(taille_x,1)/2+(min_x/2),
01040                 cpl_vector_get(taille_y,1)/2+(min_y/2)),1);
01041     cpl_imagelist_set(cube_final,cpl_image_extract(combined_3,
01042                 cpl_vector_get(taille_x,2)/2-(min_x/2)+1,
01043                 cpl_vector_get(taille_y,2)/2-(min_y/2)+1,
01044                 cpl_vector_get(taille_x,2)/2+(min_x/2),
01045                 cpl_vector_get(taille_y,2)/2+(min_y/2)),2);
01046     cpl_imagelist_set(cube_final,cpl_image_extract(combined_4,
01047                 cpl_vector_get(taille_x,3)/2-(min_x/2)+1,
01048                 cpl_vector_get(taille_y,3)/2-(min_y/2)+1,
01049                 cpl_vector_get(taille_x,3)/2+(min_x/2),
01050                 cpl_vector_get(taille_y,3)/2+(min_y/2)),3);
01051     cpl_vector_delete(taille_x);
01052     cpl_vector_delete(taille_y);
01053     cpl_image_delete(combined_1);
01054     cpl_image_delete(combined_2);
01055     cpl_image_delete(combined_3);
01056     cpl_image_delete(combined_4);
01057 
01058     skip_if(irplib_dfs_save_imagelist(framelist, parlist, framelist, cube_final,
01059                                       CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
01060                                       "IMG_BURST_COMBINE_LIST", NULL, NULL,
01061                                       visir_pipe_id, RECIPE_STRING
01062                                       "_cube_4sources" CPL_DFS_FITS));
01063 
01064     /*combine the four images of the final cube*/
01065     if ((combined = imagelist_combine(cube_final)) == NULL)
01066     {
01067         cpl_msg_error(cpl_func, "Cannot do the final shift and add");
01068         cpl_imagelist_delete(cube_final);
01069         return NULL;
01070     }
01071 
01072     end_skip;
01073 
01074     cpl_imagelist_delete(cube_final);
01075 
01076     return combined;
01077 }
01078 
01079 static int visir_img_burst_get_quadrant(double x, double y)
01080 {
01081     if (x > 128.0 && y > 128.0) return 2;
01082     if (x > 128.0 && y < 128.0) return 4;
01083     if (x < 128.0 && y > 128.0) return 1;
01084     if (x < 128.0 && y < 128.0) return 3;
01085     return -1;
01086 }
01087 
01088 
01089 /*make a function which finds the combine of a cube : *************************
01090  * we have to put all the images of the cube at the same level.
01091  * for the moment:no convolution with a kernel:we let the option.*/
01092 static cpl_image * imagelist_combine(cpl_imagelist * cube)
01093 {
01094     cpl_bivector        *   offset;
01095     cpl_bivector        *   offset_find;
01096     cpl_bivector        *   position;
01097     cpl_vector          *   correl;
01098     double              *   offs_ref_pur_x;
01099     double              *   offs_ref_pur_y;
01100     cpl_bivector        *   offs_ref_purged;
01101     int                     i,j;
01102     double              *   correl_data;
01103     double              *   offset_find_x,    * offset_find_y;
01104     int                     ngood;
01105     cpl_image           **  combined;
01106     cpl_image           *   out_ima;
01107     double                  center_x,center_y;
01108     int                     n;
01109     cpl_image           *   image;
01110     cpl_imagelist       *   cube_essai;
01111     double                  mean1,mean2;
01112     FILE                *   f_out;
01113 
01114     n=cpl_imagelist_get_size(cube);
01115     correl=cpl_vector_new(n);
01116 
01117     /*define the first estimate of the offset*/
01118     offset=cpl_bivector_new(n);
01119     cpl_vector_fill(cpl_bivector_get_x(offset),0.);
01120     cpl_vector_fill(cpl_bivector_get_y(offset),0.);
01121 
01122     /*define the bivector of the correlation point:sources are centered*/
01123     position=cpl_bivector_new(1);
01124     center_x=cpl_image_get_size_x(cpl_imagelist_get(cube,0))/2;
01125     center_y=cpl_image_get_size_y(cpl_imagelist_get(cube,0))/2;
01126     cpl_vector_fill(cpl_bivector_get_x(position),center_x);
01127     cpl_vector_fill(cpl_bivector_get_y(position),center_y);
01128 
01129     cube_essai=cpl_imagelist_new();
01130 
01131     /*method:we put the cube to the same level of noise to calculate the offset
01132      * that we apply on the real cube of data,not modified*/
01133 
01134     /*put the cube to the same level*/
01135     image = cpl_image_duplicate(cpl_imagelist_get(cube,0));
01136     mean1=cpl_image_get_mean(image);
01137     cpl_imagelist_set(cube_essai,image,0);
01138 
01139     for (i=1; i<n;  i++)
01140     {
01141         mean2=cpl_image_get_mean(cpl_imagelist_get(cube,i));
01142         image=cpl_image_add_scalar_create(cpl_imagelist_get(cube,i),
01143                 mean1-mean2);
01144         cpl_imagelist_set(cube_essai,image,i);
01145     }
01146 
01147     /*depends which cube we want to combine*/
01148     if (n == 4)
01149     {
01150         offset_find=cpl_geom_img_offset_fine(cube_essai, offset, position,
01151                 15,15 ,10, 10, correl);
01152     }
01153     else
01154     {
01155         offset_find=cpl_geom_img_offset_fine(cube_essai, offset, position,
01156                 10,10,10, 10, correl);
01157     }
01158     cpl_bivector_delete(offset);
01159     cpl_bivector_delete(position);
01160     cpl_imagelist_delete(cube_essai);
01161     if(offset_find == NULL)
01162     {
01163         cpl_msg_error(cpl_func, "Cannot find the offsets");
01164         cpl_vector_delete(correl);
01165         return NULL;
01166     }
01167 
01168     f_out=fopen(VISIR_IMG_BURST_SHIFT_FILE,"a");
01169     cpl_bivector_dump(offset_find,f_out);
01170     fclose(f_out);
01171 
01172     /*select the good offset where the correlation has worked*/
01173     offset_find_x = cpl_bivector_get_x_data(offset_find);
01174     offset_find_y = cpl_bivector_get_y_data(offset_find);
01175     correl_data = cpl_vector_get_data(correl);
01176     ngood = 0;
01177     for (i=0; i<cpl_imagelist_get_size(cube); i++)
01178         if (correl_data[i] > -0.5) ngood++;
01179     cpl_msg_info(cpl_func, "Good frames: %d / %d", ngood,
01180                  (int)cpl_imagelist_get_size(cube));
01181 
01182     /* Purge the bad correlated planes */
01183     cpl_imagelist_erase(cube, correl);
01184     offs_ref_purged = cpl_bivector_new(ngood);
01185     offs_ref_pur_x = cpl_bivector_get_x_data(offs_ref_purged);
01186     offs_ref_pur_y = cpl_bivector_get_y_data(offs_ref_purged);
01187     j = 0;
01188     for (i=0; i<n; i++)
01189     {
01190         if (correl_data[i] > -0.5)
01191         {
01192             offs_ref_pur_x[j] = offset_find_x[i];
01193             offs_ref_pur_y[j] = offset_find_y[i];
01194             j++;
01195         }
01196     }
01197     cpl_bivector_delete(offset_find);
01198     cpl_vector_delete(correl);
01199 
01200     /* Apply the shift & add on nodded */
01201     combined=cpl_geom_img_offset_saa(cube, offs_ref_purged,
01202             CPL_KERNEL_DEFAULT, 0., 0., CPL_GEOM_UNION, NULL, NULL);
01203     cpl_bivector_delete(offs_ref_purged);
01204     if (combined == NULL)
01205     {
01206         cpl_msg_error(cpl_func, "Cannot shift and add");
01207         return NULL;
01208     }
01209 
01210     /* Free and return */
01211     out_ima = cpl_image_duplicate(combined[0]);
01212     cpl_image_delete(combined[0]);
01213     cpl_image_delete(combined[1]);
01214     cpl_free(combined);
01215     return out_ima;
01216 }
01217 
01218 
01219 /*function which calculates statistic over a cube of images and****************
01220  * decides when the noise level is ok*/
01221 static int find_starting_index (
01222         cpl_frame   *   frame0,
01223         cpl_frame   *   frame1)
01224 {
01225     cpl_vector          *   stdev,  *   stdev_extract;
01226     cpl_propertylist    *   plist;
01227     int                     NAXIS3;
01228     int                     i;
01229     cpl_image           *   image,  * image1;
01230     double                  mean;
01231     double                  val;
01232     double                  threshold;
01233 
01234     cpl_msg_info(cpl_func, "Finding startindex");
01235     plist = cpl_propertylist_load(cpl_frame_get_filename(frame1), 0);
01236     NAXIS3 = visir_pfits_get_naxis3(plist);
01237     stdev=cpl_vector_new(NAXIS3);
01238 
01239     for(i=0;   i   <   NAXIS3;   i++)
01240     {
01241         image=cpl_image_load(cpl_frame_get_filename(frame0),
01242                         CPL_TYPE_FLOAT,i,0);
01243         image1=cpl_image_load(cpl_frame_get_filename(frame1),
01244                         CPL_TYPE_FLOAT,i,0);
01245         cpl_image_subtract(image,image1);
01246         cpl_image_delete(image1);
01247 
01248         cpl_vector_set(stdev,i,cpl_image_get_stdev(image));
01249         cpl_image_delete(image);
01250     }
01251 
01252     stdev_extract=cpl_vector_extract(stdev,NAXIS3-1-100,NAXIS3-1,1);
01253     mean=cpl_vector_get_mean(stdev_extract);
01254     threshold=1.3   *   mean; /*30% above the mean value*/
01255     cpl_vector_delete(stdev_extract);
01256 
01257     for(i=NAXIS3-1; i>0; i--)
01258     {
01259         val=cpl_vector_get(stdev,i);
01260         if(val > threshold)  {break;}
01261     }
01262     cpl_vector_delete(stdev);
01263 
01264     return i+1;
01265 }
01266 
01267 /*make a fit 1d-polynomial to an image*****************************************/
01268 static cpl_image *  image_1d_poly_create(const cpl_image  *   image)
01269 {
01270     const cpl_size   degree   = 1;
01271     const int        sizex    = cpl_image_get_size_x(image);
01272     const int        sizey    = cpl_image_get_size_y(image);
01273     cpl_matrix     * pixpos   = cpl_matrix_new(2, sizex * sizey);
01274     cpl_vector     * val      = cpl_vector_new(sizex * sizey);
01275     double         * pixpos_x = cpl_matrix_get_data(pixpos);
01276     double         * pixpos_y = pixpos_x + sizex * sizey;
01277     cpl_polynomial * poly;
01278     cpl_image      * image_poly;
01279     int              j;
01280     int              k = 0;
01281     cpl_error_code   error;
01282 
01283 
01284     for (j = 0; j < sizey; j++) {
01285         int i;
01286         for (i = 0; i < sizex; i++) {
01287             int          is_rejected;
01288             const double pixval = cpl_image_get(image, i+1, j+1, &is_rejected);
01289 
01290             if (!is_rejected) {
01291                 pixpos_x[k] = i;
01292                 pixpos_y[k] = j;
01293                 (void)cpl_vector_set(val, k, pixval);
01294                 k++;
01295             }
01296         }
01297     }
01298 
01299     cpl_vector_set_size(val, k);
01300     cpl_matrix_set_size(pixpos, 2, k);
01301 
01302     poly = cpl_polynomial_new(2);
01303     error = cpl_polynomial_fit(poly, pixpos, NULL, val, NULL, CPL_FALSE, NULL,
01304                                &degree);
01305 
01306     cpl_matrix_delete(pixpos);
01307     cpl_vector_delete(val);
01308 
01309     if (error) {
01310         cpl_msg_error(cpl_func,"Cannot fit the image");
01311         cpl_polynomial_delete(poly);
01312         return NULL;
01313     }
01314     image_poly = cpl_image_new(sizex, sizey, CPL_TYPE_FLOAT);
01315 
01316     error = cpl_image_fill_polynomial(image_poly, poly, 1.0,1.0,1.0,1.0);
01317     cpl_polynomial_delete(poly);
01318 
01319     if (error) {
01320         cpl_msg_error(cpl_func, "Could not fill the polynomial image");
01321         cpl_image_delete(image_poly);
01322         return NULL;
01323     }
01324 
01325     return image_poly;
01326 }
01327 
01328 /*----------------------------------------------------------------------------*/
01349 /*----------------------------------------------------------------------------*/
01350 static cpl_apertures * visir_img_burst_extract(
01351         const cpl_image     *   in,
01352         double                  sigma)
01353 {
01354     double              median, med_dist;
01355     double              threshold;
01356     cpl_mask        *   selection;
01357     cpl_mask        *   kernel = NULL;
01358     cpl_image       *   labels;
01359     cpl_apertures   *   aperts;
01360     cpl_size            nlabels;
01361     int                 i,j;
01362     int                 sizex,sizey;
01363     cpl_mask       *    edge;
01364     cpl_binary     *    data;
01365     const int           size = 17;
01366 
01367     /* Check entries */
01368     cpl_ensure(in, CPL_ERROR_NULL_INPUT, NULL);
01369     cpl_ensure(sigma>0.0, CPL_ERROR_ILLEGAL_INPUT, NULL);
01370 
01371     /* Compute the threshold */
01372     median = cpl_image_get_median_dev(in, &med_dist);
01373     threshold = median + sigma * med_dist;
01374     /* threshold = sigma * cpl_image_get_stdev(in);*/
01375 
01376     /* Binarise the image */
01377     selection = cpl_mask_threshold_image_create(in, threshold, DBL_MAX);
01378     cpl_ensure(selection, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
01379 
01380     /*modification on the 27/09/05:
01381       to avoid the bad detection on the side:
01382       put the mask to zero on the edge to not take into account
01383       the strong background*/
01384     sizex=cpl_image_get_size_x(in);
01385     sizey=cpl_image_get_size_y(in);
01386     edge=cpl_mask_new(sizex,sizey);
01387     data=cpl_mask_get_data(edge);
01388 
01389     for (i=size; i < sizex-size; i++)
01390     {
01391         for (j=size; j < sizey-size; j++)
01392         {
01393             data[i+j*sizex]=CPL_BINARY_1;
01394         }
01395     }
01396 
01397     /*cpl_image_save(selection,"selection.fits",CPL_BPP_IEEE_FLOAT, NULL,
01398                                            CPL_IO_DEFAULT);
01399     cpl_image_save(edge,"edge.fits",CPL_BPP_IEEE_FLOAT, NULL,
01400                                                        CPL_IO_DEFAULT);
01401     */
01402 
01403     cpl_mask_and(selection,edge);
01404     if (selection == NULL)
01405 
01406     {
01407         cpl_msg_error(cpl_func,"problem in the mask reduction because of the edge");
01408         return NULL;
01409     }
01410     cpl_mask_delete(edge);
01411 
01412     /* Apply a morphological closing to remove the single pixel detections */
01413     kernel = cpl_mask_new(3, 3);
01414     cpl_mask_not(kernel);
01415 
01416     if (cpl_mask_filter(selection, selection, kernel,
01417                             CPL_FILTER_CLOSING, CPL_BORDER_ZERO)) {
01418         cpl_mask_delete(selection);
01419         cpl_mask_delete(kernel);
01420         cpl_ensure(0, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
01421     }
01422 
01423     cpl_mask_delete(kernel);
01424 
01425     /* Labelise the different detected apertures */
01426     if ((labels = cpl_image_labelise_mask_create(selection, &nlabels))==NULL)
01427     {
01428         cpl_mask_delete(selection);
01429         cpl_ensure(0, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
01430     }
01431     cpl_mask_delete(selection);
01432 
01433     /* Nothing detected */
01434     if (nlabels == 0)
01435     {
01436         cpl_image_delete(labels);
01437         return NULL;
01438     }
01439 
01440     /* Create the detected apertures list */
01441     if ((aperts = cpl_apertures_new_from_image(in, labels)) == NULL)
01442     {
01443         cpl_image_delete(labels);
01444         cpl_ensure(0, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
01445     }
01446     /*sort apertures by number of pixels*/
01447     cpl_apertures_sort_by_flux(aperts);
01448 
01449     /* Free and return */
01450     cpl_image_delete(labels);
01451     return aperts;
01452 }
01453 
01454 /* function which makes a median on  square box*******************************
01455  * but we don't care about the edge
01456  return an image with value 0 on the edge: original size minus
01457  'size' on each edge*/
01458 static cpl_image * cpl_image_get_median_choose(const cpl_image * image,
01459                                                int               size)
01460 {
01461     const int   sizex = cpl_image_get_size_x(image);
01462     const int   sizey = cpl_image_get_size_y(image);
01463     const int   hsize = size/2;
01464     cpl_image * self  = cpl_image_new(sizex, sizey, CPL_TYPE_FLOAT);
01465     cpl_mask  * kernel = cpl_mask_new(1+2*hsize, 1+2*hsize);
01466 
01467     bug_if(image == NULL);
01468 
01469     bug_if(hsize <= 0);
01470     bug_if(sizex <= hsize);
01471     bug_if(sizey <= hsize);
01472 
01473     bug_if(cpl_mask_not(kernel));
01474     bug_if(cpl_image_filter_mask(self, image, kernel, CPL_FILTER_MEDIAN,
01475                                  CPL_BORDER_NOP));
01476 
01477     end_skip;
01478 
01479     cpl_mask_delete(kernel);
01480 
01481     return self;
01482 }
01483 
01484 /*function which returns a bivector of size 5:
01485  * the 4 positions of the 4 sources in the image and
01486  * the size (size_x,size_y) of the box addapted for the extraction.
01487  the kernel is used to make the convolution:in order to detect the sources*/
01488 static cpl_bivector * visir_extract_4_sources_box(cpl_image        * image,
01489                                                   const cpl_matrix * kernel,
01490                                                   double             sigma,
01491                                                   int             taille_median,
01492                                                   cpl_boolean        debug)
01493 {
01494     cpl_image       *   image_diff;
01495     cpl_image       *   image_poly;
01496     cpl_image       *   image_conv;
01497     cpl_apertures   *   aper_pos,
01498                     *   aper_neg;
01499     int                 quadrant1, quadrant2;
01500     cpl_vector      *   taille;
01501     int                 dimx, dimy, size, x1, x2, x3, x4, y_1, y2, y3, y4;
01502     cpl_bivector    *   result;
01503     int                 index;
01504 
01505     dimx=cpl_image_get_size_x(image);
01506     dimy=cpl_image_get_size_y(image);
01507 
01508     image_poly=image_1d_poly_create(image);
01509     image_diff = cpl_image_subtract_create(image,image_poly);
01510     cpl_image_delete(image_poly);
01511 
01512     /*size of the median box is choosed*/
01513     image_conv = image_median_conv(image_diff, kernel, taille_median);
01514     cpl_image_delete(image_diff);
01515     if(image_conv == NULL) return NULL;
01516 
01517     /*image_conv=cpl_image_get_median_choose(image,taille_median);*/
01518     if (debug == 1) {
01519         cpl_image_save(image_conv, RECIPE_STRING "_image00_median" CPL_DFS_FITS,
01520                        CPL_BPP_IEEE_FLOAT, NULL, CPL_IO_DEFAULT);
01521     }
01522 
01523     aper_pos=visir_img_burst_extract(image_conv, sigma);
01524     if(aper_pos == NULL)
01525     {
01526         cpl_msg_error(cpl_func,"cannot detect the positive object");
01527         cpl_image_delete(image_conv);
01528         return  NULL;
01529     }
01530     cpl_image_multiply_scalar(image_conv, -1);
01531     aper_neg=visir_img_burst_extract(image_conv, sigma);
01532     cpl_image_delete(image_conv);
01533 
01534     if (cpl_apertures_get_size(aper_pos) < 2  ||
01535          cpl_apertures_get_size(aper_neg) < 2)
01536     {
01537         cpl_msg_info(cpl_func,"no 2 sources in the detection of the 4 sources");
01538         if (aper_pos) cpl_apertures_delete(aper_pos);
01539         if (aper_neg) cpl_apertures_delete(aper_neg);
01540         return NULL;
01541     }
01542 
01543     /*detect the 2 sources positiv in the image*/
01544     quadrant1 = visir_img_burst_get_quadrant(
01545             cpl_apertures_get_centroid_x(aper_pos,1),
01546             cpl_apertures_get_centroid_y(aper_pos,1));
01547     quadrant2 = visir_img_burst_get_quadrant(
01548             cpl_apertures_get_centroid_x(aper_pos,2),
01549             cpl_apertures_get_centroid_y(aper_pos,2));
01550 
01551     if ((quadrant1 == 1 && quadrant2 == 3)||(quadrant2 == 1 && quadrant1 == 3))
01552         cpl_msg_warning(cpl_func,"2 sources detected on the same side");
01553 
01554     if ((quadrant1 == 2 && quadrant2 == 4)||(quadrant2 == 2 && quadrant1 == 4))
01555         cpl_msg_warning(cpl_func,"2 sources detected on the same side");
01556 
01557     /*coordinates of the 4 sources in the image*/
01558     x1=cpl_apertures_get_centroid_x(aper_pos,1);
01559     y_1=cpl_apertures_get_centroid_y(aper_pos,1);
01560     x2=cpl_apertures_get_centroid_x(aper_pos,2);
01561     y2=cpl_apertures_get_centroid_y(aper_pos,2);
01562     x3=cpl_apertures_get_centroid_x(aper_neg,1);
01563     y3=cpl_apertures_get_centroid_y(aper_neg,1);
01564     x4=cpl_apertures_get_centroid_x(aper_neg,2);
01565     y4=cpl_apertures_get_centroid_y(aper_neg,2);
01566     cpl_apertures_delete(aper_pos);
01567     cpl_apertures_delete(aper_neg);
01568 
01569     result=cpl_bivector_new(5);
01570 
01571     if ((x1 > 15) && (x1 < dimx-1-15)) /*not near the edge*/
01572         cpl_vector_set(cpl_bivector_get_x(result),0,x1);
01573     else
01574         cpl_vector_set(cpl_bivector_get_x(result),0,1000);
01575     if ((x2 > 15) && (x2 < dimx-1-15)) /*not near the edge*/
01576         cpl_vector_set(cpl_bivector_get_x(result),1,x2);
01577     else
01578         cpl_vector_set(cpl_bivector_get_x(result),1,1000);
01579     if ((x3 > 15) && (x3 < dimx-1-15)) /*not near the edge*/
01580         cpl_vector_set(cpl_bivector_get_x(result),2,x3);
01581     else
01582         cpl_vector_set(cpl_bivector_get_x(result),2,1000);
01583     if ((x4 > 15) && (x4 < dimx-1-15)) /*not near the edge*/
01584         cpl_vector_set(cpl_bivector_get_x(result),3,x4);
01585     else
01586         cpl_vector_set(cpl_bivector_get_x(result),3,1000);
01587     if ((y_1 > 15) && (y_1 < dimy-1-15)) /*not near the edge*/
01588         cpl_vector_set(cpl_bivector_get_y(result),0,y_1);
01589     else
01590         cpl_vector_set(cpl_bivector_get_y(result),0,1000);
01591     if ((y2 > 15) && (y2 < dimy-1-15)) /*not near the edge*/
01592         cpl_vector_set(cpl_bivector_get_y(result),1,y2);
01593     else
01594         cpl_vector_set(cpl_bivector_get_y(result),1,1000);
01595     if ((y3 > 15) && (y3 < dimy-1-15)) /*not near the edge*/
01596         cpl_vector_set(cpl_bivector_get_y(result),2,y3);
01597     else
01598         cpl_vector_set(cpl_bivector_get_y(result),2,1000);
01599     if ((y4 > 15) && (y4 < dimy-1-15)) /*not near the edge*/
01600         cpl_vector_set(cpl_bivector_get_y(result),3,y4);
01601     else
01602         cpl_vector_set(cpl_bivector_get_y(result),3,1000);
01603 
01604     x1=cpl_vector_get(cpl_bivector_get_x(result),0);
01605     x2=cpl_vector_get(cpl_bivector_get_x(result),1);
01606     x3=cpl_vector_get(cpl_bivector_get_x(result),2);
01607     x4=cpl_vector_get(cpl_bivector_get_x(result),3);
01608     y_1=cpl_vector_get(cpl_bivector_get_y(result),0);
01609     y2=cpl_vector_get(cpl_bivector_get_y(result),1);
01610     y3=cpl_vector_get(cpl_bivector_get_y(result),2);
01611     y4=cpl_vector_get(cpl_bivector_get_y(result),3);
01612 
01613     /*
01614     cpl_msg_info(cpl_func,"aper=%d\n",x1);
01615     cpl_msg_info(cpl_func,"aper=%d\n",x2);
01616     cpl_msg_info(cpl_func,"aper=%d\n",x3);
01617     cpl_msg_info(cpl_func,"aper=%d\n",x4);
01618     cpl_msg_info(cpl_func,"aper=%d\n",y_1);
01619     cpl_msg_info(cpl_func,"aper=%d\n",y2);
01620     cpl_msg_info(cpl_func,"aper=%d\n",y3);
01621     cpl_msg_info(cpl_func,"aper=%d\n",y4);
01622      */
01623 
01624     /*vector to calculate the size of the box:
01625      we take the minimum size taking into accompt the edge */
01626     taille=cpl_vector_new(22);
01627 
01628     if (fabs(x1-x2) > 50)
01629         cpl_vector_set(taille,0,fabs(x1-x2)/2);
01630     else
01631         cpl_vector_set(taille,0,1000);
01632     if(fabs(x1-x3) >50)
01633         cpl_vector_set(taille,1,fabs(x1-x3)/2);
01634     else
01635         cpl_vector_set(taille,1,1000);
01636     if (fabs(x1-x4) > 50 && fabs(x1-x4) < dimx)
01637         cpl_vector_set(taille,2,fabs(x1-x4)/2);
01638     else
01639         cpl_vector_set(taille,2,1000);
01640     if (fabs(y_1-y2) > 50)
01641         cpl_vector_set(taille,3,fabs(y_1-y2)/2);
01642     else
01643         cpl_vector_set(taille,3,1000);
01644     if (fabs(y_1-y3) > 50)
01645         cpl_vector_set(taille,4,fabs(y_1-y3)/2);
01646     else
01647         cpl_vector_set(taille,4,1000);
01648     if (fabs(y_1-y4) > 50)
01649         cpl_vector_set(taille,5,fabs(y_1-y4)/2);
01650     else
01651         cpl_vector_set(taille,5,1000);
01652 
01653     /*cpl_msg_info(cpl_func,"taille[0]=%g\n",cpl_vector_get(taille,0));
01654       cpl_msg_info(cpl_func,"taille[0]=%g\n",cpl_vector_get(taille,1));
01655       cpl_msg_info(cpl_func,"taille[0]=%g\n",cpl_vector_get(taille,2));
01656       cpl_msg_info(cpl_func,"taille[0]=%g\n",cpl_vector_get(taille,3));
01657       cpl_msg_info(cpl_func,"taille[0]=%g\n",cpl_vector_get(taille,4));
01658       cpl_msg_info(cpl_func,"taille[0]=%g\n",cpl_vector_get(taille,5));
01659      */
01660 
01661     cpl_vector_set(taille,6,x1);/*necessary if the source is near the edge*/
01662     cpl_vector_set(taille,7,dimx-1-x1);
01663     cpl_vector_set(taille,8,x2);
01664     cpl_vector_set(taille,9,dimx-1-x2);
01665     cpl_vector_set(taille,10,x3);
01666     cpl_vector_set(taille,11,dimx-1-x3);
01667     cpl_vector_set(taille,12,x4);
01668     cpl_vector_set(taille,13,dimx-1-x4);
01669     cpl_vector_set(taille,14,y_1);
01670     cpl_vector_set(taille,15,dimy-1-y_1);
01671     cpl_vector_set(taille,16,y2);
01672     cpl_vector_set(taille,17,dimy-1-y2);
01673     cpl_vector_set(taille,18,y3);
01674     cpl_vector_set(taille,19,dimy-1-y3);
01675     cpl_vector_set(taille,20,y4);
01676     cpl_vector_set(taille,21,dimy-1-y4);
01677 
01678     cpl_vector_sort(taille,1);
01679 
01680     index=cpl_vector_find(taille,0.);
01681     size=cpl_vector_get(taille,index); /*2*size is the size of the final box*/
01682     cpl_vector_delete(taille);
01683 
01684     cpl_vector_set(cpl_bivector_get_x(result),4,size);
01685     cpl_vector_set(cpl_bivector_get_y(result),4,size);
01686 
01687     /*
01688        cpl_msg_info(cpl_func,"p=%d\n",size);
01689        cpl_msg_info(cpl_func,"aper=%d\n",x1);
01690        cpl_msg_info(cpl_func,"aper=%d\n",x2);
01691        cpl_msg_info(cpl_func,"aper=%d\n",x3);
01692        cpl_msg_info(cpl_func,"aper=%d\n",x4);
01693        cpl_msg_info(cpl_func,"aper=%d\n",y_1);
01694        cpl_msg_info(cpl_func,"aper=%d\n",y2);
01695        cpl_msg_info(cpl_func,"aper=%d\n",y3);
01696        cpl_msg_info(cpl_func,"aper=%d\n",y4);
01697      */
01698 
01699     return result;
01700 }
01701 
01702 
01703 /*function which makes a median(taille,taille) + ******************************
01704  * convolution by a kernel of maximum size 9x9*/
01705 static cpl_image * image_median_conv(const cpl_image * image,
01706                                      const cpl_matrix * kernel,
01707                                      int taille)
01708 {
01709     /* make a median (taille,taille)*/
01710     cpl_image    * image_median = cpl_image_get_median_choose(image, taille);
01711     cpl_image    * image_conv;
01712     cpl_error_code error;
01713 
01714     cpl_ensure(image_median != NULL, cpl_error_get_code(), NULL);
01715     /* make a convolution with a kernel*/
01716     image_conv = cpl_image_new(cpl_image_get_size_x(image_median),
01717                                cpl_image_get_size_y(image_median),
01718                                cpl_image_get_type(image_median));
01719 
01720     error = cpl_image_filter(image_conv, image_median, kernel,
01721                              CPL_FILTER_LINEAR, CPL_BORDER_FILTER);
01722 
01723     cpl_image_delete(image_median);
01724 
01725     if (error) {
01726         cpl_image_delete(image_conv);
01727         cpl_ensure(0, error, NULL);
01728     }
01729 
01730     return image_conv;
01731 }
01732 
01733 /*----------------------------------------------------------------------------*/
01742 /*----------------------------------------------------------------------------*/
01743 static cpl_matrix * visir_img_burst_psf_create(int size)
01744 {
01745     cpl_matrix * self  = NULL;
01746     cpl_image  * iself = cpl_image_wrap_double(size, size,
01747                                                cpl_malloc(size * size
01748                                                           * sizeof(double)));
01749     const double hsize = floor(size / 2.0);
01750     const double scale = CPL_MATH_SQRT2PI;
01751     double       flux;
01752     int          i;
01753 
01754 
01755     bug_if(0);
01756     bug_if(size < 1);
01757 
01758     for (i=0; i < size; i++) {
01759         int j;
01760         for (j=0; j <= i; j++) {
01761             const double value = exp(-0.5*((i-hsize)*(i-hsize)+
01762                                            (j-hsize)*(j-hsize)));
01763             (void)cpl_image_set(iself, i+1, j+1, value/scale);
01764             if (i != j)
01765                 (void)cpl_image_set(iself, j+1, i+1, value/scale);
01766         }
01767     }
01768 
01769     flux = cpl_image_get_flux(iself);
01770 
01771     bug_if(flux <= 0.0);
01772     bug_if(cpl_image_divide_scalar(iself, flux));
01773 
01774     self = cpl_matrix_wrap(size, size, (double*)cpl_image_unwrap(iself));
01775     iself = NULL;
01776 
01777     end_skip;
01778 
01779     cpl_image_delete(iself);
01780 
01781     return self;
01782 }
01783 
01784 
01785 /*----------------------------------------------------------------------------*/
01793 /*----------------------------------------------------------------------------*/
01794 static
01795 cpl_error_code visir_destripe_imagelist(cpl_imagelist * self,
01796                                         int             niter,
01797                                         cpl_boolean     morpho)
01798 {
01799     const double threshold = 3.5 * 1.64;
01800     const double threshold_detect = 1.3;
01801     const int    size = cpl_imagelist_get_size(self);
01802     int          i;
01803 
01804     bug_if(self == NULL);
01805     bug_if(niter < 1);
01806 
01807     cpl_msg_info(cpl_func, "Destriping %d images using %d iterations and "
01808                  "threshold=%g, detection-threshold=%g", size, niter, threshold,
01809                  threshold_detect);
01810 
01811     /* Loop on images  */
01812     for (i = 0; i < size; i++) {
01813         cpl_image * image = cpl_imagelist_get(self, i);
01814 
01815         cpl_msg_info(cpl_func, "Destriping image %d of %d", i+1, size);
01816 
01817         if (visir_destripe_image(image, niter, threshold, threshold_detect,
01818                                  morpho)) break;
01819     }
01820 
01821     skip_if(0);
01822 
01823     end_skip;
01824 
01825     return cpl_error_get_code();
01826 }
01827 
01828 #include <visir_destripe.c>

Generated on Mon Feb 6 15:23:49 2012 for VISIR Pipeline Reference Manual by  doxygen 1.5.8