source: branches/fitshead-branch/ATrous/ReconSearch.cc @ 1441

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

Four major sets of changes and a couple of minor ones:

  • Changed name of saved recon/resid FITS file, so that it incorporates all reconstruction parameters.
  • Removed MW parameters from header file
  • Added hashed box to be drawn over MW range in spectral plots
  • Fixed bug that meant reon would be done in 1- or 2-d even if recon array has been read in.

Summary:
param.hh -- prototypes for FITS file name calculation functions
param.cc -- FITS file name calculation functions
Cubes/plots.hh -- drawMWRange function
ATrous/ReconSearch.cc -- tests to see if reconExists for 1- and 2-D recon
Cubes/cubes.cc -- work out enclosed flux correctly for flagNegative
Cubes/detectionIO.cc -- added reconDim line to VOTable output
Cubes/outputSpectra.cc -- added code to draw MW range
Cubes/readRecon.cc -- added call to FITS file name function, and removed

MW params and superfluous tests on atrous parameters

Cubes/saveImage.cc -- improved logical flow. added call to FITS file name func

removed MW keywords.

Detection/columns.cc -- added extra column to fluxes if negative.

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