source: tags/release-0.9/ATrous/ReconSearch.cc @ 813

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

Introduced a new parameter to the Image class : minSize, the minimum size
of a detection for it to be accepted.
Added code in the searching algorithms to distinguish between minPix and
minChannels for the 2D and 1D searches.
Set default value of minPix to 2.

File size: 11.1 KB
Line 
1#include <fstream>
2#include <iostream>
3#include <iomanip>
4#include <vector>
5#include <Cubes/cubes.hh>
6#include <ATrous/atrous.hh>
7#include <Utils/utils.hh>
8
9using std::setw;
10
11//////////////////////////////////////////////////////////////////////////////////////
12/**
13 * Cube::ReconSearch1D()
14 *   This reconstructs a cube by performing a 1D a trous reconstruction
15 *   in the spectrum of each spatial pixel.
16 *   It then searches the cube using reconSearch (below).
17 *
18 *   The resulting object list is stored in the Cube.
19 */
20void Cube::ReconSearch1D()
21{
22  long xySize = axisDim[0] * axisDim[1];
23  long zdim = axisDim[2];
24
25  // Reconstruct the cube by 1d atrous transform in each spatial pixel
26  std::cout<<"Reconstructing... ";
27  for(int npix=0; npix<xySize; npix++){
28    if((100*npix/xySize)%5==0)
29      std::cout<<setw(3)<<100*npix/xySize<<"% done"<<"\b\b\b\b\b\b\b\b\b"<<std::flush;
30    float *spec = new float[zdim];
31    float *newSpec = new float[zdim];
32    for(int z=0;z<zdim;z++){
33      int cubepos = z*xySize + npix;
34      spec[z] = this->array[cubepos];
35    }
36    atrous1DReconstruct(axisDim[2],spec,newSpec,this->par);
37    for(int z=0;z<zdim;z++){
38      int cubepos = z*xySize + npix;
39      this->recon[cubepos] = newSpec[z];
40    }
41    delete spec;
42    delete newSpec;
43  }
44  this->reconExists = true;
45  std::cout<<"All Done. Searching... ";
46   
47  this->objectList = reconSearch(this->axisDim,this->array,this->recon,this->par);
48  this->updateDetectMap();
49  if(this->par.getFlagLog()) this->logDetectionList();
50
51}
52
53//////////////////////////////////////////////////////////////////////////////////////
54/**
55 * Cube::ReconSearch2D()
56 *   This reconstructs a cube by performing a 2D a trous reconstruction
57 *   in each spatial image of the cube.
58 *   It then searches the cube using reconSearch (below).
59 *
60 *   The resulting object list is stored in the Cube.
61 */
62void Cube::ReconSearch2D()
63{
64  long xySize = axisDim[0] * axisDim[1];
65
66  // RECONSTRUCT THE CUBE BY 2D ATROUS TRANSFORM IN EACH CHANNEL 
67  bool *doChannel = new bool[axisDim[2]];
68  for(int z=0;z<axisDim[2];z++)
69    doChannel[z] = !( this->par.getFlagMW() && (z>=this->par.getMinMW()) && (z<=this->par.getMaxMW()) );
70  std::cout<<"Reconstructing... ";
71  for(int z=0;z<axisDim[2];z++){
72    if((100*z/axisDim[2])%5==0)
73      std::cout<<setw(3)<<100*z/axisDim[2]<<"% done"<<"\b\b\b\b\b\b\b\b\b"<<std::flush;
74    if(doChannel[z]){
75      float *im = new float[xySize];
76      float *newIm = new float[xySize];
77      for(int npix=0; npix<xySize; npix++){
78        int cubepos = z*xySize + npix;
79        im[npix] = this->array[cubepos];
80      }
81      atrous2DReconstruct(axisDim[0],axisDim[1],im,newIm,this->par);
82      for(int npix=0; npix<xySize; npix++){
83        int cubepos = z*xySize + npix;
84        this->recon[cubepos] = newIm[npix];
85      }
86      delete im;
87      delete newIm;
88    }
89    else
90      for(int i=0; i<xySize; i++) this->recon[z*xySize+i] = this->array[z*xySize+i];
91  }
92  this->reconExists = true;
93  std::cout<<"All Done.                      \nSearching... ";
94
95  this->objectList = reconSearch(this->axisDim,this->array,this->recon,this->par);
96 
97  this->updateDetectMap();
98  if(this->par.getFlagLog()) this->logDetectionList();
99
100  delete [] doChannel;
101
102}
103
104//////////////////////////////////////////////////////////////////////////////////////
105/**
106 * Cube::ReconSearch3D()
107 *   This reconstructs a cube by performing a full 3D a trous
108 *   reconstruction of the cube
109 *   It then searches the cube using reconSearch (below).
110 *
111 *   The resulting object list is stored in the Cube.
112 */
113void Cube::ReconSearch3D()
114{
115  if(this->axisDim[2]==1) this->ReconSearch2D();
116  else {
117
118    std::cout<<"  Reconstructing... "<<std::flush;
119    atrous3DReconstruct(this->axisDim[0],this->axisDim[1],this->axisDim[2],
120                        this->array,this->recon,this->par);
121    this->reconExists = true;
122    std::cout<<"All Done.                      \n  Searching... "<<std::flush;
123     
124    this->objectList = reconSearch(this->axisDim,this->array,this->recon,this->par);
125
126    this->updateDetectMap();
127    if(this->par.getFlagLog()) this->logDetectionList();
128
129  }
130
131}
132
133
134//////////////////////////////////////////////////////////////////////////////////////
135/**
136 * reconSearch(long *dim, float *originalArray, float *reconArray, Param &par)
137 *   This searches for objects in a cube that has been reconstructed.
138 *
139 *   Inputs:   - dimension array
140 *             - original, un-reconstructed image array
141 *             - reconstructed image array
142 *             - parameters
143 *
144 *   Searches first in each spatial pixel (1D search),
145 *   then in each channel image (2D search).
146 *
147 *   Returns: vector of Detections resulting from the search.
148 */
149vector <Detection> reconSearch(long *dim, float *originalArray, float *reconArray, Param &par)
150{
151  vector <Detection> outputList;
152  int zdim = dim[2];
153  int xySize = dim[0] * dim[1];
154  int fullSize = zdim * xySize;
155  int num, goodSize;
156
157  //  bool flagBlank=par.getFlagBlankPix();
158  float blankPixValue = par.getBlankPixVal();
159  bool *isGood = new bool[fullSize];
160  for(int pos=0;pos<fullSize;pos++)
161    isGood[pos] = !par.isBlank(originalArray[pos]);
162    //    isGood[pos] = (!flagBlank) || (originalArray[pos]!=blankPixValue);
163 
164  float dud;
165
166  // First search --  in each spectrum.
167  // First, get stats
168  if(zdim > 1){
169    std::cout << "1D: |                    |" << std::flush;
170//     if(par.isVerbose()) std::cout << "Done  0%" << "\b\b\b\b\b\b\b\b" << std::flush;
171
172    float *specMedian = new float[xySize];
173    float *specSigma = new float[xySize];
174    float *spec = new float[zdim];
175   
176    for(int npix=0; npix<xySize; npix++){
177      goodSize=0;
178      for(int z=0;z<zdim;z++)
179        if(isGood[z*xySize+npix]) spec[goodSize++] = originalArray[z*xySize+npix];
180      if(goodSize>0) findMedianStats(spec,goodSize,specMedian[npix],dud);
181      else specMedian[npix] = blankPixValue;
182      goodSize=0;
183      for(int z=0;z<zdim;z++)
184        if(isGood[z*xySize+npix])
185          spec[goodSize++] = originalArray[z*xySize+npix]-reconArray[z*xySize+npix];
186      if(goodSize>0) findNormalStats(spec,goodSize,dud,specSigma[npix]);
187      else specSigma[npix] = 1.;
188    }
189
190    // Next, do source finding.
191    long *specdim = new long[2];
192    specdim[0] = zdim; specdim[1]=1;
193    Image *spectrum = new Image(specdim);
194    spectrum->saveParam(par);
195    spectrum->pars().setBeamSize(2.); // for spectrum, only neighbouring channels correlated
196    for(int npix=0; npix<xySize; npix++){
197
198//       if(par.isVerbose() && ((1000*npix/xySize)%10==0) )
199//      std::cout << "Done " << setw(2) << 100*npix/xySize << "%\b\b\b\b\b\b\b\b" << std::flush;
200      if( par.isVerbose() && ((100*(npix+1)/xySize)%5 == 0) ){
201        std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b|";
202        for(int i=0;i<(100*(npix+1)/xySize)/5;i++) std::cout << "#";
203        for(int i=(100*(npix+1)/xySize)/5;i<20;i++) std::cout << " ";
204        std::cout << "|" << std::flush;
205      }
206
207      for(int z=0;z<zdim;z++) spec[z] = reconArray[z*xySize + npix];
208      spectrum->saveArray(spec,zdim);
209      spectrum->setStats(specMedian[npix],specSigma[npix],par.getCut());
210      if(par.getFlagFDR()) spectrum->setupFDR();
211      spectrum->setMinSize(par.getMinChannels());
212      spectrum->lutz_detect();
213      for(int obj=0;obj<spectrum->getNumObj();obj++){
214        Detection *object = new Detection;
215        *object = spectrum->getObject(obj);
216//      if(par.getFlagGrowth()) growObject(*object,*spectrum);
217        for(int pix=0;pix<object->getSize();pix++) {
218          // Fix up coordinates of each pixel to match original array
219          object->setZ(pix, object->getX(pix));
220          object->setX(pix, npix%dim[0]);
221          object->setY(pix, npix/dim[0]);
222          object->setF(pix, originalArray[object->getX(pix)+object->getY(pix)*dim[0]+object->getZ(pix)*xySize]);
223          // NB: set F to the original value, not the recon value.
224        }
225        object->addOffsets(par);
226        object->calcParams();
227//      outputList.push_back(*object);
228        mergeIntoList(*object,outputList,par);
229        delete object;
230      }
231      spectrum->clearDetectionList();
232    }
233    delete [] spec;
234    delete [] specdim;
235    delete spectrum;
236    delete [] specMedian;
237    delete [] specSigma;
238
239    num = outputList.size();
240    std::cout <<"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bFound " << num <<"; " << std::flush;
241
242  } 
243
244  // Second search --  in each channel
245  std::cout << "2D: |                    |" << std::flush;
246//   if(par.isVerbose()) std::cout << "Done  0%" << "\b\b\b\b\b\b\b\b" << std::flush;
247  float *imageMedian = new float[zdim];
248  float *imageSigma = new float[zdim];
249  float *image = new float[xySize];
250  // First, get stats
251  for(int z=0; z<zdim; z++){
252    goodSize=0;
253    for(int npix=0; npix<xySize; npix++)
254      if(isGood[z*xySize + npix]) image[goodSize++] = originalArray[z*xySize + npix];
255    if(goodSize>0) findMedianStats(image,goodSize,imageMedian[z],dud);
256    else imageMedian[z] = blankPixValue;
257    goodSize=0;
258    for(int npix=0; npix<xySize; npix++)
259      if(isGood[z*xySize+npix])
260        image[goodSize++]=originalArray[z*xySize+npix]-reconArray[z*xySize+npix];
261    if(goodSize>0) findNormalStats(image,goodSize,dud,imageSigma[z]);
262    else imageSigma[z] = 1.;
263  }
264  // Next, do source finding.
265  long *imdim = new long[2];
266  imdim[0] = dim[0]; imdim[1] = dim[1];
267  Image *channelImage = new Image(imdim);
268  channelImage->saveParam(par);
269 
270  bool *doChannel = new bool[zdim];
271  // purpose of this is to ignore the Milky Way channels -- if we are flagging them...
272  for(int z=0;z<zdim;z++)
273    doChannel[z] = !( par.getFlagMW() && (z>=par.getMinMW()) && (z<=par.getMaxMW()) );
274
275  for(int z=0; z<zdim; z++){
276
277    if( par.isVerbose() && ((100*(z+1)/zdim)%5 == 0) ){
278      std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b|";
279      for(int i=0;i<(100*(z+1)/zdim)/5;i++) std::cout << "#";
280      for(int i=(100*(z+1)/zdim)/5;i<20;i++) std::cout << " ";
281      std::cout << "|" << std::flush;
282    }
283//     if(par.isVerbose() && ((1000*z/zdim)%10==0) )
284//       std::cout << "Done " << setw(2) << 100*z/zdim << "%\b\b\b\b\b\b\b\b" << std::flush;
285
286    if( doChannel[z] ){
287      for(int npix=0; npix<xySize; npix++) image[npix] = reconArray[z*xySize + npix];
288      channelImage->saveArray(image,xySize);
289      channelImage->setStats(imageMedian[z],imageSigma[z],par.getCut());
290      if(par.getFlagFDR()) channelImage->setupFDR();
291      channelImage->setMinSize(par.getMinPix());
292      channelImage->lutz_detect();
293      for(int obj=0;obj<channelImage->getNumObj();obj++){
294        Detection *object = new Detection;
295        *object = channelImage->getObject(obj);
296//      if(par.getFlagGrowth()) growObject(*object,*channelImage);
297        // Fix up z coordinates of each pixel to match original array (x & y are fine)
298        for(int pix=0;pix<object->getSize();pix++){
299          object->setZ(pix, z);
300          object->setF(pix, originalArray[object->getX(pix)+object->getY(pix)*dim[0]+z*xySize]);
301          // NB: set F to the original value, not the recon value.
302        }
303        object->addOffsets(par);
304        object->calcParams();
305//      outputList.push_back(*object);
306        mergeIntoList(*object,outputList,par);
307        delete object;
308      }
309      channelImage->clearDetectionList();
310    }
311
312  }
313
314  std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bFound " << outputList.size() - num
315            << ".                                           "  << std::endl << std::flush;
316
317  delete [] image;
318  delete [] imdim;
319  delete channelImage;
320  delete [] doChannel;
321  delete [] imageMedian;
322  delete [] imageSigma;
323
324  delete [] isGood;
325
326  return outputList;
327}
Note: See TracBrowser for help on using the repository browser.