OpenWalnut  1.5.0dev
WHierarchicalTreeFibers.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <algorithm>
26 #include <iostream>
27 #include <list>
28 #include <memory>
29 #include <queue>
30 #include <utility>
31 #include <vector>
32 
33 #include "WHierarchicalTreeFibers.h"
34 
37 {
38 }
39 
41 {
42 }
43 
45 {
46  // after a cluster was added no more leafes may be inserted
47  if( m_leafesLocked )
48  {
49  return;
50  }
51 
52  m_level.push_back( 0 );
53  m_parents.push_back( m_clusterCount );
54  std::vector<size_t> tmp( 1, m_clusterCount );
55  m_containsLeafes.push_back( tmp );
56  std::pair<size_t, size_t>tmp2;
57  m_children.push_back( tmp2 );
58  m_customData.push_back( 0.0 );
59  m_colors.push_back( WColor( 0.3, 0.3, 0.3, 1.0 ) );
60 
61  ++m_leafCount;
63 }
64 
65 void WHierarchicalTreeFibers::addCluster( size_t cluster1, size_t cluster2, size_t level, std::vector<size_t> leafes, float customData )
66 {
67  m_leafesLocked = true;
68 
69  m_level.push_back( level );
70  m_maxLevel = std::max( m_maxLevel, level );
71 
72  m_parents.push_back( m_clusterCount );
73  m_containsLeafes.push_back( leafes );
74  m_customData.push_back( customData );
75  m_colors.push_back( WColor( 0.3, 0.3, 0.3, 1.0 ) );
76 
77  std::pair<size_t, size_t>childs( cluster1, cluster2 );
78  m_children.push_back( childs );
79 
80  m_parents[cluster1] = m_clusterCount;
81  m_parents[cluster2] = m_clusterCount;
82 
84 }
85 
86 std::shared_ptr< std::vector<bool> > WHierarchicalTreeFibers::getOutputBitfield( size_t cluster )
87 {
88  std::shared_ptr< std::vector< bool > > bf;
89  // only a single fiber selected
90  if( cluster < m_leafCount )
91  {
92  bf = std::shared_ptr< std::vector< bool > >( new std::vector< bool >( m_leafCount, false ) );
93  ( *bf )[cluster] = true;
94  }
95  else
96  {
97  if( cluster >= m_clusterCount )
98  {
99  return bf;
100  }
101 
102  bf = std::shared_ptr< std::vector< bool > >( new std::vector< bool >( m_leafCount, false ) );
103 
104  std::vector<size_t> fibers = m_containsLeafes[cluster];
105  for( size_t i = 0; i < fibers.size(); ++i )
106  {
107  ( *bf )[fibers[i]] = true;
108  }
109 
110  //std::cout << fibers.size() << " fibers selected" << std::endl;
111  }
112  return bf;
113 }
114 
115 std::shared_ptr< std::vector<bool> >WHierarchicalTreeFibers::getOutputBitfield( std::vector<size_t>clusters )
116 {
117  std::shared_ptr< std::vector< bool > > bf;
118  // only a single fiber selected
119 
120  bf = std::shared_ptr< std::vector< bool > >( new std::vector< bool >( m_leafCount, false ) );
121 
122  for( size_t k = 0; k < clusters.size(); ++k )
123  {
124  size_t cluster = clusters[k];
125  std::vector<size_t> fibers = m_containsLeafes[cluster];
126  for( size_t i = 0; i < fibers.size(); ++i )
127  {
128  ( *bf )[fibers[i]] = true;
129  }
130  }
131  return bf;
132 }
133 
134 std::vector<size_t> WHierarchicalTreeFibers::getBestClustersFittingRoi( float ratio, size_t number )
135 {
136  if( number == 0 )
137  {
138  number = 1;
139  }
140  std::list<size_t>candidateList;
141 
142  std::queue<size_t>worklist;
143  worklist.push( getClusterCount() - 1 );
144 
145  while( !worklist.empty() )
146  {
147  size_t current = worklist.front();
148  worklist.pop();
149 
150  if( getRatio( current ) >= ratio )
151  {
152  candidateList.push_back( current );
153  }
154  else
155  {
156  if( getLevel( current ) > 1 )
157  {
158  std::pair<size_t, size_t> children = getChildren( current );
159  if( getLevel( children.first ) > 0 )
160  {
161  worklist.push( children.first );
162  }
163  if( getLevel( children.second ) > 0 )
164  {
165  worklist.push( children.second );
166  }
167  }
168  }
169  }
170  candidateList.sort( compSize( this ) );
171 
172  std::vector<size_t>returnList;
173 
174  std::list<size_t>::iterator it;
175  for( it = candidateList.begin(); it != candidateList.end(); ++it )
176  {
177  size_t current = *it;
178  returnList.push_back( current );
179  --number;
180  if( number == 0 )
181  {
182  break;
183  }
184  }
185 
186 
187  return returnList;
188 }
189 
190 float WHierarchicalTreeFibers::getRatio( size_t cluster )
191 {
192  std::vector<size_t>fibersInCluster = m_containsLeafes[cluster];
193 
194  size_t countFibersInCluster = fibersInCluster.size();
195  size_t fibersFromClusterActive = 0;
196 
197  for( size_t i = 0; i < countFibersInCluster; ++i )
198  {
199  if( ( *m_roiSelection )[fibersInCluster[i]] )
200  {
201  ++fibersFromClusterActive;
202  }
203  }
204  return static_cast<float>( fibersFromClusterActive ) / static_cast<float>( countFibersInCluster );
205 }
void addCluster(size_t cluster1, size_t cluster2, size_t level, std::vector< size_t > leafes, float customData)
adds a cluster to the set, it combines 2 already existing clusters
std::shared_ptr< std::vector< bool > > m_roiSelection
stores a pointer to the bitfield by the current roi setting
std::shared_ptr< std::vector< bool > > getOutputBitfield(size_t cluster)
generates a bitfield where for every leaf in the selected cluster the value is true,...
std::vector< size_t > getBestClustersFittingRoi(float ratio=0.9, size_t number=1)
finds clusters that match a given ROI up to a certain percentage
WHierarchicalTreeFibers()
standard constructor
void addLeaf()
A leaf is at the very bottom of the tree, it represents a single fiber or voxel, for several purposes...
float getRatio(size_t cluster)
calculates the ratio of fibers in the roi for a given cluster
base class for hierarchical tree implementations
std::vector< float > m_customData
custom data for each cluster, this may some energy or similarity level generated by the clustering al...
std::vector< WColor > m_colors
a color value for each cluster
size_t m_clusterCount
overall number of cluster, counts both leafes ( clusters of size one ) and real clusters
std::vector< std::pair< size_t, size_t > > m_children
vector that stores the 2 children of each cluster, contains an empty pair for leafes
std::pair< size_t, size_t > getChildren(size_t cluster) const
getter
std::vector< size_t > m_parents
vector that stores the parent cluster for each cluster
size_t m_leafCount
number of leaf nodes
size_t m_maxLevel
the maximum level, naturally the level of the root node
size_t getLevel(size_t cluster) const
getter
std::vector< size_t > m_level
vector that stores the level of each cluster, the level is the maximum of the levels of the child clu...
bool m_leafesLocked
to enforce valid datastructures there will be no leaf with an id higher than a cluster,...
std::vector< std::vector< size_t > > m_containsLeafes
vector that stores the leaf id's for each cluster, this is quite memory intensive but speeds up selec...
size_t getClusterCount() const
getter
implements a compare operator for clusters, depending on leaf count