source: tags/release-1.1/src/Cubes/smoothCube.cc @ 1391

Last change on this file since 1391 was 309, checked in by Matthew Whiting, 17 years ago

Mostly changes to fix some memory allocation/deallocation issues raised by valgrind. Minor changes to the Guide.

File size: 8.6 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.hh>
30#include <Cubes/cubes.hh>
31#include <Detection/detection.hh>
32#include <PixelMap/Object2D.hh>
33#include <Utils/feedback.hh>
34#include <Utils/Hanning.hh>
35#include <Utils/GaussSmooth.hh>
36#include <Utils/Statistics.hh>
37#include <Utils/utils.hh>
38
39void Cube::SmoothSearch()
40{
41  /**
42   * The Cube is first smoothed, using Cube::SmoothCube().
43   * It is then searched, using search3DArray()
44   * The resulting object list is stored in the Cube, and outputted
45   *  to the log file if the user so requests.
46   */
47
48  if(!this->par.getFlagSmooth()){
49    duchampWarning("SmoothSearch",
50                   "FlagSmooth not set! Using basic CubicSearch.\n");
51    this->CubicSearch();
52  }
53  else{   
54
55    this->SmoothCube();
56 
57    if(this->par.isVerbose()) std::cout << "  ";
58
59    this->setCubeStats();
60
61//       this->Stats.scaleNoise(1./gauss.getStddevScale());
62
63    if(this->par.isVerbose()) std::cout << "  Searching... " << std::flush;
64 
65    *(this->objectList) = search3DArraySimple(this->axisDim,this->recon,
66                                              this->par,this->Stats);
67 
68    if(this->par.isVerbose()) std::cout << "  Updating detection map... "
69                                        << std::flush;
70    this->updateDetectMap();
71    if(this->par.isVerbose()) std::cout << "Done.\n";
72
73    if(this->par.getFlagLog()){
74      if(this->par.isVerbose())
75        std::cout << "  Logging intermediate detections... " << std::flush;
76      this->logDetectionList();
77      if(this->par.isVerbose()) std::cout << "Done.\n";
78    }
79 
80  }
81
82}
83//-----------------------------------------------------------
84
85void Cube::SmoothCube()
86{
87  /**
88   *  Switching function that chooses the appropriate function with
89   *  which to smooth the cube, based on the Param::smoothType
90   *  parameter.
91   *
92   */
93  if(this->par.getSmoothType()=="spectral"){
94   
95    this->SpectralSmooth();
96
97    }
98    else if(this->par.getSmoothType()=="spatial"){
99     
100      this->SpatialSmooth();
101     
102    }
103}
104//-----------------------------------------------------------
105
106void Cube::SpectralSmooth()
107{
108  /**
109   *   A function that smoothes each spectrum in the cube using the
110   *    Hanning smoothing function. The degree of smoothing is given
111   *    by the parameter Param::hanningWidth.
112   */
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.getNumAxes() <= 2)
120      duchampWarning("SpectralSmooth",
121                     "There is no spectral axis, so cannot do the spectal smoothing.\n");
122    else{
123
124      Hanning hann(this->par.getHanningWidth());
125 
126      float *spectrum = new float[this->axisDim[2]];
127
128      if(this->par.isVerbose()) {
129        std::cout<<"  Smoothing spectrally... ";
130        bar.init(xySize);
131      }
132
133      for(int pix=0;pix<xySize;pix++){
134
135        if( this->par.isVerbose() ) bar.update(pix+1);
136   
137        for(int z=0;z<zdim;z++){
138          if(this->isBlank(z*xySize+pix)) spectrum[z]=0.;
139          else spectrum[z] = this->array[z*xySize+pix];
140        }
141
142        float *smoothed = hann.smooth(spectrum,zdim);
143
144        for(int z=0;z<zdim;z++){
145          if(this->isBlank(z*xySize+pix))
146            this->recon[z*xySize+pix] = this->array[z*xySize+pix];
147          else
148            this->recon[z*xySize+pix] = smoothed[z];
149        }
150        delete [] smoothed;
151      }
152      this->reconExists = true;
153      if(this->par.isVerbose()) bar.fillSpace("All Done.\n");
154
155      delete [] spectrum;
156
157    }
158  }
159}
160//-----------------------------------------------------------
161
162void Cube::SpatialSmooth()
163{
164
165  if(!this->reconExists && this->par.getSmoothType()=="spatial"){
166
167    if( this->head.getNumAxes() < 2 )
168      duchampWarning("SpatialSmooth",
169                     "There are not enough axes to do the spatial smoothing.\n");
170    else{
171
172      long xySize = this->axisDim[0]*this->axisDim[1];
173      long xdim = this->axisDim[0];
174      long ydim = this->axisDim[1];
175      long zdim = this->axisDim[2];
176
177      ProgressBar bar;
178
179      // if kernMin is negative (not defined), make it equal to kernMaj
180      if(this->par.getKernMin() < 0)
181        this->par.setKernMin(this->par.getKernMaj());
182
183      GaussSmooth gauss(this->par.getKernMaj(),
184                        this->par.getKernMin(),
185                        this->par.getKernPA());
186
187      if(this->par.isVerbose()) {
188        std::cout<<"  Smoothing spatially... " << std::flush;
189        bar.init(zdim);
190      }
191
192      float *image = new float[xySize];
193
194      for(int z=0;z<zdim;z++){
195
196        if( this->par.isVerbose() ) bar.update(z+1);
197     
198        for(int pix=0;pix<xySize;pix++) image[pix] = this->array[z*xySize+pix];
199   
200        bool *mask      = this->par.makeBlankMask(image,xySize);
201   
202        float *smoothed = gauss.smooth(image,xdim,ydim,mask);
203   
204        for(int pix=0;pix<xySize;pix++){
205          if(mask[pix])
206            this->recon[z*xySize+pix] = this->array[z*xySize+pix];
207          else
208            this->recon[z*xySize+pix] = smoothed[pix];
209        }
210
211        delete [] smoothed;
212        delete [] mask;
213      }
214
215      delete [] image;
216 
217      this->reconExists = true;
218 
219      if(par.isVerbose()) bar.fillSpace("All Done.\n");
220    }
221  }
222}
223//-----------------------------------------------------------
224
225void Cube::SpatialSmoothNSearch()
226{
227
228  long xySize = this->axisDim[0]*this->axisDim[1];
229  long xdim = this->axisDim[0];
230  long ydim = this->axisDim[1];
231  long zdim = this->axisDim[2];
232  int numFound=0;
233  ProgressBar bar;
234
235  GaussSmooth gauss(this->par.getKernMaj(),
236                    this->par.getKernMin(),
237                    this->par.getKernPA());
238
239  this->Stats.scaleNoise(1./gauss.getStddevScale());
240  if(this->par.getFlagFDR()) this->setupFDR();
241
242  if(this->par.isVerbose()) {
243    std::cout<<"  Smoothing spatially & searching... " << std::flush;
244    bar.init(zdim);
245  }
246
247  std::vector <Detection> outputList;
248  long *imdim = new long[2];
249  imdim[0] = xdim; imdim[1] = ydim;
250  Image *channelImage = new Image(imdim);
251  delete [] imdim;
252  channelImage->saveParam(this->par);
253  channelImage->saveStats(this->Stats);
254  channelImage->setMinSize(1);
255
256  float *image = new float[xySize];
257  float *smoothed;
258  bool *mask;
259  float median,madfm;//,threshold;
260  for(int z=0;z<zdim;z++){
261
262    if( this->par.isVerbose() ) bar.update(z+1);
263     
264    if(!this->par.isInMW(z)){
265
266      for(int pix=0;pix<xySize;pix++) image[pix] = this->array[z*xySize+pix];
267
268      mask  = this->par.makeBlankMask(image,xySize);
269
270      smoothed = gauss.smooth(image,xdim,ydim,mask);
271     
272      //     for(int pix=0;pix<xySize;pix++)
273      //       this->recon[z*xySize+pix] = smoothed[pix];
274
275      findMedianStats(smoothed,xySize,mask,median,madfm);
276      //       threshold = median+this->par.getCut()*Statistics::madfmToSigma(madfm);
277      //       for(int i=0;i<xySize;i++)
278      //        if(smoothed[i]<threshold) image[i] = this->Stats.getMiddle();
279      //       channelImage->saveArray(image,xySize);
280
281
282      //       channelImage->stats().setMadfm(madfm);
283      //       channelImage->stats().setMedian(median);
284      //       channelImage->stats().setThresholdSNR(this->par.getCut());
285      channelImage->saveArray(smoothed,xySize);
286
287      std::vector<PixelInfo::Object2D> objlist = channelImage->lutz_detect();
288      numFound += objlist.size();
289      for(int obj=0;obj<objlist.size();obj++){
290        Detection newObject;
291        newObject.pixels().addChannel(z,objlist[obj]);
292        newObject.setOffsets(this->par);
293        mergeIntoList(newObject,outputList,this->par);
294      }
295
296    }
297   
298  }
299
300  delete [] smoothed;
301  delete [] mask;
302  delete [] image;
303  delete channelImage;
304   
305  //   this->reconExists = true;
306  if(par.isVerbose()){
307    bar.fillSpace("Found ");
308    std::cout << numFound << ".\n";
309  }
310   
311  *this->objectList = outputList;
312
313}
Note: See TracBrowser for help on using the repository browser.