OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #ifndef WFIBERCLUSTER_TEST_H 00026 #define WFIBERCLUSTER_TEST_H 00027 00028 #include <list> 00029 00030 #include <cxxtest/TestSuite.h> 00031 00032 #include "../../../common/WLimits.h" 00033 #include "../../../common/WLogger.h" 00034 #include "../../test/WDataSetFiberVectorTraits.h" 00035 #include "../WFiberCluster.h" 00036 00037 /** 00038 * Unit test the WFiberCluster class 00039 */ 00040 class WFiberClusterTest : public CxxTest::TestSuite 00041 { 00042 public: 00043 /** 00044 * When merging two clusters the indices are merged and the second cluster 00045 * becomes empty. 00046 */ 00047 void testMerge( void ) 00048 { 00049 WFiberCluster a( 1 ); 00050 WFiberCluster b; 00051 size_t mydata[] = { 16, 2, 77, 29 }; // NOLINT 00052 std::list< size_t > data( mydata, mydata + sizeof( mydata ) / sizeof( size_t ) ); 00053 b.m_memberIndices = data; 00054 a.merge( b ); 00055 TS_ASSERT( b.empty() ); 00056 size_t mxdata[] = { 1, 16, 2, 77, 29 }; // NOLINT 00057 std::list< size_t > xdata( mxdata, mxdata + sizeof( mxdata ) / sizeof( size_t ) ); 00058 WFiberCluster expected; 00059 expected.m_memberIndices = xdata; 00060 TS_ASSERT_EQUALS( expected, a ); 00061 } 00062 00063 /** 00064 * Generates a dataset for some unit tests. 00065 \verbatim 00066 Fiber B had initially 3 points: [0;2],[2;2],[4;2] after resampling there are 5 points: 00067 [0;2],[1;2],[2;2],[3;2],[4;2] 00068 Fiber A had initially 7 points: [0;0],[1;1],[2;1],[3;1],[4;1],[5;1],[6;1] after resampling there are 5 points: 00069 [0;0],[1.5;1],[3;1],[4.5;1],[6;1] 00070 00071 | 00072 2 -B----B-----B------B-----B 00073 | 00074 | 00075 | ,.m------m---------m-------m (center line) 00076 | / 00077 | / 00078 1 -m aA----a--A--a---A-a----Aa-----A 00079 | / 00080 | / 00081 | / 00082 | / 00083 |/ 00084 A-----+-----+-----+-----+-----+-----+--- 00085 0 1 2 3 4 5 6 00086 00087 \endverbatim 00088 */ 00089 void testCenterLine( void ) 00090 { 00091 WFiber expected; 00092 expected.push_back( WPosition( 0, 1, 0 ) ); 00093 expected.push_back( WPosition( ( ( 9.0 - 3 * std::sqrt( 2.0 ) ) / 4.0 - 1.0 ) / 2.0 + 1, 1.5, 0 ) ); 00094 expected.push_back( WPosition( ( ( 9.0 - 3 * std::sqrt( 2.0 ) ) / 4.0 + ( 5 + std::sqrt( 2.0 ) ) / 4.0 - 2.0 ) / 2.0 + 2, 1.5, 0 ) ); 00095 expected.push_back( WPosition( ( ( 9.0 - 3 * std::sqrt( 2.0 ) ) / 4.0 + 2 * ( 5 + std::sqrt( 2.0 ) ) / 4.0 - 3.0 ) / 2.0 + 3, 1.5, 0 ) ); 00096 expected.push_back( WPosition( 5, 1.5, 0 ) ); 00097 m_cluster->generateCenterLine(); 00098 assert_equals_delta( *m_cluster->getCenterLine(), expected, wlimits::FLT_EPS ); 00099 std::cout << *m_cluster->getDataSetReference() << std::endl; 00100 } 00101 00102 /** 00103 * If there are two fibers which are nearly parallel changing ones direction 00104 * will have huge effect 00105 */ 00106 void testUnifyDirectionOnTwoNearlyParallelFibers( void ) 00107 { 00108 WDataSetFiberVector expected( *m_cluster->getDataSetReference() ); // make a copy 00109 00110 boost::shared_ptr< WDataSetFiberVector > fibs( new WDataSetFiberVector( expected ) ); 00111 fibs->at( 1 ).reverseOrder(); // simulate wrong direction of the second fiber 00112 00113 m_cluster->unifyDirection( fibs ); 00114 using string_utils::operator<<; 00115 TS_ASSERT_EQUALS( *fibs, expected ); 00116 } 00117 00118 /** 00119 * Check determination of the direction of a pair of fibers which are in the following shape (all points having the same Y and Z coordinate). 00120 \verbatim 00121 AS--------------------------->AE BS------------------------->BE 00122 \endverbatim 00123 */ 00124 void testUnifyDirectionOnTwoConsecutiveFibers( void ) 00125 { 00126 WFiber a; 00127 a.push_back( WPosition( 0, 0, 0 ) ); 00128 a.push_back( WPosition( 1, 0, 0 ) ); 00129 a.push_back( WPosition( 2, 0, 0 ) ); 00130 a.push_back( WPosition( 3, 0, 0 ) ); 00131 a.push_back( WPosition( 4, 0, 0 ) ); 00132 a.push_back( WPosition( 5, 0, 0 ) ); 00133 a.push_back( WPosition( 6, 0, 0 ) ); 00134 WFiber b; 00135 b.push_back( WPosition( 10, 0, 0 ) ); 00136 b.push_back( WPosition( 11, 0, 0 ) ); 00137 b.push_back( WPosition( 12, 0, 0 ) ); 00138 b.push_back( WPosition( 13, 0, 0 ) ); 00139 b.push_back( WPosition( 14, 0, 0 ) ); 00140 b.push_back( WPosition( 15, 0, 0 ) ); 00141 b.push_back( WPosition( 16, 0, 0 ) ); 00142 WDataSetFiberVector expected; 00143 expected.push_back( a ); 00144 expected.push_back( b ); 00145 00146 boost::shared_ptr< WDataSetFiberVector > ds( new WDataSetFiberVector( expected ) ); 00147 ds->at( 1 ).reverseOrder(); 00148 m_cluster->unifyDirection( ds ); 00149 TS_ASSERT_EQUALS( *ds, expected ); // second tract should flip over 00150 m_cluster->unifyDirection( ds ); 00151 TS_ASSERT_EQUALS( *ds, expected ); // no tract should flip over 00152 } 00153 00154 /** 00155 * Check determination of the direction of a pair of fibers which are in the following shape. 00156 * 00157 \verbatim 00158 AS. _BS 00159 `. ,-' 00160 `. / 00161 \ / 00162 \ | 00163 `. .' 00164 | | 00165 | | 00166 | | 00167 | | 00168 | | 00169 | | 00170 AE BE 00171 \endverbatim 00172 */ 00173 void testUnifyDirectionOnTwoCSTShapedFibers( void ) 00174 { 00175 WFiber a; 00176 a.push_back( WPosition( 0, 0, 0 ) ); 00177 a.push_back( WPosition( 5, 1, 0 ) ); 00178 a.push_back( WPosition( 8, 3, 0 ) ); 00179 a.push_back( WPosition( 11, 7, 0 ) ); 00180 a.push_back( WPosition( 11, 10, 0 ) ); 00181 a.push_back( WPosition( 11, 12, 0 ) ); 00182 WFiber b; 00183 b.push_back( WPosition( 23, 0, 0 ) ); 00184 b.push_back( WPosition( 19, 2, 0 ) ); 00185 b.push_back( WPosition( 17, 5, 0 ) ); 00186 b.push_back( WPosition( 15, 7, 0 ) ); 00187 b.push_back( WPosition( 16, 10, 0 ) ); 00188 b.push_back( WPosition( 16, 12, 0 ) ); 00189 WDataSetFiberVector expected; 00190 expected.push_back( a ); 00191 expected.push_back( b ); 00192 00193 boost::shared_ptr< WDataSetFiberVector > ds( new WDataSetFiberVector( expected ) ); 00194 ds->at( 1 ).reverseOrder(); 00195 m_cluster->unifyDirection( ds ); 00196 TS_ASSERT_EQUALS( *ds, expected ); // second tract should flip over 00197 m_cluster->unifyDirection( ds ); 00198 TS_ASSERT_EQUALS( *ds, expected ); // no tract should flip over 00199 } 00200 00201 /** 00202 * Check determination of the direction of a pair of fibers which are in the following shape. 00203 * 00204 \verbatim 00205 _.-----AS 00206 ,' 00207 / ,-'BS 00208 | ,' 00209 | / AE 00210 | / BE | 00211 | | | | 00212 | | | | 00213 \ \ ,| | 00214 \ `. ,Y' _,' 00215 `\_ `'''''' _.' 00216 '`--------'' 00217 \endverbatim 00218 */ 00219 void testUnifyDirectionOnTwoCircularShapedFibersInSameCircle( void ) 00220 { 00221 WFiber a; 00222 a.push_back( WPosition( 14, 0, 0 ) ); 00223 a.push_back( WPosition( 5, 1, 0 ) ); 00224 a.push_back( WPosition( 2, 4, 0 ) ); 00225 a.push_back( WPosition( 3, 9, 0 ) ); 00226 a.push_back( WPosition( 11, 11, 0 ) ); 00227 a.push_back( WPosition( 19, 10, 0 ) ); 00228 a.push_back( WPosition( 24, 8, 0 ) ); 00229 a.push_back( WPosition( 23, 4, 0 ) ); 00230 WFiber b; 00231 b.push_back( WPosition( 13, 2, 0 ) ); 00232 b.push_back( WPosition( 7, 4, 0 ) ); 00233 b.push_back( WPosition( 6, 8, 0 ) ); 00234 b.push_back( WPosition( 10, 10, 0 ) ); 00235 b.push_back( WPosition( 17, 9, 0 ) ); 00236 b.push_back( WPosition( 19, 7, 0 ) ); 00237 b.push_back( WPosition( 19, 5, 0 ) ); 00238 WDataSetFiberVector expected; 00239 expected.push_back( a ); 00240 expected.push_back( b ); 00241 00242 boost::shared_ptr< WDataSetFiberVector > ds( new WDataSetFiberVector( expected ) ); 00243 ds->at( 1 ).reverseOrder(); 00244 m_cluster->unifyDirection( ds ); 00245 TS_ASSERT_EQUALS( *ds, expected ); // second tract should flip over 00246 m_cluster->unifyDirection( ds ); 00247 TS_ASSERT_EQUALS( *ds, expected ); // no tract should flip over 00248 } 00249 00250 /** 00251 * Check determination of the direction of a pair of fibers which are in the following shape. 00252 * 00253 \verbatim 00254 ,,---._ 00255 ,' \ 00256 / \ 00257 | | 00258 \ ,' 00259 \ ,' 00260 `-AS AE 00261 BS BE 00262 ,' `. 00263 / \ 00264 | | 00265 | | 00266 | | 00267 \ / 00268 `-._ _,-' 00269 `'' 00270 \endverbatim 00271 */ 00272 void testUnifyDirectionOnTwoCircularShapedFibersInDifferentCircle( void ) 00273 { 00274 WFiber a; 00275 a.push_back( WPosition( 6, 6, 0 ) ); 00276 a.push_back( WPosition( 3, 5, 0 ) ); 00277 a.push_back( WPosition( 2, 3, 0 ) ); 00278 a.push_back( WPosition( 4, 1, 0 ) ); 00279 a.push_back( WPosition( 7, 0, 0 ) ); 00280 a.push_back( WPosition( 11, 0, 0 ) ); 00281 a.push_back( WPosition( 14, 2, 0 ) ); 00282 a.push_back( WPosition( 13, 4, 0 ) ); 00283 a.push_back( WPosition( 11, 6, 0 ) ); 00284 WFiber b; 00285 b.push_back( WPosition( 6, 7, 0 ) ); 00286 b.push_back( WPosition( 3, 9, 0 ) ); 00287 b.push_back( WPosition( 1, 11, 0 ) ); 00288 b.push_back( WPosition( 3, 14, 0 ) ); 00289 b.push_back( WPosition( 8, 15, 0 ) ); 00290 b.push_back( WPosition( 13, 14, 0 ) ); 00291 b.push_back( WPosition( 15, 12, 0 ) ); 00292 b.push_back( WPosition( 14, 9, 0 ) ); 00293 b.push_back( WPosition( 11, 7, 0 ) ); 00294 WDataSetFiberVector expected; 00295 expected.push_back( a ); 00296 expected.push_back( b ); 00297 00298 boost::shared_ptr< WDataSetFiberVector > ds( new WDataSetFiberVector( expected ) ); 00299 ds->at( 1 ).reverseOrder(); 00300 m_cluster->unifyDirection( ds ); 00301 TS_ASSERT_EQUALS( *ds, expected ); // second tract should flip over 00302 m_cluster->unifyDirection( ds ); 00303 TS_ASSERT_EQUALS( *ds, expected ); // no tract should flip over 00304 } 00305 00306 /** 00307 * Check determination of the direction of a pair of fibers which are in the following shape. 00308 * 00309 \verbatim 00310 ,,-'-AE BS''`-._ 00311 ,' `. 00312 / \ 00313 / `. 00314 / `. 00315 / | 00316 | | 00317 | | 00318 | | 00319 | | 00320 | | 00321 | | 00322 AS BE 00323 \endverbatim 00324 */ 00325 void testUnifyDirectionOnTwoInverseCSTShapedFibers( void ) 00326 { 00327 WFiber a; 00328 a.push_back( WPosition( 1, 12, 0 ) ); 00329 a.push_back( WPosition( 1, 9, 0 ) ); 00330 a.push_back( WPosition( 2, 5, 0 ) ); 00331 a.push_back( WPosition( 5, 1, 0 ) ); 00332 a.push_back( WPosition( 9, 0, 0 ) ); 00333 a.push_back( WPosition( 14, 0, 0 ) ); 00334 WFiber b; 00335 b.push_back( WPosition( 19, 0, 0 ) ); 00336 b.push_back( WPosition( 24, 0, 0 ) ); 00337 b.push_back( WPosition( 29, 2, 0 ) ); 00338 b.push_back( WPosition( 32, 5, 0 ) ); 00339 b.push_back( WPosition( 33, 8, 0 ) ); 00340 b.push_back( WPosition( 33, 12, 0 ) ); 00341 WDataSetFiberVector expected; 00342 expected.push_back( a ); 00343 expected.push_back( b ); 00344 00345 boost::shared_ptr< WDataSetFiberVector > ds( new WDataSetFiberVector( expected ) ); 00346 ds->at( 1 ).reverseOrder(); 00347 m_cluster->unifyDirection( ds ); 00348 TS_ASSERT_EQUALS( *ds, expected ); // second tract should flip over 00349 m_cluster->unifyDirection( ds ); 00350 TS_ASSERT_EQUALS( *ds, expected ); // no tract should flip over 00351 } 00352 00353 private: 00354 /** 00355 * Compares to point sequences (aka lines) with a given delta. 00356 * 00357 * \param first First line to compare with 00358 * \param second Second line to compare with 00359 * \param delta The delta within two points are considered as equally 00360 */ 00361 void assert_equals_delta( const WLine& first, const WLine& second, double delta = wlimits::DBL_EPS ) const 00362 { 00363 int diffPos = 0; 00364 if( ( diffPos = equalsDelta( first, second, delta ) ) != -1 ) 00365 { 00366 using string_utils::operator<<; 00367 std::stringstream msg; 00368 msg << "Lines are different in at least point: " << diffPos; 00369 TS_FAIL( msg.str() ); 00370 std::cout << "first line at: " << diffPos << std::endl << first[diffPos] << std::endl; 00371 std::cout << "second line at: " << diffPos << std::endl << second[diffPos] << std::endl; 00372 std::cout << "first line: " << std::endl << first << std::endl; 00373 std::cout << "second line: " << std::endl << second << std::endl; 00374 } 00375 } 00376 00377 /** 00378 * Generates a dataset for some unit tests. 00379 \verbatim 00380 Fiber B has 3 points: [0;2],[2;2],[4;2] 00381 Fiber A has 7 points: [0;0],[1;1],[2;1],[3;1],[4;1],[5;1],[6;1] 00382 00383 | 00384 2 -b----------b------------b 00385 | 00386 | 00387 | 00388 | 00389 | 00390 1 -| a-----a-----a-----a-----a-----a 00391 | / 00392 | / 00393 | / 00394 | / 00395 |/ 00396 a-----+-----+-----+-----+-----+-----+--- 00397 0 1 2 3 4 5 6 00398 00399 \endverbatim 00400 */ 00401 void setUp( void ) 00402 { 00403 // generate fiber dataset to operate on 00404 WFiber fib_a; 00405 fib_a.push_back( WPosition( 0, 0, 0 ) ); 00406 fib_a.push_back( WPosition( 1, 1, 0 ) ); 00407 fib_a.push_back( WPosition( 2, 1, 0 ) ); 00408 fib_a.push_back( WPosition( 3, 1, 0 ) ); 00409 fib_a.push_back( WPosition( 4, 1, 0 ) ); 00410 fib_a.push_back( WPosition( 5, 1, 0 ) ); 00411 fib_a.push_back( WPosition( 6, 1, 0 ) ); 00412 WFiber fib_b; 00413 fib_b.push_back( WPosition( 0, 2, 0 ) ); 00414 fib_b.push_back( WPosition( 2, 2, 0 ) ); 00415 fib_b.push_back( WPosition( 4, 2, 0 ) ); 00416 boost::shared_ptr< WDataSetFiberVector > ds( new WDataSetFiberVector() ); 00417 ds->push_back( fib_a ); 00418 ds->push_back( fib_b ); 00419 generateFiberCluster( ds ); 00420 } 00421 00422 /** 00423 * Generates out of the given dataset a WFiberCluster containing all fibers. 00424 * 00425 * \param ds The fiber dataset 00426 */ 00427 void generateFiberCluster( const boost::shared_ptr< WDataSetFiberVector > ds ) 00428 { 00429 m_cluster.reset(); 00430 m_cluster = boost::shared_ptr< WFiberCluster >( new WFiberCluster() ); 00431 m_cluster->setDataSetReference( ds ); 00432 std::list< size_t > idx; 00433 for( size_t i = 0; i < ds->size(); ++i ) 00434 { 00435 idx.push_back( i ); 00436 } 00437 m_cluster->setIndices( idx ); 00438 } 00439 00440 /** 00441 * Tidyups the dataset used in some unit tests 00442 */ 00443 void tearDown( void ) 00444 { 00445 m_cluster.reset(); 00446 } 00447 00448 boost::shared_ptr< WFiberCluster > m_cluster; //!< pre generated cluster for some unit tests 00449 }; 00450 00451 #endif // WFIBERCLUSTER_TEST_H