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

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