~ubuntu-branches/ubuntu/precise/openwalnut/precise

« back to all changes in this revision

Viewing changes to src/modules/calculateGFA/WMCalculateGFA.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Eichelbaum
  • Date: 2011-06-21 10:26:54 UTC
  • Revision ID: james.westby@ubuntu.com-20110621102654-rq0zf436q949biih
Tags: upstream-1.2.5
ImportĀ upstreamĀ versionĀ 1.2.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//---------------------------------------------------------------------------
 
2
//
 
3
// Project: OpenWalnut ( http://www.openwalnut.org )
 
4
//
 
5
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-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 <string>
 
26
#include <vector>
 
27
 
 
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"
 
34
 
 
35
#include "WMCalculateGFA.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
 
 
40
WMCalculateGFA::WMCalculateGFA():
 
41
    WModule(),
 
42
    m_BMat( 1, 1 )
 
43
{
 
44
}
 
45
 
 
46
WMCalculateGFA::~WMCalculateGFA()
 
47
{
 
48
}
 
49
 
 
50
boost::shared_ptr< WModule > WMCalculateGFA::factory() const
 
51
{
 
52
    return boost::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
 
 
69
void WMCalculateGFA::connectors()
 
70
{
 
71
    m_input = boost::shared_ptr< WModuleInputData< WDataSetSphericalHarmonics > >(
 
72
                            new WModuleInputData< WDataSetSphericalHarmonics >( shared_from_this(),
 
73
                                "inSH", "A spherical harmonics dataset." )
 
74
            );
 
75
 
 
76
    m_output = boost::shared_ptr< WModuleOutputData< WDataSetScalar > >( new WModuleOutputData< WDataSetScalar >( shared_from_this(),
 
77
                "outGFA", "The generalized fractional anisotropy map." )
 
78
            );
 
79
 
 
80
    addConnector( m_input );
 
81
    addConnector( m_output );
 
82
 
 
83
    // call WModules initialization
 
84
    WModule::connectors();
 
85
}
 
86
 
 
87
void WMCalculateGFA::properties()
 
88
{
 
89
    m_exceptionCondition = boost::shared_ptr< WCondition >( new WCondition() );
 
90
 
 
91
    WModule::properties();
 
92
}
 
93
 
 
94
void WMCalculateGFA::moduleMain()
 
95
{
 
96
    m_moduleState.setResetable( true, true );
 
97
    m_moduleState.add( m_input->getDataChangedCondition() );
 
98
    m_moduleState.add( m_exceptionCondition );
 
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 > 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( grad[ k ] ) );
 
113
        }
 
114
    }
 
115
    grad.clear();
 
116
 
 
117
    m_BMat = WSymmetricSphericalHarmonic::calcBaseMatrix( ori, 4 );
 
118
    ori.clear();
 
119
 
 
120
    ready();
 
121
 
 
122
    while( !m_shutdownFlag() )
 
123
    {
 
124
        debugLog() << "Waiting.";
 
125
        m_moduleState.wait();
 
126
 
 
127
        boost::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 = boost::shared_dynamic_cast< WDataSetScalar >( m_gfaFunc->getResult() );
 
144
            m_gfaPool = boost::shared_ptr< GFAPoolType >();
 
145
            m_gfaFunc = boost::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
 
 
168
void WMCalculateGFA::resetGFAPool()
 
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
    boost::shared_ptr< WGridRegular3D > g = boost::shared_dynamic_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 = 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() );
 
193
}
 
194
 
 
195
void WMCalculateGFA::handleException( WException const& e )
 
196
{
 
197
    m_lastException = boost::shared_ptr< WException >( new WException( e ) );
 
198
    m_exceptionCondition->notify();
 
199
}
 
200
 
 
201
void WMCalculateGFA::resetProgress( std::size_t todo )
 
202
{
 
203
    if( m_currentProgress )
 
204
    {
 
205
        m_currentProgress->finish();
 
206
    }
 
207
    m_currentProgress = boost::shared_ptr< WProgress >( new WProgress( "calculate gfa", todo ) );
 
208
    m_progress->addSubProgress( m_currentProgress );
 
209
}
 
210
 
 
211
boost::array< double, 1 > WMCalculateGFA::perVoxelGFAFunc( WValueSet< double >::SubArray const& s )
 
212
{
 
213
    ++*m_currentProgress;
 
214
    boost::array< double, 1 > a;
 
215
    WValue<double> w( 15 );
 
216
    for( int i = 0; i < 15; ++i )
 
217
    {
 
218
        w[ i ] = s[ i ];
 
219
    }
 
220
    WSymmetricSphericalHarmonic h( w );
 
221
    a[ 0 ] = h.calcGFA( m_BMat );
 
222
 
 
223
    return a;
 
224
}