00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef WTHREADEDPERVOXELOPERATION_H
00026 #define WTHREADEDPERVOXELOPERATION_H
00027
00028 #include <vector>
00029 #include <string>
00030
00031 #include <boost/array.hpp>
00032 #include <boost/shared_ptr.hpp>
00033 #include <boost/function.hpp>
00034
00035 #include "../common/WException.h"
00036 #include "../common/WThreadedJobs.h"
00037 #include "../common/WSharedObject.h"
00038 #include "../common/WSharedSequenceContainer.h"
00039 #include "WDataSetSingle.h"
00040 #include "WDataSetScalar.h"
00041 #include "WValueSet.h"
00042 #include "WDataHandlerEnums.h"
00043
00044
00045 class WThreadedPerVoxelOperationTest;
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 template< typename Value_T, std::size_t numValues, typename Output_T, std::size_t numOutputs >
00069 class WThreadedPerVoxelOperation : public WThreadedStripingJobs< WValueSet< Value_T >, std::size_t >
00070 {
00071
00072 friend class WThreadedPerVoxelOperationTest;
00073
00074
00075 typedef WThreadedStripingJobs< WValueSet< Value_T >, std::size_t > BaseType;
00076
00077 public:
00078
00079 typedef WValueSet< Value_T > ValueSetType;
00080
00081
00082 typedef WValueSet< Output_T > OutValueSetType;
00083
00084
00085 typedef typename ValueSetType::SubArray const TransmitType;
00086
00087
00088 typedef boost::array< Output_T, numOutputs > OutTransmitType;
00089
00090
00091 typedef boost::function< OutTransmitType const ( TransmitType const& ) > FunctionType;
00092
00093
00094
00095
00096
00097
00098
00099 WThreadedPerVoxelOperation( boost::shared_ptr< WDataSetSingle const > dataset, FunctionType func );
00100
00101
00102
00103
00104 virtual ~WThreadedPerVoxelOperation();
00105
00106
00107
00108
00109
00110
00111
00112 virtual void compute( boost::shared_ptr< ValueSetType const > input, std::size_t voxelNum );
00113
00114
00115
00116
00117
00118
00119 boost::shared_ptr< WDataSetSingle > getResult();
00120
00121 protected:
00122 using BaseType::m_input;
00123
00124 private:
00125
00126 typedef boost::shared_ptr< std::vector< Output_T > > OutputVectorType;
00127
00128
00129 OutputVectorType m_output;
00130
00131
00132 FunctionType m_func;
00133
00134
00135 boost::shared_ptr< WGrid > m_grid;
00136 };
00137
00138 template< typename Value_T, std::size_t numValues, typename Output_T, std::size_t numOutputs >
00139 WThreadedPerVoxelOperation< Value_T, numValues, Output_T, numOutputs >::WThreadedPerVoxelOperation(
00140 boost::shared_ptr< WDataSetSingle const > dataset,
00141 FunctionType func )
00142 : BaseType( ( dataset ? boost::shared_dynamic_cast< ValueSetType >( dataset->getValueSet() )
00143 : boost::shared_ptr< ValueSetType >() ) )
00144 {
00145 if( !dataset )
00146 {
00147 throw WException( std::string( "No input dataset." ) );
00148 }
00149 if( !dataset->getValueSet() )
00150 {
00151 throw WException( std::string( "The input dataset has no valueset." ) );
00152 }
00153 if( !dataset->getGrid() )
00154 {
00155 throw WException( std::string( "The input dataset has no grid." ) );
00156 }
00157 if( dataset->getValueSet()->order() > 1 )
00158 {
00159 throw WException( std::string( "An order of 2 or more is currently not supported." ) );
00160 }
00161 if( dataset->getValueSet()->dimension() != numValues )
00162 {
00163 throw WException( std::string( "Invalid valueset dimension." ) );
00164 }
00165 if( !func )
00166 {
00167 throw WException( std::string( "No valid function provided." ) );
00168 }
00169
00170 try
00171 {
00172
00173 m_output = OutputVectorType( new std::vector< Output_T >( m_input->size() * numOutputs ) );
00174 }
00175 catch( std::exception const& e )
00176 {
00177 throw WException( std::string( e.what() ) );
00178 }
00179 m_func = func;
00180 m_grid = dataset->getGrid();
00181 }
00182
00183 template< typename Value_T, std::size_t numValues, typename Output_T, std::size_t numOutputs >
00184 WThreadedPerVoxelOperation< Value_T, numValues, Output_T, numOutputs >::~WThreadedPerVoxelOperation()
00185 {
00186 }
00187
00188 template< typename Value_T, std::size_t numValues, typename Output_T, std::size_t numOutputs >
00189 void WThreadedPerVoxelOperation< Value_T, numValues, Output_T, numOutputs >::compute( boost::shared_ptr< ValueSetType const > input,
00190 std::size_t voxelNum )
00191 {
00192 TransmitType t = input->getSubArray( voxelNum * numValues, numValues );
00193 OutTransmitType o = m_func( t );
00194 for( std::size_t k = 0; k < numOutputs; ++k )
00195 {
00196 ( *m_output )[ voxelNum * numOutputs + k ] = o[ k ];
00197 }
00198 }
00199
00200 template< typename Value_T, std::size_t numValues, typename Output_T, std::size_t numOutputs >
00201 boost::shared_ptr< WDataSetSingle > WThreadedPerVoxelOperation< Value_T, numValues, Output_T, numOutputs >::getResult()
00202 {
00203 boost::shared_ptr< OutValueSetType > values;
00204 switch( numOutputs )
00205 {
00206 case 1:
00207 values = boost::shared_ptr< OutValueSetType >( new OutValueSetType( 0, 1, m_output,
00208 DataType< Output_T >::type ) );
00209 return boost::shared_ptr< WDataSetScalar >( new WDataSetScalar( values, m_grid ) );
00210 default:
00211 values = boost::shared_ptr< OutValueSetType >( new OutValueSetType( 1, numOutputs, m_output,
00212 DataType< Output_T >::type ) );
00213 return boost::shared_ptr< WDataSetSingle >( new WDataSetSingle( values, m_grid ) );
00214 }
00215 }
00216
00217 #endif // WTHREADEDPERVOXELOPERATION_H