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