OpenWalnut  1.4.0
WDataSetFiberVector.cpp
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 }