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

Last change on this file since 521 was 463, checked in by MatthewWhiting, 16 years ago

Changes aimed at calculating the w50 and w20 parameters, and printing them out.

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/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    /**
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
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      mergeList(currentList, this->par);
70
71      // Do growth stuff
72      if(this->par.getFlagGrowth()) {
73        vector <Detection> newList(currentList.size());
74        for(int i=0;i<currentList.size();i++){
75          std::cout.setf(std::ios::right);
76          std::cout << "Growing: " << std::setw(6) << i+1 << "/";         
77          std::cout.unsetf(std::ios::right);
78          std::cout.setf(std::ios::left);
79          std::cout << std::setw(6) << currentList.size() << std::flush;
80          printBackSpace(22);
81          std::cout << std::flush;
82          Detection *obj = new Detection;
83          *obj = currentList[i];
84          growObject(*obj,*this);
85          newList[i] = *obj;
86          delete obj;
87        }
88        currentList.clear();
89        currentList = newList;
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      finaliseList(currentList, this->par);
98
99      //     *this->objectList = currentList;
100      this->objectList->resize(currentList.size());
101      for(int i=0;i<currentList.size();i++)
102        this->objectList->at(i) = currentList[i];
103   
104      currentList.clear();
105
106    }
107  }
108
109  void ObjectMerger(vector<Detection> &objList, Param &par)
110  {
111    /**
112     *   A simple front-end to the mergeList() and finaliseList() functions,
113     *    so that if you want to merge a single list, it will
114     *    do both the merging and the cleaning up afterwards.
115     */
116    mergeList(objList, par);
117    finaliseList(objList, par);
118  }
119
120  void mergeList(vector<Detection> &objList, Param &par)
121  {
122    /**
123     *   A function that merges any objects in the list of
124     *    Detections that are within stated threshold distances.
125     *   Determination of whether objects are close is done by
126     *    the function areClose.
127     */
128
129    if(objList.size() > 0){
130
131      bool isVerb = par.isVerbose();
132      vector <Detection>::iterator iter;
133
134      int 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          Detection obj1 = objList[counter];
152          Detection obj2 = objList[compCounter];
153
154          bool close = areClose(obj1, obj2, par);
155
156          if(close){
157            obj1 = obj1 + obj2 ;
158            iter = objList.begin() + compCounter;
159            objList.erase(iter);
160            iter = objList.begin() + counter;
161            objList.erase(iter);
162            objList.push_back( obj1 );
163
164            if(isVerb){
165              std::cout.setf(std::ios::right);
166              std::cout << "Merging: "
167                        << std::setw(6) << counter << "/";
168              std::cout.unsetf(std::ios::right);
169              std::cout.setf(std::ios::left);
170              std::cout << std::setw(6) << objList.size();
171              printBackSpace(22);
172              std::cout << std::flush;
173              std::cout.unsetf(std::ios::left);
174            }
175
176            compCounter = counter + 1;
177
178          }
179          else compCounter++;
180
181        } while( (compCounter<objList.size()) );
182
183        counter++;
184
185      }  // end of while(counter<(objList.size()-1)) loop
186    }
187  }
188
189
190  void finaliseList(vector<Detection> &objList, Param &par)
191  {
192    /**
193     *  A function that looks at each object in the Detection vector
194     *    and determines whether is passes the requirements for the
195     *    minimum number of channels and spatial pixels, as provided by
196     *    the Param set par.
197     *   If it does not pass, it is removed from the list.
198     *   In the process, the object parameters are calculated and offsets
199     *    are added.
200     */
201
202    int listCounter = 0;
203
204    std::cout << "Rejecting:" << std::setw(6) << objList.size();
205    printSpace(6);
206    printBackSpace(22);
207    std::cout << std::flush;
208 
209    while(listCounter < objList.size()){
210
211      objList[listCounter].setOffsets(par);
212
213      if( (objList[listCounter].hasEnoughChannels(par.getMinChannels()))
214          && (objList[listCounter].getSpatialSize() >= par.getMinPix()) ){
215
216        listCounter++;
217
218      }     
219      else{
220     
221        objList.erase(objList.begin()+listCounter);
222        if(par.isVerbose()){
223          std::cout << "Rejecting:" << std::setw(6) << objList.size();
224          printSpace(6);
225          printBackSpace(22);
226          std::cout << std::flush;
227        }
228
229      }
230    }
231  }
232
233
234}
Note: See TracBrowser for help on using the repository browser.