diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsBetweennessHistogram.cpp b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsBetweennessHistogram.cpp new file mode 100644 index 0000000000..3e42652d6f --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsBetweennessHistogram.cpp @@ -0,0 +1,132 @@ + +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile$ +Language: C++ +Date: $Date$ +Version: $Revision: 11989 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include + +#include + +#include + +mitk::ConnectomicsBetweennessHistogram::ConnectomicsBetweennessHistogram() +: m_Mode( UnweightedUndirectedMode ) +, m_CentralityMap() +{ + m_Subject = "Node Betweenness"; +} + +mitk::ConnectomicsBetweennessHistogram::~ConnectomicsBetweennessHistogram() +{ +} + +void mitk::ConnectomicsBetweennessHistogram::SetBetweennessCalculationMode( + const mitk::ConnectomicsBetweennessHistogram::BetweennessCalculationMode & mode ) +{ + m_Mode = mode; +} + +mitk::ConnectomicsBetweennessHistogram::BetweennessCalculationMode mitk::ConnectomicsBetweennessHistogram::GetBetweennessCalculationMode() +{ + return m_Mode; +} + +void mitk::ConnectomicsBetweennessHistogram::ComputeFromConnectomicsNetwork( ConnectomicsNetwork* source ) +{ + NetworkType* boostGraph = source->GetBoostGraph(); + IteratorType vertex_iterator_begin, vertex_iterator_end; + + m_CentralityMap.clear(); + m_CentralityMap.resize( source->GetNumberOfVertices() ); + + switch( m_Mode ) + { + case UnweightedUndirectedMode: + { + CalculateUnweightedUndirectedBetweennessCentrality( boostGraph, vertex_iterator_begin, vertex_iterator_end ); + break; + } + case WeightedUndirectedMode: + { + CalculateWeightedUndirectedBetweennessCentrality( boostGraph, vertex_iterator_begin, vertex_iterator_end ); + break; + } + } + + ConvertCentralityMapToHistogram(); +} + +void mitk::ConnectomicsBetweennessHistogram::CalculateUnweightedUndirectedBetweennessCentrality( + NetworkType* boostGraph, IteratorType vertex_iterator_begin, IteratorType vertex_iterator_end ) +{ + boost::brandes_betweenness_centrality( + *boostGraph, + boost::centrality_map( + boost::make_iterator_property_map( m_CentralityMap.begin(), boost::get( &mitk::ConnectomicsNetwork::NetworkNode::id, *boostGraph ), double() ) + ).vertex_index_map( boost::get( &mitk::ConnectomicsNetwork::NetworkNode::id, *boostGraph ) ) + ); + +} + +void mitk::ConnectomicsBetweennessHistogram::CalculateWeightedUndirectedBetweennessCentrality( + NetworkType* boostGraph, IteratorType vertex_iterator_begin, IteratorType vertex_iterator_end ) +{ + MBI_WARN << mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_UNIMPLEMENTED_FEATURE; +} + +void mitk::ConnectomicsBetweennessHistogram::ConvertCentralityMapToHistogram() +{ + double maximumFloat( 0.0 ); + + for ( int index( 0 ); index < m_CentralityMap.size(); index++ ) + { + if( m_CentralityMap[ index ] > maximumFloat ) + { + maximumFloat = m_CentralityMap[ index ]; + } + } + + // use the boost double to int converter + // it defaults to trunc + typedef boost::numeric::converter Double2Int ; + + // for rounding, reduces the number of nodes classed as zero + maximumFloat += 0.5; + + int maximumInt( 0 ); + try + { + maximumInt = Double2Int::convert( maximumFloat ); + } + catch ( boost::numeric::positive_overflow const& ) + { + MBI_WARN << mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_OUTSIDE_INTEGER_RANGE; + } + + m_HistogramVector.resize( maximumInt + 1 ); + + for ( int index( 0 ); index < m_CentralityMap.size(); index++ ) + { + int value( 0 ); + value = Double2Int::convert( ( m_CentralityMap[index ] + 0.5 ) ); + m_HistogramVector[ value ]++; + } + + UpdateYMax(); + + m_Valid = true; +} \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsBetweennessHistogram.h b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsBetweennessHistogram.h new file mode 100644 index 0000000000..33c683ecf9 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsBetweennessHistogram.h @@ -0,0 +1,82 @@ + +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile$ +Language: C++ +Date: $Date$ +Version: $Revision: 11989 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + + +#ifndef _MITK_ConnectomicsBetweennessHistogram_H +#define _MITK_ConnectomicsBetweennessHistogram_H + +#include + +#include + +namespace mitk { + + /** + * \brief A class to calculate and store the betweenness of each node */ + class ConnectomicsBetweennessHistogram : public mitk::ConnectomicsHistogramBase + { + + public: + + /** Enum for different ways to calculate betweenness centrality */ + + enum BetweennessCalculationMode + { + UnweightedUndirectedMode, + WeightedUndirectedMode + }; + + ConnectomicsBetweennessHistogram(); + virtual ~ConnectomicsBetweennessHistogram(); + + /** Set the calucaltion mode */ + void SetBetweennessCalculationMode( const BetweennessCalculationMode & ); + + /** Get the calculation mode */ + BetweennessCalculationMode GetBetweennessCalculationMode(); + + protected: + + /* Typedefs */ + typedef mitk::ConnectomicsNetwork::NetworkType NetworkType; + typedef boost::graph_traits< NetworkType >::vertex_iterator IteratorType; + typedef std::vector< double > BCMapType; + + /** @brief Creates a new histogram from the network source. */ + virtual void ComputeFromConnectomicsNetwork( ConnectomicsNetwork* source ); + + /** Calculate betweenness centrality ignoring the weight of the edges */ + void CalculateUnweightedUndirectedBetweennessCentrality( NetworkType*, IteratorType, IteratorType ); + + /** Calculate betweenness centrality taking into consideration the weight of the edges */ + void CalculateWeightedUndirectedBetweennessCentrality( NetworkType*, IteratorType, IteratorType ); + + /** Converts the centrality map to a histogram by binning */ + void ConvertCentralityMapToHistogram(); + + /** Stores which mode has been selected for betweenness centrality calculation */ + BetweennessCalculationMode m_Mode; + + /** Stores the betweenness centralities for each node */ + BCMapType m_CentralityMap; + }; + +} + +#endif /* _MITK_ConnectomicsBetweennessHistogram_H */ \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsDegreeHistogram.cpp b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsDegreeHistogram.cpp new file mode 100644 index 0000000000..061f335322 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsDegreeHistogram.cpp @@ -0,0 +1,60 @@ + +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile$ +Language: C++ +Date: $Date$ +Version: $Revision: 11989 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include + +mitk::ConnectomicsDegreeHistogram::ConnectomicsDegreeHistogram() +{ + m_Subject = "Node degree"; +} + +mitk::ConnectomicsDegreeHistogram::~ConnectomicsDegreeHistogram() +{ +} + +void mitk::ConnectomicsDegreeHistogram::ComputeFromConnectomicsNetwork( ConnectomicsNetwork* source ) +{ + std::vector< int > degreeOfNodesVector = source->GetDegreeOfNodes(); + + int maximumDegree( 0 ); + + for( int index( 0 ); index < degreeOfNodesVector.size(); index++ ) + { + if( maximumDegree < degreeOfNodesVector[ index ] ) + { + maximumDegree = degreeOfNodesVector[ index ]; + } + } + + this->m_HistogramVector.resize( maximumDegree + 1 ); + + for( int index( 0 ); index < m_HistogramVector.size(); index++ ) + { + this->m_HistogramVector[ index ] = 0; + } + this->m_TopValue = maximumDegree; + + for( int index( 0 ); index < degreeOfNodesVector.size(); index++ ) + { + this->m_HistogramVector[ degreeOfNodesVector[ index ] ]++; + + } + // successfully created a valid histogram + this->m_Valid = true; +} \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsDegreeHistogram.h b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsDegreeHistogram.h new file mode 100644 index 0000000000..325451273e --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsDegreeHistogram.h @@ -0,0 +1,49 @@ + +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile$ +Language: C++ +Date: $Date$ +Version: $Revision: 11989 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + + +#ifndef _MITK_ConnectomicsDegreeHistogram_H +#define _MITK_ConnectomicsDegreeHistogram_H + +#include + +namespace mitk { + + /** + * \brief A class to calculate and store the degree of each node */ + class ConnectomicsDegreeHistogram : public mitk::ConnectomicsHistogramBase + { + + public: + + ConnectomicsDegreeHistogram(); + virtual ~ConnectomicsDegreeHistogram(); + + + + protected: + + /** @brief Creates a new histogram from the network source. */ + virtual void ComputeFromConnectomicsNetwork( ConnectomicsNetwork* source ); + + }; + +} + +#endif /* _MITK_ConnectomicsDegreeHistogram_H */ \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsHistogramBase.cpp b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsHistogramBase.cpp new file mode 100644 index 0000000000..6235fc30d9 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsHistogramBase.cpp @@ -0,0 +1,228 @@ + + +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile$ +Language: C++ +Date: $Date$ +Version: $Revision: 11989 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include +#include + +#include + +mitk::ConnectomicsHistogramBase::ConnectomicsHistogramBase() +: m_Valid( false ) +, m_BaselineValue( 0 ) +, m_TopValue( 1 ) +, m_StartValue( 0 ) +, m_Subject( "" ) +{ +} + +mitk::ConnectomicsHistogramBase::~ConnectomicsHistogramBase() +{ +} + + +double mitk::ConnectomicsHistogramBase::GetYMin() const +{ + return m_BaselineValue; +} + +double mitk::ConnectomicsHistogramBase::GetYMax() const +{ + return m_TopValue; +} + +double mitk::ConnectomicsHistogramBase::GetMin() const +{ + return this->GetXMin(); +} + +double mitk::ConnectomicsHistogramBase::GetMax() const +{ + return this->GetXMax(); +} + +double mitk::ConnectomicsHistogramBase::GetXMin() const +{ + return m_StartValue; +} + +double mitk::ConnectomicsHistogramBase::GetXMax() const +{ + return ( m_StartValue + this->GetRange() ); +} + +int mitk::ConnectomicsHistogramBase::GetRange() const +{ + return m_HistogramVector.size(); +} + +bool mitk::ConnectomicsHistogramBase::IsValid() const +{ + return m_Valid; +} + +void mitk::ConnectomicsHistogramBase::PrintToConsole() const +{ + MITK_INFO << "Histogram - Maximum " << this->GetYMax() << " Minimum " << this->GetYMin() << " Range " << this->GetRange(); + + for( int index( 0 ); index < m_HistogramVector.size(); index++ ) + { + MITK_INFO << " Bin: " << index << " Value: " << m_HistogramVector[ index ]; + } +} + +std::string mitk::ConnectomicsHistogramBase::GetSubject() const +{ + return m_Subject; +} + +void mitk::ConnectomicsHistogramBase::SetSubject( std::string subject ) +{ + m_Subject = subject; +} + +void mitk::ConnectomicsHistogramBase::ComputeFromBaseData( BaseData* source ) +{ + m_Valid = false; + m_HistogramVector.clear(); + + //check if input is valid + if (source==NULL) + { // empty base data + return; + } + + mitk::ConnectomicsNetwork* networkSource = dynamic_cast(source); + + if (networkSource==NULL) + { // base data but no network + return; + } + + ComputeFromConnectomicsNetwork( networkSource ); +} + +float mitk::ConnectomicsHistogramBase::GetRelativeBin( double start, double end ) const +{ + // use the boost double to int converter + // it defaults to trunc + typedef boost::numeric::converter Double2Int ; + + float result( 0.0 ); + + if( !m_Valid ) + { + MITK_ERROR << mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_TRIED_TO_ACCESS_INVALID_HISTOGRAM; + return result; + } + + if( ( start < 0.0 ) || + ( end < 0.0 ) ) + { + MITK_ERROR << mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_PASSED_NEGATIVE_INDEX_TO_HISTOGRAM; + return result; + } + + // calculate result + if( std::abs( end - start ) <= 1.0 ) + { // if the bin size is one or less, we can do not need to interpolate + + int index( 0 ); + try + { + // show the value for n between n - .5 and n + .5 + double temp = ( start + end ) / 2.0; + index = Double2Int::convert( temp ); // By default throws positive_overflow() + } + catch ( boost::numeric::positive_overflow const& ) + { + MBI_WARN << mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_OUTSIDE_INTEGER_RANGE; + } + + if( index < m_HistogramVector.size() ) + { + result = m_HistogramVector[ index ]; + } + else + { + MBI_WARN << mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_BEYOND_SCOPE << + index << " on vector sized: " << m_HistogramVector.size(); + } + } + else + { // if the bin size is more than one we need to interpolate + + int indexStart( 0 ), indexEnd( 0 ); + + try + { + indexStart = Double2Int::convert( start ); + indexEnd = Double2Int::convert( end ); + } + catch ( boost::numeric::positive_overflow const& ) + { + MBI_WARN << mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_OUTSIDE_INTEGER_RANGE; + } + + if( ( indexStart < m_HistogramVector.size() ) && + ( indexEnd < m_HistogramVector.size() ) ) + { + // add up weighted values and divide by range + + // add partial start and end bin + + double startPercentage = 1.0 - start + indexStart; + double endPercentage = end - indexEnd; + + result += startPercentage * m_HistogramVector[ indexStart ]; + result += endPercentage * m_HistogramVector[ indexEnd ]; + + // add whole inbetween bins + for( int tempIndex = indexStart + 1; tempIndex < indexEnd; tempIndex++ ) + { + result += m_HistogramVector[ tempIndex ]; + } + } + else + { + MBI_WARN << mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_BEYOND_SCOPE << indexStart << " to " << + indexEnd << " on vector sized: " << m_HistogramVector.size(); + } + } + + // normalizeresult by dividing through maximum degree + result = result / GetYMax(); + return result; +} + +void mitk::ConnectomicsHistogramBase::UpdateYMax() +{ + for ( int index( 0 ); index < m_HistogramVector.size(); index++ ) + { + if( m_HistogramVector[ index ] > m_TopValue ) + { + m_TopValue = m_HistogramVector[ index ]; + } + } +} + +std::vector< double > mitk::ConnectomicsHistogramBase::GetHistogramVector() +{ + return m_HistogramVector; +} \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsHistogramBase.h b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsHistogramBase.h new file mode 100644 index 0000000000..ee5981640f --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsHistogramBase.h @@ -0,0 +1,103 @@ + +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile$ +Language: C++ +Date: $Date$ +Version: $Revision: 11989 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef _MITK_ConnectomicsHistogramBase_H +#define _MITK_ConnectomicsHistogramBase_H + +#include "mitkSimpleHistogram.h" +#include "mitkCommon.h" + +#include "mitkConnectomicsNetwork.h" + +namespace mitk { + + //##Documentation + //## @brief Superclass for histograms working with connectomic networks + + class ConnectomicsHistogramBase : public mitk::SimpleHistogram + { + + public: + + ConnectomicsHistogramBase(); + virtual ~ConnectomicsHistogramBase(); + + /** @brief Returns the minimal y=f(x) value of the histogram. */ + virtual double GetYMin() const; + /** @brief Returns the maximum y=f(x) value of the histogram. */ + virtual double GetYMax() const; + /** @brief Returns the minimal x value of the histogram. */ + virtual double GetXMin() const; + /** @brief Returns the maximum x value of the histogram. */ + virtual double GetXMax() const; + /** @brief Returns the range of the histogram. */ + virtual int GetRange() const; + /** @brief Update the Y maximum to the maximal value in the histogram */ + virtual void UpdateYMax(); + /** @brief Creates a new histogram from the source. */ + virtual void ComputeFromBaseData( BaseData* source ); + /** @brief Print values to console. */ + virtual void PrintToConsole( ) const; + /** @brief Returns whether the histogram can be considered valid. */ + virtual bool IsValid() const; + /** @brief Returns the subject of the histogram as a string. */ + virtual std::string GetSubject() const; + /** @brief Set the subject of the histogram as a string. */ + virtual void SetSubject( std::string ); + + /** @brief Get bin height for the bin between start and end*/ + virtual float GetRelativeBin( double start, double end ) const; + + /** @brief Get the double vector*/ + virtual std::vector< double > GetHistogramVector(); + + protected: + + // Functions + + /** @brief Creates a new histogram from the network source. */ + virtual void ComputeFromConnectomicsNetwork( ConnectomicsNetwork* source ) = 0; + /** @brief Legacy method, do no use */ + virtual double GetMin() const; + /** @brief Legacy method, do no use */ + virtual double GetMax() const; + + // Variables + + /** @brief Is this a valid histogram*/ + bool m_Valid; + /** @brief Which is the baseline value for the histogram + /* + /* This value should be zero for all network histograms */ + int m_BaselineValue; + /** @brief Which is the top value for the histogram */ + int m_TopValue; + /** @brief Which is the starting x value for the histogram */ + int m_StartValue; + + /** @brief We expect not continuous but discrete histograms */ + std::vector< double > m_HistogramVector; + + /** @brief Subject of the histogram as a string. */ + std::string m_Subject; + }; + +} + +#endif /* _MITK_ConnectomicsHistogramBase_H */ \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsHistogramCache.cpp b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsHistogramCache.cpp new file mode 100644 index 0000000000..183b3b5358 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsHistogramCache.cpp @@ -0,0 +1,84 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsHistogramCache.h" + +mitk::ConnectomicsHistogramCache::ConnectomicsHistogramCache() +{ +} + +mitk::ConnectomicsHistogramCache::~ConnectomicsHistogramCache() +{ +} + +mitk::ConnectomicsHistogramsContainer * mitk::ConnectomicsHistogramCache::operator[]( mitk::ConnectomicsNetwork::Pointer sp_NetworkData ) +{ + BaseData *p_BaseData = dynamic_cast< BaseData* >( sp_NetworkData.GetPointer() ); + + if(!p_BaseData) + { + MITK_WARN << "ConnectomicsHistogramCache::operator[] with null connectomics network data called"; + return 0; + } + + ConnectomicsHistogramsCacheElement *elementToUpdate = 0; + + bool first = true; + + for(CacheContainer::iterator iter = cache.begin(); iter != cache.end(); iter++) + { + ConnectomicsHistogramsCacheElement *e = dynamic_cast(*iter); + BaseData *p_tmp = e->baseData.GetPointer(); + + if(p_tmp == p_BaseData) + { + if(!first) + { + cache.erase(iter); + cache.push_front(e); + } + if( p_BaseData->GetMTime() > e->m_LastUpdateTime.GetMTime()) + goto recomputeElement; + + + return dynamic_cast( e->GetHistograms() ); + } + + first = false; + } + + if (dynamic_cast(p_BaseData)) + { + elementToUpdate = new ConnectomicsHistogramsCacheElement(); + } + else + { + MITK_WARN << "not supported: " << p_BaseData->GetNameOfClass(); + return NULL; + } + + elementToUpdate->baseData = p_BaseData; + cache.push_front(elementToUpdate); + TrimCache(); + + recomputeElement: + + elementToUpdate->ComputeFromBaseData(p_BaseData); + elementToUpdate->m_LastUpdateTime.Modified(); + return dynamic_cast( elementToUpdate->GetHistograms() ); +} + diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsHistogramCache.h b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsHistogramCache.h new file mode 100644 index 0000000000..78985554f0 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsHistogramCache.h @@ -0,0 +1,113 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + + +#ifndef MITKCONNECTOMICSHISTOGRAMCACHE_H +#define MITKCONNECTOMICSHISTOGRAMCACHE_H + +#include "mitkSimpleHistogram.h" +#include "mitkConnectomicsNetwork.h" + +#include +#include +#include + +#include "MitkDiffusionImagingExports.h" + +namespace mitk { + + //##Documentation + //## @brief Provides a method to cache network histograms + + class ConnectomicsHistogramsContainer + { + public: + + void ComputeFromBaseData(BaseData* baseData) + { + m_BetweennessHistogram.ComputeFromBaseData(baseData); + m_DegreeHistogram.ComputeFromBaseData(baseData); + m_ShortestPathHistogram.ComputeFromBaseData(baseData); + } + + ConnectomicsBetweennessHistogram* GetBetweennessHistogram( ) + { + return &m_BetweennessHistogram; + } + + ConnectomicsDegreeHistogram* GetDegreeHistogram( ) + { + return &m_DegreeHistogram; + } + + ConnectomicsShortestPathHistogram* GetShortestPathHistogram( ) + { + return &m_ShortestPathHistogram; + } + + ConnectomicsBetweennessHistogram m_BetweennessHistogram; + ConnectomicsDegreeHistogram m_DegreeHistogram; + ConnectomicsShortestPathHistogram m_ShortestPathHistogram; + }; + + class MitkDiffusionImaging_EXPORT ConnectomicsHistogramCache : public SimpleHistogramCache + { + public: + + ConnectomicsHistogramCache(); + ~ConnectomicsHistogramCache(); + + ConnectomicsHistogramsContainer *operator[]( ConnectomicsNetwork::Pointer sp_NetworkData); + + + protected: + + // purposely not implemented + SimpleHistogram *operator[](BaseData::Pointer sp_BaseData); + + }; + + + + class ConnectomicsHistogramsCacheElement : public ConnectomicsHistogramCache::Element + { + public: + + void ComputeFromBaseData(BaseData* baseData) + { + m_Container.ComputeFromBaseData(baseData); + } + + ConnectomicsHistogramsContainer* GetHistograms() + { + return &m_Container; + } + + ConnectomicsHistogramsContainer m_Container; + + private: + ConnectomicsHistogramBase* GetHistogram() + { + return NULL; + } + }; + + + +} + +#endif // MITKCONNECTOMICSHISTOGRAMCACHE_H diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsNetworkCreator.cpp b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsNetworkCreator.cpp new file mode 100644 index 0000000000..12317bfb1a --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsNetworkCreator.cpp @@ -0,0 +1,758 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsNetworkCreator.h" + +#include +#include + +#include "mitkConnectomicsConstantsManager.h" + +// VTK +#include +#include +#include + +mitk::ConnectomicsNetworkCreator::ConnectomicsNetworkCreator() +: m_FiberBundle() +, m_Segmentation() +, m_ConNetwork( mitk::ConnectomicsNetwork::New() ) +, idCounter(0) +, m_LabelToVertexMap() +, m_LabelToNodePropertyMap() +, allowLoops( false ) +{ +} + +mitk::ConnectomicsNetworkCreator::ConnectomicsNetworkCreator( mitk::Image::Pointer segmentation, mitk::FiberBundleX::Pointer fiberBundle ) +: m_FiberBundle(fiberBundle) +, m_Segmentation(segmentation) +, m_ConNetwork( mitk::ConnectomicsNetwork::New() ) +, idCounter(0) +, m_LabelToVertexMap() +, m_LabelToNodePropertyMap() +, allowLoops( false ) +{ +} + +mitk::ConnectomicsNetworkCreator::~ConnectomicsNetworkCreator() +{ +} + +void mitk::ConnectomicsNetworkCreator::SetFiberBundle(mitk::FiberBundleX::Pointer fiberBundle) +{ + m_FiberBundle = fiberBundle; +} + +void mitk::ConnectomicsNetworkCreator::SetSegmentation(mitk::Image::Pointer segmentation) +{ + m_Segmentation = segmentation; +} + +itk::Point mitk::ConnectomicsNetworkCreator::GetItkPoint(double point[3]) +{ + itk::Point itkPoint; + itkPoint[0] = point[0]; + itkPoint[1] = point[1]; + itkPoint[2] = point[2]; + return itkPoint; +} + +void mitk::ConnectomicsNetworkCreator::CreateNetworkFromFibersAndSegmentation() +{ + + //empty graph + m_ConNetwork->clear(); + m_LabelToVertexMap.clear(); + m_LabelToNodePropertyMap.clear(); + + vtkSmartPointer fiberPolyData = m_FiberBundle->GetFiberPolyData(); + vtkSmartPointer vLines = fiberPolyData->GetLines(); + vLines->InitTraversal(); + + //int numFibers = m_FiberBundle->GetNumFibers(); + int numFibers= 10; + for( int fiberID( 0 ); fiberID < numFibers; fiberID++ ) + { + vtkIdType numPointsInCell(0); + vtkIdType* pointsInCell(NULL); + vLines->GetNextCell ( numPointsInCell, pointsInCell ); + + TractType::Pointer singleTract = TractType::New(); + for( int pointInCellID( 0 ); pointInCellID < numPointsInCell ; pointInCellID++) + { + // push back point + PointType point = GetItkPoint( fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] ) ); + singleTract->InsertElement( singleTract->Size(), point ); + } + + //MappingStrategy strategy = EndElementPosition; + //MappingStrategy strategy = JustEndPointVerticesNoLabel; + MappingStrategy strategy = EndElementPositionAvoidingWhiteMatter; + if ( singleTract && ( singleTract->Size() > 0 ) ) + { + AddConnectionToNetwork( + ReturnAssociatedVertexPairForLabelPair( + ReturnLabelForFiberTract( singleTract, strategy ) + ) + ); + } + } + + // provide network with geometry + m_ConNetwork->SetGeometry( m_Segmentation->GetGeometry() ); + m_ConNetwork->SetIsModified( true ); + + MBI_INFO << mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_INFO_NETWORK_CREATED; +} + +void mitk::ConnectomicsNetworkCreator::AddConnectionToNetwork(ConnectionType newConnection) +{ + VertexType vertexA = newConnection.first; + VertexType vertexB = newConnection.second; + + // if vertices A and B exist + if( vertexA && vertexB) + { + // check for loops (if they are not allowed + if( allowLoops || !( vertexA == vertexB ) ) + { + // If the connection already exists, increment weight, else create connection + if ( m_ConNetwork->EdgeExists( vertexA, vertexB ) ) + { + m_ConNetwork->IncreaseEdgeWeight( vertexA, vertexB ); + } + else + { + m_ConNetwork->AddEdge( vertexA, vertexB ); + } + } + } +} + + +mitk::ConnectomicsNetworkCreator::VertexType mitk::ConnectomicsNetworkCreator::ReturnAssociatedVertexForLabel( ImageLabelType label ) +{ + // if label is not known, create entry + if( ! ( m_LabelToVertexMap.count( label ) > 0 ) ) + { + VertexType newVertex = m_ConNetwork->AddVertex( idCounter ); + idCounter++; + SupplyVertexWithInformation(label, newVertex); + m_LabelToVertexMap.insert( std::pair< ImageLabelType, VertexType >( label, newVertex ) ); + } + + //return associated vertex + return m_LabelToVertexMap.find( label )->second; +} + +mitk::ConnectomicsNetworkCreator::ConnectionType mitk::ConnectomicsNetworkCreator::ReturnAssociatedVertexPairForLabelPair( ImageLabelPairType labelpair ) +{ + //hand both labels through to the single label function + ConnectionType connection( ReturnAssociatedVertexForLabel(labelpair.first), ReturnAssociatedVertexForLabel(labelpair.second) ); + + return connection; +} + +mitk::ConnectomicsNetworkCreator::ImageLabelPairType mitk::ConnectomicsNetworkCreator::ReturnLabelForFiberTract( TractType::Pointer singleTract, mitk::ConnectomicsNetworkCreator::MappingStrategy strategy) +{ + switch( strategy ) + { + case EndElementPosition: + { + return EndElementPositionLabel( singleTract ); + } + case PrecomputeAndDistance: + { + return PrecomputeVertexLocationsBySegmentation( singleTract ); + } + case JustEndPointVerticesNoLabel: + { + return JustEndPointVerticesNoLabelTest( singleTract ); + } + case EndElementPositionAvoidingWhiteMatter: + { + return EndElementPositionLabelAvoidingWhiteMatter( singleTract ); + } + } + + // To remove warnings, this code should never be reached + MBI_ERROR << mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_INVALID_MAPPING; + ImageLabelPairType nullPair( NULL, NULL ); + return nullPair; +} + +mitk::ConnectomicsNetworkCreator::ImageLabelPairType mitk::ConnectomicsNetworkCreator::EndElementPositionLabel( TractType::Pointer singleTract ) +{ + ImageLabelPairType labelpair; + + {// Note: .fib image tracts are safed using index coordinates + mitk::Point3D firstElementFiberCoord, lastElementFiberCoord; + mitk::Point3D firstElementSegCoord, lastElementSegCoord; + mitk::Index3D firstElementSegIndex, lastElementSegIndex; + + if( singleTract->front().Size() != 3 ) + { + MBI_ERROR << mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_INVALID_DIMENSION_NEED_3; + } + for( int index = 0; index < singleTract->front().Size(); index++ ) + { + firstElementFiberCoord.SetElement( index, singleTract->front().GetElement( index ) ); + lastElementFiberCoord.SetElement( index, singleTract->back().GetElement( index ) ); + } + + // convert from fiber index coordinates to segmentation index coordinates + FiberToSegmentationCoords( firstElementFiberCoord, firstElementSegCoord ); + FiberToSegmentationCoords( lastElementFiberCoord, lastElementSegCoord ); + + for( int index = 0; index < 3; index++ ) + { + firstElementSegIndex.SetElement( index, firstElementSegCoord.GetElement( index ) ); + lastElementSegIndex.SetElement( index, lastElementSegCoord.GetElement( index ) ); + } + + int firstLabel = m_Segmentation->GetPixelValueByIndex( firstElementSegIndex ); + int lastLabel = m_Segmentation->GetPixelValueByIndex( lastElementSegIndex ); + + labelpair.first = firstLabel; + labelpair.second = lastLabel; + + // Add property to property map + if( ! ( m_LabelToNodePropertyMap.count( firstLabel ) > 0 ) ) + { + NetworkNode firstNode; + + firstNode.coordinates.resize( 3 ); + for( unsigned int index = 0; index < firstNode.coordinates.size() ; index++ ) + { + firstNode.coordinates[ index ] = firstElementSegIndex[ index ] ; + } + + firstNode.label = LabelToString( firstLabel ); + + m_LabelToNodePropertyMap.insert( std::pair< ImageLabelType, NetworkNode >( firstLabel, firstNode ) ); + } + + if( ! ( m_LabelToNodePropertyMap.count( lastLabel ) > 0 ) ) + { + NetworkNode lastNode; + + lastNode.coordinates.resize( 3 ); + for( unsigned int index = 0; index < lastNode.coordinates.size() ; index++ ) + { + lastNode.coordinates[ index ] = lastElementSegIndex[ index ] ; + } + + lastNode.label = LabelToString( lastLabel ); + + m_LabelToNodePropertyMap.insert( std::pair< ImageLabelType, NetworkNode >( lastLabel, lastNode ) ); + } + } + + return labelpair; +} + +mitk::ConnectomicsNetworkCreator::ImageLabelPairType mitk::ConnectomicsNetworkCreator::PrecomputeVertexLocationsBySegmentation( TractType::Pointer singleTract ) +{ + ImageLabelPairType labelpair; + + return labelpair; +} + +mitk::ConnectomicsNetworkCreator::ImageLabelPairType mitk::ConnectomicsNetworkCreator::EndElementPositionLabelAvoidingWhiteMatter( TractType::Pointer singleTract ) +{ + ImageLabelPairType labelpair; + + {// Note: .fib image tracts are safed using index coordinates + mitk::Point3D firstElementFiberCoord, lastElementFiberCoord; + mitk::Point3D firstElementSegCoord, lastElementSegCoord; + mitk::Index3D firstElementSegIndex, lastElementSegIndex; + + if( singleTract->front().Size() != 3 ) + { + MBI_ERROR << mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_INVALID_DIMENSION_NEED_3; + } + for( int index = 0; index < singleTract->front().Size(); index++ ) + { + firstElementFiberCoord.SetElement( index, singleTract->front().GetElement( index ) ); + lastElementFiberCoord.SetElement( index, singleTract->back().GetElement( index ) ); + } + + // convert from fiber index coordinates to segmentation index coordinates + FiberToSegmentationCoords( firstElementFiberCoord, firstElementSegCoord ); + FiberToSegmentationCoords( lastElementFiberCoord, lastElementSegCoord ); + + for( int index = 0; index < 3; index++ ) + { + firstElementSegIndex.SetElement( index, firstElementSegCoord.GetElement( index ) ); + lastElementSegIndex.SetElement( index, lastElementSegCoord.GetElement( index ) ); + } + + int firstLabel = m_Segmentation->GetPixelValueByIndex( firstElementSegIndex ); + int lastLabel = m_Segmentation->GetPixelValueByIndex( lastElementSegIndex ); + + // Check whether the labels belong to the white matter (which means, that the fibers ended early) + bool extendFront(false), extendEnd(false), retractFront(false), retractEnd(false); + extendFront = !IsNonWhiteMatterLabel( firstLabel ); + extendEnd = !IsNonWhiteMatterLabel( lastLabel ); + retractFront = IsBackgroundLabel( firstLabel ); + retractEnd = IsBackgroundLabel( lastLabel ); + + //if( extendFront || extendEnd ) + //{ + //MBI_INFO << "Before Start: " << firstLabel << " at " << firstElementSegIndex[ 0 ] << " " << firstElementSegIndex[ 1 ] << " " << firstElementSegIndex[ 2 ] << " End: " << lastLabel << " at " << lastElementSegIndex[ 0 ] << " " << lastElementSegIndex[ 1 ] << " " << lastElementSegIndex[ 2 ]; + //} + if ( extendFront ) + { + std::vector< int > indexVectorOfPointsToUse; + + //Use first two points for direction + indexVectorOfPointsToUse.push_back( 1 ); + indexVectorOfPointsToUse.push_back( 0 ); + + // label and coordinate temp storage + int tempLabel( firstLabel ); + mitk::Index3D tempIndex = firstElementSegIndex; + + LinearExtensionUntilGreyMatter( indexVectorOfPointsToUse, singleTract, tempLabel, tempIndex ); + + firstLabel = tempLabel; + firstElementSegIndex = tempIndex; + + } + + if ( extendEnd ) + { + std::vector< int > indexVectorOfPointsToUse; + + //Use last two points for direction + indexVectorOfPointsToUse.push_back( singleTract->Size() - 2 ); + indexVectorOfPointsToUse.push_back( singleTract->Size() - 1 ); + + // label and coordinate temp storage + int tempLabel( lastLabel ); + mitk::Index3D tempIndex = lastElementSegIndex; + + LinearExtensionUntilGreyMatter( indexVectorOfPointsToUse, singleTract, tempLabel, tempIndex ); + + lastLabel = tempLabel; + lastElementSegIndex = tempIndex; + } + if ( retractFront ) + { + // label and coordinate temp storage + int tempLabel( firstLabel ); + mitk::Index3D tempIndex = firstElementSegIndex; + + RetractionUntilBrainMatter( true, singleTract, tempLabel, tempIndex ); + + firstLabel = tempLabel; + firstElementSegIndex = tempIndex; + + } + + if ( retractEnd ) + { + // label and coordinate temp storage + int tempLabel( lastLabel ); + mitk::Index3D tempIndex = lastElementSegIndex; + + RetractionUntilBrainMatter( false, singleTract, tempLabel, tempIndex ); + + lastLabel = tempLabel; + lastElementSegIndex = tempIndex; + } + //if( extendFront || extendEnd ) + //{ + // MBI_INFO << "After Start: " << firstLabel << " at " << firstElementSegIndex[ 0 ] << " " << firstElementSegIndex[ 1 ] << " " << firstElementSegIndex[ 2 ] << " End: " << lastLabel << " at " << lastElementSegIndex[ 0 ] << " " << lastElementSegIndex[ 1 ] << " " << lastElementSegIndex[ 2 ]; + //} + + labelpair.first = firstLabel; + labelpair.second = lastLabel; + + // Add property to property map + if( ! ( m_LabelToNodePropertyMap.count( firstLabel ) > 0 ) ) + { + NetworkNode firstNode; + + firstNode.coordinates.resize( 3 ); + for( unsigned int index = 0; index < firstNode.coordinates.size() ; index++ ) + { + firstNode.coordinates[ index ] = firstElementSegIndex[ index ] ; + } + + firstNode.label = LabelToString( firstLabel ); + + m_LabelToNodePropertyMap.insert( std::pair< ImageLabelType, NetworkNode >( firstLabel, firstNode ) ); + } + + if( ! ( m_LabelToNodePropertyMap.count( lastLabel ) > 0 ) ) + { + NetworkNode lastNode; + + lastNode.coordinates.resize( 3 ); + for( unsigned int index = 0; index < lastNode.coordinates.size() ; index++ ) + { + lastNode.coordinates[ index ] = lastElementSegIndex[ index ] ; + } + + lastNode.label = LabelToString( lastLabel ); + + m_LabelToNodePropertyMap.insert( std::pair< ImageLabelType, NetworkNode >( lastLabel, lastNode ) ); + } + } + + return labelpair; +} + +mitk::ConnectomicsNetworkCreator::ImageLabelPairType mitk::ConnectomicsNetworkCreator::JustEndPointVerticesNoLabelTest( TractType::Pointer singleTract ) +{ + ImageLabelPairType labelpair; + + {// Note: .fib image tracts are safed using index coordinates + mitk::Point3D firstElementFiberCoord, lastElementFiberCoord; + mitk::Point3D firstElementSegCoord, lastElementSegCoord; + mitk::Index3D firstElementSegIndex, lastElementSegIndex; + + if( singleTract->front().Size() != 3 ) + { + MBI_ERROR << mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_INVALID_DIMENSION_NEED_3; + } + for( int index = 0; index < singleTract->front().Size(); index++ ) + { + firstElementFiberCoord.SetElement( index, singleTract->front().GetElement( index ) ); + lastElementFiberCoord.SetElement( index, singleTract->back().GetElement( index ) ); + } + + // convert from fiber index coordinates to segmentation index coordinates + FiberToSegmentationCoords( firstElementFiberCoord, firstElementSegCoord ); + FiberToSegmentationCoords( lastElementFiberCoord, lastElementSegCoord ); + + for( int index = 0; index < 3; index++ ) + { + firstElementSegIndex.SetElement( index, firstElementSegCoord.GetElement( index ) ); + lastElementSegIndex.SetElement( index, lastElementSegCoord.GetElement( index ) ); + } + + int firstLabel = 1 * firstElementSegIndex[ 0 ] + 1000 * firstElementSegIndex[ 1 ] + 1000000 * firstElementSegIndex[ 2 ]; + int lastLabel = 1 * firstElementSegIndex[ 0 ] + 1000 * firstElementSegIndex[ 1 ] + 1000000 * firstElementSegIndex[ 2 ]; + + labelpair.first = firstLabel; + labelpair.second = lastLabel; + + // Add property to property map + if( ! ( m_LabelToNodePropertyMap.count( firstLabel ) > 0 ) ) + { + NetworkNode firstNode; + + firstNode.coordinates.resize( 3 ); + for( unsigned int index = 0; index < firstNode.coordinates.size() ; index++ ) + { + firstNode.coordinates[ index ] = firstElementSegIndex[ index ] ; + } + + firstNode.label = LabelToString( firstLabel ); + + m_LabelToNodePropertyMap.insert( std::pair< ImageLabelType, NetworkNode >( firstLabel, firstNode ) ); + } + + if( ! ( m_LabelToNodePropertyMap.count( lastLabel ) > 0 ) ) + { + NetworkNode lastNode; + + lastNode.coordinates.resize( 3 ); + for( unsigned int index = 0; index < lastNode.coordinates.size() ; index++ ) + { + lastNode.coordinates[ index ] = lastElementSegIndex[ index ] ; + } + + lastNode.label = LabelToString( lastLabel ); + + m_LabelToNodePropertyMap.insert( std::pair< ImageLabelType, NetworkNode >( lastLabel, lastNode ) ); + } + } + + return labelpair; +} + +void mitk::ConnectomicsNetworkCreator::SupplyVertexWithInformation( ImageLabelType& label, VertexType& vertex ) +{ // supply a vertex with the additional information belonging to the label + + // TODO: Implement additional information acquisition + + m_ConNetwork->SetLabel( vertex, m_LabelToNodePropertyMap.find( label )->second.label ); + m_ConNetwork->SetCoordinates( vertex, m_LabelToNodePropertyMap.find( label )->second.coordinates ); + +} + +std::string mitk::ConnectomicsNetworkCreator::LabelToString( ImageLabelType& label ) +{ + int tempInt = (int) label; + std::stringstream ss;//create a stringstream + std::string tempString; + ss << tempInt;//add number to the stream + tempString = ss.str(); + return tempString;//return a string with the contents of the stream +} + +mitk::ConnectomicsNetwork::Pointer mitk::ConnectomicsNetworkCreator::GetNetwork() +{ + return m_ConNetwork; +} + +void mitk::ConnectomicsNetworkCreator::FiberToSegmentationCoords( mitk::Point3D& fiberCoord, mitk::Point3D& segCoord ) +{ + mitk::Point3D tempPoint; + + // convert from fiber index coordinates to segmentation index coordinates + m_FiberBundle->GetGeometry()->IndexToWorld( fiberCoord, tempPoint ); + m_Segmentation->GetGeometry()->WorldToIndex( tempPoint, segCoord ); +} + +void mitk::ConnectomicsNetworkCreator::SegmentationToFiberCoords( mitk::Point3D& segCoord, mitk::Point3D& fiberCoord ) +{ + mitk::Point3D tempPoint; + + // convert from fiber index coordinates to segmentation index coordinates + m_Segmentation->GetGeometry()->IndexToWorld( segCoord, tempPoint ); + m_FiberBundle->GetGeometry()->WorldToIndex( tempPoint, fiberCoord ); +} + +bool mitk::ConnectomicsNetworkCreator::IsNonWhiteMatterLabel( int labelInQuestion ) +{ + bool isWhite( false ); + + isWhite = ( + ( labelInQuestion == freesurfer_Left_Cerebral_White_Matter ) || + ( labelInQuestion == freesurfer_Left_Cerebellum_White_Matter ) || + ( labelInQuestion == freesurfer_Right_Cerebral_White_Matter ) || + ( labelInQuestion == freesurfer_Right_Cerebellum_White_Matter ) + ); + + return !isWhite; +} + +bool mitk::ConnectomicsNetworkCreator::IsBackgroundLabel( int labelInQuestion ) +{ + bool isBackground( false ); + + isBackground = ( labelInQuestion == 0 ); + + return isBackground; +} + +void mitk::ConnectomicsNetworkCreator::LinearExtensionUntilGreyMatter( + std::vector & indexVectorOfPointsToUse, + TractType::Pointer singleTract, + int & label, + mitk::Index3D & mitkIndex ) +{ + if( indexVectorOfPointsToUse.size() > singleTract->Size() ) + { + MBI_WARN << mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_MORE_POINTS_THAN_PRESENT; + return; + } + + if( indexVectorOfPointsToUse.size() < 2 ) + { + MBI_WARN << mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_ESTIMATING_LESS_THAN_2; + return; + } + + for( int index( 0 ); index < indexVectorOfPointsToUse.size(); index++ ) + { + if( indexVectorOfPointsToUse[ index ] > singleTract->Size() ) + { + MBI_WARN << mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_ESTIMATING_BEYOND_END; + return; + } + if( indexVectorOfPointsToUse[ index ] < 0 ) + { + MBI_WARN << mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_ESTIMATING_BEYOND_START; + return; + } + } + + mitk::Point3D startPoint, endPoint; + std::vector< double > differenceVector; + differenceVector.resize( singleTract->front().Size() ); + + { + // which points to use, currently only last two //TODO correct using all points + int endPointIndex = indexVectorOfPointsToUse.size() - 1; + int startPointIndex = indexVectorOfPointsToUse.size() - 2; + + // convert to segmentation coords + mitk::Point3D startFiber, endFiber; + for( int index = 0; index < singleTract->front().Size(); index++ ) + { + endFiber.SetElement( index, singleTract->GetElement( indexVectorOfPointsToUse[ endPointIndex ] ).GetElement( index ) ); + startFiber.SetElement( index, singleTract->GetElement( indexVectorOfPointsToUse[ startPointIndex ] ).GetElement( index ) ); + } + + FiberToSegmentationCoords( endFiber, endPoint ); + FiberToSegmentationCoords( startFiber, startPoint ); + + // calculate straight line + + for( int index = 0; index < singleTract->front().Size(); index++ ) + { + differenceVector[ index ] = endPoint.GetElement( index ) - startPoint.GetElement( index ); + } + + // normalizing direction vector + + double length( 0.0 ); + double sum( 0.0 ); + + for( int index = 0; index < differenceVector.size() ; index++ ) + { + sum = sum + differenceVector[ index ] * differenceVector[ index ]; + } + + length = std::sqrt( sum ); + + for( int index = 0; index < differenceVector.size() ; index++ ) + { + differenceVector[ index ] = differenceVector[ index ] / length; + } + + // follow line until first non white matter label + mitk::Index3D tempIndex; + int tempLabel( label ); + + bool keepOn( true ); + + for( int parameter( 0 ) ; keepOn ; parameter++ ) + { + if( parameter > 1000 ) + { + MBI_WARN << mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_DID_NOT_FIND_WHITE; + break; + } + + for( int index( 0 ); index < 3; index++ ) + { + tempIndex.SetElement( index, endPoint.GetElement( index ) + parameter * differenceVector[ index ] ); + } + + tempLabel = m_Segmentation->GetPixelValueByIndex( tempIndex ); + + if( IsNonWhiteMatterLabel( tempLabel ) ) + { + if( tempLabel < 1 ) + { + keepOn = false; + MBI_WARN << mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_NOT_EXTEND_TO_WHITE; + } + else + { + label = tempLabel; + mitkIndex = tempIndex; + keepOn = false; + } + } + } + + } + +} + +void mitk::ConnectomicsNetworkCreator::RetractionUntilBrainMatter( bool retractFront, TractType::Pointer singleTract, + int & label, mitk::Index3D & mitkIndex ) +{ + int retractionStartIndex( singleTract->Size() - 1 ); + int retractionStepIndexSize( -1 ); + int retractionTerminationIndex( 0 ); + + if( retractFront ) + { + retractionStartIndex = 0; + retractionStepIndexSize = 1; + retractionTerminationIndex = singleTract->Size() - 1; + } + + int currentRetractionIndex = retractionStartIndex; + + bool keepRetracting( true ); + + mitk::Point3D currentPoint, nextPoint; + std::vector< double > differenceVector; + differenceVector.resize( singleTract->front().Size() ); + + while( keepRetracting && ( currentRetractionIndex != retractionTerminationIndex ) ) + { + // convert to segmentation coords + mitk::Point3D currentPointFiberCoord, nextPointFiberCoord; + for( int index = 0; index < singleTract->front().Size(); index++ ) + { + currentPointFiberCoord.SetElement( index, singleTract->GetElement( currentRetractionIndex ).GetElement( index ) ); + nextPointFiberCoord.SetElement( index, singleTract->GetElement( currentRetractionIndex + retractionStepIndexSize ).GetElement( index ) ); + } + + FiberToSegmentationCoords( currentPointFiberCoord, currentPoint ); + FiberToSegmentationCoords( nextPointFiberCoord, nextPoint ); + + // calculate straight line + + for( int index = 0; index < singleTract->front().Size(); index++ ) + { + differenceVector[ index ] = nextPoint.GetElement( index ) - currentPoint.GetElement( index ); + } + + // calculate length of direction vector + + double length( 0.0 ); + double sum( 0.0 ); + + for( int index = 0; index < differenceVector.size() ; index++ ) + { + sum = sum + differenceVector[ index ] * differenceVector[ index ]; + } + + length = std::sqrt( sum ); + + // retract + mitk::Index3D tempIndex; + int tempLabel( label ); + + for( int parameter( 0 ) ; parameter < length ; parameter++ ) + { + + for( int index( 0 ); index < 3; index++ ) + { + tempIndex.SetElement( index, + currentPoint.GetElement( index ) + ( 1.0 + parameter ) / ( 1.0 + length ) * differenceVector[ index ] ); + } + + tempLabel = m_Segmentation->GetPixelValueByIndex( tempIndex ); + + if( !IsBackgroundLabel( tempLabel ) ) + { + label = tempLabel; + mitkIndex = tempIndex; + return; + } + // hit next point without finding brain matter + currentRetractionIndex = currentRetractionIndex + retractionStepIndexSize; + if( ( currentRetractionIndex < 1 ) || ( currentRetractionIndex > ( singleTract->Size() - 2 ) ) ) + { + keepRetracting = false; + } + } + } +} diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsNetworkCreator.h b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsNetworkCreator.h new file mode 100644 index 0000000000..e3112ae719 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsNetworkCreator.h @@ -0,0 +1,192 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef mitkConnectomicsNetworkCreator_h +#define mitkConnectomicsNetworkCreator_h + +#include +#include +#include + +#include "mitkCommon.h" +#include "mitkImage.h" + +#include "mitkFiberBundleX.h" +#include "mitkConnectomicsNetwork.h" + +#include "MitkDiffusionImagingExports.h" + +namespace mitk +{ + + class MitkDiffusionImaging_EXPORT ConnectomicsNetworkCreator : public itk::Object + { + public: + + /** Enum for different ways to create the mapping from fibers to network */ + + enum MappingStrategy + { + EndElementPosition, + PrecomputeAndDistance, + JustEndPointVerticesNoLabel, + EndElementPositionAvoidingWhiteMatter + }; + + /** Standard class typedefs. */ + /** Method for creation through the object factory. */ + + mitkClassMacro(ConnectomicsNetworkCreator, itk::Object); + itkNewMacro(Self); + + /** Types for the standardized Tract **/ + typedef itk::Point PointType; + typedef itk::VectorContainer TractType; + typedef itk::VectorContainer< unsigned int, TractType::Pointer > TractContainerType; //init via smartpointer + + + /** Types for Network **/ + typedef mitk::ConnectomicsNetwork::VertexDescriptorType VertexType; + typedef mitk::ConnectomicsNetwork::EdgeDescriptorType EdgeType; + typedef mitk::ConnectomicsNetwork::NetworkNode NetworkNode; + typedef std::pair< VertexType, VertexType > ConnectionType; + + /** Types for labels **/ + typedef int ImageLabelType; + typedef std::pair< ImageLabelType, ImageLabelType > ImageLabelPairType; + + + + + void CreateNetworkFromFibersAndSegmentation(); + void SetFiberBundle(mitk::FiberBundleX::Pointer fiberBundle); + void SetSegmentation(mitk::Image::Pointer segmentation); + + mitk::ConnectomicsNetwork::Pointer GetNetwork(); + + protected: + + //////////////////// Functions /////////////////////// + ConnectomicsNetworkCreator(); + ConnectomicsNetworkCreator( mitk::Image::Pointer segmentation, mitk::FiberBundleX::Pointer fiberBundle ); + ~ConnectomicsNetworkCreator(); + + /** Add a connection to the network */ + void AddConnectionToNetwork(ConnectionType newConnection); + + /** Determine if a label is already identified with a vertex, otherwise create a new one */ + VertexType ReturnAssociatedVertexForLabel( ImageLabelType label ); + + /** Return the vertexes associated with a pair of labels */ + ConnectionType ReturnAssociatedVertexPairForLabelPair( ImageLabelPairType labelpair ); + + /** Return the pair of labels which identify the areas connected by a single fiber */ + ImageLabelPairType ReturnLabelForFiberTract( TractType::Pointer singleTract, MappingStrategy strategy ); + + /** Assign the additional information which should be part of the vertex */ + void SupplyVertexWithInformation( ImageLabelType& label, VertexType& vertex ); + + /** Create a string from the label */ + std::string LabelToString( ImageLabelType& label ); + + /** Check whether the label in question belongs to white matter according to the freesurfer table */ + bool IsNonWhiteMatterLabel( int labelInQuestion ); + + /** Check whether the label in question belongs to background according to the freesurfer table */ + bool IsBackgroundLabel( int labelInQuestion ); + + /** Extend a straight line through the given points and look for the first non white matter label + + It will try extend in the direction of the points in the vector so a vector {B,C} will result in + extending from C in the direction C-B */ + void LinearExtensionUntilGreyMatter( std::vector & indexVectorOfPointsToUse, TractType::Pointer singleTract, + int & label, mitk::Index3D & mitkIndex ); + + /** Retract fiber until the first brain matter label is hit + + The bool parameter controls whether the front or the end is retracted */ + void RetractionUntilBrainMatter( bool retractFront, TractType::Pointer singleTract, + int & label, mitk::Index3D & mitkIndex ); + + /** Convert point to itk point */ + itk::Point GetItkPoint(double point[3]); + + ///////// Mapping strategies ////////// + + /** Use the position of the end and starting element only to map to labels + + Map a fiber to a vertex by taking the value of the parcellation image at the same world coordinates as the last + and first element of the tract.*/ + ImageLabelPairType EndElementPositionLabel( TractType::Pointer singleTract ); + + /** Map by distance between elements and vertices depending on their volume + + First go through the parcellation and compute the coordinates of the future vertices. Assign a radius according on their volume. + Then map an edge to a label by considering the nearest vertices and comparing the distance to them to their radii. */ + ImageLabelPairType PrecomputeVertexLocationsBySegmentation( TractType::Pointer singleTract ); + + /** Use the position of the end and starting element only to map to labels + + Just take first and last position, no labelling, nothing */ + ImageLabelPairType JustEndPointVerticesNoLabelTest( TractType::Pointer singleTract ); + + /** Use the position of the end and starting element unless it is in white matter, then search for nearby parcellation to map to labels + + Map a fiber to a vertex by taking the value of the parcellation image at the same world coordinates as the last + and first element of the tract. If this happens to be white matter, then try to extend the fiber in a line and + take the first non-white matter parcel, that is intersected. */ + ImageLabelPairType EndElementPositionLabelAvoidingWhiteMatter( TractType::Pointer singleTract ); + + ///////// Conversions ////////// + /** Convert fiber index to segmentation index coordinates */ + void FiberToSegmentationCoords( mitk::Point3D& fiberCoord, mitk::Point3D& segCoord ); + /** Convert segmentation index to fiber index coordinates */ + void SegmentationToFiberCoords( mitk::Point3D& segCoord, mitk::Point3D& fiberCoord ); + + /////////////////////// Variables //////////////////////// + mitk::FiberBundleX::Pointer m_FiberBundle; + mitk::Image::Pointer m_Segmentation; + + // the graph itself + mitk::ConnectomicsNetwork::Pointer m_ConNetwork; + + // the id counter + int idCounter; + + // the map mapping labels to vertices + std::map< ImageLabelType, VertexType > m_LabelToVertexMap; + + // mapping labels to additional information + std::map< ImageLabelType, NetworkNode > m_LabelToNodePropertyMap; + + // toggles whether edges between a node and itself can exist + bool allowLoops; + + //////////////////////// IDs //////////////////////////// + + // These IDs are the freesurfer ids used in parcellation + + static const int freesurfer_Left_Cerebral_White_Matter = 2; + static const int freesurfer_Left_Cerebellum_White_Matter = 7; + static const int freesurfer_Right_Cerebral_White_Matter = 41; + static const int freesurfer_Right_Cerebellum_White_Matter = 46; + + }; + +}// end namespace mitk + +#endif // _mitkConnectomicsNetworkCreator_H_INCLUDED \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsShortestPathHistogram.cpp b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsShortestPathHistogram.cpp new file mode 100644 index 0000000000..3c34278bef --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsShortestPathHistogram.cpp @@ -0,0 +1,186 @@ + +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile$ +Language: C++ +Date: $Date$ +Version: $Revision: 11989 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include + +#include + +#include "mitkConnectomicsConstantsManager.h" + +mitk::ConnectomicsShortestPathHistogram::ConnectomicsShortestPathHistogram() +: m_Mode( UnweightedUndirectedMode ) +, m_EverythingConnected( true ) +{ + m_Subject = "Shortest path"; +} + +mitk::ConnectomicsShortestPathHistogram::~ConnectomicsShortestPathHistogram() +{ +} + +void mitk::ConnectomicsShortestPathHistogram::SetShortestPathCalculationMode( const mitk::ConnectomicsShortestPathHistogram::ShortestPathCalculationMode & mode) +{ + m_Mode = mode; +} + +mitk::ConnectomicsShortestPathHistogram::ShortestPathCalculationMode mitk::ConnectomicsShortestPathHistogram::GetShortestPathCalculationMode() +{ + return m_Mode; +} + +void mitk::ConnectomicsShortestPathHistogram::ComputeFromConnectomicsNetwork( ConnectomicsNetwork* source ) +{ + + NetworkType* boostGraph = source->GetBoostGraph(); + + switch( m_Mode ) + { + case UnweightedUndirectedMode: + { + CalculateUnweightedUndirectedShortestPaths( boostGraph ); + break; + } + case WeightedUndirectedMode: + { + CalculateWeightedUndirectedShortestPaths( boostGraph ); + break; + } + } + + ConvertDistanceMapToHistogram(); +} + +void mitk::ConnectomicsShortestPathHistogram::CalculateUnweightedUndirectedShortestPaths( NetworkType* boostGraph ) +{ + std::vector< DescriptorType > predecessorMap( boost::num_vertices( *boostGraph ) ); + int numberOfNodes( boost::num_vertices( *boostGraph ) ); + + m_DistanceMatrix.resize( numberOfNodes ); + for( int index(0); index < m_DistanceMatrix.size(); index++ ) + { + m_DistanceMatrix[ index ].resize( numberOfNodes ); + } + + IteratorType iterator, end; + boost::tie(iterator, end) = boost::vertices( *boostGraph ); + + for ( int index(0) ; iterator != end; ++iterator, index++) + { + boost::dijkstra_shortest_paths(*boostGraph, *iterator, boost::predecessor_map(&predecessorMap[ 0 ]).distance_map(&m_DistanceMatrix[ index ][ 0 ]).weight_map( boost::get( &mitk::ConnectomicsNetwork::NetworkEdge::edge_weight ,*boostGraph ) ) ) ; + } +} + +void mitk::ConnectomicsShortestPathHistogram::CalculateWeightedUndirectedShortestPaths( NetworkType* boostGraph ) +{ + MBI_WARN << mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_UNIMPLEMENTED_FEATURE; +} + +void mitk::ConnectomicsShortestPathHistogram::ConvertDistanceMapToHistogram() +{ + // get the longest path between any two nodes in the network + // we assume that no nodes are farther apart than there are nodes, + // this is to filter unconnected nodes + int longestPath( 0 ); + int numberOfNodes( m_DistanceMatrix.size() ); + m_EverythingConnected = true; + + for( int index(0); index < m_DistanceMatrix.size(); index++ ) + { + for( int innerIndex(0); innerIndex < m_DistanceMatrix[ index ].size(); innerIndex++ ) + { + if( m_DistanceMatrix[ index ][ innerIndex ] > longestPath ) + { + if( m_DistanceMatrix[ index ][ innerIndex ] < numberOfNodes ) + { + longestPath = m_DistanceMatrix[ index ][ innerIndex ]; + } + else + { + // these nodes are not connected + m_EverythingConnected = false; + } + } + } + } + + m_HistogramVector.resize( longestPath + 1 ); + + for( int index(0); index < m_DistanceMatrix.size(); index++ ) + { + for( int innerIndex(0); innerIndex < m_DistanceMatrix[ index ].size(); innerIndex++ ) + { + if( m_DistanceMatrix[ index ][ innerIndex ] < numberOfNodes ) + { + m_HistogramVector[ m_DistanceMatrix[ index ][ innerIndex ] ]++; + } + } + } + + // correct for every path being counted twice + + for( int index(1); index < m_HistogramVector.size(); index++ ) + { + m_HistogramVector[ index ] = m_HistogramVector[ index ] / 2; + } + + // correct for every node being distance zero to itself + if( m_HistogramVector[ 0 ] >= numberOfNodes ) + { + m_HistogramVector[ 0 ] = m_HistogramVector[ 0 ] - numberOfNodes; + } + else + { + MBI_WARN << mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_ZERO_DISTANCE_NODES; + } + + UpdateYMax(); + + this->m_Valid = true; +} + +double mitk::ConnectomicsShortestPathHistogram::GetEfficiency() +{ + if( !this->m_Valid ) + { + MBI_INFO << mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_CAN_NOT_COMPUTE_EFFICIENCY << mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_NETWORK_NOT_VALID; + return 0.0; + } + + if( !m_EverythingConnected ) + { // efficiency of disconnected graphs is 0 + MBI_INFO << mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_NETWORK_DISCONNECTED; + return 0.0; + } + + double efficiency( 0.0 ); + + double overallDistance( 0.0 ); + double numberOfPairs( 0.0 ); + // add up all distances + for( int index(0); index < m_HistogramVector.size(); index++ ) + { + overallDistance = overallDistance + m_HistogramVector[ index ] * index; + numberOfPairs = numberOfPairs + m_HistogramVector[ index ]; + } + + // efficiency = 1 / averageDistance = 1 / ( overallDistance / numberofPairs ) + efficiency = numberOfPairs / overallDistance; + + return efficiency; +} diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsShortestPathHistogram.h b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsShortestPathHistogram.h new file mode 100644 index 0000000000..90059a5ea3 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsShortestPathHistogram.h @@ -0,0 +1,88 @@ + +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile$ +Language: C++ +Date: $Date$ +Version: $Revision: 11989 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + + +#ifndef _MITK_ConnectomicsShortestPathHistogram_H +#define _MITK_ConnectomicsShortestPathHistogram_H + +#include + +#include "MitkDiffusionImagingExports.h" + +namespace mitk { + + /** + * \brief A class to calculate and store the shortest path between each pair of nodes */ + class MitkDiffusionImaging_EXPORT ConnectomicsShortestPathHistogram : public mitk::ConnectomicsHistogramBase + { + + public: + + /** Enum for different ways to calculate shortest paths */ + enum ShortestPathCalculationMode + { + UnweightedUndirectedMode, + WeightedUndirectedMode + }; + + ConnectomicsShortestPathHistogram(); + virtual ~ConnectomicsShortestPathHistogram(); + + /** Set the calucaltion mode */ + void SetShortestPathCalculationMode( const ShortestPathCalculationMode & ); + + /** Get the calculation mode */ + ShortestPathCalculationMode GetShortestPathCalculationMode(); + + /** Get efficiency */ + double GetEfficiency(); + + + protected: + + /* Typedefs */ + typedef mitk::ConnectomicsNetwork::NetworkType NetworkType; + typedef boost::graph_traits< NetworkType >::vertex_descriptor DescriptorType; + typedef boost::graph_traits< NetworkType >::vertex_iterator IteratorType; + + /** @brief Creates a new histogram from the network source. */ + virtual void ComputeFromConnectomicsNetwork( ConnectomicsNetwork* source ); + + /** Calculate shortest paths ignoring the weight of the edges */ + void CalculateUnweightedUndirectedShortestPaths( NetworkType* boostGraph ); + + /** Calculate shortest paths taking into consideration the weight of the edges */ + void CalculateWeightedUndirectedShortestPaths( NetworkType* boostGraph ); + + /** Converts the distance map to a histogram */ + void ConvertDistanceMapToHistogram(); + + /** Stores which mode has been selected for shortest path calculation */ + ShortestPathCalculationMode m_Mode; + + /** Stores the shortest paths between the nodes */ + std::vector< std::vector< int > > m_DistanceMatrix; + + /** Stores, whether the graph has disconnected components */ + bool m_EverythingConnected; + }; + +} + +#endif /* _MITK_ConnectomicsShortestPathHistogram_H */ \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionBase.cpp b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionBase.cpp new file mode 100644 index 0000000000..251007d975 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionBase.cpp @@ -0,0 +1,26 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsSimulatedAnnealingCostFunctionBase.h" + +mitk::ConnectomicsSimulatedAnnealingCostFunctionBase::ConnectomicsSimulatedAnnealingCostFunctionBase() +{ +} + +mitk::ConnectomicsSimulatedAnnealingCostFunctionBase::~ConnectomicsSimulatedAnnealingCostFunctionBase() +{ +} diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionBase.h b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionBase.h new file mode 100644 index 0000000000..f44c49e0de --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionBase.h @@ -0,0 +1,55 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef mitkConnectomicsSimulatedAnnealingCostFunctionBase_h +#define mitkConnectomicsSimulatedAnnealingCostFunctionBase_h + +#include +#include +#include + +#include "mitkCommon.h" + +#include "MitkDiffusionImagingExports.h" + +namespace mitk +{ + /** + * \brief A generic base class for cost functions for use in simulated annealing */ + class MitkDiffusionImaging_EXPORT ConnectomicsSimulatedAnnealingCostFunctionBase : public itk::Object + { + public: + + /** Standard class typedefs. */ + /** Method for creation through the object factory. */ + + mitkClassMacro(ConnectomicsSimulatedAnnealingCostFunctionBase, itk::Object); + itkNewMacro(Self); + + + + protected: + + //////////////////// Functions /////////////////////// + ConnectomicsSimulatedAnnealingCostFunctionBase(); + ~ConnectomicsSimulatedAnnealingCostFunctionBase(); + + }; + +}// end namespace mitk + +#endif // mitkConnectomicsSimulatedAnnealingCostFunctionBase_h \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionModularity.cpp b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionModularity.cpp new file mode 100644 index 0000000000..cd480df657 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionModularity.cpp @@ -0,0 +1,126 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsSimulatedAnnealingCostFunctionModularity.h" + +mitk::ConnectomicsSimulatedAnnealingCostFunctionModularity::ConnectomicsSimulatedAnnealingCostFunctionModularity() +{ +} + +mitk::ConnectomicsSimulatedAnnealingCostFunctionModularity::~ConnectomicsSimulatedAnnealingCostFunctionModularity() +{ +} + +double mitk::ConnectomicsSimulatedAnnealingCostFunctionModularity::Evaluate( mitk::ConnectomicsNetwork::Pointer network, ToModuleMapType* vertexToModuleMap ) const +{ + double cost( 0.0 ); + cost = 100.0 * ( 1.0 - CalculateModularity( network, vertexToModuleMap ) ); + return cost; +} + +double mitk::ConnectomicsSimulatedAnnealingCostFunctionModularity::CalculateModularity( mitk::ConnectomicsNetwork::Pointer network, ToModuleMapType* vertexToModuleMap ) const +{ + double modularity( 0.0 ); + int numberOfModules = getNumberOfModules( vertexToModuleMap ); + + if( network->GetNumberOfVertices() != vertexToModuleMap->size() ) + { + MBI_ERROR << "Number of vertices and vertex to module map size do not match!"; + return modularity; + } + + int numberOfLinksInNetwork( 0 ); + std::vector< int > numberOfLinksInModule, sumOfDegreesInModule; + numberOfLinksInModule.resize( numberOfModules, 0 ); + sumOfDegreesInModule.resize( numberOfModules, 0 ); + // get vector of all vertex descriptors in the network + + const std::vector< VertexDescriptorType > allNodesVector + = network->GetVectorOfAllVertexDescriptors(); + + for( int nodeNumber( 0 ); nodeNumber < allNodesVector.size() ; nodeNumber++) + { + int correspondingModule = vertexToModuleMap->find( allNodesVector[ nodeNumber ] )->second; + const std::vector< VertexDescriptorType > adjacentNodexVector + = network->GetVectorOfAdjacentNodes( allNodesVector[ nodeNumber ] ); + numberOfLinksInNetwork += adjacentNodexVector.size(); + sumOfDegreesInModule[ correspondingModule ] += adjacentNodexVector.size(); + + for( int adjacentNodeNumber( 0 ); adjacentNodeNumber < adjacentNodexVector.size() ; adjacentNodeNumber++) + { + if( correspondingModule == vertexToModuleMap->find( adjacentNodexVector[ adjacentNodeNumber ] )->second ) + { + numberOfLinksInModule[ correspondingModule ]++; + } + } + } + + // the numbers for links have to be halved, as each edge was counted twice + numberOfLinksInNetwork = numberOfLinksInNetwork / 2; + + // if the network contains no links return 0 + if( numberOfLinksInNetwork < 1) + { + return 0; + } + + for( int index( 0 ); index < numberOfModules ; index++) + { + numberOfLinksInModule[ index ] = numberOfLinksInModule[ index ] / 2; + } + + //Calculate modularity M: + //M = sum_{s=1}^{N_{M}} [ (l_{s} / L) - (d_{s} / ( 2L ))^2 ] + //where N_{M} is the number of modules + //L is the number of links in the network + //l_{s} is the number of links between nodes in the module + //s is the module + //d_{s} is the sum of degrees of the nodes in the module + //( taken from Guimera, R. AND Amaral, L. A. N. + // Cartography of complex networks: modules and universal roles + // Journal of Statistical Mechanics: Theory and Experiment, 2005, 2005, P02001 ) + + for( int moduleID( 0 ); moduleID < numberOfModules; moduleID++ ) + { + modularity += (((double) numberOfLinksInModule[ moduleID ]) / ((double) numberOfLinksInNetwork)) - + ( + (((double) sumOfDegreesInModule[ moduleID ]) / ((double) 2 * numberOfLinksInNetwork) ) * + (((double) sumOfDegreesInModule[ moduleID ]) / ((double) 2 * numberOfLinksInNetwork) ) + ); + } + + return modularity; +} + +int mitk::ConnectomicsSimulatedAnnealingCostFunctionModularity::getNumberOfModules( + ToModuleMapType *vertexToModuleMap ) const +{ + int maxModule( 0 ); + ToModuleMapType::iterator iter = vertexToModuleMap->begin(); + ToModuleMapType::iterator end = vertexToModuleMap->end(); + while( iter != end ) + { + if( iter->second > maxModule ) + { + maxModule = iter->second; + } + + iter++; + } + + return maxModule + 1; +} \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionModularity.h b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionModularity.h new file mode 100644 index 0000000000..b4bb01631a --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionModularity.h @@ -0,0 +1,63 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef mitkConnectomicsSimulatedAnnealingCostFunctionModularity_h +#define mitkConnectomicsSimulatedAnnealingCostFunctionModularity_h + +#include "mitkConnectomicsSimulatedAnnealingCostFunctionBase.h" + +#include "mitkConnectomicsNetwork.h" + +namespace mitk +{ + /** + * \brief A cost function using the modularity of the network */ + class MitkDiffusionImaging_EXPORT ConnectomicsSimulatedAnnealingCostFunctionModularity : public mitk::ConnectomicsSimulatedAnnealingCostFunctionBase + { + public: + + typedef mitk::ConnectomicsNetwork::VertexDescriptorType VertexDescriptorType; + typedef std::map< VertexDescriptorType, int > ToModuleMapType; + typedef std::map< VertexDescriptorType, VertexDescriptorType > VertexToVertexMapType; + + /** Standard class typedefs. */ + /** Method for creation through the object factory. */ + + mitkClassMacro(ConnectomicsSimulatedAnnealingCostFunctionModularity, itk::Object); + itkNewMacro(Self); + + // Evaluate the network according to the set cost function + double Evaluate( mitk::ConnectomicsNetwork::Pointer network, ToModuleMapType *vertexToModuleMap ) const; + + // Will calculate and return the modularity of the network + double CalculateModularity( mitk::ConnectomicsNetwork::Pointer network, ToModuleMapType *vertexToModuleMap ) const; + + + protected: + + // returns the number of modules + int getNumberOfModules( ToModuleMapType *vertexToModuleMap ) const; + + //////////////////// Functions /////////////////////// + ConnectomicsSimulatedAnnealingCostFunctionModularity(); + ~ConnectomicsSimulatedAnnealingCostFunctionModularity(); + + }; + +}// end namespace mitk + +#endif // mitkConnectomicsSimulatedAnnealingCostFunctionModularity_h \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingManager.cpp b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingManager.cpp new file mode 100644 index 0000000000..79aa823024 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingManager.cpp @@ -0,0 +1,181 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsSimulatedAnnealingManager.h" + +//for random number generation +#include "vxl/core/vnl/vnl_random.h" +#include "vxl/core/vnl/vnl_math.h" + +mitk::ConnectomicsSimulatedAnnealingManager::ConnectomicsSimulatedAnnealingManager() +: m_Permutation( 0 ) +{ +} + +mitk::ConnectomicsSimulatedAnnealingManager::~ConnectomicsSimulatedAnnealingManager() +{ +} + + +bool mitk::ConnectomicsSimulatedAnnealingManager::AcceptChange( double costBefore, double costAfter, double temperature ) +{ + if( costAfter <= costBefore ) + {// if cost is lower after + return true; + } + + //the random number generators + vnl_random rng( (unsigned int) rand() ); + + //randomly generate threshold + const double threshold = rng.drand64( 0.0 , 1.0); + + //the likelihood of acceptance + double likelihood = std::exp( - ( costAfter - costBefore ) / temperature ); + + if( threshold < likelihood ) + { + return true; + } + + return false; +} + +void mitk::ConnectomicsSimulatedAnnealingManager::SetPermutation( mitk::ConnectomicsSimulatedAnnealingPermutationBase::Pointer permutation ) +{ + m_Permutation = permutation; +} + +void mitk::ConnectomicsSimulatedAnnealingManager::RunSimulatedAnnealing( + double temperature, + double stepSize + ) +{ + if( m_Permutation.IsNull() ) + { + MBI_ERROR << "Trying to run simulated annealing on empty permutation."; + return; + } + + if( !m_Permutation->HasCostFunction() ) + { + MBI_ERROR << "Trying to run simulated annealing on empty cost function."; + return; + } + + // Initialize the associated permutation + m_Permutation->Initialize(); + + + for( double currentTemperature( temperature ); + currentTemperature > 0.00001; + currentTemperature = currentTemperature / stepSize ) + { + // Run Permutations at the current temperature + m_Permutation->Permutate( currentTemperature ); + + } + + // Clean up result + m_Permutation->CleanUp(); + +} + + +//void mitk::ConnectomicsSimulatedAnnealingManager::Testing( mitk::ConnectomicsNetwork::Pointer network ) +//{ +// // precursor to an actual test, this will assign a to module map which is only valid for a +// // specific network and whose modularity is known +// ToModuleMapType threeModuleSolution; +// std::vector< VertexDescriptorType > vertexVector = network->GetVectorOfAllVertexDescriptors(); +// +// threeModuleSolution.insert( std::pair( vertexVector[ 0 ], 0 ) ); +// threeModuleSolution.insert( std::pair( vertexVector[ 1 ], 0 ) ); +// threeModuleSolution.insert( std::pair( vertexVector[ 2 ], 0 ) ); +// threeModuleSolution.insert( std::pair( vertexVector[ 3 ], 0 ) ); +// threeModuleSolution.insert( std::pair( vertexVector[ 4 ], 0 ) ); +// threeModuleSolution.insert( std::pair( vertexVector[ 5 ], 1 ) ); +// threeModuleSolution.insert( std::pair( vertexVector[ 6 ], 1 ) ); +// threeModuleSolution.insert( std::pair( vertexVector[ 7 ], 1 ) ); +// threeModuleSolution.insert( std::pair( vertexVector[ 8 ], 1 ) ); +// threeModuleSolution.insert( std::pair( vertexVector[ 9 ], 2 ) ); +// threeModuleSolution.insert( std::pair( vertexVector[ 10 ], 2 ) ); +// threeModuleSolution.insert( std::pair( vertexVector[ 11 ], 2 ) ); +// +// std::cout << "Modularity is " << CalculateModularity( network, &threeModuleSolution ) << " and should be " << 0.4753 << std::endl; +// +// std::cout << " Module 0 contains " << getNumberOfVerticesInModule( &threeModuleSolution, 0 ) << " nodes, should be 5.\n"; +// std::cout << " Module 1 contains " << getNumberOfVerticesInModule( &threeModuleSolution, 1 ) << " nodes, should be 4.\n"; +// std::cout << " Module 2 contains " << getNumberOfVerticesInModule( &threeModuleSolution, 2 ) << " nodes, should be 3.\n"; +// +// ToModuleMapType oneModuleSolution; +// oneModuleSolution.insert( std::pair( vertexVector[ 0 ], 0 ) ); +// oneModuleSolution.insert( std::pair( vertexVector[ 1 ], 0 ) ); +// oneModuleSolution.insert( std::pair( vertexVector[ 2 ], 0 ) ); +// oneModuleSolution.insert( std::pair( vertexVector[ 3 ], 0 ) ); +// oneModuleSolution.insert( std::pair( vertexVector[ 4 ], 0 ) ); +// oneModuleSolution.insert( std::pair( vertexVector[ 5 ], 0 ) ); +// oneModuleSolution.insert( std::pair( vertexVector[ 6 ], 0 ) ); +// oneModuleSolution.insert( std::pair( vertexVector[ 7 ], 0 ) ); +// oneModuleSolution.insert( std::pair( vertexVector[ 8 ], 0 ) ); +// oneModuleSolution.insert( std::pair( vertexVector[ 9 ], 0 ) ); +// oneModuleSolution.insert( std::pair( vertexVector[ 10 ], 0 ) ); +// oneModuleSolution.insert( std::pair( vertexVector[ 11 ], 0 ) ); +// +// std::cout << "Modularity is " << CalculateModularity( network, &oneModuleSolution ) << " and should be " << 0.0 << std::endl; +// +// std::cout << " Module 0 contains " << getNumberOfVerticesInModule( &oneModuleSolution, 0 ) << " nodes, should be 12.\n"; +// +// ToModuleMapType badTwoModuleSolution; +// badTwoModuleSolution.insert( std::pair( vertexVector[ 0 ], 0 ) ); +// badTwoModuleSolution.insert( std::pair( vertexVector[ 1 ], 0 ) ); +// badTwoModuleSolution.insert( std::pair( vertexVector[ 2 ], 0 ) ); +// badTwoModuleSolution.insert( std::pair( vertexVector[ 3 ], 0 ) ); +// badTwoModuleSolution.insert( std::pair( vertexVector[ 4 ], 0 ) ); +// badTwoModuleSolution.insert( std::pair( vertexVector[ 5 ], 1 ) ); +// badTwoModuleSolution.insert( std::pair( vertexVector[ 6 ], 1 ) ); +// badTwoModuleSolution.insert( std::pair( vertexVector[ 7 ], 1 ) ); +// badTwoModuleSolution.insert( std::pair( vertexVector[ 8 ], 0 ) ); +// badTwoModuleSolution.insert( std::pair( vertexVector[ 9 ], 1 ) ); +// badTwoModuleSolution.insert( std::pair( vertexVector[ 10 ], 1 ) ); +// badTwoModuleSolution.insert( std::pair( vertexVector[ 11 ], 0 ) ); +// +// std::cout << "Modularity is " << CalculateModularity( network, &badTwoModuleSolution ) << " and should be " << 0.10 << std::endl; +// std::cout << " Module 0 contains " << getNumberOfVerticesInModule( &badTwoModuleSolution, 0 ) << " nodes, should be 7.\n"; +// std::cout << " Module 1 contains " << getNumberOfVerticesInModule( &badTwoModuleSolution, 1 ) << " nodes, should be 5.\n"; +// +// ToModuleMapType noInternalLinksThreeModuleSolution; +// noInternalLinksThreeModuleSolution.insert( std::pair( vertexVector[ 0 ], 0 ) ); +// noInternalLinksThreeModuleSolution.insert( std::pair( vertexVector[ 1 ], 2 ) ); +// noInternalLinksThreeModuleSolution.insert( std::pair( vertexVector[ 2 ], 1 ) ); +// noInternalLinksThreeModuleSolution.insert( std::pair( vertexVector[ 3 ], 0 ) ); +// noInternalLinksThreeModuleSolution.insert( std::pair( vertexVector[ 4 ], 1 ) ); +// noInternalLinksThreeModuleSolution.insert( std::pair( vertexVector[ 5 ], 2 ) ); +// noInternalLinksThreeModuleSolution.insert( std::pair( vertexVector[ 6 ], 0 ) ); +// noInternalLinksThreeModuleSolution.insert( std::pair( vertexVector[ 7 ], 0 ) ); +// noInternalLinksThreeModuleSolution.insert( std::pair( vertexVector[ 8 ], 1 ) ); +// noInternalLinksThreeModuleSolution.insert( std::pair( vertexVector[ 9 ], 2 ) ); +// noInternalLinksThreeModuleSolution.insert( std::pair( vertexVector[ 10 ], 1 ) ); +// noInternalLinksThreeModuleSolution.insert( std::pair( vertexVector[ 11 ], 0 ) ); +// +// std::cout << "Modularity is " << CalculateModularity( network, &noInternalLinksThreeModuleSolution ) << " and should be " << -0.34 << std::endl; +// +// std::cout << " Module 0 contains " << getNumberOfVerticesInModule( &noInternalLinksThreeModuleSolution, 0 ) << " nodes, should be 5.\n"; +// std::cout << " Module 1 contains " << getNumberOfVerticesInModule( &noInternalLinksThreeModuleSolution, 1 ) << " nodes, should be 4.\n"; +// std::cout << " Module 2 contains " << getNumberOfVerticesInModule( &noInternalLinksThreeModuleSolution, 2 ) << " nodes, should be 3.\n"; +// +//} \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingManager.h b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingManager.h new file mode 100644 index 0000000000..a3964d0f4e --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingManager.h @@ -0,0 +1,70 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef mitkConnectomicsSimulatedAnnealingManager_h +#define mitkConnectomicsSimulatedAnnealingManager_h + +#include +#include +#include + +#include "mitkCommon.h" + +#include "MitkDiffusionImagingExports.h" + +#include "mitkConnectomicsSimulatedAnnealingPermutationBase.h" + +namespace mitk +{ + /** + * \brief A class allow generic simulated annealing by using classes derived from ConnectomicsSimulatedAnnealingPermutationBase */ + class MitkDiffusionImaging_EXPORT ConnectomicsSimulatedAnnealingManager : public itk::Object + { + public: + + /** Standard class typedefs. */ + /** Method for creation through the object factory. */ + + mitkClassMacro(ConnectomicsSimulatedAnnealingManager, itk::Object); + itkNewMacro(Self); + + // Decide whether to accept the change or not + bool AcceptChange( double costBefore, double costAfter, double temperature ); + + // Run the permutations at different temperatures, where t_n = t_n-1 / stepSize + void RunSimulatedAnnealing( double temperature, double stepSize ); + + // Set the permutation to be used + void SetPermutation( mitk::ConnectomicsSimulatedAnnealingPermutationBase::Pointer permutation ); + + //void Testing( mitk::ConnectomicsNetwork::Pointer network ); + + protected: + + //////////////////// Functions /////////////////////// + ConnectomicsSimulatedAnnealingManager(); + ~ConnectomicsSimulatedAnnealingManager(); + + /////////////////////// Variables //////////////////////// + // The permutation assigned to the simulated annealing manager + mitk::ConnectomicsSimulatedAnnealingPermutationBase::Pointer m_Permutation; + + }; + +}// end namespace mitk + +#endif // mitkConnectomicsSimulatedAnnealingManager_h \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationBase.cpp b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationBase.cpp new file mode 100644 index 0000000000..895c434309 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationBase.cpp @@ -0,0 +1,45 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsSimulatedAnnealingPermutationBase.h" + +mitk::ConnectomicsSimulatedAnnealingPermutationBase::ConnectomicsSimulatedAnnealingPermutationBase() +: m_CostFunction( 0 ) +{ +} + +mitk::ConnectomicsSimulatedAnnealingPermutationBase::~ConnectomicsSimulatedAnnealingPermutationBase() +{ +} + +void mitk::ConnectomicsSimulatedAnnealingPermutationBase::SetCostFunction( + mitk::ConnectomicsSimulatedAnnealingCostFunctionBase::Pointer costFunction ) +{ + m_CostFunction = costFunction; +} + +bool mitk::ConnectomicsSimulatedAnnealingPermutationBase::HasCostFunction( ) +{ + bool hasCostFunction( false ); + + if( m_CostFunction.IsNotNull() ) + { + hasCostFunction = true; + } + + return hasCostFunction; +} diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationBase.h b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationBase.h new file mode 100644 index 0000000000..9b0906c12c --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationBase.h @@ -0,0 +1,75 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef mitkConnectomicsSimulatedAnnealingPermutationBase_h +#define mitkConnectomicsSimulatedAnnealingPermutationBase_h + +#include +#include +#include + +#include "mitkCommon.h" + +#include "MitkDiffusionImagingExports.h" + +#include "mitkConnectomicsSimulatedAnnealingCostFunctionBase.h" + +namespace mitk +{ + + /** + * \brief Base class of a permutation to be used in simulated annealing */ + class MitkDiffusionImaging_EXPORT ConnectomicsSimulatedAnnealingPermutationBase : public itk::Object + { + public: + + /** Standard class typedefs. */ + /** Method for creation through the object factory. */ + + mitkClassMacro(ConnectomicsSimulatedAnnealingPermutationBase, itk::Object); + itkNewMacro(Self); + + // Set the cost function + void SetCostFunction( mitk::ConnectomicsSimulatedAnnealingCostFunctionBase::Pointer costFunction ); + + // Returns true if a cost function is assigned + bool HasCostFunction( ); + + // Initialize the permutation + virtual void Initialize(){}; + + // Do a permutation for a specific temperature + virtual void Permutate( double temperature ){}; + + // Do clean up necessary after a permutation + virtual void CleanUp(){}; + + protected: + + //////////////////// Functions /////////////////////// + ConnectomicsSimulatedAnnealingPermutationBase(); + ~ConnectomicsSimulatedAnnealingPermutationBase(); + + /////////////////////// Variables //////////////////////// + // The cost function assigned to the permutation + mitk::ConnectomicsSimulatedAnnealingCostFunctionBase::Pointer m_CostFunction; + + }; + +}// end namespace mitk + +#endif // mitkConnectomicsSimulatedAnnealingPermutationBase_h \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationModularity.cpp b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationModularity.cpp new file mode 100644 index 0000000000..fcbdfe1797 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationModularity.cpp @@ -0,0 +1,545 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsSimulatedAnnealingPermutationModularity.h" +#include "mitkConnectomicsSimulatedAnnealingCostFunctionModularity.h" +#include "mitkConnectomicsSimulatedAnnealingManager.h" + +//for random number generation +#include "vxl/core/vnl/vnl_random.h" +#include "vxl/core/vnl/vnl_math.h" + +mitk::ConnectomicsSimulatedAnnealingPermutationModularity::ConnectomicsSimulatedAnnealingPermutationModularity() +{ +} + +mitk::ConnectomicsSimulatedAnnealingPermutationModularity::~ConnectomicsSimulatedAnnealingPermutationModularity() +{ +} + +void mitk::ConnectomicsSimulatedAnnealingPermutationModularity::SetNetwork( + mitk::ConnectomicsNetwork::Pointer theNetwork ) +{ + m_Network = theNetwork; +} + +void mitk::ConnectomicsSimulatedAnnealingPermutationModularity::Initialize() +{ + // create entry for every vertex + std::vector< VertexDescriptorType > vertexVector = m_Network->GetVectorOfAllVertexDescriptors(); + const int vectorSize = vertexVector.size(); + + for( int index( 0 ); index < vectorSize; index++) + { + m_BestSolution.insert( std::pair( vertexVector[ index ], 0 ) ); + } + + // initialize with random distribution of n modules + int n( 5 ); + randomlyAssignNodesToModules( &m_BestSolution, n ); + +} + +void mitk::ConnectomicsSimulatedAnnealingPermutationModularity::Permutate( double temperature ) +{ + + ToModuleMapType currentSolution = m_BestSolution; + ToModuleMapType currentBestSolution = m_BestSolution; + + int factor = 1; + int numberOfVertices = m_BestSolution.size(); + int singleNodeMaxNumber = factor * numberOfVertices * numberOfVertices; + int moduleMaxNumber = factor * numberOfVertices; + double currentBestCost = Evaluate( ¤tBestSolution ); + + // do singleNodeMaxNumber node permutations and evaluate + for(int loop( 0 ); loop < singleNodeMaxNumber; loop++) + { + permutateMappingSingleNodeShift( ¤tSolution, m_Network ); + if( AcceptChange( currentBestCost, Evaluate( ¤tSolution ), temperature ) ) + { + currentBestSolution = currentSolution; + currentBestCost = Evaluate( ¤tBestSolution ); + } + } + + // do moduleMaxNumber module permutations + for(int loop( 0 ); loop < moduleMaxNumber; loop++) + { + permutateMappingModuleChange( ¤tSolution, temperature, m_Network ); + if( AcceptChange( currentBestCost, Evaluate( ¤tSolution ), temperature ) ) + { + currentBestSolution = currentSolution; + currentBestCost = Evaluate( ¤tBestSolution ); + } + } + + // store the best solution after the run + m_BestSolution = currentBestSolution; +} + +void mitk::ConnectomicsSimulatedAnnealingPermutationModularity::CleanUp() +{ + // delete empty modules, if any + for( int loop( 0 ); loop < getNumberOfModules( &m_BestSolution ) ; loop++ ) + { + if( getNumberOfVerticesInModule( &m_BestSolution, loop ) < 1 ) + { + removeModule( &m_BestSolution, loop ); + } + } +} + +void mitk::ConnectomicsSimulatedAnnealingPermutationModularity::permutateMappingSingleNodeShift( + ToModuleMapType *vertexToModuleMap, mitk::ConnectomicsNetwork::Pointer network ) +{ + + const int nodeCount = vertexToModuleMap->size(); + const int moduleCount = getNumberOfModules( vertexToModuleMap ); + + // the random number generators + vnl_random rng( (unsigned int) rand() ); + unsigned long randomNode = rng.lrand32( nodeCount - 1 ); + // move the node either to any existing module, or to its own + //unsigned long randomModule = rng.lrand32( moduleCount ); + unsigned long randomModule = rng.lrand32( moduleCount - 1 ); + + // do some sanity checks + + if ( nodeCount < 2 ) + { + // no sense in doing anything + return; + } + + const std::vector< VertexDescriptorType > allNodesVector + = network->GetVectorOfAllVertexDescriptors(); + + ToModuleMapType::iterator iter = vertexToModuleMap->find( allNodesVector[ randomNode ] ); + const int previousModuleNumber = iter->second; + + // if we move the node to its own module, do nothing + if( previousModuleNumber == randomModule ) + { + return; + } + + iter->second = randomModule; + + if( getNumberOfVerticesInModule( vertexToModuleMap, previousModuleNumber ) < 1 ) + { + removeModule( vertexToModuleMap, previousModuleNumber ); + } +} + +void mitk::ConnectomicsSimulatedAnnealingPermutationModularity::permutateMappingModuleChange( + ToModuleMapType *vertexToModuleMap, double currentTemperature, mitk::ConnectomicsNetwork::Pointer network ) +{ + //the random number generators + vnl_random rng( (unsigned int) rand() ); + + //randomly generate threshold + const double threshold = rng.drand64( 0.0 , 1.0); + + //for deciding whether to join two modules or split one + double splitThreshold = 0.5; + + //stores whether to join or two split + bool joinModules( false ); + + //select random module + int numberOfModules = getNumberOfModules( vertexToModuleMap ); + unsigned long randomModuleA = rng.lrand32( numberOfModules - 1 ); + + //select the second module to join, if joining + unsigned long randomModuleB = rng.lrand32( numberOfModules - 1 ); + + if( ( threshold < splitThreshold ) && ( randomModuleA != randomModuleB ) ) + { + joinModules = true; + } + + if( joinModules ) + { + // this being an kommutative operation, we will always join B to A + joinTwoModules( vertexToModuleMap, randomModuleA, randomModuleB ); + //eliminate the empty module + removeModule( vertexToModuleMap, randomModuleB ); + + } + else + { + //split module + splitModule( vertexToModuleMap, currentTemperature, network, randomModuleA ); + } + + +} + +void mitk::ConnectomicsSimulatedAnnealingPermutationModularity::joinTwoModules( + ToModuleMapType *vertexToModuleMap, int moduleA, int moduleB ) +{ + + ToModuleMapType::iterator iter = vertexToModuleMap->begin(); + ToModuleMapType::iterator end = vertexToModuleMap->end(); + + while( iter != end ) + { + // if vertex belongs to module B move it to A + if( iter->second == moduleB ) + { + iter->second = moduleA; + } + + iter++; + }// end while( iter != end ) +} + +void mitk::ConnectomicsSimulatedAnnealingPermutationModularity::splitModule( + ToModuleMapType *vertexToModuleMap, double currentTemperature, mitk::ConnectomicsNetwork::Pointer network, int moduleToSplit ) +{ + + if( m_Depth == 0 ) + { + // do nothing + return; + } + + // if the module contains only one node, no more division is sensible + if( getNumberOfVerticesInModule( vertexToModuleMap, moduleToSplit ) < 2 ) + { + // do nothing + return; + } + + // create subgraph of the module, that is to be splitted + + mitk::ConnectomicsNetwork::Pointer subNetwork = mitk::ConnectomicsNetwork::New(); + VertexToVertexMapType graphToSubgraphVertexMap; + VertexToVertexMapType subgraphToGraphVertexMap; + + + extractModuleSubgraph( vertexToModuleMap, network, moduleToSplit, subNetwork, &graphToSubgraphVertexMap, &subgraphToGraphVertexMap ); + + + // The submap + ToModuleMapType vertexToModuleSubMap; + + // copy vertices + VertexToVertexMapType::iterator iter = graphToSubgraphVertexMap.begin(); + VertexToVertexMapType::iterator end = graphToSubgraphVertexMap.end(); + + // run simulated annealing on the subgraph to determine how the module should be split + if( m_Depth > 0 && m_StepSize > 0 ) + { + mitk::ConnectomicsSimulatedAnnealingManager::Pointer manager = mitk::ConnectomicsSimulatedAnnealingManager::New(); + mitk::ConnectomicsSimulatedAnnealingPermutationModularity::Pointer permutation = mitk::ConnectomicsSimulatedAnnealingPermutationModularity::New(); + mitk::ConnectomicsSimulatedAnnealingCostFunctionModularity::Pointer costFunction = mitk::ConnectomicsSimulatedAnnealingCostFunctionModularity::New(); + + permutation->SetCostFunction( costFunction.GetPointer() ); + permutation->SetNetwork( subNetwork ); + permutation->SetDepth( m_Depth - 1 ); + permutation->SetStepSize( m_StepSize * 2 ); + + manager->SetPermutation( permutation.GetPointer() ); + + manager->RunSimulatedAnnealing( currentTemperature, m_StepSize * 2 ); + + vertexToModuleSubMap = permutation->GetMapping(); + } + + // now carry the information over to the original map + std::vector< int > moduleTranslationVector; + moduleTranslationVector.resize( getNumberOfModules( &vertexToModuleSubMap ), 0 ); + int originalNumber = getNumberOfModules( vertexToModuleMap ); + + // the new parts are added at the end + for(int index( 0 ); index < moduleTranslationVector.size() ; index++) + { + moduleTranslationVector[ index ] = originalNumber + index; + } + + ToModuleMapType::iterator iter2 = vertexToModuleSubMap.begin(); + ToModuleMapType::iterator end2 = vertexToModuleSubMap.end(); + + while( iter2 != end2 ) + { + // translate vertex descriptor from subgraph to graph + VertexDescriptorType key = subgraphToGraphVertexMap.find( iter2->first )->second; + // translate module number from subgraph to graph + int value = moduleTranslationVector[ iter2->second ]; + // change the corresponding entry + vertexToModuleMap->find( key )->second = value; + + iter2++; + } + + // remove the now empty module, that was splitted + removeModule( vertexToModuleMap, moduleToSplit ); + +} + +void mitk::ConnectomicsSimulatedAnnealingPermutationModularity::extractModuleSubgraph( + ToModuleMapType *vertexToModuleMap, + mitk::ConnectomicsNetwork::Pointer network, + int moduleToSplit, + mitk::ConnectomicsNetwork::Pointer subNetwork, + VertexToVertexMapType* graphToSubgraphVertexMap, + VertexToVertexMapType* subgraphToGraphVertexMap ) +{ + const std::vector< VertexDescriptorType > allNodesVector = network->GetVectorOfAllVertexDescriptors(); + + // add vertices to subgraph + for( int nodeNumber( 0 ); nodeNumber < allNodesVector.size() ; nodeNumber++) + { + int correspondingModule = vertexToModuleMap->find( allNodesVector[ nodeNumber ] )->second; + + if( moduleToSplit == vertexToModuleMap->find( allNodesVector[ nodeNumber ] )->second ) + { + int id = network->GetNode( allNodesVector[ nodeNumber ] ).id; + VertexDescriptorType newVertex = subNetwork->AddVertex( id ); + + graphToSubgraphVertexMap->insert( + std::pair( + allNodesVector[ nodeNumber ], newVertex + ) + ); + subgraphToGraphVertexMap->insert( + std::pair( + newVertex, allNodesVector[ nodeNumber ] + ) + ); + } + } + + // add edges to subgraph + VertexToVertexMapType::iterator iter = graphToSubgraphVertexMap->begin(); + VertexToVertexMapType::iterator end = graphToSubgraphVertexMap->end(); + + while( iter != end ) + { + const std::vector< VertexDescriptorType > adjacentNodexVector + = network->GetVectorOfAdjacentNodes( iter->first ); + + for( int adjacentNodeNumber( 0 ); adjacentNodeNumber < adjacentNodexVector.size() ; adjacentNodeNumber++) + { + // if the adjacent vertex is part of the subgraph, + // add edge, if it does not exist yet, else do nothing + + VertexDescriptorType adjacentVertex = adjacentNodexVector[ adjacentNodeNumber ]; + if( graphToSubgraphVertexMap->count( adjacentVertex ) > 0 ) + { + if( !subNetwork->EdgeExists( iter->second, graphToSubgraphVertexMap->find( adjacentVertex )->second ) ) + { //edge exists in parent network, but not yet in sub network + const VertexDescriptorType vertexA = iter->second; + const VertexDescriptorType vertexB = graphToSubgraphVertexMap->find( adjacentVertex )->second; + const int sourceID = network->GetNode( vertexA ).id; + const int targetID = network->GetNode( vertexB ).id; + const int weight = network->GetEdge( iter->first, graphToSubgraphVertexMap->find( adjacentVertex )->first ).weight; + subNetwork->AddEdge( vertexA , vertexB, sourceID, targetID, weight ); + } + } + } + iter++; + }// end while( iter != end ) +} + +int mitk::ConnectomicsSimulatedAnnealingPermutationModularity::getNumberOfModules( + ToModuleMapType *vertexToModuleMap ) const +{ + int maxModule( 0 ); + ToModuleMapType::iterator iter = vertexToModuleMap->begin(); + ToModuleMapType::iterator end = vertexToModuleMap->end(); + while( iter != end ) + { + if( iter->second > maxModule ) + { + maxModule = iter->second; + } + + iter++; + } + + return maxModule + 1; +} + +int mitk::ConnectomicsSimulatedAnnealingPermutationModularity::getNumberOfVerticesInModule( + ToModuleMapType *vertexToModuleMap, int module ) const +{ + int number( 0 ); + ToModuleMapType::iterator iter = vertexToModuleMap->begin(); + ToModuleMapType::iterator end = vertexToModuleMap->end(); + while( iter != end ) + { + if( iter->second == module ) + { + number++; + } + + iter++; + } + + return number; +} + +void mitk::ConnectomicsSimulatedAnnealingPermutationModularity::removeModule( + ToModuleMapType *vertexToModuleMap, int module ) +{ + int lastModuleNumber = getNumberOfModules( vertexToModuleMap ) - 1; + if( module == lastModuleNumber ) + { + // no need to do anything, the last module is deleted "automatically" + return; + } + + if( getNumberOfVerticesInModule( vertexToModuleMap, module ) > 0 ) + { + MBI_WARN << "Trying to remove non-empty module"; + return; + } + + ToModuleMapType::iterator iter = vertexToModuleMap->begin(); + ToModuleMapType::iterator end = vertexToModuleMap->end(); + while( iter != end ) + { + if( iter->second == lastModuleNumber ) + { + // renumber last module to to-be-deleted module + iter->second = module; + } + + iter++; + } +} + +void mitk::ConnectomicsSimulatedAnnealingPermutationModularity::randomlyAssignNodesToModules( + ToModuleMapType *vertexToModuleMap, int numberOfIntendedModules ) +{ + // we make sure that each intended module contains *at least* one node + // thus if more modules are asked for than node exists we will only generate + // as many modules as there are nodes + if( numberOfIntendedModules > vertexToModuleMap->size() ) + { + MBI_ERROR << "Tried to generate more modules than vertices were provided"; + numberOfIntendedModules = vertexToModuleMap->size(); + } + + //the random number generators + vnl_random rng( (unsigned int) rand() ); + + std::vector< int > histogram; + std::vector< int > nodeList; + + histogram.resize( numberOfIntendedModules, 0 ); + nodeList.resize( vertexToModuleMap->size(), 0 ); + + int numberOfVertices = vertexToModuleMap->size(); + + //randomly distribute nodes to modules + for( int nodeIndex( 0 ); nodeIndex < nodeList.size(); nodeIndex++ ) + { + //select random module + nodeList[ nodeIndex ] = rng.lrand32( numberOfIntendedModules - 1 ); + + histogram[ nodeList[ nodeIndex ] ]++; + + } + + // make sure no module contains no node, if one does assign it one of a random module + // that does contain at least two + for( int moduleIndex( 0 ); moduleIndex < histogram.size(); moduleIndex++ ) + { + while( histogram[ moduleIndex ] == 0 ) + { + int randomNodeIndex = rng.lrand32( numberOfVertices - 1 ); + if( histogram[ nodeList[ randomNodeIndex ] ] > 1 ) + { + histogram[ moduleIndex ]++; + histogram[ nodeList[ randomNodeIndex ] ]--; + nodeList[ randomNodeIndex ] = moduleIndex; + } + } + } + + ToModuleMapType::iterator iter = vertexToModuleMap->begin(); + ToModuleMapType::iterator end = vertexToModuleMap->end(); + + for( int index( 0 ); ( iter != end ) && ( index < nodeList.size() ); index++, iter++ ) + { + iter->second = nodeList[ index ] ; + } +} + +void mitk::ConnectomicsSimulatedAnnealingPermutationModularity::SetMapping( ToModuleMapType mapping ) +{ + m_BestSolution = mapping; +} + +mitk::ConnectomicsSimulatedAnnealingPermutationModularity::ToModuleMapType +mitk::ConnectomicsSimulatedAnnealingPermutationModularity::GetMapping() +{ + return m_BestSolution; +} + +double mitk::ConnectomicsSimulatedAnnealingPermutationModularity::Evaluate( ToModuleMapType* mapping ) const +{ + mitk::ConnectomicsSimulatedAnnealingCostFunctionModularity* costMapping = + dynamic_cast( m_CostFunction.GetPointer() ); + if( costMapping ) + { + return costMapping->Evaluate( m_Network, mapping ); + } + else + { + return 0; + } +} + +bool mitk::ConnectomicsSimulatedAnnealingPermutationModularity::AcceptChange( double costBefore, double costAfter, double temperature ) const +{ + if( costAfter <= costBefore ) + {// if cost is lower after + return true; + } + + //the random number generators + vnl_random rng( (unsigned int) rand() ); + + //randomly generate threshold + const double threshold = rng.drand64( 0.0 , 1.0); + + //the likelihood of acceptance + double likelihood = std::exp( - ( costAfter - costBefore ) / temperature ); + + if( threshold < likelihood ) + { + return true; + } + + return false; +} + + +void mitk::ConnectomicsSimulatedAnnealingPermutationModularity::SetDepth( int depth ) +{ + m_Depth = depth; +} + +void mitk::ConnectomicsSimulatedAnnealingPermutationModularity::SetStepSize( double size ) +{ + m_StepSize = size; +} \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationModularity.h b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationModularity.h new file mode 100644 index 0000000000..9f56b2d7e1 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationModularity.h @@ -0,0 +1,140 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef mitkConnectomicsSimulatedAnnealingPermutationModularity_h +#define mitkConnectomicsSimulatedAnnealingPermutationModularity_h + +#include "mitkConnectomicsSimulatedAnnealingPermutationBase.h" + +#include "mitkConnectomicsNetwork.h" + +namespace mitk +{ + /** + * \brief A class providing permutations for the calculation of modularity using simulated annealing */ + class MitkDiffusionImaging_EXPORT ConnectomicsSimulatedAnnealingPermutationModularity : public mitk::ConnectomicsSimulatedAnnealingPermutationBase + { + public: + + typedef mitk::ConnectomicsNetwork::VertexDescriptorType VertexDescriptorType; + typedef std::map< VertexDescriptorType, int > ToModuleMapType; + typedef std::map< VertexDescriptorType, VertexDescriptorType > VertexToVertexMapType; + + /** Standard class typedefs. */ + /** Method for creation through the object factory. */ + + mitkClassMacro(ConnectomicsSimulatedAnnealingPermutationModularity, itk::Object); + itkNewMacro(Self); + + // Initialize the permutation + virtual void Initialize(); + + // Do a permutation for a specific temperature + virtual void Permutate( double temperature ); + + // Do clean up necessary after a permutation + virtual void CleanUp(); + + // set the network permutation is to be run upon + void SetNetwork( mitk::ConnectomicsNetwork::Pointer theNetwork ); + + // Get the number of modules the graph has ( highest number - 1 ) + int getNumberOfModules( ToModuleMapType *vertexToModuleMap ) const; + + // Get the number of vertices belonging to a given module + int getNumberOfVerticesInModule( ToModuleMapType *vertexToModuleMap, int module ) const; + + // Set the mapping + void SetMapping( ToModuleMapType mapping ); + + // Get the mapping + ToModuleMapType GetMapping(); + + // Set depth + void SetDepth( int depth ); + + // Set stepSize + void SetStepSize( double size ); + + protected: + + //////////////////// Functions /////////////////////// + ConnectomicsSimulatedAnnealingPermutationModularity(); + ~ConnectomicsSimulatedAnnealingPermutationModularity(); + + // This function moves one single node from a module to another + void permutateMappingSingleNodeShift( + ToModuleMapType *vertexToModuleMap, + mitk::ConnectomicsNetwork::Pointer network ); + + // This function splits and joins modules + void permutateMappingModuleChange( + ToModuleMapType *vertexToModuleMap, + double currentTemperature, + mitk::ConnectomicsNetwork::Pointer network ); + + // join the two given modules to a single one + void joinTwoModules( ToModuleMapType *vertexToModuleMap, int moduleA, int moduleB ); + + // split the given module recursively up to a certain level + // first randomly assigns nodes and then starts another simulated annealing + // on the sub network, as long as depthOfModuleChange > 0 + void splitModule( + ToModuleMapType *vertexToModuleMap, + double currentTemperature, + mitk::ConnectomicsNetwork::Pointer network, + int moduleToSplit ); + + // Extract the subgraph of a network containing all nodes + // of a given module and the egdes between them + void extractModuleSubgraph( + ToModuleMapType *vertexToModuleMap, + mitk::ConnectomicsNetwork::Pointer network, + int moduleToSplit, + mitk::ConnectomicsNetwork::Pointer subNetwork, + VertexToVertexMapType* graphToSubgraphVertexMap, + VertexToVertexMapType* subgraphToGraphVertexMap ); + + // Remove empty modules by moving all nodes of the highest module to the given module + void removeModule( ToModuleMapType *vertexToModuleMap, int module ); + + // Randomly assign nodes to modules, this makes sure each module contains at least one node + // as long as numberOfIntendedModules < number of nodes + void randomlyAssignNodesToModules(ToModuleMapType *vertexToModuleMap, int numberOfIntendedModules ); + + // Evaluate mapping using a modularity cost function + double Evaluate( ToModuleMapType* mapping ) const; + + // Whether to accept the permutation + bool AcceptChange( double costBefore, double costAfter, double temperature ) const; + + // the current best solution + ToModuleMapType m_BestSolution; + + // the network + mitk::ConnectomicsNetwork::Pointer m_Network; + + // How many levels of recursive calls can be gone down + int m_Depth; + + // The step size for recursive configuring of simulated annealing manager + double m_StepSize; + }; + +}// end namespace mitk + +#endif // mitkConnectomicsSimulatedAnnealingPermutationModularity_h \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSyntheticNetworkGenerator.cpp b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSyntheticNetworkGenerator.cpp new file mode 100644 index 0000000000..927ae173c6 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSyntheticNetworkGenerator.cpp @@ -0,0 +1,350 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsSyntheticNetworkGenerator.h" + +#include +#include + +#include "mitkConnectomicsConstantsManager.h" + +#include + +//for random number generation +#include "vxl/core/vnl/vnl_random.h" +#include "vxl/core/vnl/vnl_math.h" + +mitk::ConnectomicsSyntheticNetworkGenerator::ConnectomicsSyntheticNetworkGenerator() +{ +} + +mitk::ConnectomicsSyntheticNetworkGenerator::~ConnectomicsSyntheticNetworkGenerator() +{ +} + +mitk::ConnectomicsNetwork::Pointer mitk::ConnectomicsSyntheticNetworkGenerator::CreateSyntheticNetwork(int networkTypeId, int paramterOne, double parameterTwo) +{ + mitk::ConnectomicsNetwork::Pointer network = mitk::ConnectomicsNetwork::New(); + + // give the network an artificial geometry + network->SetGeometry( this->GenerateDefaultGeometry() ); + + switch (networkTypeId) { + case 0: + GenerateSyntheticCubeNetwork( network, paramterOne, parameterTwo ); + break; + case 1: + GenerateSyntheticCenterToSurfaceNetwork( network, paramterOne, parameterTwo ); + break; + case 2: + GenerateSyntheticRandomNetwork( network, paramterOne, parameterTwo ); + break; + case 3: + //GenerateSyntheticScaleFreeNetwork( network, 1000 ); + break; + case 4: + //GenerateSyntheticSmallWorldNetwork( network, 1000 ); + break; + default: + MBI_ERROR << "Unrecognized Network ID"; + } + + return network; + +} + +mitk::Geometry3D::Pointer mitk::ConnectomicsSyntheticNetworkGenerator::GenerateDefaultGeometry() +{ + mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); + + double zero( 0.0 ); + double one( 1.0 ); + // origin = {0,0,0} + mitk::Point3D origin; + + origin[0] = zero; + origin[1] = zero; + origin[2] = zero; + geometry->SetOrigin(origin); + + // spacing = {1,1,1} + float spacing[3]; + spacing[0] = one; + spacing[1] = one; + spacing[2] = one; + geometry->SetSpacing(spacing); + + // transform + vtkMatrix4x4* transformMatrix = vtkMatrix4x4::New(); + transformMatrix->SetElement(0,0,one); + transformMatrix->SetElement(1,0,zero); + transformMatrix->SetElement(2,0,zero); + transformMatrix->SetElement(0,1,zero); + transformMatrix->SetElement(1,1,one); + transformMatrix->SetElement(2,1,zero); + transformMatrix->SetElement(0,2,zero); + transformMatrix->SetElement(1,2,zero); + transformMatrix->SetElement(2,2,one); + + transformMatrix->SetElement(0,3,origin[0]); + transformMatrix->SetElement(1,3,origin[1]); + transformMatrix->SetElement(2,3,origin[2]); + transformMatrix->SetElement(3,3,1); + geometry->SetIndexToWorldTransformByVtkMatrix( transformMatrix ); + + geometry->SetImageGeometry(true); + + return geometry; +} + +void mitk::ConnectomicsSyntheticNetworkGenerator::GenerateSyntheticCubeNetwork( + mitk::ConnectomicsNetwork::Pointer network, int cubeExtent, double distance ) +{ + // map for storing the conversion from indices to vertex descriptor + std::map< int, mitk::ConnectomicsNetwork::VertexDescriptorType > idToVertexMap; + + int vertexID(0); + for( int loopX( 0 ); loopX < cubeExtent; loopX++ ) + { + for( int loopY( 0 ); loopY < cubeExtent; loopY++ ) + { + for( int loopZ( 0 ); loopZ < cubeExtent; loopZ++ ) + { + std::vector< float > position; + std::string label; + std::stringstream labelStream; + labelStream << vertexID; + label = labelStream.str(); + + position.push_back( loopX * distance ); + position.push_back( loopY * distance ); + position.push_back( loopZ * distance ); + + mitk::ConnectomicsNetwork::VertexDescriptorType newVertex = network->AddVertex( vertexID ); + network->SetLabel( newVertex, label ); + network->SetCoordinates( newVertex, position ); + + if ( idToVertexMap.count( vertexID ) > 0 ) + { + MITK_ERROR << "Aborting network creation, duplicate vertex ID generated."; + return; + } + idToVertexMap.insert( std::pair< int, mitk::ConnectomicsNetwork::VertexDescriptorType >( vertexID, newVertex) ); + + vertexID++; + } + } + } + + int edgeID(0), edgeSourceID(0), edgeTargetID(0); + // uniform weight of one + int edgeWeight(1); + + mitk::ConnectomicsNetwork::VertexDescriptorType source; + mitk::ConnectomicsNetwork::VertexDescriptorType target; + + for( int loopX( 0 ); loopX < cubeExtent; loopX++ ) + { + for( int loopY( 0 ); loopY < cubeExtent; loopY++ ) + { + for( int loopZ( 0 ); loopZ < cubeExtent; loopZ++ ) + { + // to avoid creating an edge twice (this being an undirected graph) we only generate + // edges in three directions, the others will be supplied by the corresponding nodes + if( loopX != 0 ) + { + edgeTargetID = edgeSourceID - cubeExtent * cubeExtent; + + source = idToVertexMap.find( edgeSourceID )->second; + target = idToVertexMap.find( edgeTargetID )->second; + network->AddEdge( source, target, edgeSourceID, edgeTargetID, edgeWeight); + + edgeID++; + } + if( loopY != 0 ) + { + edgeTargetID = edgeSourceID - cubeExtent; + + source = idToVertexMap.find( edgeSourceID )->second; + target = idToVertexMap.find( edgeTargetID )->second; + network->AddEdge( source, target, edgeSourceID, edgeTargetID, edgeWeight); + + edgeID++; + } + if( loopZ != 0 ) + { + edgeTargetID = edgeSourceID - 1; + + source = idToVertexMap.find( edgeSourceID )->second; + target = idToVertexMap.find( edgeTargetID )->second; + network->AddEdge( source, target, edgeSourceID, edgeTargetID, edgeWeight); + + edgeID++; + } + + edgeSourceID++; + } // end for( int loopZ( 0 ); loopZ < cubeExtent; loopZ++ ) + } // end for( int loopY( 0 ); loopY < cubeExtent; loopY++ ) + } // end for( int loopX( 0 ); loopX < cubeExtent; loopX++ ) +} + +void mitk::ConnectomicsSyntheticNetworkGenerator::GenerateSyntheticCenterToSurfaceNetwork( + mitk::ConnectomicsNetwork::Pointer network, int numberOfPoints, double radius ) +{ + //the random number generators + unsigned int randomOne = (unsigned int) rand(); + unsigned int randomTwo = (unsigned int) rand(); + + vnl_random rng( (unsigned int) rand() ); + vnl_random rng2( (unsigned int) rand() ); + + mitk::ConnectomicsNetwork::VertexDescriptorType centerVertex; + int vertexID(0); + { //add center vertex + std::vector< float > position; + std::string label; + std::stringstream labelStream; + labelStream << vertexID; + label = labelStream.str(); + + position.push_back( 0 ); + position.push_back( 0 ); + position.push_back( 0 ); + + centerVertex = network->AddVertex( vertexID ); + network->SetLabel( centerVertex, label ); + network->SetCoordinates( centerVertex, position ); + }//end add center vertex + + // uniform weight of one + int edgeWeight(1); + + mitk::ConnectomicsNetwork::VertexDescriptorType source; + mitk::ConnectomicsNetwork::VertexDescriptorType target; + + //add vertices on sphere surface + for( int loopID( 1 ); loopID < numberOfPoints; loopID++ ) + { + + std::vector< float > position; + std::string label; + std::stringstream labelStream; + labelStream << loopID; + label = labelStream.str(); + + //generate random, uniformly distributed points on a sphere surface + const double uVariable = rng.drand64( 0.0 , 1.0); + const double vVariable = rng.drand64( 0.0 , 1.0); + const double phi = 2 * vnl_math::pi * uVariable; + const double theta = std::acos( 2 * vVariable - 1 ); + + double xpos = radius * std::cos( phi ) * std::sin( theta ); + double ypos = radius * std::sin( phi ) * std::sin( theta ); + double zpos = radius * std::cos( theta ); + + position.push_back( xpos ); + position.push_back( ypos ); + position.push_back( zpos ); + + mitk::ConnectomicsNetwork::VertexDescriptorType newVertex = network->AddVertex( loopID ); + network->SetLabel( newVertex, label ); + network->SetCoordinates( newVertex, position ); + + network->AddEdge( newVertex, centerVertex, loopID, 0, edgeWeight); + } +} + +void mitk::ConnectomicsSyntheticNetworkGenerator::GenerateSyntheticRandomNetwork( + mitk::ConnectomicsNetwork::Pointer network, int numberOfPoints, double threshold ) +{ + // as the surface is proportional to the square of the radius the density stays the same + double radius = 5 * std::sqrt( (float) numberOfPoints ); + + //the random number generators + unsigned int randomOne = (unsigned int) rand(); + unsigned int randomTwo = (unsigned int) rand(); + + vnl_random rng( (unsigned int) rand() ); + vnl_random rng2( (unsigned int) rand() ); + + // map for storing the conversion from indices to vertex descriptor + std::map< int, mitk::ConnectomicsNetwork::VertexDescriptorType > idToVertexMap; + + //add vertices on sphere surface + for( int loopID( 0 ); loopID < numberOfPoints; loopID++ ) + { + + std::vector< float > position; + std::string label; + std::stringstream labelStream; + labelStream << loopID; + label = labelStream.str(); + + //generate random, uniformly distributed points on a sphere surface + const double uVariable = rng.drand64( 0.0 , 1.0); + const double vVariable = rng.drand64( 0.0 , 1.0); + const double phi = 2 * vnl_math::pi * uVariable; + const double theta = std::acos( 2 * vVariable - 1 ); + + double xpos = radius * std::cos( phi ) * std::sin( theta ); + double ypos = radius * std::sin( phi ) * std::sin( theta ); + double zpos = radius * std::cos( theta ); + + position.push_back( xpos ); + position.push_back( ypos ); + position.push_back( zpos ); + + mitk::ConnectomicsNetwork::VertexDescriptorType newVertex = network->AddVertex( loopID ); + network->SetLabel( newVertex, label ); + network->SetCoordinates( newVertex, position ); + + if ( idToVertexMap.count( loopID ) > 0 ) + { + MITK_ERROR << "Aborting network creation, duplicate vertex ID generated."; + return; + } + idToVertexMap.insert( std::pair< int, mitk::ConnectomicsNetwork::VertexDescriptorType >( loopID, newVertex) ); + } + + int edgeID(0); + // uniform weight of one + int edgeWeight(1); + + mitk::ConnectomicsNetwork::VertexDescriptorType source; + mitk::ConnectomicsNetwork::VertexDescriptorType target; + + for( int loopID( 0 ); loopID < numberOfPoints; loopID++ ) + { + // to avoid creating an edge twice (this being an undirected graph) we only + // potentially generate edges with all nodes with a bigger ID + for( int innerLoopID( loopID ); innerLoopID < numberOfPoints; innerLoopID++ ) + { + if( rng.drand64( 0.0 , 1.0) > threshold) + { + // do nothing + } + else + { + source = idToVertexMap.find( loopID )->second; + target = idToVertexMap.find( innerLoopID )->second; + network->AddEdge( source, target, loopID, innerLoopID, edgeWeight); + + edgeID++; + } + } // end for( int innerLoopID( loopID ); innerLoopID < numberOfPoints; innerLoopID++ ) + } // end for( int loopID( 0 ); loopID < numberOfPoints; loopID++ ) +} \ No newline at end of file diff --git a/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSyntheticNetworkGenerator.h b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSyntheticNetworkGenerator.h new file mode 100644 index 0000000000..dca9005c48 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/Connectomics/mitkConnectomicsSyntheticNetworkGenerator.h @@ -0,0 +1,83 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef mitkConnectomicsSyntheticNetworkGenerator_h +#define mitkConnectomicsSyntheticNetworkGenerator_h + +#include +#include +#include + +#include "mitkCommon.h" +#include "mitkImage.h" + +#include "mitkConnectomicsNetwork.h" + +#include "MitkDiffusionImagingExports.h" + +namespace mitk +{ + + /** + * \brief A class to generate synthetic networks */ + class MitkDiffusionImaging_EXPORT ConnectomicsSyntheticNetworkGenerator : public itk::Object + { + public: + + /** Standard class typedefs. */ + /** Method for creation through the object factory. */ + + mitkClassMacro(ConnectomicsSyntheticNetworkGenerator, itk::Object); + itkNewMacro(Self); + + /** Create Synthetic Networks */ + mitk::ConnectomicsNetwork::Pointer CreateSyntheticNetwork(int networkTypeId, int paramterOne, double parameterTwo); + + protected: + + //////////////////// Functions /////////////////////// + ConnectomicsSyntheticNetworkGenerator(); + ~ConnectomicsSyntheticNetworkGenerator(); + + /** Generate a default geometry for synthetic images */ + mitk::Geometry3D::Pointer GenerateDefaultGeometry(); + + /** Generate a synthetic cube (regular lattice) network */ + void GenerateSyntheticCubeNetwork( mitk::ConnectomicsNetwork::Pointer network, int cubeExtent, double distance ); + + /** Generate a highly heterogenic network + * + * This is achieved by generating a center vertex and vertices on + * a sphere surface, which are all only connected to the center + * vertex. */ + void GenerateSyntheticCenterToSurfaceNetwork( + mitk::ConnectomicsNetwork::Pointer network, int numberOfPoints, double radius ); + + /** Generate a random network without specific characteristics + * + * This is achieved by generating vertices and then deciding whether to + * specific vertices are connected by comparing a random number to the threshold */ + void GenerateSyntheticRandomNetwork( + mitk::ConnectomicsNetwork::Pointer network, int numberOfPoints, double threshold ); + + /////////////////////// Variables //////////////////////// + + }; + +}// end namespace mitk + +#endif // _mitkConnectomicsSyntheticNetworkGenerator_H_INCLUDED \ No newline at end of file diff --git a/Modules/DiffusionImaging/CMakeLists.txt b/Modules/DiffusionImaging/CMakeLists.txt index d072bc8493..0baae5d9ef 100644 --- a/Modules/DiffusionImaging/CMakeLists.txt +++ b/Modules/DiffusionImaging/CMakeLists.txt @@ -1,28 +1,28 @@ find_package(ITK) if(ITK_GDCM_DIR) include(${ITK_GDCM_DIR}/GDCMConfig.cmake) if(GDCM_MAJOR_VERSION EQUAL 2) add_definitions(-DGDCM2) set(ITK_USES_GDCM2 1) endif(GDCM_MAJOR_VERSION EQUAL 2) endif(ITK_GDCM_DIR) MITK_CREATE_MODULE( MitkDiffusionImaging SUBPROJECTS MITK-DTI - INCLUDE_DIRS IODataStructures Reconstruction Tractography Rendering Algorithms DicomImport Interactions IODataStructures/DiffusionWeightedImages IODataStructures/QBallImages IODataStructures/TensorImages IODataStructures/FiberBundle IODataStructures/FiberBundleX IODataStructures/PlanarFigureComposite IODataStructures/TbssImages ${CMAKE_CURRENT_BINARY_DIR} + INCLUDE_DIRS IODataStructures Reconstruction Tractography Rendering Algorithms DicomImport Interactions IODataStructures/DiffusionWeightedImages IODataStructures/QBallImages IODataStructures/TensorImages IODataStructures/FiberBundle IODataStructures/FiberBundleX IODataStructures/PlanarFigureComposite IODataStructures/TbssImages Algorithms/Connectomics IODataStructures/ConnectomicsNetwork ${CMAKE_CURRENT_BINARY_DIR} DEPENDS MitkExt SceneSerializationBase QmitkExt MitkGraphAlgorithms PACKAGE_DEPENDS Boost ) MITK_USE_MODULE(MitkDiffusionImaging) if(MitkDiffusionImaging_IS_ENABLED) file(DOWNLOAD http://mitk.org/download/data/FibertrackingLUT.tar.gz ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/FibertrackingLUT.tar.gz TIMEOUT 10) execute_process(COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} tar xzf FibertrackingLUT.tar.gz) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Rendering/mitkShaderFiberClipping.xml ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mitkShaderFiberClipping.xml) MITK_INSTALL(FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mitkShaderFiberClipping.xml ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/FiberTrackingLUTBaryCoords.bin ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/FiberTrackingLUTIndices.bin) endif() add_subdirectory(Testing) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/mitkDiffusionImagingConfigure.h.in ${CMAKE_CURRENT_BINARY_DIR}/mitkDiffusionImagingConfigure.h) diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsConstantsManager.cpp b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsConstantsManager.cpp new file mode 100644 index 0000000000..884f2ec928 --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsConstantsManager.cpp @@ -0,0 +1,61 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile$ +Language: C++ +Date: $Date$ +Version: $Revision: 11989 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +//#ifndef _MITK_ConnectomicsConstantsManager_CPP +//#define _MITK_ConnectomicsConstantsManager_CPP + +#include "mitkConnectomicsConstantsManager.h" + +//============== String and other constants =================== + +//==== Error messages ==== +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_TRIED_TO_ACCESS_INVALID_HISTOGRAM = "Tried to access invalid histogram."; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_PASSED_NEGATIVE_INDEX_TO_HISTOGRAM = "Passed negative index to histogram."; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_OUTSIDE_INTEGER_RANGE = "Tried to access histogram vector outside integer range."; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_BEYOND_SCOPE = "Tried to access histogram vector for value beyond scope: "; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_INVALID_MAPPING = "Invalid mapping strategy selected."; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_ERROR_INVALID_DIMENSION_NEED_3 = "Invalid dimension, need dimension 3."; + +//==== Warnings ==== +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_ZERO_DISTANCE_NODES = "There are nodes which are not distance 0 to themselves."; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_UNIMPLEMENTED_FEATURE = "You are trying to use an as of yet unimplemented feature."; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_MORE_POINTS_THAN_PRESENT = "Trying to estimate using more points than are present."; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_ESTIMATING_LESS_THAN_2 = "Trying to estimate using less than two points."; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_ESTIMATING_BEYOND_END = "Trying to estimate using points beyond track end."; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_ESTIMATING_BEYOND_START = "Trying to estimate using points beyond track start."; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_DID_NOT_FIND_WHITE = "Did not find a non white matter label."; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_NOT_EXTEND_TO_WHITE = "Could not extend to non white matter."; + +//==== Information ==== +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_INFO_NETWORK_CREATED = "Network has been created."; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_NETWORK_NOT_VALID = "Network not valid."; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_NETWORK_DISCONNECTED = "Network is disconnected."; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_CAN_NOT_COMPUTE_EFFICIENCY = "Can not compute efficiency. "; + +//==== GUI ==== +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_DASH = "-"; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_CONNECTOMICS_CREATION = "Connectomics Creation"; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_SELECTION_WARNING = "Please load and select exactly one parcellation image and one fiber image before starting network creation."; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_PERFORMING_IMAGE_PROCESSING_FOR_IMAGE = "Performing image processing for image "; + +//==== Properties ==== +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_PROPERTY_DEFAULT_RGBA_NAME = "rgbaImage"; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_PROPERTY_NAME = "name"; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_PROPERTY_VOLUMERENDERING = "volumerendering"; +const char* mitk::ConnectomicsConstantsManager::CONNECTOMICS_PROPERTY_DEFAULT_CNF_NAME = "Connectomics network"; + +//#endif /* _MITK_ConnectomicsConstantsManager_CPP */ \ No newline at end of file diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsConstantsManager.h b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsConstantsManager.h new file mode 100644 index 0000000000..12cbdf5b45 --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsConstantsManager.h @@ -0,0 +1,86 @@ + +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile$ +Language: C++ +Date: $Date$ +Version: $Revision: 11989 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef _MITK_ConnectomicsConstantsManager_H +#define _MITK_ConnectomicsConstantsManager_H + +#include "MitkDiffusionImagingExports.h" + +namespace mitk +{ + + /** \brief The XML consts for reading and writing + */ + + class MitkDiffusionImaging_EXPORT ConnectomicsConstantsManager + { + public: + + //============== String and other constants =================== + + //==== Error messages ==== + static const char* CONNECTOMICS_ERROR_TRIED_TO_ACCESS_INVALID_HISTOGRAM; + static const char* CONNECTOMICS_ERROR_PASSED_NEGATIVE_INDEX_TO_HISTOGRAM; + static const char* CONNECTOMICS_ERROR_OUTSIDE_INTEGER_RANGE; + static const char* CONNECTOMICS_ERROR_BEYOND_SCOPE; + static const char* CONNECTOMICS_ERROR_INVALID_MAPPING; + static const char* CONNECTOMICS_ERROR_INVALID_DIMENSION_NEED_3; + + //==== Warnings ==== + static const char* CONNECTOMICS_WARNING_ZERO_DISTANCE_NODES; + static const char* CONNECTOMICS_WARNING_UNIMPLEMENTED_FEATURE; + static const char* CONNECTOMICS_WARNING_MORE_POINTS_THAN_PRESENT; + static const char* CONNECTOMICS_WARNING_ESTIMATING_LESS_THAN_2; + static const char* CONNECTOMICS_WARNING_ESTIMATING_BEYOND_END; + static const char* CONNECTOMICS_WARNING_ESTIMATING_BEYOND_START; + static const char* CONNECTOMICS_WARNING_DID_NOT_FIND_WHITE; + static const char* CONNECTOMICS_WARNING_NOT_EXTEND_TO_WHITE; + + //==== Information ==== + static const char* CONNECTOMICS_WARNING_INFO_NETWORK_CREATED; + static const char* CONNECTOMICS_WARNING_NETWORK_NOT_VALID; + static const char* CONNECTOMICS_WARNING_NETWORK_DISCONNECTED; + static const char* CONNECTOMICS_WARNING_CAN_NOT_COMPUTE_EFFICIENCY; + + //==== GUI ==== + static const char* CONNECTOMICS_GUI_DASH; + static const char* CONNECTOMICS_GUI_CONNECTOMICS_CREATION; + static const char* CONNECTOMICS_GUI_SELECTION_WARNING; + static const char* CONNECTOMICS_GUI_PERFORMING_IMAGE_PROCESSING_FOR_IMAGE; + + //==== Properties ==== + static const char* CONNECTOMICS_PROPERTY_DEFAULT_RGBA_NAME; + static const char* CONNECTOMICS_PROPERTY_NAME; + static const char* CONNECTOMICS_PROPERTY_VOLUMERENDERING; + static const char* CONNECTOMICS_PROPERTY_DEFAULT_CNF_NAME; + + + private: + ConnectomicsConstantsManager(); + ~ConnectomicsConstantsManager(); + + }; + +} //namespace MITK + +// include cpp + +//#include + +#endif /* _MITK_ConnectomicsConstantsManager_H */ \ No newline at end of file diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetwork.cpp b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetwork.cpp new file mode 100644 index 0000000000..144e4227c5 --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetwork.cpp @@ -0,0 +1,454 @@ + +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile$ +Language: C++ +Date: $Date$ +Version: $Revision: 11989 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsNetwork.h" +#include + +/* Constructor and Destructor */ +mitk::ConnectomicsNetwork::ConnectomicsNetwork() +: m_IsModified( false ) +{ +} + +mitk::ConnectomicsNetwork::~ConnectomicsNetwork() +{ +} + +/* Wrapper methods */ + +bool mitk::ConnectomicsNetwork::EdgeExists( + mitk::ConnectomicsNetwork::VertexDescriptorType vertexA, mitk::ConnectomicsNetwork::VertexDescriptorType vertexB ) const +{ + return boost::edge(vertexA, vertexB, m_Network ).second; +} + +void mitk::ConnectomicsNetwork::IncreaseEdgeWeight( + mitk::ConnectomicsNetwork::VertexDescriptorType vertexA, mitk::ConnectomicsNetwork::VertexDescriptorType vertexB ) +{ + m_Network[ boost::edge(vertexA, vertexB, m_Network ).first ].weight++; + + SetIsModified( true ); +} + +void mitk::ConnectomicsNetwork::AddEdge( + mitk::ConnectomicsNetwork::VertexDescriptorType vertexA, + mitk::ConnectomicsNetwork::VertexDescriptorType vertexB + ) +{ + AddEdge(vertexA, vertexB, m_Network[ vertexA ].id, m_Network[ vertexB ].id ); +} + +void mitk::ConnectomicsNetwork::AddEdge( + mitk::ConnectomicsNetwork::VertexDescriptorType vertexA, + mitk::ConnectomicsNetwork::VertexDescriptorType vertexB, + int sourceID, int targetID, int weight ) +{ + boost::add_edge( vertexA, vertexB, m_Network ); + m_Network[ boost::edge(vertexA, vertexB, m_Network ).first ].sourceId = sourceID; + m_Network[ boost::edge(vertexA, vertexB, m_Network ).first ].targetId = targetID; + m_Network[ boost::edge(vertexA, vertexB, m_Network ).first ].weight = weight; + m_Network[ boost::edge(vertexA, vertexB, m_Network ).first ].edge_weight = 1.0; + + SetIsModified( true ); +} + +mitk::ConnectomicsNetwork::VertexDescriptorType mitk::ConnectomicsNetwork::AddVertex( int id ) +{ + VertexDescriptorType vertex = boost::add_vertex( m_Network ); + m_Network[vertex].id = id; + + SetIsModified( true ); + + return vertex; +} + +void mitk::ConnectomicsNetwork::SetLabel( + mitk::ConnectomicsNetwork::VertexDescriptorType vertex, std::string inLabel ) +{ + m_Network[vertex].label = inLabel; + + SetIsModified( true ); +} + +void mitk::ConnectomicsNetwork::SetCoordinates( + mitk::ConnectomicsNetwork::VertexDescriptorType vertex, std::vector< float > inCoordinates ) +{ + m_Network[vertex].coordinates = inCoordinates; + + SetIsModified( true ); +} + +void mitk::ConnectomicsNetwork::clear() +{ + m_Network.clear(); + + SetIsModified( true ); +} + +/* Superclass methods, that need to be implemented */ +void mitk::ConnectomicsNetwork::UpdateOutputInformation() +{ + +} +void mitk::ConnectomicsNetwork::SetRequestedRegionToLargestPossibleRegion() +{ + +} +bool mitk::ConnectomicsNetwork::RequestedRegionIsOutsideOfTheBufferedRegion() +{ + return false; +} +bool mitk::ConnectomicsNetwork::VerifyRequestedRegion() +{ + return true; +} +void mitk::ConnectomicsNetwork::SetRequestedRegion( itk::DataObject *data ) +{ + +} + + + +std::vector< mitk::ConnectomicsNetwork::NetworkNode > +mitk::ConnectomicsNetwork::GetVectorOfAllNodes() const +{ + boost::graph_traits::vertex_iterator iterator, end; + + // sets iterator to start end end to end + boost::tie(iterator, end) = boost::vertices( m_Network ); + + std::vector< NetworkNode > vectorOfNodes; + + for ( ; iterator != end; ++iterator) + { + NetworkNode tempNode; + + // the value of an iterator is a descriptor + tempNode = m_Network[ *iterator ]; + + vectorOfNodes.push_back( tempNode ); + } + + return vectorOfNodes; +} + +std::vector< mitk::ConnectomicsNetwork::VertexDescriptorType > +mitk::ConnectomicsNetwork::GetVectorOfAllVertexDescriptors() const +{ + boost::graph_traits::vertex_iterator iterator, end; + + // sets iterator to start end end to end + boost::tie(iterator, end) = boost::vertices( m_Network ); + + std::vector< VertexDescriptorType > vectorOfDescriptors; + + for ( ; iterator != end; ++iterator) + { + vectorOfDescriptors.push_back( *iterator ); + } + + return vectorOfDescriptors; +} + +std::vector< std::pair< +std::pair< mitk::ConnectomicsNetwork::NetworkNode, mitk::ConnectomicsNetwork::NetworkNode > +, mitk::ConnectomicsNetwork::NetworkEdge > > +mitk::ConnectomicsNetwork::GetVectorOfAllEdges() const +{ + boost::graph_traits::edge_iterator iterator, end; + + // sets iterator to start end end to end + boost::tie(iterator, end) = boost::edges( m_Network ); + + std::vector< + std::pair< + std::pair< NetworkNode, NetworkNode > + , NetworkEdge + > + > vectorOfEdges; + + for ( ; iterator != end; ++iterator) + { + NetworkNode sourceNode, targetNode; + NetworkEdge tempEdge; + + // the value of an iterator is a descriptor + tempEdge = m_Network[ *iterator ]; + sourceNode = m_Network[ boost::source( *iterator, m_Network ) ]; + targetNode = m_Network[ boost::target( *iterator, m_Network ) ]; + + std::pair< NetworkNode, NetworkNode > nodePair( sourceNode, targetNode ); + std::pair< std::pair< NetworkNode, NetworkNode > , NetworkEdge > edgePair( nodePair, tempEdge); + vectorOfEdges.push_back( edgePair ); + } + + return vectorOfEdges; +} + +int mitk::ConnectomicsNetwork::GetNumberOfVertices() const +{ + return boost::num_vertices( m_Network ); +} + +int mitk::ConnectomicsNetwork::GetNumberOfEdges() +{ + return boost::num_edges( m_Network ); +} + +int mitk::ConnectomicsNetwork::GetMaximumWeight() const +{ + int maxWeight( 0 ); + + boost::graph_traits::edge_iterator iterator, end; + + // sets iterator to start end end to end + boost::tie(iterator, end) = boost::edges( m_Network ); + + for ( ; iterator != end; ++iterator) + { + int tempWeight; + + // the value of an iterator is a descriptor + tempWeight = m_Network[ *iterator ].weight; + + if( tempWeight > maxWeight ) + { + maxWeight = tempWeight; + } + } + + return maxWeight; +} + +int mitk::ConnectomicsNetwork::GetNumberOfSelfLoops() +{ + int noOfSelfLoops( 0 ); + + std::vector< std::pair< std::pair< NetworkNode, NetworkNode > , NetworkEdge > > + edgeVector = GetVectorOfAllEdges(); + + for( int index = 0; index < edgeVector.size() ; index++ ) + { + double sourceX, sourceY, sourceZ, targetX, targetY, targetZ; + + sourceX = edgeVector[ index ].first.first.coordinates[0] ; + sourceY = edgeVector[ index ].first.first.coordinates[1] ; + sourceZ = edgeVector[ index ].first.first.coordinates[2] ; + targetX = edgeVector[ index ].first.second.coordinates[0] ; + targetY = edgeVector[ index ].first.second.coordinates[1] ; + targetZ = edgeVector[ index ].first.second.coordinates[2] ; + + // if the coordinates are the same + if( + sourceX > ( targetX - 0.01 ) && + sourceX < ( targetX + 0.01 ) && + sourceY > ( targetY - 0.01 ) && + sourceY < ( targetY + 0.01 ) && + sourceZ > ( targetZ - 0.01 ) && + sourceZ < ( targetZ + 0.01 ) + ) + { + noOfSelfLoops++; + } + } + + return noOfSelfLoops; +} + +double mitk::ConnectomicsNetwork::GetAverageDegree() +{ + double vertices = (double) GetNumberOfVertices(); + double edges = (double) GetNumberOfEdges(); + + return ( ( edges * 2.0 ) / vertices ); +} + +double mitk::ConnectomicsNetwork::GetConnectionDensity() +{ + double vertices = (double) GetNumberOfVertices(); + double edges = (double) GetNumberOfEdges(); + double numberOfPossibleEdges = vertices * ( vertices - 1 ) / 2 ; + + return ( edges / numberOfPossibleEdges ); +} + +std::vector< int > mitk::ConnectomicsNetwork::GetDegreeOfNodes( ) const +{ + std::vector< int > vectorOfDegree; + + boost::graph_traits::vertex_iterator iterator, end; + + // sets iterator to start end end to end + boost::tie( iterator, end ) = boost::vertices( m_Network ); + + vectorOfDegree.resize( this->GetNumberOfVertices() ); + + for ( ; iterator != end; ++iterator) + { + // the value of an iterator is a descriptor + vectorOfDegree[ m_Network[ *iterator ].id ] = GetVectorOfAdjacentNodes( *iterator ).size(); + } + return vectorOfDegree; +} + +std::vector< mitk::ConnectomicsNetwork::VertexDescriptorType > +mitk::ConnectomicsNetwork::GetVectorOfAdjacentNodes( mitk::ConnectomicsNetwork::VertexDescriptorType vertex ) const +{ + std::vector< mitk::ConnectomicsNetwork::VertexDescriptorType > vectorOfAdjacentNodes; + + boost::graph_traits::adjacency_iterator adjIter, adjEnd; + + boost::tie( adjIter, adjEnd ) = boost::adjacent_vertices( vertex, m_Network); + + for ( ; adjIter != adjEnd; ++adjIter) + { + vectorOfAdjacentNodes.push_back( *adjIter ); + } + + return vectorOfAdjacentNodes; +} + +int mitk::ConnectomicsNetwork::GetMaximumDegree() const +{ + int maximumDegree( 0 ); + + std::vector< int > vectorOfDegree = GetDegreeOfNodes(); + + for( int index( 0 ); index < vectorOfDegree.size(); ++index ) + { + if( maximumDegree < vectorOfDegree[ index ] ) + { + maximumDegree = vectorOfDegree[ index ]; + } + } + + return maximumDegree; +} + +std::vector< double > mitk::ConnectomicsNetwork::GetLocalClusteringCoefficients( ) +{ + std::vector< double > vectorOfClusteringCoefficients; + + typedef boost::graph_traits::vertex_iterator vertexIter; + + vectorOfClusteringCoefficients.resize( this->GetNumberOfVertices() ); + + std::pair vertexPair; + + //for every vertex calculate the clustering coefficient + for (vertexPair = vertices(m_Network); vertexPair.first != vertexPair.second; ++vertexPair.first) + { + vectorOfClusteringCoefficients[ m_Network[ *vertexPair.first ].id ] = + boost::clustering_coefficient(m_Network,*vertexPair.first) ; + } + + return vectorOfClusteringCoefficients; +} + +std::vector< double > mitk::ConnectomicsNetwork::GetClusteringCoefficientsByDegree( ) +{ + std::vector< double > vectorOfClusteringCoefficients = GetLocalClusteringCoefficients(); + std::vector< int > vectorOfDegree = GetDegreeOfNodes(); + + std::vector< double > vectorOfClusteringCoefficientsByDegree; + vectorOfClusteringCoefficientsByDegree.resize( GetMaximumDegree() + 1, 0 ); + + // c_{mean}(k) = frac{1}_{N_{k}} sum_{i in Y(k)} c_{i} + // where N_{k} is the number of vertices of degree k + // Y(k) is the set of vertices of degree k + // c_{i} is the local clustering coefficient of vertex i + for( int degree( 0 ); degree < vectorOfClusteringCoefficientsByDegree.size(); ++degree ) + { + vectorOfClusteringCoefficientsByDegree[ degree ] = 0; + int n_k( 0 ); + for( int index( 0 ); index < vectorOfDegree.size(); ++index ) + { + if( degree == vectorOfDegree[ index ] ) + {// if in Y( degree ) + vectorOfClusteringCoefficientsByDegree[ degree ] += vectorOfClusteringCoefficients[ index ]; + n_k++; + } + } + if( n_k != 0 ) + { + vectorOfClusteringCoefficientsByDegree[ degree ] = + vectorOfClusteringCoefficientsByDegree[ degree ] / n_k; + } + } + + return vectorOfClusteringCoefficientsByDegree; +} + +double mitk::ConnectomicsNetwork::GetGlobalClusteringCoefficient( ) +{ + double globalClusteringCoefficient( 0.0 ); + + std::vector< double > vectorOfClusteringCoefficientsByDegree = GetClusteringCoefficientsByDegree(); + std::vector< int > vectorOfDegree = GetDegreeOfNodes(); + std::vector< int > degreeDistribution; + degreeDistribution.resize( vectorOfClusteringCoefficientsByDegree.size(), 0 ); + + int normalizationParameter( 0 ); + + for( int index( 0 ); index < vectorOfDegree.size(); ++index ) + { + degreeDistribution[ vectorOfDegree[ index ] ]++; + normalizationParameter++; + } + // c_{mean} = sum_{k} P_{k} c_{mean}(k) + // where P_{k} is the degree distribution + // k is the degree + for( int degree( 0 ); degree < degreeDistribution.size(); ++degree ) + { + globalClusteringCoefficient += + degreeDistribution[ degree ] / ( (double) normalizationParameter) + * vectorOfClusteringCoefficientsByDegree[ degree ]; + } + + return globalClusteringCoefficient; +} + +mitk::ConnectomicsNetwork::NetworkType* mitk::ConnectomicsNetwork::GetBoostGraph() +{ + return &m_Network; +} + + +bool mitk::ConnectomicsNetwork::GetIsModified() const +{ + return m_IsModified; +} + + +void mitk::ConnectomicsNetwork::SetIsModified( bool value) +{ + m_IsModified = value; +} + + +mitk::ConnectomicsNetwork::NetworkNode mitk::ConnectomicsNetwork::GetNode( VertexDescriptorType vertex ) const +{ + return m_Network[ vertex ]; +} + + +mitk::ConnectomicsNetwork::NetworkEdge mitk::ConnectomicsNetwork::GetEdge( VertexDescriptorType vertexA, VertexDescriptorType vertexB ) const +{ + return m_Network[ boost::edge(vertexA, vertexB, m_Network ).first ]; +} \ No newline at end of file diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetwork.h b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetwork.h new file mode 100644 index 0000000000..0f60898443 --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetwork.h @@ -0,0 +1,177 @@ + +/*========================================================================= + + Program: Medical Imaging & Interaction Toolkit + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision: 11989 $ + + Copyright (c) German Cancer Research Center, Division of Medical and + Biological Informatics. All rights reserved. + See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + + =========================================================================*/ + + +#ifndef _MITK_ConnectomicsNetwork_H +#define _MITK_ConnectomicsNetwork_H + +#include "MitkDiffusionImagingExports.h" + +#include "mitkBaseData.h" + +#include + +namespace mitk { + + /** + * \brief Base Class for Connectomics Networks */ + class MitkDiffusionImaging_EXPORT ConnectomicsNetwork : public BaseData + { + public: + /** Structs for the graph */ + + /** The Node */ + struct NetworkNode + { + int id; + std::string label; + std::vector< float > coordinates; + }; + + /** The Edge */ + struct NetworkEdge + { + int sourceId; + int targetId; + int weight; // For now the number of times it was present + double edge_weight; // For boost, currently set to 1 by default for unweighted calculations + }; + + /** Typedefs **/ + //typedef boost::adjacency_list< boost::listS, boost::listS, boost::undirectedS, NetworkNode, NetworkEdge > NetworkType; + typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, NetworkNode, NetworkEdge > NetworkType; + typedef boost::graph_traits::vertex_descriptor VertexDescriptorType; + typedef boost::graph_traits::edge_descriptor EdgeDescriptorType; + + // virtual methods that need to be implemented + virtual void UpdateOutputInformation(); + virtual void SetRequestedRegionToLargestPossibleRegion(); + virtual bool RequestedRegionIsOutsideOfTheBufferedRegion(); + virtual bool VerifyRequestedRegion(); + virtual void SetRequestedRegion( itk::DataObject *data ); + + + // Macros + mitkClassMacro( ConnectomicsNetwork, BaseData ); + itkNewMacro( Self ); + + ////////////////// Interface /////////////////// + /** return whether an edge exists between the two given vertices */ + bool EdgeExists( VertexDescriptorType vertexA, VertexDescriptorType vertexB ) const; + + /** increase the weight of an edge between the two given vertices */ + void IncreaseEdgeWeight( VertexDescriptorType vertexA, VertexDescriptorType vertexB ); + + /** add an edge between two given vertices */ + void AddEdge( VertexDescriptorType vertexA, VertexDescriptorType vertexB); + + /** add an edge between two given vertices ( with a specific weight ) */ + void AddEdge( VertexDescriptorType vertexA, VertexDescriptorType vertexB, int sourceID, int targetID, int weight = 1 ); + + /** add a vertex with a specified id */ + VertexDescriptorType AddVertex( int id); + + /** set the label of a vertex */ + void SetLabel( VertexDescriptorType vertex, std::string inLabel ); + + /** set the coordinates of a vertex */ + void SetCoordinates( VertexDescriptorType vertex, std::vector< float > inCoordinates ); + + /** clear the graph */ + void clear(); + + /** return the node struct for a given node descriptor */ + NetworkNode GetNode( VertexDescriptorType vertex ) const; + + /** return the edge struct for two given node descriptors */ + NetworkEdge GetEdge( VertexDescriptorType vertexA, VertexDescriptorType vertexB ) const; + + /** get vector containing all the nodes of the network */ + std::vector< NetworkNode > GetVectorOfAllNodes() const; + + /** get vector containing all the vertex descriptors of the network */ + std::vector< VertexDescriptorType > GetVectorOfAllVertexDescriptors() const; + + /** get vector containing the descriptors of nodes adjacent to the vertex denoted by the given descriptor */ + std::vector< VertexDescriptorType > GetVectorOfAdjacentNodes( VertexDescriptorType vertex ) const; + + /** get vector containing all the edges of the network and the connected nodes */ + std::vector< std::pair< std::pair< NetworkNode, NetworkNode > , NetworkEdge > > GetVectorOfAllEdges() const; + + /** get overall number of vertices in the network */ + int GetNumberOfVertices() const; + + /** get overall number of edges in the network */ + int GetNumberOfEdges(); + + /** get number of vertices, that are connected to themselves */ + int GetNumberOfSelfLoops(); + + /** get number of vertices, that are connected to themselves */ + double GetAverageDegree(); + + /** get number of edges divided by number of possible edges */ + double GetConnectionDensity(); + + /** Get the maximum weight of all edges */ + int GetMaximumWeight() const; + + /** Get a vector in the format vector[ vertexID ] = degree */ + std::vector< int > GetDegreeOfNodes( ) const; + + /** Get the maximum degree of all nodes */ + int GetMaximumDegree() const; + + /** Get a vector in the format vector[ vertexID ] = clustering coefficient */ + std::vector< double > GetLocalClusteringCoefficients( ); + + /** Get a vector in the format vector[ degree ] = average clustering coefficient */ + std::vector< double > GetClusteringCoefficientsByDegree( ); + + /** Get the global clustering coefficient */ + double GetGlobalClusteringCoefficient( ); + + /** Access boost graph directly */ + NetworkType* GetBoostGraph(); + + /** Get the modified flag */ + bool GetIsModified() const; + + /** Set the modified flag */ + void SetIsModified( bool ); + + protected: + ConnectomicsNetwork(); + virtual ~ConnectomicsNetwork(); + + NetworkType m_Network; + + /// Flag which indicates whether the network has been modified since the last check + /// + /// mainly for rendering purposes + + bool m_IsModified; + + private: + + }; + +} // namespace mitk + +#endif /* _MITK_ConnectomicsNetwork_H */ diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkDefinitions.cpp b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkDefinitions.cpp new file mode 100644 index 0000000000..b9c87455eb --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkDefinitions.cpp @@ -0,0 +1,65 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $ +Version: $Revision: 18127 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsNetworkDefinitions.h" + +//============== XML const chars =================== + +//==== Header information ==== +const char* mitk::ConnectomicsNetworkDefinitions::XML_CONNECTOMICS_FILE = "connectomics_network_file" ; +const char* mitk::ConnectomicsNetworkDefinitions::XML_FILE_VERSION = "file_version" ; +const char* mitk::ConnectomicsNetworkDefinitions::VERSION_STRING = "0.1" ; +const char* mitk::ConnectomicsNetworkDefinitions::ASCII_FILE = "ascii_file" ; +const char* mitk::ConnectomicsNetworkDefinitions::FILE_NAME = "file_name" ; + +//==== Geometry details ==== +const char* mitk::ConnectomicsNetworkDefinitions::XML_GEOMETRY = "geometry"; + +const char* mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_XX = "xx"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_XY = "xy"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_XZ = "xz"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_YX = "yx"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_YY = "yy"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_YZ = "yz"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_ZX = "zx"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_ZY = "zy"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_ZZ = "zz"; + +const char* mitk::ConnectomicsNetworkDefinitions::XML_ORIGIN_X = "origin_x"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_ORIGIN_Y = "origin_y"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_ORIGIN_Z = "origin_z"; + +const char* mitk::ConnectomicsNetworkDefinitions::XML_SPACING_X = "spacing_x"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_SPACING_Y = "spacing_y"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_SPACING_Z = "spacing_z"; + +//==== Connectomics structures ==== +const char* mitk::ConnectomicsNetworkDefinitions::XML_VERTICES = "vertices"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_EDGES = "edges"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_VERTEX = "vertex"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_EDGE = "edge"; + +//==== Connectomics properties ==== +const char* mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_ID = "v_id"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_LABEL = "v_label"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_X = "v_x"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_Y = "v_y"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_Z = "v_z"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_EDGE_ID = "e_id"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_EDGE_SOURCE_ID = "e_s_id"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_EDGE_TARGET_ID = "e_t_id"; +const char* mitk::ConnectomicsNetworkDefinitions::XML_EDGE_WEIGHT_ID = "e_weight"; diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkDefinitions.h b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkDefinitions.h new file mode 100644 index 0000000000..11173ee956 --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkDefinitions.h @@ -0,0 +1,86 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $ +Version: $Revision: 18127 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef __mitkConnectomicsNetworkDefinitions_h +#define __mitkConnectomicsNetworkDefinitions_h + +namespace mitk +{ + + /** \brief The XML consts for reading and writing + */ + + class ConnectomicsNetworkDefinitions + { + public: + + //============== XML const chars =================== + + //==== Header information ==== + static const char* XML_CONNECTOMICS_FILE; + static const char* XML_FILE_VERSION; + static const char* VERSION_STRING; + static const char* ASCII_FILE; + static const char* FILE_NAME; + + //==== Geometry details ==== + static const char* XML_GEOMETRY; + + static const char* XML_MATRIX_XX; + static const char* XML_MATRIX_XY; + static const char* XML_MATRIX_XZ; + static const char* XML_MATRIX_YX; + static const char* XML_MATRIX_YY; + static const char* XML_MATRIX_YZ; + static const char* XML_MATRIX_ZX; + static const char* XML_MATRIX_ZY; + static const char* XML_MATRIX_ZZ; + + static const char* XML_ORIGIN_X; + static const char* XML_ORIGIN_Y; + static const char* XML_ORIGIN_Z; + + static const char* XML_SPACING_X; + static const char* XML_SPACING_Y; + static const char* XML_SPACING_Z; + + //==== Connectomics structures ==== + static const char* XML_VERTICES; + static const char* XML_EDGES; + static const char* XML_VERTEX; + static const char* XML_EDGE; + + //==== Connectomics properties ==== + static const char* XML_VERTEX_ID; + static const char* XML_VERTEX_LABEL; + static const char* XML_VERTEX_X; + static const char* XML_VERTEX_Y; + static const char* XML_VERTEX_Z; + static const char* XML_EDGE_ID; + static const char* XML_EDGE_SOURCE_ID; + static const char* XML_EDGE_TARGET_ID; + static const char* XML_EDGE_WEIGHT_ID; + + private: + ConnectomicsNetworkDefinitions(); + ~ConnectomicsNetworkDefinitions(); + + }; + +} //namespace MITK + +#endif // __mitkConnectomicsNetworkDefinitions_h diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkIOFactory.cpp b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkIOFactory.cpp new file mode 100644 index 0000000000..d7aece611b --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkIOFactory.cpp @@ -0,0 +1,52 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2007-12-11 14:46:19 +0100 (Di, 11 Dez 2007) $ +Version: $Revision: 6607 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsNetworkIOFactory.h" +#include "mitkIOAdapter.h" +#include "mitkConnectomicsNetworkReader.h" + +#include "itkVersion.h" + + +namespace mitk +{ + +ConnectomicsNetworkIOFactory::ConnectomicsNetworkIOFactory() +{ + typedef ConnectomicsNetworkReader ConnectomicsNetworkReaderType; + this->RegisterOverride("mitkIOAdapter", //beibehalten + "mitkConnectomicsNetworkReader", //umbenennen + "Connectomics Network IO", //angezeigter name + 1, + itk::CreateObjectFunction >::New()); +} + +ConnectomicsNetworkIOFactory::~ConnectomicsNetworkIOFactory() +{ +} + +const char* ConnectomicsNetworkIOFactory::GetITKSourceVersion() const +{ + return ITK_SOURCE_VERSION; +} + +const char* ConnectomicsNetworkIOFactory::GetDescription() const +{ + return "ConnectomicsNetworkIOFactory, allows the loading of Connectomics Networks"; +} + +} // end namespace mitk diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkIOFactory.h b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkIOFactory.h new file mode 100644 index 0000000000..7132cfe89e --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkIOFactory.h @@ -0,0 +1,73 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2009-05-13 18:06:46 +0200 (Mi, 13 Mai 2009) $ +Version: $Revision: 6590 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef __MITK_CONNECTOMICS_NETWORK_IO_FACTORY_H_HEADER__ +#define __MITK_CONNECTOMICS_NETWORK_IO_FACTORY_H_HEADER__ + +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) +#endif + +#include "itkObjectFactoryBase.h" +#include "mitkBaseData.h" +#include "MitkDiffusionImagingExports.h" + +namespace mitk +{ +//##Documentation +//## @brief Create instances of ConnectomicsNetwork objects using an object factory. +//## +//## @ingroup IO +class MitkDiffusionImaging_EXPORT ConnectomicsNetworkIOFactory : public itk::ObjectFactoryBase +{ +public: + /** Standard class typedefs. */ + typedef ConnectomicsNetworkIOFactory Self; + typedef itk::ObjectFactoryBase Superclass; + typedef itk::SmartPointer Pointer; + typedef itk::SmartPointer ConstPointer; + + /** Class methods used to interface with the registered factories. */ + virtual const char* GetITKSourceVersion(void) const; + virtual const char* GetDescription(void) const; + + /** Method for class instantiation. */ + itkFactorylessNewMacro(Self); + static ConnectomicsNetworkIOFactory* FactoryNew() { return new ConnectomicsNetworkIOFactory;} + /** Run-time type information (and related methods). */ + itkTypeMacro(ConnectomicsNetworkIOFactory, ObjectFactoryBase); + + /** Register one factory of this type */ + static void RegisterOneFactory(void) + { + ConnectomicsNetworkIOFactory::Pointer ConnectomicsNetworkIOFactory = ConnectomicsNetworkIOFactory::New(); + ObjectFactoryBase::RegisterFactory(ConnectomicsNetworkIOFactory); + } + +protected: + ConnectomicsNetworkIOFactory(); + ~ConnectomicsNetworkIOFactory(); + +private: + ConnectomicsNetworkIOFactory(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented + +}; + + +} // end namespace mitk + +#endif // __MITK_CONNECTOMICS_NETWORK_IO_FACTORY_H_HEADER__ diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkReader.cpp b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkReader.cpp new file mode 100644 index 0000000000..a1d3fcd1e2 --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkReader.cpp @@ -0,0 +1,252 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $ +Version: $Revision: 18127 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsNetworkReader.h" +#include "mitkConnectomicsNetworkDefinitions.h" +#include +#include "itksys/SystemTools.hxx" +#include + +void mitk::ConnectomicsNetworkReader::GenerateData() +{ + MITK_INFO << "Reading connectomics network"; + if ( ( ! m_OutputCache ) ) + { + Superclass::SetNumberOfRequiredOutputs(0); + this->GenerateOutputInformation(); + } + + if (!m_OutputCache) + { + itkWarningMacro("Tree cache is empty!"); + } + + + Superclass::SetNumberOfRequiredOutputs(1); + Superclass::SetNthOutput(0, m_OutputCache.GetPointer()); +} + +void mitk::ConnectomicsNetworkReader::GenerateOutputInformation() +{ + m_OutputCache = OutputType::New(); + + std::string ext = itksys::SystemTools::GetFilenameLastExtension(m_FileName); + ext = itksys::SystemTools::LowerCase(ext); + + if ( m_FileName == "") + { + MITK_ERROR << "No file name specified."; + } + else if (ext == ".cnf") + { + try + { + TiXmlDocument doc( m_FileName ); + doc.LoadFile(); + + TiXmlHandle hDoc(&doc); + TiXmlElement* pElem; + TiXmlHandle hRoot(0); + + pElem = hDoc.FirstChildElement().Element(); + + // save this for later + hRoot = TiXmlHandle(pElem); + + pElem = hRoot.FirstChildElement(mitk::ConnectomicsNetworkDefinitions::XML_GEOMETRY).Element(); + + // read geometry + mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); + + // read origin + mitk::Point3D origin; + double temp = 0; + pElem->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_ORIGIN_X, &temp); + origin[0] = temp; + pElem->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_ORIGIN_Y, &temp); + origin[1] = temp; + pElem->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_ORIGIN_Z, &temp); + origin[2] = temp; + geometry->SetOrigin(origin); + + // read spacing + float spacing[3]; + pElem->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_SPACING_X, &temp); + spacing[0] = temp; + pElem->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_SPACING_Y, &temp); + spacing[1] = temp; + pElem->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_SPACING_Z, &temp); + spacing[2] = temp; + geometry->SetSpacing(spacing); + + // read transform + vtkMatrix4x4* m = vtkMatrix4x4::New(); + pElem->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_XX, &temp); + m->SetElement(0,0,temp); + pElem->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_XY, &temp); + m->SetElement(1,0,temp); + pElem->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_XZ, &temp); + m->SetElement(2,0,temp); + pElem->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_YX, &temp); + m->SetElement(0,1,temp); + pElem->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_YY, &temp); + m->SetElement(1,1,temp); + pElem->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_YZ, &temp); + m->SetElement(2,1,temp); + pElem->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_ZX, &temp); + m->SetElement(0,2,temp); + pElem->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_ZY, &temp); + m->SetElement(1,2,temp); + pElem->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_ZZ, &temp); + m->SetElement(2,2,temp); + + m->SetElement(0,3,origin[0]); + m->SetElement(1,3,origin[1]); + m->SetElement(2,3,origin[2]); + m->SetElement(3,3,1); + geometry->SetIndexToWorldTransformByVtkMatrix(m); + + geometry->SetImageGeometry(true); + m_OutputCache->SetGeometry(geometry); + + // read network + std::map< int, mitk::ConnectomicsNetwork::VertexDescriptorType > idToVertexMap; + // read vertices + pElem = hRoot.FirstChildElement(mitk::ConnectomicsNetworkDefinitions::XML_VERTICES).Element(); + { + // walk through the vertices + TiXmlElement* vertexElement = pElem->FirstChildElement(); + + for( vertexElement; vertexElement; vertexElement=vertexElement->NextSiblingElement()) + { + std::vector< float > pos; + std::string label; + int vertexID(0); + + vertexElement->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_X, &temp); + pos.push_back(temp); + vertexElement->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_Y, &temp); + pos.push_back(temp); + vertexElement->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_Z, &temp); + pos.push_back(temp); + vertexElement->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_ID, &vertexID); + vertexElement->QueryStringAttribute(mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_LABEL, &label); + + mitk::ConnectomicsNetwork::VertexDescriptorType newVertex = m_OutputCache->AddVertex( vertexID ); + m_OutputCache->SetLabel( newVertex, label ); + m_OutputCache->SetCoordinates( newVertex, pos ); + + if ( idToVertexMap.count( vertexID ) > 0 ) + { + MITK_ERROR << "Aborting network creation, duplicate vertex ID in file."; + return; + } + idToVertexMap.insert( std::pair< int, mitk::ConnectomicsNetwork::VertexDescriptorType >( vertexID, newVertex) ); + } + } + + // read edges + pElem = hRoot.FirstChildElement(mitk::ConnectomicsNetworkDefinitions::XML_EDGES).Element(); + { + // walk through the edges + TiXmlElement* edgeElement = pElem->FirstChildElement(); + + for( edgeElement; edgeElement; edgeElement=edgeElement->NextSiblingElement()) + { + int edgeID(0), edgeSourceID(0), edgeTargetID(0), edgeWeight(0); + + edgeElement->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_EDGE_ID, &edgeID); + edgeElement->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_EDGE_SOURCE_ID, &edgeSourceID); + edgeElement->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_EDGE_TARGET_ID, &edgeTargetID); + edgeElement->Attribute(mitk::ConnectomicsNetworkDefinitions::XML_EDGE_WEIGHT_ID, &edgeWeight); + + mitk::ConnectomicsNetwork::VertexDescriptorType source = idToVertexMap.find( edgeSourceID )->second; + mitk::ConnectomicsNetwork::VertexDescriptorType target = idToVertexMap.find( edgeTargetID )->second; + m_OutputCache->AddEdge( source, target, edgeSourceID, edgeTargetID, edgeWeight); + } + } + + MITK_INFO << "Network read"; + } + catch(...) + { + MITK_INFO << "Could not read file "; + } + } +} + +void mitk::ConnectomicsNetworkReader::Update() +{ + this->GenerateData(); +} + +const char* mitk::ConnectomicsNetworkReader::GetFileName() const +{ + return m_FileName.c_str(); +} + + +void mitk::ConnectomicsNetworkReader::SetFileName(const char* aFileName) +{ + m_FileName = aFileName; +} + + +const char* mitk::ConnectomicsNetworkReader::GetFilePrefix() const +{ + return m_FilePrefix.c_str(); +} + + +void mitk::ConnectomicsNetworkReader::SetFilePrefix(const char* aFilePrefix) +{ + m_FilePrefix = aFilePrefix; +} + + +const char* mitk::ConnectomicsNetworkReader::GetFilePattern() const +{ + return m_FilePattern.c_str(); +} + + +void mitk::ConnectomicsNetworkReader::SetFilePattern(const char* aFilePattern) +{ + m_FilePattern = aFilePattern; +} + + +bool mitk::ConnectomicsNetworkReader::CanReadFile( + const std::string filename, const std::string /*filePrefix*/, + const std::string /*filePattern*/) +{ + // First check the extension + if( filename == "" ) + { + return false; + } + std::string ext = itksys::SystemTools::GetFilenameLastExtension(filename); + ext = itksys::SystemTools::LowerCase(ext); + + if (ext == ".cnf") + { + return true; + } + + return false; +} + diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkReader.h b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkReader.h new file mode 100644 index 0000000000..af6666984d --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkReader.h @@ -0,0 +1,72 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $ +Version: $Revision: 18127 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef __mitkConnectomicsNetworkReader_h +#define __mitkConnectomicsNetworkReader_h + +#include "mitkCommon.h" +#include "mitkFileReader.h" +#include "mitkConnectomicsNetwork.h" + +namespace mitk +{ + + /** \brief The reader for connectomics network files (.cnf) + */ + + class ConnectomicsNetworkReader : public FileReader, public BaseProcess + { + public: + + + typedef mitk::ConnectomicsNetwork OutputType; + + mitkClassMacro( ConnectomicsNetworkReader, BaseProcess ); + itkNewMacro(Self); + + const char* GetFileName() const; + void SetFileName(const char* aFileName); + const char* GetFilePrefix() const; + void SetFilePrefix(const char* aFilePrefix); + const char* GetFilePattern() const; + void SetFilePattern(const char* aFilePattern); + + static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern); + + virtual void Update(); + + + + protected: + + /** Does the real work. */ + virtual void GenerateData(); + virtual void GenerateOutputInformation(); + + OutputType::Pointer m_OutputCache; + + std::string m_FileName; + std::string m_FilePrefix; + std::string m_FilePattern; + + private: + void operator=(const Self&); //purposely not implemented + }; + +} //namespace MITK + +#endif // __mitkConnectomicsNetworkReader_h diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkSerializer.cpp b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkSerializer.cpp new file mode 100644 index 0000000000..95bf4b0277 --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkSerializer.cpp @@ -0,0 +1,75 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision: 1.12 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsNetworkSerializer.h" +#include "mitkConnectomicsNetwork.h" +#include "mitkConnectomicsNetworkWriter.h" + +#include + + +MITK_REGISTER_SERIALIZER(ConnectomicsNetworkSerializer) + + +mitk::ConnectomicsNetworkSerializer::ConnectomicsNetworkSerializer() +{ +} + + +mitk::ConnectomicsNetworkSerializer::~ConnectomicsNetworkSerializer() +{ +} + + +std::string mitk::ConnectomicsNetworkSerializer::Serialize() +{ + const ConnectomicsNetwork* conNet = dynamic_cast( m_Data.GetPointer() ); + if (conNet == NULL) + { + MITK_ERROR << " Object at " << (const void*) this->m_Data + << " is not an mitk::ConnectomicsNetwork. Cannot serialize as ConnectomicsNetwork."; + return ""; + } + + std::string filename( this->GetUniqueFilenameInWorkingDirectory() ); + filename += "_"; + filename += m_FilenameHint; + filename += ".cnf"; + + std::string fullname(m_WorkingDirectory); + fullname += "/"; + fullname += itksys::SystemTools::ConvertToOutputPath(filename.c_str()); + + try + { + ConnectomicsNetworkWriter::Pointer writer = ConnectomicsNetworkWriter::New(); + writer->SetFileName(fullname); + writer->SetInputConnectomicsNetwork(const_cast(conNet)); + writer->Write(); + } + catch (std::exception& e) + { + MITK_ERROR << " Error serializing object at " << (const void*) this->m_Data + << " to " + << fullname + << ": " + << e.what(); + return ""; + } + return filename; +} + diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkSerializer.h b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkSerializer.h new file mode 100644 index 0000000000..9c18cefe6f --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkSerializer.h @@ -0,0 +1,40 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision: 1.12 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef mitkConnectomicsNetworkSerializer_h_included +#define mitkConnectomicsNetworkSerializer_h_included + +#include "MitkDiffusionImagingExports.h" +#include "mitkBaseDataSerializer.h" + +namespace mitk +{ +/** + \brief Serializes mitk::Surface for mitk::SceneIO +*/ +class MitkDiffusionImaging_EXPORT ConnectomicsNetworkSerializer : public BaseDataSerializer +{ + public: + mitkClassMacro( ConnectomicsNetworkSerializer, BaseDataSerializer ); + itkNewMacro(Self); + virtual std::string Serialize(); + protected: + ConnectomicsNetworkSerializer(); + virtual ~ConnectomicsNetworkSerializer(); +}; +} // namespace +#endif diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriter.cpp b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriter.cpp new file mode 100644 index 0000000000..c183a3d596 --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriter.cpp @@ -0,0 +1,158 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2008-12-10 18:05:13 +0100 (Mi, 10 Dez 2008) $ +Version: $Revision: 15922 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsNetworkWriter.h" +#include "mitkConnectomicsNetworkDefinitions.h" +#include +#include "itksys/SystemTools.hxx" + +mitk::ConnectomicsNetworkWriter::ConnectomicsNetworkWriter() +: m_FileName(""), m_FilePrefix(""), m_FilePattern(""), m_Success(false) +{ + this->SetNumberOfRequiredInputs( 1 ); +} + + +mitk::ConnectomicsNetworkWriter::~ConnectomicsNetworkWriter() +{} + + +void mitk::ConnectomicsNetworkWriter::GenerateData() +{ + MITK_INFO << "Writing connectomics network"; + m_Success = false; + InputType* input = this->GetInput(); + if (input == NULL) + { + itkWarningMacro(<<"Sorry, input to ConnectomicsNetworkWriter is NULL!"); + return; + } + if ( m_FileName == "" ) + { + itkWarningMacro( << "Sorry, filename has not been set!" ); + return ; + } + + std::string ext = itksys::SystemTools::GetFilenameLastExtension(m_FileName); + ext = itksys::SystemTools::LowerCase(ext); + + if (ext == ".cnf") + { + // Get geometry of the network + mitk::Geometry3D* geometry = input->GetGeometry(); + + // Create XML document + TiXmlDocument documentXML; + { // begin document + TiXmlDeclaration* declXML = new TiXmlDeclaration( "1.0", "", "" ); // TODO what to write here? encoding? etc.... + documentXML.LinkEndChild( declXML ); + + TiXmlElement* mainXML = new TiXmlElement(mitk::ConnectomicsNetworkDefinitions::XML_CONNECTOMICS_FILE); + mainXML->SetAttribute(mitk::ConnectomicsNetworkDefinitions::XML_FILE_VERSION, mitk::ConnectomicsNetworkDefinitions::VERSION_STRING); + documentXML.LinkEndChild(mainXML); + + TiXmlElement* geometryXML = new TiXmlElement(mitk::ConnectomicsNetworkDefinitions::XML_GEOMETRY); + { // begin geometry + geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_XX, geometry->GetMatrixColumn(0)[0]); + geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_XY, geometry->GetMatrixColumn(0)[1]); + geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_XZ, geometry->GetMatrixColumn(0)[2]); + geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_YX, geometry->GetMatrixColumn(1)[0]); + geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_YY, geometry->GetMatrixColumn(1)[1]); + geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_YZ, geometry->GetMatrixColumn(1)[2]); + geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_ZX, geometry->GetMatrixColumn(2)[0]); + geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_ZY, geometry->GetMatrixColumn(2)[1]); + geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_ZZ, geometry->GetMatrixColumn(2)[2]); + + geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_ORIGIN_X, geometry->GetOrigin()[0]); + geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_ORIGIN_Y, geometry->GetOrigin()[1]); + geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_ORIGIN_Z, geometry->GetOrigin()[2]); + + geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_SPACING_X, geometry->GetSpacing()[0]); + geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_SPACING_Y, geometry->GetSpacing()[1]); + geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_SPACING_Z, geometry->GetSpacing()[2]); + + } // end geometry + mainXML->LinkEndChild(geometryXML); + + TiXmlElement* verticesXML = new TiXmlElement(mitk::ConnectomicsNetworkDefinitions::XML_VERTICES); + { // begin vertices section + VertexVectorType vertexVector = this->GetInput()->GetVectorOfAllNodes(); + for( int index = 0; index < vertexVector.size(); index++ ) + { + // not localized as of yet TODO + TiXmlElement* vertexXML = new TiXmlElement(mitk::ConnectomicsNetworkDefinitions::XML_VERTEX ); + vertexXML->SetAttribute( mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_ID , vertexVector[ index ].id ); + vertexXML->SetAttribute( mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_LABEL , vertexVector[ index ].label ); + vertexXML->SetDoubleAttribute( mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_X , vertexVector[ index ].coordinates[0] ); + vertexXML->SetDoubleAttribute( mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_Y , vertexVector[ index ].coordinates[1] ); + vertexXML->SetDoubleAttribute( mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_Z , vertexVector[ index ].coordinates[2] ); + verticesXML->LinkEndChild(vertexXML); + } + } // end vertices section + mainXML->LinkEndChild(verticesXML); + + TiXmlElement* edgesXML = new TiXmlElement(mitk::ConnectomicsNetworkDefinitions::XML_EDGES); + { // begin edges section + EdgeVectorType edgeVector = this->GetInput()->GetVectorOfAllEdges(); + for( int index = 0; index < edgeVector.size(); index++ ) + { + TiXmlElement* edgeXML = new TiXmlElement(mitk::ConnectomicsNetworkDefinitions::XML_EDGE ); + edgeXML->SetAttribute( mitk::ConnectomicsNetworkDefinitions::XML_EDGE_ID , index ); + edgeXML->SetAttribute( mitk::ConnectomicsNetworkDefinitions::XML_EDGE_SOURCE_ID , edgeVector[ index ].second.sourceId ); + edgeXML->SetAttribute( mitk::ConnectomicsNetworkDefinitions::XML_EDGE_TARGET_ID , edgeVector[ index ].second.targetId ); + edgeXML->SetAttribute( mitk::ConnectomicsNetworkDefinitions::XML_EDGE_WEIGHT_ID , edgeVector[ index ].second.weight ); + edgesXML->LinkEndChild(edgeXML); + } + } // end edges section + mainXML->LinkEndChild(edgesXML); + + } // end document + documentXML.SaveFile( m_FileName ); + + m_Success = true; + + MITK_INFO << "Connectomics network written"; + + } +} + + +void mitk::ConnectomicsNetworkWriter::SetInputConnectomicsNetwork( InputType* conNetwork ) +{ + this->ProcessObject::SetNthInput( 0, conNetwork ); +} + + +mitk::ConnectomicsNetwork* mitk::ConnectomicsNetworkWriter::GetInput() +{ + if ( this->GetNumberOfInputs() < 1 ) + { + return NULL; + } + else + { + return dynamic_cast ( this->ProcessObject::GetInput( 0 ) ); + } +} + + +std::vector mitk::ConnectomicsNetworkWriter::GetPossibleFileExtensions() +{ + std::vector possibleFileExtensions; + possibleFileExtensions.push_back(".cnf"); + return possibleFileExtensions; +} diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriter.h b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriter.h new file mode 100644 index 0000000000..dba351d031 --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriter.h @@ -0,0 +1,157 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2008-08-27 17:18:46 +0200 (Mi, 27 Aug 2008) $ +Version: $Revision: 15096 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef __mitkConnectomicsNetworkWriter_h +#define __mitkConnectomicsNetworkWriter_h + +#include +#include +#include "mitkConnectomicsNetwork.h" +#include + + +namespace mitk +{ + + /** + * Writes connectomics networks to a file + * @ingroup Process + */ + class ConnectomicsNetworkWriter : public mitk::FileWriterWithInformation + { + public: + + mitkClassMacro( ConnectomicsNetworkWriter, mitk::FileWriterWithInformation ); + + //mitkWriterMacro; + + virtual void Write() + { + if ( this->GetInput() == NULL ) + { + itkExceptionMacro(<<"Write:Please specify an input!"); + return; + } + /* Fill in image information.*/ + this->UpdateOutputInformation(); + (*(this->GetInputs().begin()))->SetRequestedRegionToLargestPossibleRegion(); + this->PropagateRequestedRegion(NULL); + this->UpdateOutputData(NULL); + } + + virtual void Update() + { + Write(); + } + + itkNewMacro( Self ); + + typedef mitk::ConnectomicsNetwork InputType; + typedef std::vector< std::pair< std::pair< + mitk::ConnectomicsNetwork::NetworkNode, mitk::ConnectomicsNetwork::NetworkNode > + , mitk::ConnectomicsNetwork::NetworkEdge > > EdgeVectorType; + typedef std::vector< mitk::ConnectomicsNetwork::NetworkNode > VertexVectorType; + + /** + * Sets the filename of the file to write. + * @param FileName the name of the file to write. + */ + itkSetStringMacro( FileName ); + + /** + * @returns the name of the file to be written to disk. + */ + itkGetStringMacro( FileName ); + + /** + * @warning multiple write not (yet) supported + */ + itkSetStringMacro( FilePrefix ); + + /** + * @warning multiple write not (yet) supported + */ + itkGetStringMacro( FilePrefix ); + + /** + * @warning multiple write not (yet) supported + */ + itkSetStringMacro( FilePattern ); + + /** + * @warning multiple write not (yet) supported + */ + itkGetStringMacro( FilePattern ); + + /** + * Sets the input object for the filter. + * @param input the diffusion volumes to write to file. + */ + void SetInputConnectomicsNetwork( InputType* input ); + + /** + * @returns the 0'th input object of the filter. + */ + InputType* GetInput(); + + /** + * Returns false if an error happened during writing + */ + itkGetMacro( Success, bool ); + + /** + * @return possible file extensions for the data type associated with the writer + */ + virtual std::vector GetPossibleFileExtensions(); + + // FileWriterWithInformation methods + virtual const char * GetDefaultFilename() { return "ConnectomicsNetwork.cnf"; } + virtual const char * GetFileDialogPattern() { return "ConnectomicsNetwork (*.cnf)"; } + virtual const char * GetDefaultExtension() { return ".cnf"; } + virtual bool CanWriteBaseDataType(BaseData::Pointer data) { + return (dynamic_cast(data.GetPointer()) != NULL); } + + virtual void DoWrite(BaseData::Pointer data) { + if (CanWriteBaseDataType(data)) { + this->SetInputConnectomicsNetwork(dynamic_cast(data.GetPointer())); + this->Update(); + } + } + + + protected: + + ConnectomicsNetworkWriter(); + + virtual ~ConnectomicsNetworkWriter(); + + virtual void GenerateData(); + + std::string m_FileName; + + std::string m_FilePrefix; + + std::string m_FilePattern; + + bool m_Success; + + }; + + +} // end of namespace mitk + +#endif //__mitkConnectomicsNetworkWriter_h diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriterFactory.cpp b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriterFactory.cpp new file mode 100644 index 0000000000..182fe975eb --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriterFactory.cpp @@ -0,0 +1,76 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2007-12-11 14:46:19 +0100 (Di, 11 Dez 2007) $ +Version: $Revision: 11215 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsNetworkWriterFactory.h" + +#include "itkCreateObjectFunction.h" +#include "itkVersion.h" + +#include "mitkConnectomicsNetworkWriter.h" + +namespace mitk +{ + +template +class CreateConnectomicsNetworkWriter : public itk::CreateObjectFunctionBase +{ +public: + + /** Standard class typedefs. */ + typedef CreateConnectomicsNetworkWriter Self; + typedef itk::SmartPointer Pointer; + + /** Methods from itk:LightObject. */ + itkFactorylessNewMacro(Self); + LightObject::Pointer CreateObject() { typename T::Pointer p = T::New(); + p->Register(); + return p.GetPointer(); + } + +protected: + CreateConnectomicsNetworkWriter() {} + ~CreateConnectomicsNetworkWriter() {} + +private: + CreateConnectomicsNetworkWriter(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented +}; + +ConnectomicsNetworkWriterFactory::ConnectomicsNetworkWriterFactory() +{ + this->RegisterOverride("IOWriter", + "ConnectomicsNetworkWriter", + "ConnectomicsNetwork Writer", + 1, + mitk::CreateConnectomicsNetworkWriter< mitk::ConnectomicsNetworkWriter >::New()); +} + +ConnectomicsNetworkWriterFactory::~ConnectomicsNetworkWriterFactory() +{ +} + +const char* ConnectomicsNetworkWriterFactory::GetITKSourceVersion() const +{ + return ITK_SOURCE_VERSION; +} + +const char* ConnectomicsNetworkWriterFactory::GetDescription() const +{ + return "ConnectomicsNetworkWriterFactory"; +} + +} // end namespace mitk diff --git a/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriterFactory.h b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriterFactory.h new file mode 100644 index 0000000000..a1e6fc19fc --- /dev/null +++ b/Modules/DiffusionImaging/IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriterFactory.h @@ -0,0 +1,68 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2009-05-13 18:06:46 +0200 (Mi, 13 Mai 2009) $ +Version: $Revision: 11215 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef ConnectomicsNetwork_WRITERFACTORY_H_HEADER_INCLUDED +#define ConnectomicsNetwork_WRITERFACTORY_H_HEADER_INCLUDED + +#include "itkObjectFactoryBase.h" +#include "mitkBaseData.h" +#include "MitkDiffusionImagingExports.h" + +namespace mitk +{ + +class MitkDiffusionImaging_EXPORT ConnectomicsNetworkWriterFactory : public itk::ObjectFactoryBase +{ +public: + + mitkClassMacro( mitk::ConnectomicsNetworkWriterFactory, itk::ObjectFactoryBase ) + + /** Class methods used to interface with the registered factories. */ + virtual const char* GetITKSourceVersion(void) const; + virtual const char* GetDescription(void) const; + + /** Method for class instantiation. */ + itkFactorylessNewMacro(Self); + + /** Register one factory of this type */ + static void RegisterOneFactory(void) + { + static bool IsRegistered = false; + if ( !IsRegistered ) + { + ConnectomicsNetworkWriterFactory::Pointer cnfWriterFactory = ConnectomicsNetworkWriterFactory::New(); + ObjectFactoryBase::RegisterFactory( cnfWriterFactory ); + IsRegistered = true; + } + } + +protected: + ConnectomicsNetworkWriterFactory(); + ~ConnectomicsNetworkWriterFactory(); + +private: + ConnectomicsNetworkWriterFactory(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented + +}; + +} // end namespace mitk + +#endif // ConnectomicsNetwork_WRITERFACTORY_H_HEADER_INCLUDED + + + diff --git a/Modules/DiffusionImaging/IODataStructures/mitkDiffusionImagingObjectFactory.cpp b/Modules/DiffusionImaging/IODataStructures/mitkDiffusionImagingObjectFactory.cpp index 4fd83614f6..23bd820e97 100644 --- a/Modules/DiffusionImaging/IODataStructures/mitkDiffusionImagingObjectFactory.cpp +++ b/Modules/DiffusionImaging/IODataStructures/mitkDiffusionImagingObjectFactory.cpp @@ -1,374 +1,396 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-06-18 15:59:04 +0200 (Do, 18 Jun 2009) $ Version: $Revision: 16916 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkDiffusionImagingObjectFactory.h" #include "mitkProperties.h" #include "mitkBaseRenderer.h" #include "mitkDataNode.h" #include "mitkNrrdDiffusionImageIOFactory.h" #include "mitkNrrdDiffusionImageWriterFactory.h" #include "mitkNrrdDiffusionImageWriter.h" #include "mitkDiffusionImage.h" #include "mitkNrrdQBallImageIOFactory.h" #include "mitkNrrdQBallImageWriterFactory.h" #include "mitkNrrdQBallImageWriter.h" #include "mitkNrrdTensorImageIOFactory.h" #include "mitkNrrdTensorImageWriterFactory.h" #include "mitkNrrdTensorImageWriter.h" #include "mitkCompositeMapper.h" #include "mitkDiffusionImageMapper.h" #include "mitkGPUVolumeMapper3D.h" #include "mitkVolumeDataVtkMapper3D.h" #include "mitkTbssImageMapper.h" //modernized fiberbundle datastrucutre #include "mitkFiberBundleX.h" #include "mitkFiberBundleXIOFactory.h" #include "mitkFiberBundleXWriterFactory.h" #include "mitkFiberBundleXWriter.h" #include "mitkFiberBundleXMapper3D.h" #include "mitkFiberBundleXMapper2D.h" #include "mitkFiberBundleXThreadMonitorMapper3D.h" #include "mitkFiberBundleXThreadMonitor.h" #include "mitkNrrdTbssImageIOFactory.h" #include "mitkNrrdTbssImageWriterFactory.h" #include "mitkNrrdTbssImageWriter.h" #include "mitkNrrdTbssRoiImageIOFactory.h" #include "mitkNrrdTbssRoiImageWriterFactory.h" #include "mitkNrrdTbssRoiImageWriter.h" #include "mitkPlanarCircleMapper3D.h" #include "mitkPlanarPolygonMapper3D.h" - +#include "mitkConnectomicsNetwork.h" +#include "mitkConnectomicsNetworkIOFactory.h" +#include "mitkConnectomicsNetworkWriter.h" +#include "mitkConnectomicsNetworkWriterFactory.h" +#include "mitkConnectomicsNetworkMapper3D.h" typedef short DiffusionPixelType; typedef char TbssRoiPixelType; typedef float TbssPixelType; typedef int TbssGradientPixelType; typedef mitk::DiffusionImage DiffusionImageShort; typedef std::multimap MultimapType; mitk::DiffusionImagingObjectFactory::DiffusionImagingObjectFactory(bool /*registerSelf*/) :CoreObjectFactoryBase() { static bool alreadyDone = false; if (!alreadyDone) { MITK_DEBUG << "DiffusionImagingObjectFactory c'tor" << std::endl; RegisterIOFactories(); mitk::NrrdDiffusionImageIOFactory::RegisterOneFactory(); mitk::NrrdQBallImageIOFactory::RegisterOneFactory(); mitk::NrrdTensorImageIOFactory::RegisterOneFactory(); mitk::NrrdTbssImageIOFactory::RegisterOneFactory(); mitk::NrrdTbssRoiImageIOFactory::RegisterOneFactory(); mitk::FiberBundleXIOFactory::RegisterOneFactory(); //modernized + mitk::ConnectomicsNetworkIOFactory::RegisterOneFactory(); mitk::NrrdDiffusionImageWriterFactory::RegisterOneFactory(); mitk::NrrdQBallImageWriterFactory::RegisterOneFactory(); mitk::NrrdTensorImageWriterFactory::RegisterOneFactory(); mitk::NrrdTbssImageWriterFactory::RegisterOneFactory(); mitk::NrrdTbssRoiImageWriterFactory::RegisterOneFactory(); mitk::FiberBundleXWriterFactory::RegisterOneFactory();//modernized + mitk::ConnectomicsNetworkWriterFactory::RegisterOneFactory(); m_FileWriters.push_back( NrrdDiffusionImageWriter::New().GetPointer() ); m_FileWriters.push_back( NrrdQBallImageWriter::New().GetPointer() ); m_FileWriters.push_back( NrrdTensorImageWriter::New().GetPointer() ); m_FileWriters.push_back( NrrdTbssImageWriter::New().GetPointer() ); m_FileWriters.push_back( NrrdTbssRoiImageWriter::New().GetPointer() ); m_FileWriters.push_back( mitk::FiberBundleXWriter::New().GetPointer() );//modernized + m_FileWriters.push_back( mitk::ConnectomicsNetworkWriter::New().GetPointer() ); mitk::CoreObjectFactory::GetInstance()->RegisterExtraFactory(this); CreateFileExtensionsMap(); alreadyDone = true; } } mitk::Mapper::Pointer mitk::DiffusionImagingObjectFactory::CreateMapper(mitk::DataNode* node, MapperSlotId id) { mitk::Mapper::Pointer newMapper=NULL; if ( id == mitk::BaseRenderer::Standard2D ) { std::string classname("QBallImage"); if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::CompositeMapper::New(); newMapper->SetDataNode(node); node->SetMapper(3, ((CompositeMapper*)newMapper.GetPointer())->GetImageMapper()); } classname = "TensorImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::CompositeMapper::New(); newMapper->SetDataNode(node); node->SetMapper(3, ((CompositeMapper*)newMapper.GetPointer())->GetImageMapper()); } classname = "DiffusionImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::DiffusionImageMapper::New(); newMapper->SetDataNode(node); } classname = "TbssRoiImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::ImageVtkMapper2D::New(); newMapper->SetDataNode(node); } classname = "FiberBundleX"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::FiberBundleXMapper2D::New(); newMapper->SetDataNode(node); } classname = "TbssImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::TbssImageMapper::New(); newMapper->SetDataNode(node); } } else if ( id == mitk::BaseRenderer::Standard3D ) { std::string classname("QBallImage"); if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::GPUVolumeMapper3D::New(); newMapper->SetDataNode(node); } classname = "TensorImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::GPUVolumeMapper3D::New(); newMapper->SetDataNode(node); } classname = "DiffusionImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::GPUVolumeMapper3D::New(); newMapper->SetDataNode(node); } classname = "FiberBundleX"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::FiberBundleXMapper3D::New(); newMapper->SetDataNode(node); } classname = "FiberBundleXThreadMonitor"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::FiberBundleXThreadMonitorMapper3D::New(); newMapper->SetDataNode(node); } classname = "TbssRoiImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::VolumeDataVtkMapper3D::New(); newMapper->SetDataNode(node); } classname = "TbssImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::TbssImageMapper::New(); newMapper->SetDataNode(node); } classname = "PlanarCircle"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::PlanarCircleMapper3D::New(); newMapper->SetDataNode(node); } classname = "PlanarPolygon"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { newMapper = mitk::PlanarPolygonMapper3D::New(); newMapper->SetDataNode(node); } + + classname = "ConnectomicsNetwork"; + if (node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) + { + newMapper = mitk::ConnectomicsNetworkMapper3D::New(); + newMapper->SetDataNode(node); + } } return newMapper; } void mitk::DiffusionImagingObjectFactory::SetDefaultProperties(mitk::DataNode* node) { std::string classname = "QBallImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::CompositeMapper::SetDefaultProperties(node); mitk::GPUVolumeMapper3D::SetDefaultProperties(node); } classname = "TensorImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::CompositeMapper::SetDefaultProperties(node); mitk::GPUVolumeMapper3D::SetDefaultProperties(node); } classname = "DiffusionImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::DiffusionImageMapper::SetDefaultProperties(node); mitk::GPUVolumeMapper3D::SetDefaultProperties(node); } classname = "FiberBundleX"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::FiberBundleXMapper3D::SetDefaultProperties(node); mitk::FiberBundleXMapper2D::SetDefaultProperties(node); } classname = "FiberBundleXThreadMonitor"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::FiberBundleXThreadMonitorMapper3D::SetDefaultProperties(node); } classname = "TbssRoiImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::ImageVtkMapper2D::SetDefaultProperties(node); mitk::VolumeDataVtkMapper3D::SetDefaultProperties(node); } classname = "TbssImage"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::TbssImageMapper::SetDefaultProperties(node); mitk::GPUVolumeMapper3D::SetDefaultProperties(node); } classname = "PlanarCircle"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::PlanarCircleMapper3D::SetDefaultProperties(node); } classname = "PlanarPolygon"; if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) { mitk::PlanarPolygonMapper3D::SetDefaultProperties(node); } + + classname = "ConnectomicsNetwork"; + if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) + { + mitk::ConnectomicsNetworkMapper3D::SetDefaultProperties(node); + } } const char* mitk::DiffusionImagingObjectFactory::GetFileExtensions() { std::string fileExtension; this->CreateFileExtensions(m_FileExtensionsMap, fileExtension); return fileExtension.c_str(); }; mitk::CoreObjectFactoryBase::MultimapType mitk::DiffusionImagingObjectFactory::GetFileExtensionsMap() { return m_FileExtensionsMap; } const char* mitk::DiffusionImagingObjectFactory::GetSaveFileExtensions() { std::string fileExtension; this->CreateFileExtensions(m_SaveFileExtensionsMap, fileExtension); return fileExtension.c_str(); }; mitk::CoreObjectFactoryBase::MultimapType mitk::DiffusionImagingObjectFactory::GetSaveFileExtensionsMap() { return m_SaveFileExtensionsMap; } void mitk::DiffusionImagingObjectFactory::CreateFileExtensionsMap() { m_FileExtensionsMap.insert(std::pair("*.dwi", "Diffusion Weighted Images")); m_FileExtensionsMap.insert(std::pair("*.hdwi", "Diffusion Weighted Images")); m_FileExtensionsMap.insert(std::pair("*.nii", "Diffusion Weighted Images for FSL")); m_FileExtensionsMap.insert(std::pair("*.fsl", "Diffusion Weighted Images for FSL")); m_FileExtensionsMap.insert(std::pair("*.fslgz", "Diffusion Weighted Images for FSL")); m_FileExtensionsMap.insert(std::pair("*.qbi", "Q-Ball Images")); m_FileExtensionsMap.insert(std::pair("*.hqbi", "Q-Ball Images")); m_FileExtensionsMap.insert(std::pair("*.dti", "Tensor Images")); m_FileExtensionsMap.insert(std::pair("*.hdti", "Tensor Images")); m_FileExtensionsMap.insert(std::pair("*.fib", "Fiber Bundle")); m_FileExtensionsMap.insert(std::pair("*.vtk", "Fiber Bundle")); m_FileExtensionsMap.insert(std::pair("*.tbss", "TBSS data")); m_FileExtensionsMap.insert(std::pair("*.pf", "Planar Figure File")); m_FileExtensionsMap.insert(std::pair("*.roi", "TBSS ROI data")); + m_FileExtensionsMap.insert(std::pair("*.cnf", "Connectomics Network File")); m_SaveFileExtensionsMap.insert(std::pair("*.dwi", "Diffusion Weighted Images")); m_SaveFileExtensionsMap.insert(std::pair("*.hdwi", "Diffusion Weighted Images")); m_SaveFileExtensionsMap.insert(std::pair("*.nii", "Diffusion Weighted Images for FSL")); m_SaveFileExtensionsMap.insert(std::pair("*.fsl", "Diffusion Weighted Images for FSL")); m_SaveFileExtensionsMap.insert(std::pair("*.fslgz", "Diffusion Weighted Images for FSL")); m_SaveFileExtensionsMap.insert(std::pair("*.qbi", "Q-Ball Images")); m_SaveFileExtensionsMap.insert(std::pair("*.hqbi", "Q-Ball Images")); m_SaveFileExtensionsMap.insert(std::pair("*.dti", "Tensor Images")); m_SaveFileExtensionsMap.insert(std::pair("*.hdti", "Tensor Images")); m_SaveFileExtensionsMap.insert(std::pair("*.fib", "Fiber Bundle")); m_SaveFileExtensionsMap.insert(std::pair("*.vtk", "Fiber Bundle")); m_SaveFileExtensionsMap.insert(std::pair("*.tbss", "TBSS data")); m_SaveFileExtensionsMap.insert(std::pair("*.pf", "Planar Figure File")); m_SaveFileExtensionsMap.insert(std::pair("*.roi", "TBSS ROI data")); + m_SaveFileExtensionsMap.insert(std::pair("*.cnf", "Connectomics Network File")); } void mitk::DiffusionImagingObjectFactory::RegisterIOFactories() { } void RegisterDiffusionImagingObjectFactory() { static bool oneDiffusionImagingObjectFactoryRegistered = false; if ( ! oneDiffusionImagingObjectFactoryRegistered ) { MITK_DEBUG << "Registering DiffusionImagingObjectFactory..." << std::endl; mitk::CoreObjectFactory::GetInstance()->RegisterExtraFactory(mitk::DiffusionImagingObjectFactory::New()); oneDiffusionImagingObjectFactoryRegistered = true; } } diff --git a/Modules/DiffusionImaging/Rendering/mitkConnectomicsNetworkMapper3D.cpp b/Modules/DiffusionImaging/Rendering/mitkConnectomicsNetworkMapper3D.cpp new file mode 100644 index 0000000000..45ee4656e3 --- /dev/null +++ b/Modules/DiffusionImaging/Rendering/mitkConnectomicsNetworkMapper3D.cpp @@ -0,0 +1,181 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $ +Version: $Revision: 17179 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkConnectomicsNetworkMapper3D.h" + +mitk::ConnectomicsNetworkMapper3D::ConnectomicsNetworkMapper3D() +{ + //TODO: implement + m_NetworkAssembly = vtkPropAssembly::New(); + +} + +mitk::ConnectomicsNetworkMapper3D:: ~ConnectomicsNetworkMapper3D() +{ + //TODO: implement + m_NetworkAssembly->Delete(); + +} + +void mitk::ConnectomicsNetworkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer* renderer) +{ + //TODO: implement + + if( this->GetInput() == NULL ) + { + return; + } + if( this->GetInput()->GetIsModified( ) ) + { + GenerateData(); + } +} + +void mitk::ConnectomicsNetworkMapper3D::GenerateData() +{ + //TODO: implement + + // Here is the part where a graph is given and converted to points and connections between points... + std::vector< mitk::ConnectomicsNetwork::NetworkNode > vectorOfNodes = this->GetInput()->GetVectorOfAllNodes(); + std::vector< std::pair< + std::pair< mitk::ConnectomicsNetwork::NetworkNode, mitk::ConnectomicsNetwork::NetworkNode > + , mitk::ConnectomicsNetwork::NetworkEdge > > vectorOfEdges = this->GetInput()->GetVectorOfAllEdges(); + + mitk::Point3D tempWorldPoint, tempCNFGeometryPoint; + + //////////////////////Create Spheres///////////////////////// + for(unsigned int i = 0; i < vectorOfNodes.size(); i++) + { + vtkSmartPointer sphereSource = + vtkSmartPointer::New(); + + for(unsigned int dimension = 0; dimension < 3; dimension++) + { + tempCNFGeometryPoint.SetElement( dimension , vectorOfNodes[i].coordinates[dimension] ); + } + + this->GetData()->GetGeometry()->IndexToWorld( tempCNFGeometryPoint, tempWorldPoint ); + + sphereSource->SetCenter( tempWorldPoint[0] , tempWorldPoint[1], tempWorldPoint[2] ); + sphereSource->SetRadius(1.0); + + vtkSmartPointer mapper = + vtkSmartPointer::New(); + mapper->SetInput(sphereSource->GetOutput()); + + vtkSmartPointer actor = + vtkSmartPointer::New(); + actor->SetMapper(mapper); + + m_NetworkAssembly->AddPart(actor); + } + + //////////////////////Create Tubes///////////////////////// + + for(unsigned int i = 0; i < vectorOfEdges.size(); i++) + { + + vtkSmartPointer lineSource = + vtkSmartPointer::New(); + + for(unsigned int dimension = 0; dimension < 3; dimension++) + { + tempCNFGeometryPoint[ dimension ] = vectorOfEdges[i].first.first.coordinates[dimension]; + } + + this->GetData()->GetGeometry()->IndexToWorld( tempCNFGeometryPoint, tempWorldPoint ); + + lineSource->SetPoint1(tempWorldPoint[0], tempWorldPoint[1],tempWorldPoint[2] ); + + for(unsigned int dimension = 0; dimension < 3; dimension++) + { + tempCNFGeometryPoint[ dimension ] = vectorOfEdges[i].first.second.coordinates[dimension]; + } + + this->GetData()->GetGeometry()->IndexToWorld( tempCNFGeometryPoint, tempWorldPoint ); + + lineSource->SetPoint2(tempWorldPoint[0], tempWorldPoint[1], tempWorldPoint[2] ); + + vtkSmartPointer tubes = vtkSmartPointer::New(); + tubes->SetInput( lineSource->GetOutput() ); + tubes->SetNumberOfSides( 12 ); + double radiusFactor = 1.0 + ((double) vectorOfEdges[i].second.weight) / 10.0 ; + tubes->SetRadius( std::log10( radiusFactor ) ); + + vtkSmartPointer mapper2 = + vtkSmartPointer::New(); + mapper2->SetInput( tubes->GetOutput() ); + + vtkSmartPointer actor = + vtkSmartPointer::New(); + actor->SetMapper(mapper2); + + double maxWeight = (double) this->GetInput()->GetMaximumWeight(); + double colourFactor = vectorOfEdges[i].second.weight / maxWeight; + actor->GetProperty()->SetColor( colourFactor, colourFactor, colourFactor); + + + m_NetworkAssembly->AddPart(actor); + + } + + (static_cast ( GetData() ) )->SetIsModified( false ); + + //this->UpdateVtkObjects(); + + +} + +const mitk::ConnectomicsNetwork* mitk::ConnectomicsNetworkMapper3D::GetInput() +{ + + return static_cast ( GetData() ); +} + + +void mitk::ConnectomicsNetworkMapper3D::SetDefaultProperties(DataNode* node, BaseRenderer* renderer , bool overwrite) +{ + //TODO: implement + + + // hand it to the superclass for base default properties + Superclass::SetDefaultProperties(node, renderer, overwrite); +} + +void mitk::ConnectomicsNetworkMapper3D::ApplyProperties(mitk::BaseRenderer* renderer) +{ + //TODO: implement + +} + +void mitk::ConnectomicsNetworkMapper3D::SetVtkMapperImmediateModeRendering(vtkMapper *mapper) +{ + //TODO: implement + +} + +void mitk::ConnectomicsNetworkMapper3D::UpdateVtkObjects() +{ + //TODO: implement +} + +vtkProp* mitk::ConnectomicsNetworkMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) +{ + + return m_NetworkAssembly; + +} \ No newline at end of file diff --git a/Modules/DiffusionImaging/Rendering/mitkConnectomicsNetworkMapper3D.h b/Modules/DiffusionImaging/Rendering/mitkConnectomicsNetworkMapper3D.h new file mode 100644 index 0000000000..ff68ca0f30 --- /dev/null +++ b/Modules/DiffusionImaging/Rendering/mitkConnectomicsNetworkMapper3D.h @@ -0,0 +1,107 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $ +Version: $Revision: 17179 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + + +#ifndef ConnectomicsNetworkMapper3D_H_HEADER_INCLUDED +#define ConnectomicsNetworkMapper3D_H_HEADER_INCLUDED + +// VTK includes + +#include +#include "vtkPropAssembly.h" + +// MITK includes +// base class +#include "mitkVtkMapper3D.h" + +// data type + +#include "mitkConnectomicsNetwork.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include "MitkDiffusionImagingExports.h" + +namespace mitk { + + //##Documentation + //## @brief Mapper for Networks + //## @ingroup Mapper +// template + class MitkDiffusionImaging_EXPORT ConnectomicsNetworkMapper3D : public VtkMapper3D + { + public: + + mitkClassMacro(ConnectomicsNetworkMapper3D, VtkMapper3D); + itkNewMacro(Self); + + virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer); //looks like deprecated.. should be replaced bz GetViewProp() + static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false ); + + virtual void ApplyProperties(mitk::BaseRenderer* renderer); + static void SetVtkMapperImmediateModeRendering(vtkMapper *mapper); + + virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); + virtual void GenerateData(); + + virtual const mitk::ConnectomicsNetwork* GetInput(); + + + protected: + + ConnectomicsNetworkMapper3D(); + virtual ~ConnectomicsNetworkMapper3D(); + + void UpdateVtkObjects(); + + vtkPropAssembly *m_NetworkAssembly; + + + + + + }; + +} // namespace mitk + + + + +#endif /* ConnectomicsNetworkMapper3D_H_HEADER_INCLUDED */ + diff --git a/Modules/DiffusionImaging/files.cmake b/Modules/DiffusionImaging/files.cmake index d3a7484ab7..a637ddc986 100644 --- a/Modules/DiffusionImaging/files.cmake +++ b/Modules/DiffusionImaging/files.cmake @@ -1,165 +1,215 @@ set(CPP_FILES # DicomImport DicomImport/mitkDicomDiffusionImageReader.cpp DicomImport/mitkGroupDiffusionHeadersFilter.cpp DicomImport/mitkDicomDiffusionImageHeaderReader.cpp DicomImport/mitkGEDicomDiffusionImageHeaderReader.cpp DicomImport/mitkPhilipsDicomDiffusionImageHeaderReader.cpp DicomImport/mitkSiemensDicomDiffusionImageHeaderReader.cpp DicomImport/mitkSiemensMosaicDicomDiffusionImageHeaderReader.cpp # DataStructures IODataStructures/mitkDiffusionImagingObjectFactory.cpp # DataStructures -> DWI IODataStructures/DiffusionWeightedImages/mitkDiffusionImageHeaderInformation.cpp IODataStructures/DiffusionWeightedImages/mitkDiffusionImageSource.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageReader.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageWriter.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageIOFactory.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageWriterFactory.cpp IODataStructures/DiffusionWeightedImages/mitkDiffusionImageSerializer.cpp # DataStructures -> QBall IODataStructures/QBallImages/mitkQBallImageSource.cpp IODataStructures/QBallImages/mitkNrrdQBallImageReader.cpp IODataStructures/QBallImages/mitkNrrdQBallImageWriter.cpp IODataStructures/QBallImages/mitkNrrdQBallImageIOFactory.cpp IODataStructures/QBallImages/mitkNrrdQBallImageWriterFactory.cpp IODataStructures/QBallImages/mitkQBallImage.cpp IODataStructures/QBallImages/mitkQBallImageSerializer.cpp # DataStructures -> Tensor IODataStructures/TensorImages/mitkTensorImageSource.cpp IODataStructures/TensorImages/mitkNrrdTensorImageReader.cpp IODataStructures/TensorImages/mitkNrrdTensorImageWriter.cpp IODataStructures/TensorImages/mitkNrrdTensorImageIOFactory.cpp IODataStructures/TensorImages/mitkNrrdTensorImageWriterFactory.cpp IODataStructures/TensorImages/mitkTensorImage.cpp IODataStructures/TensorImages/mitkTensorImageSerializer.cpp # DataStructures -> FiberBundleX IODataStructures/FiberBundleX/mitkFiberBundleX.cpp IODataStructures/FiberBundleX/mitkFiberBundleXWriter.cpp IODataStructures/FiberBundleX/mitkFiberBundleXReader.cpp IODataStructures/FiberBundleX/mitkFiberBundleXIOFactory.cpp IODataStructures/FiberBundleX/mitkFiberBundleXWriterFactory.cpp IODataStructures/FiberBundleX/mitkFiberBundleXSerializer.cpp IODataStructures/FiberBundleX/mitkFiberBundleXThreadMonitor.cpp # DataStructures -> PlanarFigureComposite IODataStructures/PlanarFigureComposite/mitkPlanarFigureComposite.cpp # DataStructures -> Tbss IODataStructures/TbssImages/mitkTbssImageSource.cpp IODataStructures/TbssImages/mitkTbssRoiImageSource.cpp IODataStructures/TbssImages/mitkNrrdTbssImageReader.cpp IODataStructures/TbssImages/mitkNrrdTbssImageIOFactory.cpp IODataStructures/TbssImages/mitkNrrdTbssRoiImageReader.cpp IODataStructures/TbssImages/mitkNrrdTbssRoiImageIOFactory.cpp IODataStructures/TbssImages/mitkTbssImage.cpp IODataStructures/TbssImages/mitkTbssRoiImage.cpp IODataStructures/TbssImages/mitkNrrdTbssImageWriter.cpp IODataStructures/TbssImages/mitkNrrdTbssImageWriterFactory.cpp IODataStructures/TbssImages/mitkNrrdTbssRoiImageWriter.cpp IODataStructures/TbssImages/mitkNrrdTbssRoiImageWriterFactory.cpp IODataStructures/TbssImages/mitkTbssImporter.cpp + + # DataStructures Connectomics + IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetwork.cpp + IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkReader.cpp + IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkIOFactory.cpp + IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkSerializer.cpp + IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriter.cpp + IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriterFactory.cpp + IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkDefinitions.cpp + IODataStructures/ConnectomicsNetwork/mitkConnectomicsConstantsManager.cpp # Rendering Rendering/vtkMaskedProgrammableGlyphFilter.cpp Rendering/mitkCompositeMapper.cpp Rendering/mitkVectorImageVtkGlyphMapper3D.cpp Rendering/vtkOdfSource.cxx Rendering/vtkThickPlane.cxx Rendering/mitkOdfNormalizationMethodProperty.cpp Rendering/mitkOdfScaleByProperty.cpp Rendering/mitkFiberBundleXMapper2D.cpp Rendering/mitkFiberBundleXMapper3D.cpp Rendering/mitkFiberBundleXThreadMonitorMapper3D.cpp Rendering/mitkTbssImageMapper.cpp Rendering/mitkPlanarCircleMapper3D.cpp Rendering/mitkPlanarPolygonMapper3D.cpp + Rendering/mitkConnectomicsNetworkMapper3D.cpp # Interactions Interactions/mitkFiberBundleInteractor.cpp # Algorithms Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.cpp Algorithms/mitkPartialVolumeAnalysisClusteringCalculator.cpp Algorithms/mitkTractAnalyzer.cpp + + # Algorithms Connectomics + Algorithms/Connectomics/mitkConnectomicsNetworkCreator.cpp + Algorithms/Connectomics/mitkConnectomicsHistogramBase.cpp + Algorithms/Connectomics/mitkConnectomicsDegreeHistogram.cpp + Algorithms/Connectomics/mitkConnectomicsShortestPathHistogram.cpp + Algorithms/Connectomics/mitkConnectomicsBetweennessHistogram.cpp + Algorithms/Connectomics/mitkConnectomicsHistogramCache.cpp + Algorithms/Connectomics/mitkConnectomicsSyntheticNetworkGenerator.cpp + Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationBase.cpp + Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationModularity.cpp + Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingManager.cpp + Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionBase.cpp + Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionModularity.cpp # Tractography Tractography/itkStochasticTractographyFilter.h ) set(H_FILES # Rendering Rendering/mitkDiffusionImageMapper.h Rendering/mitkTbssImageMapper.h Rendering/mitkOdfVtkMapper2D.h Rendering/mitkFiberBundleXMapper3D.h Rendering/mitkFiberBundleXMapper2D.h Rendering/mitkFiberBundleXThreadMonitorMapper3D.h Rendering/mitkPlanarCircleMapper3D.h Rendering/mitkPlanarPolygonMapper3D.h + Rendering/mitkConnectomicsNetworkMapper3D.h # Reconstruction Reconstruction/itkDiffusionQballReconstructionImageFilter.h Reconstruction/mitkTeemDiffusionTensor3DReconstructionImageFilter.h Reconstruction/itkAnalyticalDiffusionQballReconstructionImageFilter.h Reconstruction/itkPointShell.h Reconstruction/itkOrientationDistributionFunction.h Reconstruction/itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h Reconstruction/itkRegularizedIVIMLocalVariationImageFilter.h Reconstruction/itkRegularizedIVIMReconstructionFilter.h Reconstruction/itkRegularizedIVIMReconstructionSingleIteration.h # IO Datastructures IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h IODataStructures/TbssImages/mitkTbssImporter.h # DataStructures -> FiberBundleX IODataStructures/FiberBundleX/mitkFiberBundleX.h IODataStructures/FiberBundleX/mitkFiberBundleXWriter.h IODataStructures/FiberBundleX/mitkFiberBundleXReader.h IODataStructures/FiberBundleX/mitkFiberBundleXIOFactory.h IODataStructures/FiberBundleX/mitkFiberBundleXWriterFactory.h IODataStructures/FiberBundleX/mitkFiberBundleXSerializer.h IODataStructures/FiberBundleX/mitkFiberBundleXThreadMonitor.h + + # Datastructures Connectomics + IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetwork.h + IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkReader.h + IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkIOFactory.h + IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkSerializer.h + IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriter.h + IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkWriterFactory.h + IODataStructures/ConnectomicsNetwork/mitkConnectomicsNetworkDefinitions.h + IODataStructures/ConnectomicsNetwork/mitkConnectomicsConstantsManager.h # Tractography Tractography/itkGibbsTrackingFilter.h Tractography/itkStochasticTractographyFilter.h # Algorithms Algorithms/itkDiffusionQballGeneralizedFaImageFilter.h Algorithms/itkDiffusionQballPrepareVisualizationImageFilter.h Algorithms/itkTensorDerivedMeasurementsFilter.h Algorithms/itkBrainMaskExtractionImageFilter.h Algorithms/itkB0ImageExtractionImageFilter.h Algorithms/itkTensorImageToDiffusionImageFilter.h Algorithms/itkTensorToL2NormImageFilter.h Algorithms/itkTractDensityImageFilter.h Algorithms/itkTractsToFiberEndingsImageFilter.h Algorithms/itkTractsToRgbaImageFilter.h Algorithms/itkGaussianInterpolateImageFunction.h Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.h Algorithms/mitkPartialVolumeAnalysisClusteringCalculator.h Algorithms/itkDiffusionTensorPrincipleDirectionImageFilter.h Algorithms/itkCartesianToPolarVectorImageFilter.h Algorithms/itkPolarToCartesianVectorImageFilter.h Algorithms/itkDistanceMapFilter.h Algorithms/itkProjectionFilter.h Algorithms/itkSkeletonizationFilter.h Algorithms/itkReduceDirectionGradientsFilter.h Algorithms/itkResidualImageFilter.h + + # Algorithms Connectomics + Algorithms/Connectomics/mitkConnectomicsNetworkCreator.h + Algorithms/Connectomics/mitkConnectomicsHistogramBase.h + Algorithms/Connectomics/mitkConnectomicsDegreeHistogram.h + Algorithms/Connectomics/mitkConnectomicsShortestPathHistogram.h + Algorithms/Connectomics/mitkConnectomicsBetweennessHistogram.h + Algorithms/Connectomics/mitkConnectomicsHistogramCache.h + Algorithms/Connectomics/mitkConnectomicsSyntheticNetworkGenerator.h + Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationBase.h + Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingPermutationModularity.h + Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingManager.h + Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionBase.h + Algorithms/Connectomics/mitkConnectomicsSimulatedAnnealingCostFunctionModularity.h ) set( TOOL_FILES ) if(WIN32) endif(WIN32) #MITK_MULTIPLEX_PICTYPE( Algorithms/mitkImageRegistrationMethod-TYPE.cpp ) diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkBrainNetworkAnalysis.dox b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkBrainNetworkAnalysis.dox new file mode 100644 index 0000000000..47b688052a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkBrainNetworkAnalysis.dox @@ -0,0 +1,61 @@ +/** +\page org_brainnetworkanalysis The Brain Network Analysis Module + +\image html QmitkBrainNetworkAnalysisViewIcon_64.png "Icon of the Module" + +\section QmitkBrainNetworkAnalysisUserManualSummary Summary + +This module can be used to create a network from a parcellation and a fiber image as well as to calculate and display network statistics. + +This document will tell you how to use this module, but it is assumed that you already know how to use MITK in general. + +Please see \ref QmitkBrainNetworkAnalysisUserManualDetails for more detailed information on usage and supported filters. +If you encounter problems using the module, please have a look at the \ref QmitkBrainNetworkAnalysisUserManualTrouble page. + +\section QmitkBrainNetworkAnalysisUserManualDetails Details + +Manual sections: + +- \ref QmitkBrainNetworkAnalysisUserManualOverview +- \ref QmitkBrainNetworkAnalysisUserManualUsage +- \ref QmitkBrainNetworkAnalysisUserManualTrouble + +\section QmitkBrainNetworkAnalysisUserManualOverview Overview + +This module is currently under heavy development and as such the interface as well as the capabilities are likely to change significantly between different versions. + +This documentation describes the features of this current version. + +\image html QmitkBrainNetworkAnalysisInterface.png "The interface" + +\section QmitkBrainNetworkAnalysisUserManualUsage Usage + +To create a network select first a parcellation of the brain (e.g. as provided by freesurfer ) by CTRL+Leftclick and secondly a fiber image ( as created using tractography module). Then click on the "Create Network" button. + +To calculate network statistics select a network in the datamanager. At this time the following statistics are calculated for the entire network: + +
    +
  • The number of vertices in the network +
  • The number of edges in the network +
  • The number of edges which have the same vertex as beginning and end point +
  • The average degree of the nodes in the network +
  • The connection density the network (the number of edges divided by the number of possible edges) +
  • The unweighted efficiency of the network ( 1 divided by average path length, this is zero for disconnected graphs) +
