diff --git a/Modules/DiffusionImaging/Connectomics/Algorithms/itkConnectomicsNetworkToConnectivityMatrixImageFilter.cpp b/Modules/DiffusionImaging/Connectomics/Algorithms/itkConnectomicsNetworkToConnectivityMatrixImageFilter.cpp index 5baaf2fa7e..947032fbb8 100644 --- a/Modules/DiffusionImaging/Connectomics/Algorithms/itkConnectomicsNetworkToConnectivityMatrixImageFilter.cpp +++ b/Modules/DiffusionImaging/Connectomics/Algorithms/itkConnectomicsNetworkToConnectivityMatrixImageFilter.cpp @@ -1,186 +1,185 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef ITK_ConnectomicsNetworkToConnectivityMatrixImageFilter_CPP #define ITK_ConnectomicsNetworkToConnectivityMatrixImageFilter_CPP #include #include itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::ConnectomicsNetworkToConnectivityMatrixImageFilter() - : m_BinaryConnectivity(false) - , m_RescaleConnectivity(false) - , m_InputNetwork(NULL) + : m_BinaryConnectivity(false) + , m_RescaleConnectivity(false) + , m_InputNetwork(NULL) { } itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::~ConnectomicsNetworkToConnectivityMatrixImageFilter() { } void itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::GenerateData() { - this->AllocateOutputs(); + this->AllocateOutputs(); - OutputImageType::Pointer output = this->GetOutput(); + OutputImageType::Pointer output = this->GetOutput(); - if(m_InputNetwork.IsNull()) - { - MITK_ERROR << "Failed to generate data, no valid network was set."; - return; - } + if(m_InputNetwork.IsNull()) + { + MITK_ERROR << "Failed to generate data, no valid network was set."; + return; + } - typedef mitk::ConnectomicsNetwork::NetworkType NetworkType; - typedef boost::graph_traits< NetworkType >::vertex_descriptor DescriptorType; - typedef boost::graph_traits< NetworkType >::vertex_iterator IteratorType; + typedef mitk::ConnectomicsNetwork::NetworkType NetworkType; + typedef boost::graph_traits< NetworkType >::vertex_descriptor DescriptorType; + typedef boost::graph_traits< NetworkType >::vertex_iterator IteratorType; - // prepare connectivity matrix for data - std::vector< std::vector< int > > connectivityMatrix; - int numberOfVertices = m_InputNetwork->GetNumberOfVertices(); + // prepare connectivity matrix for data + std::vector< std::vector< int > > connectivityMatrix; + int numberOfVertices = m_InputNetwork->GetNumberOfVertices(); - connectivityMatrix.resize( numberOfVertices ); - for( int index(0); index < numberOfVertices; index++ ) - { - connectivityMatrix[ index ].resize( numberOfVertices ); - } + connectivityMatrix.resize( numberOfVertices ); + for( int index(0); index < numberOfVertices; index++ ) + { + connectivityMatrix[ index ].resize( numberOfVertices ); + } - // Create LabelToIndex translation - std::map< std::string, DescriptorType > labelToIndexMap; + // Create LabelToIndex translation + std::map< std::string, DescriptorType > labelToIndexMap; - NetworkType boostGraph = *(m_InputNetwork->GetBoostGraph()); + NetworkType boostGraph = *(m_InputNetwork->GetBoostGraph()); - // translate index to label - IteratorType iterator, end; - boost::tie(iterator, end) = boost::vertices( boostGraph ); + // translate index to label + IteratorType iterator, end; + boost::tie(iterator, end) = boost::vertices( boostGraph ); - for ( ; iterator != end; ++iterator) - { - labelToIndexMap.insert( - std::pair< std::string, DescriptorType >( - boostGraph[ *iterator ].label, *iterator ) - ); - } + for ( ; iterator != end; ++iterator) + { + labelToIndexMap.insert( + std::pair< std::string, DescriptorType >( + boostGraph[ *iterator ].label, *iterator ) + ); + } - std::vector< std::string > indexToLabel; + std::vector< std::string > indexToLabel; - // translate index to label - indexToLabel.resize( numberOfVertices ); + // translate index to label + indexToLabel.resize( numberOfVertices ); - boost::tie(iterator, end) = boost::vertices( boostGraph ); + boost::tie(iterator, end) = boost::vertices( boostGraph ); - for ( ; iterator != end; ++iterator) - { - indexToLabel[ *iterator ] = boostGraph[ *iterator ].label; - } + for ( ; iterator != end; ++iterator) + { + indexToLabel[ *iterator ] = boostGraph[ *iterator ].label; + } - //translate label to position - std::vector< std::string > positionToLabelVector; - positionToLabelVector = indexToLabel; + //translate label to position + std::vector< std::string > positionToLabelVector; + positionToLabelVector = indexToLabel; - std::sort ( positionToLabelVector.begin(), positionToLabelVector.end() ); + std::sort ( positionToLabelVector.begin(), positionToLabelVector.end() ); - for( int outerLoop( 0 ); outerLoop < numberOfVertices; outerLoop++ ) - { - DescriptorType fromVertexDescriptor = labelToIndexMap.find( positionToLabelVector[ outerLoop ] )->second; - for( int innerLoop( outerLoop + 1 ); innerLoop < numberOfVertices; innerLoop++ ) + for( int outerLoop( 0 ); outerLoop < numberOfVertices; outerLoop++ ) { - DescriptorType toVertexDescriptor = labelToIndexMap.find( positionToLabelVector[ innerLoop ] )->second; + DescriptorType fromVertexDescriptor = labelToIndexMap.find( positionToLabelVector[ outerLoop ] )->second; + for( int innerLoop( outerLoop + 1 ); innerLoop < numberOfVertices; innerLoop++ ) + { + DescriptorType toVertexDescriptor = labelToIndexMap.find( positionToLabelVector[ innerLoop ] )->second; - int weight( 0 ); + int weight( 0 ); - if( boost::edge(toVertexDescriptor, fromVertexDescriptor, boostGraph ).second ) - { - weight = m_InputNetwork->GetEdge( fromVertexDescriptor , toVertexDescriptor ).weight;; - } - connectivityMatrix[outerLoop][innerLoop] = weight; - connectivityMatrix[innerLoop][outerLoop] = weight; + if( boost::edge(toVertexDescriptor, fromVertexDescriptor, boostGraph ).second ) + { + weight = m_InputNetwork->GetEdge( fromVertexDescriptor , toVertexDescriptor ).weight;; + } + connectivityMatrix[outerLoop][innerLoop] = weight; + connectivityMatrix[innerLoop][outerLoop] = weight; + } } - } - - - OutputImageType::SpacingType spacing; - spacing[0] = 1.0; - spacing[1] = 1.0; - OutputImageType::PointType origin; - origin[0] = 0.0; - origin[1] = 0.0; - OutputImageType::IndexType index; - index[0] = 0.0; - index[1] = 0.0; - OutputImageType::SizeType size; - size[0] = numberOfVertices; - size[1] = numberOfVertices; - OutputImageType::RegionType region; - region.SetIndex( index ); - region.SetSize( size ); - - output->SetSpacing( spacing ); // Set the image spacing - output->SetOrigin( origin ); // Set the image origin - output->SetRegions( region ); - output->Allocate(); - output->FillBuffer(0); - - - itk::ImageRegionIterator< OutputImageType > it_connect(output, output->GetLargestPossibleRegion()); - - int counter( 0 ); - - double rescaleFactor( 1.0 ); - double rescaleMax( 255.0 ); - - if( m_RescaleConnectivity ) - { - rescaleFactor = rescaleMax / m_InputNetwork->GetMaximumWeight(); - } - - // Colour pixels according to connectivity - if( m_BinaryConnectivity ) - { - // binary connectivity - while( !it_connect.IsAtEnd() ) + + + OutputImageType::SpacingType spacing; + spacing[0] = 1.0; + spacing[1] = 1.0; + OutputImageType::PointType origin; + origin[0] = 0.0; + origin[1] = 0.0; + OutputImageType::IndexType index; + index[0] = 0.0; + index[1] = 0.0; + OutputImageType::SizeType size; + size[0] = numberOfVertices; + size[1] = numberOfVertices; + OutputImageType::RegionType region; + region.SetIndex( index ); + region.SetSize( size ); + + output->SetSpacing( spacing ); // Set the image spacing + output->SetOrigin( origin ); // Set the image origin + output->SetRegions( region ); + output->Allocate(); + output->FillBuffer(0); + + + itk::ImageRegionIterator< OutputImageType > it_connect(output, output->GetLargestPossibleRegion()); + + int counter( 0 ); + + double rescaleFactor( 1.0 ); + double rescaleMax( 1.0 ); + + if( m_RescaleConnectivity ) + { + rescaleFactor = rescaleMax / m_InputNetwork->GetMaximumWeight(); + } + + // Colour pixels according to connectivity + if( m_BinaryConnectivity ) { - if( connectivityMatrix[ ( counter - counter % numberOfVertices ) / numberOfVertices][ counter % numberOfVertices ] ) - { - it_connect.Set( 1 ); - } - else - { - it_connect.Set( 0 ); - } - ++it_connect; - counter++; + // binary connectivity + while( !it_connect.IsAtEnd() ) + { + if( connectivityMatrix[ ( counter - counter % numberOfVertices ) / numberOfVertices][ counter % numberOfVertices ] ) + { + it_connect.Set( 1 ); + } + else + { + it_connect.Set( 0 ); + } + ++it_connect; + counter++; + } } - } - else - { - // if desired rescale to the 0-255 range - while( !it_connect.IsAtEnd() ) + else { - it_connect.Set( ( unsigned short ) rescaleFactor * - connectivityMatrix[ ( counter - counter % numberOfVertices ) / numberOfVertices][ counter % numberOfVertices ] - ); - ++it_connect; - counter++; + // if desired rescale to the 0-255 range + while( !it_connect.IsAtEnd() ) + { + double val = rescaleFactor*connectivityMatrix[ ( counter - counter % numberOfVertices ) / numberOfVertices][ counter % numberOfVertices ]; + it_connect.Set( val ); + ++it_connect; + counter++; + } } - } } #endif diff --git a/Modules/DiffusionImaging/Connectomics/Algorithms/itkConnectomicsNetworkToConnectivityMatrixImageFilter.h b/Modules/DiffusionImaging/Connectomics/Algorithms/itkConnectomicsNetworkToConnectivityMatrixImageFilter.h index 6d984feba8..f1133a6030 100644 --- a/Modules/DiffusionImaging/Connectomics/Algorithms/itkConnectomicsNetworkToConnectivityMatrixImageFilter.h +++ b/Modules/DiffusionImaging/Connectomics/Algorithms/itkConnectomicsNetworkToConnectivityMatrixImageFilter.h @@ -1,80 +1,80 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef ITK_ConnectomicsNetworkToConnectivityMatrixImageFilter_H #define ITK_ConnectomicsNetworkToConnectivityMatrixImageFilter_H // ITK includes #include #include // MITK includes #include "mitkConnectomicsNetwork.h" namespace itk { - class ConnectomicsNetworkToConnectivityMatrixImageFilter : public ImageSource< itk::Image< unsigned short, 2 > > + class ConnectomicsNetworkToConnectivityMatrixImageFilter : public ImageSource< itk::Image< double, 2 > > { public: typedef ConnectomicsNetworkToConnectivityMatrixImageFilter Self; typedef ProcessObject Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; - typedef itk::Image< unsigned short, 2 > OutputImageType; + typedef itk::Image< double, 2 > OutputImageType; typedef OutputImageType::PixelType OutPixelType; typedef mitk::ConnectomicsNetwork InputType; itkNewMacro(Self) itkTypeMacro( ConnectomicsNetworkToConnectivityMatrixImageFilter, ImageSource ) /** Get/Set m_BinaryConnectivity **/ itkSetMacro( BinaryConnectivity, bool) itkGetMacro( BinaryConnectivity, bool) /** Get/Set m_RescaleConnectivity **/ itkSetMacro( RescaleConnectivity, bool) itkGetMacro( RescaleConnectivity, bool) itkSetMacro( InputNetwork, InputType::Pointer) void GenerateData(); protected: ConnectomicsNetworkToConnectivityMatrixImageFilter(); virtual ~ConnectomicsNetworkToConnectivityMatrixImageFilter(); /** Controls whether the connectivity matrix is binary */ bool m_BinaryConnectivity; /** Controls whether the connectivity matrix entries are rescaled to lie between 0 and 255*/ bool m_RescaleConnectivity; InputType::Pointer m_InputNetwork; }; } #ifndef ITK_MANUAL_INSTANTIATION #include "itkConnectomicsNetworkToConnectivityMatrixImageFilter.cpp" #endif #endif /* ITK_ConnectomicsNetworkToConnectivityMatrixImageFilter_H */ diff --git a/Modules/DiffusionImaging/Connectomics/Algorithms/mitkConnectomicsNetworkCreator.cpp b/Modules/DiffusionImaging/Connectomics/Algorithms/mitkConnectomicsNetworkCreator.cpp index ea5f62a746..bfa02769d7 100644 --- a/Modules/DiffusionImaging/Connectomics/Algorithms/mitkConnectomicsNetworkCreator.cpp +++ b/Modules/DiffusionImaging/Connectomics/Algorithms/mitkConnectomicsNetworkCreator.cpp @@ -1,840 +1,860 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkConnectomicsNetworkCreator.h" #include #include #include "mitkConnectomicsConstantsManager.h" #include "mitkImageAccessByItk.h" #include "mitkImageStatisticsHolder.h" #include "mitkImageCast.h" #include "itkImageRegionIteratorWithIndex.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 ) , m_UseCoMCoordinates( false ) , m_LabelsToCoordinatesMap() -, m_MappingStrategy( EndElementPositionAvoidingWhiteMatter ) +, m_MappingStrategy( EndElementPosition ) , m_EndPointSearchRadius( 10.0 ) { } 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 ) , m_LabelsToCoordinatesMap() -, m_MappingStrategy( EndElementPositionAvoidingWhiteMatter ) +, m_MappingStrategy( EndElementPosition ) , m_EndPointSearchRadius( 10.0 ) { } 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(); + { + CalculateCenterOfMass(); + } + + std::cout << m_ConNetwork->GetNumberOfVertices() << std::endl; vtkSmartPointer fiberPolyData = m_FiberBundle->GetFiberPolyData(); - vtkSmartPointer vLines = fiberPolyData->GetLines(); - vLines->InitTraversal(); int numFibers = m_FiberBundle->GetNumFibers(); for( int fiberID( 0 ); fiberID < numFibers; fiberID++ ) { - vtkIdType numPointsInCell(0); - vtkIdType* pointsInCell(NULL); - vLines->GetNextCell ( numPointsInCell, pointsInCell ); + vtkCell* cell = fiberPolyData->GetCell(fiberID); + int numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); TractType::Pointer singleTract = TractType::New(); - for( int pointInCellID( 0 ); pointInCellID < numPointsInCell ; pointInCellID++) + for( int pointInCellID( 0 ); pointInCellID < numPoints ; pointInCellID++) { // push back point - PointType point = GetItkPoint( fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] ) ); + PointType point = GetItkPoint( points->GetPoint( pointInCellID ) ); singleTract->InsertElement( singleTract->Size(), point ); } if ( singleTract && ( singleTract->Size() > 0 ) ) { AddConnectionToNetwork( ReturnAssociatedVertexPairForLabelPair( ReturnLabelForFiberTract( singleTract, m_MappingStrategy ) ) ); } } // Prune unconnected nodes //m_ConNetwork->PruneUnconnectedSingleNodes(); // provide network with geometry m_ConNetwork->SetGeometry( dynamic_cast(m_Segmentation->GetGeometry()->Clone().GetPointer()) ); m_ConNetwork->UpdateBounds(); 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; // 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 CreateNewNode( firstLabel, firstElementSegIndex, m_UseCoMCoordinates ); CreateNewNode( lastLabel, lastElementSegIndex, m_UseCoMCoordinates ); } 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 CreateNewNode( firstLabel, firstElementSegIndex, m_UseCoMCoordinates ); CreateNewNode( lastLabel, lastElementSegIndex, m_UseCoMCoordinates ); } 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 CreateNewNode( firstLabel, firstElementSegIndex, m_UseCoMCoordinates ); CreateNewNode( lastLabel, lastElementSegIndex, m_UseCoMCoordinates ); } 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 )|| ( labelInQuestion == freesurfer_Left_Cerebellum_Cortex ) || ( labelInQuestion == freesurfer_Right_Cerebellum_Cortex ) || ( labelInQuestion == freesurfer_Brain_Stem ) ); 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 ); + if( length < mitk::eps ) + { + continue; + } + // 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 ) ) { // check whether result is within the search space { mitk::Point3D endPoint, foundPointSegmentation, foundPointFiber; for( int index = 0; index < singleTract->front().Size(); index++ ) { // this is in fiber (world) coordinates endPoint.SetElement( index, singleTract->GetElement( retractionStartIndex ).GetElement( index ) ); } for( int index( 0 ); index < 3; index++ ) { foundPointSegmentation.SetElement( index, currentPoint.GetElement( index ) + ( 1.0 + parameter ) / ( 1.0 + length ) * differenceVector[ index ] ); } SegmentationToFiberCoords( foundPointSegmentation, foundPointFiber ); std::vector< double > finalDistance; finalDistance.resize( singleTract->front().Size() ); for( int index = 0; index < singleTract->front().Size(); index++ ) { finalDistance[ index ] = foundPointFiber.GetElement( index ) - endPoint.GetElement( index ); } // calculate length of direction vector double finalLength( 0.0 ); double finalSum( 0.0 ); for( int index = 0; index < finalDistance.size() ; index++ ) { finalSum = finalSum + finalDistance[ index ] * finalDistance[ index ]; } finalLength = std::sqrt( finalSum ); if( finalLength > m_EndPointSearchRadius ) { // the found point was not within the search space return; } } label = tempLabel; mitkIndex = tempIndex; return; } // hit next point without finding brain matter currentRetractionIndex = currentRetractionIndex + retractionStepIndexSize; if( ( currentRetractionIndex < 1 ) || ( currentRetractionIndex > ( singleTract->Size() - 2 ) ) ) { keepRetracting = false; } } } } void mitk::ConnectomicsNetworkCreator::CalculateCenterOfMass() { const int dimensions = 3; typedef itk::Image ITKImageType; ITKImageType::Pointer itkImage = ITKImageType::New(); mitk::CastToItkImage( m_Segmentation, itkImage ); int max = m_Segmentation->GetStatistics()->GetScalarValueMax(); int min = m_Segmentation->GetStatistics()->GetScalarValueMin(); int range = max - min +1; // each label owns a vector of coordinates std::vector< std::vector< std::vector< double> > > coordinatesPerLabelVector; coordinatesPerLabelVector.resize( range ); itk::ImageRegionIteratorWithIndex it_itkImage( itkImage, itkImage->GetLargestPossibleRegion() ); for( it_itkImage.GoToBegin(); !it_itkImage.IsAtEnd(); ++it_itkImage ) { std::vector< double > coordinates; coordinates.resize(dimensions); itk::Index< dimensions > index = it_itkImage.GetIndex(); for( int loop(0); loop < dimensions; loop++) { coordinates.at( loop ) = index.GetElement( loop ); } // add the coordinates to the corresponding label vector coordinatesPerLabelVector.at( it_itkImage.Value() - min ).push_back( coordinates ); } for(int currentIndex(0), currentLabel( min ); currentIndex < range; currentIndex++, currentLabel++ ) { std::vector< double > currentCoordinates; currentCoordinates.resize(dimensions); int numberOfPoints = coordinatesPerLabelVector.at( currentIndex ).size(); std::vector< double > sumCoords; sumCoords.resize( dimensions ); for( int loop(0); loop < numberOfPoints; loop++ ) { for( int loopDimension( 0 ); loopDimension < dimensions; loopDimension++ ) { sumCoords.at( loopDimension ) += coordinatesPerLabelVector.at( currentIndex ).at( loop ).at( loopDimension ); } } for( int loopDimension( 0 ); loopDimension < dimensions; loopDimension++ ) { currentCoordinates.at( loopDimension ) = sumCoords.at( loopDimension ) / numberOfPoints; } m_LabelsToCoordinatesMap.insert( std::pair< int, std::vector >( currentLabel, currentCoordinates ) ); + + // Peter Hack + { + CreateNewNode( currentLabel, mitk::Index3D(), true ); + if( ! ( m_LabelToVertexMap.count( currentLabel ) > 0 ) ) + { + VertexType newVertex = m_ConNetwork->AddVertex( idCounter ); + idCounter++; + SupplyVertexWithInformation(currentLabel, newVertex); + m_LabelToVertexMap.insert( std::pair< ImageLabelType, VertexType >( currentLabel, newVertex ) ); + } + } } //can now use center of mass coordinates m_UseCoMCoordinates = true; } std::vector< double > mitk::ConnectomicsNetworkCreator::GetCenterOfMass( int label ) { // if label is not known, warn if( ! ( m_LabelsToCoordinatesMap.count( label ) > 0 ) ) { MITK_ERROR << "Label " << label << " not found. Could not return coordinates."; std::vector< double > nullVector; nullVector.resize(3); return nullVector; } //return associated coordinates return m_LabelsToCoordinatesMap.find( label )->second; } void mitk::ConnectomicsNetworkCreator::CreateNewNode( int label, mitk::Index3D index, bool useCoM ) { // Only create node if it does not exist yet if( ! ( m_LabelToNodePropertyMap.count( label ) > 0 ) ) { NetworkNode newNode; newNode.coordinates.resize( 3 ); if( !useCoM ) { for( unsigned int loop = 0; loop < newNode.coordinates.size() ; loop++ ) { newNode.coordinates[ loop ] = index[ loop ] ; } } else { std::vector labelCoords = GetCenterOfMass( label ); for( unsigned int loop = 0; loop < newNode.coordinates.size() ; loop++ ) { newNode.coordinates[ loop ] = labelCoords.at( loop ) ; } } newNode.label = LabelToString( label ); m_LabelToNodePropertyMap.insert( std::pair< ImageLabelType, NetworkNode >( label, newNode ) ); } } diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFieldmapGeneratorFilter.cpp b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFieldmapGeneratorFilter.cpp index f6f7516e67..15c27ca564 100644 --- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFieldmapGeneratorFilter.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFieldmapGeneratorFilter.cpp @@ -1,79 +1,107 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Coindex[1]right (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "itkFieldmapGeneratorFilter.h" #include #include #include namespace itk{ template< class OutputImageType > FieldmapGeneratorFilter< OutputImageType >::FieldmapGeneratorFilter() { m_Gradient.fill(0.0); m_Offset.fill(0.0); } template< class OutputImageType > FieldmapGeneratorFilter< OutputImageType >::~FieldmapGeneratorFilter() { } template< class OutputImageType > void FieldmapGeneratorFilter< OutputImageType >::BeforeThreadedGenerateData() { typename OutputImageType::Pointer outImage = OutputImageType::New(); outImage->SetSpacing( m_Spacing ); outImage->SetOrigin( m_Origin ); outImage->SetDirection( m_DirectionMatrix ); outImage->SetLargestPossibleRegion( m_ImageRegion ); outImage->SetBufferedRegion( m_ImageRegion ); outImage->SetRequestedRegion( m_ImageRegion ); outImage->Allocate(); outImage->FillBuffer(0); this->SetNthOutput(0, outImage); } template< class OutputImageType > void FieldmapGeneratorFilter< OutputImageType >::ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread, ThreadIdType threadId) { typename OutputImageType::Pointer outImage = static_cast< OutputImageType * >(this->ProcessObject::GetOutput(0)); ImageRegionIterator< OutputImageType > oit(outImage, outputRegionForThread); + int szx = m_ImageRegion.GetSize(0); + int szy = m_ImageRegion.GetSize(1); + int szz = m_ImageRegion.GetSize(2); + + double max = szx*szx + szy*szy - szx*szy; + while( !oit.IsAtEnd() ) { double value = 0; IndexType idx = oit.GetIndex(); - for (int i=0; i<3; i++) - value += idx[i]*m_Gradient[i] + m_Offset[i]; +// for (int i=0; i<3; i++) +// value += std::exp(-(double)idx[i]/32.0)*m_Gradient[i] + m_Offset[i]; + + //value += idx[0]*idx[0] + idx[1]*idx[1] - idx[0]*idx[1]; for (int i=0; i vertex; outImage->TransformIndexToPhysicalPoint(idx, vertex); double dist = c.EuclideanDistanceTo(vertex); - value += m_Heights.at(i)*exp(-dist*dist/(2*m_Variances.at(i))); + + c[0] -= vertex[0]; + c[1] -= vertex[1]; + c[2] -= vertex[2]; + + double x = c[0]; + double y = c[1]; + double z = c[2]; + + dist = fabs(dist) - m_Variances.at(i); + if (dist>0) + value += (2*z*z-y*y-x*x)/pow(x*x+y*y+z*z,5/2); + + +// dist = fabs(dist) - m_Variances.at(i); +// if (dist<0) +// dist = 0; +// value += std::exp(-dist/m_Variances.at(i))*m_Heights.at(i); + + // value += m_Heights.at(i)*exp(-dist*dist/(2*m_Variances.at(i))); } - oit.Set(value); + + oit.Set(m_Gradient[0]*value/max); ++oit; } MITK_INFO << "Thread " << threadId << "finished processing"; } } diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp index 772cbcda29..46fc032ff7 100644 --- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp @@ -1,709 +1,708 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "itkTractsToDWIImageFilter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace itk { TractsToDWIImageFilter::TractsToDWIImageFilter() : m_CircleDummy(false) , m_VolumeAccuracy(10) , m_Upsampling(1) , m_NumberOfRepetitions(1) , m_EnforcePureFiberVoxels(false) , m_InterpolationShrink(1000) , m_FiberRadius(0) , m_SignalScale(25) , m_kOffset(0) , m_tLine(1) , m_UseInterpolation(false) , m_SimulateRelaxation(true) , m_tInhom(50) , m_TE(100) , m_FrequencyMap(NULL) , m_EddyGradientStrength(0.001) , m_SimulateEddyCurrents(false) { m_Spacing.Fill(2.5); m_Origin.Fill(0.0); m_DirectionMatrix.SetIdentity(); m_ImageRegion.SetSize(0, 10); m_ImageRegion.SetSize(1, 10); m_ImageRegion.SetSize(2, 10); } TractsToDWIImageFilter::~TractsToDWIImageFilter() { } TractsToDWIImageFilter::DoubleDwiType::Pointer TractsToDWIImageFilter::DoKspaceStuff( std::vector< DoubleDwiType::Pointer >& images ) { // create slice object ImageRegion<2> sliceRegion; sliceRegion.SetSize(0, m_UpsampledImageRegion.GetSize()[0]); sliceRegion.SetSize(1, m_UpsampledImageRegion.GetSize()[1]); // frequency map slice SliceType::Pointer fMap = NULL; if (m_FrequencyMap.IsNotNull()) { fMap = SliceType::New(); ImageRegion<2> region; region.SetSize(0, m_UpsampledImageRegion.GetSize()[0]); region.SetSize(1, m_UpsampledImageRegion.GetSize()[1]); fMap->SetLargestPossibleRegion( region ); fMap->SetBufferedRegion( region ); fMap->SetRequestedRegion( region ); fMap->Allocate(); } DoubleDwiType::Pointer newImage = DoubleDwiType::New(); newImage->SetSpacing( m_Spacing ); newImage->SetOrigin( m_Origin ); newImage->SetDirection( m_DirectionMatrix ); newImage->SetLargestPossibleRegion( m_ImageRegion ); newImage->SetBufferedRegion( m_ImageRegion ); newImage->SetRequestedRegion( m_ImageRegion ); newImage->SetVectorLength( images.at(0)->GetVectorLength() ); newImage->Allocate(); MatrixType transform = m_DirectionMatrix; for (int i=0; i<3; i++) for (int j=0; j<3; j++) { if (j<2) transform[i][j] *= m_UpsampledSpacing[j]; else transform[i][j] *= m_Spacing[j]; } boost::progress_display disp(images.at(0)->GetVectorLength()*images.at(0)->GetLargestPossibleRegion().GetSize(2)); for (int g=0; gGetVectorLength(); g++) for (int z=0; zGetLargestPossibleRegion().GetSize(2); z++) { ++disp; std::vector< SliceType::Pointer > compartmentSlices; std::vector< double > t2Vector; for (int i=0; i* signalModel; if (iSetLargestPossibleRegion( sliceRegion ); slice->SetBufferedRegion( sliceRegion ); slice->SetRequestedRegion( sliceRegion ); slice->Allocate(); slice->FillBuffer(0.0); // extract slice from channel g for (int y=0; yGetLargestPossibleRegion().GetSize(1); y++) for (int x=0; xGetLargestPossibleRegion().GetSize(0); x++) { SliceType::IndexType index2D; index2D[0]=x; index2D[1]=y; DoubleDwiType::IndexType index3D; index3D[0]=x; index3D[1]=y; index3D[2]=z; slice->SetPixel(index2D, images.at(i)->GetPixel(index3D)[g]); if (fMap.IsNotNull() && i==0) fMap->SetPixel(index2D, m_FrequencyMap->GetPixel(index3D)); } compartmentSlices.push_back(slice); t2Vector.push_back(signalModel->GetT2()); } // create k-sapce (inverse fourier transform slices) itk::KspaceImageFilter< SliceType::PixelType >::Pointer idft = itk::KspaceImageFilter< SliceType::PixelType >::New(); idft->SetCompartmentImages(compartmentSlices); idft->SetT2(t2Vector); idft->SetkOffset(m_kOffset); idft->SettLine(m_tLine); idft->SetTE(m_TE); idft->SetTinhom(m_tInhom); idft->SetSimulateRelaxation(m_SimulateRelaxation); idft->SetSimulateEddyCurrents(m_SimulateEddyCurrents); idft->SetEddyGradientMagnitude(m_EddyGradientStrength); idft->SetZ((double)z-(double)images.at(0)->GetLargestPossibleRegion().GetSize(2)/2.0); idft->SetDirectionMatrix(transform); idft->SetDiffusionGradientDirection(m_FiberModels.at(0)->GetGradientDirection(g)); idft->SetFrequencyMap(fMap); idft->SetSignalScale(m_SignalScale); idft->Update(); ComplexSliceType::Pointer fSlice; fSlice = idft->GetOutput(); fSlice = RearrangeSlice(fSlice); // add artifacts for (int a=0; aAddArtifact(fSlice); // fourier transform slice SliceType::Pointer newSlice; itk::DftImageFilter< SliceType::PixelType >::Pointer dft = itk::DftImageFilter< SliceType::PixelType >::New(); dft->SetInput(fSlice); dft->Update(); newSlice = dft->GetOutput(); // put slice back into channel g for (int y=0; yGetLargestPossibleRegion().GetSize(1); y++) for (int x=0; xGetLargestPossibleRegion().GetSize(0); x++) { DoubleDwiType::IndexType index3D; index3D[0]=x; index3D[1]=y; index3D[2]=z; SliceType::IndexType index2D; index2D[0]=x; index2D[1]=y; DoubleDwiType::PixelType pix3D = newImage->GetPixel(index3D); pix3D[g] = newSlice->GetPixel(index2D); newImage->SetPixel(index3D, pix3D); } } return newImage; } TractsToDWIImageFilter::ComplexSliceType::Pointer TractsToDWIImageFilter::RearrangeSlice(ComplexSliceType::Pointer slice) { ImageRegion<2> region = slice->GetLargestPossibleRegion(); ComplexSliceType::Pointer rearrangedSlice = ComplexSliceType::New(); rearrangedSlice->SetLargestPossibleRegion( region ); rearrangedSlice->SetBufferedRegion( region ); rearrangedSlice->SetRequestedRegion( region ); rearrangedSlice->Allocate(); int xHalf = region.GetSize(0)/2; int yHalf = region.GetSize(1)/2; for (int y=0; y pix = slice->GetPixel(idx); if( idx[0] < xHalf ) idx[0] = idx[0] + xHalf; else idx[0] = idx[0] - xHalf; if( idx[1] < yHalf ) idx[1] = idx[1] + yHalf; else idx[1] = idx[1] - yHalf; rearrangedSlice->SetPixel(idx, pix); } return rearrangedSlice; } void TractsToDWIImageFilter::GenerateData() { // check input data if (m_FiberBundle.IsNull()) itkExceptionMacro("Input fiber bundle is NULL!"); int numFibers = m_FiberBundle->GetNumFibers(); if (numFibers<=0) itkExceptionMacro("Input fiber bundle contains no fibers!"); if (m_FiberModels.empty()) itkExceptionMacro("No diffusion model for fiber compartments defined!"); if (m_NonFiberModels.empty()) itkExceptionMacro("No diffusion model for non-fiber compartments defined!"); int baselineIndex = m_FiberModels[0]->GetFirstBaselineIndex(); if (baselineIndex<0) itkExceptionMacro("No baseline index found!"); // determine k-space undersampling for (int i=0; i*>(m_KspaceArtifacts.at(i)) ) m_Upsampling = dynamic_cast*>(m_KspaceArtifacts.at(i))->GetKspaceCropping(); if (m_Upsampling<1) m_Upsampling = 1; if (m_TissueMask.IsNotNull()) { // use input tissue mask m_Spacing = m_TissueMask->GetSpacing(); m_Origin = m_TissueMask->GetOrigin(); m_DirectionMatrix = m_TissueMask->GetDirection(); m_ImageRegion = m_TissueMask->GetLargestPossibleRegion(); if (m_Upsampling>1) { ImageRegion<3> region = m_ImageRegion; region.SetSize(0, m_ImageRegion.GetSize(0)*m_Upsampling); region.SetSize(1, m_ImageRegion.GetSize(1)*m_Upsampling); itk::Vector spacing = m_Spacing; spacing[0] /= m_Upsampling; spacing[1] /= m_Upsampling; itk::RescaleIntensityImageFilter::Pointer rescaler = itk::RescaleIntensityImageFilter::New(); rescaler->SetInput(0,m_TissueMask); rescaler->SetOutputMaximum(100); rescaler->SetOutputMinimum(0); rescaler->Update(); itk::ResampleImageFilter::Pointer resampler = itk::ResampleImageFilter::New(); resampler->SetInput(rescaler->GetOutput()); resampler->SetOutputParametersFromImage(m_TissueMask); resampler->SetSize(region.GetSize()); resampler->SetOutputSpacing(spacing); resampler->Update(); m_TissueMask = resampler->GetOutput(); } MITK_INFO << "Using tissue mask"; } // initialize output dwi image OutputImageType::Pointer outImage = OutputImageType::New(); outImage->SetSpacing( m_Spacing ); outImage->SetOrigin( m_Origin ); outImage->SetDirection( m_DirectionMatrix ); outImage->SetLargestPossibleRegion( m_ImageRegion ); outImage->SetBufferedRegion( m_ImageRegion ); outImage->SetRequestedRegion( m_ImageRegion ); outImage->SetVectorLength( m_FiberModels[0]->GetNumGradients() ); outImage->Allocate(); OutputImageType::PixelType temp; temp.SetSize(m_FiberModels[0]->GetNumGradients()); temp.Fill(0.0); outImage->FillBuffer(temp); // is input slize size a power of two? int x=m_ImageRegion.GetSize(0); int y=m_ImageRegion.GetSize(1); if ( x%2 == 1 ) x += 1; if ( y%2 == 1 ) y += 1; // if not, adjust size and dimension (needed for FFT); zero-padding if (x!=m_ImageRegion.GetSize(0)) { MITK_INFO << "Adjusting image width: " << m_ImageRegion.GetSize(0) << " --> " << x << " --> " << x*m_Upsampling; m_ImageRegion.SetSize(0, x); } if (y!=m_ImageRegion.GetSize(1)) { MITK_INFO << "Adjusting image height: " << m_ImageRegion.GetSize(1) << " --> " << y << " --> " << y*m_Upsampling; m_ImageRegion.SetSize(1, y); } // apply undersampling to image parameters m_UpsampledSpacing = m_Spacing; m_UpsampledImageRegion = m_ImageRegion; m_UpsampledSpacing[0] /= m_Upsampling; m_UpsampledSpacing[1] /= m_Upsampling; m_UpsampledImageRegion.SetSize(0, m_ImageRegion.GetSize()[0]*m_Upsampling); m_UpsampledImageRegion.SetSize(1, m_ImageRegion.GetSize()[1]*m_Upsampling); // everything from here on is using the upsampled image parameters!!! if (m_TissueMask.IsNull()) { m_TissueMask = ItkUcharImgType::New(); m_TissueMask->SetSpacing( m_UpsampledSpacing ); m_TissueMask->SetOrigin( m_Origin ); m_TissueMask->SetDirection( m_DirectionMatrix ); m_TissueMask->SetLargestPossibleRegion( m_UpsampledImageRegion ); m_TissueMask->SetBufferedRegion( m_UpsampledImageRegion ); m_TissueMask->SetRequestedRegion( m_UpsampledImageRegion ); m_TissueMask->Allocate(); m_TissueMask->FillBuffer(1); } // resample frequency map if (m_FrequencyMap.IsNotNull()) { itk::ResampleImageFilter::Pointer resampler = itk::ResampleImageFilter::New(); resampler->SetInput(m_FrequencyMap); resampler->SetOutputParametersFromImage(m_FrequencyMap); resampler->SetSize(m_UpsampledImageRegion.GetSize()); resampler->SetOutputSpacing(m_UpsampledSpacing); resampler->Update(); m_FrequencyMap = resampler->GetOutput(); } // initialize volume fraction images m_VolumeFractions.clear(); for (int i=0; iSetSpacing( m_UpsampledSpacing ); tempimg->SetOrigin( m_Origin ); tempimg->SetDirection( m_DirectionMatrix ); tempimg->SetLargestPossibleRegion( m_UpsampledImageRegion ); tempimg->SetBufferedRegion( m_UpsampledImageRegion ); tempimg->SetRequestedRegion( m_UpsampledImageRegion ); tempimg->Allocate(); tempimg->FillBuffer(0); m_VolumeFractions.push_back(tempimg); } // resample fiber bundle for sufficient voxel coverage double segmentVolume = 0.0001; float minSpacing = 1; if(m_UpsampledSpacing[0]GetDeepCopy(); fiberBundle->ResampleFibers(minSpacing/m_VolumeAccuracy); double mmRadius = m_FiberRadius/1000; if (mmRadius>0) segmentVolume = M_PI*mmRadius*mmRadius*minSpacing/m_VolumeAccuracy; // generate double images to work with because we don't want to lose precision // we use a separate image for each compartment model std::vector< DoubleDwiType::Pointer > compartments; for (int i=0; iSetSpacing( m_UpsampledSpacing ); doubleDwi->SetOrigin( m_Origin ); doubleDwi->SetDirection( m_DirectionMatrix ); doubleDwi->SetLargestPossibleRegion( m_UpsampledImageRegion ); doubleDwi->SetBufferedRegion( m_UpsampledImageRegion ); doubleDwi->SetRequestedRegion( m_UpsampledImageRegion ); doubleDwi->SetVectorLength( m_FiberModels[0]->GetNumGradients() ); doubleDwi->Allocate(); DoubleDwiType::PixelType pix; pix.SetSize(m_FiberModels[0]->GetNumGradients()); pix.Fill(0.0); doubleDwi->FillBuffer(pix); compartments.push_back(doubleDwi); } double interpFact = 2*atan(-0.5*m_InterpolationShrink); double maxVolume = 0; - vtkSmartPointer fiberPolyData = fiberBundle->GetFiberPolyData(); - vtkSmartPointer vLines = fiberPolyData->GetLines(); - vLines->InitTraversal(); - MITK_INFO << "Generating signal of " << m_FiberModels.size() << " fiber compartments"; + vtkSmartPointer fiberPolyData = fiberBundle->GetFiberPolyData(); boost::progress_display disp(numFibers); for( int i=0; iGetNextCell ( numPoints, points ); + + vtkCell* cell = fiberPolyData->GetCell(i); + int numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + if (numPoints<2) continue; for( int j=0; jGetPoint(points[j]); + double* temp = points->GetPoint(j); itk::Point vertex = GetItkPoint(temp); itk::Vector v = GetItkVector(temp); itk::Vector dir(3); if (jGetPoint(points[j+1]))-v; + dir = GetItkVector(points->GetPoint(j+1))-v; else - dir = v-GetItkVector(fiberPolyData->GetPoint(points[j-1])); + dir = v-GetItkVector(points->GetPoint(j-1)); itk::Index<3> idx; itk::ContinuousIndex contIndex; m_TissueMask->TransformPhysicalPointToIndex(vertex, idx); m_TissueMask->TransformPhysicalPointToContinuousIndex(vertex, contIndex); if (!m_UseInterpolation) // use nearest neighbour interpolation { if (!m_TissueMask->GetLargestPossibleRegion().IsInside(idx) || m_TissueMask->GetPixel(idx)<=0) continue; // generate signal for each fiber compartment for (int k=0; kSetFiberDirection(dir); DoubleDwiType::PixelType pix = doubleDwi->GetPixel(idx); pix += segmentVolume*m_FiberModels[k]->SimulateMeasurement(); doubleDwi->SetPixel(idx, pix ); if (pix[baselineIndex]>maxVolume) maxVolume = pix[baselineIndex]; } continue; } double frac_x = contIndex[0] - idx[0]; double frac_y = contIndex[1] - idx[1]; double frac_z = contIndex[2] - idx[2]; if (frac_x<0) { idx[0] -= 1; frac_x += 1; } if (frac_y<0) { idx[1] -= 1; frac_y += 1; } if (frac_z<0) { idx[2] -= 1; frac_z += 1; } frac_x = atan((0.5-frac_x)*m_InterpolationShrink)/interpFact + 0.5; frac_y = atan((0.5-frac_y)*m_InterpolationShrink)/interpFact + 0.5; frac_z = atan((0.5-frac_z)*m_InterpolationShrink)/interpFact + 0.5; // use trilinear interpolation itk::Index<3> newIdx; for (int x=0; x<2; x++) { frac_x = 1-frac_x; for (int y=0; y<2; y++) { frac_y = 1-frac_y; for (int z=0; z<2; z++) { frac_z = 1-frac_z; newIdx[0] = idx[0]+x; newIdx[1] = idx[1]+y; newIdx[2] = idx[2]+z; double frac = frac_x*frac_y*frac_z; // is position valid? if (!m_TissueMask->GetLargestPossibleRegion().IsInside(newIdx) || m_TissueMask->GetPixel(newIdx)<=0) continue; // generate signal for each fiber compartment for (int k=0; kSetFiberDirection(dir); DoubleDwiType::PixelType pix = doubleDwi->GetPixel(newIdx); pix += segmentVolume*frac*m_FiberModels[k]->SimulateMeasurement(); doubleDwi->SetPixel(newIdx, pix ); if (pix[baselineIndex]>maxVolume) maxVolume = pix[baselineIndex]; } } } } } } MITK_INFO << "Generating signal of " << m_NonFiberModels.size() << " non-fiber compartments"; ImageRegionIterator it3(m_TissueMask, m_TissueMask->GetLargestPossibleRegion()); boost::progress_display disp3(m_TissueMask->GetLargestPossibleRegion().GetNumberOfPixels()); double voxelVolume = m_UpsampledSpacing[0]*m_UpsampledSpacing[1]*m_UpsampledSpacing[2]; double fact = 1; if (m_FiberRadius<0.0001) fact = voxelVolume/maxVolume; while(!it3.IsAtEnd()) { ++disp3; DoubleDwiType::IndexType index = it3.GetIndex(); if (it3.Get()>0) { // get fiber volume fraction DoubleDwiType::Pointer fiberDwi = compartments.at(0); DoubleDwiType::PixelType fiberPix = fiberDwi->GetPixel(index); // intra axonal compartment if (fact>1) // auto scale intra-axonal if no fiber radius is specified { fiberPix *= fact; fiberDwi->SetPixel(index, fiberPix); } double f = fiberPix[baselineIndex]; if (f>voxelVolume || f>0 && m_EnforcePureFiberVoxels) // more fiber than space in voxel? { fiberDwi->SetPixel(index, fiberPix*voxelVolume/f); for (int i=1; iSetPixel(index, pix); m_VolumeFractions.at(i)->SetPixel(index, 1); } } else { m_VolumeFractions.at(0)->SetPixel(index, f); double nonf = voxelVolume-f; // non-fiber volume double inter = 0; if (m_FiberModels.size()>1) inter = nonf * f/voxelVolume; // intra-axonal fraction of non fiber compartment scales linearly with f double other = nonf - inter; // rest of compartment double singleinter = inter/(m_FiberModels.size()-1); // adjust non-fiber and intra-axonal signal for (int i=1; iGetPixel(index); if (pix[baselineIndex]>0) pix /= pix[baselineIndex]; pix *= singleinter; doubleDwi->SetPixel(index, pix); m_VolumeFractions.at(i)->SetPixel(index, singleinter/voxelVolume); } for (int i=0; iGetPixel(index) + m_NonFiberModels[i]->SimulateMeasurement()*other*m_NonFiberModels[i]->GetWeight(); doubleDwi->SetPixel(index, pix); m_VolumeFractions.at(i+m_FiberModels.size())->SetPixel(index, other/voxelVolume*m_NonFiberModels[i]->GetWeight()); } } } ++it3; } // do k-space stuff DoubleDwiType::Pointer doubleOutImage; if (m_FrequencyMap.IsNotNull() || !m_KspaceArtifacts.empty() || m_kOffset>0 || m_SimulateRelaxation || m_SimulateEddyCurrents) { MITK_INFO << "Adjusting complex signal"; doubleOutImage = DoKspaceStuff(compartments); m_SignalScale = 1; } else { MITK_INFO << "Summing compartments"; doubleOutImage = compartments.at(0); for (int i=1; i::Pointer adder = itk::AddImageFilter< DoubleDwiType, DoubleDwiType, DoubleDwiType>::New(); adder->SetInput1(doubleOutImage); adder->SetInput2(compartments.at(i)); adder->Update(); doubleOutImage = adder->GetOutput(); } } MITK_INFO << "Finalizing image"; unsigned int window = 0; unsigned int min = itk::NumericTraits::max(); ImageRegionIterator it4 (outImage, outImage->GetLargestPossibleRegion()); DoubleDwiType::PixelType signal; signal.SetSize(m_FiberModels[0]->GetNumGradients()); boost::progress_display disp4(outImage->GetLargestPossibleRegion().GetNumberOfPixels()); while(!it4.IsAtEnd()) { ++disp4; DWIImageType::IndexType index = it4.GetIndex(); signal = doubleOutImage->GetPixel(index)*m_SignalScale; if (m_NoiseModel->GetNoiseVariance() > 0) { DoubleDwiType::PixelType accu = signal; accu.Fill(0.0); for (int i=0; iAddNoise(temp); accu += temp; } signal = accu/m_NumberOfRepetitions; } for (int i=0; i0) signal[i] = floor(signal[i]+0.5); else signal[i] = ceil(signal[i]-0.5); if (!m_FiberModels.at(0)->IsBaselineIndex(i) && signal[i]>window) window = signal[i]; if (!m_FiberModels.at(0)->IsBaselineIndex(i) && signal[i]SetNthOutput(0, outImage); } itk::Point TractsToDWIImageFilter::GetItkPoint(double point[3]) { itk::Point itkPoint; itkPoint[0] = point[0]; itkPoint[1] = point[1]; itkPoint[2] = point[2]; return itkPoint; } itk::Vector TractsToDWIImageFilter::GetItkVector(double point[3]) { itk::Vector itkVector; itkVector[0] = point[0]; itkVector[1] = point[1]; itkVector[2] = point[2]; return itkVector; } vnl_vector_fixed TractsToDWIImageFilter::GetVnlVector(double point[3]) { vnl_vector_fixed vnlVector; vnlVector[0] = point[0]; vnlVector[1] = point[1]; vnlVector[2] = point[2]; return vnlVector; } vnl_vector_fixed TractsToDWIImageFilter::GetVnlVector(Vector& vector) { vnl_vector_fixed vnlVector; vnlVector[0] = vector[0]; vnlVector[1] = vector[1]; vnlVector[2] = vector[2]; return vnlVector; } } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkConnectomicsDataView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkConnectomicsDataView.cpp index d089e8f2ee..b4cf3217e0 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkConnectomicsDataView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkConnectomicsDataView.cpp @@ -1,392 +1,370 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // ####### Blueberry includes ####### #include #include // ####### Qmitk includes ####### #include "QmitkConnectomicsDataView.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" //#include // Includes for image casting between ITK and MITK #include "mitkImageCast.h" #include "mitkITKImageImport.h" #include "mitkImageAccessByItk.h" const std::string QmitkConnectomicsDataView::VIEW_ID = "org.mitk.views.connectomicsdata"; QmitkConnectomicsDataView::QmitkConnectomicsDataView() -: QmitkFunctionality() -, m_Controls( 0 ) -, m_MultiWidget( NULL ) -, m_ConnectomicsNetworkCreator( mitk::ConnectomicsNetworkCreator::New() ) -, m_demomode( false ) -, m_currentIndex( 0 ) + : QmitkFunctionality() + , m_Controls( 0 ) + , m_MultiWidget( NULL ) + , m_ConnectomicsNetworkCreator( mitk::ConnectomicsNetworkCreator::New() ) + , m_demomode( false ) + , m_currentIndex( 0 ) { } QmitkConnectomicsDataView::~QmitkConnectomicsDataView() { } void QmitkConnectomicsDataView::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::QmitkConnectomicsDataViewControls; - m_Controls->setupUi( parent ); - - 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)) ); - } - - // GUI is different for developer and demo mode - m_demomode = true; - if( m_demomode ) - { - this->m_Controls->networkifyPushButton->show(); - this->m_Controls->networkifyPushButton->setText( "Create Network" ); - 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"); - } - else - { - this->m_Controls->networkifyPushButton->show(); - this->m_Controls->networkifyPushButton->setText( "Networkify" ); - 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"); - } - - this->WipeDisplay(); + // build up qt view, unless already done + if ( !m_Controls ) + { + // create GUI widgets from the Qt Designer's .ui file + m_Controls = new Ui::QmitkConnectomicsDataViewControls; + m_Controls->setupUi( parent ); + + 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)) ); + } + + // GUI is different for developer and demo mode + m_demomode = true; + if( m_demomode ) + { + this->m_Controls->networkifyPushButton->show(); + this->m_Controls->networkifyPushButton->setText( "Create Network" ); + 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"); + } + else + { + this->m_Controls->networkifyPushButton->show(); + this->m_Controls->networkifyPushButton->setText( "Networkify" ); + 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"); + } + + this->WipeDisplay(); } void QmitkConnectomicsDataView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { - m_MultiWidget = &stdMultiWidget; + m_MultiWidget = &stdMultiWidget; } void QmitkConnectomicsDataView::StdMultiWidgetNotAvailable() { - m_MultiWidget = NULL; + m_MultiWidget = NULL; } void QmitkConnectomicsDataView::WipeDisplay() { - m_Controls->lblWarning->setVisible( true ); - m_Controls->inputImageOneNameLabel->setText( mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_DASH ); - m_Controls->inputImageOneNameLabel->setVisible( false ); - m_Controls->inputImageOneLabel->setVisible( false ); - m_Controls->inputImageTwoNameLabel->setText( mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_DASH ); - m_Controls->inputImageTwoNameLabel->setVisible( false ); - m_Controls->inputImageTwoLabel->setVisible( false ); + m_Controls->lblWarning->setVisible( true ); + m_Controls->inputImageOneNameLabel->setText( mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_DASH ); + m_Controls->inputImageOneNameLabel->setVisible( false ); + m_Controls->inputImageOneLabel->setVisible( false ); + m_Controls->inputImageTwoNameLabel->setText( mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_DASH ); + m_Controls->inputImageTwoNameLabel->setVisible( false ); + m_Controls->inputImageTwoLabel->setVisible( false ); } void QmitkConnectomicsDataView::OnSelectionChanged( std::vector nodes ) { - this->WipeDisplay(); - - // Valid options are either - // 1 image (parcellation) - // - // 1 image (parcellation) - // 1 fiber bundle - // - // 1 network - if( nodes.size() > 2 ) - { - return; - } - - bool alreadyFiberBundleSelected( false ), alreadyImageSelected( false ), currentFormatUnknown( true ); - // iterate all selected objects, adjust warning visibility - for( std::vector::iterator it = nodes.begin(); - it != nodes.end(); - ++it ) - { - mitk::DataNode::Pointer node = *it; - currentFormatUnknown = true; - - if( node.IsNotNull() && dynamic_cast(node->GetData()) ) + this->WipeDisplay(); + + // Valid options are either + // 1 image (parcellation) + // + // 1 image (parcellation) + // 1 fiber bundle + // + // 1 network + if( nodes.size() < 2 ) { - currentFormatUnknown = false; - if( alreadyImageSelected ) - { - this->WipeDisplay(); return; - } - alreadyImageSelected = true; - m_Controls->lblWarning->setVisible( false ); - m_Controls->inputImageOneNameLabel->setText(node->GetName().c_str()); - m_Controls->inputImageOneNameLabel->setVisible( true ); - m_Controls->inputImageOneLabel->setVisible( true ); } - if( node.IsNotNull() && dynamic_cast(node->GetData()) ) + m_SelectedParcellationImage = NULL; + m_SelectedFiberBundles.clear(); + + bool alreadyImageSelected( false ), currentFormatUnknown( true ); + // iterate all selected objects, adjust warning visibility + for( std::vector::iterator it = nodes.begin(); + it != nodes.end(); + ++it ) { - currentFormatUnknown = false; - // a fiber bundle has to be in conjunction with a parcellation - if( nodes.size() != 2 || alreadyFiberBundleSelected ) - { - this->WipeDisplay(); - return; - } - alreadyFiberBundleSelected = true; - m_Controls->lblWarning->setVisible( false ); - m_Controls->inputImageTwoNameLabel->setText(node->GetName().c_str()); - m_Controls->inputImageTwoNameLabel->setVisible( true ); - m_Controls->inputImageTwoLabel->setVisible( true ); - } + mitk::DataNode::Pointer node = *it; + currentFormatUnknown = true; - { // network section - mitk::ConnectomicsNetwork* network = dynamic_cast( node->GetData() ); - if( node.IsNotNull() && network ) - { - currentFormatUnknown = false; - if( nodes.size() != 1 ) + if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { - // only valid option is a single network - this->WipeDisplay(); - return; + currentFormatUnknown = false; + if( alreadyImageSelected ) + { + this->WipeDisplay(); + return; + } + + m_SelectedParcellationImage = node; + + alreadyImageSelected = true; + m_Controls->lblWarning->setVisible( false ); + m_Controls->inputImageOneNameLabel->setText(node->GetName().c_str()); + m_Controls->inputImageOneNameLabel->setVisible( true ); + m_Controls->inputImageOneLabel->setVisible( true ); } - m_Controls->lblWarning->setVisible( false ); - m_Controls->inputImageOneNameLabel->setText(node->GetName().c_str()); - m_Controls->inputImageOneNameLabel->setVisible( true ); - m_Controls->inputImageOneLabel->setVisible( true ); - } - } // end network section + if( node.IsNotNull() && dynamic_cast(node->GetData()) ) + { + currentFormatUnknown = false; + // a fiber bundle has to be in conjunction with a parcellation + if( nodes.size() < 2 ) + { + this->WipeDisplay(); + return; + } + + m_SelectedFiberBundles.push_back(node); + m_Controls->lblWarning->setVisible( false ); + m_Controls->inputImageTwoNameLabel->setText(node->GetName().c_str()); + m_Controls->inputImageTwoNameLabel->setVisible( true ); + m_Controls->inputImageTwoLabel->setVisible( true ); + } - if ( currentFormatUnknown ) - { - this->WipeDisplay(); - return; - } - } // end for loop + { // network section + mitk::ConnectomicsNetwork* network = dynamic_cast( node->GetData() ); + if( node.IsNotNull() && network ) + { + currentFormatUnknown = false; + if( nodes.size() != 1 ) + { + // only valid option is a single network + this->WipeDisplay(); + return; + } + m_Controls->lblWarning->setVisible( false ); + m_Controls->inputImageOneNameLabel->setText(node->GetName().c_str()); + m_Controls->inputImageOneNameLabel->setVisible( true ); + m_Controls->inputImageOneLabel->setVisible( true ); + + } + } // end network section + + if ( currentFormatUnknown ) + { + this->WipeDisplay(); + return; + } + } // end for loop } void QmitkConnectomicsDataView::OnSyntheticNetworkComboBoxCurrentIndexChanged(int currentIndex) { - m_currentIndex = 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 ); + 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 QmitkConnectomicsDataView::OnSyntheticNetworkCreationPushButtonClicked() { - // warn if trying to create a very big network - // big network is a network with > 5000 nodes (estimate) - // this might fill up the memory to the point it freezes - int numberOfNodes( 0 ); - switch (m_currentIndex) { - case 0: - numberOfNodes = this->m_Controls->parameterOneSpinBox->value() - * this->m_Controls->parameterOneSpinBox->value() - * this->m_Controls->parameterOneSpinBox->value(); - break; - case 1: - numberOfNodes = this->m_Controls->parameterOneSpinBox->value(); - break; - case 2: - numberOfNodes = this->m_Controls->parameterOneSpinBox->value(); - break; - case 3: - // not implemented yet - break; - case 4: - // not implemented yet - break; - default: - break; - - } - - if( numberOfNodes > 5000 ) - { - QMessageBox msgBox; - msgBox.setText("Trying to generate very large network."); - msgBox.setIcon( QMessageBox::Warning ); - msgBox.setInformativeText("You are trying to generate a network with more than 5000 nodes, this is very resource intensive and might lead to program instability. Proceed with network generation?"); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::No); - int ret = msgBox.exec(); - - switch (ret) { - case QMessageBox::Yes: - // continue - break; - case QMessageBox::No: - // stop - return; - break; + // warn if trying to create a very big network + // big network is a network with > 5000 nodes (estimate) + // this might fill up the memory to the point it freezes + int numberOfNodes( 0 ); + switch (m_currentIndex) { + case 0: + numberOfNodes = this->m_Controls->parameterOneSpinBox->value() + * this->m_Controls->parameterOneSpinBox->value() + * this->m_Controls->parameterOneSpinBox->value(); + break; + case 1: + numberOfNodes = this->m_Controls->parameterOneSpinBox->value(); + break; + case 2: + numberOfNodes = this->m_Controls->parameterOneSpinBox->value(); + break; + case 3: + // not implemented yet + break; + case 4: + // not implemented yet + break; + default: + break; - default: - // should never be reached - break; } - } - - // proceed - 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 ); - if( generator->WasGenerationSuccessfull() ) - { - this->GetDefaultDataStorage()->Add( networkNode ); - } - else - { - MITK_WARN << "Problem occured during synthetic network generation."; - } - - return; -} -void QmitkConnectomicsDataView::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( numberOfNodes > 5000 ) + { + QMessageBox msgBox; + msgBox.setText("Trying to generate very large network."); + msgBox.setIcon( QMessageBox::Warning ); + msgBox.setInformativeText("You are trying to generate a network with more than 5000 nodes, this is very resource intensive and might lead to program instability. Proceed with network generation?"); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::No); + int ret = msgBox.exec(); + + switch (ret) { + case QMessageBox::Yes: + // continue + break; + case QMessageBox::No: + // stop + return; + break; + + default: + // should never be reached + break; + } + } - if (! ( nodes.size() == 2 ) ) - { - QMessageBox::information( NULL, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_CONNECTOMICS_CREATION, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_SELECTION_WARNING); - return; - } - mitk::DataNode* firstNode = nodes.front(); - mitk::DataNode* secondNode = nodes.at(1); - - if (!firstNode) - { - // Nothing selected. Inform the user and return - QMessageBox::information( NULL, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_CONNECTOMICS_CREATION, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_SELECTION_WARNING); - return; - } + // proceed + mitk::ConnectomicsSyntheticNetworkGenerator::Pointer generator = mitk::ConnectomicsSyntheticNetworkGenerator::New(); - // here we have a valid mitk::DataNode + 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 ); + if( generator->WasGenerationSuccessfull() ) + { + this->GetDefaultDataStorage()->Add( networkNode ); + } + else + { + MITK_WARN << "Problem occured during synthetic network generation."; + } - // a node itself is not very useful, we need its data item (the image) - mitk::BaseData* firstData = firstNode->GetData(); - mitk::BaseData* secondData = secondNode->GetData(); - if (firstData && secondData) - { - // test if this data item is an image or not (could also be a surface or something totally different) - mitk::Image* image = dynamic_cast( firstData ); - mitk::FiberBundleX* fiberBundle = dynamic_cast( secondData ); + return; +} - // check whether order was switched - if (! (image && fiberBundle) ) +void QmitkConnectomicsDataView::OnNetworkifyPushButtonClicked() +{ + if ( m_SelectedParcellationImage.IsNull() || m_SelectedFiberBundles.empty() ) { - image = dynamic_cast( secondData ); - fiberBundle = dynamic_cast( firstData ); + QMessageBox::information( NULL, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_CONNECTOMICS_CREATION, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_SELECTION_WARNING); + return; } - if (image && fiberBundle) + mitk::Image::Pointer image = dynamic_cast< mitk::Image* >(m_SelectedParcellationImage->GetData()); + for (int i=0; iSetSegmentation( image ); - m_ConnectomicsNetworkCreator->SetFiberBundle( fiberBundle ); - m_ConnectomicsNetworkCreator->CalculateCenterOfMass(); - m_ConnectomicsNetworkCreator->SetEndPointSearchRadius( 15 ); - 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::FiberBundleX* fiberBundle = dynamic_cast( m_SelectedFiberBundles.at(i)->GetData() ); + + m_ConnectomicsNetworkCreator= mitk::ConnectomicsNetworkCreator::New(); + m_ConnectomicsNetworkCreator->SetSegmentation( image ); + m_ConnectomicsNetworkCreator->SetFiberBundle( fiberBundle ); + m_ConnectomicsNetworkCreator->CalculateCenterOfMass(); + m_ConnectomicsNetworkCreator->SetEndPointSearchRadius( 15 ); + m_ConnectomicsNetworkCreator->CreateNetworkFromFibersAndSegmentation(); + mitk::DataNode::Pointer networkNode = mitk::DataNode::New(); + + //add network to datastorage + QString name(m_SelectedFiberBundles.at(i)->GetName().c_str()); + name += "_Connectome"; + networkNode->SetData( m_ConnectomicsNetworkCreator->GetNetwork() ); + networkNode->SetName( name.toStdString().c_str() ); + this->GetDefaultDataStorage()->Add( networkNode, m_SelectedParcellationImage ); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } - } - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkConnectomicsDataView.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkConnectomicsDataView.h index 1e184dff6e..6ef3a2d6fd 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkConnectomicsDataView.h +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkConnectomicsDataView.h @@ -1,104 +1,107 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkConnectomicsDataView_h #define QmitkConnectomicsDataView_h #include #include #include "ui_QmitkConnectomicsDataViewControls.h" #include "mitkConnectomicsNetworkCreator.h" #include "mitkConnectomicsNetworkMapper3D.h" // ####### ITK includes ####### #include /*! \brief QmitkConnectomicsDataView This view provides functionality for the generation of networks. Either from parcellation and fiber bundle or synthetically. \sa QmitkFunctionality \ingroup Functionalities */ class QmitkConnectomicsDataView : 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; QmitkConnectomicsDataView(); virtual ~QmitkConnectomicsDataView(); virtual void CreateQtPartControl(QWidget *parent); virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget); virtual void StdMultiWidgetNotAvailable(); protected slots: /// \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); 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::QmitkConnectomicsDataViewControls* m_Controls; QmitkStdMultiWidget* m_MultiWidget; - mitk::ConnectomicsNetworkCreator::Pointer m_ConnectomicsNetworkCreator; + mitk::ConnectomicsNetworkCreator::Pointer m_ConnectomicsNetworkCreator; - mitk::ConnectomicsNetworkMapper3D::Pointer m_NetworkMapper; + mitk::ConnectomicsNetworkMapper3D::Pointer m_NetworkMapper; + + mitk::DataNode::Pointer m_SelectedParcellationImage; + std::vector< mitk::DataNode::Pointer > m_SelectedFiberBundles; // 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/QmitkConnectomicsNetworkOperationsView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkConnectomicsNetworkOperationsView.cpp index f6528f5b15..cea47effc9 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkConnectomicsNetworkOperationsView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/Connectomics/QmitkConnectomicsNetworkOperationsView.cpp @@ -1,488 +1,481 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // ####### Blueberry includes ####### #include #include // ####### Qmitk includes ####### #include "QmitkConnectomicsNetworkOperationsView.h" #include "QmitkStdMultiWidget.h" // ####### Qt includes ####### #include // ####### ITK includes ####### #include // ####### MITK includes ####### #include #include "mitkConnectomicsSimulatedAnnealingManager.h" #include "mitkConnectomicsSimulatedAnnealingPermutationModularity.h" #include "mitkConnectomicsSimulatedAnnealingCostFunctionModularity.h" #include // Includes for image casting between ITK and MITK #include "mitkImageCast.h" #include "mitkITKImageImport.h" #include "mitkImageAccessByItk.h" const std::string QmitkConnectomicsNetworkOperationsView::VIEW_ID = "org.mitk.views.connectomicsnetworkoperations"; QmitkConnectomicsNetworkOperationsView::QmitkConnectomicsNetworkOperationsView() -: QmitkFunctionality() -, m_Controls( 0 ) -, m_MultiWidget( NULL ) -, m_demomode( false ) -, m_currentIndex( 0 ) + : QmitkFunctionality() + , m_Controls( 0 ) + , m_MultiWidget( NULL ) + , m_demomode( false ) + , m_currentIndex( 0 ) { } QmitkConnectomicsNetworkOperationsView::~QmitkConnectomicsNetworkOperationsView() { } void QmitkConnectomicsNetworkOperationsView::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::QmitkConnectomicsNetworkOperationsViewControls; - m_Controls->setupUi( parent ); - - QObject::connect( m_Controls->convertToRGBAImagePushButton, SIGNAL(clicked()), this, SLOT(OnConvertToRGBAImagePushButtonClicked()) ); - QObject::connect( (QObject*)( m_Controls->modularizePushButton ), SIGNAL(clicked()), this, SLOT(OnModularizePushButtonClicked()) ); - QObject::connect( (QObject*)( m_Controls->prunePushButton ), SIGNAL(clicked()), this, SLOT(OnPrunePushButtonClicked()) ); - QObject::connect( (QObject*)( m_Controls->createConnectivityMatrixImagePushButton ), SIGNAL(clicked()), this, SLOT(OnCreateConnectivityMatrixImagePushButtonClicked()) ); - } - - // GUI is different for developer and demo mode - m_demomode = true; - if( m_demomode ) - { - this->m_Controls->convertToRGBAImagePushButton->show(); - this->m_Controls->modularizePushButton->hide(); - this->m_Controls->pruneOptionsGroupBox->hide(); - } - else - { - this->m_Controls->convertToRGBAImagePushButton->show(); - this->m_Controls->modularizePushButton->show(); - this->m_Controls->pruneOptionsGroupBox->show(); - } - - this->WipeDisplay(); + // build up qt view, unless already done + if ( !m_Controls ) + { + // create GUI widgets from the Qt Designer's .ui file + m_Controls = new Ui::QmitkConnectomicsNetworkOperationsViewControls; + m_Controls->setupUi( parent ); + + QObject::connect( m_Controls->convertToRGBAImagePushButton, SIGNAL(clicked()), this, SLOT(OnConvertToRGBAImagePushButtonClicked()) ); + QObject::connect( (QObject*)( m_Controls->modularizePushButton ), SIGNAL(clicked()), this, SLOT(OnModularizePushButtonClicked()) ); + QObject::connect( (QObject*)( m_Controls->prunePushButton ), SIGNAL(clicked()), this, SLOT(OnPrunePushButtonClicked()) ); + QObject::connect( (QObject*)( m_Controls->createConnectivityMatrixImagePushButton ), SIGNAL(clicked()), this, SLOT(OnCreateConnectivityMatrixImagePushButtonClicked()) ); + } + + // GUI is different for developer and demo mode + m_demomode = true; + if( m_demomode ) + { + this->m_Controls->convertToRGBAImagePushButton->show(); + this->m_Controls->modularizePushButton->hide(); + this->m_Controls->pruneOptionsGroupBox->hide(); + } + else + { + this->m_Controls->convertToRGBAImagePushButton->show(); + this->m_Controls->modularizePushButton->show(); + this->m_Controls->pruneOptionsGroupBox->show(); + } + + this->WipeDisplay(); } void QmitkConnectomicsNetworkOperationsView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { - m_MultiWidget = &stdMultiWidget; + m_MultiWidget = &stdMultiWidget; } void QmitkConnectomicsNetworkOperationsView::StdMultiWidgetNotAvailable() { - m_MultiWidget = NULL; + m_MultiWidget = NULL; } void QmitkConnectomicsNetworkOperationsView::WipeDisplay() { - m_Controls->lblWarning->setVisible( true ); - m_Controls->inputImageOneNameLabel->setText( mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_DASH ); - m_Controls->inputImageOneNameLabel->setVisible( false ); - m_Controls->inputImageOneLabel->setVisible( false ); + m_Controls->lblWarning->setVisible( true ); + m_Controls->inputImageOneNameLabel->setText( mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_DASH ); + m_Controls->inputImageOneNameLabel->setVisible( false ); + m_Controls->inputImageOneLabel->setVisible( false ); } void QmitkConnectomicsNetworkOperationsView::OnSelectionChanged( std::vector nodes ) { - this->WipeDisplay(); - - // Valid options are either - if( nodes.size() > 2 ) - { - return; - } - - bool currentFormatUnknown(true), alreadyImageSelected(false); + 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; - currentFormatUnknown = true; - - if( node.IsNotNull() && dynamic_cast(node->GetData()) ) + // Valid options are either + if( nodes.size() > 2 ) { - currentFormatUnknown = false; - if( alreadyImageSelected ) - { - this->WipeDisplay(); return; - } - alreadyImageSelected = true; - m_Controls->lblWarning->setVisible( false ); - m_Controls->inputImageOneNameLabel->setText(node->GetName().c_str()); - m_Controls->inputImageOneNameLabel->setVisible( true ); - m_Controls->inputImageOneLabel->setVisible( true ); } - if( node.IsNotNull() ) - { // network section - mitk::ConnectomicsNetwork* network = dynamic_cast( node->GetData() ); - if( network ) - { - currentFormatUnknown = false; - if( nodes.size() != 1 ) + bool currentFormatUnknown(true), alreadyImageSelected(false); + + // iterate all selected objects, adjust warning visibility + for( std::vector::iterator it = nodes.begin(); + it != nodes.end(); + ++it ) + { + mitk::DataNode::Pointer node = *it; + currentFormatUnknown = true; + + if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { - // only valid option is a single network - this->WipeDisplay(); - return; + currentFormatUnknown = false; + if( alreadyImageSelected ) + { + this->WipeDisplay(); + return; + } + alreadyImageSelected = true; + m_Controls->lblWarning->setVisible( false ); + m_Controls->inputImageOneNameLabel->setText(node->GetName().c_str()); + m_Controls->inputImageOneNameLabel->setVisible( true ); + m_Controls->inputImageOneLabel->setVisible( true ); } - m_Controls->lblWarning->setVisible( false ); - m_Controls->inputImageOneNameLabel->setText(node->GetName().c_str()); - m_Controls->inputImageOneNameLabel->setVisible( true ); - m_Controls->inputImageOneLabel->setVisible( true ); - - } - } // end network section - if ( currentFormatUnknown ) - { - this->WipeDisplay(); - return; - } - } // end for loop + if( node.IsNotNull() ) + { // network section + mitk::ConnectomicsNetwork* network = dynamic_cast( node->GetData() ); + if( network ) + { + currentFormatUnknown = false; + if( nodes.size() != 1 ) + { + // only valid option is a single network + this->WipeDisplay(); + return; + } + m_Controls->lblWarning->setVisible( false ); + m_Controls->inputImageOneNameLabel->setText(node->GetName().c_str()); + m_Controls->inputImageOneNameLabel->setVisible( true ); + m_Controls->inputImageOneLabel->setVisible( true ); + + } + } // end network section + + if ( currentFormatUnknown ) + { + this->WipeDisplay(); + return; + } + } // end for loop } void QmitkConnectomicsNetworkOperationsView::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, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_ONLY_PARCELLATION_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::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, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_ONLY_PARCELLATION_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) { - 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(); + // 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(); + } + else + { + QMessageBox::information( NULL, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_CONNECTOMICS, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_ONLY_PARCELLATION_SELECTION_WARNING); + return; + } } else { - QMessageBox::information( NULL, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_CONNECTOMICS, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_ONLY_PARCELLATION_SELECTION_WARNING); - return; + QMessageBox::information( NULL, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_CONNECTOMICS, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_ONLY_PARCELLATION_SELECTION_WARNING); + return; } - } - else - { - QMessageBox::information( NULL, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_CONNECTOMICS, mitk::ConnectomicsConstantsManager::CONNECTOMICS_GUI_ONLY_PARCELLATION_SELECTION_WARNING); - return; - } } template < typename TPixel, unsigned int VImageDimension > void QmitkConnectomicsNetworkOperationsView::TurnIntoRGBA( itk::Image* inputImage) { - typedef itk::RGBAPixel< unsigned char > RGBAPixelType; - typedef itk::Image< TPixel, VImageDimension > TemplateImageType; - typedef itk::Image< RGBAPixelType, VImageDimension > RGBAImageType; + 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()); + itk::ImageRegionIterator it_inputImage(inputImage, inputImage->GetLargestPossibleRegion()); - TPixel minimumValue, maximumValue; + TPixel minimumValue, maximumValue; - it_inputImage.GoToBegin(); - maximumValue = minimumValue = it_inputImage.Value(); + it_inputImage.GoToBegin(); + maximumValue = minimumValue = it_inputImage.Value(); - for(it_inputImage.GoToBegin(); !it_inputImage.IsAtEnd(); ++it_inputImage) - { - if ( it_inputImage.Value() < minimumValue ) + for(it_inputImage.GoToBegin(); !it_inputImage.IsAtEnd(); ++it_inputImage) { - minimumValue = it_inputImage.Value(); - } - else - { - if ( it_inputImage.Value() > maximumValue ) - { - maximumValue = it_inputImage.Value(); - } + 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 ); + int range = int ( maximumValue - minimumValue ); //needs to be castable to int + int offset = int ( minimumValue ); - if ( range < 0 ) //error - { - return; - } + if ( range < 0 ) //error + { + return; + } - std::vector< unsigned int > histogram; - histogram.resize( range + 1, 0 ); + 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; - } + 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 + 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 ); + //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 ) + for( int index = 0; index <= range; index++ ) { - gapCounter++; //if the label is empty, increase gapCounter + if( histogram[ index ] == 0 ) + { + gapCounter++; //if the label is empty, increase gapCounter + } + else + { + subtractionStorage[ index ] = TPixel ( gapCounter ); + } } - else + + //remove gaps from label image + for(it_inputImage.GoToBegin(); !it_inputImage.IsAtEnd(); ++it_inputImage) { - subtractionStorage[ index ] = TPixel ( gapCounter ); + it_inputImage.Value() = it_inputImage.Value() - subtractionStorage[int ( it_inputImage.Value() ) - offset ]; } - } - - //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() ) - offset ]; - } - // create colour vector - std::vector< RGBAPixelType > lookupTable; + // create colour vector + std::vector< RGBAPixelType > lookupTable; - { - RGBAPixelType backgroundColour; - for( int elementIndex = 0; elementIndex < 4; ++elementIndex ) { - backgroundColour.SetElement( elementIndex, 0 ); - } + RGBAPixelType backgroundColour; + for( int elementIndex = 0; elementIndex < 4; ++elementIndex ) + { + backgroundColour.SetElement( elementIndex, 0 ); + } - lookupTable.push_back( backgroundColour ); + 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 ); + 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(); + // create RGBA image + typename RGBAImageType::Pointer rgbaImage = RGBAImageType::New(); - rgbaImage->SetRegions(inputImage->GetLargestPossibleRegion().GetSize()); - rgbaImage->SetSpacing(inputImage->GetSpacing()); - rgbaImage->SetOrigin(inputImage->GetOrigin()); - rgbaImage->Allocate(); + 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()); + //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() ) - offset ]; - } + for(it_inputImage.GoToBegin(), it_rgbaImage.GoToBegin(); !it_inputImage.IsAtEnd(); ++it_inputImage, ++it_rgbaImage) + { + it_rgbaImage.Value() = lookupTable[ int ( it_inputImage.Value() ) - offset ]; + } - mitk::Image::Pointer mitkRGBAImage = mitk::ImportItkImage( rgbaImage )->Clone(); + mitk::Image::Pointer mitkRGBAImage = mitk::ImportItkImage( rgbaImage )->Clone(); - 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 ); + 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 QmitkConnectomicsNetworkOperationsView::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()) ) + std::vector nodes = this->GetDataManagerSelection(); + if ( nodes.empty() ) { - return; + QMessageBox::information( NULL, "Modularization calculation", "Please select exactly one network."); + return; } + for( std::vector::iterator it = nodes.begin(); + it != nodes.end(); + ++it ) { - mitk::ConnectomicsNetwork* network = dynamic_cast( node->GetData() ); - if( node.IsNotNull() && network ) - { + mitk::DataNode::Pointer node = *it; + + if( node.IsNotNull() && dynamic_cast(node->GetData()) ) + { + return; + } - typedef mitk::ConnectomicsSimulatedAnnealingPermutationModularity::ToModuleMapType MappingType; + { + mitk::ConnectomicsNetwork* network = dynamic_cast( node->GetData() ); + if( node.IsNotNull() && network ) + { - int depthOfModuleRecursive( 2 ); - double startTemperature( 2.0 ); - double stepSize( 4.0 ); + typedef mitk::ConnectomicsSimulatedAnnealingPermutationModularity::ToModuleMapType MappingType; - 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(); + int depthOfModuleRecursive( 2 ); + double startTemperature( 2.0 ); + double stepSize( 4.0 ); - permutation->SetCostFunction( costFunction.GetPointer() ); - permutation->SetNetwork( connectomicsNetwork ); - permutation->SetDepth( depthOfModuleRecursive ); - permutation->SetStepSize( stepSize ); + 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(); - manager->SetPermutation( permutation.GetPointer() ); + permutation->SetCostFunction( costFunction.GetPointer() ); + permutation->SetNetwork( connectomicsNetwork ); + permutation->SetDepth( depthOfModuleRecursive ); + permutation->SetStepSize( stepSize ); - manager->RunSimulatedAnnealing( startTemperature, stepSize ); + manager->SetPermutation( permutation.GetPointer() ); - MappingType mapping = permutation->GetMapping(); + manager->RunSimulatedAnnealing( startTemperature, stepSize ); - MappingType::iterator iter = mapping.begin(); - MappingType::iterator end = mapping.end(); + MappingType mapping = permutation->GetMapping(); - 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++; - } + MappingType::iterator iter = mapping.begin(); + MappingType::iterator end = mapping.end(); - 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 ) ; + 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++; + } - return; - } + 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; + } + } } - } } void QmitkConnectomicsNetworkOperationsView::OnPrunePushButtonClicked() { - std::vector nodes = this->GetDataManagerSelection(); - if ( nodes.empty() ) - { - QMessageBox::information( NULL, "Network pruning", "Please select one or more networks."); - return; - } - - for( std::vector::iterator it = nodes.begin(); - it != nodes.end(); - ++it ) - { - mitk::DataNode::Pointer node = *it; - - if( node.IsNotNull() && dynamic_cast(node->GetData()) ) + std::vector nodes = this->GetDataManagerSelection(); + if ( nodes.empty() ) { - return; + QMessageBox::information( NULL, "Network pruning", "Please select one or more networks."); + return; } + for( std::vector::iterator it = nodes.begin(); + it != nodes.end(); + ++it ) { - mitk::ConnectomicsNetwork* network = dynamic_cast( node->GetData() ); - if( node.IsNotNull() && network ) - { - // Edge pruning will also do node pruning - network->PruneEdgesBelowWeight( this->m_Controls->pruneEdgeWeightSpinBox->value() ); - } + mitk::DataNode::Pointer node = *it; + + if( node.IsNotNull() && dynamic_cast(node->GetData()) ) + { + return; + } + + { + mitk::ConnectomicsNetwork* network = dynamic_cast( node->GetData() ); + if( node.IsNotNull() && network ) + { + // Edge pruning will also do node pruning + network->PruneEdgesBelowWeight( this->m_Controls->pruneEdgeWeightSpinBox->value() ); + } + } } - } } void QmitkConnectomicsNetworkOperationsView::OnCreateConnectivityMatrixImagePushButtonClicked() { - std::vector nodes = this->GetDataManagerSelection(); - if ( nodes.empty() ) - { - QMessageBox::information( NULL, "Connectivity Matrix Image creation", "Please select one or more networks."); - return; - } - - for( std::vector::iterator it = nodes.begin(); - it != nodes.end(); - ++it ) - { - mitk::DataNode::Pointer node = *it; - - if( node.IsNotNull() && dynamic_cast(node->GetData()) ) + std::vector nodes = this->GetDataManagerSelection(); + if ( nodes.empty() ) { - return; + QMessageBox::information( NULL, "Connectivity Matrix Image creation", "Please select one or more networks."); + return; } + for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { - mitk::ConnectomicsNetwork* network = dynamic_cast( node->GetData() ); - if( node.IsNotNull() && network ) - { - itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::Pointer filter = itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::New(); - filter->SetInputNetwork( network ); - filter->SetBinaryConnectivity(m_Controls->binaryCheckBox->isChecked()); - filter->SetRescaleConnectivity(m_Controls->rescaleCheckBox->isChecked()); - filter->Update(); - - mitk::Image::Pointer connectivityMatrixImage = mitk::ImportItkImage( filter->GetOutput())->Clone(); - mitk::DataNode::Pointer connectivityMatrixImageNode = mitk::DataNode::New(); - connectivityMatrixImageNode->SetData ( connectivityMatrixImage ); - connectivityMatrixImageNode->SetName( "Connectivity matrix" ); - this->GetDefaultDataStorage()->Add(connectivityMatrixImageNode, node ); - } + mitk::DataNode::Pointer node = *it; + + if( node.IsNotNull() && dynamic_cast( node->GetData() ) ) + { + mitk::ConnectomicsNetwork* network = dynamic_cast( node->GetData() ); + itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::Pointer filter = itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::New(); + filter->SetInputNetwork( network ); + filter->SetBinaryConnectivity(m_Controls->binaryCheckBox->isChecked()); + filter->SetRescaleConnectivity(m_Controls->rescaleCheckBox->isChecked()); + filter->Update(); + + mitk::Image::Pointer connectivityMatrixImage = mitk::ImportItkImage( filter->GetOutput())->Clone(); + mitk::DataNode::Pointer connectivityMatrixImageNode = mitk::DataNode::New(); + connectivityMatrixImageNode->SetData ( connectivityMatrixImage ); + QString name(node->GetName().c_str()); + name += "_ConnectivityMatrix"; + connectivityMatrixImageNode->SetName( name.toStdString().c_str() ); + this->GetDefaultDataStorage()->Add(connectivityMatrixImageNode, node ); + } } - } -} \ No newline at end of file +}