source: trunk/src/Cubes/CubicSearch.cc @ 1441

Last change on this file since 1441 was 1393, checked in by MatthewWhiting, 10 years ago

A large changeset that moves all use of bool arrays (ie. bool *) to std::vector<bool>. This will be a bit safer, plus potentially cheaper in memory usage. Interfaces to all stats functions with masks have changed accordingly, as well as the Gaussian smoothing functions and some spectral utility functions.

File size: 7.7 KB
Line 
1// -----------------------------------------------------------------------
2// CubicSearch.cc: Searching a 3-dimensional Cube.
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 <iostream>
29#include <iomanip>
30#include <fstream>
31#include <vector>
32#include <duchamp/param.hh>
33#include <duchamp/PixelMap/Object3D.hh>
34#include <duchamp/Cubes/cubes.hh>
35#include <duchamp/Utils/utils.hh>
36#include <duchamp/Utils/feedback.hh>
37#include <duchamp/Utils/Statistics.hh>
38
39using std::vector;
40using namespace PixelInfo;
41using namespace Statistics;
42
43namespace duchamp
44{
45
46void Cube::CubicSearch()
47{
48  /// @details
49  ///  A front end to the cubic searching routine that does not
50  ///  involve any wavelet reconstruction.
51  ///  The statistics of the cube are calculated first of all.
52  ///  If baseline-removal is required that is done prior to searching.
53  ///  Once searching is complete, the detection map is updated and
54  ///  the intermediate detections are logged in the log file.
55
56  if(this->par.isVerbose()) std::cout << "  ";
57
58  this->setCubeStats();
59   
60  if(this->par.isVerbose()) std::cout << "  Searching... " << std::flush;
61 
62  *this->objectList = search3DArray(this->axisDim,this->array,
63                                    this->par,this->Stats);
64
65  if(this->par.isVerbose()) std::cout << "  Updating detection map... "
66                                      << std::flush;
67  this->updateDetectMap();
68  if(this->par.isVerbose()) std::cout << "Done.\n";
69
70  if(this->par.getFlagLog()){
71    if(this->par.isVerbose())
72      std::cout << "  Logging intermediate detections... " << std::flush;
73    this->logDetectionList();
74    if(this->par.isVerbose()) std::cout << "Done.\n";
75  }
76
77}
78//---------------------------------------------------------------
79
80std::vector <Detection> search3DArray(size_t *dim, float *Array, Param &par,
81                                      StatsContainer<float> &stats)
82{
83
84  if(par.getSearchType()=="spectral")
85    return search3DArraySpectral(dim,Array,par,stats);
86  else if(par.getSearchType()=="spatial")
87    return search3DArraySpatial(dim,Array,par,stats);
88  else{
89    DUCHAMPERROR("search3DArray","Unknown search type : " << par.getSearchType());
90    return std::vector<Detection>(0);
91  }
92}
93//---------------------------------------------------------------
94
95
96std::vector <Detection> search3DArraySpectral(size_t *dim, float *Array, Param &par,
97                                              StatsContainer<float> &stats)
98{
99  /// @details
100  ///  Takes a dimension array and data array as input (and Parameter set)
101  ///  and searches for detections in just the 1D spectra.
102  ///  Returns a vector list of Detections.
103  ///  No reconstruction is assumed to have taken place, so statistics are
104  ///  calculated (using robust methods) from the data array itself.
105  /// \param dim Array of dimension sizes for the data array.
106  /// \param Array Array of data.
107  /// \param par Param set defining how to do detection, and what a
108  /// BLANK pixel is etc.
109  /// \param stats The statistics that define what a detection is.
110  /// \return Vector of detected objects.
111
112  std::vector <Detection> outputList;
113  size_t zdim = dim[2];
114  size_t xySize = dim[0] * dim[1];
115  int num = 0;
116
117  if(zdim>1){
118   
119    ProgressBar bar;
120    if(par.isVerbose()) bar.init(xySize);
121
122    std::vector<bool> doPixel(xySize,false);
123    for(size_t npix=0; npix<xySize; npix++){
124      for(size_t z=0;z<zdim;z++){
125        doPixel[npix] = doPixel[npix] ||
126            (!par.isBlank(Array[npix+xySize*z]) && !par.isFlaggedChannel(z));
127      }
128      // doPixel[i] is false only when there are no good pixels in spectrum
129      //  of pixel #i.
130    }
131
132    size_t *specdim = new size_t[2];
133    specdim[0] = zdim; specdim[1]=1;
134    Image *spectrum = new Image(specdim);
135    delete [] specdim;
136    spectrum->saveParam(par);
137    spectrum->saveStats(stats);
138    //    spectrum->setMinSize(par.getMinChannels());
139    spectrum->setMinSize(1);
140
141    for(size_t y=0; y<dim[1]; y++){
142      for(size_t x=0; x<dim[0]; x++){
143
144        size_t npix = y*dim[0] + x;
145        if( par.isVerbose() ) bar.update(npix+1);
146       
147        if(doPixel[npix]){
148          spectrum->extractSpectrum(Array,dim,npix);
149          spectrum->removeFlaggedChannels();
150          std::vector<Scan> objlist = spectrum->findSources1D();
151          std::vector<Scan>::iterator obj;
152          num += objlist.size();
153          for(obj=objlist.begin();obj<objlist.end();obj++){
154            Detection newObject;
155            // Fix up coordinates of each pixel to match original array
156            for(int z=obj->getX();z<=obj->getXmax();z++) {
157              newObject.addPixel(x,y,z);
158            }
159            newObject.setOffsets(par);
160            if(par.getFlagTwoStageMerging()) mergeIntoList(newObject,outputList,par);
161            else outputList.push_back(newObject);
162          }
163        }
164      }
165    }
166
167    delete spectrum; 
168
169    if(par.isVerbose()){
170      bar.remove();
171      std::cout << "Found " << num << ".\n";
172    }
173
174  }
175
176  return outputList;
177}
178//---------------------------------------------------------------
179
180std::vector <Detection> search3DArraySpatial(size_t *dim, float *Array,
181                                             Param &par,
182                                             StatsContainer<float> &stats)
183{
184  /// @details
185  ///  Takes a dimension array and data array as input (and Parameter
186  ///  set) and searches for detections just in the channel maps -- no
187  ///  1D searches are done. 
188  ///  Returns a vector list of Detections.
189  ///  No reconstruction is assumed to have taken place, so only the base
190  ///  data array is searched.
191  /// \param dim Array of dimension sizes for the data array.
192  /// \param Array Array of data.
193  /// \param par Param set defining how to do detection, and what a
194  ///              BLANK pixel is etc.
195  /// \param stats The statistics that define what a detection is.
196  /// \return A std::vector of detected objects.
197
198  std::vector <Detection> outputList;
199  size_t zdim = dim[2];
200  int num = 0;
201
202  ProgressBar bar;
203  bool useBar = (zdim>1);
204  if(useBar && par.isVerbose()) bar.init(zdim);
205 
206  size_t *imdim = new size_t[2];
207  imdim[0] = dim[0]; imdim[1] = dim[1];
208  Image *channelImage = new Image(imdim);
209  delete [] imdim;
210  channelImage->saveParam(par);
211  channelImage->saveStats(stats);
212  channelImage->setMinSize(1);
213
214  for(size_t z=0; z<zdim; z++){
215
216    if( par.isVerbose() && useBar ) bar.update(z+1);
217
218    if(!par.isFlaggedChannel(z)){
219
220      channelImage->extractImage(Array,dim,z);
221      std::vector<Object2D> objlist = channelImage->findSources2D();
222      std::vector<Object2D>::iterator obj;
223      num += objlist.size();
224      for(obj=objlist.begin();obj!=objlist.end();obj++){
225        Detection newObject;
226        newObject.addChannel(z,*obj);
227        newObject.setOffsets(par);
228        if(par.getFlagTwoStageMerging()) mergeIntoList(newObject,outputList,par);
229        else outputList.push_back(newObject);
230      }
231    }
232
233  }
234
235  delete channelImage;
236
237  if(par.isVerbose()){
238    if(useBar) bar.remove();
239    std::cout << "Found " << num << ".\n";
240  }
241
242  return outputList;
243}
244
245
246}
Note: See TracBrowser for help on using the repository browser.