Commit cf0bd6d7 authored by reichenbach's avatar reichenbach

[FIX] some doc warnings

[CHANGE] mori tracking now uses the WThreadedFunction interface
parent 1ee3a2c7
......@@ -26,6 +26,7 @@
#define WTHREADEDFUNCTION_H
#include <memory.h>
#include <iostream>
#include <vector>
#include <boost/thread.hpp>
......@@ -50,6 +51,8 @@ enum WThreadedFunctionStatus
* Creates threads that compute a function in a multithreaded fashion.
*
* \note This class is NOT thread-safe, do not access it from different threads simultaneously.
*
* \ingroup common
*/
template< class Function_T >
class WThreadedFunction
......@@ -288,15 +291,18 @@ void WThreadedFunction< Function_T >::handleThreadDone()
if( s->get() == W_THREADS_RUNNING )
{
s->get() = W_THREADS_FINISHED;
std::cout << "All threads finished." << std::endl;
}
else if( s->get() == W_THREADS_STOP_REQUESTED )
{
s->get() = W_THREADS_ABORTED;
std::cout << "All threads aborted." << std::endl;
}
else
{
throw WException( "Invalid status change." );
}
std::cout << "Notifiing condition." << std::endl;
m_doneCondition->notify();
}
}
......
......@@ -71,7 +71,7 @@ public:
/**
* Abstract function for the job aquisition.
*
* \param [out]job The job.
* \param job The job (output).
* \return false, iff no more jobs need to be processed.
*/
virtual bool getJob( JobType& job ) = 0; // NOLINT
......
......@@ -198,6 +198,13 @@ public:
/**
* Request (read-) access object to a subarray of this valueset.
* The object returned by this function can be used as an array
* ( starting at index 0 ), whose elements are the data elements
* at positions start to ( including ) start + size - 1 of the valueset.
*
* \param start The position of the first element of the subarray.
* \param size The number of elements in the subarray.
* \return The subarray.
*/
SubArray const getSubArray( std::size_t start, std::size_t size ) const
{
......
......@@ -30,7 +30,6 @@
#include "../WValueSetBase.h"
#include "../WDataHandlerEnums.h"
/**
* Dummy class for testing the abstract class WValueSetBase
*/
......@@ -40,7 +39,7 @@ friend class WValueSetBaseTest;
public:
/**
* Standar constructor of Dummy class.
* Standard constructor of Dummy class.
*/
Dummy()
: WValueSetBase( 0, 1, W_DT_INT8 )
......@@ -56,20 +55,39 @@ public:
{
}
/**
* Destructor.
*/
virtual ~Dummy()
{
}
/**
* Get the size.
*
* \return The size.
*/
virtual size_t size() const
{
return 255;
}
/**
* Get the raw size.
*
* \return The raw size.
*/
virtual size_t rawSize() const
{
return 255;
}
/**
* Get the value.
*
* \param i The position of the value.
* \return The value at position i.
*/
virtual double getScalarDouble( size_t i ) const
{
return 255;
......
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <cmath>
#include <vector>
#include "../../common/WAssert.h"
#include "../../common/WLimits.h"
#include "../../common/math/WTensorFunctions.h"
#include "WEigenThread.h"
WEigenThread::WEigenThread( boost::shared_ptr< WGridRegular3D > grid,
boost::shared_ptr< WValueSet< float > > values,
boost::shared_ptr< WProgress > progr,
uint32_t index,
boost::shared_ptr< std::vector< wmath::WVector3D > > eigenVectors,
boost::shared_ptr< std::vector< double > > fa )
: m_grid( grid ),
m_values( values ),
m_progress( progr ),
m_index( index ),
m_eigenVectors( eigenVectors ),
m_FA( fa )
{
}
WEigenThread::~WEigenThread()
{
}
void WEigenThread::threadMain()
{
size_t sx, tx, sy, ty, sz, tz;
sx = ( m_index & 1u ? m_grid->getNbCoordsX() / 2 : 0 );
tx = ( m_index & 1u ? m_grid->getNbCoordsX() : m_grid->getNbCoordsX() / 2 );
sy = ( m_index & 2u ? m_grid->getNbCoordsY() / 2 : 0 );
ty = ( m_index & 2u ? m_grid->getNbCoordsY() : m_grid->getNbCoordsY() / 2 );
sz = ( m_index & 4u ? m_grid->getNbCoordsZ() / 2 : 0 );
tz = ( m_index & 4u ? m_grid->getNbCoordsZ() : m_grid->getNbCoordsZ() / 2 );
for( size_t k = sz; k < tz; ++k )
{
for( size_t j = sy; j < ty; ++j )
{
for( size_t i = sx; i < tx; ++i )
{
++*m_progress;
size_t t = i + j * m_grid->getNbCoordsX() + k * m_grid->getNbCoordsX() * m_grid->getNbCoordsY();
eigen( t );
}
}
}
}
void WEigenThread::eigen( size_t i )
{
wmath::WTensorSym< 2, 3, double > m;
m( 0, 0 ) = static_cast< double >( m_values->rawData()[ 6 * i + 0 ] );
m( 0, 1 ) = static_cast< double >( m_values->rawData()[ 6 * i + 1 ] );
m( 0, 2 ) = static_cast< double >( m_values->rawData()[ 6 * i + 2 ] );
m( 1, 1 ) = static_cast< double >( m_values->rawData()[ 6 * i + 3 ] );
m( 1, 2 ) = static_cast< double >( m_values->rawData()[ 6 * i + 4 ] );
m( 2, 2 ) = static_cast< double >( m_values->rawData()[ 6 * i + 5 ] );
std::vector< double > ev( 3 );
std::vector< wmath::WVector3D > vectors( 3 );
wmath::jacobiEigenvector3D( m, &ev, &vectors );
int u = 0;
double h = 0.0;
for( int n = 0; n < 3; ++n )
{
if( fabs( ev[ n ] ) > h )
{
h = fabs( ev[ n ] );
u = n;
}
}
m_eigenVectors->at( i ) = vectors[ u ];
calcFA( ev[ 0 ], ev[ 1 ], ev[ 2 ], i );
}
void WEigenThread::calcFA( double const t0, double const t1, double const t2, size_t const i )
{
double d = t0 * t0 + t1 * t1 + t2 * t2;
if( fabs( d ) == 0.0 )
{
m_FA->at( i ) = 0.0;
return;
}
double trace = ( t0 + t1 + t2 ) / 3;
m_FA->at( i ) = sqrt( 1.5 * ( ( t0 - trace ) * ( t0 - trace ) + ( t1 - trace ) * ( t1 - trace ) + ( t2 - trace ) * ( t2 - trace ) ) / d );
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WEIGENTHREAD_H
#define WEIGENTHREAD_H
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include "../../common/WThreadedRunner.h"
#include "../../common/WProgress.h"
#include "../../dataHandler/WValueSet.h"
#include "../../dataHandler/WGridRegular3D.h"
#include "../../common/math/WLinearAlgebraFunctions.h"
#include "../../common/datastructures/WFiber.h"
#include "../../common/math/WVector3D.h"
#include "../../common/math/WMatrix.h"
/**
* A class that computes the largest eigenvectors on a subset of a tensor array
* in its own thread.
*/
class WEigenThread : public WThreadedRunner
{
public:
/**
* Constructor.
*
* \param grid The grid of the input dataset.
* \param values The input tensors.
* \param progr The progress object.
* \param index An index indicating what part of the grid this thread should work on.
* \param eigenVectors A vector of (output) eigenvectors.
* \param fa A vector of (output) FA values.
*/
WEigenThread( boost::shared_ptr< WGridRegular3D > grid,
boost::shared_ptr< WValueSet< float > > values,
boost::shared_ptr< WProgress > progr,
uint32_t index,
boost::shared_ptr< std::vector< wmath::WVector3D > > eigenVectors,
boost::shared_ptr< std::vector< double > > fa );
/**
* Destructor.
*/
virtual ~WEigenThread();
protected:
private:
/**
* The actual thread routine.
*/
virtual void threadMain();
/**
* Calculate the largest eigenvector and the FA at grid position i.
* \param i A position in the input datasets' grid.
*/
void eigen( size_t i );
/**
* Calculate the fractional anisotropy at the grid position from the eigenvalues t0, t1 and t2.
* \param t0 One of the input tensor's eigenvalues.
* \param t1 Another one of the input tensor's eigenvalues.
* \param t2 The last eigenvalue of the input tensor.
* \param i The position on the input grid.
*/
void calcFA( double const t0, double const t1, double const t2, size_t const i );
/**
* The input grid.
*/
boost::shared_ptr< WGridRegular3D > m_grid;
/**
* The input tensors.
*/
boost::shared_ptr< WValueSet< float > > m_values;
/**
* The progress of the eigenvector calculation. All threads
* share the same progress object.
*/
boost::shared_ptr< WProgress > m_progress;
/**
* An index indicating in what part of the grid this thread should look for seed points.
*/
uint32_t m_index;
/**
* The vector storing the computed eigenvectors.
*/
boost::shared_ptr< std::vector< wmath::WVector3D > > m_eigenVectors;
/**
* The vector storing the fractional anisotropy.
*/
boost::shared_ptr< std::vector< double > > m_FA;
};
#endif // WEIGENTHREAD_H
......@@ -39,6 +39,8 @@
#include "../../dataHandler/WDataSetFiberVector.h"
#include "../../common/math/WVector3D.h"
#include "../../common/math/WMatrix.h"
#include "../../common/WThreadedFunction.h"
#include "../../dataHandler/WThreadedPerVoxelOperation.h"
/**
* This module implements the simple fiber tracking algorithm by Mori et al.
......@@ -111,14 +113,33 @@ protected:
private:
//! the threaded per-voxel function
typedef WThreadedPerVoxelOperation< float, 6, double, 4 > TPVO;
//! the thread pool type
typedef WThreadedFunction< TPVO > EigenFunctionType;
//! the input of the per-voxel operation
typedef TPVO::TransmitType EigenInArrayType;
//! the output of the per-voxel operation
typedef TPVO::OutTransmitType EigenOutArrayType;
//! the valueset type
typedef WValueSet< double > FloatValueSetType;
/**
* Computes the largest eigenvector as well as the fractional anisotropy (FA)
* for every position in the input dataset. The calculation is spread over
* multiple threads.
* The function that computes the eigenvectors.
*
* \see WEigenThread
* \param input A subarray of a valueset that consists of the 6 floats that make up the tensor.
* \return The components of the largest eigenvector and the fa value in a 4-float array.
*/
void doEigen();
EigenOutArrayType const eigenFunc( EigenInArrayType const& input );
/**
* Resets the threaded function/threadpool.
*/
void resetEigenFunction();
/**
* Calculate fibers using the fiber tracking algorithm by Mori et al.
......@@ -133,59 +154,47 @@ private:
void doMori( double const minFA, unsigned int const minPoints, double minCos );
/**
* A condition for property changes.
* Resets the current progress to 0.
*
* \param todo The number of operations of the new progress.
*/
void resetProgress( std::size_t todo );
//! A condition for property changes.
boost::shared_ptr< WCondition > m_propCondition;
/**
* A pointer to the input tensor dataset.
*/
//! A pointer to the input tensor dataset.
boost::shared_ptr< WDataSetSingle > m_dataSet;
/**
* The output dataset. Stores all fibers extracted from the input tensor field.
*/
//! The output dataset. Stores all fibers extracted from the input tensor field.
boost::shared_ptr< WDataSetFibers > m_fiberSet;
/**
* The output Connector.
*/
//! The output Connector.
boost::shared_ptr< WModuleOutputData< WDataSetFibers > > m_output;
/**
* The input Connector.
*/
//! The input Connector.
boost::shared_ptr< WModuleInputData< WDataSetSingle > > m_input;
/**
* Stores the eigenvectors extracted from the input tensor field.
*/
boost::shared_ptr< std::vector< wmath::WVector3D > > m_eigenVectors;
//! Stores eigenvectors and fractional anisotropy of the input dataset.
boost::shared_ptr< WDataSetSingle > m_eigenField;
/**
* Stores the fractional anisotropy of the input tensor field.
*/
boost::shared_ptr< std::vector< double > > m_FA;
//! the functor used for the calculation of the eigenvectors
boost::shared_ptr< TPVO > m_eigenOperation;
/**
* The minimum FA property.
*/
//! the object that keeps track of the current progress
boost::shared_ptr< WProgress > m_currentProgress;
//! The threadpool for the eigenvector and fa computations.
boost::shared_ptr< EigenFunctionType > m_eigenPool;
//! The minimum FA property.
WPropDouble m_minFA;
/**
* The minimum number of points property.
*/
//! The minimum number of points property.
WPropInt m_minPoints;
/**
* The minimum cosine property.
*/
//! The minimum cosine property.
WPropDouble m_minCos;
/**
* Run the algorithm.
*/
WPropBool m_run;
};
#endif // WMDETERMINISTICFTMORI_H
......@@ -81,8 +81,7 @@ boost::shared_ptr< WDataSetFibers > WMoriThread::WFiberAccumulator::buildDataSet
}
WMoriThread::WMoriThread( boost::shared_ptr< WGridRegular3D > grid,
boost::shared_ptr< std::vector< wmath::WVector3D > > eigenVectors,
boost::shared_ptr< std::vector< double > > fa,
boost::shared_ptr< WDataSetSingle > eigenField,
double const minFA,
unsigned int const minPoints,
double const minCos,
......@@ -90,8 +89,7 @@ WMoriThread::WMoriThread( boost::shared_ptr< WGridRegular3D > grid,
uint32_t const index,
boost::shared_ptr< WFiberAccumulator > fiberAccu )
: m_grid( grid ),
m_eigenVectors( eigenVectors ),
m_FA( fa ),
m_eigenSet( boost::shared_dynamic_cast< WValueSet< double > >( eigenField->getValueSet() ) ),
m_minFA( minFA ),
m_minPoints( minPoints ),
m_minCos( minCos ),
......@@ -103,6 +101,8 @@ WMoriThread::WMoriThread( boost::shared_ptr< WGridRegular3D > grid,
m_gridTransform( 3, 3 ),
m_invGridTransform( 3, 3 )
{
WAssert( m_eigenSet, "" );
m_gridSize[ 0 ] = m_grid->getNbCoordsX();
m_gridSize[ 1 ] = m_grid->getNbCoordsY();
m_gridSize[ 2 ] = m_grid->getNbCoordsZ();
......@@ -360,10 +360,14 @@ wmath::WVector3D WMoriThread::getEigenAt( wmath::WValue< size_t > const& coords
return res;
}
}
return m_eigenVectors->at( coords[ 0 ] + coords[ 1 ] * m_gridSize[ 0 ] + coords[ 2 ] * m_gridSize[ 0 ] * m_gridSize[ 1 ] );
std::size_t c = coords[ 0 ] + coords[ 1 ] * m_gridSize[ 0 ] + coords[ 2 ] * m_gridSize[ 0 ] * m_gridSize[ 1 ];
double const* ptr = m_eigenSet->rawData();
return wmath::WVector3D( ptr[ 4 * c ], ptr[ 4 * c + 1 ], ptr[ 4 * c + 2 ] );
}
bool WMoriThread::testFA( wmath::WValue< size_t > const& coords ) const
{
return m_minFA < m_FA->at( coords[ 0 ] + coords[ 1 ] * m_gridSize[ 0 ] + coords[ 2 ] * m_gridSize[ 0 ] * m_gridSize[ 1 ] );
std::size_t c = coords[ 0 ] + coords[ 1 ] * m_gridSize[ 0 ] + coords[ 2 ] * m_gridSize[ 0 ] * m_gridSize[ 1 ];
double const* ptr = m_eigenSet->rawData();
return m_minFA < ptr[ 4 * c + 3 ];
}
......@@ -116,8 +116,7 @@ public:
/**
* Constructor.
* \param grid The regular 3D grid of the input dataset.
* \param eigenVectors A vector storing the eigenvector that belongs to the eigenvalue of largest magnitude for every grid position.
* \param fa A vector that stores the fractional anisotropy for every grid position.
* \param eigenField A vector storing the largest eigenvector and the fa for every voxel.
* \param minFA The minimum fractional anisotropy threshold needed by the tracking algorithm.
* \param minPoints The minimum length of a fiber.
* \param minCos The minimum cosine of the angle of bends between adjacent fiber segments.
......@@ -126,8 +125,7 @@ public:
* \param fiberAccu A WFiberAccumulator.
*/
WMoriThread( boost::shared_ptr< WGridRegular3D > grid,
boost::shared_ptr< std::vector< wmath::WVector3D > > eigenVectors,
boost::shared_ptr< std::vector< double > > fa,
boost::shared_ptr< WDataSetSingle > eigenField,
double const minFA,
unsigned int const minPoints,
double const minCos,
......@@ -231,74 +229,43 @@ private:
*/
double distanceToBorder( double const& pos, size_t const& coord, double const& eigen ) const;
/**
* A shared pointer to the grid.
*/
//! A shared pointer to the grid.
boost::shared_ptr< WGridRegular3D > m_grid;
/**
* A shared pointer to the vector of eigenvectors.
*/
boost::shared_ptr< std::vector< wmath::WVector3D > > m_eigenVectors;
/**
* A shared poiter to the vector of fractional anisotropy values.
*/
boost::shared_ptr< std::vector< double > > m_FA;
//! the type of valueset used
boost::shared_ptr< WValueSet< double > > m_eigenSet;
/**
* The fractional anisotropy threshold.
*/
//! The fractional anisotropy threshold.
double const m_minFA;
/**
* Minimum of points per fiber.
*/
//! Minimum of points per fiber.
unsigned int const m_minPoints;
/**
* The minimum angle between two adjacent segments of a fiber.
*/
//! The minimum angle between two adjacent segments of a fiber.
double const m_minCos;
/**
* A shared pointer to a WProgress object.
*/
//! A shared pointer to a WProgress object.
boost::shared_ptr< WProgress > m_progress;
/**
* Determines what part of the grid the seedpoints should be placed in.
*/
//! Determines what part of the grid the seedpoints should be placed in.
uint32_t const m_index;
/**
* A WFiberAccumulator.
*/
//! A WFiberAccumulator.
boost::shared_ptr< WFiberAccumulator > m_fiberAccu;
/**
* A constant needed for comparations.
*/
//! A constant needed for comparations.
double const m_eps;
/**
* The extent of the grid in each axis' direction.
*/
//! The extent of the grid in each axis' direction.
wmath::WValue< size_t > m_gridSize;
/**
* The grid's transformation matrix.
*/
//! The grid's transformation matrix.
wmath::WMatrix< double > m_gridTransform;