~noskcaj/ubuntu/saucy/openwalnut/liberation

« back to all changes in this revision

Viewing changes to .pc/boost153/src/modules/calculateTensors/WMCalculateTensors.cpp

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2013-05-24 03:12:03 UTC
  • Revision ID: package-import@ubuntu.com-20130524031203-l5g1lzm1vd83fupi
Tags: 1.3.1+hg5849-1ubuntu1
Cherrypick boost1.53 pointer cast fixes.

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/math/WMatrix.h"
 
30
#include "core/common/math/linearAlgebra/WLinearAlgebra.h"
 
31
#include "core/common/WLimits.h"
 
32
#include "core/kernel/WKernel.h"
 
33
 
 
34
#include "WMCalculateTensors.h"
 
35
 
 
36
// This line is needed by the module loader to actually find your module. Do not remove. Do NOT add a ";" here.
 
37
W_LOADABLE_MODULE( WMCalculateTensors )
 
38
 
 
39
WMCalculateTensors::WMCalculateTensors():
 
40
    WModule(),
 
41
    m_SHToTensorMat( 1, 1 )
 
42
{
 
43
}
 
44
 
 
45
WMCalculateTensors::~WMCalculateTensors()
 
46
{
 
47
}
 
48
 
 
49
boost::shared_ptr< WModule > WMCalculateTensors::factory() const
 
50
{
 
51
    return boost::shared_ptr< WModule >( new WMCalculateTensors() );
 
52
}
 
53
 
 
54
const char** WMCalculateTensors::getXPMIcon() const
 
55
{
 
56
    return NULL;
 
57
}
 
58
const std::string WMCalculateTensors::getName() const
 
59
{
 
60
    return "Calculate Tensors";
 
61
}
 
62
 
 
63
const std::string WMCalculateTensors::getDescription() const
 
64
{
 
65
    return "Calculates diffusion tensors from an input sh dataset.";
 
66
}
 
67
 
 
68
void WMCalculateTensors::connectors()
 
69
{
 
70
    m_input = boost::shared_ptr< WModuleInputData< WDataSetSphericalHarmonics > >(
 
71
                            new WModuleInputData< WDataSetSphericalHarmonics >( shared_from_this(),
 
72
                                "shInput", "A spherical harmonics dataset." )
 
73
            );
 
74
 
 
75
    m_output = boost::shared_ptr< WModuleOutputData< WDataSetDTI > >( new WModuleOutputData< WDataSetDTI >( shared_from_this(),
 
76
                "dtiOutput", "The diffusion tensor image." )
 
77
            );
 
78
 
 
79
    addConnector( m_input );
 
80
    addConnector( m_output );
 
81
 
 
82
    // call WModules initialization
 
83
    WModule::connectors();
 
84
}
 
85
 
 
86
void WMCalculateTensors::properties()
 
87
{
 
88
    m_exceptionCondition = boost::shared_ptr< WCondition >( new WCondition() );
 
89
 
 
90
    WModule::properties();
 
91
}
 
92
 
 
93
void WMCalculateTensors::moduleMain()
 
94
{
 
95
    m_moduleState.setResetable( true, true );
 
96
    m_moduleState.add( m_input->getDataChangedCondition() );
 
97
    m_moduleState.add( m_exceptionCondition );
 
98
 
 
99
    // calc sh->tensor conversion matrix
 
100
    std::vector< WUnitSphereCoordinates > orientations;
 
101
    orientations.push_back( WUnitSphereCoordinates( normalize( WVector3d( 1.0, 0.0, 0.0 ) ) ) );
 
102
    orientations.push_back( WUnitSphereCoordinates( normalize( WVector3d( 0.6, -0.1, 0.2 ) ) ) );
 
103
    orientations.push_back( WUnitSphereCoordinates( normalize( WVector3d( 1.0, 1.0, 1.0 ) ) ) );
 
104
    orientations.push_back( WUnitSphereCoordinates( normalize( WVector3d( -0.1, -0.3, 0.5 ) ) ) );
 
105
    orientations.push_back( WUnitSphereCoordinates( normalize( WVector3d( -0.56347, 0.374, -0.676676 ) ) ) );
 
106
    orientations.push_back( WUnitSphereCoordinates( normalize( WVector3d( 0.0, 4.0, 1.0 ) ) ) );
 
107
 
 
108
    m_SHToTensorMat = WSymmetricSphericalHarmonic::calcSHToTensorSymMatrix( 2, orientations );
 
109
 
 
110
    ready();
 
111
 
 
112
    while( !m_shutdownFlag() )
 
113
    {
 
114
        debugLog() << "Waiting.";
 
115
        m_moduleState.wait();
 
116
 
 
117
        boost::shared_ptr< WDataSetSphericalHarmonics > inData = m_input->getData();
 
118
        bool dataChanged = ( m_dataSet != inData );
 
119
 
 
120
        if( dataChanged && inData )
 
121
        {
 
122
            m_dataSet = inData;
 
123
 
 
124
            // start computation
 
125
            resetTensorPool();
 
126
            if( m_tensorPool )
 
127
            {
 
128
                m_tensorPool->run();
 
129
            }
 
130
            debugLog() << "Running computation.";
 
131
        }
 
132
        else if( m_tensorPool && ( m_tensorPool->status() == W_THREADS_FINISHED || m_tensorPool->status() == W_THREADS_ABORTED ) )
 
133
        {
 
134
            debugLog() << "Computation finished.";
 
135
            m_currentProgress->finish();
 
136
            boost::shared_ptr< WDataSetSingle > temp = m_tensorFunc->getResult();
 
137
            m_result = boost::shared_ptr< WDataSetDTI >( new WDataSetDTI( temp->getValueSet(), temp->getGrid() ) );
 
138
            m_tensorPool = boost::shared_ptr< TensorPoolType >();
 
139
            m_tensorFunc = boost::shared_ptr< TensorFuncType >();
 
140
 
 
141
            // forward result
 
142
            m_output->updateData( m_result );
 
143
        }
 
144
        else if( m_lastException )
 
145
        {
 
146
            throw WException( *m_lastException );
 
147
        }
 
148
    }
 
149
 
 
150
    // module shutdown
 
151
    debugLog() << "Shutting down module.";
 
152
    if( m_tensorPool )
 
153
    {
 
154
        if( m_tensorPool->status() == W_THREADS_RUNNING || m_tensorPool->status() == W_THREADS_STOP_REQUESTED )
 
155
        {
 
156
            m_tensorPool->stop();
 
157
            m_tensorPool->wait();
 
158
        }
 
159
    }
 
160
}
 
