source: branches/pixel-map-branch/src/ATrous/ReconSearch.cc

Last change on this file was 252, checked in by Matthew Whiting, 17 years ago
  • Have put all classes in the files in src/PixelMap/ into a PixelInfo? namespace.
  • Added "using namespace PixelInfo?" to all necessary files.
  • Removed "friend class Detection" from Voxel and Object3D classes -- not necessary and complicated now by them being in the namespace
  • Various minor changes, including fixing up commentary.
File size: 9.5 KB
Line 
1#include <fstream>
2#include <iostream>
3#include <iomanip>
4#include <vector>
5#include <duchamp.hh>
6#include <PixelMap/Object3D.hh>
7#include <Cubes/cubes.hh>
8#include <Detection/detection.hh>
9#include <ATrous/atrous.hh>
10#include <Utils/utils.hh>
11#include <Utils/feedback.hh>
12#include <Utils/Statistics.hh>
13
14using namespace PixelInfo;
15
16void Cube::ReconSearch()
17{
18  /**
19   * The Cube is first reconstructed, using Cube::ReconCube().
20   * The statistics of the cube are calculated next.
21   * It is then searched, using searchReconArray.
22   * The resulting object list is stored in the Cube, and outputted
23   *  to the log file if the user so requests.
24   */
25 
26  this->ReconCube();
27
28  if(this->par.isVerbose()) std::cout << "  ";
29
30  this->setCubeStats();
31   
32  if(this->par.isVerbose()) std::cout << "  Searching... " << std::flush;
33 
34  this->objectList = searchReconArray(this->axisDim,this->array,
35                                      this->recon,this->par,this->Stats);
36
37  if(this->par.isVerbose()) std::cout << "  Updating detection map... "
38                                      << std::flush;
39  this->updateDetectMap();
40  if(this->par.isVerbose()) std::cout << "Done.\n";
41
42  if(this->par.getFlagLog()){
43    if(this->par.isVerbose())
44      std::cout << "  Logging intermediate detections... " << std::flush;
45    this->logDetectionList();
46    if(this->par.isVerbose()) std::cout << "Done.\n";
47  }
48
49}
50
51/////////////////////////////////////////////////////////////////////////////
52void Cube::ReconCube()
53{
54  /**
55   * A front-end to the various reconstruction functions, the choice of
56   *  which is determined by the use of the reconDim parameter.
57   * Differs from ReconSearch only in that no searching is done.
58   */
59  int dimRecon = this->par.getReconDim();
60  // Test whether we have eg. an image, but have requested a 3-d
61  //  reconstruction.
62  // If dimension of data array is less than dimRecon, change dimRecon
63  //  to the dimension of the array.
64  int numGoodDim = 0;
65  for(int i=0;i<this->numDim;i++) if(this->axisDim[i]>1) numGoodDim++;
66  if(numGoodDim<dimRecon) dimRecon = numGoodDim;
67  this->par.setReconDim(dimRecon);
68
69  switch(dimRecon)
70    {
71    case 1: this->ReconCube1D(); break;
72    case 2: this->ReconCube2D(); break;
73    case 3: this->ReconCube3D(); break;
74    default:
75      if(dimRecon<=0){
76        std::stringstream errmsg;
77        errmsg << "reconDim (" << dimRecon
78               << ") is less than 1. Performing 1-D reconstruction.\n";
79        duchampWarning("ReconCube", errmsg.str());
80        this->par.setReconDim(1);
81        this->ReconCube1D();
82      }
83      else if(dimRecon>3){
84        //this probably won't happen with new code above, but just in case...
85        std::stringstream errmsg;
86        errmsg << "reconDim (" << dimRecon
87               << ") is more than 3. Performing 3-D reconstruction.\n";
88        duchampWarning("ReconCube", errmsg.str());
89        this->par.setReconDim(3);
90        this->ReconCube3D();
91      }
92      break;
93    }
94}
95
96/////////////////////////////////////////////////////////////////////////////
97void Cube::ReconCube1D()
98{
99  /**
100   * This reconstructs a cube by performing a 1D a trous reconstruction
101   *  in the spectrum of each spatial pixel.
102   */
103  long xySize = this->axisDim[0] * this->axisDim[1];
104
105  long zdim = this->axisDim[2];
106
107  ProgressBar bar;
108  if(!this->reconExists){
109    std::cout<<"  Reconstructing... ";
110    if(par.isVerbose()) bar.init(xySize);
111    for(int npix=0; npix<xySize; npix++){
112
113      if( par.isVerbose() ) bar.update(npix+1);
114
115      float *spec = new float[zdim];
116      float *newSpec = new float[zdim];
117      for(int z=0;z<zdim;z++) spec[z] = this->array[z*xySize + npix];
118      bool verboseFlag = this->par.isVerbose();
119      this->par.setVerbosity(false);
120      atrous1DReconstruct(this->axisDim[2],spec,newSpec,this->par);
121      this->par.setVerbosity(verboseFlag);
122      for(int z=0;z<zdim;z++) this->recon[z*xySize+npix] = newSpec[z];
123      delete [] spec;
124      delete [] newSpec;
125    }
126    this->reconExists = true;
127    bar.fillSpace(" All Done.");
128    printSpace(22);
129    std::cout << "\n";
130  }
131
132}
133
134/////////////////////////////////////////////////////////////////////////////
135void Cube::ReconCube2D()
136{
137  /**
138   * This reconstructs a cube by performing a 2D a trous reconstruction
139   *  in each spatial image (ie. each channel map) of the cube.
140   */
141  long xySize = this->axisDim[0] * this->axisDim[1];
142  ProgressBar bar;
143
144  if(!this->reconExists){
145    std::cout<<"  Reconstructing... ";
146    if(par.isVerbose()) bar.init(this->axisDim[2]);
147    for(int z=0;z<this->axisDim[2];z++){
148
149      if( par.isVerbose() ) bar.update((z+1));
150
151      if(!this->par.isInMW(z)){
152        float *im = new float[xySize];
153        float *newIm = new float[xySize];
154        for(int npix=0; npix<xySize; npix++)
155          im[npix] = this->array[z*xySize+npix];
156        bool verboseFlag = this->par.isVerbose();
157        this->par.setVerbosity(false);
158        atrous2DReconstruct(this->axisDim[0],this->axisDim[1],
159                            im,newIm,this->par);
160        this->par.setVerbosity(verboseFlag);
161        for(int npix=0; npix<xySize; npix++)
162          this->recon[z*xySize+npix] = newIm[npix];
163        delete [] im;
164        delete [] newIm;
165      }
166      else {
167        for(int i=z*xySize; i<(z+1)*xySize; i++)
168          this->recon[i] = this->array[i];
169      }
170    }
171    this->reconExists = true;
172    bar.fillSpace(" All Done.");
173    printSpace(22);
174    std::cout << "\n";
175  }
176}
177
178/////////////////////////////////////////////////////////////////////////////
179void Cube::ReconCube3D()
180{
181  /**
182   * This performs a full 3D a trous reconstruction of the cube
183   */
184  if(this->axisDim[2]==1) this->ReconCube2D();
185  else {
186
187    if(!this->reconExists){
188      std::cout<<"  Reconstructing... "<<std::flush;
189      atrous3DReconstruct(this->axisDim[0],this->axisDim[1],this->axisDim[2],
190                          this->array,this->recon,this->par);
191      this->reconExists = true;
192      std::cout << "  All Done.";
193      printSpace(22);
194      std::cout << "\n";
195    }
196
197  }
198}
199
200/////////////////////////////////////////////////////////////////////////////
201std::vector <Detection> searchReconArray(long *dim, float *originalArray,
202                                         float *reconArray, Param &par,
203                                         StatsContainer<float> &stats)
204{
205  /**
206   *  This searches for objects in a cube that has been reconstructed.
207   *
208   *  The search is conducted first in each spatial pixel (xdim*ydim 1D
209   *   searches), then in each channel image (zdim 2D searches).
210   *  The searches are done on the reconstructed array, although the detected
211   *   objects have fluxes drawn from the corresponding pixels of the original
212   *   array.
213   *
214   *  \param dim Array of dimension sizes
215   *  \param originalArray Original, un-reconstructed image array.
216   *  \param reconArray Reconstructed image array
217   *  \param par The Param set.
218   *  \param stats The StatsContainer that defines what a detection is.
219   *
220   *  \return A vector of Detections resulting from the search.
221   */
222  std::vector <Detection> outputList;
223  long zdim = dim[2];
224  long xySize = dim[0] * dim[1];
225  int num=0;
226  ProgressBar bar;
227
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    bool *doPixel = new bool[xySize];
236    // doPixel is a bool array to say whether to look in a given spectrum
237    for(int npix=0; npix<xySize; npix++){
238      doPixel[npix] = false;
239      for(int z=0;z<zdim;z++) {
240        doPixel[npix] = doPixel[npix] ||
241          (!par.isBlank(originalArray[npix]) && !par.isInMW(z));
242      }
243      // doPixel[i] is false only when there are no good pixels in spectrum
244      //  of pixel #i.
245    }
246
247    long *specdim = new long[2];
248    specdim[0] = zdim; specdim[1]=1;
249    Image *spectrum = new Image(specdim);
250    delete [] specdim;
251    spectrum->saveParam(par);
252    spectrum->saveStats(stats);
253    spectrum->setMinSize(par.getMinChannels());
254    spectrum->pars().setBeamSize(2.);
255    // beam size: for spectrum, only neighbouring channels correlated
256
257    for(int y=0; y<dim[1]; y++){
258      for(int x=0; x<dim[0]; x++){
259
260        int npix = y*dim[0] + x;
261        if( par.isVerbose() ) bar.update(npix+1);
262
263        if(doPixel[npix]){
264
265          spectrum->extractSpectrum(reconArray,dim,npix);
266          spectrum->removeMW(); // only works if flagMW is true
267          std::vector<Scan> objlist = spectrum->spectrumDetect();
268          num += objlist.size();
269          for(int obj=0;obj<objlist.size();obj++){
270            Detection newObject;
271            // Fix up coordinates of each pixel to match original array
272            for(int z=objlist[obj].getX();z<=objlist[obj].getXmax();z++) {
273              newObject.pixels().addPixel(x,y,z);
274            }
275            newObject.setOffsets(par);
276            mergeIntoList(newObject,outputList,par);
277          }
278        }
279
280      }
281    }
282
283    delete spectrum;
284    delete [] doPixel;
285
286    if(par.isVerbose()) {
287      bar.fillSpace("Found ");
288      std::cout << num <<";" << std::flush;
289    }
290  }
291
292  // Second search --  in each channel
293  if(par.isVerbose()){
294    std::cout << "  2D: ";
295    bar.init(zdim);
296  }
297
298  num = 0;
299
300  long *imdim = new long[2];
301  imdim[0] = dim[0]; imdim[1] = dim[1];
302  Image *channelImage = new Image(imdim);
303  delete [] imdim;
304  channelImage->saveParam(par);
305  channelImage->saveStats(stats);
306  channelImage->setMinSize(par.getMinPix());
307
308  for(int z=0; z<zdim; z++){  // loop over all channels
309
310    if( par.isVerbose() ) bar.update(z+1);
311
312    if(!par.isInMW(z)){
313      // purpose of this is to ignore the Milky Way channels
314      //  if we are flagging them
315
316      channelImage->extractImage(reconArray,dim,z);
317      std::vector<Object2D> objlist = channelImage->lutz_detect();
318      num += objlist.size();
319      for(int obj=0;obj<objlist.size();obj++){
320        Detection newObject;
321        newObject.pixels().addChannel(z,objlist[obj]);
322        newObject.setOffsets(par);
323        mergeIntoList(newObject,outputList,par);
324      }
325    }
326   
327  }
328
329  delete channelImage;
330
331  if(par.isVerbose()){
332    bar.fillSpace("Found ");
333    std::cout << num << ".\n";
334  }
335
336
337  return outputList;
338}
Note: See TracBrowser for help on using the repository browser.