25 #ifndef WSPHERICALHARMONICSCOEFFICIENTSTHREAD_H
26 #define WSPHERICALHARMONICSCOEFFICIENTSTHREAD_H
37 #include <boost/math/special_functions/spherical_harmonic.hpp>
38 #include <boost/thread/thread.hpp>
40 #include "core/common/WAssert.h"
41 #include "core/common/WLimits.h"
42 #include "core/common/WProgress.h"
43 #include "core/common/WThreadedRunner.h"
44 #include "core/common/math/WMatrix.h"
45 #include "core/dataHandler/WDataSetRawHARDI.h"
46 #include "core/dataHandler/WDataSetSphericalHarmonics.h"
47 #include "core/dataHandler/WGridRegular3D.h"
50 template<
typename T =
void >
63 struct ThreadParameter
71 : m_CSADelta1( 0.01 ),
95 std::shared_ptr< std::vector<double> >
m_data;
175 template<
typename T >
205 template<
typename T >
208 std::pair< size_t, size_t > range )
209 : m_parameter( parameter ),
214 template<
typename T >
218 m_overallError = 0.0;
221 size_t l = ( m_parameter.m_order + 1 ) * ( m_parameter.m_order + 2 ) / 2;
223 for(
size_t i = m_range.first; i < m_range.second; i++ )
225 if( m_parameter.m_shutdownFlag() )
231 std::shared_ptr< WValueSet< T > > vs = std::dynamic_pointer_cast< WValueSet< T > >( m_parameter.m_valueSet );
234 throw WException(
"Valueset pointer not valid." );
241 unsigned int idx = 0;
245 for( std::vector< size_t >::const_iterator it = m_parameter.m_S0Indexes.begin(); it != m_parameter.m_S0Indexes.end(); it++ )
247 S0avg +=
static_cast< double >( allMeasures[ *it ] );
249 S0avg /= m_parameter.m_S0Indexes.size();
259 for( std::vector< size_t >::const_iterator it = m_parameter.m_validIndices.begin(); it != m_parameter.m_validIndices.end(); it++, idx++ )
261 if( m_parameter.m_csa )
263 double val =
static_cast< double >( allMeasures[ *it ] ) / S0avg;
266 val = m_parameter.m_CSADelta1 / 2.0;
268 else if( val < m_parameter.m_CSADelta1 )
270 val = m_parameter.m_CSADelta1 / 2.0 + val * val / ( 2.0 * m_parameter.m_CSADelta1 );
272 else if( val > 1.0 - m_parameter.m_CSADelta2 && val < 1.0 )
274 val = 1.0 - m_parameter.m_CSADelta2 / 2.0 - std::pow( 1.0 - val, 2 ) / ( 2.0 * m_parameter.m_CSADelta2 );
276 else if( val >= 1.0 )
278 val = 1.0 - m_parameter.m_CSADelta2 / 2.0;
280 measures[ idx ] = std::log( -std::log( val ) );
284 measures[ idx ] =
static_cast< double >( allMeasures[ *it ] ) / S0avg;
290 if( m_parameter.m_doResidualCalculation || m_parameter.m_doErrorCalculation )
293 for( idx = 0; idx < m_parameter.m_validIndices.size(); idx++ )
295 double error =
static_cast< double >( measures[ idx ] )
298 if( m_parameter.m_doResidualCalculation )
300 m_parameter.m_dataResiduals->operator[]( m_parameter.m_validIndices.size() * i + idx ) = error;
302 if( m_parameter.m_doErrorCalculation )
304 m_overallError += fabs( error );
311 ++( *( m_parameter.m_progress ) );
317 if( m_parameter.m_normalize )
319 scale *= std::sqrt( 4.0 * pi() ) / coefficients[ 0 ];
322 if( m_parameter.m_csa )
324 coefficients[ 0 ] = 1.0 / ( 2.0 * std::sqrt( pi() ) );
327 for( std::size_t j = 0; j < l; j++ )
329 m_parameter.m_data->operator[]( l * i + j ) = coefficients[ j ];
335 template<
typename T >
338 if( m_errorCount == 0 )
return 0.0;
339 return m_overallError /
static_cast< double >( m_errorCount );
Module for the creation of a spherical harmonic data set from raw HARDI data.
double getError() const
Returns the average error of the thread.
std::pair< size_t, size_t > m_range
the range (start and end) of input data this thread use
unsigned int m_errorCount
number of accumulated errors, necessary for average error calculation
void threadMain()
The main function of the thread.
double m_overallError
accumulated error
WSphericalHarmonicsCoefficientsThread ::ThreadParameter m_parameter
collection of parameter and so on (description in more detail above)
WSphericalHarmonicsCoefficientsThread(WSphericalHarmonicsCoefficientsThread<>::ThreadParameter parameter, std::pair< size_t, size_t > range)
The constructor.
Class for symmetric spherical harmonics The index scheme of the coefficients/basis values is like in ...
T getValue(T theta, T phi) const
Return the value on the sphere.
Base class for all classes needing to be executed in a separate thread.
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
This class stores coordinates on the unit sphere.
Base class for all higher level values like tensors, vectors, matrices and so on.
std::vector< size_t > m_validIndices
Indices of nonzero gradients.
std::vector< size_t > m_S0Indexes
Indices of zero gradients (this should be normal T2 measurement)
std::shared_ptr< WMatrix< double > > m_TransformMatrix
Transformation-Matrix for conversion from HARDI measurements to spherical harmonics coefficients (see...
WBoolFlag const & m_shutdownFlag
A shutdownFlag that may tell the thread to stop.
std::shared_ptr< WValueSetBase > m_valueSet
Pointer to the HARDI measurements.
bool m_doResidualCalculation
Indicate if the residuals will be calculated.
std::vector< WVector3d > m_gradients
Gradients of all measurements (including )
ThreadParameter(WBoolFlag const &flag)
Constructor, we need to initialize a reference.
int m_order
The order of the calculated spherical harmonics.
bool m_doErrorCalculation
Indicate if the is error calculation is done.
bool m_csa
Indicate if the constant solid angle reconstruction is done.
double m_CSADelta1
Delta1 value for the constant solid angle reconstruction.
bool m_doFunkRadonTransformation
Indicate if the Funk-Radon-Transformation is done.
std::shared_ptr< WProgress > m_progress
Pointer to progess indicator.
double m_bDiffusionWeightingFactor
The b-value used during the creation of the HARDI-data.
std::shared_ptr< std::vector< double > > m_data
Output data, the spherical harmonics coefficients.
std::shared_ptr< std::vector< double > > m_dataResiduals
The stored residuals.
double m_CSADelta2
Delta2 value for the constant solid angle reconstruction.
bool m_normalize
Indicate if the normalisation from 0 to 1 is done.