source: trunk/src/ATrous/ReconSearch.cc @ 208

Last change on this file since 208 was 205, checked in by Matthew Whiting, 18 years ago

Changes here mostly aimed at reducing/removing memory leaks. These were one of:

  • Forgetting to delete something allocated with "new". The Cube destructor has improved with the use of bool variables to keep track of when recon & baseline ahave been allocated.
  • Incorrectly using the wcs->flag parameter (eg. wcsIO had it set to -1 *after* calling wcsini)
  • Not closing a fits file once finished with (dataIO)
  • Allocating the wcsprm structs with calloc before calling wcsini, so that wcsvfree can work (it calls "free", so the memory needs to be allocated with calloc or malloc).

The only other change was the following:

  • A new way of doing the Cube::setCubeStats -- rather than calling the functions in getStats.cc, we explicitly do the calculations. This means we can sort the tempArray that has the BLANKS etc removed. This saves a great deal of memory usage on large FITS files (such as Enno's 2Gb one)
  • The old setCubeStats function is still there but called setCubeStatsOld.
File size: 9.6 KB
Line 
1#include <fstream>
2#include <iostream>
3#include <iomanip>
4#include <vector>
5#include <duchamp.hh>
6#include <Cubes/cubes.hh>
7#include <Detection/detection.hh>
8#include <ATrous/atrous.hh>
9#include <Utils/utils.hh>
10#include <Utils/Statistics.hh>
11
12void Cube::ReconSearch()
13{
14  /**
15   * Cube::ReconSearch()
16   *   The Cube is first reconstructed, using Cube::ReconCube().
17   *   It is then searched, using searchReconArray.
18   *   The resulting object list is stored in the Cube, and outputted
19   *    to the log file if the user so requests.
20   */
21 
22  this->ReconCube();
23
24  this->setCubeStats();
25   
26  std::cout << "  Searching... " << std::flush;
27 
28  this->objectList = searchReconArray(this->axisDim,this->array,
29                                      this->recon,this->par,this->Stats);
30
31  this->updateDetectMap();
32  if(this->par.getFlagLog()) this->logDetectionList();
33
34}
35
36/////////////////////////////////////////////////////////////////////////////
37void Cube::ReconCube()
38{
39  /**
40   * Cube::ReconSearch()
41   *   A front-end to the various reconstruction functions, the choice of
42   *    which is determined by the use of the reconDim parameter.
43   *   Differs from ReconSearch only in that no searching is done.
44   */
45  int dimRecon = this->par.getReconDim();
46  // Test whether we have eg. an image, but have requested a 3-d
47  //  reconstruction.
48  // If dimension of data array is less than dimRecon, change dimRecon
49  //  to the dimension of the array.
50  int numGoodDim = 0;
51  for(int i=0;i<this->numDim;i++) if(this->axisDim[i]>1) numGoodDim++;
52  if(numGoodDim<dimRecon) dimRecon = numGoodDim;
53  this->par.setReconDim(dimRecon);
54
55  switch(dimRecon)
56    {
57    case 1: this->ReconCube1D(); break;
58    case 2: this->ReconCube2D(); break;
59    case 3: this->ReconCube3D(); break;
60    default:
61      if(dimRecon<=0){
62        std::stringstream errmsg;
63        errmsg << "reconDim (" << dimRecon
64               << ") is less than 1. Performing 1-D reconstruction.\n";
65        duchampWarning("ReconCube", errmsg.str());
66        this->par.setReconDim(1);
67        this->ReconCube1D();
68      }
69      else if(dimRecon>3){
70        //this probably won't happen with new code above, but just in case...
71        std::stringstream errmsg;
72        errmsg << "reconDim (" << dimRecon
73               << ") is more than 3. Performing 3-D reconstruction.\n";
74        duchampWarning("ReconCube", errmsg.str());
75        this->par.setReconDim(3);
76        this->ReconCube3D();
77      }
78      break;
79    }
80}
81
82/////////////////////////////////////////////////////////////////////////////
83void Cube::ReconCube1D()
84{
85  /**
86   * Cube::ReconCube1D()
87   *   This reconstructs a cube by performing a 1D a trous reconstruction
88   *   in the spectrum of each spatial pixel.
89   */
90  long xySize = this->axisDim[0] * this->axisDim[1];
91
92  long zdim = this->axisDim[2];
93
94  ProgressBar bar;
95  if(!this->reconExists){
96    std::cout<<"  Reconstructing... ";
97    if(par.isVerbose()) bar.init(xySize);
98    for(int npix=0; npix<xySize; npix++){
99
100      if( par.isVerbose() ) bar.update(npix+1);
101
102      float *spec = new float[zdim];
103      float *newSpec = new float[zdim];
104      for(int z=0;z<zdim;z++) spec[z] = this->array[z*xySize + npix];
105      bool verboseFlag = this->par.isVerbose();
106      this->par.setVerbosity(false);
107      atrous1DReconstruct(this->axisDim[2],spec,newSpec,this->par);
108      this->par.setVerbosity(verboseFlag);
109      for(int z=0;z<zdim;z++) this->recon[z*xySize+npix] = newSpec[z];
110      delete [] spec;
111      delete [] newSpec;
112    }
113    this->reconExists = true;
114    bar.rewind();
115    std::cout << "  All Done.";
116    printSpace(22);
117    std::cout << "\n";
118  }
119
120}
121
122/////////////////////////////////////////////////////////////////////////////
123void Cube::ReconCube2D()
124{
125  /**
126   * Cube::ReconCube2D()
127   *   This reconstructs a cube by performing a 2D a trous reconstruction
128   *   in each spatial image (ie. each channel map) of the cube.
129   */
130  long xySize = this->axisDim[0] * this->axisDim[1];
131  ProgressBar bar;
132
133  if(!this->reconExists){
134    std::cout<<"  Reconstructing... ";
135    if(par.isVerbose()) bar.init(this->axisDim[2]);
136    for(int z=0;z<this->axisDim[2];z++){
137
138      if( par.isVerbose() ) bar.update((z+1));
139
140      if(!this->par.isInMW(z)){
141        float *im = new float[xySize];
142        float *newIm = new float[xySize];
143        for(int npix=0; npix<xySize; npix++)
144          im[npix] = this->array[z*xySize+npix];
145        bool verboseFlag = this->par.isVerbose();
146        this->par.setVerbosity(false);
147        atrous2DReconstruct(this->axisDim[0],this->axisDim[1],
148                            im,newIm,this->par);
149        this->par.setVerbosity(verboseFlag);
150        for(int npix=0; npix<xySize; npix++)
151          this->recon[z*xySize+npix] = newIm[npix];
152        delete [] im;
153        delete [] newIm;
154      }
155      else {
156        for(int i=z*xySize; i<(z+1)*xySize; i++)
157          this->recon[i] = this->array[i];
158      }
159    }
160    this->reconExists = true;
161    bar.rewind();
162    std::cout << "  All Done.";
163    printSpace(22);
164    std::cout << "\n";
165  }
166}
167
168/////////////////////////////////////////////////////////////////////////////
169void Cube::ReconCube3D()
170{
171  /**
172   * Cube::ReconCube3D()
173   *   This performs a full 3D a trous reconstruction of the cube
174   */
175  if(this->axisDim[2]==1) this->ReconCube2D();
176  else {
177
178    if(!this->reconExists){
179      std::cout<<"  Reconstructing... "<<std::flush;
180      atrous3DReconstruct(this->axisDim[0],this->axisDim[1],this->axisDim[2],
181                          this->array,this->recon,this->par);
182      this->reconExists = true;
183      std::cout << "  All Done.";
184      printSpace(22);
185      std::cout << "\n";
186    }
187
188  }
189}
190
191/////////////////////////////////////////////////////////////////////////////
192vector <Detection> searchReconArray(long *dim, float *originalArray,
193                                    float *reconArray, Param &par,
194                                    StatsContainer<float> &stats)
195{
196  /**
197   * searchReconArray(long *dim, float *originalArray,
198   *                  float *reconArray, Param &par)
199   *   This searches for objects in a cube that has been reconstructed.
200   *
201   *   Inputs:   - dimension array
202   *             - original, un-reconstructed image array
203   *             - reconstructed image array
204   *             - parameters
205   *
206   *   Searches first in each spatial pixel (1D search),
207   *   then in each channel image (2D search).
208   *
209   *   Returns: vector of Detections resulting from the search.
210   */
211  vector <Detection> outputList;
212  long zdim = dim[2];
213  long xySize = dim[0] * dim[1];
214  int num=0;
215
216  bool *doPixel = new bool[xySize];
217  // doPixel is a bool array to say whether to look in a given spectrum
218  for(int npix=0; npix<xySize; npix++){
219    doPixel[npix] = false;
220    for(int z=0;z<zdim;z++) {
221      doPixel[npix] = doPixel[npix] ||
222        (!par.isBlank(originalArray[npix]) && !par.isInMW(z));
223    }
224    // doPixel[i] is false only when there are no good pixels in spectrum
225    //  of pixel #i.
226  }
227 
228  ProgressBar bar;
229  // First search --  in each spectrum.
230  if(zdim > 1){
231    if(par.isVerbose()){
232      std::cout << "1D: ";
233      bar.init(xySize);
234    }
235
236    for(int npix=0; npix<xySize; npix++){
237
238      if( par.isVerbose() ) bar.update(npix+1);
239
240      if(doPixel[npix]){
241
242        long *specdim = new long[2];
243        specdim[0] = zdim; specdim[1]=1;
244        Image *spectrum = new Image(specdim);
245        delete [] specdim;
246        spectrum->saveParam(par);
247        spectrum->saveStats(stats);
248        // beam size: for spectrum, only neighbouring channels correlated
249        spectrum->extractSpectrum(reconArray,dim,npix);
250        spectrum->setMinSize(par.getMinChannels());
251        spectrum->removeMW(); // only works if flagMW is true
252        spectrum->spectrumDetect();
253        num += spectrum->getNumObj();
254        for(int obj=0;obj<spectrum->getNumObj();obj++){
255          Detection *object = new Detection;
256          *object = spectrum->getObject(obj);
257          for(int pix=0;pix<object->getSize();pix++) {
258            // Fix up coordinates of each pixel to match original array
259            object->setZ(pix, object->getX(pix));
260            object->setX(pix, npix%dim[0]);
261            object->setY(pix, npix/dim[0]);
262            object->setF(pix, originalArray[object->getX(pix)+
263                                            object->getY(pix)*dim[0]+
264                                            object->getZ(pix)*xySize]);
265            // NB: set F to the original value, not the recon value.
266          }
267          object->addOffsets(par);
268          object->calcParams();
269          mergeIntoList(*object,outputList,par);
270          delete object;
271        }
272        delete spectrum;
273      }
274    }
275
276    num = outputList.size();
277    if(par.isVerbose()) {
278      bar.rewind();
279      std::cout <<"Found " << num <<"; " << std::flush;
280    }
281  }
282
283  // Second search --  in each channel
284  if(par.isVerbose()){
285    std::cout << "2D: ";
286    bar.init(zdim);
287  }
288
289  num = 0;
290
291  for(int z=0; z<zdim; z++){  // loop over all channels
292
293    if( par.isVerbose() ) bar.update(z+1);
294
295    if(!par.isInMW(z)){
296      // purpose of this is to ignore the Milky Way channels
297      //  if we are flagging them
298
299      long *imdim = new long[2];
300      imdim[0] = dim[0]; imdim[1] = dim[1];
301      Image *channelImage = new Image(imdim);
302      channelImage->saveParam(par);
303      channelImage->saveStats(stats);
304      delete [] imdim;
305      channelImage->extractImage(reconArray,dim,z);
306      channelImage->setMinSize(par.getMinPix());
307      channelImage->lutz_detect();
308      num += channelImage->getNumObj();
309      for(int obj=0;obj<channelImage->getNumObj();obj++){
310        Detection *object = new Detection;
311        *object = channelImage->getObject(obj);
312        // Fix up z coordinates of each pixel to match original array
313        //   (x & y are fine)
314        for(int pix=0;pix<object->getSize();pix++){
315          object->setZ(pix, z);
316          object->setF(pix, originalArray[object->getX(pix)+
317                                          object->getY(pix)*dim[0]+
318                                          z*xySize]);
319          // NB: set F to the original value, not the recon value.
320        }
321        object->addOffsets(par);
322        object->calcParams();
323        mergeIntoList(*object,outputList,par);
324        delete object;
325      }
326      delete channelImage;
327   }
328
329  }
330
331  bar.rewind();
332  std::cout << "Found " << num << ".";
333  printSpace(22); 
334  std::cout << std::endl << std::flush;
335
336  delete [] doPixel;
337
338  return outputList;
339}
Note: See TracBrowser for help on using the repository browser.