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

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

Changing minChannels and minPix to unsigned int. Making sure Cubes/Merger?.cc (which makes use of their accessors) actually includes param.hh

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