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

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

Large suite of edits, mostly due to testing with valgrind, which clear up bad memory allocations and so on.
Improved the printing of progress bars in some routines by introducing a new ProgressBar? class, with associated functions to do the printing (now much cleaner).

File size: 11.3 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
11using std::setw;
12
13/////////////////////////////////////////////////////////////////////////////
14void Cube::ReconSearch()
15{
16  /**
17   * Cube::ReconSearch()
18   *   A front-end to the various ReconSearch functions, the choice of
19   *   which is determined by the use of the reconDim parameter.
20   */
21  int dimRecon = this->par.getReconDim();
22 
23  // Test whether we have eg. an image, but have requested a 3-d
24  //  reconstruction.
25  // If dimension of data array is less than dimRecon, change dimRecon
26  //  to the dimension of the array.
27  int numGoodDim = 0;
28  for(int i=0;i<this->numDim;i++) if(this->axisDim[i]>1) numGoodDim++;
29  if(numGoodDim<dimRecon) dimRecon = numGoodDim;
30  this->par.setReconDim(dimRecon);
31
32  switch(dimRecon)
33    {
34    case 1: this->ReconSearch1D(); break;
35    case 2: this->ReconSearch2D(); break;
36    case 3: this->ReconSearch3D(); break;
37    default:
38      if(dimRecon<=0){
39        std::stringstream errmsg;
40        errmsg << "reconDim (" << dimRecon
41               << ") is less than 1. Performing 1-D reconstruction.\n";
42        duchampWarning("ReconSearch", errmsg.str());
43        this->par.setReconDim(1);
44        this->ReconSearch1D();
45      }
46      else if(dimRecon>3){
47        //this probably won't happen with new code above, but just in case...
48        std::stringstream errmsg;
49        errmsg << "reconDim (" << dimRecon
50               << ") is more than 3. Performing 3-D reconstruction.\n";
51        duchampWarning("ReconSearch", errmsg.str());
52        this->par.setReconDim(3);
53        this->ReconSearch3D();
54      }
55      break;
56    }
57 
58}
59
60
61/////////////////////////////////////////////////////////////////////////////
62void Cube::ReconSearch1D()
63{
64  /**
65   * Cube::ReconSearch1D()
66   *   This reconstructs a cube by performing a 1D a trous reconstruction
67   *   in the spectrum of each spatial pixel.
68   *   It then searches the cube using searchReconArray (below).
69   *
70   *   The resulting object list is stored in the Cube.
71   */
72  long xySize = this->axisDim[0] * this->axisDim[1];
73  long zdim = this->axisDim[2];
74
75  ProgressBar bar;
76  // Reconstruct the cube by 1d atrous transform in each spatial pixel
77  if(!this->reconExists){
78    std::cout<<"  Reconstructing... ";
79    if(par.isVerbose()) bar.init(xySize);
80    for(int npix=0; npix<xySize; npix++){
81
82      if( par.isVerbose() ) bar.update(npix+1);
83
84      float *spec = new float[zdim];
85      float *newSpec = new float[zdim];
86      for(int z=0;z<zdim;z++) spec[z] = this->array[z*xySize + npix];
87      bool verboseFlag = this->par.isVerbose();
88      this->par.setVerbosity(false);
89      atrous1DReconstruct(this->axisDim[2],spec,newSpec,this->par);
90      this->par.setVerbosity(verboseFlag);
91      for(int z=0;z<zdim;z++) this->recon[z*xySize+npix] = newSpec[z];
92      delete [] spec,newSpec;
93    }
94    this->reconExists = true;
95    bar.rewind();
96    std::cout << "  All Done.";
97    printSpace(22);
98    std::cout << "\n  Searching... "<<std::flush;
99  }
100   
101  this->objectList = searchReconArray(this->axisDim,this->array,
102                                      this->recon,this->par);
103
104  this->updateDetectMap();
105  if(this->par.getFlagLog()) this->logDetectionList();
106
107}
108
109/////////////////////////////////////////////////////////////////////////////
110void Cube::ReconSearch2D()
111{
112  /**
113   * Cube::ReconSearch2D()
114   *   This reconstructs a cube by performing a 2D a trous reconstruction
115   *   in each spatial image (ie. each channel map) of the cube.
116   *   It then searches the cube using searchReconArray (below).
117   *
118   *   The resulting object list is stored in the Cube.
119   */
120  long xySize = this->axisDim[0] * this->axisDim[1];
121  ProgressBar bar;
122
123  if(!this->reconExists){
124    // RECONSTRUCT THE CUBE BY 2D ATROUS TRANSFORM IN EACH CHANNEL 
125    std::cout<<"  Reconstructing... ";
126    if(par.isVerbose()) bar.init(this->axisDim[2]);
127    for(int z=0;z<this->axisDim[2];z++){
128
129      if( par.isVerbose() ) bar.update((z+1));
130
131      if(!this->par.isInMW(z)){
132        float *im = new float[xySize];
133        float *newIm = new float[xySize];
134        for(int npix=0; npix<xySize; npix++)
135          im[npix] = this->array[z*xySize+npix];
136        bool verboseFlag = this->par.isVerbose();
137        this->par.setVerbosity(false);
138        atrous2DReconstruct(this->axisDim[0],this->axisDim[1],
139                            im,newIm,this->par);
140        this->par.setVerbosity(verboseFlag);
141        for(int npix=0; npix<xySize; npix++)
142          this->recon[z*xySize+npix] = newIm[npix];
143        delete [] im, newIm;
144      }
145      else {
146        for(int i=z*xySize; i<(z+1)*xySize; i++)
147          this->recon[i] = this->array[i];
148      }
149    }
150    this->reconExists = true;
151    bar.rewind();
152    std::cout << "  All Done.";
153    printSpace(22);
154    std::cout << "\nSearching... "<<std::flush;
155
156  }
157
158  this->objectList = searchReconArray(this->axisDim,this->array,
159                                      this->recon,this->par);
160 
161  this->updateDetectMap();
162  if(this->par.getFlagLog()) this->logDetectionList();
163
164}
165
166/////////////////////////////////////////////////////////////////////////////
167void Cube::ReconSearch3D()
168{
169  /**
170   * Cube::ReconSearch3D()
171   *   This performs a full 3D a trous reconstruction of the cube
172   *   It then searches the cube using searchReconArray (below).
173   *
174   *   The resulting object list is stored in the Cube.
175   */
176  if(this->axisDim[2]==1) this->ReconSearch2D();
177  else {
178
179    if(!this->reconExists){
180      std::cout<<"  Reconstructing... "<<std::flush;
181      atrous3DReconstruct(this->axisDim[0],this->axisDim[1],this->axisDim[2],
182                          this->array,this->recon,this->par);
183      this->reconExists = true;
184      std::cout << "  All Done.";
185      printSpace(22);
186      std::cout << "\n  Searching... "<<std::flush;
187    }
188
189    this->objectList = searchReconArray(this->axisDim,this->array,
190                                        this->recon,this->par);
191
192    this->updateDetectMap();
193    if(this->par.getFlagLog()) this->logDetectionList();
194
195  }
196
197}
198
199
200/////////////////////////////////////////////////////////////////////////////
201vector <Detection> searchReconArray(long *dim, float *originalArray,
202                                    float *reconArray, Param &par)
203{
204  /**
205   * searchReconArray(long *dim, float *originalArray,
206   *                  float *reconArray, Param &par)
207   *   This searches for objects in a cube that has been reconstructed.
208   *
209   *   Inputs:   - dimension array
210   *             - original, un-reconstructed image array
211   *             - reconstructed image array
212   *             - parameters
213   *
214   *   Searches first in each spatial pixel (1D search),
215   *   then in each channel image (2D search).
216   *
217   *   Returns: vector of Detections resulting from the search.
218   */
219  vector <Detection> outputList;
220  long zdim = dim[2];
221  long xySize = dim[0] * dim[1];
222  long fullSize = zdim * xySize;
223  int num=0, goodSize;
224
225  bool *isGood = new bool[fullSize];
226  for(int pos=0;pos<fullSize;pos++){
227    isGood[pos] = ((!par.isBlank(originalArray[pos])) &&
228      (!par.isInMW(pos/xySize)));
229  }
230  bool *doChannel = new bool[xySize];
231  for(int npix=0; npix<xySize; npix++){
232    doChannel[npix] = false;
233    for(int z=0;z<zdim;z++)
234      doChannel[npix] = doChannel[npix] || isGood[z*xySize+npix];
235  }
236 
237  ProgressBar bar;
238  // First search --  in each spectrum.
239  if(zdim > 1){
240    if(par.isVerbose()){
241      std::cout << "1D: ";
242      bar.init(xySize);
243    }
244
245    for(int npix=0; npix<xySize; npix++){
246
247      if( par.isVerbose() ) bar.update(npix+1);
248
249      if(doChannel[npix]){
250       
251        // First, get stats
252        float *spec = new float[zdim];
253        float specMedian,specSigma;
254        goodSize=0;
255        for(int z=0;z<zdim;z++) {
256          if(isGood[z*xySize+npix])
257            spec[goodSize++] = originalArray[z*xySize+npix];
258        }
259        specMedian = findMedian(spec,goodSize);
260        goodSize=0;
261        for(int z=0;z<zdim;z++) {
262          if(isGood[z*xySize+npix])
263            spec[goodSize++] = originalArray[z*xySize+npix] -
264              reconArray[z*xySize+npix];
265        }
266        specSigma = findMADFM(spec,goodSize) / correctionFactor;
267        delete [] spec;
268       
269        // Next, do source finding.
270        long *specdim = new long[2];
271        specdim[0] = zdim; specdim[1]=1;
272        Image *spectrum = new Image(specdim);
273        delete [] specdim;
274        spectrum->saveParam(par);
275        spectrum->pars().setBeamSize(2.);
276        // beam size: for spectrum, only neighbouring channels correlated
277        spectrum->extractSpectrum(reconArray,dim,npix);
278        spectrum->removeMW(); // only works if flagMW is true
279        spectrum->setStats(specMedian,specSigma,par.getCut());
280        if(par.getFlagFDR()) spectrum->setupFDR();
281        spectrum->setMinSize(par.getMinChannels());
282        spectrum->spectrumDetect();
283        num += spectrum->getNumObj();
284        for(int obj=0;obj<spectrum->getNumObj();obj++){
285          Detection *object = new Detection;
286          *object = spectrum->getObject(obj);
287          for(int pix=0;pix<object->getSize();pix++) {
288            // Fix up coordinates of each pixel to match original array
289            object->setZ(pix, object->getX(pix));
290            object->setX(pix, npix%dim[0]);
291            object->setY(pix, npix/dim[0]);
292            object->setF(pix, originalArray[object->getX(pix)+
293                                            object->getY(pix)*dim[0]+
294                                            object->getZ(pix)*xySize]);
295            // NB: set F to the original value, not the recon value.
296          }
297          object->addOffsets(par);
298          object->calcParams();
299          mergeIntoList(*object,outputList,par);
300          delete object;
301        }
302        delete spectrum;
303      }
304    }
305
306    num = outputList.size();
307    if(par.isVerbose()) {
308      bar.rewind();
309      std::cout <<"Found " << num <<"; " << std::flush;
310    }
311  }
312
313  // Second search --  in each channel
314  if(par.isVerbose()){
315    std::cout << "2D: ";
316    bar.init(zdim);
317  }
318
319  num = 0;
320
321  for(int z=0; z<zdim; z++){  // loop over all channels
322
323    if( par.isVerbose() ) bar.update(z+1);
324
325    if(!par.isInMW(z)){
326
327      // purpose of this is to ignore the Milky Way channels
328      //  if we are flagging them
329
330      //  First, get stats
331      float *image = new float[xySize];
332      float imageMedian,imageSigma;
333      goodSize=0;
334      for(int npix=0; npix<xySize; npix++) {
335        if(isGood[z*xySize + npix])
336          image[goodSize++] = originalArray[z*xySize + npix];
337      }
338      imageMedian = findMedian(image,goodSize);
339      goodSize=0;
340      for(int npix=0; npix<xySize; npix++)
341        if(isGood[z*xySize+npix])
342          image[goodSize++]=originalArray[z*xySize+npix]-
343            reconArray[z*xySize+npix];
344      imageSigma = findMADFM(image,goodSize) / correctionFactor;
345      delete [] image;
346
347      // Next, do source finding.
348      long *imdim = new long[2];
349      imdim[0] = dim[0]; imdim[1] = dim[1];
350      Image *channelImage = new Image(imdim);
351      channelImage->saveParam(par);
352      delete [] imdim;
353      channelImage->extractImage(reconArray,dim,z);
354      channelImage->setStats(imageMedian,imageSigma,par.getCut());
355      if(par.getFlagFDR()) channelImage->setupFDR();
356      channelImage->setMinSize(par.getMinPix());
357      channelImage->lutz_detect();
358      num += channelImage->getNumObj();
359      for(int obj=0;obj<channelImage->getNumObj();obj++){
360        Detection *object = new Detection;
361        *object = channelImage->getObject(obj);
362        // Fix up z coordinates of each pixel to match original array
363        //   (x & y are fine)
364        for(int pix=0;pix<object->getSize();pix++){
365          object->setZ(pix, z);
366          object->setF(pix, originalArray[object->getX(pix)+
367                                          object->getY(pix)*dim[0]+
368                                          z*xySize]);
369          // NB: set F to the original value, not the recon value.
370        }
371        object->addOffsets(par);
372        object->calcParams();
373        mergeIntoList(*object,outputList,par);
374        delete object;
375      }
376      delete channelImage;
377   }
378
379  }
380
381  bar.rewind();
382  std::cout << "Found " << num << ".";
383  printSpace(22); 
384  std::cout << std::endl << std::flush;
385
386  delete [] isGood;
387  delete [] doChannel;
388
389  return outputList;
390}
Note: See TracBrowser for help on using the repository browser.