source: tags/release-1.1.9/src/Cubes/Merger.cc @ 1441

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

Addressing #74. Need to assess the impact of this, but I think the functionality requested is all there.

File size: 7.0 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/Utils/utils.hh>
39#include <duchamp/Utils/feedback.hh>
40
41using std::vector;
42using namespace PixelInfo;
43
44namespace duchamp
45{
46
47  void Cube::ObjectMerger()
48  {
49    /// @details
50    /// A Function that takes a Cube's list of Detections and
51    /// combines those that are close (according to the
52    /// thresholds specified in the parameter list par).
53    /// It also excludes those that do not make the minimum
54    /// number of channels requirement.
55    /// A front end to simpler functions mergeList and finaliseList,
56    ///  with code to cover the option of growing objects.
57
58    int startSize = this->objectList->size();
59
60    if(startSize > 0){
61
62      // make a vector "currentList", which starts as a copy of the Cube's
63      //  objectList, but is the one worked on.
64      vector <Detection> currentList(startSize);
65      for(int i=0;i<startSize;i++) currentList[i] = this->objectList->at(i);
66      this->objectList->clear();
67
68      if(this->par.getFlagRejectBeforeMerge())
69        finaliseList(currentList, this->par);
70
71      mergeList(currentList, this->par);
72
73      // Do growth stuff
74      if(this->par.getFlagGrowth()) {
75        vector <Detection> newList(currentList.size());
76        for(size_t i=0;i<currentList.size();i++){
77          if(this->par.isVerbose()){
78            std::cout.setf(std::ios::right);
79            std::cout << "Growing: " << std::setw(6) << i+1 << "/";       
80            std::cout.unsetf(std::ios::right);
81            std::cout.setf(std::ios::left);
82            std::cout << std::setw(6) << currentList.size() << std::flush;
83            printBackSpace(22);
84            std::cout << std::flush;
85          }
86          Detection *obj = new Detection;
87          *obj = currentList[i];
88          growObject(*obj,*this);
89          newList[i] = *obj;
90          delete obj;
91        }
92        currentList.clear();
93        currentList = newList;
94        std::cout.unsetf(std::ios::left);
95
96        // and do the merging again to pick up objects that have
97        //  grown into each other.
98        mergeList(currentList, this->par);
99      }
100
101      if(!this->par.getFlagRejectBeforeMerge())
102        finaliseList(currentList, this->par);
103
104      //     *this->objectList = currentList;
105      this->objectList->resize(currentList.size());
106      for(size_t i=0;i<currentList.size();i++)
107        this->objectList->at(i) = currentList[i];
108   
109      currentList.clear();
110
111    }
112  }
113
114  void ObjectMerger(vector<Detection> &objList, Param &par)
115  {
116    /// @details
117    ///   A simple front-end to the mergeList() and finaliseList() functions,
118    ///    so that if you want to merge a single list, it will
119    ///    do both the merging and the cleaning up afterwards.
120
121    mergeList(objList, par);
122    finaliseList(objList, par);
123  }
124
125  void mergeList(vector<Detection> &objList, Param &par)
126  {
127    /// @details
128    ///   A function that merges any objects in the list of
129    ///    Detections that are within stated threshold distances.
130    ///   Determination of whether objects are close is done by
131    ///    the function areClose.
132
133    if(objList.size() > 0){
134
135      bool isVerb = par.isVerbose();
136      vector <Detection>::iterator iter;
137
138      size_t counter=0, compCounter;
139      while( counter < (objList.size()-1) ){
140        if(isVerb){
141          std::cout.setf(std::ios::right);
142          std::cout << "Merging: " << std::setw(6) << counter+1 << "/" ;
143          std::cout.unsetf(std::ios::right);
144          std::cout.setf(std::ios::left);
145          std::cout << std::setw(6) << objList.size();
146          printBackSpace(22);
147          std::cout << std::flush;
148          std::cout.unsetf(std::ios::left);
149        }
150
151        compCounter = counter + 1;
152
153        do {
154
155          Detection obj1 = objList[counter];
156          Detection obj2 = objList[compCounter];
157          Detection newobj;
158
159          bool close = areClose(obj1, obj2, par);
160
161          if(close){
162            newobj = obj1 + obj2 ;
163            iter = objList.begin() + compCounter;
164            objList.erase(iter);
165            iter = objList.begin() + counter;
166            objList.erase(iter);
167            objList.push_back( newobj );
168
169            if(isVerb){
170              std::cout.setf(std::ios::right);
171              std::cout << "Merging: "
172                        << std::setw(6) << counter << "/";
173              std::cout.unsetf(std::ios::right);
174              std::cout.setf(std::ios::left);
175              std::cout << std::setw(6) << objList.size();
176              printBackSpace(22);
177              std::cout << std::flush;
178              std::cout.unsetf(std::ios::left);
179            }
180
181            compCounter = counter + 1;
182
183          }
184          else compCounter++;
185
186        } while( (compCounter<objList.size()) );
187
188        counter++;
189
190      }  // end of while(counter<(objList.size()-1)) loop
191    }
192  }
193
194
195  void finaliseList(vector<Detection> &objList, Param &par)
196  {
197    /// @details
198    ///  A function that looks at each object in the Detection vector
199    ///    and determines whether is passes the requirements for the
200    ///    minimum number of channels and spatial pixels, as provided by
201    ///    the Param set par.
202    ///   If it does not pass, it is removed from the list.
203    ///   In the process, the object parameters are calculated and offsets
204    ///    are added.
205
206    if(par.isVerbose()){
207      std::cout << "Rejecting:" << std::setw(6) << objList.size();
208      printSpace(6);
209      printBackSpace(22);
210      std::cout << std::flush;
211    }
212
213    std::vector<Detection>::iterator obj = objList.begin();
214
215    while(obj < objList.end()){
216
217      obj->setOffsets(par);
218     
219      if( (obj->hasEnoughChannels(par.getMinChannels()))
220          && (obj->getSpatialSize() >= par.getMinPix()) ){
221
222        obj++;
223
224      }     
225      else{
226     
227        objList.erase(obj);
228        if(par.isVerbose()){
229          std::cout << "Rejecting:" << std::setw(6) << objList.size();
230          printSpace(6);
231          printBackSpace(22);
232          std::cout << std::flush;
233        }
234
235      }
236    }
237  }
238
239
240}
Note: See TracBrowser for help on using the repository browser.