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