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

Last change on this file since 691 was 691, checked in by MatthewWhiting, 14 years ago

New parameter that allows us to turn off the use of mergeIntoList. Fully documented!

File size: 7.8 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(long *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    std::stringstream ss;
90    ss << "Unknown search type : " << par.getSearchType();
91    duchampError("search3DArray",ss.str());
92    return std::vector<Detection>(0);
93  }
94}
95//---------------------------------------------------------------
96
97
98std::vector <Detection> search3DArraySpectral(long *dim, float *Array, Param &par,
99                                              StatsContainer<float> &stats)
100{
101  /// @details
102  ///  Takes a dimension array and data array as input (and Parameter set)
103  ///  and searches for detections in just the 1D spectra.
104  ///  Returns a vector list of Detections.
105  ///  No reconstruction is assumed to have taken place, so statistics are
106  ///  calculated (using robust methods) from the data array itself.
107  /// \param dim Array of dimension sizes for the data array.
108  /// \param Array Array of data.
109  /// \param par Param set defining how to do detection, and what a
110  /// BLANK pixel is etc.
111  /// \param stats The statistics that define what a detection is.
112  /// \return Vector of detected objects.
113
114  std::vector <Detection> outputList;
115  long zdim = dim[2];
116  long xySize = dim[0] * dim[1];
117  int num = 0;
118
119  if(zdim>1){
120   
121    ProgressBar bar;
122    if(par.isVerbose()) bar.init(xySize);
123
124    bool *doPixel = new bool[xySize];
125    for(int npix=0; npix<xySize; npix++){
126      doPixel[npix] = false;
127      for(int z=0;z<zdim;z++){
128        doPixel[npix] = doPixel[npix] ||
129          (!par.isBlank(Array[npix]) && !par.isInMW(z));
130      }
131      // doPixel[i] is false only when there are no good pixels in spectrum
132      //  of pixel #i.
133    }
134
135    long *specdim = new long[2];
136    specdim[0] = zdim; specdim[1]=1;
137    Image *spectrum = new Image(specdim);
138    delete [] specdim;
139    spectrum->saveParam(par);
140    spectrum->saveStats(stats);
141    //    spectrum->setMinSize(par.getMinChannels());
142    spectrum->setMinSize(1);
143    // beam size: for spectrum, only neighbouring channels correlated
144
145    for(int y=0; y<dim[1]; y++){
146      for(int x=0; x<dim[0]; x++){
147
148        int npix = y*dim[0] + x;
149        if( par.isVerbose() ) bar.update(npix+1);
150       
151        if(doPixel[npix]){
152          spectrum->extractSpectrum(Array,dim,npix);
153          spectrum->removeMW(); // only works if flagMW is true
154          std::vector<Scan> objlist = spectrum->findSources1D();
155          std::vector<Scan>::iterator obj;
156          num += objlist.size();
157          for(obj=objlist.begin();obj<objlist.end();obj++){
158            Detection newObject;
159            // Fix up coordinates of each pixel to match original array
160            for(int z=obj->getX();z<=obj->getXmax();z++) {
161              newObject.addPixel(x,y,z);
162            }
163            newObject.setOffsets(par);
164            if(par.getFlagTwoStageMerging()) mergeIntoList(newObject,outputList,par);
165            else outputList.push_back(newObject);
166          }
167        }
168      }
169    }
170
171    delete spectrum;
172    delete [] doPixel;
173 
174
175    if(par.isVerbose()){
176      bar.remove();
177      std::cout << "Found " << num << ".\n";
178    }
179
180  }
181
182  return outputList;
183}
184//---------------------------------------------------------------
185
186std::vector <Detection> search3DArraySpatial(long *dim, float *Array,
187                                             Param &par,
188                                             StatsContainer<float> &stats)
189{
190  /// @details
191  ///  Takes a dimension array and data array as input (and Parameter
192  ///  set) and searches for detections just in the channel maps -- no
193  ///  1D searches are done. 
194  ///  Returns a vector list of Detections.
195  ///  No reconstruction is assumed to have taken place, so only the base
196  ///  data array is searched.
197  /// \param dim Array of dimension sizes for the data array.
198  /// \param Array Array of data.
199  /// \param par Param set defining how to do detection, and what a
200  ///              BLANK pixel is etc.
201  /// \param stats The statistics that define what a detection is.
202  /// \return A std::vector of detected objects.
203
204  std::vector <Detection> outputList;
205  long zdim = dim[2];
206  int num = 0;
207
208  ProgressBar bar;
209  bool useBar = (zdim>1);
210  if(useBar && par.isVerbose()) bar.init(zdim);
211 
212  long *imdim = new long[2];
213  imdim[0] = dim[0]; imdim[1] = dim[1];
214  Image *channelImage = new Image(imdim);
215  delete [] imdim;
216  channelImage->saveParam(par);
217  channelImage->saveStats(stats);
218  channelImage->setMinSize(1);
219
220  for(int z=0; z<zdim; z++){
221
222    if( par.isVerbose() && useBar ) bar.update(z+1);
223
224    if(!par.isInMW(z)){
225
226      channelImage->extractImage(Array,dim,z);
227      std::vector<Object2D> objlist = channelImage->findSources2D();
228      std::vector<Object2D>::iterator obj;
229      num += objlist.size();
230      for(obj=objlist.begin();obj!=objlist.end();obj++){
231        Detection newObject;
232        newObject.addChannel(z,*obj);
233        newObject.setOffsets(par);
234        if(par.getFlagTwoStageMerging()) mergeIntoList(newObject,outputList,par);
235        else outputList.push_back(newObject);
236      }
237    }
238
239  }
240
241  delete channelImage;
242
243  if(par.isVerbose()){
244    if(useBar) bar.remove();
245    std::cout << "Found " << num << ".\n";
246  }
247
248  return outputList;
249}
250
251
252}
Note: See TracBrowser for help on using the repository browser.