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

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

Summary:

  • Fixed the scale bar plotting for the spectral output, so that it can deal properly with very fine angular scales.
    • Improved the loop in Cube::drawScale
    • Included code in angularSeparation to deal with finely-separated positions.
  • Moved the ProgressBar? class to a new header file Utils/feedback.hh from duchamp.hh
    • Updated #include statements in many files
  • Fixed allocation bug in param copy constructor (related to offsets array).
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.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.