33 #include <boost/math/special_functions/spherical_harmonic.hpp>
34 #include <boost/thread/thread.hpp>
36 #include "WMHARDIToSphericalHarmonics.h"
37 #include "WMHARDIToSphericalHarmonics.xpm"
38 #include "WSphericalHarmonicsCoefficientsThread.h"
39 #include "core/common/WAssert.h"
40 #include "core/common/WLimits.h"
41 #include "core/common/WProgress.h"
42 #include "core/common/math/WLinearAlgebraFunctions.h"
43 #include "core/common/math/WMatrix.h"
44 #include "core/common/math/WSymmetricSphericalHarmonic.h"
45 #include "core/common/math/WUnitSphereCoordinates.h"
46 #include "core/common/math/linearAlgebra/WVectorFixed.h"
47 #include "core/dataHandler/WDataHandler.h"
48 #include "core/dataHandler/WSubject.h"
49 #include "core/kernel/WKernel.h"
70 return WMHARDIToSphericalHarmonics_xpm;
75 return "Spherical Harmonic Calculator";
80 return "This module creates a Spherical Harmonics data set from raw HARDI data ";
85 enum RECONSTRUCTION_TYPE
90 RECONSTRUCTION_TYPE reconstructionType( DEFAULT );
97 debugLog() <<
"Module is now ready.";
110 std::shared_ptr< WDataSetRawHARDI > newDataSet =
m_input->getData();
111 bool dataChanged = (
m_dataSet != newDataSet );
112 bool dataValid = ( newDataSet != NULL );
123 reconstructionType = DEFAULT;
132 reconstructionType = CSA;
136 if( dataChanged && dataValid )
143 double q = std::sqrt( 0.25 + 2.0 *
static_cast<double>(
m_dataSet->getNumberOfMeasurements() ) ) - 1.5;
144 m_order->setMax(
static_cast<unsigned int>( q ) % 2 == 1 ?
static_cast<unsigned int>( q ) - 3 :
static_cast<unsigned int>( q ) - 2 );
153 debugLog() <<
"Data changed. Recalculating output.";
156 std::shared_ptr< WDataSetSphericalHarmonics > newData;
162 std::vector< size_t > S0Indexes;
164 debugLog() <<
"Determine usable gradients." << std::endl;
165 std::vector< size_t > validIndices;
166 for(
size_t i = 0; i <
m_dataSet->getNumberOfMeasurements(); i++ )
169 if( ( grad[ 0 ] != 0.0 ) || ( grad[ 1 ] != 0.0 ) || ( grad[ 2 ] != 0.0 ) )
171 validIndices.push_back( i );
175 S0Indexes.push_back( i );
178 debugLog() <<
"Found " << validIndices.size() <<
" usable gradients." << std::endl;
179 debugLog() <<
"Found " << S0Indexes.size() <<
" zero gradients." << std::endl;
181 if( S0Indexes.size() == 0 )
183 errorLog() <<
"No entry with zero gradient. Can't get S0 (basis) signal.";
188 std::vector< WVector3d > gradients;
189 for( std::vector< size_t >::const_iterator it = validIndices.begin(); it != validIndices.end(); it++ )
191 gradients.push_back(
m_dataSet->getGradient( *it ) );
193 int order =
m_order->get(
true );
197 parameter.m_valueSet =
m_dataSet->getValueSet();
198 parameter.m_validIndices = validIndices;
199 parameter.m_S0Indexes = S0Indexes;
200 parameter.m_order = order;
201 parameter.m_gradients = gradients;
203 parameter.m_doErrorCalculation =
m_doErrorCalculation->get(
true ) || parameter.m_doResidualCalculation;
205 parameter.m_bDiffusionWeightingFactor =
m_dataSet->getDiffusionBValue();
207 parameter.m_csa = ( reconstructionType == CSA );
213 parameter.m_doFunkRadonTransformation ) );
214 if( reconstructionType == CSA )
216 parameter.m_doResidualCalculation =
false;
217 parameter.m_doErrorCalculation =
false;
218 parameter.m_normalize =
false;
219 parameter.m_doFunkRadonTransformation =
false;
227 parameter.m_TransformMatrix = std::shared_ptr< WMatrix< double > >(
new WMatrix< double >( transformMatrix ) );
230 parameter.m_progress = std::shared_ptr< WProgress >(
new WProgress(
"Creating Spherical Harmonics",
232 m_progress->addSubProgress( parameter.m_progress );
234 debugLog() <<
"Starting calculation.";
237 HARDICalculation::result_type res =
m_dataSet->getValueSet()->applyFunction( hc );
245 if( parameter.m_doResidualCalculation )
258 m_input = std::shared_ptr< WModuleInputData < WDataSetRawHARDI > >(
264 m_output = std::shared_ptr< WModuleOutputData< WDataSetSphericalHarmonics > >(
287 "Which reconstruction type will be used?",
294 "Order of Spherical Harmonics",
299 "Apply the Funk-Radon-Transformation to the calculated Spherical Harmonics.",
304 "Calculate the reprojection error of the spherical harmonics.",
309 "Indicating whether the reprojection errors is stored into a separate dataset.",
314 "Factor for Regularisation",
324 "Normalise the HARDI measurements to 0 to 1 for each voxel.",
363 m_order->addConstraint( std::shared_ptr< evenInt >(
new evenInt ) );
369 return ( value % 2 == 0 );
378 bool multiThreaded, std::shared_ptr< WGrid > grid,
379 std::vector< WVector3d >
const& gradients )
380 : m_parameter( threadParams ),
383 m_gradients( gradients )
virtual void wait() const
Wait for the condition.
void setResetable(bool resetable=true, bool autoReset=true)
Sets the resetable flag.
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.
A class containing a list of named items.
Functor that does multithreaded spherical harmonic fitting.
~HARDICalculation()
Destructor.
HARDICalculation(WSphericalHarmonicsCoefficientsThread<>::ThreadParameter threadParams, bool multiThreaded, std::shared_ptr< WGrid > grid, std::vector< WVector3d > const &gradients)
Constructor.
This class is derived from PropertyConstraint and ensures that only even values are valid.
virtual bool accept(std::shared_ptr< WPropertyVariable< WPVBaseTypes::PV_INT > > property, const WPVBaseTypes::PV_INT &value)
You need to overwrite this method.
virtual std::shared_ptr< WPropertyVariable< WPVBaseTypes::PV_INT >::PropertyConstraint > clone()
Method to clone the constraint and create a new one with the correct dynamic type.
Module for the creation of a spherical harmonic data set from raw HARDI data.
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 const std::string getName() const
Gives back the name of this module.
WPropInt m_order
Property holding the order of the spherical harmonics.
std::shared_ptr< WModuleOutputData< WDataSetSphericalHarmonics > > m_output
Output connector provided by this module.
WPropBool m_doNormalisation
Property indicating whether the measurements are normalized from 0 to 1 for each voxel.
WPropSelection m_reconstructionTypeProp
To choose the reconstruction type.
std::shared_ptr< WDataSetRawHARDI > m_dataSet
This is a pointer to the dataset the module is currently working on.
std::shared_ptr< WModuleInputData< WDataSetRawHARDI > > m_input
Input connector required by this module.
~WMHARDIToSphericalHarmonics()
Destructor.
virtual void properties()
Initialize the properties for this module.
WPropBool m_doResidualCalculation
Property indicating whether the reprojection error (measurement relative to spherical harmonic calcul...
WMHARDIToSphericalHarmonics()
Standard constructor.
std::shared_ptr< WCondition > m_propCondition
A condition used to notify about changes in several properties.
virtual const std::string getDescription() const
Gives back a description of this module.
WPropBool m_doFunkRadonTransformation
Property indicating whether to do the Funk-Radon-transformation with calculated spherical harmonics.
virtual void moduleMain()
Entry point after loading the module.
WPropDouble m_CSADelta1
Delta1 value for the constant solid angle reconstruction.
WPropBool m_doErrorCalculation
Property indicating whether a reprojection error of the spherical harmonics is calculated.
std::shared_ptr< WModuleOutputData< WDataSetRawHARDI > > m_outputResiduals
The reprojection error for each measurement.
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
WPropBool m_multiThreaded
Property indicating whether the spherical harmonics calculation is done multithreaded.
std::shared_ptr< WItemSelection > m_reconstructionTypes
A list of the selectable reconstruction types.
WPropDouble m_regularisationFactorLambda
Property holding the regularisation factor lambda.
virtual void connectors()
Initialize the connectors this module is using.
WPropDouble m_CSADelta2
Delta2 value for the constant solid angle reconstruction.
Class offering an instantiate-able data connection between modules.
Class representing a single module of OpenWalnut.
wlog::WStreamedLogger debugLog() const
Logger instance for comfortable debug logging.
void removeConnectors()
Removes all connectors properly.
void addConnector(std::shared_ptr< WModuleInputConnector > con)
Adds the specified connector to the list of inputs.
std::shared_ptr< WProperties > m_properties
The property object for the module.
void ready()
Call this whenever your module is ready and can react on property changes.
WConditionSet m_moduleState
The internal state of the module.
wlog::WStreamedLogger errorLog() const
Logger instance for comfortable error logging.
std::shared_ptr< WProgressCombiner > m_progress
Progress indicator used as parent for all progress' of this module.
virtual void connectors()
Initialize connectors in this function.
Class managing progress inside of modules.
A named property class with a concrete type.
Module for the creation of a spherical harmonic data set from raw HARDI data.
Class for symmetric spherical harmonics The index scheme of the coefficients/basis values is like in ...
static WMatrix< T > getSHFittingMatrixForConstantSolidAngle(const std::vector< WMatrixFixed< T, 3, 1 > > &orientations, int order, T lambda)
This calculates the transformation/fitting matrix T like in the 2010 Aganj paper.
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
int32_t PV_INT
base type used for every WPVInt
void addTo(WPropSelection prop)
Add the PC_SELECTONLYONE constraint to the property.