source: tags/release-1.1.12/src/Cubes/CubicSearch.cc

Last change on this file was 788, checked in by MatthewWhiting, 13 years ago

First part of dealing with #110. Have defined a Beam & DuchampBeam? class and use these to hold the beam information. FitsHeader? holds the one that we work with, and copies it to Param for use with outputs. Parameters will be taken into account if no header information is present. Still need to add code to deal with the case of neither being present (the beam being EMPTY) and how that affects the integrated flux calculations.

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
144    for(int y=0; y<dim[1]; y++){
145      for(int x=0; x<dim[0]; x++){
146
147        int npix = y*dim[0] + x;
148        if( par.isVerbose() ) bar.update(npix+1);
149       
150        if(doPixel[npix]){
151          spectrum->extractSpectrum(Array,dim,npix);
152          spectrum->removeMW(); // only works if flagMW is true
153          std::vector<Scan> objlist = spectrum->findSources1D();
154          std::vector<Scan>::iterator obj;
155          num += objlist.size();
156          for(obj=objlist.begin();obj<objlist.end();obj++){
157            Detection newObject;
158            // Fix up coordinates of each pixel to match original array
159            for(int z=obj->getX();z<=obj->getXmax();z++) {
160              newObject.addPixel(x,y,z);
161            }
162            newObject.setOffsets(par);
163            if(par.getFlagTwoStageMerging()) mergeIntoList(newObject,outputList,par);
164            else outputList.push_back(newObject);
165          }
166        }
167      }
168    }
169
170    delete spectrum;
171    delete [] doPixel;
172 
173
174    if(par.isVerbose()){
175      bar.remove();
176      std::cout << "Found " << num << ".\n";
177    }
178
179  }
180
181  return outputList;
182}
183//---------------------------------------------------------------
184
185std::vector <Detection> search3DArraySpatial(long *dim, float *Array,
186                                             Param &par,
187                                             StatsContainer<float> &stats)
188{
189  /// @details
190  ///  Takes a dimension array and data array as input (and Parameter
191  ///  set) and searches for detections just in the channel maps -- no
192  ///  1D searches are done. 
193  ///  Returns a vector list of Detections.
194  ///  No reconstruction is assumed to have taken place, so only the base
195  ///  data array is searched.
196  /// \param dim Array of dimension sizes for the data array.
197  /// \param Array Array of data.
198  /// \param par Param set defining how to do detection, and what a
199  ///              BLANK pixel is etc.
200  /// \param stats The statistics that define what a detection is.
201  /// \return A std::vector of detected objects.
202
203  std::vector <Detection> outputList;
204  long zdim = dim[2];
205  int num = 0;
206
207  ProgressBar bar;
208  bool useBar = (zdim>1);
209  if(useBar && par.isVerbose()) bar.init(zdim);
210 
211  long *imdim = new long[2];
212  imdim[0] = dim[0]; imdim[1] = dim[1];
213  Image *channelImage = new Image(imdim);
214  delete [] imdim;
215  channelImage->saveParam(par);
216  channelImage->saveStats(stats);
217  channelImage->setMinSize(1);
218
219  for(int z=0; z<zdim; z++){
220
221    if( par.isVerbose() && useBar ) bar.update(z+1);
222
223    if(!par.isInMW(z)){
224
225      channelImage->extractImage(Array,dim,z);
226      std::vector<Object2D> objlist = channelImage->findSources2D();
227      std::vector<Object2D>::iterator obj;
228      num += objlist.size();
229      for(obj=objlist.begin();obj!=objlist.end();obj++){
230        Detection newObject;
231        newObject.addChannel(z,*obj);
232        newObject.setOffsets(par);
233        if(par.getFlagTwoStageMerging()) mergeIntoList(newObject,outputList,par);
234        else outputList.push_back(newObject);
235      }
236    }
237
238  }
239
240  delete channelImage;
241
242  if(par.isVerbose()){
243    if(useBar) bar.remove();
244    std::cout << "Found " << num << ".\n";
245  }
246
247  return outputList;
248}
249
250
251}
Note: See TracBrowser for help on using the repository browser.