OpenWalnut  1.4.0
WThreadedPerVoxelOperation.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-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 #ifndef WTHREADEDPERVOXELOPERATION_H
26 #define WTHREADEDPERVOXELOPERATION_H
27 
28 #include <vector>
29 #include <string>
30 
31 #ifndef Q_MOC_RUN
32 #include <boost/array.hpp>
33 #endif
34 #ifndef Q_MOC_RUN
35 #include <boost/shared_ptr.hpp>
36 #endif
37 #ifndef Q_MOC_RUN
38 #include <boost/function.hpp>
39 #endif
40 
41 #include "../common/WException.h"
42 #include "../common/WThreadedJobs.h"
43 #include "../common/WSharedObject.h"
44 #include "../common/WSharedSequenceContainer.h"
45 #include "WDataSetSingle.h"
46 #include "WDataSetScalar.h"
47 #include "WValueSet.h"
48 #include "WDataHandlerEnums.h"
49 
50 //! forward declaration for the test
52 
53 /**
54  * \class WThreadedPerVoxelOperation
55  *
56  * A template that performs an operation on a per voxel basis. This
57  * template is intended to be used in combination with \see WThreadedFunction.
58  *
59  * The template parameters are the internal datatype of the input datasets valueset,
60  * the number of input data elements per voxel, the type of the output data and the number of
61  * outputs per voxel.
62  *
63  * Example: Suppose one wants to calculate the largest eigenvector of a symmetric tensor of order
64  * 2 per voxel, where the input tensors are stored als 6 floats. The output could be 3 double values.
65  * The corresponding template parameters would be float, 6, double, 3.
66  *
67  * A function that converts the input values to output values needs to be given via a boost::function
68  * object. The correct 'signature' is:
69  *
70  * boost::array< Output_T, numOutputs > func( WValueSet< Value_T >::SubArray const& );
71  *
72  * The subarray will have exactly numInputs entries.
73  */
74 template< typename Value_T, std::size_t numValues, typename Output_T, std::size_t numOutputs >
75 class WThreadedPerVoxelOperation : public WThreadedStripingJobs< WValueSet< Value_T >, std::size_t >
76 {
77  //! the test is a friend
79 
80  //! the base class
82 
83 public:
84  //! the input valueset's type
86 
87  //! the output valueset's type
89 
90  //! the input type for the per-voxel operation
91  typedef typename ValueSetType::SubArray const TransmitType;
92 
93  //! the output type for the per-voxel operation
94  typedef boost::array< Output_T, numOutputs > OutTransmitType;
95 
96  //! the function type
97  typedef boost::function< OutTransmitType const ( TransmitType const& ) > FunctionType;
98 
99  /**
100  * Construct a per-voxel operation.
101  *
102  * \param dataset The input dataset.
103  * \param func The function to be evaluated per voxel.
104  */
105  WThreadedPerVoxelOperation( boost::shared_ptr< WDataSetSingle const > dataset, FunctionType func );
106 
107  /**
108  * Destructor.
109  */
110  virtual ~WThreadedPerVoxelOperation();
111 
112  /**
113  * Perform the computation for a specific voxel.
114  *
115  * \param input The input dataset.
116  * \param voxelNum The voxel number to operate on.
117  */
118  virtual void compute( boost::shared_ptr< ValueSetType const > input, std::size_t voxelNum );
119 
120  /**
121  * Get the output dataset.
122  *
123  * \return The oupput dataset.
124  */
125  boost::shared_ptr< WDataSetSingle > getResult();
126 
127 protected:
128  using BaseType::m_input;
129 
130 private:
131  //! a threadsafe vector (container)
132  typedef boost::shared_ptr< std::vector< Output_T > > OutputVectorType;
133 
134  //! stores the output of the per-voxel-operation
135  OutputVectorType m_output;
136 
137  //! the function applied to every voxel
138  FunctionType m_func;
139 
140  //! store the grid
141  boost::shared_ptr< WGrid > m_grid;
142 };
143 
144 template< typename Value_T, std::size_t numValues, typename Output_T, std::size_t numOutputs >
146  boost::shared_ptr< WDataSetSingle const > dataset,
148  : BaseType( ( dataset ? boost::dynamic_pointer_cast< ValueSetType >( dataset->getValueSet() )
149  : boost::shared_ptr< ValueSetType >() ) ) // NOLINT
150 {
151  if( !dataset )
152  {
153  throw WException( std::string( "No input dataset." ) );
154  }
155  if( !dataset->getValueSet() )
156  {
157  throw WException( std::string( "The input dataset has no valueset." ) );
158  }
159  if( !dataset->getGrid() )
160  {
161  throw WException( std::string( "The input dataset has no grid." ) );
162  }
163  if( dataset->getValueSet()->order() > 1 )
164  {
165  throw WException( std::string( "An order of 2 or more is currently not supported." ) );
166  }
167  if( dataset->getValueSet()->dimension() != numValues )
168  {
169  throw WException( std::string( "Invalid valueset dimension." ) );
170  }
171  if( !func )
172  {
173  throw WException( std::string( "No valid function provided." ) );
174  }
175 
176  try
177  {
178  // allocate enough memory for the output data
179  m_output = OutputVectorType( new std::vector< Output_T >( m_input->size() * numOutputs ) );
180  }
181  catch( std::exception const& e )
182  {
183  throw WException( std::string( e.what() ) );
184  }
185  m_func = func;
186  m_grid = dataset->getGrid();
187 }
188 
189 template< typename Value_T, std::size_t numValues, typename Output_T, std::size_t numOutputs >
191 {
192 }
193 
194 template< typename Value_T, std::size_t numValues, typename Output_T, std::size_t numOutputs >
196  std::size_t voxelNum )
197 {
198  TransmitType t = input->getSubArray( voxelNum * numValues, numValues );
199  OutTransmitType o = m_func( t );
200  for( std::size_t k = 0; k < numOutputs; ++k )
201  {
202  ( *m_output )[ voxelNum * numOutputs + k ] = o[ k ];
203  }
204 }
205 
206 template< typename Value_T, std::size_t numValues, typename Output_T, std::size_t numOutputs >
208 {
209  boost::shared_ptr< OutValueSetType > values;
210  switch( numOutputs )
211  {
212  case 1:
213  values = boost::shared_ptr< OutValueSetType >( new OutValueSetType( 0, 1, m_output,
215  return boost::shared_ptr< WDataSetScalar >( new WDataSetScalar( values, m_grid ) );
216  default:
217  values = boost::shared_ptr< OutValueSetType >( new OutValueSetType( 1, numOutputs, m_output,
219  return boost::shared_ptr< WDataSetSingle >( new WDataSetSingle( values, m_grid ) );
220  }
221 }
222 
223 #endif // WTHREADEDPERVOXELOPERATION_H
FunctionType m_func
the function applied to every voxel
WThreadedStripingJobs< WValueSet< Value_T >, std::size_t > BaseType
the base class
ValueSetType::SubArray const TransmitType
the input type for the per-voxel operation
boost::shared_ptr< std::vector< Output_T > > OutputVectorType
a threadsafe vector (container)
OutArrayType const func(ArrayType const &a) const
The test operation.
boost::function< OutTransmitType const (TransmitType const &) > FunctionType
the function type
boost::shared_ptr< WDataSetSingle > getResult()
Get the output dataset.
WValueSet< Value_T > ValueSetType
the input valueset's type
A helper class granting safe access to a certain part of the valueset.
Definition: WValueSet.h:66
OutputVectorType m_output
stores the output of the per-voxel-operation
A template that performs an operation on a per voxel basis.
An object that knows an appropriate dataType flag for the typename T.
virtual ~WThreadedPerVoxelOperation()
Destructor.
boost::shared_ptr< InputType const > m_input
the input
A data set consisting of a set of values based on a grid.
Nearly the same class as WThreadedJobs, but this class is intended to be used for multithreaded opera...
WThreadedPerVoxelOperation(boost::shared_ptr< WDataSetSingle const > dataset, FunctionType func)
Construct a per-voxel operation.
Base Class for all value set types.
Definition: WValueSet.h:48
WValueSet< Output_T > OutValueSetType
the output valueset's type
boost::shared_ptr< WGrid > m_grid
store the grid
This data set type contains scalars as values.
virtual void compute(boost::shared_ptr< ValueSetType const > input, std::size_t voxelNum)
Perform the computation for a specific voxel.
Basic exception handler.
Definition: WException.h:38
boost::array< Output_T, numOutputs > OutTransmitType
the output type for the per-voxel operation
Test the WThreadedPerVoxelOperation template.