~noskcaj/ubuntu/saucy/openwalnut/liberation

« back to all changes in this revision

Viewing changes to .pc/boost153/src/core/dataHandler/test/WThreadedTrackingFunction_test.h

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2013-05-24 03:12:03 UTC
  • Revision ID: package-import@ubuntu.com-20130524031203-l5g1lzm1vd83fupi
Tags: 1.3.1+hg5849-1ubuntu1
Cherrypick boost1.53 pointer cast fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 WTHREADEDTRACKINGFUNCTION_TEST_H
 
26
#define WTHREADEDTRACKINGFUNCTION_TEST_H
 
27
 
 
28
#include <vector>
 
29
 
 
30
#include <cxxtest/TestSuite.h>
 
31
 
 
32
#include "../../common/WLogger.h"
 
33
#include "../WThreadedTrackingFunction.h"
 
34
 
 
35
/**
 
36
 * \class WTrackingUtilityTest
 
37
 *
 
38
 * Test the utility functions for tracking.
 
39
 */
 
40
class WTrackingUtilityTest : public CxxTest::TestSuite
 
41
{
 
42
    //! an abbreviation
 
43
    typedef WTrackingUtilityTest This;
 
44
 
 
45
public:
 
46
    /**
 
47
     * Setup logger and other stuff for each test.
 
48
     */
 
49
    void setUp()
 
50
    {
 
51
        WLogger::startup();
 
52
    }
 
53
 
 
54
    /**
 
55
     * Test if positions with a distance less then TRACKING_EPS from a boundary
 
56
     * are determined correctly by onBoundary().
 
57
     */
 
58
    void testBoundary()
 
59
    {
 
60
        WVector3d x( 0.707, 0.707, 0.0 );
 
61
        WVector3d y( -0.707, 0.707, 0.0 );
 
62
        WVector3d z( 0.0, 0.0, 1.0 );
 
63
        x = normalize( x );
 
64
        y = normalize( y );
 
65
 
 
66
        boost::shared_ptr< WDataSetSingle > ds = buildTestData( WVector3d( 0.0, 1.0, 0.0 ) );
 
67
        // test the test
 
68
        TS_ASSERT( ds );
 
69
        boost::shared_ptr< WGridRegular3D > g = boost::shared_dynamic_cast< WGridRegular3D >( ds->getGrid() );
 
70
 
 
71
        WVector3d v( 1.0, 0.0, 0.0 );
 
72
        v += x * -0.5;
 
73
        TS_ASSERT( wtracking::WTrackingUtility::onBoundary( g, v ) );
 
74
        v[ 0 ] += 0.5 * TRACKING_EPS;
 
75
        TS_ASSERT( wtracking::WTrackingUtility::onBoundary( g, v ) );
 
76
        v[ 2 ] -= 2.0 * TRACKING_EPS;
 
77
        v[ 1 ] += 1.6 * TRACKING_EPS;
 
78
        TS_ASSERT( !wtracking::WTrackingUtility::onBoundary( g, v ) );
 
79
 
 
80
        v = WVector3d( 1.0, 0.0, 0.0 ) + x * 0.5;
 
81
        TS_ASSERT( wtracking::WTrackingUtility::onBoundary( g, v ) );
 
82
        v[ 0 ] -= 0.6 * TRACKING_EPS;
 
83
        TS_ASSERT( wtracking::WTrackingUtility::onBoundary( g, v ) );
 
84
        v[ 2 ] += 1.5 * TRACKING_EPS;
 
85
        v[ 1 ] += 2.6 * TRACKING_EPS;
 
86
        TS_ASSERT( !wtracking::WTrackingUtility::onBoundary( g, v ) );
 
87
 
 
88
        v = WVector3d( 1.0, 0.0, 0.0 ) + y * 1.77 + z * 0.65;
 
89
        TS_ASSERT( !wtracking::WTrackingUtility::onBoundary( g, v ) );
 
90
 
 
91
        v = WVector3d( 1.0, 0.0, 0.0 ) + y * 1.0 + z * 0.65;
 
92
        TS_ASSERT( wtracking::WTrackingUtility::onBoundary( g, v ) );
 
93
 
 
94
        v = WVector3d( 1.0, 0.0, 0.0 ) + x * 3.5 + y * 1.77 + z * 0.65;
 
95
        TS_ASSERT( wtracking::WTrackingUtility::onBoundary( g, v ) );
 
96
 
 
97
        v = WVector3d( 1.0, 0.0, 0.0 ) + x * 1.5 + y * 1.77 + z * 0.65;
 
98
        TS_ASSERT( wtracking::WTrackingUtility::onBoundary( g, v ) );
 
99
 
 
100
        v = WVector3d( 1.0, 0.0, 0.0 ) + x * 3.9 + y * 5.0 + z * 0.65;
 
101
        TS_ASSERT( wtracking::WTrackingUtility::onBoundary( g, v ) );
 
102
 
 
103
        v = WVector3d( 1.0, 0.0, 0.0 ) + x * 2.3 + y * 7.73 + z * 3.75;
 
104
        TS_ASSERT( wtracking::WTrackingUtility::onBoundary( g, v ) );
 
105
 
 
106
        v = WVector3d( 1.0, 0.0, 0.0 ) + x * 3.4 + y * 1.77 + z * 6.75;
 
107
        TS_ASSERT( wtracking::WTrackingUtility::onBoundary( g, v ) );
 
108
 
 
109
        v = WVector3d( 1.0, 0.0, 0.0 ) + x * 3.5 + y * 5.0 + z * 0.65;
 
110
        TS_ASSERT( wtracking::WTrackingUtility::onBoundary( g, v ) );
 
111
        v[ 1 ] -= 0.7 * TRACKING_EPS;
 
112
        TS_ASSERT( wtracking::WTrackingUtility::onBoundary( g, v ) );
 
113
        v[ 0 ] += 3.5 * TRACKING_EPS;
 
114
        v[ 1 ] += 0.7 * TRACKING_EPS;
 
115
        TS_ASSERT( !wtracking::WTrackingUtility::onBoundary( g, v ) );
 
116
 
 
117
        v = WVector3d( 1.0, 0.0, 0.0 ) + x * 1.2 + y * 7.9 + z * 5.3;
 
118
        TS_ASSERT( !wtracking::WTrackingUtility::onBoundary( g, v ) );
 
119
    }
 
120
 
 
121
    /**
 
122
     * Check if getDistanceToBoundary() returns the correct distance.
 
123
     */
 
124
    void testGetDistanceToBoundary()
 
125
    {
 
126
        WVector3d x( 0.707, 0.707, 0.0 );
 
127
        WVector3d y( -0.707, 0.707, 0.0 );
 
128
        WVector3d z( 0.0, 0.0, 1.0 );
 
129
        x = normalize( x );
 
130
        y = normalize( y );
 
131
 
 
132
        WVector3d v( 1.0, 0.0, 0.0 );
 
133
 
 
134
        boost::shared_ptr< WDataSetSingle > ds = buildTestData( WVector3d( 0.0, 1.0, 0.0 ) );
 
135
        boost::shared_ptr< WGridRegular3D > g = boost::shared_dynamic_cast< WGridRegular3D >( ds->getGrid() );
 
136
 
 
137
        TS_ASSERT_DELTA( wtracking::WTrackingUtility::getDistanceToBoundary( g, v, x ), 0.5, TRACKING_EPS );
 
138
        TS_ASSERT_DELTA( wtracking::WTrackingUtility::getDistanceToBoundary( g, v, y ), 1.0, TRACKING_EPS );
 
139
        TS_ASSERT_DELTA( wtracking::WTrackingUtility::getDistanceToBoundary( g, v, z ), 0.75, TRACKING_EPS );
 
140
 
 
141
        v = WVector3d( 1.0, 0.0, 0.0 ) + x * 0.5;
 
142
        TS_ASSERT_THROWS( wtracking::WTrackingUtility::getDistanceToBoundary( g, v, x ), WException );
 
143
 
 
144
        v -= x * 2.0 * TRACKING_EPS;
 
145
        TS_ASSERT_DELTA( wtracking::WTrackingUtility::getDistanceToBoundary( g, v, x ), 2.0 * TRACKING_EPS, TRACKING_EPS );
 
146
 
 
147
        v = WVector3d( 2.9741, 3.527, 1.992 );
 
148
        WVector3d dir( 3, 4, -2.003 );
 
149
        dir = normalize( dir );
 
150
        double t = wtracking::WTrackingUtility::getDistanceToBoundary( g, v, dir );
 
151
        WVector3d res = v + dir * t;
 
152
        TS_ASSERT( wtracking::WTrackingUtility::onBoundary( g, res ) );
 
153
 
 
154
        v = WVector3d( 1.0, 0.0, 0.0 ) + x * 3.75 + y * 6.65 + z * 5.59;
 
155
        TS_ASSERT_DELTA( wtracking::WTrackingUtility::getDistanceToBoundary( g, v, y ), 0.35, TRACKING_EPS );
 
156
    }
 
157
 
 
158
    /**
 
159
     * Test if followToNextVoxel() returns a valid (inside the grid) position
 
160
     * in the next voxel (and not on any boundary).
 
161
     */
 
162
    void testFollowToNextVoxel()
 
163
    {
 
164
        {
 
165
            WVector3d x( 0.707, 0.707, 0.0 );
 
166
            WVector3d y( -0.707, 0.707, 0.0 );
 
167
            WVector3d z( 0.0, 0.0, 1.0 );
 
168
            x = normalize( x );
 
169
            y = normalize( y );
 
170
 
 
171
            boost::shared_ptr< WDataSetSingle > ds = buildTestData( WVector3d( 0.0, 1.0, 0.0 ) );
 
172
            boost::shared_ptr< WGridRegular3D > g = boost::shared_dynamic_cast< WGridRegular3D >( ds->getGrid() );
 
173
 
 
174
            wtracking::WTrackingUtility::JobType j;
 
175
            // TODO(wiebel): somehow changing the order of the last multiplication does not find the desired operator*
 
176
            j.first = WVector3d( 1.0, 0.0, 0.0 ) + ( x + y + z ) * ( wlimits::FLT_EPS + 0.7 ); // the starting point
 
177
            j.second = x; // initial direction
 
178
            TS_ASSERT( g->encloses( j.first ) );
 
179
 
 
180
            WVector3d v = j.first;
 
181
 
 
182
            TS_ASSERT( wtracking::WTrackingUtility::followToNextVoxel( ds, j, boost::bind( &This::simpleDirFunc, this, _1, _2 ) ) );
 
183
            TS_ASSERT( !wtracking::WTrackingUtility::onBoundary( g, j.first ) );
 
184
            TS_ASSERT( g->encloses( j.first ) );
 
185
            v += x * 0.8;
 
186
            TS_ASSERT_DELTA( length( j.first - v ), 0.0, 2.0 * TRACKING_EPS );
 
187
        }
 
188
    }
 
189
 
 
190
private:
 
191
    /**
 
192
     * A simple direction calculation function.
 
193
     *
 
194
     * \return A direction.
 
195
     */
 
196
    WVector3d simpleDirFunc( wtracking::WTrackingUtility::DataSetPtr, wtracking::WTrackingUtility::JobType const& )
 
197
    {
 
198
        WVector3d v( 1.0, 1.0, 0.0 );
 
199
        v = normalize( v );
 
200
        return v;
 
201
    }
 
202
 
 
203
    /**
 
204
     * Build a test dataset.
 
205
     *
 
206
     * \param data The vector for every voxel.
 
207
     *
 
208
     * \return the test dataset
 
209
     */
 
210
    boost::shared_ptr< WDataSetSingle > buildTestData( WVector3d data )
 
211
    {
 
212
        WVector3d x( 0.707, 0.707, 0.0 );
 
213
        WVector3d y( -0.707, 0.707, 0.0 );
 
214
        WVector3d z( 0.0, 0.0, 1.0 );
 
215
 
 
216
        x = normalize( x );
 
217
        y = normalize( y );
 
218
 
 
219
        y *= 2.0;
 
220
        z *= 1.5;
 
221
 
 
222
        WMatrix< double > mat( 4, 4 );
 
223
        mat.makeIdentity();
 
224
        mat( 0, 0 ) = x[ 0 ];
 
225
        mat( 1, 0 ) = x[ 1 ];
 
226
        mat( 2, 0 ) = x[ 2 ];
 
227
        mat( 0, 1 ) = y[ 0 ];
 
228
        mat( 1, 1 ) = y[ 1 ];
 
229
        mat( 2, 1 ) = y[ 2 ];
 
230
        mat( 0, 2 ) = z[ 0 ];
 
231
        mat( 1, 2 ) = z[ 1 ];
 
232
        mat( 2, 2 ) = z[ 2 ];
 
233
        mat( 0, 3 ) = 1.0;
 
234
 
 
235
        WGridTransformOrtho t( mat );
 
236
        boost::shared_ptr< WGrid > g( new WGridRegular3D( 5, 5, 5, t ) );
 
237
 
 
238
        data = normalize( data );
 
239
 
 
240
        boost::shared_ptr< std::vector< double > > v = boost::shared_ptr< std::vector< double > >( new  std::vector< double > ( 5 * 5 * 5 * 3 ) );
 
241
        for( std::size_t k = 0; k < 5 * 5 * 5; ++k )
 
242
        {
 
243
            v->at( 3 * k + 0 ) = data[ 0 ];
 
244
            v->at( 3 * k + 1 ) = data[ 1 ];
 
245
            v->at( 3 * k + 2 ) = data[ 2 ];
 
246
        }
 
247
 
 
248
        boost::shared_ptr< WValueSetBase > vs( new WValueSet< double >( 1, 3, v, W_DT_DOUBLE ) );
 
249
        return boost::shared_ptr< WDataSetSingle >( new WDataSetSingle( vs, g ) );
 
250
    }
 
251
};
 
