1
//---------------------------------------------------------------------------
3
// Project: OpenWalnut ( http://www.openwalnut.org )
5
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
6
// For more information see http://www.openwalnut.org/copying
8
// This file is part of OpenWalnut.
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.
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.
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/>.
23
//---------------------------------------------------------------------------
28
#include "core/common/math/WSymmetricSphericalHarmonic.h"
29
#include "core/common/WLimits.h"
30
#include "core/common/math/linearAlgebra/WLinearAlgebra.h"
31
#include "core/common/math/WGeometryFunctions.h"
32
#include "core/kernel/WKernel.h"
33
#include "WMCalculateGFA.xpm"
35
#include "WMCalculateGFA.h"
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 )
40
WMCalculateGFA::WMCalculateGFA():
46
WMCalculateGFA::~WMCalculateGFA()
50
boost::shared_ptr< WModule > WMCalculateGFA::factory() const
52
return boost::shared_ptr< WModule >( new WMCalculateGFA() );
55
const char** WMCalculateGFA::getXPMIcon() const
57
return WMCalculateGFA_xpm;
59
const std::string WMCalculateGFA::getName() const
61
return "Calculate GFA";
64
const std::string WMCalculateGFA::getDescription() const
66
return "Calculates the generalized fractional anisotropy as defined in \"Q-Ball Imaging\" by S.Tuch in 2004";
69
void WMCalculateGFA::connectors()
71
m_input = boost::shared_ptr< WModuleInputData< WDataSetSphericalHarmonics > >(
72
new WModuleInputData< WDataSetSphericalHarmonics >( shared_from_this(),
73
"inSH", "A spherical harmonics dataset." )
76
m_output = boost::shared_ptr< WModuleOutputData< WDataSetScalar > >( new WModuleOutputData< WDataSetScalar >( shared_from_this(),
77
"outGFA", "The generalized fractional anisotropy map." )
80
addConnector( m_input );
81
addConnector( m_output );
83
// call WModules initialization
84
WModule::connectors();
87
void WMCalculateGFA::properties()
89
m_exceptionCondition = boost::shared_ptr< WCondition >( new WCondition() );
91
WModule::properties();
94
void WMCalculateGFA::moduleMain()
96
m_moduleState.setResetable( true, true );
97
m_moduleState.add( m_input->getDataChangedCondition() );
98
m_moduleState.add( m_exceptionCondition );
100
std::vector< unsigned int > temp;
101
std::vector< WVector3d > grad;
103
tesselateIcosahedron( &grad, &temp, 2 );
107
std::vector< WUnitSphereCoordinates > ori;
108
for( std::size_t k = 0; k < grad.size(); ++k )
110
if( grad[ k ][ 0 ] >= 0.0 )
112
ori.push_back( WUnitSphereCoordinates( grad[ k ] ) );
117
m_BMat = WSymmetricSphericalHarmonic::calcBaseMatrix( ori, 4 );
122
while( !m_shutdownFlag() )
124
debugLog() << "Waiting.";
125
m_moduleState.wait();
127
boost::shared_ptr< WDataSetSphericalHarmonics > inData = m_input->getData();
128
bool dataChanged = ( m_dataSet != inData );
130
if( dataChanged && inData )
137
debugLog() << "Running computation.";
139
else if( m_gfaPool && ( m_gfaPool->status() == W_THREADS_FINISHED || m_gfaPool->status() == W_THREADS_ABORTED ) )
141
debugLog() << "Computation finished.";
142
m_currentProgress->finish();
143
m_result = boost::shared_dynamic_cast< WDataSetScalar >( m_gfaFunc->getResult() );
144
m_gfaPool = boost::shared_ptr< GFAPoolType >();
145
m_gfaFunc = boost::shared_ptr< GFAFuncType >();
148
m_output->updateData( m_result );
150
else if( m_lastException )
152
throw WException( *m_lastException );
157
debugLog() << "Shutting down module.";
160
if( m_gfaPool->status() == W_THREADS_RUNNING || m_gfaPool->status() == W_THREADS_STOP_REQUESTED )
168
void WMCalculateGFA::resetGFAPool()
172
WThreadedFunctionStatus s = m_gfaPool->status();
173
if( s != W_THREADS_FINISHED && s != W_THREADS_ABORTED )
177
s = m_gfaPool->status();
178
WAssert( s == W_THREADS_FINISHED || s == W_THREADS_ABORTED, "" );
180
m_moduleState.remove( m_gfaPool->getThreadsDoneCondition() );
182
// the threadpool should have finished computing by now
184
boost::shared_ptr< WGridRegular3D > g = boost::shared_dynamic_cast< WGridRegular3D >( m_dataSet->getGrid() );
186
resetProgress( g->getNbCoordsX() * g->getNbCoordsY() * g->getNbCoordsZ() );
189
m_gfaFunc = boost::shared_ptr< GFAFuncType >( new GFAFuncType( m_dataSet, boost::bind( &This::perVoxelGFAFunc, this, _1 ) ) );
190
m_gfaPool = boost::shared_ptr< GFAPoolType >( new GFAPoolType( 0, m_gfaFunc ) );
191
m_gfaPool->subscribeExceptionSignal( boost::bind( &This::handleException, this, _1 ) );
192
m_moduleState.add( m_gfaPool->getThreadsDoneCondition() );
195
void WMCalculateGFA::handleException( WException const& e )
197
m_lastException = boost::shared_ptr< WException >( new WException( e ) );
198
m_exceptionCondition->notify();
201
void WMCalculateGFA::resetProgress( std::size_t todo )
203
if( m_currentProgress )
205
m_currentProgress->finish();
207
m_currentProgress = boost::shared_ptr< WProgress >( new WProgress( "calculate gfa", todo ) );
208
m_progress->addSubProgress( m_currentProgress );
211
boost::array< double, 1 > WMCalculateGFA::perVoxelGFAFunc( WValueSet< double >::SubArray const& s )
213
++*m_currentProgress;
214
boost::array< double, 1 > a;
215
WValue<double> w( 15 );
216
for( int i = 0; i < 15; ++i )
220
WSymmetricSphericalHarmonic h( w );
221
a[ 0 ] = h.calcGFA( m_BMat );