source: tags/release-1.0.6/src/ATrous/ReconSearch.cc @ 1391

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

A large commit based around a few changes:

  • Implemented the new SNRpeak column, defining it in columns.cc and printing it out in outputDetection.cc.
  • Corrected a bug in the subsection parsing that miscalculated the pixel offset when "*" was given as an axis range.
  • setupFDR now calculates the flux threshold so this can be reported.
  • The object flags now distinguish between spatial edge and spectral edge locations.
  • Other minor changes for clarity's sake.
File size: 9.5 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,newSpec;
111    }
112    this->reconExists = true;
113    bar.rewind();
114    std::cout << "  All Done.";
115    printSpace(22);
116    std::cout << "\n";
117  }
118
119}
120
121/////////////////////////////////////////////////////////////////////////////
122void Cube::ReconCube2D()
123{
124  /**
125   * Cube::ReconCube2D()
126   *   This reconstructs a cube by performing a 2D a trous reconstruction
127   *   in each spatial image (ie. each channel map) of the cube.
128   */
129  long xySize = this->axisDim[0] * this->axisDim[1];
130  ProgressBar bar;
131
132  if(!this->reconExists){
133    std::cout<<"  Reconstructing... ";
134    if(par.isVerbose()) bar.init(this->axisDim[2]);
135    for(int z=0;z<this->axisDim[2];z++){
136
137      if( par.isVerbose() ) bar.update((z+1));
138
139      if(!this->par.isInMW(z)){
140        float *im = new float[xySize];
141        float *newIm = new float[xySize];
142        for(int npix=0; npix<xySize; npix++)
143          im[npix] = this->array[z*xySize+npix];
144        bool verboseFlag = this->par.isVerbose();
145        this->par.setVerbosity(false);
146        atrous2DReconstruct(this->axisDim[0],this->axisDim[1],
147                            im,newIm,this->par);
148        this->par.setVerbosity(verboseFlag);
149        for(int npix=0; npix<xySize; npix++)
150          this->recon[z*xySize+npix] = newIm[npix];
151        delete [] im, newIm;
152      }
153      else {
154        for(int i=z*xySize; i<(z+1)*xySize; i++)
155          this->recon[i] = this->array[i];
156      }
157    }
158    this->reconExists = true;
159    bar.rewind();
160    std::cout << "  All Done.";
161    printSpace(22);
162    std::cout << "\n";
163  }
164}
165
166/////////////////////////////////////////////////////////////////////////////
167void Cube::ReconCube3D()
168{
169  /**
170   * Cube::ReconCube3D()
171   *   This performs a full 3D a trous reconstruction of the cube
172   */
173  if(this->axisDim[2]==1) this->ReconCube2D();
174  else {
175
176    if(!this->reconExists){
177      std::cout<<"  Reconstructing... "<<std::flush;
178      atrous3DReconstruct(this->axisDim[0],this->axisDim[1],this->axisDim[2],
179                          this->array,this->recon,this->par);
180      this->reconExists = true;
181      std::cout << "  All Done.";
182      printSpace(22);
183      std::cout << "\n";
184    }
185
186  }
187}
188
189/////////////////////////////////////////////////////////////////////////////
190vector <Detection> searchReconArray(long *dim, float *originalArray,
191                                    float *reconArray, Param &par,
192                                    StatsContainer<float> &stats)
193{
194  /**
195   * searchReconArray(long *dim, float *originalArray,
196   *                  float *reconArray, Param &par)
197   *   This searches for objects in a cube that has been reconstructed.
198   *
199   *   Inputs:   - dimension array
200   *             - original, un-reconstructed image array
201   *             - reconstructed image array
202   *             - parameters
203   *
204   *   Searches first in each spatial pixel (1D search),
205   *   then in each channel image (2D search).
206   *
207   *   Returns: vector of Detections resulting from the search.
208   */
209  vector <Detection> outputList;
210  long zdim = dim[2];
211  long xySize = dim[0] * dim[1];
212  int num=0;
213
214  bool *doPixel = new bool[xySize];
215  // doPixel is a bool array to say whether to look in a given spectrum
216  for(int npix=0; npix<xySize; npix++){
217    doPixel[npix] = false;
218    for(int z=0;z<zdim;z++) {
219      doPixel[npix] = doPixel[npix] ||
220        (!par.isBlank(originalArray[npix]) && !par.isInMW(z));
221    }
222    // doPixel[i] is false only when there are no good pixels in spectrum
223    //  of pixel #i.
224  }
225 
226  ProgressBar bar;
227  // First search --  in each spectrum.
228  if(zdim > 1){
229    if(par.isVerbose()){
230      std::cout << "1D: ";
231      bar.init(xySize);
232    }
233
234    for(int npix=0; npix<xySize; npix++){
235
236      if( par.isVerbose() ) bar.update(npix+1);
237
238      if(doPixel[npix]){
239
240        long *specdim = new long[2];
241        specdim[0] = zdim; specdim[1]=1;
242        Image *spectrum = new Image(specdim);
243        delete [] specdim;
244        spectrum->saveParam(par);
245        spectrum->saveStats(stats);
246        // beam size: for spectrum, only neighbouring channels correlated
247        spectrum->extractSpectrum(reconArray,dim,npix);
248        spectrum->setMinSize(par.getMinChannels());
249        spectrum->removeMW(); // only works if flagMW is true
250        spectrum->spectrumDetect();
251        num += spectrum->getNumObj();
252        for(int obj=0;obj<spectrum->getNumObj();obj++){
253          Detection *object = new Detection;
254          *object = spectrum->getObject(obj);
255          for(int pix=0;pix<object->getSize();pix++) {
256            // Fix up coordinates of each pixel to match original array
257            object->setZ(pix, object->getX(pix));
258            object->setX(pix, npix%dim[0]);
259            object->setY(pix, npix/dim[0]);
260            object->setF(pix, originalArray[object->getX(pix)+
261                                            object->getY(pix)*dim[0]+
262                                            object->getZ(pix)*xySize]);
263            // NB: set F to the original value, not the recon value.
264          }
265          object->addOffsets(par);
266          object->calcParams();
267          mergeIntoList(*object,outputList,par);
268          delete object;
269        }
270        delete spectrum;
271      }
272    }
273
274    num = outputList.size();
275    if(par.isVerbose()) {
276      bar.rewind();
277      std::cout <<"Found " << num <<"; " << std::flush;
278    }
279  }
280
281  // Second search --  in each channel
282  if(par.isVerbose()){
283    std::cout << "2D: ";
284    bar.init(zdim);
285  }
286
287  num = 0;
288
289  for(int z=0; z<zdim; z++){  // loop over all channels
290
291    if( par.isVerbose() ) bar.update(z+1);
292
293    if(!par.isInMW(z)){
294      // purpose of this is to ignore the Milky Way channels
295      //  if we are flagging them
296
297      long *imdim = new long[2];
298      imdim[0] = dim[0]; imdim[1] = dim[1];
299      Image *channelImage = new Image(imdim);
300      channelImage->saveParam(par);
301      channelImage->saveStats(stats);
302      delete [] imdim;
303      channelImage->extractImage(reconArray,dim,z);
304      channelImage->setMinSize(par.getMinPix());
305      channelImage->lutz_detect();
306      num += channelImage->getNumObj();
307      for(int obj=0;obj<channelImage->getNumObj();obj++){
308        Detection *object = new Detection;
309        *object = channelImage->getObject(obj);
310        // Fix up z coordinates of each pixel to match original array
311        //   (x & y are fine)
312        for(int pix=0;pix<object->getSize();pix++){
313          object->setZ(pix, z);
314          object->setF(pix, originalArray[object->getX(pix)+
315                                          object->getY(pix)*dim[0]+
316                                          z*xySize]);
317          // NB: set F to the original value, not the recon value.
318        }
319        object->addOffsets(par);
320        object->calcParams();
321        mergeIntoList(*object,outputList,par);
322        delete object;
323      }
324      delete channelImage;
325   }
326
327  }
328
329  bar.rewind();
330  std::cout << "Found " << num << ".";
331  printSpace(22); 
332  std::cout << std::endl << std::flush;
333
334  delete [] doPixel;
335
336  return outputList;
337}
Note: See TracBrowser for help on using the repository browser.