source: tags/release-1.0.7/src/ATrous/ReconSearch.cc

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

Slight change to use of ProgressBar?.

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