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
RevLine 
[3]1#include <fstream>
2#include <iostream>
3#include <iomanip>
4#include <vector>
[120]5#include <duchamp.hh>
[243]6#include <PixelMap/Object3D.hh>
[3]7#include <Cubes/cubes.hh>
[144]8#include <Detection/detection.hh>
[3]9#include <ATrous/atrous.hh>
10#include <Utils/utils.hh>
[213]11#include <Utils/feedback.hh>
[192]12#include <Utils/Statistics.hh>
[3]13
[252]14using namespace PixelInfo;
15
[103]16void Cube::ReconSearch()
17{
18  /**
[220]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.
[103]24   */
[188]25 
26  this->ReconCube();
27
[219]28  if(this->par.isVerbose()) std::cout << "  ";
29
[212]30  this->setCubeStats();
[189]31   
[219]32  if(this->par.isVerbose()) std::cout << "  Searching... " << std::flush;
[188]33 
34  this->objectList = searchReconArray(this->axisDim,this->array,
[190]35                                      this->recon,this->par,this->Stats);
[188]36
[248]37  if(this->par.isVerbose()) std::cout << "  Updating detection map... "
38                                      << std::flush;
[188]39  this->updateDetectMap();
[248]40  if(this->par.isVerbose()) std::cout << "Done.\n";
[188]41
[248]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
[188]49}
50
51/////////////////////////////////////////////////////////////////////////////
52void Cube::ReconCube()
53{
54  /**
[220]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.
[188]58   */
[120]59  int dimRecon = this->par.getReconDim();
[146]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.
[120]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)
[103]70    {
[188]71    case 1: this->ReconCube1D(); break;
72    case 2: this->ReconCube2D(); break;
73    case 3: this->ReconCube3D(); break;
[103]74    default:
[120]75      if(dimRecon<=0){
76        std::stringstream errmsg;
77        errmsg << "reconDim (" << dimRecon
78               << ") is less than 1. Performing 1-D reconstruction.\n";
[188]79        duchampWarning("ReconCube", errmsg.str());
[103]80        this->par.setReconDim(1);
[188]81        this->ReconCube1D();
[103]82      }
[120]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";
[188]88        duchampWarning("ReconCube", errmsg.str());
[103]89        this->par.setReconDim(3);
[188]90        this->ReconCube3D();
[103]91      }
92      break;
93    }
94}
95
[146]96/////////////////////////////////////////////////////////////////////////////
[188]97void Cube::ReconCube1D()
[3]98{
[103]99  /**
[220]100   * This reconstructs a cube by performing a 1D a trous reconstruction
101   *  in the spectrum of each spatial pixel.
[103]102   */
103  long xySize = this->axisDim[0] * this->axisDim[1];
[188]104
[103]105  long zdim = this->axisDim[2];
[3]106
[187]107  ProgressBar bar;
[103]108  if(!this->reconExists){
109    std::cout<<"  Reconstructing... ";
[187]110    if(par.isVerbose()) bar.init(xySize);
[103]111    for(int npix=0; npix<xySize; npix++){
[175]112
[187]113      if( par.isVerbose() ) bar.update(npix+1);
[175]114
[103]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];
[205]123      delete [] spec;
124      delete [] newSpec;
[3]125    }
[103]126    this->reconExists = true;
[214]127    bar.fillSpace(" All Done.");
[175]128    printSpace(22);
[188]129    std::cout << "\n";
[3]130  }
[103]131
[3]132}
133
[146]134/////////////////////////////////////////////////////////////////////////////
[188]135void Cube::ReconCube2D()
[3]136{
[103]137  /**
[220]138   * This reconstructs a cube by performing a 2D a trous reconstruction
139   *  in each spatial image (ie. each channel map) of the cube.
[103]140   */
141  long xySize = this->axisDim[0] * this->axisDim[1];
[187]142  ProgressBar bar;
[3]143
[103]144  if(!this->reconExists){
145    std::cout<<"  Reconstructing... ";
[187]146    if(par.isVerbose()) bar.init(this->axisDim[2]);
[103]147    for(int z=0;z<this->axisDim[2];z++){
[175]148
[187]149      if( par.isVerbose() ) bar.update((z+1));
[175]150
[103]151      if(!this->par.isInMW(z)){
152        float *im = new float[xySize];
153        float *newIm = new float[xySize];
[146]154        for(int npix=0; npix<xySize; npix++)
155          im[npix] = this->array[z*xySize+npix];
[103]156        bool verboseFlag = this->par.isVerbose();
157        this->par.setVerbosity(false);
[146]158        atrous2DReconstruct(this->axisDim[0],this->axisDim[1],
159                            im,newIm,this->par);
[103]160        this->par.setVerbosity(verboseFlag);
[146]161        for(int npix=0; npix<xySize; npix++)
162          this->recon[z*xySize+npix] = newIm[npix];
[205]163        delete [] im;
164        delete [] newIm;
[3]165      }
[103]166      else {
[146]167        for(int i=z*xySize; i<(z+1)*xySize; i++)
168          this->recon[i] = this->array[i];
[103]169      }
[3]170    }
[103]171    this->reconExists = true;
[214]172    bar.fillSpace(" All Done.");
[175]173    printSpace(22);
[188]174    std::cout << "\n";
[3]175  }
176}
177
[146]178/////////////////////////////////////////////////////////////////////////////
[188]179void Cube::ReconCube3D()
[3]180{
[103]181  /**
[220]182   * This performs a full 3D a trous reconstruction of the cube
[103]183   */
[188]184  if(this->axisDim[2]==1) this->ReconCube2D();
[3]185  else {
186
[71]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;
[175]192      std::cout << "  All Done.";
193      printSpace(22);
[188]194      std::cout << "\n";
[71]195    }
196
[3]197  }
198}
199
[146]200/////////////////////////////////////////////////////////////////////////////
[232]201std::vector <Detection> searchReconArray(long *dim, float *originalArray,
202                                         float *reconArray, Param &par,
203                                         StatsContainer<float> &stats)
[3]204{
[103]205  /**
[220]206   *  This searches for objects in a cube that has been reconstructed.
[103]207   *
[220]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.
[103]213   *
[220]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.
[103]219   *
[220]220   *  \return A vector of Detections resulting from the search.
[103]221   */
[232]222  std::vector <Detection> outputList;
[103]223  long zdim = dim[2];
224  long xySize = dim[0] * dim[1];
[192]225  int num=0;
[251]226  ProgressBar bar;
[3]227
228  // First search --  in each spectrum.
229  if(zdim > 1){
[175]230    if(par.isVerbose()){
231      std::cout << "1D: ";
[187]232      bar.init(xySize);
[175]233    }
[3]234
[251]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
[243]247    long *specdim = new long[2];
248    specdim[0] = zdim; specdim[1]=1;
[251]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
[3]256
[243]257    for(int y=0; y<dim[1]; y++){
258      for(int x=0; x<dim[0]; x++){
[3]259
[243]260        int npix = y*dim[0] + x;
261        if( par.isVerbose() ) bar.update(npix+1);
[192]262
[243]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;
[103]271            // Fix up coordinates of each pixel to match original array
[243]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);
[103]277          }
[3]278        }
[251]279
[3]280      }
281    }
282
[251]283    delete spectrum;
284    delete [] doPixel;
285
[175]286    if(par.isVerbose()) {
[219]287      bar.fillSpace("Found ");
288      std::cout << num <<";" << std::flush;
[175]289    }
[86]290  }
[3]291
292  // Second search --  in each channel
[175]293  if(par.isVerbose()){
[219]294    std::cout << "  2D: ";
[187]295    bar.init(zdim);
[175]296  }
[71]297
[146]298  num = 0;
299
[251]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
[86]308  for(int z=0; z<zdim; z++){  // loop over all channels
[3]309
[187]310    if( par.isVerbose() ) bar.update(z+1);
[3]311
[146]312    if(!par.isInMW(z)){
313      // purpose of this is to ignore the Milky Way channels
314      //  if we are flagging them
315
[53]316      channelImage->extractImage(reconArray,dim,z);
[243]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);
[3]324      }
[251]325    }
326   
[3]327  }
328
[251]329  delete channelImage;
330
[219]331  if(par.isVerbose()){
332    bar.fillSpace("Found ");
333    std::cout << num << ".\n";
334  }
[86]335
[3]336
337  return outputList;
338}
Note: See TracBrowser for help on using the repository browser.