source: trunk/src/Cubes/Merger.cc @ 747

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

More improvements based on some profiling with Shark. Tara's test case down to just over a minute!

File size: 6.8 KB
Line 
1// -----------------------------------------------------------------------
2// Merger.cc: Merging a list of Detections, and rejecting on the basis
3//            of number of channels or pixels.
4// -----------------------------------------------------------------------
5// Copyright (C) 2006, Matthew Whiting, ATNF
6//
7// This program is free software; you can redistribute it and/or modify it
8// under the terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2 of the License, or (at your
10// option) any later version.
11//
12// Duchamp is distributed in the hope that it will be useful, but WITHOUT
13// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15// for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with Duchamp; if not, write to the Free Software Foundation,
19// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
20//
21// Correspondence concerning Duchamp may be directed to:
22//    Internet email: Matthew.Whiting [at] atnf.csiro.au
23//    Postal address: Dr. Matthew Whiting
24//                    Australia Telescope National Facility, CSIRO
25//                    PO Box 76
26//                    Epping NSW 1710
27//                    AUSTRALIA
28// -----------------------------------------------------------------------
29#include <iostream>
30#include <fstream>
31#include <iomanip>
32#include <math.h>
33#include <vector>
34#include <duchamp/PixelMap/Object3D.hh>
35#include <duchamp/Cubes/cubes.hh>
36#include <duchamp/Cubes/cubeUtils.hh>
37#include <duchamp/Detection/detection.hh>
38#include <duchamp/Detection/ObjectGrower.hh>
39#include <duchamp/Utils/utils.hh>
40#include <duchamp/Utils/feedback.hh>
41
42using std::vector;
43using namespace PixelInfo;
44
45namespace duchamp
46{
47
48  void Cube::ObjectMerger()
49  {
50    /// @details
51    /// A Function that takes a Cube's list of Detections and
52    /// combines those that are close (according to the
53    /// thresholds specified in the parameter list par).
54    /// It also excludes those that do not make the minimum
55    /// number of channels requirement.
56    /// A front end to simpler functions mergeList and finaliseList,
57    ///  with code to cover the option of growing objects.
58
59    int startSize = this->objectList->size();
60
61    if(startSize > 0){
62
63      // make a vector "currentList", which starts as a copy of the Cube's
64      //  objectList, but is the one worked on.
65      vector <Detection> currentList(startSize);
66      for(int i=0;i<startSize;i++) currentList[i] = this->objectList->at(i);
67      this->objectList->clear();
68
69      if(this->par.getFlagRejectBeforeMerge())
70        finaliseList(currentList, this->par);
71
72      mergeList(currentList, this->par);
73
74      // Do growth stuff
75      if(this->par.getFlagGrowth()) {
76        ObjectGrower grower;
77        grower.define(this);
78        for(size_t i=0;i<currentList.size();i++){
79          if(this->par.isVerbose()){
80            std::cout.setf(std::ios::right);
81            std::cout << "Growing: " << std::setw(6) << i+1 << "/";       
82            std::cout.unsetf(std::ios::right);
83            std::cout.setf(std::ios::left);
84            std::cout << std::setw(6) << currentList.size() << std::flush;
85            printBackSpace(22);
86            std::cout << std::flush;
87          }
88          grower.grow(&currentList[i]);
89        }
90        std::cout.unsetf(std::ios::left);
91
92        // and do the merging again to pick up objects that have
93        //  grown into each other.
94        mergeList(currentList, this->par);
95      }
96
97      if(!this->par.getFlagRejectBeforeMerge())
98        finaliseList(currentList, this->par);
99
100      //     *this->objectList = currentList;
101      this->objectList->resize(currentList.size());
102      for(size_t i=0;i<currentList.size();i++)
103        this->objectList->at(i) = currentList[i];
104   
105      currentList.clear();
106
107    }
108  }
109
110  void ObjectMerger(vector<Detection> &objList, Param &par)
111  {
112    /// @details
113    ///   A simple front-end to the mergeList() and finaliseList() functions,
114    ///    so that if you want to merge a single list, it will
115    ///    do both the merging and the cleaning up afterwards.
116
117    mergeList(objList, par);
118    finaliseList(objList, par);
119  }
120
121  void mergeList(vector<Detection> &objList, Param &par)
122  {
123    /// @details
124    ///   A function that merges any objects in the list of
125    ///    Detections that are within stated threshold distances.
126    ///   Determination of whether objects are close is done by
127    ///    the function areClose.
128
129    if(objList.size() > 0){
130
131      bool isVerb = par.isVerbose();
132      vector <Detection>::iterator iter;
133
134      size_t counter=0, compCounter;
135      while( counter < (objList.size()-1) ){
136        if(isVerb){
137          std::cout.setf(std::ios::right);
138          std::cout << "Merging: " << std::setw(6) << counter+1 << "/" ;
139          std::cout.unsetf(std::ios::right);
140          std::cout.setf(std::ios::left);
141          std::cout << std::setw(6) << objList.size();
142          printBackSpace(22);
143          std::cout << std::flush;
144          std::cout.unsetf(std::ios::left);
145        }
146
147        compCounter = counter + 1;
148
149        do {
150
151          bool close = areClose(objList[counter], objList[compCounter], par);
152
153          if(close){
154            objList[counter].addDetection(objList[compCounter]);
155            iter=objList.begin()+compCounter;
156            objList.erase(iter);
157
158            if(isVerb){
159              std::cout.setf(std::ios::right);
160              std::cout << "Merging: "
161                        << std::setw(6) << counter << "/";
162              std::cout.unsetf(std::ios::right);
163              std::cout.setf(std::ios::left);
164              std::cout << std::setw(6) << objList.size();
165              printBackSpace(22);
166              std::cout << std::flush;
167              std::cout.unsetf(std::ios::left);
168            }
169
170            compCounter = counter + 1;
171
172          }
173          else compCounter++;
174
175        } while( (compCounter<objList.size()) );
176
177        counter++;
178
179      }  // end of while(counter<(objList.size()-1)) loop
180    }
181  }
182
183
184  void finaliseList(vector<Detection> &objList, Param &par)
185  {
186    /// @details
187    ///  A function that looks at each object in the Detection vector
188    ///    and determines whether is passes the requirements for the
189    ///    minimum number of channels and spatial pixels, as provided by
190    ///    the Param set par.
191    ///   If it does not pass, it is removed from the list.
192    ///   In the process, the offsets are set.
193
194    if(par.isVerbose()){
195      std::cout << "Rejecting:" << std::setw(6) << objList.size();
196      printSpace(6);
197      printBackSpace(22);
198      std::cout << std::flush;
199    }
200
201    std::vector<Detection>::iterator obj = objList.begin();
202
203    while(obj < objList.end()){
204
205      obj->setOffsets(par);
206     
207      if( (obj->hasEnoughChannels(par.getMinChannels()))
208          && (obj->getSpatialSize() >= par.getMinPix())
209          && (obj->getSize() >= par.getMinVoxels() ) ){
210
211        obj++;
212
213      }     
214      else{
215     
216        objList.erase(obj);
217        if(par.isVerbose()){
218          std::cout << "Rejecting:" << std::setw(6) << objList.size();
219          printSpace(6);
220          printBackSpace(22);
221          std::cout << std::flush;
222        }
223
224      }
225    }
226  }
227
228
229}
Note: See TracBrowser for help on using the repository browser.