161
 
 
162
void WMCalculateTensors::resetTensorPool()
 
163
{
 
164
    if( m_tensorPool )
 
165
    {
 
166
        WThreadedFunctionStatus s = m_tensorPool->status();
 
167
        if( s != W_THREADS_FINISHED && s != W_THREADS_ABORTED )
 
168
        {
 
169
            m_tensorPool->stop();
 
170
            m_tensorPool->wait();
 
171
            s = m_tensorPool->status();
 
172
            WAssert( s == W_THREADS_FINISHED || s == W_THREADS_ABORTED, "" );
 
173
        }
 
174
        m_moduleState.remove( m_tensorPool->getThreadsDoneCondition() );
 
175
    }
 
176
    // the threadpool should have finished computing by now
 
177
 
 
178
    if( m_dataSet->getSphericalHarmonicAt( 0 ).getOrder() == 2 )
 
179
    {
 
180
        boost::shared_ptr< WGridRegular3D > g = boost::shared_dynamic_cast< WGridRegular3D >( m_dataSet->getGrid() );
 
181
        WAssert( g, "" );
 
182
        resetProgress( g->getNbCoordsX() * g->getNbCoordsY() * g->getNbCoordsZ() );
 
183
 
 
184
        // create a new one
 
185
        m_tensorFunc = boost::shared_ptr< TensorFuncType >( new TensorFuncType( m_dataSet, boost::bind( &This::perVoxelTensorFunc, this, _1 ) ) );
 
186
        m_tensorPool = boost::shared_ptr< TensorPoolType >( new TensorPoolType( 0, m_tensorFunc ) );
 
187
        m_tensorPool->subscribeExceptionSignal( boost::bind( &This::handleException, this, _1 ) );
 
188
        m_moduleState.add( m_tensorPool->getThreadsDoneCondition() );
 
189
    }
 
190
    else
 
191
    {
 
192
        warnLog() << "SH dataset has order > 2";
 
193
    }
 
194
}
 
195
 
 
196
void WMCalculateTensors::handleException( WException const& e )
 
197
{
 
198
    m_lastException = boost::shared_ptr< WException >( new WException( e ) );
 
199
    m_exceptionCondition->notify();
 
200
}
 
201
 
 
202
void WMCalculateTensors::resetProgress( std::size_t todo )
 
203
{
 
204
    if( m_currentProgress )
 
205
    {
 
206
        m_currentProgress->finish();
 
207
    }
 
208
    m_currentProgress = boost::shared_ptr< WProgress >( new WProgress( "calculate tensors", todo ) );
 
209
    m_progress->addSubProgress( m_currentProgress );
 
210
}
 
211
 
 
212
boost::array< double, 6 > WMCalculateTensors::perVoxelTensorFunc( WValueSet< double >::SubArray const& s )
 
213
{
 
214
    ++*m_currentProgress;
 
215
    boost::array< double, 6 > a;
 
216
    WValue<double> v( 6 );
 
217
 
 
218
    // calculation
 
219
    for( std::size_t k = 0; k < 6; ++k )
 
220
    {
 
221
        v[ k ] = s[ k ];
 
222
    }
 
223
 
 
224
    v = m_SHToTensorMat * v;
 
225
 
 
226
    for( std::size_t k = 0; k < 6; ++k )
 
227
    {
 
228
        a[ k ] = v[ k ];
 
229
    }
 
230
 
 
231
    return a;
 
232
}