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