OpenWalnut  1.4.0
WFiberCluster.h
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 #ifndef WFIBERCLUSTER_H
26 #define WFIBERCLUSTER_H
27 
28 #include <list>
29 #include <string>
30 #include <vector>
31 
32 #include <boost/shared_ptr.hpp>
33 #include <boost/thread.hpp>
34 
35 #include "../../common/WColor.h"
36 #include "../../common/WTransferable.h"
37 #include "../WDataSetFiberVector.h"
38 
39 
40 /**
41  * Represents a cluster of indices of a WDataSetFiberVector.
42  */
43 class WFiberCluster: public WTransferable // NOLINT
44 {
45 friend class WFiberClusterTest;
46 public:
47  /**
48  * Shared pointer abbreviation.
49  */
50  typedef boost::shared_ptr< WFiberCluster > SPtr;
51 
52  /**
53  * Const shared pointer abbreviation.
54  */
55  typedef boost::shared_ptr< const WFiberCluster > ConstSPtr;
56 
57  /**
58  * This is the list of indices of fibers.
59  */
60  typedef std::list< size_t > IndexList;
61 
62  /**
63  * Const iterator on the index list.
64  */
65  typedef IndexList::const_iterator IndexListConstIterator;
66 
67  /**
68  * Constructs an cluster with one fiber and a reference to the fiber dataset
69  * to compute the intercluster distance.
70  *
71  * \param index The index of the first fiber belonging to this cluster
72  */
73  explicit WFiberCluster( size_t index );
74 
75  /**
76  * Constructs a cluster with the specified set of indices and the given color.
77  *
78  * \param indices the indices initially used for this clustering
79  * \param color the color of this cluster
80  */
81  WFiberCluster( const IndexList& indices, const WColor& color = WColor() );
82 
83  /**
84  * Constructs a clustering with the given set of indices. The indexlist is generated using the given iterators. It copies the elements in
85  * [indicesBegin,indicesEnd).
86  *
87  * \param indicesBegin begin iterator in the predefined index set
88  * \param indicesEnd end iterator in the predefined index set
89  * \param color the color of this cluster
90  */
91  WFiberCluster( IndexListConstIterator indicesBegin,
92  IndexListConstIterator indicesEnd, const WColor& color = WColor() );
93 
94  /**
95  * Copies the specified \ref WFiberCluster Instance. The copy does not contain a valid centerline or longest line.
96  *
97  * \param other the other instance to clone.
98  */
99  WFiberCluster( const WFiberCluster& other );
100 
101  /**
102  * Constructs an empty cluster.
103  */
104  WFiberCluster();
105 
106  /**
107  * Destructs. Frees used locks/mutex.
108  */
109  virtual ~WFiberCluster();
110 
111  /**
112  * Returns true if there are no fibers in that cluster, false otherwise.
113  *
114  * \return true if empty
115  */
116  bool empty() const;
117 
118  /**
119  * Merge the fibers of the other cluster with the fibers of this cluster.
120  * Afterwards the other cluster is empty.
121  *
122  * \param other The other WFiberCluster which should merged into this one
123  */
124  void merge( WFiberCluster &other ); // NOLINT
125 
126  /**
127  * Copy the elements denoted by the two iterators to this cluster. In contrast to the other merge() methods, this will not clean the source
128  * list.
129  *
130  * \param indicesBegin begin iterator in the predefined index set
131  * \param indicesEnd end iterator in the predefined index set
132  */
133  void merge( IndexListConstIterator indicesBegin, IndexListConstIterator indicesEnd );
134 
135  /**
136  * Returns a const reference of all indices inside this cluster
137  *
138  * \return the index list
139  */
140  const IndexList& getIndices() const;
141 
142  /**
143  * Reset the indices belonging to that cluster
144  *
145  * \param indices list of indices
146  */
147  void setIndices( const IndexList& indices );
148 
149  /**
150  * Sort the indices of fibers associated with this cluster in ascending
151  * order.
152  */
153  void sort();
154 
155  /**
156  * \return Number of fibers associated with this cluster.
157  */
158  size_t size() const;
159 
160  /**
161  * Make this cluster empty. Note: The real fibers from fiber dataset are
162  * not deleted.
163  */
164  void clear();
165 
166  /**
167  * Sets the color of which all fibers of this clusters should be painted
168  * with.
169  *
170  * \param color The color for all fibers of this cluster.
171  */
172  void setColor( WColor color );
173 
174  /**
175  * Gets the color of which all fibers of this clusters should be painted
176  * with.
177  *
178  * \return cluster color.
179  */
180  WColor getColor() const;
181 
182  /**
183  * Sets the main direction of the cluster
184  *
185  * \param mainDirection the cluster's main direction
186  */
187  void setMainDirection( osg::Vec3 mainDirection );
188 
189  /**
190  * Gets the main direction of the cluster ( if set )
191  *
192  * \return the cluster's main direction
193  */
194  osg::Vec3 getMainDirection() const;
195 
196  /**
197  * The name of this transferable. This is useful information for the users.
198  *
199  * \return the name.
200  */
201  virtual const std::string getName() const;
202 
203  /**
204  *
205  * The description of this transferable. This is useful information for the users.
206  *
207  * \return A description
208  */
209  virtual const std::string getDescription() const;
210 
211  /**
212  * \param other The other fiber which should be compared
213  * \return true If both clusters having same fibers IN SAME ORDER!
214  */
215  bool operator==( const WFiberCluster& other ) const;
216 
217  /**
218  * The opposite of the operator==
219  *
220  * \param other The other fiber which should be compared
221  * \return false If both clusters having same fibers IN SAME ORDER!
222  */
223  bool operator!=( const WFiberCluster& other ) const;
224 
225  /**
226  * Copy assignment operator which does NOT copy the mutex's!!!
227  *
228  * \param other The instance to copy.
229  *
230  * \return itself
231  */
233  {
234  WTransferable::operator=( other );
236  m_fibs = other.m_fibs;
237  m_color = other.m_color;
238  m_centerLineCreationLock = new boost::shared_mutex();
239  m_longestLineCreationLock = new boost::shared_mutex();
240  // copy them only if they exist
241  if( other.m_centerLine )
242  {
243  m_centerLine = boost::shared_ptr< WFiber >( new WFiber( *other.m_centerLine.get() ) );
244  }
245  if( other.m_longestLine )
246  {
247  m_longestLine = boost::shared_ptr< WFiber >( new WFiber( *other.m_longestLine.get() ) );
248  }
249  return *this;
250  }
251 
252  // TODO(math): The only reason why we store here a Reference to the fiber
253  // dataset is, we need it in the WMVoxelizer module as well as the clustering
254  // information. Since we don't have the possibility of multiple
255  // InputConnectors we must agglomerate those into one object. Please remove this.
256  // \cond Suppress_Doxygen
257  void setDataSetReference( boost::shared_ptr< const WDataSetFiberVector > fibs );
258  boost::shared_ptr< const WDataSetFiberVector > getDataSetReference() const;
259  // \endcond
260 
261  /**
262  * Returns a prototype instantiated with the true type of the deriving class.
263  *
264  * \return the prototype.
265  */
266  static boost::shared_ptr< WPrototyped > getPrototype();
267 
268  /**
269  * Returns the center line of this cluster. The centerline gets calculated during the first call of this method.
270  *
271  * \return Reference to the center line
272  */
273  boost::shared_ptr< WFiber > getCenterLine() const;
274 
275  /**
276  * Returns the center line of this cluster. The longest line gets calculated during the first call if this method.
277  *
278  * \return Reference to the longest line
279  */
280  boost::shared_ptr< WFiber > getLongestLine() const;
281 
282  /**
283  * Makes the hard work to compute the center line.
284  */
285  void generateCenterLine() const;
286 
287  /**
288  * Makes the hard work to find the longest line.
289  */
290  void generateLongestLine() const;
291 
292  /**
293  * Recomputes on every call the axis aligned bounding box incorporating all tracts in this cluster.
294  *
295  * \return AABB as WBoundingBox.
296  */
298 
299 protected:
300  /**
301  * Prototype for this dataset
302  */
303  static boost::shared_ptr< WPrototyped > m_prototype;
304 
305  /**
306  * Alings all fibers within the given dataset to be in one main direction. But Alignment only may swap the ordering of the fibers
307  * but not the positions or something similar. We need this only for the centerline generation.
308  *
309  * \param fibs The dataset
310  */
311  void unifyDirection( boost::shared_ptr< WDataSetFiberVector > fibs ) const;
312 
313 private:
314  /**
315  * The centerline may be shortened due to the averaging of outliers. To
316  * nevertheless color almost the whole bundle surface we need a surface
317  * parameterization (given via the centerline) upto the endings of the
318  * bundle. Therefore the centerline is stepwise elongated with the last
319  * known direction, until no perpendicular plane intersects any of the
320  * tracts inside of the bundle.
321  */
322  void elongateCenterLine() const;
323 
324  /**
325  * All indices in this set are members of this cluster
326  */
327  IndexList m_memberIndices;
328 
329  // TODO(math): The only reason why we store here a Reference to the fiber
330  // dataset is, we need it in the WMVoxelizer module as well as the clustering
331  // information. Since we don't have the possibility of multiple
332  // InputConnectors we must agglomerate those into one object. Please remove this.
333  /**
334  * Reference to the real fibers of the brain this cluster belongs to.
335  */
336  boost::shared_ptr< const WDataSetFiberVector > m_fibs;
337 
338  /**
339  * Color which is used to paint the members of this cluster.
340  */
341  WColor m_color;
342 
343  /**
344  * The cluster's main direction
345  */
346  osg::Vec3 m_mainDirection;
347 
348  /**
349  * Lock the modification in the m_centerLine mutable. The lock is stored as pointer to avoid copy construction problems.
350  */
351  boost::shared_mutex* m_centerLineCreationLock;
352 
353  /**
354  * Lock the modification in the m_longestLine mutable. The lock is stored as pointer to avoid copy construction problems.
355  */
356  boost::shared_mutex* m_longestLineCreationLock;
357 
358  /**
359  * Average fiber for this cluster representing the main direction and curvature of this cluster.
360  *
361  * \note This member is mutable as it needs to be modified during a const getter.
362  */
363  mutable boost::shared_ptr< WFiber > m_centerLine;
364 
365  /**
366  * The longest fiber in the dataset.
367  *
368  * \note This member is mutable as it needs to be modified during a const getter.
369  */
370  mutable boost::shared_ptr< WFiber > m_longestLine;
371 };
372 
373 inline bool WFiberCluster::empty() const
374 {
375  return m_memberIndices.empty();
376 }
377 
378 inline void WFiberCluster::sort()
379 {
380  m_memberIndices.sort();
381 }
382 
383 inline size_t WFiberCluster::size() const
384 {
385  return m_memberIndices.size();
386 }
387 
388 inline void WFiberCluster::clear()
389 {
390  m_memberIndices.clear();
391 }
392 
393 inline void WFiberCluster::setColor( WColor color )
394 {
395  m_color = color;
396 }
397 
398 inline WColor WFiberCluster::getColor() const
399 {
400  return m_color;
401 }
402 
403 inline void WFiberCluster::setMainDirection( osg::Vec3 mainDirection )
404 {
405  m_mainDirection = mainDirection;
406 }
407 
408 inline osg::Vec3 WFiberCluster::getMainDirection() const
409 {
410  return m_mainDirection;
411 }
412 
413 inline const std::string WFiberCluster::getName() const
414 {
415  return "FiberCluster";
416 }
417 
418 inline const std::string WFiberCluster::getDescription() const
419 {
420  return "A collection of indices for fibers representing a fiber cluster";
421 }
422 
423 inline bool WFiberCluster::operator==( const WFiberCluster& other ) const
424 {
425  return m_memberIndices == other.m_memberIndices;
426 }
427 
428 inline bool WFiberCluster::operator!=( const WFiberCluster& other ) const
429 {
430  return m_memberIndices != other.m_memberIndices;
431 }
432 
434 {
435  return m_memberIndices;
436 }
437 
439 {
440  m_memberIndices = indices;
441 }
442 
443 inline std::ostream& operator<<( std::ostream& os, const WFiberCluster& c )
444 {
445  using string_utils::operator<<;
446  return os << c.getIndices();
447 }
448 
449 #endif // WFIBERCLUSTER_H
bool operator!=(const WFiberCluster &other) const
The opposite of the operator==.
virtual ~WFiberCluster()
Destructs.
Unit test the WFiberCluster class.
const IndexList & getIndices() const
Returns a const reference of all indices inside this cluster.
Represents a neural pathway.
Definition: WFiber.h:39
boost::shared_ptr< WFiber > m_centerLine
Average fiber for this cluster representing the main direction and curvature of this cluster...
void elongateCenterLine() const
The centerline may be shortened due to the averaging of outliers.
Represents a cluster of indices of a WDataSetFiberVector.
Definition: WFiberCluster.h:43
void sort()
Sort the indices of fibers associated with this cluster in ascending order.
boost::shared_ptr< WFiber > getCenterLine() const
Returns the center line of this cluster.
std::list< size_t > IndexList
This is the list of indices of fibers.
Definition: WFiberCluster.h:60
boost::shared_mutex * m_centerLineCreationLock
Lock the modification in the m_centerLine mutable.
WColor getColor() const
Gets the color of which all fibers of this clusters should be painted with.
bool operator==(const WFiberCluster &other) const
WBoundingBox getBoundingBox() const
Recomputes on every call the axis aligned bounding box incorporating all tracts in this cluster...
WColor m_color
Color which is used to paint the members of this cluster.
osg::Vec3 m_mainDirection
The cluster's main direction.
void merge(WFiberCluster &other)
Merge the fibers of the other cluster with the fibers of this cluster.
bool empty() const
Returns true if there are no fibers in that cluster, false otherwise.
Class building the interface for classes that might be transferred using WModuleConnector.
Definition: WTransferable.h:37
IndexList m_memberIndices
All indices in this set are members of this cluster.
void setIndices(const IndexList &indices)
Reset the indices belonging to that cluster.
void unifyDirection(boost::shared_ptr< WDataSetFiberVector > fibs) const
Alings all fibers within the given dataset to be in one main direction.
void setMainDirection(osg::Vec3 mainDirection)
Sets the main direction of the cluster.
virtual const std::string getDescription() const
The description of this transferable.
void clear()
Make this cluster empty.
void generateCenterLine() const
Makes the hard work to compute the center line.
WFiberCluster & operator=(const WFiberCluster &other)
Copy assignment operator which does NOT copy the mutex's!!!
size_t size() const
boost::shared_ptr< WFiberCluster > SPtr
Shared pointer abbreviation.
Definition: WFiberCluster.h:50
boost::shared_ptr< WFiber > m_longestLine
The longest fiber in the dataset.
boost::shared_ptr< const WFiberCluster > ConstSPtr
Const shared pointer abbreviation.
Definition: WFiberCluster.h:55
static boost::shared_ptr< WPrototyped > getPrototype()
Returns a prototype instantiated with the true type of the deriving class.
boost::shared_mutex * m_longestLineCreationLock
Lock the modification in the m_longestLine mutable.
void generateLongestLine() const
Makes the hard work to find the longest line.
static boost::shared_ptr< WPrototyped > m_prototype
Prototype for this dataset.
boost::shared_ptr< WFiber > getLongestLine() const
Returns the center line of this cluster.
boost::shared_ptr< const WDataSetFiberVector > m_fibs
Reference to the real fibers of the brain this cluster belongs to.
void setColor(WColor color)
Sets the color of which all fibers of this clusters should be painted with.
IndexList::const_iterator IndexListConstIterator
Const iterator on the index list.
Definition: WFiberCluster.h:65
virtual const std::string getName() const
The name of this transferable.
osg::Vec3 getMainDirection() const
Gets the main direction of the cluster ( if set )
WFiberCluster()
Constructs an empty cluster.