+ +Furthermore some statistics are calculated on a per node basis and displayed as histograms: + +
    +
  • The degree of each node +
  • The (unweighted) betweenness centrality of each node +
  • The spread of shortest paths between each pair of nodes (For disconnected graphs the shortest paths with infinite length are omitted for readability) +
+ +\section QmitkBrainNetworkAnalysisUserManualTrouble Troubleshooting + +No known problems. + +All other problems.
+Please report to the MITK mailing list. +See http://www.mitk.org/wiki/Mailinglist on how to do this. +*/ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkBrainNetworkAnalysisInterface.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkBrainNetworkAnalysisInterface.png new file mode 100644 index 0000000000..f6ef05bdb9 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkBrainNetworkAnalysisInterface.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkBrainNetworkAnalysisViewIcon_64.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkBrainNetworkAnalysisViewIcon_64.png new file mode 100644 index 0000000000..edcbab0254 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkBrainNetworkAnalysisViewIcon_64.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkDiffusionImagingUserManual.dox b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkDiffusionImagingUserManual.dox index cf3c8d228a..252dc1d22c 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkDiffusionImagingUserManual.dox +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkDiffusionImagingUserManual.dox @@ -1,123 +1,124 @@ /** \bundlemainpage{org_diffusion} MITK Diffusion Imaging (MITK-DI) This module provides means to diffusion weighted image reconstruction, visualization and quantification. Diffusion tensors as well as different q-ball reconstruction schemes are supported. Q-ball imaging aims at recovering more detailed information about the orientations of fibers from diffusion MRI measurements and, in particular, to resolve the orientations of crossing fibers. Available sections: - \ref QmitkDiffusionImagingUserManualIssues - \ref QmitkDiffusionImagingUserManualPreprocessing - \ref QmitkDiffusionImagingUserManualTensorReconstruction - \ref QmitkDiffusionImagingUserManualQBallReconstruction - \ref QmitkDiffusionImagingUserManualDicomImport - \ref QmitkDiffusionImagingUserManualQuantification - \ref QmitkDiffusionImagingUserManualVisualizationSettings - \ref QmitkDiffusionImagingUserManualReferences - \ref QmitkDiffusionImagingUserManualTechnicalDetail - \ref QmitkDiffusionImagingUserManualSubManuals \image html overview.png The MITK Diffusion Imaging Module \section QmitkDiffusionImagingUserManualIssues Known Issues \li Dicom Import: The dicom import has so far only been implemented for Siemens dicom images. MITK-DI is capable of reading the nrrd format, which is documented elsewhere [1, 2]. These files can be created by combining the raw image data with a corresponding textual header file. The file extension should be changed from *.nrrd to *.dwi or from *.nhdr to *.hdwi respectively in order to let MITK-DI recognize the diffusion related header information provided in the files. \section QmitkDiffusionImagingUserManualPreprocessing Preprocessing The preprocessing view gives an overview over the important features of a diffusion weighted image like the number of gradient directions, b-value and the measurement frame. Additionally it allows the extraction of the B0 image and the generation of a binary brain mask. The image volume can be modified by applying a new mesurement frame, which is useful if the measurement frame is not set correctly in the image header, or by averaging redundant gradient directions. \image html prepro1.png Preprocessing \section QmitkDiffusionImagingUserManualTensorReconstruction Tensor Reconstruction The tensor reconstruction view allows ITK based tensor reconstruction [3]. The advanced settings for ITK reconstruction let you configure a manual threshold on the non-diffusion weighted image. All voxels below this threshold will not be reconstructed and left blank. It is also possible to check for negative eigenvalues. The according voxels are also left blank. \image html tensor1.png ITK tensor reconstruction A few seconds (depending on the image size) after the reconstruction button is hit, a colored image should appear in the main window. \image html tensor4.png Tensor image after reconstruction The view also allows the generation of artificial diffusion weighted or Q-Ball images from the selected tensor image. The ODFs of the Q-Ball image are directly initialized from the tensor values and afterwards normalized. The diffusion weighted image is estimated using the l2-norm image of the tensor image as B0. The gradient images are afterwards generated using the standard tensor equation. \section QmitkDiffusionImagingUserManualQBallReconstruction Q-Ball Reconstruction The q-ball reonstruction bundle implements a variety of reconstruction methods. The different reconstruction methods are described in the following: \li Numerical: The original, numerical q-ball reconstruction presented by Tuch et al. [5] \li Standard (SH): Descoteaux's reconstruction based on spherical harmonic basis functions [6] \li Solid Angle (SH): Aganj's reconstruction with solid angle consideration [7] \li ADC-profile only: The ADC-profile reconstructed with spherical harmonic basis functions \li Raw signal only: The raw signal reconstructed with spherical harmonic basis functions \image html qballs1.png The q-ball resonstruction view B0 threshold works the same as in tensor reconstruction. The maximum l-level configures the size of the spherical harmonics basis. Larger l-values (e.g. l=8) allow higher levels of detail, lower levels are more stable against noise (e.g. l=4). Lambda is a regularisation parameter. Set it to 0 for no regularisation. lambda = 0.006 has proven to be a stable choice under various settings. \image html qballs2.png Advanced q-ball reconstruction settings This is how a q-ball image should initially look after reconstruction. Standard q-balls feature a relatively low GFA and thus appear rather dark. Adjust the level-window to solve this. \image html qballs3.png q-ball image after reconstruction \section QmitkDiffusionImagingUserManualDicomImport Dicom Import The dicom import does not cover all hardware manufacturers but only Siemens dicom images. MITK-DI is also capable of reading the nrrd format, which is documented elsewhere [1, 2]. These files can be created by combining the raw image data with a corresponding textual header file. The file extension should be changed from *.nrrd to *.dwi or from *.nhdr to *.hdwi respectively in order to let MITK-DI recognize the diffusion related header information provided in the files. In case your dicom images are readable by MITK-DI, select one or more input dicom folders and click import. Each input folder must only contain DICOM-images that can be combined into one vector-valued 3D output volume. Different patients must be loaded from different input-folders. The folders must not contain other acquisitions (e.g. T1,T2,localizer). In case many imports are performed at once, it is recommended to set the the optional output folder argument. This prevents the images from being kept in memory. \image html dicom1.png Dicom import The option "Average duplicate gradients" accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "blur radius" > 0 is configured. \section QmitkDiffusionImagingUserManualQuantification Quantification The quantification view allows the derivation of different scalar anisotropy measures for the reconstructed tensors (Fractional Anisotropy, Relative Anisotropy, Axial Diffusivity, Radial Diffusivity) or q-balls (Generalized Fractional Anisotropy). \image html quantification.png Anisotropy quantification \section QmitkDiffusionImagingUserManualVisualizationSettings ODF Visualization Setting In this small view, the visualization of ODFs and diffusion images can be configured. Depending on the selected image in the data storage, different options are shown here. For tensor or q-ball images, the visibility of glyphs in the different render windows (T)ransversal, (S)agittal, and (C)oronal can be configured here. The maximal number of glyphs to display can also be configured here for. This is usefull to keep the system response time during rendering feasible. The other options configure normalization and scaling of the glyphs. In diffusion images, a slider lets you choose the desired image channel from the vector of images (each gradient direction one image) for rendering. Furthermore reinit can be performed and texture interpolation toggled. This is how a visualization with activated glyphs should look like: \image html visualization3.png Q-ball image with ODF glyph visibility toggled ON \section QmitkDiffusionImagingUserManualReferences References 1. http://teem.sourceforge.net/nrrd/format.html 2. http://www.cmake.org/Wiki/Getting_Started_with_the_NRRD_Format 3. C.F.Westin, S.E.Maier, H.Mamata, A.Nabavi, F.A.Jolesz, R.Kikinis, "Processing and visualization for Diffusion tensor MRI", Medical image Analysis, 2002, pp 93-108 5. Tuch, D.S., 2004. Q-ball imaging. Magn Reson Med 52, 1358-1372. 6. Descoteaux, M., Angelino, E., Fitzgibbons, S., Deriche, R., 2007. Regularized, fast, and robust analytical Q-ball imaging. Magn Reson Med 58, 497-510. 7. Aganj, I., Lenglet, C., Sapiro, G., 2009. ODF reconstruction in q-ball imaging with solid angle consideration. Proceedings of the Sixth IEEE International Symposium on Biomedical Imaging Boston, MA. 8. Goh, A., Lenglet, C., Thompson, P.M., Vidal, R., 2009. Estimating Orientation Distribution Functions with Probability Density Constraints and Spatial Regularity. Med Image Comput Comput Assist Interv Int Conf Med Image Comput Comput Assist Interv LNCS 5761, 877 ff. \section QmitkDiffusionImagingUserManualTechnicalDetail Technical Information for Developers The diffusion imaging module uses additional properties beside the ones in use in other modules, for further information see \subpage DiffusionImagingPropertiesPage . \section QmitkDiffusionImagingUserManualSubManuals Manuals of componentes The MITK Diffusion tools consist of further components, which have their own documentation, see: \li \subpage org_fiberprocessing \li \subpage org_gibbstracking \li \subpage org_odfdetails \li \subpage org_pvanalysis \li \subpage screenshot_maker \li \subpage org_stochastictracking \li \subpage org_ivim + \li \subpage org_brainnetworkanalysis */ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/files.cmake b/Plugins/org.mitk.gui.qt.diffusionimaging/files.cmake index 22679483fb..6d734cf9ed 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/files.cmake +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/files.cmake @@ -1,114 +1,120 @@ set(SRC_CPP_FILES QmitkODFDetailsWidget.cpp QmitkODFRenderWidget.cpp QmitkPartialVolumeAnalysisWidget.cpp QmitkIVIMWidget.cpp QmitkTbssRoiAnalysisWidget.cpp QmitkResidualAnalysisWidget.cpp QmitkResidualViewWidget.cpp ) set(INTERNAL_CPP_FILES mitkPluginActivator.cpp QmitkQBallReconstructionView.cpp QmitkPreprocessingView.cpp QmitkDiffusionDicomImportView.cpp QmitkDiffusionQuantificationView.cpp QmitkTensorReconstructionView.cpp QmitkDiffusionImagingPublicPerspective.cpp QmitkControlVisualizationPropertiesView.cpp QmitkODFDetailsView.cpp QmitkGibbsTrackingView.cpp QmitkStochasticFiberTrackingView.cpp QmitkFiberProcessingView.cpp QmitkFiberBundleDeveloperView.cpp QmitkPartialVolumeAnalysisView.cpp QmitkIVIMView.cpp QmitkTractbasedSpatialStatisticsView.cpp QmitkTbssTableModel.cpp QmitkTbssMetaTableModel.cpp QmitkTbssSkeletonizationView.cpp + Connectomics/QmitkBrainNetworkAnalysisView.cpp + Connectomics/QmitkNetworkHistogramCanvas.cpp ) set(UI_FILES src/internal/QmitkQBallReconstructionViewControls.ui src/internal/QmitkPreprocessingViewControls.ui src/internal/QmitkDiffusionDicomImportViewControls.ui src/internal/QmitkDiffusionQuantificationViewControls.ui src/internal/QmitkTensorReconstructionViewControls.ui src/internal/QmitkControlVisualizationPropertiesViewControls.ui src/internal/QmitkODFDetailsViewControls.ui src/internal/QmitkGibbsTrackingViewControls.ui src/internal/QmitkStochasticFiberTrackingViewControls.ui src/internal/QmitkFiberProcessingViewControls.ui src/internal/QmitkFiberBundleDeveloperViewControls.ui src/internal/QmitkPartialVolumeAnalysisViewControls.ui src/internal/QmitkIVIMViewControls.ui src/internal/QmitkTractbasedSpatialStatisticsViewControls.ui src/internal/QmitkTbssSkeletonizationViewControls.ui + src/internal/Connectomics/QmitkBrainNetworkAnalysisViewControls.ui ) set(MOC_H_FILES src/internal/mitkPluginActivator.h src/internal/QmitkQBallReconstructionView.h src/internal/QmitkPreprocessingView.h src/internal/QmitkDiffusionDicomImportView.h src/internal/QmitkDiffusionImagingPublicPerspective.h src/internal/QmitkDiffusionQuantificationView.h src/internal/QmitkTensorReconstructionView.h src/internal/QmitkControlVisualizationPropertiesView.h src/internal/QmitkODFDetailsView.h src/QmitkODFRenderWidget.h src/QmitkODFDetailsWidget.h src/internal/QmitkGibbsTrackingView.h src/internal/QmitkStochasticFiberTrackingView.h src/internal/QmitkFiberProcessingView.h src/internal/QmitkFiberBundleDeveloperView.h src/internal/QmitkPartialVolumeAnalysisView.h src/QmitkPartialVolumeAnalysisWidget.h src/internal/QmitkIVIMView.h src/internal/QmitkTractbasedSpatialStatisticsView.h src/internal/QmitkTbssSkeletonizationView.h src/QmitkTbssRoiAnalysisWidget.h src/QmitkResidualAnalysisWidget.h src/QmitkResidualViewWidget.h + src/internal/Connectomics/QmitkBrainNetworkAnalysisView.h + src/internal/Connectomics/QmitkNetworkHistogramCanvas.h ) set(CACHED_RESOURCE_FILES # list of resource files which can be used by the plug-in # system without loading the plug-ins shared library, # for example the icon used in the menu and tabs for the # plug-in views in the workbench plugin.xml resources/preprocessing.png resources/dwiimport.png resources/quantification.png resources/reconodf.png resources/recontensor.png resources/vizControls.png resources/OdfDetails.png resources/GibbsTracking.png resources/FiberBundleOperations.png resources/PartialVolumeAnalysis_24.png resources/IVIM_48.png resources/stochFB.png resources/tbss.png + resources/QmitkBrainNetworkAnalysisViewIcon_48.png ) set(QRC_FILES # uncomment the following line if you want to use Qt resources resources/QmitkDiffusionImaging.qrc #resources/QmitkTractbasedSpatialStatisticsView.qrc ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/plugin.xml b/Plugins/org.mitk.gui.qt.diffusionimaging/plugin.xml index 53f7c26b88..e8b9846c4b 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/plugin.xml +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/plugin.xml @@ -1,119 +1,125 @@ + + + diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/resources/QmitkBrainNetworkAnalysisViewIcon_48.png b/Plugins/org.mitk.gui.qt.diffusionimaging/resources/QmitkBrainNetworkAnalysisViewIcon_48.png new file mode 100644 index 0000000000..7f458d358d Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging/resources/QmitkBrainNetworkAnalysisViewIcon_48.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/resources/QmitkBrainNetworkAnalysisViewIcon_64.png b/Plugins/org.mitk.gui.qt.diffusionimaging/resources/QmitkBrainNetworkAnalysisViewIcon_64.png new file mode 100644 index 0000000000..edcbab0254 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging/resources/QmitkBrainNetworkAnalysisViewIcon_64.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkBrainNetworkAnalysisView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkBrainNetworkAnalysisView.cpp new file mode 100644 index 0000000000..10a3a57089 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkBrainNetworkAnalysisView.cpp @@ -0,0 +1,537 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +// ####### Blueberry includes ####### +#include +#include + +// ####### Qmitk includes ####### +#include "QmitkBrainNetworkAnalysisView.h" +#include "QmitkStdMultiWidget.h" + +// ####### Qt includes ####### +#include + +// ####### ITK includes ####### +#include + +// ####### MITK includes ####### + +#include +#include "mitkConnectomicsSyntheticNetworkGenerator.h" +#include "mitkConnectomicsSimulatedAnnealingManager.h" +#include "mitkConnectomicsSimulatedAnnealingPermutationModularity.h" +#include "mitkConnectomicsSimulatedAnnealingCostFunctionModularity.h" + +// Includes for image casting between ITK and MITK +#include "mitkImageCast.h" +#include "mitkITKImageImport.h" +#include "mitkImageAccessByItk.h" + +const std::string QmitkBrainNetworkAnalysisView::VIEW_ID = "org.mitk.views.brainnetworkanalysis"; + +QmitkBrainNetworkAnalysisView::QmitkBrainNetworkAnalysisView() +: QmitkFunctionality() +, m_Controls( 0 ) +, m_MultiWidget( NULL ) +, m_ConnectomicsNetworkCreator( mitk::ConnectomicsNetworkCreator::New() ) +, m_demomode( false ) +, m_currentIndex( 0 ) +{ +} + +QmitkBrainNetworkAnalysisView::~QmitkBrainNetworkAnalysisView() +{ +} + + +void QmitkBrainNetworkAnalysisView::CreateQtPartControl( QWidget *parent ) +{ + // build up qt view, unless already done + if ( !m_Controls ) + { + // create GUI widgets from the Qt Designer's .ui file + m_Controls = new Ui::QmitkBrainNetworkAnalysisViewControls; + m_Controls->setupUi( parent ); + + QObject::connect( m_Controls->convertToRGBAImagePushButton, SIGNAL(clicked()), this, SLOT(OnConvertToRGBAImagePushButtonClicked()) ); + QObject::connect( m_Controls->networkifyPushButton, SIGNAL(clicked()), this, SLOT(OnNetworkifyPushButtonClicked()) ); + QObject::connect( m_Controls->syntheticNetworkCreationPushButton, SIGNAL(clicked()), this, SLOT(OnSyntheticNetworkCreationPushButtonClicked()) ); + QObject::connect( (QObject*)( m_Controls->syntheticNetworkComboBox ), SIGNAL(currentIndexChanged (int)), this, SLOT(OnSyntheticNetworkComboBoxCurrentIndexChanged(int)) ); + QObject::connect( (QObject*)( m_Controls->modularizePushButton ), SIGNAL(clicked()), this, SLOT(OnModularizePushButtonClicked()) ); + } + + // GUI is different for developer and demo mode + m_demomode = false; + if( m_demomode ) + { + this->m_Controls->convertToRGBAImagePushButton->hide(); + this->m_Controls->networkifyPushButton->show(); + this->m_Controls->networkifyPushButton->setText( "Create Network" ); + this->m_Controls->modularizePushButton->show(); + + this->m_Controls->syntheticNetworkOptionsGroupBox->hide(); + } + else + { + this->m_Controls->convertToRGBAImagePushButton->show(); + this->m_Controls->networkifyPushButton->show(); + this->m_Controls->networkifyPushButton->setText( "Networkify" ); + this->m_Controls->modularizePushButton->show(); + + this->m_Controls->syntheticNetworkOptionsGroupBox->show(); + //--------------------------- fill comboBox--------------------------- + this->m_Controls->syntheticNetworkComboBox->insertItem(0,"Regular lattice"); + this->m_Controls->syntheticNetworkComboBox->insertItem(1,"Heterogenic sphere"); + this->m_Controls->syntheticNetworkComboBox->insertItem(2,"Random network"); + this->m_Controls->syntheticNetworkComboBox->insertItem(3,"Scale free network"); + this->m_Controls->syntheticNetworkComboBox->insertItem(4,"Small world network"); + } +} + + +void QmitkBrainNetworkAnalysisView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) +{ + m_MultiWidget = &stdMultiWidget; +} + + +void QmitkBrainNetworkAnalysisView::StdMultiWidgetNotAvailable() +{ + m_MultiWidget = NULL; +} + +void QmitkBrainNetworkAnalysisView::WipeDisplay() +{ + m_Controls->numberOfVerticesLabel->setText( mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_DASH ); + m_Controls->numberOfEdgesLabel->setText( mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_DASH ); + m_Controls->numberOfSelfLoopsLabel->setText( mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_DASH ); + m_Controls->averageDegreeLabel->setText( mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_DASH ); + m_Controls->connectionDensityLabel->setText( mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_DASH ); + m_Controls->efficiencyLabel->setText( mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_DASH ); + m_Controls->globalClusteringLabel->setText( mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_DASH ); + m_Controls->betweennessNetworkHistogramCanvas->SetHistogram( NULL ); + m_Controls->degreeNetworkHistogramCanvas->SetHistogram( NULL ); + m_Controls->shortestPathNetworkHistogramCanvas->SetHistogram( NULL ); + m_Controls->betweennessNetworkHistogramCanvas->update(); + m_Controls->degreeNetworkHistogramCanvas->update(); + m_Controls->shortestPathNetworkHistogramCanvas->update(); +} + +void QmitkBrainNetworkAnalysisView::OnSelectionChanged( std::vector nodes ) +{ + this->WipeDisplay(); + + // iterate all selected objects, adjust warning visibility + for( std::vector::iterator it = nodes.begin(); + it != nodes.end(); + ++it ) + { + mitk::DataNode::Pointer node = *it; + + if( node.IsNotNull() && dynamic_cast(node->GetData()) ) + { + m_Controls->lblWarning->setVisible( false ); + return; + } + + { + mitk::ConnectomicsNetwork* network = dynamic_cast( node->GetData() ); + if( node.IsNotNull() && network ) + { + m_Controls->lblWarning->setVisible( false ); + + int noVertices = network->GetNumberOfVertices(); + int noEdges = network->GetNumberOfEdges(); + int noSelfLoops = network->GetNumberOfSelfLoops(); + double averageDegree = network->GetAverageDegree(); + double connectionDensity = network->GetConnectionDensity(); + double globalClustering = network->GetGlobalClusteringCoefficient(); + + m_Controls->numberOfVerticesLabel->setText( QString::number( noVertices ) ); + m_Controls->numberOfEdgesLabel->setText( QString::number( noEdges ) ); + m_Controls->numberOfSelfLoopsLabel->setText( QString::number( noSelfLoops ) ); + m_Controls->averageDegreeLabel->setText( QString::number( averageDegree ) ); + m_Controls->connectionDensityLabel->setText( QString::number( connectionDensity ) ); + m_Controls->globalClusteringLabel->setText( QString::number( globalClustering ) ); + + mitk::ConnectomicsNetwork::Pointer connectomicsNetwork( network ); + mitk::ConnectomicsHistogramsContainer *histogramContainer = histogramCache[ connectomicsNetwork ]; + m_Controls->betweennessNetworkHistogramCanvas->SetHistogram( histogramContainer->GetBetweennessHistogram() ); + m_Controls->degreeNetworkHistogramCanvas->SetHistogram( histogramContainer->GetDegreeHistogram() ); + m_Controls->shortestPathNetworkHistogramCanvas->SetHistogram( histogramContainer->GetShortestPathHistogram() ); + m_Controls->betweennessNetworkHistogramCanvas->DrawProfiles(); + m_Controls->degreeNetworkHistogramCanvas->DrawProfiles(); + m_Controls->shortestPathNetworkHistogramCanvas->DrawProfiles(); + + double efficiency = histogramContainer->GetShortestPathHistogram()->GetEfficiency(); + + m_Controls->efficiencyLabel->setText( QString::number( efficiency ) ); + + return; + } + } + } + + m_Controls->lblWarning->setVisible( true ); +} + +void QmitkBrainNetworkAnalysisView::OnSyntheticNetworkComboBoxCurrentIndexChanged(int currentIndex) +{ + m_currentIndex = currentIndex; + + switch (m_currentIndex) { + case 0: + this->m_Controls->parameterOneLabel->setText( "Nodes per side" ); + this->m_Controls->parameterTwoLabel->setText( "Internode distance" ); + this->m_Controls->parameterOneSpinBox->setEnabled( true ); + this->m_Controls->parameterOneSpinBox->setValue( 5 ); + this->m_Controls->parameterTwoDoubleSpinBox->setEnabled( true ); + this->m_Controls->parameterTwoDoubleSpinBox->setMaximum( 999.999 ); + this->m_Controls->parameterTwoDoubleSpinBox->setValue( 10.0 ); + break; + case 1: + this->m_Controls->parameterOneLabel->setText( "Number of nodes" ); + this->m_Controls->parameterTwoLabel->setText( "Radius" ); + this->m_Controls->parameterOneSpinBox->setEnabled( true ); + this->m_Controls->parameterOneSpinBox->setValue( 1000 ); + this->m_Controls->parameterTwoDoubleSpinBox->setEnabled( true ); + this->m_Controls->parameterTwoDoubleSpinBox->setMaximum( 999.999 ); + this->m_Controls->parameterTwoDoubleSpinBox->setValue( 50.0 ); + break; + case 2: + this->m_Controls->parameterOneLabel->setText( "Number of nodes" ); + this->m_Controls->parameterTwoLabel->setText( "Edge percentage" ); + this->m_Controls->parameterOneSpinBox->setEnabled( true ); + this->m_Controls->parameterOneSpinBox->setValue( 100 ); + this->m_Controls->parameterTwoDoubleSpinBox->setEnabled( true ); + this->m_Controls->parameterTwoDoubleSpinBox->setMaximum( 1.0 ); + this->m_Controls->parameterTwoDoubleSpinBox->setValue( 0.5 ); + break; + case 3: + //GenerateSyntheticScaleFreeNetwork( network, 1000 ); + break; + case 4: + //GenerateSyntheticSmallWorldNetwork( network, 1000 ); + break; + default: + this->m_Controls->parameterOneLabel->setText( "Parameter 1" ); + this->m_Controls->parameterTwoLabel->setText( "Paramater 2" ); + this->m_Controls->parameterOneSpinBox->setEnabled( false ); + this->m_Controls->parameterOneSpinBox->setValue( 0 ); + this->m_Controls->parameterTwoDoubleSpinBox->setEnabled( false ); + this->m_Controls->parameterTwoDoubleSpinBox->setValue( 0.0 ); + } +} + +void QmitkBrainNetworkAnalysisView::OnSyntheticNetworkCreationPushButtonClicked() +{ + mitk::ConnectomicsSyntheticNetworkGenerator::Pointer generator = mitk::ConnectomicsSyntheticNetworkGenerator::New(); + + mitk::DataNode::Pointer networkNode = mitk::DataNode::New(); + int parameterOne = this->m_Controls->parameterOneSpinBox->value(); + double parameterTwo = this->m_Controls->parameterTwoDoubleSpinBox->value(); + ////add network to datastorage + networkNode->SetData( generator->CreateSyntheticNetwork( m_currentIndex, parameterOne, parameterTwo ) ); + networkNode->SetName( mitk::ConnectomicsConstantsManager::CONNECTOMICS_PROPERTY_DEFAULT_CNF_NAME ); + this->GetDefaultDataStorage()->Add( networkNode ); + + return; +} + +void QmitkBrainNetworkAnalysisView::OnConvertToRGBAImagePushButtonClicked() +{ + std::vector nodes = this->GetDataManagerSelection(); + if (nodes.empty()) return; + + mitk::DataNode* node = nodes.front(); + + if (!node) + { + // Nothing selected. Inform the user and return + QMessageBox::information( NULL, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_CONNECTOMICS_CREATION, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_SELECTION_WARNING); + return; + } + + // here we have a valid mitk::DataNode + + // a node itself is not very useful, we need its data item (the image) + mitk::BaseData* data = node->GetData(); + if (data) + { + // test if this data item is an image or not (could also be a surface or something totally different) + mitk::Image* image = dynamic_cast( data ); + if (image) + { + std::stringstream message; + std::string name; + message << mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_PERFORMING_IMAGE_PROCESSING_FOR_IMAGE; + if (node->GetName(name)) + { + // a property called "name" was found for this DataNode + message << "'" << name << "'"; + } + message << "."; + MITK_INFO << message.str(); + + // Convert to RGBA + AccessByItk( image, TurnIntoRGBA ); + this->GetDefaultDataStorage()->GetNamedNode( mitk::ConnectomicsConstantsManager::CONNECTOMICS_PROPERTY_DEFAULT_RGBA_NAME )->GetData()->SetGeometry( node->GetData()->GetGeometry() ); + + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + } +} + +template < typename TPixel, unsigned int VImageDimension > +void QmitkBrainNetworkAnalysisView::TurnIntoRGBA( itk::Image* inputImage) +{ + typedef itk::RGBAPixel< unsigned char > RGBAPixelType; + typedef itk::Image< TPixel, VImageDimension > TemplateImageType; + typedef itk::Image< RGBAPixelType, VImageDimension > RGBAImageType; + + itk::ImageRegionIterator it_inputImage(inputImage, inputImage->GetLargestPossibleRegion()); + + TPixel minimumValue, maximumValue; + + it_inputImage.GoToBegin(); + maximumValue = minimumValue = it_inputImage.Value(); + + for(it_inputImage.GoToBegin(); !it_inputImage.IsAtEnd(); ++it_inputImage) + { + if ( it_inputImage.Value() < minimumValue ) + { + minimumValue = it_inputImage.Value(); + } + else + { + if ( it_inputImage.Value() > maximumValue ) + { + maximumValue = it_inputImage.Value(); + } + } + } + + int range = int ( maximumValue - minimumValue ); //needs to be castable to int + int offset = int ( minimumValue ); + + if ( range < 0 ) //error + { + return; + } + + std::vector< unsigned int > histogram; + histogram.resize( range + 1, 0 ); + + for(it_inputImage.GoToBegin(); !it_inputImage.IsAtEnd(); ++it_inputImage) + { + histogram[ int ( it_inputImage.Value() ) - offset ] += 1; + } + + int gapCounter = 0; //this variable will be used to count the empty labels + + //stores how much has to be subtracted from the image to remove gaps + std::vector< TPixel > subtractionStorage; + subtractionStorage.resize( range + 1, 0 ); + + for( int index = 0; index <= range; index++ ) + { + if( histogram[ index ] == 0 ) + { + gapCounter++; //if the label is empty, increase gapCounter + } + else + { + subtractionStorage[ index ] = TPixel ( gapCounter ); + } + } + + //remove gaps from label image + for(it_inputImage.GoToBegin(); !it_inputImage.IsAtEnd(); ++it_inputImage) + { + it_inputImage.Value() = it_inputImage.Value() - subtractionStorage[ int ( it_inputImage.Value() ) ]; + } + + // create colour vector + std::vector< RGBAPixelType > lookupTable; + + { + RGBAPixelType backgroundColour; + for( int elementIndex = 0; elementIndex < 4; ++elementIndex ) + { + backgroundColour.SetElement( elementIndex, 0 ); + } + + lookupTable.push_back( backgroundColour ); + + for(int colourNumber = 0; colourNumber < range ; ++colourNumber) + { + RGBAPixelType colour; + for( int elementIndex = 0; elementIndex < 3; ++elementIndex ) + { + colour.SetElement( elementIndex, rand() % 256 ); + } + colour.SetAlpha( 255 ); + lookupTable.push_back( colour ); + } + } + + // create RGBA image + typename RGBAImageType::Pointer rgbaImage = RGBAImageType::New(); + + rgbaImage->SetRegions(inputImage->GetLargestPossibleRegion().GetSize()); + rgbaImage->SetSpacing(inputImage->GetSpacing()); + rgbaImage->SetOrigin(inputImage->GetOrigin()); + rgbaImage->Allocate(); + + //fill with appropriate colours + itk::ImageRegionIterator it_rgbaImage(rgbaImage, rgbaImage->GetLargestPossibleRegion()); + + for(it_inputImage.GoToBegin(), it_rgbaImage.GoToBegin(); !it_inputImage.IsAtEnd(); ++it_inputImage, ++it_rgbaImage) + { + it_rgbaImage.Value() = lookupTable[ int ( it_inputImage.Value() ) ]; + } + + mitk::Image::Pointer mitkRGBAImage = mitk::ImportItkImage( rgbaImage ); + + mitk::DataNode::Pointer rgbaImageNode = mitk::DataNode::New(); + rgbaImageNode->SetData(mitkRGBAImage); + rgbaImageNode->SetProperty(mitk::ConnectomicsConstantsManager::CONNECTOMICS_PROPERTY_NAME, mitk::StringProperty::New(mitk::ConnectomicsConstantsManager::CONNECTOMICS_PROPERTY_DEFAULT_RGBA_NAME)); + rgbaImageNode->SetBoolProperty( mitk::ConnectomicsConstantsManager::CONNECTOMICS_PROPERTY_VOLUMERENDERING, true); + this->GetDefaultDataStorage()->Add( rgbaImageNode ); +} + +void QmitkBrainNetworkAnalysisView::OnNetworkifyPushButtonClicked() +{ + std::vector nodes = this->GetDataManagerSelection(); + if ( nodes.empty() ) + { + QMessageBox::information( NULL, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_CONNECTOMICS_CREATION, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_SELECTION_WARNING); + return; + } + + if (! ( nodes.size() == 2 ) ) + { + QMessageBox::information( NULL, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_CONNECTOMICS_CREATION, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_SELECTION_WARNING); + return; + } + mitk::DataNode* node = nodes.front(); + mitk::DataNode* fiberNode = nodes.at(1); + + if (!node) + { + // Nothing selected. Inform the user and return + QMessageBox::information( NULL, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_CONNECTOMICS_CREATION, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_SELECTION_WARNING); + return; + } + + // here we have a valid mitk::DataNode + + // a node itself is not very useful, we need its data item (the image) + mitk::BaseData* data = node->GetData(); + mitk::BaseData* fiberData = fiberNode->GetData(); + if (data && fiberData) + { + // test if this data item is an image or not (could also be a surface or something totally different) + mitk::Image* image = dynamic_cast( data ); + mitk::FiberBundleX* fiberBundle = dynamic_cast( fiberData ); + if (image && fiberBundle) + { + m_ConnectomicsNetworkCreator->SetSegmentation( image ); + m_ConnectomicsNetworkCreator->SetFiberBundle( fiberBundle ); + m_ConnectomicsNetworkCreator->CreateNetworkFromFibersAndSegmentation(); + mitk::DataNode::Pointer networkNode = mitk::DataNode::New(); + + ////add network to datastorage + networkNode->SetData( m_ConnectomicsNetworkCreator->GetNetwork() ); + networkNode->SetName( mitk::ConnectomicsConstantsManager::CONNECTOMICS_PROPERTY_DEFAULT_CNF_NAME ); + this->GetDefaultDataStorage()->Add( networkNode ); + } + } + + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void QmitkBrainNetworkAnalysisView::OnModularizePushButtonClicked() +{ + std::vector nodes = this->GetDataManagerSelection(); + if ( nodes.empty() ) + { + QMessageBox::information( NULL, "Modularization calculation", "Please select exactly one network."); + return; + } + + for( std::vector::iterator it = nodes.begin(); + it != nodes.end(); + ++it ) + { + mitk::DataNode::Pointer node = *it; + + if( node.IsNotNull() && dynamic_cast(node->GetData()) ) + { + return; + } + + { + mitk::ConnectomicsNetwork* network = dynamic_cast( node->GetData() ); + if( node.IsNotNull() && network ) + { + + typedef mitk::ConnectomicsSimulatedAnnealingPermutationModularity::ToModuleMapType MappingType; + + int depthOfModuleRecursive( 2 ); + double startTemperature( 2.0 ); + double stepSize( 4.0 ); + + mitk::ConnectomicsNetwork::Pointer connectomicsNetwork( network ); + mitk::ConnectomicsSimulatedAnnealingManager::Pointer manager = mitk::ConnectomicsSimulatedAnnealingManager::New(); + mitk::ConnectomicsSimulatedAnnealingPermutationModularity::Pointer permutation = mitk::ConnectomicsSimulatedAnnealingPermutationModularity::New(); + mitk::ConnectomicsSimulatedAnnealingCostFunctionModularity::Pointer costFunction = mitk::ConnectomicsSimulatedAnnealingCostFunctionModularity::New(); + + permutation->SetCostFunction( costFunction.GetPointer() ); + permutation->SetNetwork( connectomicsNetwork ); + permutation->SetDepth( depthOfModuleRecursive ); + permutation->SetStepSize( stepSize ); + + manager->SetPermutation( permutation.GetPointer() ); + + manager->RunSimulatedAnnealing( startTemperature, stepSize ); + + MappingType mapping = permutation->GetMapping(); + + MappingType::iterator iter = mapping.begin(); + MappingType::iterator end = mapping.end(); + + int loop( 0 ); + while( iter != end ) + { + MBI_DEBUG << "Vertex " << iter->first << " belongs to module " << iter->second ; + MBI_INFO << "Vertex " << iter->first << " belongs to module " << iter->second ; + iter++; + } + + MBI_DEBUG << "Overall number of modules is " << permutation->getNumberOfModules( &mapping ) ; + MBI_DEBUG << "Cost is " << costFunction->Evaluate( network, &mapping ) ; + MBI_INFO << "Overall number of modules is " << permutation->getNumberOfModules( &mapping ) ; + MBI_INFO << "Cost is " << costFunction->Evaluate( network, &mapping ) ; + + return; + } + } + } + +} diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkBrainNetworkAnalysisView.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkBrainNetworkAnalysisView.h new file mode 100644 index 0000000000..36592fa804 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkBrainNetworkAnalysisView.h @@ -0,0 +1,116 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef QmitkBrainNetworkAnalysisView_h +#define QmitkBrainNetworkAnalysisView_h + +#include + +#include + +#include "ui_QmitkBrainNetworkAnalysisViewControls.h" + +#include "mitkConnectomicsNetworkCreator.h" +#include "mitkConnectomicsNetworkMapper3D.h" + +#include "mitkConnectomicsHistogramCache.h" + +// ####### ITK includes ####### +#include + +/*! +\brief QmitkBrainNetworkAnalysisView + +This bundle provides GUI for the brain network analysis algorithms. + +\sa QmitkFunctionality +\ingroup Functionalities +*/ +class QmitkBrainNetworkAnalysisView : public QmitkFunctionality +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + +public: + + static const std::string VIEW_ID; + + QmitkBrainNetworkAnalysisView(); + virtual ~QmitkBrainNetworkAnalysisView(); + + virtual void CreateQtPartControl(QWidget *parent); + + virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget); + virtual void StdMultiWidgetNotAvailable(); + + protected slots: + + /// \brief Called when the user clicks the GUI button + void OnConvertToRGBAImagePushButtonClicked(); + + /// \brief Align two images by copying the geometry + void OnNetworkifyPushButtonClicked(); + + /// \brief Create synthetic networks + void OnSyntheticNetworkCreationPushButtonClicked(); + + /// \brief Adjust parameters depending on synthetic network type + void OnSyntheticNetworkComboBoxCurrentIndexChanged(int currentIndex); + + /// \brief Create modularization of network + void OnModularizePushButtonClicked(); + +protected: + + // ####### Functions ####### + /// \brief called by QmitkFunctionality when DataManager's selection has changed + virtual void OnSelectionChanged( std::vector nodes ); + + /// \brief Converts an image into a RGBA image + template < typename TPixel, unsigned int VImageDimension > + void TurnIntoRGBA( itk::Image* inputImage); + + /// \brief Wipe display and empty statistics + void WipeDisplay(); + + + // ####### Variables ####### + + + Ui::QmitkBrainNetworkAnalysisViewControls* m_Controls; + + QmitkStdMultiWidget* m_MultiWidget; + + mitk::ConnectomicsNetworkCreator::Pointer m_ConnectomicsNetworkCreator; + + mitk::ConnectomicsNetworkMapper3D::Pointer m_NetworkMapper; + + /// Cache for histograms + mitk::ConnectomicsHistogramCache histogramCache; + + // Demo/Developer mode toggle + bool m_demomode; + + // The selected synthetic network type + int m_currentIndex; +}; + + + +#endif // _QMITKBRAINNETWORKANALYSISVIEW_H_INCLUDED + diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkBrainNetworkAnalysisViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkBrainNetworkAnalysisViewControls.ui new file mode 100644 index 0000000000..d92a3700de --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkBrainNetworkAnalysisViewControls.ui @@ -0,0 +1,318 @@ + + + QmitkBrainNetworkAnalysisViewControls + + + + 0 + 0 + 227 + 941 + + + + + 0 + 0 + + + + QmitkTemplate + + + + + + QLabel { color: rgb(255, 0, 0) } + + + Please select data! + + + + + + + Convert the selected image to RGBA format + + + Convert to RGBA + + + + + + + Create a network from a parcellation and a fiber image + + + Networkify + + + + + + + Create Synthetic Networks + + + + + + + Divide in Modules + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + true + + + Synthetic Network Options + + + + + + + + + + + Parameter 1 + + + + + + + false + + + 9999 + + + + + + + + + + + Parameter 2 + + + + + + + false + + + 3 + + + 999.899999999999977 + + + + + + + + + + + + Network Statistics + + + + + + # of vertices: + + + + + + + # of edges: + + + + + + + - + + + + + + + - + + + + + + + # of self loops: + + + + + + + - + + + + + + + average degree + + + + + + + - + + + + + + + connection density + + + + + + + - + + + + + + + efficiency + + + + + + + - + + + + + + + global clustering + + + + + + + - + + + + + + + + + + Histograms + + + + + + + 0 + 0 + + + + + 50 + 150 + + + + + + + + + 50 + 150 + + + + + + + + + 50 + 150 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + QmitkNetworkHistogramCanvas + QWidget +
internal/Connectomics/QmitkNetworkHistogramCanvas.h
+ 1 +
+
+ + +
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkNetworkHistogramCanvas.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkNetworkHistogramCanvas.cpp new file mode 100644 index 0000000000..5aaab3a638 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkNetworkHistogramCanvas.cpp @@ -0,0 +1,99 @@ +/*========================================================================= + + Program: Medical Imaging & Interaction Toolkit + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) German Cancer Research Center, Division of Medical and + Biological Informatics. All rights reserved. + See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + + =========================================================================*/ + +#include "QmitkNetworkHistogramCanvas.h" + +#include + +#include +#include +#include +#include +#include +#include + +QmitkNetworkHistogramCanvas::QmitkNetworkHistogramCanvas(QWidget * parent, + Qt::WindowFlags f) + : QmitkPlotWidget(parent) +{ + setEnabled(false); + setFocusPolicy(Qt::ClickFocus); + +} + +QmitkNetworkHistogramCanvas::~QmitkNetworkHistogramCanvas() +{ +} + +void QmitkNetworkHistogramCanvas::DrawProfiles( ) +{ + this->Clear(); + + if( !(m_Histogram) || !( m_Histogram->IsValid() )) + { + return; + } + + std::vector histogramVector = m_Histogram->GetHistogramVector(); + + // create a data vector which contains the points to be drawn + // to create nice bars, the curve takes four points for each bar + std::vector< std::pair< double, double > > dataPointsVector; + + std::pair< double, double > leftBottom, leftTop, rightTop, rightBottom; + + // how wide the bar is, the gap to the next one will be 1 - barWidth + double barWidth( 0.95 ); + const int range = histogramVector.size(); + + for(int i=0; i < range ; ++i) + { + leftBottom.first = ((double) i) ; + leftBottom.second = 0.0; + leftTop.first = ((double) i) ; + leftTop.second = histogramVector.at( i ); + rightTop.first = ((double) i) + barWidth ; + rightTop.second = histogramVector.at( i ); + rightBottom.first = ((double) i) + barWidth ; + rightBottom.second = 0.0; + + dataPointsVector.push_back( leftBottom ); + dataPointsVector.push_back( leftTop ); + dataPointsVector.push_back( rightTop ); + dataPointsVector.push_back( rightBottom ); + } + + this->SetPlotTitle( (m_Histogram->GetSubject()).c_str() ); + + QPen pen( Qt::NoPen ); + QBrush brush( Qt::SolidPattern ); + + brush.setColor( Qt::blue ); + + int curveId = this->InsertCurve( (m_Histogram->GetSubject()).c_str() ); + this->SetCurveData( curveId, dataPointsVector ); + + this->SetCurvePen( curveId, pen ); + this->SetCurveBrush( curveId, brush ); + + // Axis 0 is the y axis, axis to the x axis + this->m_Plot->setAxisTitle(0, "n"); + //this->m_Plot->setAxisTitle(2, ""); + + this->Replot(); + +} \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkNetworkHistogramCanvas.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkNetworkHistogramCanvas.h new file mode 100644 index 0000000000..37a84e83ff --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkNetworkHistogramCanvas.h @@ -0,0 +1,75 @@ +/*========================================================================= + + Program: Medical Imaging & Interaction Toolkit + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) German Cancer Research Center, Division of Medical and + Biological Informatics. All rights reserved. + See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + + =========================================================================*/ + +#ifndef QmitkNetworkHistogramCanvas_H_INCLUDED +#define QmitkNetworkHistogramCanvas_H_INCLUDED + + +#include +#include + +#include "QmitkPlotWidget.h" + +#include +#include +#include +#include +#include + + //##Documentation + //## @brief A widget for displaying the data in a ConnectomicsHistogramBase + +class QmitkNetworkHistogramCanvas : public QmitkPlotWidget +{ + + Q_OBJECT + +public: + + QmitkNetworkHistogramCanvas( QWidget * parent=0, Qt::WindowFlags f = 0 ); + ~QmitkNetworkHistogramCanvas(); + + /** @brief Returns the histogram the canvas is using */ + mitk::ConnectomicsHistogramBase* GetHistogram() + { + return m_Histogram; + } + + /** @brief Set the histogram the canvas is to use */ + void SetHistogram(mitk::ConnectomicsHistogramBase *histogram) + { + m_Histogram = histogram; + } + + /** @brief Draw the histogram */ + void DrawProfiles(); + + /** @brief Return the plot */ + QwtPlot* GetPlot() + { + return m_Plot; + } + + +protected: + + /** @brief The histogram to be plotted */ + mitk::ConnectomicsHistogramBase *m_Histogram; + +}; +#endif + diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp index c9fc3aba29..4df517ea27 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp @@ -1,54 +1,56 @@ #include "mitkPluginActivator.h" #include #include "src/internal/QmitkDiffusionImagingPublicPerspective.h" #include "src/internal/QmitkQBallReconstructionView.h" #include "src/internal/QmitkPreprocessingView.h" #include "src/internal/QmitkDiffusionDicomImportView.h" #include "src/internal/QmitkDiffusionQuantificationView.h" #include "src/internal/QmitkTensorReconstructionView.h" #include "src/internal/QmitkControlVisualizationPropertiesView.h" #include "src/internal/QmitkODFDetailsView.h" #include "src/internal/QmitkGibbsTrackingView.h" #include "src/internal/QmitkStochasticFiberTrackingView.h" #include "src/internal/QmitkFiberProcessingView.h" #include "src/internal/QmitkFiberBundleDeveloperView.h" #include "src/internal/QmitkPartialVolumeAnalysisView.h" #include "src/internal/QmitkIVIMView.h" #include "src/internal/QmitkTractbasedSpatialStatisticsView.h" #include "src/internal/QmitkTbssSkeletonizationView.h" +#include "src/internal/Connectomics/QmitkBrainNetworkAnalysisView.h" namespace mitk { void PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionImagingPublicPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkQBallReconstructionView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkPreprocessingView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionDicomImport, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionQuantificationView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkTensorReconstructionView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkControlVisualizationPropertiesView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkODFDetailsView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkGibbsTrackingView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkStochasticFiberTrackingView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberProcessingView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberBundleDeveloperView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkPartialVolumeAnalysisView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkIVIMView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkTractbasedSpatialStatisticsView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkTbssSkeletonizationView, context) + BERRY_REGISTER_EXTENSION_CLASS(QmitkBrainNetworkAnalysisView, context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } Q_EXPORT_PLUGIN2(org_mitk_gui_qt_diffusionimaging, mitk::PluginActivator)