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

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

Introduced some simple inline functions to duchamp.hh to make the printing of progress bars simpler and of a more unified fashion.

File size: 11.5 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
11using std::setw;
12
13/////////////////////////////////////////////////////////////////////////////
14void Cube::ReconSearch()
15{
16  /**
17   * Cube::ReconSearch()
18   *   A front-end to the various ReconSearch functions, the choice of
19   *   which is determined by the use of the reconDim parameter.
20   */
21  int dimRecon = this->par.getReconDim();
22 
23  // Test whether we have eg. an image, but have requested a 3-d
24  //  reconstruction.
25  // If dimension of data array is less than dimRecon, change dimRecon
26  //  to the dimension of the array.
27  int numGoodDim = 0;
28  for(int i=0;i<this->numDim;i++) if(this->axisDim[i]>1) numGoodDim++;
29  if(numGoodDim<dimRecon) dimRecon = numGoodDim;
30  this->par.setReconDim(dimRecon);
31
32  switch(dimRecon)
33    {
34    case 1: this->ReconSearch1D(); break;
35    case 2: this->ReconSearch2D(); break;
36    case 3: this->ReconSearch3D(); break;
37    default:
38      if(dimRecon<=0){
39        std::stringstream errmsg;
40        errmsg << "reconDim (" << dimRecon
41               << ") is less than 1. Performing 1-D reconstruction.\n";
42        duchampWarning("ReconSearch", errmsg.str());
43        this->par.setReconDim(1);
44        this->ReconSearch1D();
45      }
46      else if(dimRecon>3){
47        //this probably won't happen with new code above, but just in case...
48        std::stringstream errmsg;
49        errmsg << "reconDim (" << dimRecon
50               << ") is more than 3. Performing 3-D reconstruction.\n";
51        duchampWarning("ReconSearch", errmsg.str());
52        this->par.setReconDim(3);
53        this->ReconSearch3D();
54      }
55      break;
56    }
57 
58}
59
60
61/////////////////////////////////////////////////////////////////////////////
62void Cube::ReconSearch1D()
63{
64  /**
65   * Cube::ReconSearch1D()
66   *   This reconstructs a cube by performing a 1D a trous reconstruction
67   *   in the spectrum of each spatial pixel.
68   *   It then searches the cube using searchReconArray (below).
69   *
70   *   The resulting object list is stored in the Cube.
71   */
72  long xySize = this->axisDim[0] * this->axisDim[1];
73  long zdim = this->axisDim[2];
74
75  // Reconstruct the cube by 1d atrous transform in each spatial pixel
76  if(!this->reconExists){
77    std::cout<<"  Reconstructing... ";
78    if(par.isVerbose()) initialiseMeter();
79    for(int npix=0; npix<xySize; npix++){
80
81      if( par.isVerbose() && ((100*(npix+1)/xySize)%5 == 0) )
82        updateMeter((100*(npix+1)/xySize)/5);
83
84      float *spec = new float[zdim];
85      float *newSpec = new float[zdim];
86      for(int z=0;z<zdim;z++) spec[z] = this->array[z*xySize + npix];
87      bool verboseFlag = this->par.isVerbose();
88      this->par.setVerbosity(false);
89      atrous1DReconstruct(this->axisDim[2],spec,newSpec,this->par);
90      this->par.setVerbosity(verboseFlag);
91      for(int z=0;z<zdim;z++) this->recon[z*xySize+npix] = newSpec[z];
92      delete spec;
93      delete newSpec;
94    }
95    this->reconExists = true;
96    printBackSpace(22);
97    std::cout << "  All Done.";
98    printSpace(22);
99    std::cout << "\n  Searching... "<<std::flush;
100  }
101   
102  this->objectList = searchReconArray(this->axisDim,this->array,
103                                      this->recon,this->par);
104
105  this->updateDetectMap();
106  if(this->par.getFlagLog()) this->logDetectionList();
107
108}
109
110/////////////////////////////////////////////////////////////////////////////
111void Cube::ReconSearch2D()
112{
113  /**
114   * Cube::ReconSearch2D()
115   *   This reconstructs a cube by performing a 2D a trous reconstruction
116   *   in each spatial image (ie. each channel map) of the cube.
117   *   It then searches the cube using searchReconArray (below).
118   *
119   *   The resulting object list is stored in the Cube.
120   */
121  long xySize = this->axisDim[0] * this->axisDim[1];
122
123  if(!this->reconExists){
124    // RECONSTRUCT THE CUBE BY 2D ATROUS TRANSFORM IN EACH CHANNEL 
125    std::cout<<"  Reconstructing... ";
126    if(par.isVerbose()) initialiseMeter();
127    for(int z=0;z<this->axisDim[2];z++){
128
129      if( par.isVerbose() && ((100*(z+1)/this->axisDim[2])%5 == 0) )
130        updateMeter((100*(z+1)/this->axisDim[2])/5);
131
132      if(!this->par.isInMW(z)){
133        float *im = new float[xySize];
134        float *newIm = new float[xySize];
135        for(int npix=0; npix<xySize; npix++)
136          im[npix] = this->array[z*xySize+npix];
137        bool verboseFlag = this->par.isVerbose();
138        this->par.setVerbosity(false);
139        atrous2DReconstruct(this->axisDim[0],this->axisDim[1],
140                            im,newIm,this->par);
141        this->par.setVerbosity(verboseFlag);
142        for(int npix=0; npix<xySize; npix++)
143          this->recon[z*xySize+npix] = newIm[npix];
144        delete im;
145        delete newIm;
146      }
147      else {
148        for(int i=z*xySize; i<(z+1)*xySize; i++)
149          this->recon[i] = this->array[i];
150      }
151    }
152    this->reconExists = true;
153    printBackSpace(22);
154    std::cout << "  All Done.";
155    printSpace(22);
156    std::cout << "\nSearching... "<<std::flush;
157
158  }
159
160  this->objectList = searchReconArray(this->axisDim,this->array,
161                                      this->recon,this->par);
162 
163  this->updateDetectMap();
164  if(this->par.getFlagLog()) this->logDetectionList();
165
166}
167
168/////////////////////////////////////////////////////////////////////////////
169void Cube::ReconSearch3D()
170{
171  /**
172   * Cube::ReconSearch3D()
173   *   This performs a full 3D a trous reconstruction of the cube
174   *   It then searches the cube using searchReconArray (below).
175   *
176   *   The resulting object list is stored in the Cube.
177   */
178  if(this->axisDim[2]==1) this->ReconSearch2D();
179  else {
180
181    if(!this->reconExists){
182      std::cout<<"  Reconstructing... "<<std::flush;
183      atrous3DReconstruct(this->axisDim[0],this->axisDim[1],this->axisDim[2],
184                          this->array,this->recon,this->par);
185      this->reconExists = true;
186      std::cout << "  All Done.";
187      printSpace(22);
188      std::cout << "\n  Searching... "<<std::flush;
189    }
190
191    this->objectList = searchReconArray(this->axisDim,this->array,
192                                        this->recon,this->par);
193
194    this->updateDetectMap();
195    if(this->par.getFlagLog()) this->logDetectionList();
196
197  }
198
199}
200
201
202/////////////////////////////////////////////////////////////////////////////
203vector <Detection> searchReconArray(long *dim, float *originalArray,
204                                    float *reconArray, Param &par)
205{
206  /**
207   * searchReconArray(long *dim, float *originalArray,
208   *                  float *reconArray, Param &par)
209   *   This searches for objects in a cube that has been reconstructed.
210   *
211   *   Inputs:   - dimension array
212   *             - original, un-reconstructed image array
213   *             - reconstructed image array
214   *             - parameters
215   *
216   *   Searches first in each spatial pixel (1D search),
217   *   then in each channel image (2D search).
218   *
219   *   Returns: vector of Detections resulting from the search.
220   */
221  vector <Detection> outputList;
222  long zdim = dim[2];
223  long xySize = dim[0] * dim[1];
224  long fullSize = zdim * xySize;
225  int num=0, goodSize;
226
227  bool *isGood = new bool[fullSize];
228  for(int pos=0;pos<fullSize;pos++){
229    isGood[pos] = ((!par.isBlank(originalArray[pos])) &&
230      (!par.isInMW(pos/xySize)));
231  }
232  bool *doChannel = new bool[xySize];
233  for(int npix=0; npix<xySize; npix++){
234    doChannel[npix] = false;
235    for(int z=0;z<zdim;z++)
236      doChannel[npix] = doChannel[npix] || isGood[z*xySize+npix];
237  }
238 
239  float dud;
240
241  // First search --  in each spectrum.
242  if(zdim > 1){
243    if(par.isVerbose()){
244      std::cout << "1D: ";
245      initialiseMeter();
246    }
247
248    for(int npix=0; npix<xySize; npix++){
249
250      if( par.isVerbose() && ((100*(npix+1)/xySize)%5 == 0) )
251        updateMeter((100*(npix+1)/xySize)/5);
252
253      if(doChannel[npix]){
254       
255        // First, get stats
256        float *spec = new float[zdim];
257        float specMedian,specSigma;
258        goodSize=0;
259        for(int z=0;z<zdim;z++) {
260          if(isGood[z*xySize+npix])
261            spec[goodSize++] = originalArray[z*xySize+npix];
262        }
263        specMedian = findMedian(spec,goodSize);
264        goodSize=0;
265        for(int z=0;z<zdim;z++) {
266          if(isGood[z*xySize+npix])
267            spec[goodSize++] = originalArray[z*xySize+npix] -
268              reconArray[z*xySize+npix];
269        }
270        specSigma = findMADFM(spec,goodSize) / correctionFactor;
271        delete [] spec;
272       
273        // Next, do source finding.
274        long *specdim = new long[2];
275        specdim[0] = zdim; specdim[1]=1;
276        Image *spectrum = new Image(specdim);
277        delete [] specdim;
278        spectrum->saveParam(par);
279        spectrum->pars().setBeamSize(2.);
280        // beam size: for spectrum, only neighbouring channels correlated
281        spectrum->extractSpectrum(reconArray,dim,npix);
282        spectrum->removeMW(); // only works if flagMW is true
283        spectrum->setStats(specMedian,specSigma,par.getCut());
284        if(par.getFlagFDR()) spectrum->setupFDR();
285        spectrum->setMinSize(par.getMinChannels());
286        spectrum->spectrumDetect();
287        num += spectrum->getNumObj();
288        for(int obj=0;obj<spectrum->getNumObj();obj++){
289          Detection *object = new Detection;
290          *object = spectrum->getObject(obj);
291          for(int pix=0;pix<object->getSize();pix++) {
292            // Fix up coordinates of each pixel to match original array
293            object->setZ(pix, object->getX(pix));
294            object->setX(pix, npix%dim[0]);
295            object->setY(pix, npix/dim[0]);
296            object->setF(pix, originalArray[object->getX(pix)+
297                                            object->getY(pix)*dim[0]+
298                                            object->getZ(pix)*xySize]);
299            // NB: set F to the original value, not the recon value.
300          }
301          object->addOffsets(par);
302          object->calcParams();
303          mergeIntoList(*object,outputList,par);
304          delete object;
305        }
306        delete spectrum;
307      }
308    }
309
310    num = outputList.size();
311    if(par.isVerbose()) {
312      printBackSpace(22);
313      std::cout <<"Found " << num <<"; " << std::flush;
314    }
315  }
316
317  // Second search --  in each channel
318  if(par.isVerbose()){
319    std::cout << "2D: ";
320    initialiseMeter();
321  }
322
323  num = 0;
324
325  for(int z=0; z<zdim; z++){  // loop over all channels
326
327    if( par.isVerbose() && ((100*(z+1)/zdim)%5 == 0) )
328      updateMeter((100*(z+1)/zdim)/5);
329
330    if(!par.isInMW(z)){
331
332      // purpose of this is to ignore the Milky Way channels
333      //  if we are flagging them
334
335      //  First, get stats
336      float *image = new float[xySize];
337      float imageMedian,imageSigma;
338      goodSize=0;
339      for(int npix=0; npix<xySize; npix++) {
340        if(isGood[z*xySize + npix])
341          image[goodSize++] = originalArray[z*xySize + npix];
342      }
343      imageMedian = findMedian(image,goodSize);
344      goodSize=0;
345      for(int npix=0; npix<xySize; npix++)
346        if(isGood[z*xySize+npix])
347          image[goodSize++]=originalArray[z*xySize+npix]-
348            reconArray[z*xySize+npix];
349      imageSigma = findMADFM(image,goodSize) / correctionFactor;
350      delete [] image;
351
352      // Next, do source finding.
353      long *imdim = new long[2];
354      imdim[0] = dim[0]; imdim[1] = dim[1];
355      Image *channelImage = new Image(imdim);
356      channelImage->saveParam(par);
357      delete [] imdim;
358      channelImage->extractImage(reconArray,dim,z);
359      channelImage->setStats(imageMedian,imageSigma,par.getCut());
360      if(par.getFlagFDR()) channelImage->setupFDR();
361      channelImage->setMinSize(par.getMinPix());
362      channelImage->lutz_detect();
363      num += channelImage->getNumObj();
364      for(int obj=0;obj<channelImage->getNumObj();obj++){
365        Detection *object = new Detection;
366        *object = channelImage->getObject(obj);
367        // Fix up z coordinates of each pixel to match original array
368        //   (x & y are fine)
369        for(int pix=0;pix<object->getSize();pix++){
370          object->setZ(pix, z);
371          object->setF(pix, originalArray[object->getX(pix)+
372                                          object->getY(pix)*dim[0]+
373                                          z*xySize]);
374          // NB: set F to the original value, not the recon value.
375        }
376        object->addOffsets(par);
377        object->calcParams();
378        mergeIntoList(*object,outputList,par);
379        delete object;
380      }
381      delete channelImage;
382   }
383
384  }
385
386  printBackSpace(22);
387  std::cout << "Found " << num << ".";
388  printSpace(22); 
389  std::cout << std::endl << std::flush;
390
391  delete [] isGood;
392  delete [] doChannel;
393
394  return outputList;
395}
Note: See TracBrowser for help on using the repository browser.