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

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

A few new things:

  • Made a mycpgplot.hh file, to keep PGPlot-related constants (enum types)

in a standard namespace (so one can do cpgsci(RED) rather than cpgsci(2)...).
Incorporated this into all code that uses pgplot.

  • Improved the outputting of the number of detected objects in the search

functions. Now shows how many have been detected, before they are merged
into the list.

  • Fixed a bug in columns.cc that was incorrectly updating the precision for

negative velocities.

  • Additional text in the Guide, and general clean up of code.
File size: 12.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()) std::cout << "|                    |" << std::flush;
79    for(int npix=0; npix<xySize; npix++){
80      if( par.isVerbose() && ((100*(npix+1)/xySize)%5 == 0) ){
81        std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b|";
82        for(int i=0;i<(100*(npix+1)/xySize)/5;i++) std::cout << "#";
83        for(int i=(100*(npix+1)/xySize)/5;i<20;i++) std::cout << " ";
84        std::cout << "|" << std::flush;
85      }
86      float *spec = new float[zdim];
87      float *newSpec = new float[zdim];
88      for(int z=0;z<zdim;z++) spec[z] = this->array[z*xySize + npix];
89      bool verboseFlag = this->par.isVerbose();
90      this->par.setVerbosity(false);
91      atrous1DReconstruct(this->axisDim[2],spec,newSpec,this->par);
92      this->par.setVerbosity(verboseFlag);
93      for(int z=0;z<zdim;z++) this->recon[z*xySize+npix] = newSpec[z];
94      delete spec;
95      delete newSpec;
96    }
97    this->reconExists = true;
98    std::cout<<"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
99             <<"  All Done.                      \n"
100             <<"  Searching... "<<std::flush;
101  }
102   
103  this->objectList = searchReconArray(this->axisDim,this->array,
104                                      this->recon,this->par);
105
106  this->updateDetectMap();
107  if(this->par.getFlagLog()) this->logDetectionList();
108
109}
110
111/////////////////////////////////////////////////////////////////////////////
112void Cube::ReconSearch2D()
113{
114  /**
115   * Cube::ReconSearch2D()
116   *   This reconstructs a cube by performing a 2D a trous reconstruction
117   *   in each spatial image (ie. each channel map) of the cube.
118   *   It then searches the cube using searchReconArray (below).
119   *
120   *   The resulting object list is stored in the Cube.
121   */
122  long xySize = this->axisDim[0] * this->axisDim[1];
123
124  if(!this->reconExists){
125    // RECONSTRUCT THE CUBE BY 2D ATROUS TRANSFORM IN EACH CHANNEL 
126    std::cout<<"  Reconstructing... ";
127    if(par.isVerbose()) std::cout << "|                    |" << std::flush;
128    for(int z=0;z<this->axisDim[2];z++){
129      if( par.isVerbose() && ((100*(z+1)/this->axisDim[2])%5 == 0) ){
130        std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b|";
131        for(int i=0;i<(100*(z+1)/this->axisDim[2])/5;i++) std::cout << "#";
132        for(int i=(100*(z+1)/this->axisDim[2])/5;i<20;i++) std::cout << " ";
133        std::cout << "|" << std::flush;
134      }
135      if(!this->par.isInMW(z)){
136        float *im = new float[xySize];
137        float *newIm = new float[xySize];
138        for(int npix=0; npix<xySize; npix++)
139          im[npix] = this->array[z*xySize+npix];
140        bool verboseFlag = this->par.isVerbose();
141        this->par.setVerbosity(false);
142        atrous2DReconstruct(this->axisDim[0],this->axisDim[1],
143                            im,newIm,this->par);
144        this->par.setVerbosity(verboseFlag);
145        for(int npix=0; npix<xySize; npix++)
146          this->recon[z*xySize+npix] = newIm[npix];
147        delete im;
148        delete newIm;
149      }
150      else {
151        for(int i=z*xySize; i<(z+1)*xySize; i++)
152          this->recon[i] = this->array[i];
153      }
154    }
155    this->reconExists = true;
156    std::cout<<"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
157             <<"  All Done.                      \n"
158             <<"Searching... "<<std::flush;
159
160  }
161
162  this->objectList = searchReconArray(this->axisDim,this->array,
163                                      this->recon,this->par);
164 
165  this->updateDetectMap();
166  if(this->par.getFlagLog()) this->logDetectionList();
167
168}
169
170/////////////////////////////////////////////////////////////////////////////
171void Cube::ReconSearch3D()
172{
173  /**
174   * Cube::ReconSearch3D()
175   *   This performs a full 3D a trous reconstruction of the cube
176   *   It then searches the cube using searchReconArray (below).
177   *
178   *   The resulting object list is stored in the Cube.
179   */
180  if(this->axisDim[2]==1) this->ReconSearch2D();
181  else {
182
183    if(!this->reconExists){
184      std::cout<<"  Reconstructing... "<<std::flush;
185      atrous3DReconstruct(this->axisDim[0],this->axisDim[1],this->axisDim[2],
186                          this->array,this->recon,this->par);
187      this->reconExists = true;
188      std::cout << "All Done.                      \n  Searching... "
189                << std::flush;
190    }
191
192    this->objectList = searchReconArray(this->axisDim,this->array,
193                                        this->recon,this->par);
194
195    this->updateDetectMap();
196    if(this->par.getFlagLog()) this->logDetectionList();
197
198  }
199
200}
201
202
203/////////////////////////////////////////////////////////////////////////////
204vector <Detection> searchReconArray(long *dim, float *originalArray,
205                                    float *reconArray, Param &par)
206{
207  /**
208   * searchReconArray(long *dim, float *originalArray,
209   *                  float *reconArray, Param &par)
210   *   This searches for objects in a cube that has been reconstructed.
211   *
212   *   Inputs:   - dimension array
213   *             - original, un-reconstructed image array
214   *             - reconstructed image array
215   *             - parameters
216   *
217   *   Searches first in each spatial pixel (1D search),
218   *   then in each channel image (2D search).
219   *
220   *   Returns: vector of Detections resulting from the search.
221   */
222  vector <Detection> outputList;
223  long zdim = dim[2];
224  long xySize = dim[0] * dim[1];
225  long fullSize = zdim * xySize;
226  int num=0, goodSize;
227
228  float blankPixValue = par.getBlankPixVal();
229  bool *isGood = new bool[fullSize];
230  for(int pos=0;pos<fullSize;pos++){
231    isGood[pos] = !par.isBlank(originalArray[pos]) && !par.isInMW(pos/xySize);
232  }
233  bool *doChannel = new bool[xySize];
234  goodSize=0;
235  for(int npix=0; npix<xySize; npix++){
236    for(int z=0;z<zdim;z++) if(isGood[z*xySize+npix]) goodSize++;
237    if(goodSize==0) doChannel[npix] = false;
238    else doChannel[npix] = true;
239  }
240 
241  float dud;
242
243  // First search --  in each spectrum.
244  if(zdim > 1){
245    if(par.isVerbose()) std::cout << "1D: |                    |"
246                                  << std::flush;
247
248    for(int npix=0; npix<xySize; npix++){
249
250      if( par.isVerbose() && ((100*(npix+1)/xySize)%5 == 0) ){
251        std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b|";
252        for(int i=0;i<(100*(npix+1)/xySize)/5;i++) std::cout << "#";
253        for(int i=(100*(npix+1)/xySize)/5;i<20;i++) std::cout << " ";
254        std::cout << "|" << std::flush;
255      }
256
257      if(doChannel[npix]){
258       
259        // First, get stats
260        float *spec = new float[zdim];
261        float specMedian,specSigma;
262        goodSize=0;
263        for(int z=0;z<zdim;z++) {
264          if(isGood[z*xySize+npix])
265            spec[goodSize++] = originalArray[z*xySize+npix];
266        }
267        specMedian = findMedian(spec,goodSize);
268        goodSize=0;
269        for(int z=0;z<zdim;z++) {
270          if(isGood[z*xySize+npix])
271            spec[goodSize++] = originalArray[z*xySize+npix] -
272              reconArray[z*xySize+npix];
273        }
274        specSigma = findMADFM(spec,goodSize) / correctionFactor;
275        delete [] spec;
276       
277        // Next, do source finding.
278        long *specdim = new long[2];
279        specdim[0] = zdim; specdim[1]=1;
280        Image *spectrum = new Image(specdim);
281        delete [] specdim;
282        spectrum->saveParam(par);
283        spectrum->pars().setBeamSize(2.);
284        // beam size: for spectrum, only neighbouring channels correlated
285        spectrum->extractSpectrum(reconArray,dim,npix);
286        spectrum->removeMW(); // only works if flagMW is true
287        spectrum->setStats(specMedian,specSigma,par.getCut());
288        if(par.getFlagFDR()) spectrum->setupFDR();
289        spectrum->setMinSize(par.getMinChannels());
290        spectrum->spectrumDetect();
291        num += spectrum->getNumObj();
292        for(int obj=0;obj<spectrum->getNumObj();obj++){
293          Detection *object = new Detection;
294          *object = spectrum->getObject(obj);
295          for(int pix=0;pix<object->getSize();pix++) {
296            // Fix up coordinates of each pixel to match original array
297            object->setZ(pix, object->getX(pix));
298            object->setX(pix, npix%dim[0]);
299            object->setY(pix, npix/dim[0]);
300            object->setF(pix, originalArray[object->getX(pix)+
301                                            object->getY(pix)*dim[0]+
302                                            object->getZ(pix)*xySize]);
303            // NB: set F to the original value, not the recon value.
304          }
305          object->addOffsets(par);
306          object->calcParams();
307          mergeIntoList(*object,outputList,par);
308          delete object;
309        }
310        delete spectrum;
311      }
312    }
313
314    num = outputList.size();
315    if(par.isVerbose())
316      std::cout <<"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bFound "
317                << num <<"; " << std::flush;
318
319  }
320
321  // Second search --  in each channel
322  if(par.isVerbose()) std::cout << "2D: |                    |"
323                                << std::flush;
324
325  num = 0;
326
327  for(int z=0; z<zdim; z++){  // loop over all channels
328
329    if( par.isVerbose() && ((100*(z+1)/zdim)%5 == 0) ){
330      std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b|";
331      for(int i=0;i<(100*(z+1)/zdim)/5;i++)  std::cout << "#";
332      for(int i=(100*(z+1)/zdim)/5;i<20;i++) std::cout << " ";
333      std::cout << "|" << std::flush;
334    }
335
336    if(!par.isInMW(z)){
337      // purpose of this is to ignore the Milky Way channels
338      //  if we are flagging them
339
340      //  First, get stats
341      float *image = new float[xySize];
342      float imageMedian,imageSigma;
343      goodSize=0;
344      for(int npix=0; npix<xySize; npix++) {
345        if(isGood[z*xySize + npix])
346          image[goodSize++] = originalArray[z*xySize + npix];
347      }
348      imageMedian = findMedian(image,goodSize);
349      goodSize=0;
350      for(int npix=0; npix<xySize; npix++)
351        if(isGood[z*xySize+npix])
352          image[goodSize++]=originalArray[z*xySize+npix]-
353            reconArray[z*xySize+npix];
354      imageSigma = findMADFM(image,goodSize) / correctionFactor;
355      delete [] image;
356
357      // Next, do source finding.
358      long *imdim = new long[2];
359      imdim[0] = dim[0]; imdim[1] = dim[1];
360      Image *channelImage = new Image(imdim);
361      channelImage->saveParam(par);
362      delete [] imdim;
363      channelImage->extractImage(reconArray,dim,z);
364      channelImage->setStats(imageMedian,imageSigma,par.getCut());
365      if(par.getFlagFDR()) channelImage->setupFDR();
366      channelImage->setMinSize(par.getMinPix());
367      channelImage->lutz_detect();
368      num += channelImage->getNumObj();
369      for(int obj=0;obj<channelImage->getNumObj();obj++){
370        Detection *object = new Detection;
371        *object = channelImage->getObject(obj);
372        // Fix up z coordinates of each pixel to match original array
373        //   (x & y are fine)
374        for(int pix=0;pix<object->getSize();pix++){
375          object->setZ(pix, z);
376          object->setF(pix, originalArray[object->getX(pix)+
377                                          object->getY(pix)*dim[0]+
378                                          z*xySize]);
379          // NB: set F to the original value, not the recon value.
380        }
381        object->addOffsets(par);
382        object->calcParams();
383        mergeIntoList(*object,outputList,par);
384        delete object;
385      }
386      delete channelImage;
387   }
388
389  }
390
391
392  std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bFound "
393            << num
394            << ".                                           " 
395            << std::endl << std::flush;
396
397  delete [] isGood;
398  delete [] doChannel;
399
400  return outputList;
401}
Note: See TracBrowser for help on using the repository browser.