visir_img_burst.c

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

Generated on Thu Mar 24 11:59:39 2011 for VISIR Pipeline Reference Manual by  doxygen 1.5.8