source: tags/release-1.1.7/src/Cubes/smoothCube.cc @ 533

Last change on this file since 533 was 528, checked in by MatthewWhiting, 15 years ago

Changing the documentation comments to match the askapsoft style. Also have split ChanMap? and Object3D into separate files.

File size: 8.9 KB
Line 
1// -----------------------------------------------------------------------
2// smoothCube: Smooth a Cube's array, and search for objects.
3// -----------------------------------------------------------------------
4// Copyright (C) 2006, Matthew Whiting, ATNF
5//
6// This program is free software; you can redistribute it and/or modify it
7// under the terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 2 of the License, or (at your
9// option) any later version.
10//
11// Duchamp is distributed in the hope that it will be useful, but WITHOUT
12// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14// for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with Duchamp; if not, write to the Free Software Foundation,
18// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
19//
20// Correspondence concerning Duchamp may be directed to:
21//    Internet email: Matthew.Whiting [at] atnf.csiro.au
22//    Postal address: Dr. Matthew Whiting
23//                    Australia Telescope National Facility, CSIRO
24//                    PO Box 76
25//                    Epping NSW 1710
26//                    AUSTRALIA
27// -----------------------------------------------------------------------
28#include <vector>
29#include <duchamp/duchamp.hh>
30#include <duchamp/Cubes/cubes.hh>
31#include <duchamp/Detection/detection.hh>
32#include <duchamp/PixelMap/Object2D.hh>
33#include <duchamp/Utils/feedback.hh>
34#include <duchamp/Utils/Hanning.hh>
35#include <duchamp/Utils/GaussSmooth.hh>
36#include <duchamp/Utils/Statistics.hh>
37#include <duchamp/Utils/utils.hh>
38
39namespace duchamp
40{
41
42void Cube::SmoothSearch()
43{
44  /// @details
45  /// The Cube is first smoothed, using Cube::SmoothCube().
46  /// It is then searched, using search3DArray()
47  /// The resulting object list is stored in the Cube, and outputted
48  ///  to the log file if the user so requests.
49
50  if(!this->par.getFlagSmooth()){
51    duchampWarning("SmoothSearch",
52                   "FlagSmooth not set! Using basic CubicSearch.\n");
53    this->CubicSearch();
54  }
55  else{   
56
57    this->SmoothCube();
58 
59    if(this->par.isVerbose()) std::cout << "  ";
60
61    this->setCubeStats();
62
63//       this->Stats.scaleNoise(1./gauss.getStddevScale());
64
65    if(this->par.isVerbose()) std::cout << "  Searching... " << std::flush;
66 
67    *(this->objectList) = search3DArraySimple(this->axisDim,this->recon,
68                                              this->par,this->Stats);
69 
70    if(this->par.isVerbose()) std::cout << "  Updating detection map... "
71                                        << std::flush;
72    this->updateDetectMap();
73    if(this->par.isVerbose()) std::cout << "Done.\n";
74
75    if(this->par.getFlagLog()){
76      if(this->par.isVerbose())
77        std::cout << "  Logging intermediate detections... " << std::flush;
78      this->logDetectionList();
79      if(this->par.isVerbose()) std::cout << "Done.\n";
80    }
81 
82  }
83
84}
85//-----------------------------------------------------------
86
87void Cube::SmoothCube()
88{
89  /// @details
90  ///  Switching function that chooses the appropriate function with
91  ///  which to smooth the cube, based on the Param::smoothType
92  ///  parameter.
93
94  if(this->par.getSmoothType()=="spectral"){
95   
96    this->SpectralSmooth();
97   
98  }
99  else if(this->par.getSmoothType()=="spatial"){
100   
101    this->SpatialSmooth();
102   
103  }
104}
105//-----------------------------------------------------------
106
107void Cube::SpectralSmooth()
108{
109  /// @details
110  ///   A function that smoothes each spectrum in the cube using the
111  ///    Hanning smoothing function. The degree of smoothing is given
112  ///    by the parameter Param::hanningWidth.
113
114  long xySize = this->axisDim[0]*this->axisDim[1];
115  long zdim = this->axisDim[2];
116  ProgressBar bar;
117
118  if(!this->reconExists && this->par.getSmoothType()=="spectral"){
119    //    if(!this->head.isSpecOK())
120    if(!this->head.canUseThirdAxis())
121      duchampWarning("SpectralSmooth",
122                     "There is no spectral axis, so cannot do the spectral smoothing.\n");
123    else{
124
125      Hanning hann(this->par.getHanningWidth());
126 
127      float *spectrum = new float[this->axisDim[2]];
128
129      if(this->par.isVerbose()) {
130        std::cout<<"  Smoothing spectrally... ";
131        bar.init(xySize);
132      }
133
134      for(int pix=0;pix<xySize;pix++){
135
136        if( this->par.isVerbose() ) bar.update(pix+1);
137   
138        for(int z=0;z<zdim;z++){
139          if(this->isBlank(z*xySize+pix)) spectrum[z]=0.;
140          else spectrum[z] = this->array[z*xySize+pix];
141        }
142
143        float *smoothed = hann.smooth(spectrum,zdim);
144
145        for(int z=0;z<zdim;z++){
146          if(this->isBlank(z*xySize+pix))
147            this->recon[z*xySize+pix] = this->array[z*xySize+pix];
148          else
149            this->recon[z*xySize+pix] = smoothed[z];
150        }
151        delete [] smoothed;
152      }
153      this->reconExists = true;
154      if(this->par.isVerbose()) bar.fillSpace("All Done.\n");
155
156      delete [] spectrum;
157
158    }
159  }
160}
161//-----------------------------------------------------------
162
163void Cube::SpatialSmooth()
164{
165
166  if(!this->reconExists && this->par.getSmoothType()=="spatial"){
167
168    if( this->head.getNumAxes() < 2 )
169      duchampWarning("SpatialSmooth",
170                     "There are not enough axes to do the spatial smoothing.\n");
171    else{
172
173      long xySize = this->axisDim[0]*this->axisDim[1];
174      long xdim = this->axisDim[0];
175      long ydim = this->axisDim[1];
176      long zdim = this->axisDim[2];
177
178      ProgressBar bar;
179//       bool useBar = this->head.canUseThirdAxis();
180      bool useBar = (zdim > 1);
181     
182      // if kernMin is negative (not defined), make it equal to kernMaj
183      if(this->par.getKernMin() < 0)
184        this->par.setKernMin(this->par.getKernMaj());
185
186      GaussSmooth<float> gauss(this->par.getKernMaj(),
187                               this->par.getKernMin(),
188                               this->par.getKernPA());
189
190      if(this->par.isVerbose()) {
191        std::cout<<"  Smoothing spatially... " << std::flush;
192        if(useBar) bar.init(zdim);
193      }
194
195      float *image = new float[xySize];
196
197      for(int z=0;z<zdim;z++){
198
199        if( this->par.isVerbose() && useBar ) bar.update(z+1);
200     
201        for(int pix=0;pix<xySize;pix++) image[pix] = this->array[z*xySize+pix];
202   
203        bool *mask      = this->par.makeBlankMask(image,xySize);
204   
205        float *smoothed = gauss.smooth(image,xdim,ydim,mask);
206   
207        for(int pix=0;pix<xySize;pix++){
208          if(mask[pix])
209            this->recon[z*xySize+pix] = this->array[z*xySize+pix];
210          else
211            this->recon[z*xySize+pix] = smoothed[pix];
212        }
213
214        delete [] smoothed;
215        delete [] mask;
216      }
217
218      delete [] image;
219 
220      this->reconExists = true;
221 
222      if(par.isVerbose()){
223        if(useBar) bar.fillSpace("All Done.");
224        std::cout << "\n";
225      }
226
227    }
228  }
229}
230//-----------------------------------------------------------
231
232void Cube::SpatialSmoothNSearch()
233{
234
235  long xySize = this->axisDim[0]*this->axisDim[1];
236  long xdim = this->axisDim[0];
237  long ydim = this->axisDim[1];
238  long zdim = this->axisDim[2];
239  int numFound=0;
240  ProgressBar bar;
241
242  GaussSmooth<float> gauss(this->par.getKernMaj(),
243                           this->par.getKernMin(),
244                           this->par.getKernPA());
245
246  this->Stats.scaleNoise(1./gauss.getStddevScale());
247  if(this->par.getFlagFDR()) this->setupFDR();
248
249  if(this->par.isVerbose()) {
250    std::cout<<"  Smoothing spatially & searching... " << std::flush;
251    bar.init(zdim);
252  }
253
254  std::vector <Detection> outputList;
255  long *imdim = new long[2];
256  imdim[0] = xdim; imdim[1] = ydim;
257  Image *channelImage = new Image(imdim);
258  delete [] imdim;
259  channelImage->saveParam(this->par);
260  channelImage->saveStats(this->Stats);
261  channelImage->setMinSize(1);
262
263  float *image = new float[xySize];
264  float *smoothed;
265  bool *mask;
266  float median,madfm;//,threshold;
267  for(int z=0;z<zdim;z++){
268
269    if( this->par.isVerbose() ) bar.update(z+1);
270     
271    if(!this->par.isInMW(z)){
272
273      for(int pix=0;pix<xySize;pix++) image[pix] = this->array[z*xySize+pix];
274
275      mask  = this->par.makeBlankMask(image,xySize);
276
277      smoothed = gauss.smooth(image,xdim,ydim,mask);
278     
279      //     for(int pix=0;pix<xySize;pix++)
280      //       this->recon[z*xySize+pix] = smoothed[pix];
281
282      findMedianStats(smoothed,xySize,mask,median,madfm);
283      //       threshold = median+this->par.getCut()*Statistics::madfmToSigma(madfm);
284      //       for(int i=0;i<xySize;i++)
285      //        if(smoothed[i]<threshold) image[i] = this->Stats.getMiddle();
286      //       channelImage->saveArray(image,xySize);
287
288
289      //       channelImage->stats().setMadfm(madfm);
290      //       channelImage->stats().setMedian(median);
291      //       channelImage->stats().setThresholdSNR(this->par.getCut());
292      channelImage->saveArray(smoothed,xySize);
293
294      std::vector<PixelInfo::Object2D> objlist = channelImage->lutz_detect();
295      numFound += objlist.size();
296      for(int obj=0;obj<objlist.size();obj++){
297        Detection newObject;
298        newObject.pixels().addChannel(z,objlist[obj]);
299        newObject.setOffsets(this->par);
300        mergeIntoList(newObject,outputList,this->par);
301      }
302
303    }
304   
305  }
306
307  delete [] smoothed;
308  delete [] mask;
309  delete [] image;
310  delete channelImage;
311   
312  //   this->reconExists = true;
313  if(par.isVerbose()){
314    bar.fillSpace("Found ");
315    std::cout << numFound << ".\n";
316  }
317   
318  *this->objectList = outputList;
319
320}
321
322}
Note: See TracBrowser for help on using the repository browser.