OpenWalnut  1.5.0dev
WMCalculateGFA.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 <memory>
26 #include <string>
27 #include <vector>
28 
29 #include "WMCalculateGFA.h"
30 #include "WMCalculateGFA.xpm"
31 #include "core/common/WLimits.h"
32 #include "core/common/math/WGeometryFunctions.h"
33 #include "core/common/math/WSymmetricSphericalHarmonic.h"
34 #include "core/common/math/linearAlgebra/WVectorFixed.h"
35 #include "core/kernel/WKernel.h"
36 
37 // This line is needed by the module loader to actually find your module. Do not remove. Do NOT add a ";" here.
38 W_LOADABLE_MODULE( WMCalculateGFA )
39 
41  WModule(),
42  m_BMat( 1, 1 )
43 {
44 }
45 
47 {
48 }
49 
50 std::shared_ptr< WModule > WMCalculateGFA::factory() const
51 {
52  return std::shared_ptr< WModule >( new WMCalculateGFA() );
53 }
54 
55 const char** WMCalculateGFA::getXPMIcon() const
56 {
57  return WMCalculateGFA_xpm;
58 }
59 const std::string WMCalculateGFA::getName() const
60 {
61  return "Calculate GFA";
62 }
63 
64 const std::string WMCalculateGFA::getDescription() const
65 {
66  return "Calculates the generalized fractional anisotropy as defined in \"Q-Ball Imaging\" by S.Tuch in 2004";
67 }
68 
70 {
71  m_input = std::shared_ptr< WModuleInputData< WDataSetSphericalHarmonics > >(
72  new WModuleInputData< WDataSetSphericalHarmonics >( shared_from_this(),
73  "inSH", "A spherical harmonics dataset." )
74  );
75 
76  m_output = std::shared_ptr< WModuleOutputData< WDataSetScalar > >( new WModuleOutputData< WDataSetScalar >( shared_from_this(),
77  "outGFA", "The generalized fractional anisotropy map." )
78  );
79 
82 
83  // call WModules initialization
85 }
86 
88 {
89  m_exceptionCondition = std::shared_ptr< WCondition >( new WCondition() );
90 
92 }
93 
95 {
96  m_moduleState.setResetable( true, true );
97  m_moduleState.add( m_input->getDataChangedCondition() );
99 
100  std::vector< unsigned int > temp;
101  std::vector< WVector3d > grad;
102 
103  tesselateIcosahedron( &grad, &temp, 2 );
104 
105  temp.clear();
106 
107  std::vector< WUnitSphereCoordinates< double > > ori;
108  for( std::size_t k = 0; k < grad.size(); ++k )
109  {
110  if( grad[ k ][ 0 ] >= 0.0 )
111  {
112  ori.push_back( WUnitSphereCoordinates< double >( grad[ k ] ) );
113  }
114  }
115  grad.clear();
116 
118  ori.clear();
119 
120  ready();
121 
122  while( !m_shutdownFlag() )
123  {
124  debugLog() << "Waiting.";
126 
127  std::shared_ptr< WDataSetSphericalHarmonics > inData = m_input->getData();
128  bool dataChanged = ( m_dataSet != inData );
129 
130  if( dataChanged && inData )
131  {
132  m_dataSet = inData;
133 
134  // start computation
135  resetGFAPool();
136  m_gfaPool->run();
137  debugLog() << "Running computation.";
138  }
139  else if( m_gfaPool && ( m_gfaPool->status() == W_THREADS_FINISHED || m_gfaPool->status() == W_THREADS_ABORTED ) )
140  {
141  debugLog() << "Computation finished.";
142  m_currentProgress->finish();
143  m_result = std::dynamic_pointer_cast< WDataSetScalar >( m_gfaFunc->getResult() );
144  m_gfaPool = std::shared_ptr< GFAPoolType >();
145  m_gfaFunc = std::shared_ptr< GFAFuncType >();
146 
147  // forward result
148  m_output->updateData( m_result );
149  }
150  else if( m_lastException )
151  {
152  throw WException( *m_lastException );
153  }
154  }
155 
156  // module shutdown
157  debugLog() << "Shutting down module.";
158  if( m_gfaPool )
159  {
160  if( m_gfaPool->status() == W_THREADS_RUNNING || m_gfaPool->status() == W_THREADS_STOP_REQUESTED )
161  {
162  m_gfaPool->stop();
163  m_gfaPool->wait();
164  }
165  }
166 }
167 
169 {
170  if( m_gfaPool )
171  {
172  WThreadedFunctionStatus s = m_gfaPool->status();
173  if( s != W_THREADS_FINISHED && s != W_THREADS_ABORTED )
174  {
175  m_gfaPool->stop();
176  m_gfaPool->wait();
177  s = m_gfaPool->status();
178  WAssert( s == W_THREADS_FINISHED || s == W_THREADS_ABORTED, "" );
179  }
180  m_moduleState.remove( m_gfaPool->getThreadsDoneCondition() );
181  }
182  // the threadpool should have finished computing by now
183 
184  std::shared_ptr< WGridRegular3D > g = std::dynamic_pointer_cast< WGridRegular3D >( m_dataSet->getGrid() );
185  WAssert( g, "" );
186  resetProgress( g->getNbCoordsX() * g->getNbCoordsY() * g->getNbCoordsZ() );
187 
188  // create a new one
189  m_gfaFunc = std::shared_ptr< GFAFuncType >( new GFAFuncType( m_dataSet, boost::bind( &This::perVoxelGFAFunc,
190  this,
191  boost::placeholders::_1 ) ) );
192  m_gfaPool = std::shared_ptr< GFAPoolType >( new GFAPoolType( 0, m_gfaFunc ) );
193  m_gfaPool->subscribeExceptionSignal( boost::bind( &This::handleException, this, boost::placeholders::_1 ) );
194  m_moduleState.add( m_gfaPool->getThreadsDoneCondition() );
195 }
196 
198 {
199  m_lastException = std::shared_ptr< WException >( new WException( e ) );
200  m_exceptionCondition->notify();
201 }
202 
203 void WMCalculateGFA::resetProgress( std::size_t todo )
204 {
205  if( m_currentProgress )
206  {
207  m_currentProgress->finish();
208  }
209  m_currentProgress = std::shared_ptr< WProgress >( new WProgress( "calculate gfa", todo ) );
210  m_progress->addSubProgress( m_currentProgress );
211 }
212 
214 {
216  boost::array< double, 1 > a;
217  WValue<double> w( 15 );
218  for( int i = 0; i < 15; ++i )
219  {
220  w[ i ] = s[ i ];
221  }
223  a[ 0 ] = h.calcGFA( m_BMat );
224 
225  return a;
226 }
virtual void wait() const
Wait for the condition.
void setResetable(bool resetable=true, bool autoReset=true)
Sets the resetable flag.
virtual void remove(std::shared_ptr< WCondition > condition)
Removes the specified condition.
virtual void add(std::shared_ptr< WCondition > condition)
Adds another condition to the set of conditions to wait for.
Class to encapsulate boost::condition_variable_any.
Definition: WCondition.h:42
Basic exception handler.
Definition: WException.h:39
A module that calculates the generalized fractional anisotropy for every voxel of the input dataset.
virtual ~WMCalculateGFA()
Destructor.
std::shared_ptr< WCondition > m_exceptionCondition
Condition indicating if any exception was thrown.
void resetProgress(std::size_t todo)
Reset the progress indicator in the ui.
std::shared_ptr< WException > m_lastException
The last exception thrown by any worker thread.
std::shared_ptr< WModuleInputData< WDataSetSphericalHarmonics > > m_input
The input Connector for the SH data.
std::shared_ptr< WProgress > m_currentProgress
The object that keeps track of the current progress.
WThreadedFunction< GFAFuncType > GFAPoolType
the threadpool
virtual void connectors()
Initialize the connectors this module is using.
virtual const std::string getDescription() const
Gives back a description of this module.
WMatrix< double > m_BMat
A matrix of SH base function values for various gradients.
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 void properties()
Initialize the properties for this module.
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
virtual void moduleMain()
Entry point after loading the module.
void resetGFAPool()
Reset the threaded functions.
WMCalculateGFA()
Standard constructor.
boost::array< double, 1 > perVoxelGFAFunc(WValueSet< double >::SubArray const &s)
A function that gets called for every voxel in the input SH-dataset.
std::shared_ptr< GFAFuncType > m_gfaFunc
The threaded function object.
std::shared_ptr< WDataSetScalar > m_result
The output dataset.
std::shared_ptr< WModuleOutputData< WDataSetScalar > > m_output
The output Connector.
WThreadedPerVoxelOperation< double, 15, double, 1 > GFAFuncType
the threaded function type for gfa computation
std::shared_ptr< WDataSetSphericalHarmonics > m_dataSet
A pointer to the input dataset.
std::shared_ptr< GFAPoolType > m_gfaPool
The threadpool.
virtual const std::string getName() const
Gives back the name of this module.
void handleException(WException const &e)
Handle an exception thrown by a worker thread.
Class offering an instantiate-able data connection between modules.
Class offering an instantiate-able data connection between modules.
Class representing a single module of OpenWalnut.
Definition: WModule.h:72
virtual void properties()
Initialize properties in this function.
Definition: WModule.cpp:212
wlog::WStreamedLogger debugLog() const
Logger instance for comfortable debug logging.
Definition: WModule.cpp:575
void addConnector(std::shared_ptr< WModuleInputConnector > con)
Adds the specified connector to the list of inputs.
Definition: WModule.cpp:108
void ready()
Call this whenever your module is ready and can react on property changes.
Definition: WModule.cpp:505
WConditionSet m_moduleState
The internal state of the module.
Definition: WModule.h:703
std::shared_ptr< WProgressCombiner > m_progress
Progress indicator used as parent for all progress' of this module.
Definition: WModule.h:652
virtual void connectors()
Initialize connectors in this function.
Definition: WModule.cpp:208
Class managing progress inside of modules.
Definition: WProgress.h:42
Class for symmetric spherical harmonics The index scheme of the coefficients/basis values is like in ...
static WMatrix< T > calcBaseMatrix(const std::vector< WUnitSphereCoordinates< T > > &orientations, int order)
Calculates the base matrix B like in the dissertation of Descoteaux.
T calcGFA(std::vector< WUnitSphereCoordinates< T > > const &orientations) const
Calculate the generalized fractional anisotropy for this ODF.
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
This class stores coordinates on the unit sphere.
A helper class granting safe access to a certain part of the valueset.
Definition: WValueSet.h:65
Base class for all higher level values like tensors, vectors, matrices and so on.
Definition: WValue.h:41