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 #include <string> 00026 #include <algorithm> 00027 #include <vector> 00028 00029 #include "../common/WLogger.h" 00030 #include "../common/datastructures/WFiber.h" 00031 #include "WDataSet.h" 00032 #include "WDataSetFiberVector.h" 00033 00034 // prototype instance as singleton 00035 boost::shared_ptr< WPrototyped > WDataSetFiberVector::m_prototype = boost::shared_ptr< WPrototyped >(); 00036 00037 WDataSetFiberVector::WDataSetFiberVector() 00038 : WMixinVector< WFiber >(), 00039 WDataSet() 00040 { 00041 } 00042 00043 WDataSetFiberVector::WDataSetFiberVector( boost::shared_ptr< std::vector< WFiber > > fibs ) 00044 : WMixinVector< WFiber >( *fibs ), // COPYING this into this since, WMixinVector has no possibility for references or boost::shared_ptr 00045 WDataSet() 00046 { 00047 } 00048 00049 WDataSetFiberVector::WDataSetFiberVector( boost::shared_ptr< const WDataSetFibers > fiberDS ) 00050 : WMixinVector< WFiber >(), 00051 WDataSet() 00052 { 00053 if( !fiberDS.get() ) 00054 { 00055 wlog::error( "WDataSetFiberVector" ) << "During constructing a WDataSetFiberVector out of an empty WDataSetFibers"; 00056 return; 00057 } 00058 00059 if( fiberDS->getFilename() != "" ) 00060 { 00061 setFilename( fiberDS->getFilename() ); 00062 } 00063 size_t numLines = fiberDS->size(); 00064 const std::vector< size_t >& lineLengths = *fiberDS->getLineLengths(); 00065 reserve( numLines ); 00066 00067 while( size() < numLines ) 00068 { 00069 WFiber fib; 00070 for( size_t i = 0; i < lineLengths[ size() ]; ++i ) 00071 { 00072 fib.push_back( fiberDS->getPosition( size(), i ) ); 00073 } 00074 push_back( fib ); 00075 } 00076 } 00077 00078 WDataSetFiberVector::WDataSetFiberVector( const WDataSetFiberVector& other ) 00079 : WMixinVector< WFiber >( other ), 00080 WDataSet() 00081 { 00082 } 00083 00084 WDataSetFiberVector& WDataSetFiberVector::operator=( const WDataSetFiberVector& other ) 00085 { 00086 if( this == &other ) 00087 { 00088 return *this; 00089 } 00090 assign( other.begin(), other.end() ); 00091 return *this; 00092 } 00093 00094 WDataSetFiberVector::~WDataSetFiberVector() 00095 { 00096 // since no pointer deallocation is needed, nothing to do here 00097 } 00098 00099 void WDataSetFiberVector::sortDescLength() 00100 { 00101 std::sort( begin(), end(), hasMorePointsThen ); 00102 } 00103 00104 boost::shared_ptr< WDataSetFiberVector > WDataSetFiberVector::generateDataSetOutOfUsedFibers( const std::vector< bool > &unused ) const 00105 { 00106 boost::shared_ptr< WDataSetFiberVector > result( new WDataSetFiberVector() ); 00107 assert( unused.size() == size() ); 00108 for( size_t i = 0 ; i < unused.size(); ++i ) 00109 { 00110 if( !unused[i] ) 00111 { 00112 result->push_back( at( i ) ); 00113 } 00114 } 00115 return result; 00116 } 00117 00118 bool WDataSetFiberVector::isTexture() const 00119 { 00120 return false; 00121 } 00122 00123 const std::string WDataSetFiberVector::getName() const 00124 { 00125 return "WDataSetFiberVector"; 00126 } 00127 00128 const std::string WDataSetFiberVector::getDescription() const 00129 { 00130 return "Contains tracked fiber data."; 00131 } 00132 00133 boost::shared_ptr< WPrototyped > WDataSetFiberVector::getPrototype() 00134 { 00135 if( !m_prototype ) 00136 { 00137 m_prototype = boost::shared_ptr< WPrototyped >( new WDataSetFiberVector() ); 00138 } 00139 00140 return m_prototype; 00141 } 00142 00143 boost::shared_ptr< WDataSetFibers > WDataSetFiberVector::toWDataSetFibers() const 00144 { 00145 boost::shared_ptr< std::vector< float > > points( new std::vector< float > ); 00146 boost::shared_ptr< std::vector< size_t > > fiberStartIndices( new std::vector< size_t > ); 00147 boost::shared_ptr< std::vector< size_t > > fiberLengths( new std::vector< size_t > ); 00148 boost::shared_ptr< std::vector< size_t > > pointFiberMapping( new std::vector< size_t > ); 00149 00150 fiberStartIndices->reserve( size() ); 00151 fiberLengths->reserve( size() ); 00152 // other reserving for points and pointFiberMapping is not possible here without cycling through the whole data 00153 00154 size_t fiberID = 0; 00155 for( const_iterator cit = begin(); cit != end(); ++cit, ++fiberID ) 00156 { 00157 const WFiber& fib = *cit; 00158 // the division by 3 is necessary since it carries the point numbers not the number of the i'th component 00159 fiberStartIndices->push_back( points->size() / 3 ); 00160 fiberLengths->push_back( fib.size() ); 00161 for( WFiber::const_iterator fit = fib.begin(); fit != fib.end(); ++fit ) 00162 { 00163 points->push_back( ( *fit )[0] ); 00164 points->push_back( ( *fit )[1] ); 00165 points->push_back( ( *fit )[2] ); 00166 pointFiberMapping->push_back( fiberID ); 00167 } 00168 } 00169 00170 return boost::shared_ptr< WDataSetFibers >( new WDataSetFibers( points, fiberStartIndices, fiberLengths, pointFiberMapping ) ); 00171 } 00172 00173 boost::shared_ptr< WFiber > centerLine( boost::shared_ptr< const WDataSetFiberVector > tracts ) 00174 { 00175 if( !tracts || tracts->empty() ) // invalid data produces invalid center lines 00176 { 00177 return boost::shared_ptr< WFiber >( new WFiber() ); 00178 } 00179 00180 size_t avgTractSize = 0; 00181 for( WDataSetFiberVector::const_iterator cit = tracts->begin(); cit != tracts->end(); ++cit ) 00182 { 00183 avgTractSize += cit->size(); 00184 } 00185 avgTractSize /= tracts->size(); 00186 00187 WFiber firstTract( tracts->front() ); 00188 firstTract.resampleByNumberOfPoints( avgTractSize ); 00189 boost::shared_ptr< WFiber > result( new WFiber( firstTract ) ); // copy the first tract into result centerline 00190 00191 for( size_t tractIndex = 1; tractIndex < tracts->size(); ++tractIndex ) 00192 { 00193 WFiber other( tracts->at( tractIndex ) ); 00194 other.resampleByNumberOfPoints( avgTractSize ); 00195 other.unifyDirectionBy( firstTract ); 00196 00197 for( size_t pointIndex = 0; pointIndex < avgTractSize; ++pointIndex ) 00198 { 00199 result->at( pointIndex ) += other[ pointIndex ]; 00200 } 00201 } 00202 00203 for( size_t pointIndex = 0; pointIndex < avgTractSize; ++pointIndex ) 00204 { 00205 result->at( pointIndex ) /= static_cast< double >( tracts->size() ); 00206 } 00207 00208 return result; 00209 } 00210 00211 boost::shared_ptr< WFiber > longestLine( boost::shared_ptr< const WDataSetFiberVector > tracts ) 00212 { 00213 if( !tracts || tracts->empty() ) // invalid data produces invalid longest lines 00214 { 00215 return boost::shared_ptr< WFiber >( new WFiber() ); 00216 } 00217 00218 size_t maxSize = 0; 00219 size_t maxIndex = 0; 00220 00221 for( size_t tractIndex = 0; tractIndex < tracts->size(); ++tractIndex ) 00222 { 00223 if( maxSize < tracts->at( tractIndex ).size() ) 00224 { 00225 maxSize = tracts->at( tractIndex ).size(); 00226 maxIndex = tractIndex; 00227 } 00228 } 00229 00230 return boost::shared_ptr< WFiber >( new WFiber( tracts->at( maxIndex ) ) ); 00231 } 00232 00233 boost::shared_ptr< WFiber > centerLine( boost::shared_ptr< const WDataSetFibers > tracts ) 00234 { 00235 return centerLine( boost::shared_ptr< WDataSetFiberVector >( new WDataSetFiberVector( tracts ) ) ); 00236 } 00237 00238 boost::shared_ptr< WFiber > longestLine( boost::shared_ptr< const WDataSetFibers > tracts ) 00239 { 00240 return longestLine( boost::shared_ptr< WDataSetFiberVector >( new WDataSetFiberVector( tracts ) ) ); 00241 }