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

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

Improved the setCubeStats function and changed the sorting function over to the STL sort and stable_sort function. Summary:

  • Utils/getStats.cc : changed calls to sort to std::sort
  • Utils/utils.hh : made swap function an inline one.
  • Utils/zscale.cc : changed calls to sort to std::sort
  • ATrous/ReconSearch.cc : minor change from setCubeStats testing
  • Cubes/cubes.cc : Some tweaking to improve performance, and changing calls to sort to std::sort.
  • Detection/sorting.cc : Define a new class "Pair" to sort pairs of arrays in the same sense -- removes need for second sort function in sort.cc. Make use of stable_sort to preserve order of matching elements.
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//this->setCubeStatsOld();
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.rewind();
116    std::cout << "  All Done.";
117    printSpace(22);
118    std::cout << "\n";
119  }
120
121}
122
123/////////////////////////////////////////////////////////////////////////////
124void Cube::ReconCube2D()
125{
126  /**
127   * Cube::ReconCube2D()
128   *   This reconstructs a cube by performing a 2D a trous reconstruction
129   *   in each spatial image (ie. each channel map) of the cube.
130   */
131  long xySize = this->axisDim[0] * this->axisDim[1];
132  ProgressBar bar;
133
134  if(!this->reconExists){
135    std::cout<<"  Reconstructing... ";
136    if(par.isVerbose()) bar.init(this->axisDim[2]);
137    for(int z=0;z<this->axisDim[2];z++){
138
139      if( par.isVerbose() ) bar.update((z+1));
140
141      if(!this->par.isInMW(z)){
142        float *im = new float[xySize];
143        float *newIm = new float[xySize];
144        for(int npix=0; npix<xySize; npix++)
145          im[npix] = this->array[z*xySize+npix];
146        bool verboseFlag = this->par.isVerbose();
147        this->par.setVerbosity(false);
148        atrous2DReconstruct(this->axisDim[0],this->axisDim[1],
149                            im,newIm,this->par);
150        this->par.setVerbosity(verboseFlag);
151        for(int npix=0; npix<xySize; npix++)
152          this->recon[z*xySize+npix] = newIm[npix];
153        delete [] im;
154        delete [] newIm;
155      }
156      else {
157        for(int i=z*xySize; i<(z+1)*xySize; i++)
158          this->recon[i] = this->array[i];
159      }
160    }
161    this->reconExists = true;
162    bar.rewind();
163    std::cout << "  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.rewind();
280      std::cout <<"Found " << 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  bar.rewind();
333  std::cout << "Found " << num << ".";
334  printSpace(22); 
335  std::cout << std::endl << std::flush;
336
337  delete [] doPixel;
338
339  return outputList;
340}
Note: See TracBrowser for help on using the repository browser.