OpenWalnut  1.5.0dev
WThreadedPerVoxelOperation_test.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_TEST_H
26 #define WTHREADEDPERVOXELOPERATION_TEST_H
27 
28 #include <memory>
29 #include <vector>
30 
31 #include <cxxtest/TestSuite.h>
32 
33 #include "../../common/WLogger.h"
34 #include "../../common/WThreadedFunction.h"
35 #include "../WDataHandlerEnums.h"
36 #include "../WDataSetSingle.h"
37 #include "../WThreadedPerVoxelOperation.h"
38 
39 /**
40  * \class WThreadedPerVoxelOperationTest
41  *
42  * Test the WThreadedPerVoxelOperation template.
43  */
44 class WThreadedPerVoxelOperationTest : public CxxTest::TestSuite
45 {
46  //! the test instance of the template
48 
49  //! the type of valueset used in the test
51 
52  //! the input type of the test function
54 
55  //! the output type of the test function
57 
58 public:
59  /**
60  * Setup logger and other stuff for each test.
61  */
62  void setUp()
63  {
65  }
66 
67  /**
68  * Test if everything gets instantiated correctly or if
69  * incorrect values properly lead to exceptions.
70  */
72  {
73  std::shared_ptr< WDataSetSingle > ds = buildTestData();
74 
75  TS_ASSERT_THROWS( TPVO t( std::shared_ptr< WDataSetSingle >(),
76  boost::bind( &WThreadedPerVoxelOperationTest::func, this, boost::placeholders::_1 ) ), const WException& );
77  TS_ASSERT_THROWS( TPVO t( ds, TPVO::FunctionType() ), const WException& );
78  TS_ASSERT_THROWS( TPVO t( std::shared_ptr< WDataSetSingle >( new WDataSetSingle( ds->getValueSet(),
79  std::shared_ptr< WGrid >() ) ),
80  boost::bind( &WThreadedPerVoxelOperationTest::func, this, boost::placeholders::_1 ) ), const WException& );
81  TS_ASSERT_THROWS( TPVO t( std::shared_ptr< WDataSetSingle >( new WDataSetSingle( std::shared_ptr< WValueSetBase >(),
82  ds->getGrid() ) ),
83  boost::bind( &WThreadedPerVoxelOperationTest::func, this, boost::placeholders::_1 ) ), const WException& );
84 
85  TS_ASSERT_THROWS_NOTHING( TPVO t( ds, boost::bind( &WThreadedPerVoxelOperationTest::func, this, boost::placeholders::_1 ) ) );
86 
87  TPVO t( ds, boost::bind( &WThreadedPerVoxelOperationTest::func, this, boost::placeholders::_1 ) );
88 
89  TS_ASSERT_EQUALS( ds->getGrid(), t.m_grid );
90  }
91 
92  /**
93  * Now test the whole class as a multithreaded function.
94  */
96  {
97  std::shared_ptr< WDataSetSingle > ds = buildTestData();
98  std::shared_ptr< TPVO > t( new TPVO( ds, boost::bind( &WThreadedPerVoxelOperationTest::func, this, boost::placeholders::_1 ) ) );
99 
100  m_exception = false;
101  m_threadsDone = false;
102 
103  WThreadedFunction< TPVO > f( 5, t );
104  f.getThreadsDoneCondition()->subscribeSignal( boost::bind( &WThreadedPerVoxelOperationTest::handleThreadsDone, this ) );
105  f.subscribeExceptionSignal( boost::bind( &WThreadedPerVoxelOperationTest::handleException, this, boost::placeholders::_1 ) );
106 
107  TS_ASSERT_THROWS_NOTHING( f.run() );
108  TS_ASSERT_THROWS_NOTHING( f.wait() );
109  TS_ASSERT( !m_exception );
110  TS_ASSERT( m_threadsDone );
111 
112  std::shared_ptr< WDataSetSingle > res = t->getResult();
113 
114  float shouldBe[] = {
115  2.0f, 2.0f, 5.0f,
116  -5.0f, 4.0f, -7.0f,
117  8.0f, 8.0f, 23.0f,
118  -4.0f, 3.0f, -6.0f,
119  -28.0f, 13.0f, -44.0f,
120  3.0f, 4.0f, 9.0f,
121  -4.0f, 5.0f, -4.0f,
122  2.0f, -4.0f, -1.0f
123  };
124 
125  TS_ASSERT( res );
126  TS_ASSERT( res->getValueSet() );
127  TS_ASSERT_EQUALS( res->getGrid(), ds->getGrid() );
128  TS_ASSERT_EQUALS( res->getValueSet()->dimension(), 3 );
129  TS_ASSERT_EQUALS( res->getValueSet()->order(), 1 );
130  TS_ASSERT_EQUALS( res->getValueSet()->size(), 8 );
131 
132  std::shared_ptr< WValueSet< float > > vs = std::dynamic_pointer_cast< WValueSet< float > >( res->getValueSet() );
133 
134  TS_ASSERT( vs );
135  TS_ASSERT( vs->rawData() );
136  TS_ASSERT_EQUALS( vs->rawDataVectorPointer()->size(), 24 );
137  TS_ASSERT_SAME_DATA( vs->rawData(), shouldBe, 8 * 3 * sizeof( float ) );
138  }
139 
140 private:
141  /**
142  * The test operation.
143  *
144  * \param a The subarray of the input valueset that denotes the voxel's data.
145  * \return The output data as an array.
146  */
147  OutArrayType const func( ArrayType const& a ) const
148  {
149  OutArrayType o;
150  o[ 0 ] = static_cast< float >( a[ 1 ] );
151  o[ 1 ] = static_cast< float >( a[ 0 ] + 1 );
152  o[ 2 ] = static_cast< float >( a[ 0 ] + 2 * a[ 1 ] );
153  return o;
154  }
155 
156  /**
157  * Build a test dataset.
158  *
159  * \return The test dataset.
160  */
161  std::shared_ptr< WDataSetSingle > buildTestData()
162  {
163  int a[] = { 1, 2, 3, -5, 7, 8, 2, -4, 12, -28, 3, 3, 4, -4, -5, 2 };
164  std::shared_ptr< std::vector< int > > v( new std::vector< int >( a, a + 16 ) );
166  std::shared_ptr< ValueSetType > vs( new ValueSetType( 1, 2, v, r ) );
167  std::shared_ptr< WGridRegular3D > g( new WGridRegular3D( 2, 2, 2 ) );
168  return std::shared_ptr< WDataSetSingle >( new WDataSetSingle( vs, g ) );
169  }
170 
171  /**
172  * Handle an exception.
173  */
175  {
176  m_exception = true;
177  }
178 
179  //! a flag that is used to check if any exceptions were thrown
181 
182  /**
183  * This function gets called when all threads are done.
184  */
186  {
187  m_threadsDone = true;
188  }
189 
190  //! a flag indicating if all threads are done
192 };
193 
194 #endif // WTHREADEDPERVOXELOPERATION_TEST_H
A data set consisting of a set of values based on a grid.
Basic exception handler.
Definition: WException.h:39
A grid that has parallelepiped cells which all have the same proportion.
static void startup(std::ostream &output=std::cout, LogLevel level=LL_DEBUG)
Create the first and only instance of the logger as it is a singleton.
Definition: WLogger.cpp:41
std::shared_ptr< WCondition > getThreadsDoneCondition()
Returns a condition that gets fired when all threads have finished.
void subscribeExceptionSignal(ExceptionFunction func)
Subscribe a function to an exception signal.
Creates threads that computes a function in a multithreaded fashion.
virtual void wait()
Wait for all threads to stop.
virtual void run()
Starts the threads.
Test the WThreadedPerVoxelOperation template.
TPVO::OutTransmitType OutArrayType
the output type of the test function
bool m_exception
a flag that is used to check if any exceptions were thrown
void handleException(WException const &)
Handle an exception.
void testInstantiation()
Test if everything gets instantiated correctly or if incorrect values properly lead to exceptions.
void handleThreadsDone()
This function gets called when all threads are done.
void testMultithreadedFunction()
Now test the whole class as a multithreaded function.
WThreadedPerVoxelOperation< int, 2, float, 3 > TPVO
the test instance of the template
TPVO::TransmitType ArrayType
the input type of the test function
OutArrayType const func(ArrayType const &a) const
The test operation.
TPVO::ValueSetType ValueSetType
the type of valueset used in the test
void setUp()
Setup logger and other stuff for each test.
std::shared_ptr< WDataSetSingle > buildTestData()
Build a test dataset.
bool m_threadsDone
a flag indicating if all threads are done
A template that performs an operation on a per voxel basis.
boost::array< Output_T, numOutputs > OutTransmitType
the output type for the per-voxel operation
ValueSetType::SubArray const TransmitType
the input type for the per-voxel operation
boost::function< OutTransmitType const(TransmitType const &) > FunctionType
the function type
std::shared_ptr< WGrid > m_grid
store the grid
Base Class for all value set types.
Definition: WValueSet.h:47
dataType
Data types and number values taken from the nifti1.h, at this point it's unknown if it makes sense to...
An object that knows an appropriate dataType flag for the typename T.