OpenWalnut  1.5.0dev
WMHARDIToSphericalHarmonics.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 WMHARDITOSPHERICALHARMONICS_H
26 #define WMHARDITOSPHERICALHARMONICS_H
27 
28 #include <map>
29 #include <memory>
30 #include <string>
31 #include <utility>
32 #include <vector>
33 
34 #include "WSphericalHarmonicsCoefficientsThread.h"
35 #include "core/common/WThreadedRunner.h"
36 #include "core/common/math/WMatrix.h"
37 #include "core/dataHandler/WDataSetRawHARDI.h"
38 #include "core/dataHandler/WDataSetSphericalHarmonics.h"
39 #include "core/dataHandler/WGridRegular3D.h"
40 #include "core/kernel/WModule.h"
41 #include "core/kernel/WModuleInputData.h"
42 #include "core/kernel/WModuleOutputData.h"
43 
44 // forward declaration
45 template< typename T >
47 
48 /**
49  * Module for the creation of a spherical harmonic data set from raw HARDI data.
50  * \ingroup modules
51  */
53 {
54 /**
55  * Only UnitTests may be friends.
56  */
58 
59 public:
60  /**
61  * Standard constructor.
62  */
64 
65  /**
66  * Destructor.
67  */
69 
70  /**
71  * Gives back the name of this module.
72  * \return the module's name.
73  */
74  virtual const std::string getName() const;
75 
76  /**
77  * Gives back a description of this module.
78  * \return description of module.
79  */
80  virtual const std::string getDescription() const;
81 
82  /**
83  * Due to the prototype design pattern used to build modules, this method returns a new instance of this method. NOTE: it
84  * should never be initialized or modified in some other way. A simple new instance is required.
85  *
86  * \return the prototype used to create every module in OpenWalnut.
87  */
88  virtual std::shared_ptr< WModule > factory() const;
89 
90  /**
91  * Get the icon for this module in XPM format.
92  * \return The icon.
93  */
94  virtual const char** getXPMIcon() const;
95 
96  // TODO(philips): can we move this method to private or at least protected
97  /**
98  * Stop the threads.
99  */
100  void stopThreads();
101 
102 protected:
103  /**
104  * Entry point after loading the module. Runs in separate thread.
105  */
106  virtual void moduleMain();
107 
108  /**
109  * Initialize the connectors this module is using.
110  */
111  virtual void connectors();
112 
113  /**
114  * Initialize the properties for this module.
115  */
116  virtual void properties();
117 
118 private:
119  std::shared_ptr< WItemSelection > m_reconstructionTypes; //!< A list of the selectable reconstruction types.
120  WPropSelection m_reconstructionTypeProp; //!< To choose the reconstruction type.
121 
122  WPropInt m_order; //!< Property holding the order of the spherical harmonics
123 
124  WPropDouble m_regularisationFactorLambda; //!< Property holding the regularisation factor lambda
125 
126  WPropBool m_doFunkRadonTransformation; //!< Property indicating whether to do the Funk-Radon-transformation with calculated spherical harmonics.
127 
128  WPropBool m_doErrorCalculation; //!< Property indicating whether a reprojection error of the spherical harmonics is calculated.
129 
130  /**
131  * Property indicating whether the reprojection error (measurement relative to spherical harmonic calculation) is stored into a separate dataset.
132  */
134 
135  /**
136  * Property indicating whether the spherical harmonics calculation is done multithreaded.
137  */
138  WPropBool m_multiThreaded;
139 
140  /**
141  * Property indicating whether the measurements are normalized from 0 to 1 for each voxel.
142  */
143  WPropBool m_doNormalisation;
144 
145  WPropDouble m_CSADelta1; //!< Delta1 value for the constant solid angle reconstruction.
146 
147  WPropDouble m_CSADelta2; //!< Delta2 value for the constant solid angle reconstruction.
148  /**
149  * This is a pointer to the dataset the module is currently working on.
150  */
151  std::shared_ptr< WDataSetRawHARDI > m_dataSet;
152 
153  /**
154  * Input connector required by this module. The HARDI measurements.
155  */
156  std::shared_ptr< WModuleInputData< WDataSetRawHARDI > > m_input;
157 
158  /**
159  * Output connector provided by this module. The calculated spherical harmonics.
160  */
161  std::shared_ptr< WModuleOutputData< WDataSetSphericalHarmonics > > m_output;
162 
163  /**
164  * The reprojection error for each measurement.
165  */
166  std::shared_ptr< WModuleOutputData< WDataSetRawHARDI > > m_outputResiduals;
167 
168  /**
169  * A condition used to notify about changes in several properties.
170  */
171  std::shared_ptr< WCondition > m_propCondition;
172 
173  /**
174  * This class is derived from PropertyConstraint and ensures that only even values are valid.
175  */
176  class evenInt: public WPropertyVariable< WPVBaseTypes::PV_INT >::PropertyConstraint
177  {
178  /**
179  * You need to overwrite this method. It decides whether the specified new value should be accepted or not.
180  *
181  * \param property the property thats going to be changed.
182  * \param value the new value
183  *
184  * \return true if the new value is OK.
185  */
186  virtual bool accept( std::shared_ptr< WPropertyVariable< WPVBaseTypes::PV_INT > > property, const WPVBaseTypes::PV_INT& value );
187 
188  /**
189  * Method to clone the constraint and create a new one with the correct dynamic type.
190  *
191  * \return the constraint.
192  */
193  virtual std::shared_ptr< WPropertyVariable< WPVBaseTypes::PV_INT >::PropertyConstraint > clone();
194  };
195 
196  /**
197  * \class HARDICalculation
198  *
199  * Functor that does multithreaded spherical harmonic fitting.
200  *
201  * This functor provides a template operator() that has the type of the values stored in the valueset
202  * as a template parameter. WValueSet's applyFunction will call the version with the correct type.
203  */
204  class HARDICalculation;
205 };
206 
207 class WMHARDIToSphericalHarmonics::HARDICalculation : public boost::static_visitor< std::pair< std::shared_ptr< WDataSetSphericalHarmonics >,
208  std::shared_ptr< WDataSetRawHARDI > > >
209 {
210 public:
211  /**
212  * Constructor.
213  *
214  * \param threadParams The partially initialised thread parameter struct that will be forwarded to the worker threads.
215  * \param multiThreaded If true, the maximum number of threads should be used.
216  * \param grid The grid of the input data.
217  * \param gradients The gradients of the hardi data.
218  */
220  std::shared_ptr< WGrid > grid, std::vector< WVector3d > const& gradients );
221 
222  /**
223  * Destructor.
224  */
226 
227  /**
228  * Allocate shared memory and construct and run threads, construct output datasets.
229  *
230  * \tparam T The integral type of values in the valueset.
231  *
232  * \return result value
233  */
234  template< typename T >
235  result_type operator() ( WValueSet< T > const* /* vs */ ) const;
236 
237 private:
238  //! The parameters that will be forwarded to the threads.
240 
241  //! If more than 1 thread should be used.
243 
244  //! The grid of the data.
245  std::shared_ptr< WGrid > m_grid;
246 
247  //! The gradients of the hardi data.
248  std::vector< WVector3d > const& m_gradients;
249 };
250 
251 template< typename T >
252 WMHARDIToSphericalHarmonics::HARDICalculation::result_type
254 {
255  // the number of coeffs for the spherical harmonics of the given order
256  int dimension = ( m_parameter.m_order + 1 ) * ( m_parameter.m_order + 2 ) / 2;
257  size_t voxelCount = m_parameter.m_valueSet->size();
258 
260 
261  // data vector stores spherical harmonics coefficients
262  parameter.m_data = std::shared_ptr< std::vector< double > >( new std::vector< double >( voxelCount * dimension ) );
263 
264  const unsigned int threadCount = m_multiThreaded ?
265  ( boost::thread::hardware_concurrency() == 0 ? 1 : boost::thread::hardware_concurrency() ) : 1;
266 
267  // data vector to store reprojection residuals
268  if( parameter.m_doResidualCalculation )
269  {
270  parameter.m_dataResiduals = std::shared_ptr< std::vector< double > >(
271  new std::vector< double >( parameter.m_valueSet->size() * parameter.m_validIndices.size() ) );
272  }
273 
274  std::pair< size_t, size_t > range;
275 
276  typename std::vector< WSphericalHarmonicsCoefficientsThread< T >* > threads;
277 
278  // create Threads
279  for( unsigned int i = 0; i < threadCount; i++ )
280  {
281  range.first = ( voxelCount / threadCount ) * i;
282  range.second = ( i == ( threadCount - 1 ) ) ? voxelCount : ( voxelCount / threadCount ) * ( i + 1 );
283  threads.push_back( new WSphericalHarmonicsCoefficientsThread< T >( parameter, range ) );
284  threads.back()->run();
285  }
286 
287  for( unsigned int i = 0; i < threads.size(); i++ )
288  {
289  threads[ i ]->wait();
290  delete threads[ i ];
291  }
292 
293  threads.clear();
294 
295  parameter.m_progress->finish();
296 
297  result_type result;
298 
299  // create final output data
300  std::shared_ptr< WValueSet< double > > sphericalHarmonicsData
301  = std::shared_ptr< WValueSet< double > >( new WValueSet< double >( 1, dimension, parameter.m_data, W_DT_DOUBLE ) );
302 
303  result.first = std::shared_ptr< WDataSetSphericalHarmonics >(
304  new WDataSetSphericalHarmonics( sphericalHarmonicsData, m_grid ) );
305 
306  if( parameter.m_doResidualCalculation )
307  {
308  std::shared_ptr< WValueSet< double > > residualsData = std::shared_ptr< WValueSet< double > >(
309  new WValueSet< double >( 1, parameter.m_validIndices.size(), parameter.m_dataResiduals, W_DT_DOUBLE ) );
310 
311  result.second = std::shared_ptr< WDataSetRawHARDI >( new WDataSetRawHARDI( residualsData, m_grid,
312  std::shared_ptr< std::vector< WVector3d > >(
313  new std::vector< WVector3d >( m_gradients ) ) ) );
314  }
315 
316  return result;
317 }
318 
319 #endif // WMHARDITOSPHERICALHARMONICS_H
This data set type contains raw HARDI and its gradients.
This data set type contains spherical harmonic coefficients as values.
Functor that does multithreaded spherical harmonic fitting.
std::vector< WVector3d > const & m_gradients
The gradients of the hardi data.
WSphericalHarmonicsCoefficientsThread ::ThreadParameter m_parameter
The parameters that will be forwarded to the threads.
result_type operator()(WValueSet< T > const *) const
Allocate shared memory and construct and run threads, construct output datasets.
std::shared_ptr< WGrid > m_grid
The grid of the data.
bool m_multiThreaded
If more than 1 thread should be used.
HARDICalculation(WSphericalHarmonicsCoefficientsThread<>::ThreadParameter threadParams, bool multiThreaded, std::shared_ptr< WGrid > grid, std::vector< WVector3d > const &gradients)
Constructor.
This class is derived from PropertyConstraint and ensures that only even values are valid.
virtual bool accept(std::shared_ptr< WPropertyVariable< WPVBaseTypes::PV_INT > > property, const WPVBaseTypes::PV_INT &value)
You need to overwrite this method.
virtual std::shared_ptr< WPropertyVariable< WPVBaseTypes::PV_INT >::PropertyConstraint > clone()
Method to clone the constraint and create a new one with the correct dynamic type.
Module for the creation of a spherical harmonic data set from raw HARDI data.
virtual std::shared_ptr< WModule > factory() const
Due to the prototype design pattern used to build modules, this method returns a new instance of this...
virtual const std::string getName() const
Gives back the name of this module.
WPropInt m_order
Property holding the order of the spherical harmonics.
std::shared_ptr< WModuleOutputData< WDataSetSphericalHarmonics > > m_output
Output connector provided by this module.
WPropBool m_doNormalisation
Property indicating whether the measurements are normalized from 0 to 1 for each voxel.
WPropSelection m_reconstructionTypeProp
To choose the reconstruction type.
std::shared_ptr< WDataSetRawHARDI > m_dataSet
This is a pointer to the dataset the module is currently working on.
std::shared_ptr< WModuleInputData< WDataSetRawHARDI > > m_input
Input connector required by this module.
virtual void properties()
Initialize the properties for this module.
WPropBool m_doResidualCalculation
Property indicating whether the reprojection error (measurement relative to spherical harmonic calcul...
WMHARDIToSphericalHarmonics()
Standard constructor.
std::shared_ptr< WCondition > m_propCondition
A condition used to notify about changes in several properties.
virtual const std::string getDescription() const
Gives back a description of this module.
WPropBool m_doFunkRadonTransformation
Property indicating whether to do the Funk-Radon-transformation with calculated spherical harmonics.
virtual void moduleMain()
Entry point after loading the module.
WPropDouble m_CSADelta1
Delta1 value for the constant solid angle reconstruction.
friend class WMHARDIToSphericalHarmonicsTest
Only UnitTests may be friends.
WPropBool m_doErrorCalculation
Property indicating whether a reprojection error of the spherical harmonics is calculated.
std::shared_ptr< WModuleOutputData< WDataSetRawHARDI > > m_outputResiduals
The reprojection error for each measurement.
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
WPropBool m_multiThreaded
Property indicating whether the spherical harmonics calculation is done multithreaded.
std::shared_ptr< WItemSelection > m_reconstructionTypes
A list of the selectable reconstruction types.
WPropDouble m_regularisationFactorLambda
Property holding the regularisation factor lambda.
virtual void connectors()
Initialize the connectors this module is using.
WPropDouble m_CSADelta2
Delta2 value for the constant solid angle reconstruction.
void stopThreads()
Stop the threads.
Class representing a single module of OpenWalnut.
Definition: WModule.h:72
A named property class with a concrete type.
Module for the creation of a spherical harmonic data set from raw HARDI data.
virtual void run()
Run thread.
Base Class for all value set types.
Definition: WValueSet.h:47
int32_t PV_INT
base type used for every WPVInt