OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
WThreadedTrackingFunction.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 WTHREADEDTRACKINGFUNCTION_H
26 #define WTHREADEDTRACKINGFUNCTION_H
27 
28 #include <vector>
29 #include <utility>
30 
31 #include <boost/array.hpp>
32 
33 #include "../common/math/linearAlgebra/WLinearAlgebra.h"
34 #include "../common/WSharedObject.h"
35 #include "../common/WThreadedJobs.h"
36 #include "WExportDataHandler.h"
37 #include "WDataSetSingle.h"
38 
39 class WThreadedTrackingFunctionTest; //! forward declaration
40 
41 
42 /**
43  * For tracking related functionality.
44  */
45 namespace wtracking // note that this is not final
46 {
47  // an epsilon value for various floating point comparisons
48 #define TRACKING_EPS 0.0000001
49 
50  /**
51  * \class WTrackingUtility
52  *
53  * A class that provides untility functions and typedefs for tracking algorithms.
54  */
56  {
57  public:
58 
59  //! define a job type for tracking algorithms
60  typedef std::pair< WVector3d, WVector3d > JobType;
61 
62  //! the dataset type
64 
65  //! a pointer to a dataset
66  typedef boost::shared_ptr< DataSetType const > DataSetPtr;
67 
68  //! a function that calculates a direction to continue tracking
69  typedef boost::function< WVector3d ( DataSetPtr, JobType const& ) > DirFunc;
70 
71  //! a pointer to a regular 3d grid
72  // other grid types are not supported at the moment
73  typedef boost::shared_ptr< WGridRegular3D > Grid3DPtr;
74 
75  /**
76  * A function that follows a direction until leaving the current voxel.
77  *
78  * \param dataset A pointer to the input dataset.
79  * \param job A pair of vectors, the position and the direction of the last integration.
80  * \param dirFunc A function that computes the next direction.
81  *
82  * \return true, iff the calculated point is a valid position inside the grid
83  */
84  static bool followToNextVoxel( DataSetPtr dataset, JobType& job, DirFunc const& dirFunc );
85 
86  // one could add a runge-kutta-integrator too
87 
88  /**
89  * Check if a point is on the boundary of the given grid, where boundary
90  * means a distance less then TRACKING_EPS from any plane between
91  * voxels. This does not check if the position is actually inside the grid.
92  *
93  * \param grid The grid.
94  * \param pos The position to test.
95  *
96  * \return true, iff the position is on any voxel boundary
97  */
98  static bool onBoundary( Grid3DPtr grid, WVector3d const& pos );
99 
100  /**
101  * Calculate the distance from a given position to the nearest voxel boundary
102  * on the ray from the position along the given direction.
103  *
104  * \param grid The grid.
105  * \param pos The starting position of the ray.
106  * \param dir The normalized direction of the ray.
107  *
108  * \return The distance to the next voxel boundary.
109  *
110  * \note pos + getDistanceToBoundary( grid, pos, dir ) * dir will be a position on a voxel boundary
111  */
112  static double getDistanceToBoundary( Grid3DPtr grid, WVector3d const& pos, WVector3d const& dir );
113  };
114 
115  //////////////////////////////////////////////////////////////////////////////////////////
116 
117  /**
118  * \class WThreadedTrackingFunction
119  *
120  * Implements a generalized multithreaded tracking algorithm. A function that calculates the direction
121  * and a function that calculates a new position have to be provided.
122  *
123  * Output values can be retrieved via two visitor functions that get called per fiber tracked and
124  * per point calculated respectively.
125  *
126  * There are a certain number n of seeds per direction, this meens n*n*n seeds per voxel. For every
127  * seed, m fibers get integrated. These two parameters are the seedPositions and seedsPerVoxel parameters
128  * of the constructor, respectively.
129  *
130  * A 'cubic' region of the grid can be chosen for seeding. The v0 and v1 parameters of the constructor
131  * are the starting/target voxel coords. Example:
132  *
133  * v0: 1, 1, 1
134  * v1: 4, 5, 3
135  *
136  * In this case, only voxels between coords 1 to 3 in the x-direction, the voxels 1 to 4 in y- and the voxels 1 to 2
137  * in z-direction are used for seeding.
138  *
139  * Note that voxels at the first (0) and last (grid->getNbCoords*()) position in any direction are
140  * invalid seeding voxels as they are partially outside of the grid.
141  */
142  class OWDATAHANDLER_EXPORT WThreadedTrackingFunction : public WThreadedJobs< WTrackingUtility::DataSetType, WTrackingUtility::JobType >
143  {
144  //! make the test a friend
145  friend class ::WThreadedTrackingFunctionTest;
146 
147  //! the job type
149 
150  //! the dataset type
152 
153  //! a pointer to a dataset
155 
156  //! the grid type
158 
159  //! a pointer to the grid
160  typedef boost::shared_ptr< GridType > GridPtr;
161 
162  //! the direction calculation function
164 
165  //! the path integration function
166  typedef boost::function< bool ( DataSetPtr, JobType&, DirFunc const& ) > NextPositionFunc;
167 
168  //! a visitor function for fibers
169  typedef boost::function< void ( std::vector< WVector3d > const& ) > FiberVisitorFunc;
170 
171  //! a visitor function type for points
172  typedef boost::function< void ( WVector3d const& ) > PointVisitorFunc;
173 
174  //! the base class, a threaded job function
176 
177  //! this type
179 
180  public:
181  /**
182  * Constructor.
183  *
184  * \param dataset A pointer to a dataset.
185  * \param dirFunc A direction calculation function.
186  * \param nextFunc A position integration function.
187  * \param fiberVst A visitor for fibers.
188  * \param pointVst A visitor for points.
189  * \param seedPositions The number of seed positions in every direction per voxel.
190  * \param seedsPerPos The number of fibers startet from every seed position.
191  * \param v0 A vector of starting voxel indices for every direction.
192  * \param v1 A vector of target voxel indices for every direction.
193  */
194  WThreadedTrackingFunction( DataSetPtr dataset, DirFunc dirFunc, NextPositionFunc nextFunc,
195  FiberVisitorFunc fiberVst, PointVisitorFunc pointVst,
196  std::size_t seedPositions = 1, std::size_t seedsPerPos = 1,
197  std::vector< int > v0 = std::vector< int >(),
198  std::vector< int > v1 = std::vector< int >() );
199 
200  /**
201  * Destructor.
202  */
203  virtual ~WThreadedTrackingFunction();
204 
205  /**
206  * The job generator.
207  *
208  * \param job The next job (output).
209  *
210  * \return false, iff there are no more jobs.
211  */
212  virtual bool getJob( JobType& job ); // NOLINT
213 
214  /**
215  * The calculation per job.
216  *
217  * \param input The input dataset.
218  * \param job The job.
219  */
220  virtual void compute( DataSetPtr input, JobType const& job );
221 
222  private:
223  /**
224  * \class IndexType
225  *
226  * An index for seed positions.
227  */
228  class IndexType
229  {
230  friend class ::WThreadedTrackingFunctionTest;
231  public:
232  /**
233  * Construct an invalid index.
234  */
235  IndexType();
236 
237  /**
238  * Construct an index.
239  *
240  * \param grid The grid.
241  * \param v0 A vector of starting voxel indices for every direction.
242  * \param v1 A vector of target voxel indices for every direction.
243  * \param seedPositions The number of seed positions in every direction per voxel.
244  * \param seedsPerPosition The number of fibers startet from every seed position.
245  */
246  IndexType( GridPtr grid, std::vector< int > const& v0,
247  std::vector< int > const& v1, std::size_t seedPositions,
248  std::size_t seedsPerPosition );
249 
250  /**
251  * Increase the index by one, effectively generating the next seed position.
252  *
253  * \return *this
254  */
255  IndexType& operator++ ();
256 
257  /**
258  * Check if there aren't any more seed positions.
259  *
260  * \return true, iff there aren't any more seed positions.
261  */
262  bool done();
263 
264  /**
265  * Create a job from this index.
266  *
267  * \return The job that is the current position.
268  */
269  JobType job();
270 
271  private:
272  //! a pointer to the grid
274 
275  //! true, iff there are no more seeds
276  bool m_done;
277 
278  //! the position in the seed space
279  boost::array< std::size_t, 4 > m_pos;
280 
281  //! the minimum position in the seed space
282  boost::array< std::size_t, 4 > m_min;
283 
284  //! the maximum position in the seed space
285  boost::array< std::size_t, 4 > m_max;
286 
287  //! the relative (to the size of a voxel) distance between seeds
288  double m_offset;
289  };
290 
291  //! a pointer to the grid
293 
294  //! a function that returns the next direction
296 
297  //! a function that calculates the next position
299 
300  //! the fiber visitor
302 
303  //! the point visitor
305 
306  //! the maximum number of points per forward/backward integration of a fiber
307  std::size_t m_maxPoints;
308 
309  //! the current index/seed position
311  };
312 
313 } /* namespace wtracking */
314 
315 #endif // WTHREADEDTRACKINGFUNCTION_H