252
 
 
253
/**
 
254
 * \class WThreadedTrackingFunctionTest
 
255
 *
 
256
 * Test the WThreadedTrackingFunction class.
 
257
 */
 
258
class WThreadedTrackingFunctionTest : public CxxTest::TestSuite
 
259
{
 
260
    //! a handy abbreviation
 
261
    typedef WThreadedTrackingFunctionTest This;
 
262
 
 
263
public:
 
264
    /**
 
265
     * Test if everything gets initialized correctly.
 
266
     */
 
267
    void testIndexInitialization()
 
268
    {
 
269
        std::vector< int > v0;
 
270
        std::vector< int > v1;
 
271
        std::size_t numSeeds = 1;
 
272
        std::size_t seedsPerPosition = 1;
 
273
 
 
274
        boost::shared_ptr< WDataSetSingle > ds = buildTestData( WVector3d( 1.0, 0.0, 0.0 ), 5 );
 
275
        boost::shared_ptr< WGridRegular3D > g = boost::shared_dynamic_cast< WGridRegular3D >( ds->getGrid() );
 
276
        TS_ASSERT( g );
 
277
 
 
278
        {
 
279
            wtracking::WThreadedTrackingFunction::IndexType i;
 
280
            i = wtracking::WThreadedTrackingFunction::IndexType( g, v0, v1, numSeeds, seedsPerPosition );
 
281
 
 
282
            // new test if everything was initialized correctly
 
283
            TS_ASSERT_EQUALS( i.m_done, false );
 
284
            TS_ASSERT_EQUALS( i.m_offset, 1.0 );
 
285
            TS_ASSERT_EQUALS( i.m_pos[ 0 ], 1 );
 
286
            TS_ASSERT_EQUALS( i.m_pos[ 1 ], 1 );
 
287
            TS_ASSERT_EQUALS( i.m_pos[ 2 ], 1 );
 
288
            TS_ASSERT_EQUALS( i.m_pos[ 3 ], 0 );
 
289
            TS_ASSERT_EQUALS( i.m_min[ 0 ], 1 );
 
290
            TS_ASSERT_EQUALS( i.m_min[ 1 ], 1 );
 
291
            TS_ASSERT_EQUALS( i.m_min[ 2 ], 1 );
 
292
            TS_ASSERT_EQUALS( i.m_min[ 3 ], 0 );
 
293
            TS_ASSERT_EQUALS( i.m_max[ 0 ], 4 );
 
294
            TS_ASSERT_EQUALS( i.m_max[ 1 ], 4 );
 
295
            TS_ASSERT_EQUALS( i.m_max[ 2 ], 4 );
 
296
            TS_ASSERT_EQUALS( i.m_max[ 3 ], 1 );
 
297
        }
 
298
        {
 
299
            v0.resize( 3 );
 
300
            v1.resize( 3 );
 
301
            v0[ 0 ] = 1;
 
302
            v0[ 1 ] = 2;
 
303
            v0[ 2 ] = 1;
 
304
            v1[ 0 ] = 3;
 
305
            v1[ 1 ] = 3;
 
306
            v1[ 2 ] = 4;
 
307
            numSeeds = 4;
 
308
            seedsPerPosition = 3;
 
309
 
 
310
            wtracking::WThreadedTrackingFunction::IndexType i;
 
311
            TS_ASSERT_THROWS_NOTHING( i = wtracking::WThreadedTrackingFunction::IndexType( g, v0, v1, numSeeds, seedsPerPosition ) );
 
312
 
 
313
            // new test if everything was initialized correctly
 
314
            TS_ASSERT_EQUALS( i.m_done, false );
 
315
            TS_ASSERT_EQUALS( i.m_offset, 0.25 );
 
316
            TS_ASSERT_EQUALS( i.m_pos[ 0 ], 4 );
 
317
            TS_ASSERT_EQUALS( i.m_pos[ 1 ], 8 );
 
318
            TS_ASSERT_EQUALS( i.m_pos[ 2 ], 4 );
 
319
            TS_ASSERT_EQUALS( i.m_pos[ 3 ], 0 );
 
320
            TS_ASSERT_EQUALS( i.m_min[ 0 ], 4 );
 
321
            TS_ASSERT_EQUALS( i.m_min[ 1 ], 8 );
 
322
            TS_ASSERT_EQUALS( i.m_min[ 2 ], 4 );
 
323
            TS_ASSERT_EQUALS( i.m_min[ 3 ], 0 );
 
324
            TS_ASSERT_EQUALS( i.m_max[ 0 ], 12 );
 
325
            TS_ASSERT_EQUALS( i.m_max[ 1 ], 12 );
 
326
            TS_ASSERT_EQUALS( i.m_max[ 2 ], 16 );
 
327
            TS_ASSERT_EQUALS( i.m_max[ 3 ], 3 );
 
328
        }
 
329
        {
 
330
            // now lets do something wrong
 
331
            wtracking::WThreadedTrackingFunction::IndexType i;
 
332
            v0[ 0 ] = -1;
 
333
            TS_ASSERT_THROWS( i = wtracking::WThreadedTrackingFunction::IndexType( g, v0, v1, numSeeds, seedsPerPosition ), WException );
 
334
            v0[ 0 ] = 0;
 
335
            v1[ 1 ] = 5;
 
336
            TS_ASSERT_THROWS( i = wtracking::WThreadedTrackingFunction::IndexType( g, v0, v1, numSeeds, seedsPerPosition ), WException );
 
337
        }
 
338
    }
 
339
 
 
340
    /**
 
341
     * Test if indices (seed positions) iteration works.
 
342
     */
 
343
    void testIndexIncrement()
 
344
    {
 
345
        std::vector< int > v0;
 
346
        std::vector< int > v1;
 
347
        std::size_t numSeeds = 1;
 
348
        std::size_t seedsPerPosition = 1;
 
349
 
 
350
        boost::shared_ptr< WDataSetSingle > ds = buildTestData( WVector3d( 1.0, 0.0, 0.0 ), 5 );
 
351
        boost::shared_ptr< WGridRegular3D > g = boost::shared_dynamic_cast< WGridRegular3D >( ds->getGrid() );
 
352
        TS_ASSERT( g );
 
353
 
 
354
        {
 
355
            wtracking::WThreadedTrackingFunction::IndexType i;
 
356
            TS_ASSERT_THROWS_NOTHING( i = wtracking::WThreadedTrackingFunction::IndexType( g, v0, v1, numSeeds, seedsPerPosition ) );
 
357
 
 
358
            for( int j = 0; j < 27; ++j )
 
359
            {
 
360
                TS_ASSERT( !i.done() );
 
361
                ++i;
 
362
            }
 
363
            TS_ASSERT( i.done() );
 
364
        }
 
365
        {
 
366
            numSeeds = 4;
 
367
            wtracking::WThreadedTrackingFunction::IndexType i;
 
368
            TS_ASSERT_THROWS_NOTHING( i = wtracking::WThreadedTrackingFunction::IndexType( g, v0, v1, numSeeds, seedsPerPosition ) );
 
369
 
 
370
            for( int j = 0; j < 27 * 64; ++j )
 
371
            {
 
372
                TS_ASSERT( !i.done() );
 
373
                ++i;
 
374
            }
 
375
            TS_ASSERT( i.done() );
 
376
        }
 
377
        {
 
378
            seedsPerPosition = 3;
 
379
            wtracking::WThreadedTrackingFunction::IndexType i;
 
380
            TS_ASSERT_THROWS_NOTHING( i = wtracking::WThreadedTrackingFunction::IndexType( g, v0, v1, numSeeds, seedsPerPosition ) );
 
381
 
 
382
            for( int j = 0; j < 27 * 64 * 3; ++j )
 
383
            {
 
384
                TS_ASSERT( !i.done() );
 
385
                ++i;
 
386
            }
 
387
            TS_ASSERT( i.done() );
 
388
        }
 
389
        {
 
390
            v0.resize( 3, 1 );
 
391
            v1.resize( 3 );
 
392
            v1[ 0 ] = 4;
 
393
            v1[ 1 ] = 3;
 
394
            v1[ 2 ] = 4;
 
395
            wtracking::WThreadedTrackingFunction::IndexType i;
 
396
            TS_ASSERT_THROWS_NOTHING( i = wtracking::WThreadedTrackingFunction::IndexType( g, v0, v1, numSeeds, seedsPerPosition ) );
 
397
 
 
398
            for( int j = 0; j < 18 * 64 * 3; ++j )
 
399
            {
 
400
                TS_ASSERT( !i.done() );
 
401
                ++i;
 
402
            }
 
403
            TS_ASSERT( i.done() );
 
404
        }
 
405
    }
 
406
 
 
407
    /**
 
408
     * Test if the right jobs get created from seeds.
 
409
     */
 
410
    void testIndexToJob()
 
411
    {
 
412
        WVector3d x( 0.707, 0.707, 0.0 );
 
413
        WVector3d y( -0.707, 0.707, 0.0 );
 
414
        WVector3d z( 0.0, 0.0, 1.0 );
 
415
        x = normalize( x );
 
416
        y = normalize( y );
 
417
        y *= 2.0;
 
418
        z *= 1.5;
 
419
 
 
420
        std::vector< int > v0;
 
421
        std::vector< int > v1;
 
422
        std::size_t numSeeds = 2;
 
423
        std::size_t seedsPerPosition = 1;
 
424
 
 
425
        boost::shared_ptr< WDataSetSingle > ds = buildTestData( WVector3d( 1.0, 0.0, 0.0 ), 5 );
 
426
        boost::shared_ptr< WGridRegular3D > g = boost::shared_dynamic_cast< WGridRegular3D >( ds->getGrid() );
 
427
        TS_ASSERT( g );
 
428
 
 
429
        {
 
430
            wtracking::WThreadedTrackingFunction::IndexType i;
 
431
            TS_ASSERT_THROWS_NOTHING( i = wtracking::WThreadedTrackingFunction::IndexType( g, v0, v1, numSeeds, seedsPerPosition ) );
 
432
 
 
433
            wtracking::WThreadedTrackingFunction::JobType job = i.job();
 
434
            WVector3d v = g->getOrigin() + 0.75 * x + 0.75 * y + 0.75 * z;
 
435
 
 
436
            std::cout << g->getOrigin() << std::endl;
 
437
 
 
438
            TS_ASSERT_DELTA( v[ 0 ], job.first[ 0 ], TRACKING_EPS );
 
439
            TS_ASSERT_DELTA( v[ 1 ], job.first[ 1 ], TRACKING_EPS );
 
440
            TS_ASSERT_DELTA( v[ 2 ], job.first[ 2 ], TRACKING_EPS );
 
441
 
 
442
            v += 0.5 * z;
 
443
            ++i;
 
444
            job = i.job();
 
445
            TS_ASSERT_DELTA( v[ 0 ], job.first[ 0 ], TRACKING_EPS );
 
446
            TS_ASSERT_DELTA( v[ 1 ], job.first[ 1 ], TRACKING_EPS );
 
447
            TS_ASSERT_DELTA( v[ 2 ], job.first[ 2 ], TRACKING_EPS );
 
448
 
 
449
            for( int k = 0; k < 6; ++k )
 
450
            {
 
451
                ++i;
 
452
            }
 
453
            v += 0.5 * y;
 
454
            job = i.job();
 
455
            TS_ASSERT_DELTA( v[ 0 ], job.first[ 0 ], TRACKING_EPS );
 
456
            TS_ASSERT_DELTA( v[ 1 ], job.first[ 1 ], TRACKING_EPS );
 
457
            TS_ASSERT_DELTA( v[ 2 ], job.first[ 2 ], TRACKING_EPS );
 
458
 
 
459
            for( int k = 0; k < 36; ++k )
 
460
            {
 
461
                ++i;
 
462
            }
 
463
            v += 0.5 * x;
 
464
            job = i.job();
 
465
            TS_ASSERT_DELTA( v[ 0 ], job.first[ 0 ], TRACKING_EPS );
 
466
            TS_ASSERT_DELTA( v[ 1 ], job.first[ 1 ], TRACKING_EPS );
 
467
            TS_ASSERT_DELTA( v[ 2 ], job.first[ 2 ], TRACKING_EPS );
 
468
 
 
469
            TS_ASSERT_EQUALS( job.second[ 0 ], 0.0 );
 
470
            TS_ASSERT_EQUALS( job.second[ 1 ], 0.0 );
 
471
            TS_ASSERT_EQUALS( job.second[ 2 ], 0.0 );
 
472
        }
 
473
        {
 
474
            numSeeds = 4;
 
475
            seedsPerPosition = 11;
 
476
            wtracking::WThreadedTrackingFunction::IndexType i;
 
477
            TS_ASSERT_THROWS_NOTHING( i = wtracking::WThreadedTrackingFunction::IndexType( g, v0, v1, numSeeds, seedsPerPosition ) );
 
478
 
 
479
            wtracking::WThreadedTrackingFunction::JobType job;
 
480
            WVector3d v = g->getOrigin() + 0.625 * x + 0.625 * y + 0.625 * z;
 
481
            for( int k = 0; k < 11; ++k )
 
482
            {
 
483
                job = i.job();
 
484
                TS_ASSERT_DELTA( v[ 0 ], job.first[ 0 ], TRACKING_EPS );
 
485
                TS_ASSERT_DELTA( v[ 1 ], job.first[ 1 ], TRACKING_EPS );
 
486
                TS_ASSERT_DELTA( v[ 2 ], job.first[ 2 ], TRACKING_EPS );
 
487
                ++i;
 
488
            }
 
489
        }
 
490
    }
 
491
 
 
492
    /**
 
493
     * Test if everything gets initialized correctly.
 
494
     */
 
495
    void testInstantiation()
 
496
    {
 
497
        boost::shared_ptr< WDataSetSingle > ds = buildTestData( WVector3d( 1.0, 0.0, 0.0 ), 5 );
 
498
        boost::shared_ptr< WGridRegular3D > g = boost::shared_dynamic_cast< WGridRegular3D >( ds->getGrid() );
 
499
        TS_ASSERT( g );
 
500
 
 
501
        TS_ASSERT_THROWS_NOTHING(
 
502
                wtracking::WThreadedTrackingFunction w( ds,
 
503
                                                        boost::bind( &This::dirFunc, this, _1, _2, WVector3d( 1.0, 0.0, 0.0 ) ),
 
504
                                                        boost::bind( &wtracking::WTrackingUtility::followToNextVoxel, _1, _2, _3 ),
 
505
                                                        boost::bind( &This::fibVis, this, _1 ),
 
506
                                                        boost::bind( &This::pntVis, this, _1 ) ) );
 
507
    }
 
508
 
 
509
    /**
 
510
     * Test if the correct amount of jobs gets created.
 
511
     */
 
512
    void testGetJob()
 
513
    {
 
514
        boost::shared_ptr< WDataSetSingle > ds = buildTestData( WVector3d( 1.0, 0.0, 0.0 ), 7 );
 
515
        boost::shared_ptr< WGridRegular3D > g = boost::shared_dynamic_cast< WGridRegular3D >( ds->getGrid() );
 
516
        TS_ASSERT( g );
 
517
 
 
518
        wtracking::WThreadedTrackingFunction w( ds, boost::bind( &This::dirFunc, this, _1, _2, WVector3d( 1.0, 0.0, 0.0 ) ),
 
519
                                                    boost::bind( &wtracking::WTrackingUtility::followToNextVoxel, _1, _2, _3 ),
 
520
                                                    boost::bind( &This::fibVis, this, _1 ),
 
521
                                                    boost::bind( &This::pntVis, this, _1 ) );
 
522
        wtracking::WThreadedTrackingFunction::JobType job;
 
523
        for( int i = 0; i < 125; ++i )
 
524
        {
 
525
            TS_ASSERT( w.getJob( job ) );
 
526
        }
 
527
        TS_ASSERT( !w.getJob( job ) );
 
528
    }
 
529
 
 
530
    /**
 
531
     * Test if fibers with the right number of points get created.
 
532
     */
 
533
    void testCompute()
 
534
    {
 
535
        WVector3d x( 0.707, 0.707, 0.0 );
 
536
        WVector3d y( -0.707, 0.707, 0.0 );
 
537
        WVector3d z( 0.0, 0.0, 1.0 );
 
538
        x = normalize( x );
 
539
        y = normalize( y );
 
540
 
 
541
        boost::shared_ptr< WDataSetSingle > ds = buildTestData( WVector3d( 1.0, 0.0, 0.0 ), 7 );
 
542
        boost::shared_ptr< WGridRegular3D > g = boost::shared_dynamic_cast< WGridRegular3D >( ds->getGrid() );
 
543
        TS_ASSERT( g );
 
544
        {
 
545
            wtracking::WThreadedTrackingFunction w( ds, boost::bind( &This::dirFunc, this, _1, _2, x ),
 
546
                                                        boost::bind( &wtracking::WTrackingUtility::followToNextVoxel, _1, _2, _3 ),
 
547
                                                        boost::bind( &This::fibVis, this, _1 ),
 
548
                                                        boost::bind( &This::pntVis, this, _1 ) );
 
549
            wtracking::WThreadedTrackingFunction::JobType job;
 
550
            m_points.getWriteTicket()->get() = 0;
 
551
            w.getJob( job );
 
552
            w.compute( ds, job );
 
553
            TS_ASSERT_EQUALS( m_points.getReadTicket()->get(), 7 );
 
554
        }
 
555
        {
 
556
            wtracking::WThreadedTrackingFunction w( ds, boost::bind( &This::dirFunc, this, _1, _2, y ),
 
557
                                                        boost::bind( &wtracking::WTrackingUtility::followToNextVoxel, _1, _2, _3 ),
 
558
                                                        boost::bind( &This::fibVis, this, _1 ),
 
559
                                                        boost::bind( &This::pntVis, this, _1 ) );
 
560
            wtracking::WThreadedTrackingFunction::JobType job;
 
561
            m_points.getWriteTicket()->get() = 0;
 
562
            w.getJob( job );
 
563
            w.compute( ds, job );
 
564
            TS_ASSERT_EQUALS( m_points.getReadTicket()->get(), 7 );
 
565
        }
 
566
    }
 
567
 
 
568
private:
 
569
    /**
 
570
     * Build a test dataset.
 
571
     *
 
572
     * \param data The vector for every voxel.
 
573
     * \param n The number of grid position in every direction.
 
574
     *
 
575
     * \return The dataset.
 
576
     */
 
577
    boost::shared_ptr< WDataSetSingle > buildTestData( WVector3d data, int n )
 
578
    {
 
579
        WVector3d x( 0.707, 0.707, 0.0 );
 
580
        WVector3d y( -0.707, 0.707, 0.0 );
 
581
        WVector3d z( 0.0, 0.0, 1.0 );
 
582
        x = normalize( x );
 
583
        y = normalize( y );
 
584
        y *= 2.0;
 
585
        z *= 1.5;
 
586
 
 
587
        WMatrix< double > mat( 4, 4 );
 
588
        mat.makeIdentity();
 
589
        mat( 0, 0 ) = x[ 0 ];
 
590
        mat( 1, 0 ) = x[ 1 ];
 
591
        mat( 2, 0 ) = x[ 2 ];
 
592
        mat( 0, 1 ) = y[ 0 ];
 
593
        mat( 1, 1 ) = y[ 1 ];
 
594
        mat( 2, 1 ) = y[ 2 ];
 
595
        mat( 0, 2 ) = z[ 0 ];
 
596
        mat( 1, 2 ) = z[ 1 ];
 
597
        mat( 2, 2 ) = z[ 2 ];
 
598
        mat( 0, 3 ) = 1.0;
 
599
 
 
600
        WGridTransformOrtho t( mat );
 
601
        boost::shared_ptr< WGrid > g( new WGridRegular3D( n, n, n, t ) );
 
602
 
 
603
        data = normalize( data );
 
604
 
 
605
        boost::shared_ptr< std::vector< double > > v = boost::shared_ptr< std::vector< double > >( new  std::vector< double >( n * n * n * 3 ) );
 
606
        for( std::size_t k = 0; k < static_cast< std::size_t >( n * n * n ); ++k )
 
607
        {
 
608
            v->at( 3 * k + 0 ) = data[ 0 ];
 
609
            v->at( 3 * k + 1 ) = data[ 1 ];
 
610
            v->at( 3 * k + 2 ) = data[ 2 ];
 
611
        }
 
612
 
 
613
        boost::shared_ptr< WValueSetBase > vs( new WValueSet< double >( 1, 3, v, W_DT_DOUBLE ) );
 
614
        return boost::shared_ptr< WDataSetSingle >( new WDataSetSingle( vs, g ) );
 
615
    }
 
616
 
 
617
    /**
 
618
     * The direction computation function. Simply returns the parameter vector.
 
619
     *
 
620
     * \param j The current job.
 
621
     * \param d The direction to return.
 
622
     *
 
623
     * \return d
 
624
     */
 
625
    WVector3d dirFunc( wtracking::WThreadedTrackingFunction::DataSetPtr,
 
626
                              wtracking::WThreadedTrackingFunction::JobType const& j,
 
627
                              WVector3d d )
 
628
    {
 
629
        if( dot( j.second, d ) > 0.0 )
 
630
        {
 
631
            return d;
 
632
        }
 
633
        else
 
634
        {
 
635
            return d * -1.0;
 
636
        }
 
637
    }
 
638
 
 
639
    /**
 
640
     * The fiber visitor. Does nothing.
 
641
     */
 
642
    void fibVis( std::vector< WVector3d > const& )
 
643
    {
 
644
    }
 
645
 
 
646
    /**
 
647
     * The point visitor. Counts the number of points found.
 
648
     */
 
649
    void pntVis( WVector3d const& )
 
650
    {
 
651
        ++m_points.getWriteTicket()->get();
 
652
    }
 
653
 
 
654
    //! the number of points found
 
655
    WSharedObject< std::size_t > m_points;
 
656
};
 
657
 
 
658
#endif  // WTHREADEDTRACKINGFUNCTION_TEST_H