visir_img_burst.c

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

Generated on Tue Jun 29 12:20:52 2010 for VISIR Pipeline Reference Manual by  doxygen 1.4.7