visir_img_burst.c

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

Generated on Fri Jul 3 11:15:23 2009 for VISIR Pipeline Reference Manual by  doxygen 1.5.8