source: tags/release-1.2.2/src/Cubes/Merger.cc

Last change on this file was 1056, checked in by MatthewWhiting, 12 years ago

Moving the code for growing sources into a separate function - this might make it easier to do things piecemeal.

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