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
RevLine 
[299]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// -----------------------------------------------------------------------
[3]29#include <iostream>
[258]30#include <fstream>
[3]31#include <iomanip>
32#include <math.h>
33#include <vector>
[393]34#include <duchamp/PixelMap/Object3D.hh>
35#include <duchamp/Cubes/cubes.hh>
[463]36#include <duchamp/Cubes/cubeUtils.hh>
[393]37#include <duchamp/Detection/detection.hh>
[744]38#include <duchamp/Detection/ObjectGrower.hh>
[393]39#include <duchamp/Utils/utils.hh>
40#include <duchamp/Utils/feedback.hh>
[3]41
[232]42using std::vector;
[258]43using namespace PixelInfo;
[232]44
[378]45namespace duchamp
[3]46{
47
[378]48  void Cube::ObjectMerger()
49  {
[528]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.
[3]58
[378]59    int startSize = this->objectList->size();
[258]60
[378]61    if(startSize > 0){
[3]62
[378]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();
[3]68
[672]69      if(this->par.getFlagRejectBeforeMerge())
70        finaliseList(currentList, this->par);
71
[423]72      mergeList(currentList, this->par);
[378]73
74      // Do growth stuff
75      if(this->par.getFlagGrowth()) {
[744]76        ObjectGrower grower;
77        grower.define(this);
[623]78        for(size_t i=0;i<currentList.size();i++){
[629]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          }
[744]88          grower.grow(&currentList[i]);
[378]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.
[423]94        mergeList(currentList, this->par);
[137]95      }
[3]96
[672]97      if(!this->par.getFlagRejectBeforeMerge())
98        finaliseList(currentList, this->par);
[3]99
[378]100      //     *this->objectList = currentList;
101      this->objectList->resize(currentList.size());
[623]102      for(size_t i=0;i<currentList.size();i++)
[378]103        this->objectList->at(i) = currentList[i];
[291]104   
[378]105      currentList.clear();
[3]106
[378]107    }
[137]108  }
[3]109
[378]110  void ObjectMerger(vector<Detection> &objList, Param &par)
111  {
[528]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
[378]117    mergeList(objList, par);
118    finaliseList(objList, par);
119  }
[138]120
[378]121  void mergeList(vector<Detection> &objList, Param &par)
122  {
[528]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.
[86]128
[378]129    if(objList.size() > 0){
[3]130
[378]131      bool isVerb = par.isVerbose();
132      vector <Detection>::iterator iter;
[3]133
[623]134      size_t counter=0, compCounter;
[378]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        }
[3]146
[378]147        compCounter = counter + 1;
[3]148
[378]149        do {
[3]150
[747]151          bool close = areClose(objList[counter], objList[compCounter], par);
[3]152
[378]153          if(close){
[747]154            objList[counter].addDetection(objList[compCounter]);
155            iter=objList.begin()+compCounter;
[378]156            objList.erase(iter);
[137]157
[378]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            }
[137]169
[378]170            compCounter = counter + 1;
[137]171
[378]172          }
173          else compCounter++;
[3]174
[378]175        } while( (compCounter<objList.size()) );
[3]176
[378]177        counter++;
[3]178
[378]179      }  // end of while(counter<(objList.size()-1)) loop
180    }
[137]181  }
[3]182
183
[378]184  void finaliseList(vector<Detection> &objList, Param &par)
185  {
[528]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.
[728]192    ///   In the process, the offsets are set.
[3]193
[637]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
[577]201    std::vector<Detection>::iterator obj = objList.begin();
[3]202
[577]203    while(obj < objList.end()){
204
205      obj->setOffsets(par);
[570]206     
[577]207      if( (obj->hasEnoughChannels(par.getMinChannels()))
[720]208          && (obj->getSpatialSize() >= par.getMinPix())
[721]209          && (obj->getSize() >= par.getMinVoxels() ) ){
[139]210
[577]211        obj++;
[265]212
[378]213      }     
214      else{
[271]215     
[577]216        objList.erase(obj);
[378]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
[137]224      }
[265]225    }
[3]226  }
227
[137]228
[378]229}
Note: See TracBrowser for help on using the repository browser.