diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.cpp b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.cpp index 3ffb27fb47..374ea1315f 100644 --- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.cpp @@ -1,254 +1,254 @@ /*=================================================================== 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 "itkFibersFromPlanarFiguresFilter.h" #define _USE_MATH_DEFINES #include // MITK #include #include #include #include #include #include #include #include #include // ITK #include #include #include #include // MISC #include #include #include #include namespace itk{ FibersFromPlanarFiguresFilter::FibersFromPlanarFiguresFilter() : m_Density(1000) , m_FiberSampling(1) , m_Tension(0) , m_Continuity(0) , m_Bias(0) , m_FiberDistribution(DISTRIBUTE_UNIFORM) , m_Variance(0.1) { } FibersFromPlanarFiguresFilter::~FibersFromPlanarFiguresFilter() { } void FibersFromPlanarFiguresFilter::GeneratePoints() { Statistics::MersenneTwisterRandomVariateGenerator::Pointer randGen = Statistics::MersenneTwisterRandomVariateGenerator::New(); randGen->SetSeed((unsigned int)0); m_2DPoints.clear(); int count = 0; while (count < m_Density) { mitk::Vector2D p; switch (m_FiberDistribution) { case DISTRIBUTE_GAUSSIAN: p[0] = randGen->GetNormalVariate(0, m_Variance); p[1] = randGen->GetNormalVariate(0, m_Variance); break; default: p[0] = randGen->GetUniformVariate(-1, 1); p[1] = randGen->GetUniformVariate(-1, 1); } if (sqrt(p[0]*p[0]+p[1]*p[1]) <= 1) { m_2DPoints.push_back(p); count++; } } } // perform global tracking void FibersFromPlanarFiguresFilter::GenerateData() { // check if enough fiducials are available for (int i=0; i m_VtkCellArray = vtkSmartPointer::New(); vtkSmartPointer m_VtkPoints = vtkSmartPointer::New(); vector< mitk::PlanarEllipse::Pointer > bundle = m_Fiducials.at(i); vector< unsigned int > fliplist; if (i container = vtkSmartPointer::New(); mitk::PlanarEllipse::Pointer figure = bundle.at(0); mitk::Point2D p0 = figure->GetControlPoint(0); mitk::Point2D p1 = figure->GetControlPoint(1); mitk::Point2D p2 = figure->GetControlPoint(2); mitk::Point2D p3 = figure->GetControlPoint(3); - float r1 = p0.EuclideanDistanceTo(p1); - float r2 = p0.EuclideanDistanceTo(p2); + double r1 = p0.EuclideanDistanceTo(p1); + double r2 = p0.EuclideanDistanceTo(p2); mitk::Vector2D eDir = p1-p0; eDir.Normalize(); mitk::Vector2D tDir = p3-p0; tDir.Normalize(); // apply twist - vnl_matrix_fixed tRot; + vnl_matrix_fixed tRot; tRot[0][0] = tDir[0]; tRot[1][1] = tRot[0][0]; tRot[1][0] = sin(acos(tRot[0][0])); tRot[0][1] = -tRot[1][0]; if (tDir[1]<0) tRot.inplace_transpose(); m_2DPoints[j].SetVnlVector(tRot*m_2DPoints[j].GetVnlVector()); // apply new ellipse shape - vnl_vector_fixed< float, 2 > newP; + vnl_vector_fixed< double, 2 > newP; newP[0] = m_2DPoints.at(j)[0]; newP[1] = m_2DPoints.at(j)[1]; - float alpha = acos(eDir[0]); + double alpha = acos(eDir[0]); if (eDir[1]>0) alpha = 2*M_PI-alpha; - vnl_matrix_fixed eRot; + vnl_matrix_fixed eRot; eRot[0][0] = cos(alpha); eRot[1][1] = eRot[0][0]; eRot[1][0] = sin(alpha); eRot[0][1] = -eRot[1][0]; newP = eRot*newP; newP[0] *= r1; newP[1] *= r2; newP = eRot.transpose()*newP; p0[0] += newP[0]; p0[1] += newP[1]; const mitk::Geometry2D* pfgeometry = figure->GetGeometry2D(); const mitk::PlaneGeometry* planeGeo = dynamic_cast(pfgeometry); mitk::Point3D w, wc; planeGeo->Map(p0, w); wc = figure->GetWorldControlPoint(0); vtkIdType id = m_VtkPoints->InsertNextPoint(w.GetDataPointer()); container->GetPointIds()->InsertNextId(id); - vnl_vector_fixed< float, 3 > n = planeGeo->GetNormalVnl(); + vnl_vector_fixed< double, 3 > n = planeGeo->GetNormalVnl(); for (int k=1; kGetControlPoint(0); p1 = figure->GetControlPoint(1); p2 = figure->GetControlPoint(2); p3 = figure->GetControlPoint(3); r1 = p0.EuclideanDistanceTo(p1); r2 = p0.EuclideanDistanceTo(p2); eDir = p1-p0; eDir.Normalize(); mitk::Vector2D tDir2 = p3-p0; tDir2.Normalize(); mitk::Vector2D temp; temp.SetVnlVector(tRot.transpose() * tDir2.GetVnlVector()); // apply twist tRot[0][0] = tDir[0]*tDir2[0] + tDir[1]*tDir2[1]; tRot[1][1] = tRot[0][0]; tRot[1][0] = sin(acos(tRot[0][0])); tRot[0][1] = -tRot[1][0]; if (temp[1]<0) tRot.inplace_transpose(); m_2DPoints[j].SetVnlVector(tRot*m_2DPoints[j].GetVnlVector()); tDir = tDir2; // apply new ellipse shape newP[0] = m_2DPoints.at(j)[0]; newP[1] = m_2DPoints.at(j)[1]; // calculate normal mitk::Geometry2D* pfgeometry = const_cast(figure->GetGeometry2D()); mitk::PlaneGeometry* planeGeo = dynamic_cast(pfgeometry); mitk::Vector3D perp = wc-planeGeo->ProjectPointOntoPlane(wc); perp.Normalize(); - vnl_vector_fixed< float, 3 > n2 = planeGeo->GetNormalVnl(); + vnl_vector_fixed< double, 3 > n2 = planeGeo->GetNormalVnl(); wc = figure->GetWorldControlPoint(0); // is flip needed? if (dot_product(perp.GetVnlVector(),n2)>0 && dot_product(n,n2)<=0.00001) newP[0] *= -1; if (fliplist.at(k)>0) newP[0] *= -1; n = n2; alpha = acos(eDir[0]); if (eDir[1]>0) alpha = 2*M_PI-alpha; eRot[0][0] = cos(alpha); eRot[1][1] = eRot[0][0]; eRot[1][0] = sin(alpha); eRot[0][1] = -eRot[1][0]; newP = eRot*newP; newP[0] *= r1; newP[1] *= r2; newP = eRot.transpose()*newP; p0[0] += newP[0]; p0[1] += newP[1]; mitk::Point3D w; planeGeo->Map(p0, w); vtkIdType id = m_VtkPoints->InsertNextPoint(w.GetDataPointer()); container->GetPointIds()->InsertNextId(id); } m_VtkCellArray->InsertNextCell(container); } vtkSmartPointer fiberPolyData = vtkSmartPointer::New(); fiberPolyData->SetPoints(m_VtkPoints); fiberPolyData->SetLines(m_VtkCellArray); mitk::FiberBundleX::Pointer mitkFiberBundle = mitk::FiberBundleX::New(fiberPolyData); mitkFiberBundle->DoFiberSmoothing(m_FiberSampling, m_Tension, m_Continuity, m_Bias); m_FiberBundles.push_back(mitkFiberBundle); } } } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkTbssRoiAnalysisWidget.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkTbssRoiAnalysisWidget.cpp index a8ec051b03..7ecd28be54 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkTbssRoiAnalysisWidget.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkTbssRoiAnalysisWidget.cpp @@ -1,963 +1,963 @@ /*=================================================================== 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 "QmitkTbssRoiAnalysisWidget.h" #include #include #include #include QmitkTbssRoiAnalysisWidget::QmitkTbssRoiAnalysisWidget( QWidget * parent ) : QmitkPlotWidget(parent) { m_PlotPicker = new QwtPlotPicker(m_Plot->canvas()); m_PlotPicker->setStateMachine(new QwtPickerDragPointMachine()); m_PlotPicker->setTrackerMode(QwtPicker::ActiveOnly); m_PlottingFiberBundle = false; } void QmitkTbssRoiAnalysisWidget::DoPlotFiberBundles(mitk::FiberBundleX *fib, mitk::Image* img, mitk::PlanarFigure* startRoi, mitk::PlanarFigure* endRoi, bool avg, int number) { TractContainerType tracts = CreateTracts(fib, startRoi, endRoi); TractContainerType resampledTracts = ParameterizeTracts(tracts, number); // Now we have the resampled tracts. Next we should use these points to read out the values PlotFiberBundles(resampledTracts, img, avg); m_CurrentTracts = resampledTracts; } TractContainerType QmitkTbssRoiAnalysisWidget::CreateTracts(mitk::FiberBundleX *fib, mitk::PlanarFigure *startRoi, mitk::PlanarFigure *endRoi) { mitk::PlaneGeometry* startGeometry2D = dynamic_cast( const_cast(startRoi->GetGeometry2D()) ); mitk::PlaneGeometry* endGeometry2D = dynamic_cast( const_cast(endRoi->GetGeometry2D()) ); mitk::Point3D startCenter = startRoi->GetWorldControlPoint(0); //center Point of start roi mitk::Point3D endCenter = endRoi->GetWorldControlPoint(0); //center Point of end roi mitk::FiberBundleX::Pointer inStart = fib->ExtractFiberSubset(startRoi); mitk::FiberBundleX::Pointer inBoth = inStart->ExtractFiberSubset(endRoi); int num = inBoth->GetNumFibers(); TractContainerType tracts; vtkSmartPointer fiberPolyData = inBoth->GetFiberPolyData(); vtkCellArray* lines = fiberPolyData->GetLines(); lines->InitTraversal(); // Now find out for each fiber which ROI is encountered first. If this is the startRoi, the direction is ok // Otherwise the plot should be in the reverse direction for( int fiberID( 0 ); fiberID < num; fiberID++ ) { vtkIdType numPointsInCell(0); vtkIdType* pointsInCell(NULL); lines->GetNextCell ( numPointsInCell, pointsInCell ); int startId = 0; int endId = 0; - float minDistStart = std::numeric_limits::max(); - float minDistEnd = std::numeric_limits::max(); + mitk::ScalarType minDistStart = std::numeric_limits::max(); + mitk::ScalarType minDistEnd = std::numeric_limits::max(); for( int pointInCellID( 0 ); pointInCellID < numPointsInCell ; pointInCellID++) { - double *p = fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] ); + mitk::ScalarType *p = fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] ); mitk::Point3D point; point[0] = p[0]; point[1] = p[1]; point[2] = p[2]; - float distanceToStart = point.EuclideanDistanceTo(startCenter); - float distanceToEnd = point.EuclideanDistanceTo(endCenter); + mitk::ScalarType distanceToStart = point.EuclideanDistanceTo(startCenter); + mitk::ScalarType distanceToEnd = point.EuclideanDistanceTo(endCenter); if(distanceToStart < minDistStart) { minDistStart = distanceToStart; startId = pointInCellID; } if(distanceToEnd < minDistEnd) { minDistEnd = distanceToEnd; endId = pointInCellID; } } /* We found the start and end points of of the part that should be plottet for the current fiber. now we need to plot them. If the endId is smaller than the startId the plot order must be reversed*/ TractType singleTract; PointType point; if(startId < endId) { // Calculate the intersection of the ROI with the startRoi and decide if the startId is part of the roi or must be cut of - double *p = fiberPolyData->GetPoint( pointsInCell[ startId ] ); + mitk::ScalarType *p = fiberPolyData->GetPoint( pointsInCell[ startId ] ); mitk::Vector3D p0; p0[0] = p[0]; p0[1] = p[1]; p0[2] = p[2]; p = fiberPolyData->GetPoint( pointsInCell[ startId+1 ] ); mitk::Vector3D p1; p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2]; // Check if p and p2 are both on the same side of the plane mitk::Vector3D normal = startGeometry2D->GetNormal(); mitk::Point3D pStart; pStart[0] = p0[0]; pStart[1] = p0[1]; pStart[2] = p0[2]; mitk::Point3D pSecond; pSecond[0] = p1[0]; pSecond[1] = p1[1]; pSecond[2] = p1[2]; bool startOnPositive = startGeometry2D->IsAbove(pStart); bool secondOnPositive = startGeometry2D->IsAbove(pSecond); mitk::Vector3D onPlane; onPlane[0] = startCenter[0]; onPlane[1] = startCenter[1]; onPlane[2] = startCenter[2]; if(! (secondOnPositive ^ startOnPositive) ) { /* startId and startId+1 lie on the same side of the plane, so we need need startId-1 to calculate the intersection with the planar figure*/ p = fiberPolyData->GetPoint( pointsInCell[ startId-1 ] ); p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2]; } - double d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal ); + mitk::ScalarType d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal ); mitk::Vector3D newPoint = (p0-p1); point[0] = d*newPoint[0] + p0[0]; point[1] = d*newPoint[1] + p0[1]; point[2] = d*newPoint[2] + p0[2]; singleTract.push_back(point); if(! (secondOnPositive ^ startOnPositive) ) { /* StartId and startId+1 lie on the same side of the plane so startId is also part of the ROI*/ - double *start = fiberPolyData->GetPoint( pointsInCell[startId] ); + mitk::ScalarType *start = fiberPolyData->GetPoint( pointsInCell[startId] ); point[0] = start[0]; point[1] = start[1]; point[2] = start[2]; singleTract.push_back(point); } for( int pointInCellID( startId+1 ); pointInCellID < endId ; pointInCellID++) { // push back point - double *p = fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] ); + mitk::ScalarType *p = fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] ); point[0] = p[0]; point[1] = p[1]; point[2] = p[2]; singleTract.push_back( point ); } /* endId must be included if endId and endId-1 lie on the same side of the plane defined by endRoi*/ p = fiberPolyData->GetPoint( pointsInCell[ endId ] ); p0[0] = p[0]; p0[1] = p[1]; p0[2] = p[2]; p = fiberPolyData->GetPoint( pointsInCell[ endId-1 ] ); p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2]; mitk::Point3D pLast; pLast[0] = p0[0]; pLast[1] = p0[1]; pLast[2] = p0[2]; mitk::Point3D pBeforeLast; pBeforeLast[0] = p1[0]; pBeforeLast[1] = p1[1]; pBeforeLast[2] = p1[2]; normal = endGeometry2D->GetNormal(); bool lastOnPositive = endGeometry2D->IsAbove(pLast); bool secondLastOnPositive = endGeometry2D->IsAbove(pBeforeLast); onPlane[0] = endCenter[0]; onPlane[1] = endCenter[1]; onPlane[2] = endCenter[2]; if(! (lastOnPositive ^ secondLastOnPositive) ) { /* endId and endId-1 lie on the same side of the plane, so we need need endId+1 to calculate the intersection with the planar figure. this should exist since we know that the fiber crosses the planar figure endId is also part of the tract and can be inserted here */ p = fiberPolyData->GetPoint( pointsInCell[ endId ] ); point[0] = p[0]; point[1] = p[1]; point[2] = p[2]; singleTract.push_back( point ); p = fiberPolyData->GetPoint( pointsInCell[ endId+1 ] ); } d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal ); newPoint = (p0-p1); point[0] = d*newPoint[0] + p0[0]; point[1] = d*newPoint[1] + p0[1]; point[2] = d*newPoint[2] + p0[2]; singleTract.push_back(point); } else{ // Calculate the intersection of the ROI with the startRoi and decide if the startId is part of the roi or must be cut of - double *p = fiberPolyData->GetPoint( pointsInCell[ startId ] ); + mitk::ScalarType *p = fiberPolyData->GetPoint( pointsInCell[ startId ] ); mitk::Vector3D p0; p0[0] = p[0]; p0[1] = p[1]; p0[2] = p[2]; p = fiberPolyData->GetPoint( pointsInCell[ startId-1 ] ); mitk::Vector3D p1; p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2]; // Check if p and p2 are both on the same side of the plane mitk::Vector3D normal = startGeometry2D->GetNormal(); mitk::Point3D pStart; pStart[0] = p0[0]; pStart[1] = p0[1]; pStart[2] = p0[2]; mitk::Point3D pSecond; pSecond[0] = p1[0]; pSecond[1] = p1[1]; pSecond[2] = p1[2]; bool startOnPositive = startGeometry2D->IsAbove(pStart); bool secondOnPositive = startGeometry2D->IsAbove(pSecond); mitk::Vector3D onPlane; onPlane[0] = startCenter[0]; onPlane[1] = startCenter[1]; onPlane[2] = startCenter[2]; if(! (secondOnPositive ^ startOnPositive) ) { /* startId and startId+1 lie on the same side of the plane, so we need need startId-1 to calculate the intersection with the planar figure*/ p = fiberPolyData->GetPoint( pointsInCell[ startId-1 ] ); p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2]; } - double d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal ); + mitk::ScalarType d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal ); mitk::Vector3D newPoint = (p0-p1); point[0] = d*newPoint[0] + p0[0]; point[1] = d*newPoint[1] + p0[1]; point[2] = d*newPoint[2] + p0[2]; singleTract.push_back(point); if(! (secondOnPositive ^ startOnPositive) ) { /* StartId and startId+1 lie on the same side of the plane so startId is also part of the ROI*/ - double *start = fiberPolyData->GetPoint( pointsInCell[startId] ); + mitk::ScalarType *start = fiberPolyData->GetPoint( pointsInCell[startId] ); point[0] = start[0]; point[1] = start[1]; point[2] = start[2]; singleTract.push_back(point); } for( int pointInCellID( startId-1 ); pointInCellID > endId ; pointInCellID--) { // push back point - double *p = fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] ); + mitk::ScalarType *p = fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] ); point[0] = p[0]; point[1] = p[1]; point[2] = p[2]; singleTract.push_back( point ); } /* endId must be included if endId and endI+1 lie on the same side of the plane defined by endRoi*/ p = fiberPolyData->GetPoint( pointsInCell[ endId ] ); p0[0] = p[0]; p0[1] = p[1]; p0[2] = p[2]; p = fiberPolyData->GetPoint( pointsInCell[ endId+1 ] ); p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2]; mitk::Point3D pLast; pLast[0] = p0[0]; pLast[1] = p0[1]; pLast[2] = p0[2]; mitk::Point3D pBeforeLast; pBeforeLast[0] = p1[0]; pBeforeLast[1] = p1[1]; pBeforeLast[2] = p1[2]; bool lastOnPositive = endGeometry2D->IsAbove(pLast); bool secondLastOnPositive = endGeometry2D->IsAbove(pBeforeLast); normal = endGeometry2D->GetNormal(); onPlane[0] = endCenter[0]; onPlane[1] = endCenter[1]; onPlane[2] = endCenter[2]; if(! (lastOnPositive ^ secondLastOnPositive) ) { /* endId and endId+1 lie on the same side of the plane, so we need need endId-1 to calculate the intersection with the planar figure. this should exist since we know that the fiber crosses the planar figure endId is also part of the tract and can be inserted here */ p = fiberPolyData->GetPoint( pointsInCell[ endId ] ); point[0] = p[0]; point[1] = p[1]; point[2] = p[2]; singleTract.push_back( point ); p = fiberPolyData->GetPoint( pointsInCell[ endId-1 ] ); } d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal ); newPoint = (p0-p1); point[0] = d*newPoint[0] + p0[0]; point[1] = d*newPoint[1] + p0[1]; point[2] = d*newPoint[2] + p0[2]; singleTract.push_back(point); } tracts.push_back(singleTract); } return tracts; } void QmitkTbssRoiAnalysisWidget::PlotFiberBetweenRois(mitk::FiberBundleX *fib, mitk::Image* img, mitk::PlanarFigure* startRoi, mitk::PlanarFigure* endRoi, bool avg, int number) { if(fib == NULL || img == NULL || startRoi == NULL || endRoi == NULL) return; m_Fib = fib; m_CurrentImage = img; m_CurrentStartRoi = startRoi; m_CurrentEndRoi = endRoi; DoPlotFiberBundles(fib, img, startRoi, endRoi, avg, number); } void QmitkTbssRoiAnalysisWidget::ModifyPlot(int number, bool avg) { if(m_Fib == NULL || m_CurrentTbssImage == NULL || m_CurrentStartRoi == NULL || m_CurrentEndRoi == NULL) return; if(m_PlottingFiberBundle) { DoPlotFiberBundles(m_Fib, m_CurrentImage, m_CurrentStartRoi, m_CurrentEndRoi, avg, number); } else { PlotFiber4D(m_CurrentTbssImage, m_Fib, m_CurrentStartRoi, m_CurrentEndRoi, number); } } TractContainerType QmitkTbssRoiAnalysisWidget::ParameterizeTracts(TractContainerType tracts, int number) { TractContainerType resampledTracts; for(TractContainerType::iterator it = tracts.begin(); it != tracts.end(); ++it) { TractType resampledTract; TractType tract = *it; // Calculate the total length - float totalLength = 0; + mitk::ScalarType totalLength = 0; if(tract.size() < 2) continue; PointType p0 = tract.at(0); for(int i = 1; i distance+0.001) { if(tractCounter == tract.size()) std::cout << "problem"; // Determine by what distance we are no on the next segment locationBetween = locationBetween - distance; p0 = p1; p1 = tract.at(tractCounter); tractCounter++; distance = p0.EuclideanDistanceTo(p1); } // Direction PointType::VectorType direction = p1-p0; direction.Normalize(); PointType newSample = p0 + direction*locationBetween; resampledTract.push_back(newSample); locationBetween += stepSize; } resampledTracts.push_back(resampledTract); } return resampledTracts; } mitk::Point3D QmitkTbssRoiAnalysisWidget::GetPositionInWorld(int index) { - float xSum = 0.0; - float ySum = 0.0; - float zSum = 0.0; + mitk::ScalarType xSum = 0.0; + mitk::ScalarType ySum = 0.0; + mitk::ScalarType zSum = 0.0; for(TractContainerType::iterator it = m_CurrentTracts.begin(); it!=m_CurrentTracts.end(); ++it) { TractType tract = *it; PointType p = tract.at(index); xSum += p[0]; ySum += p[1]; zSum += p[2]; } int number = m_CurrentTracts.size(); - float xPos = xSum / number; - float yPos = ySum / number; - float zPos = zSum / number; + mitk::ScalarType xPos = xSum / number; + mitk::ScalarType yPos = ySum / number; + mitk::ScalarType zPos = zSum / number; mitk::Point3D pos; pos[0] = xPos; pos[1] = yPos; pos[2] = zPos; return pos; } -std::vector< std::vector > QmitkTbssRoiAnalysisWidget::CalculateGroupProfiles() +std::vector< std::vector > QmitkTbssRoiAnalysisWidget::CalculateGroupProfiles() { MITK_INFO << "make profiles!"; - std::vector< std::vector > profiles; + std::vector< std::vector > profiles; int size = m_Projections->GetVectorLength(); for(int s=0; s profile; + std::vector profile; RoiType::iterator it; it = m_Roi.begin(); while(it != m_Roi.end()) { itk::Index<3> ix = *it; profile.push_back(m_Projections->GetPixel(ix).GetElement(s)); it++; } profiles.push_back(profile); } m_IndividualProfiles = profiles; // Calculate the averages // Here a check could be build in to check whether all profiles have // the same length, but this should normally be the case if the input // data were corrected with the TBSS Module. - std::vector< std::vector > groupProfiles; + std::vector< std::vector > groupProfiles; std::vector< std::pair >::iterator it; it = m_Groups.begin(); int c = 0; //the current profile number while(it != m_Groups.end() && profiles.size() > 0) { std::pair p = *it; int size = p.second; //initialize a vector of the right length with zeroes - std::vector averageProfile; + std::vector averageProfile; for(int i=0; i > groupProfiles = CalculateGroupProfiles(); + std::vector > groupProfiles = CalculateGroupProfiles(); Plot(groupProfiles); } -void QmitkTbssRoiAnalysisWidget::Plot(std::vector > groupProfiles) +void QmitkTbssRoiAnalysisWidget::Plot(std::vector > groupProfiles) { this->Clear(); m_Vals.clear(); - std::vector v1; + std::vector v1; - std::vector xAxis; + std::vector xAxis; for(int i=0; iSetPlotTitle( title.c_str() ); QPen pen( Qt::SolidLine ); pen.setWidth(2); std::vector< std::pair >::iterator it; it = m_Groups.begin(); int c = 0; //the current profile number QColor colors[4] = {Qt::green, Qt::blue, Qt::yellow, Qt::red}; while(it != m_Groups.end() && groupProfiles.size() > 0) { std::pair< std::string, int > group = *it; pen.setColor(colors[c]); int curveId = this->InsertCurve( group.first.c_str() ); this->SetCurveData( curveId, xAxis, groupProfiles.at(c) ); this->SetCurvePen( curveId, pen ); c++; it++; } QwtLegend *legend = new QwtLegend; this->SetLegend(legend, QwtPlot::RightLegend, 0.5); std::cout << m_Measure << std::endl; this->m_Plot->setAxisTitle(0, m_Measure.c_str()); this->m_Plot->setAxisTitle(3, "Position"); this->Replot(); } -std::vector< std::vector > QmitkTbssRoiAnalysisWidget::CalculateGroupProfilesFibers(mitk::TbssImage::Pointer tbssImage, +std::vector< std::vector > QmitkTbssRoiAnalysisWidget::CalculateGroupProfilesFibers(mitk::TbssImage::Pointer tbssImage, mitk::FiberBundleX *fib, mitk::PlanarFigure* startRoi, mitk::PlanarFigure* endRoi, int number) { TractContainerType tracts = CreateTracts(fib, startRoi, endRoi); TractContainerType resampledTracts = ParameterizeTracts(tracts, number); int nTracts = resampledTracts.size(); this->Clear(); // For every group we have m fibers * n subjects of profiles to fill - std::vector< std::vector > profiles; + std::vector< std::vector > profiles; // calculate individual profiles by going through all n subjects int size = m_Projections->GetVectorLength(); for(int s=0; s profile; + std::vector profile; TractType::iterator it = resampledTracts[t].begin(); while(it != resampledTracts[t].end()) { PointType p = *it; PointType index; tbssImage->GetGeometry()->WorldToIndex(p, index); itk::Index<3> ix; ix[0] = index[0]; ix[1] = index[1]; ix[2] = index[2]; // Get value from image profile.push_back(m_Projections->GetPixel(ix).GetElement(s)); it++; } profiles.push_back(profile); } } m_IndividualProfiles = profiles; // Now create the group averages (every group contains m fibers * n_i group members std::vector< std::pair >::iterator it; it = m_Groups.begin(); int c = 0; //the current profile number // Calculate the group averages - std::vector< std::vector > groupProfiles; + std::vector< std::vector > groupProfiles; while(it != m_Groups.end() && profiles.size() > 0) { std::pair p = *it; int size = p.second; //initialize a vector of the right length with zeroes - std::vector averageProfile; + std::vector averageProfile; for(int i=0; i > groupProfiles = CalculateGroupProfilesFibers(tbssImage, fib, startRoi, endRoi, number); + std::vector > groupProfiles = CalculateGroupProfilesFibers(tbssImage, fib, startRoi, endRoi, number); Plot(groupProfiles); } void QmitkTbssRoiAnalysisWidget::PlotFiberBundles(TractContainerType tracts, mitk::Image *img, bool avg) { m_PlottingFiberBundle = true; this->Clear(); std::vector::iterator it = tracts.begin(); - std::vector< std::vector > profiles; + std::vector< std::vector > profiles; it = tracts.begin(); while(it != tracts.end()) { TractType tract = *it; TractType::iterator tractIt = tract.begin(); - std::vector profile; + std::vector profile; while(tractIt != tract.end()) { PointType p = *tractIt; // Get value from image - profile.push_back( (double)img->GetPixelValueByWorldCoordinate(p) ); + profile.push_back( (mitk::ScalarType)img->GetPixelValueByWorldCoordinate(p) ); ++tractIt; } profiles.push_back(profile); std::cout << std::endl; ++it; } if(profiles.size() == 0) return; m_IndividualProfiles = profiles; std::string title = "Fiber bundle plot"; this->SetPlotTitle( title.c_str() ); // initialize average profile - std::vector averageProfile; - std::vector profile = profiles.at(0); // can do this because we checked the size of profiles before + std::vector averageProfile; + std::vector profile = profiles.at(0); // can do this because we checked the size of profiles before for(int i=0; i >::iterator profit = profiles.begin(); + std::vector< std::vector >::iterator profit = profiles.begin(); int id=0; while(profit != profiles.end()) { - std::vector profile = *profit; + std::vector profile = *profit; - std::vector xAxis; + std::vector xAxis; for(int i=0; iInsertCurve( "" ); this->SetCurveData( curveId, xAxis, profile ); ++profit; id++; } m_Average = averageProfile; if(avg) { // Draw the average profile - std::vector xAxis; + std::vector xAxis; for(int i=0; iInsertCurve( "" ); this->SetCurveData( curveId, xAxis, averageProfile ); QPen pen( Qt::SolidLine ); pen.setWidth(3); pen.setColor(Qt::red); this->SetCurvePen( curveId, pen ); id++; } this->Replot(); } void QmitkTbssRoiAnalysisWidget::drawBar(int x) { m_Plot->detachItems(QwtPlotItem::Rtti_PlotMarker, true); QwtPlotMarker *mX = new QwtPlotMarker(); //mX->setLabel(QString::fromLatin1("selected point")); mX->setLabelAlignment(Qt::AlignLeft | Qt::AlignBottom); mX->setLabelOrientation(Qt::Vertical); mX->setLineStyle(QwtPlotMarker::VLine); mX->setLinePen(QPen(Qt::black, 0, Qt::SolidLine)); mX->setXValue(x); mX->attach(m_Plot); this->Replot(); } QmitkTbssRoiAnalysisWidget::~QmitkTbssRoiAnalysisWidget() { delete m_PlotPicker; } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkTbssRoiAnalysisWidget.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkTbssRoiAnalysisWidget.h index 238bd07a6d..afc012d027 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkTbssRoiAnalysisWidget.h +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkTbssRoiAnalysisWidget.h @@ -1,226 +1,226 @@ /*=================================================================== 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 QmitkTbssRoiAnalysisWidget_H_ #define QmitkTbssRoiAnalysisWidget_H_ #include "QmitkPlotWidget.h" #include #include #include #include typedef itk::VectorImage VectorImageType; typedef std::vector< itk::Index<3> > RoiType; -typedef itk::Point PointType; +typedef mitk::Point3D PointType; typedef std::vector< PointType> TractType; typedef std::vector< TractType > TractContainerType; class QwtPlotPicker; /** * \brief Plot widget for TBSS Data * This widget can plot regions of interest on TBSS projection data. */ class DIFFUSIONIMAGING_EXPORT QmitkTbssRoiAnalysisWidget : public QmitkPlotWidget { Q_OBJECT public: QmitkTbssRoiAnalysisWidget( QWidget * parent); virtual ~QmitkTbssRoiAnalysisWidget(); /* \brief Set group information */ void SetGroups(std::vector< std::pair > groups) { m_Groups = groups; } /* \brief Draws the group averaged profiles */ void DrawProfiles(); void PlotFiber4D(mitk::TbssImage::Pointer tbssImage, mitk::FiberBundleX *fib, mitk::PlanarFigure* startRoi, mitk::PlanarFigure* endRoi, int number); void PlotFiberBundles(TractContainerType tracts, mitk::Image* img, bool avg=false); /* \brief Sets the projections of the individual subjects */ void SetProjections(VectorImageType::Pointer projections) { m_Projections = projections; } /* \brief Set the region of interest*/ void SetRoi(RoiType roi) { m_Roi = roi; } /* \brief Set structure information to display in the plot */ void SetStructure(std::string structure) { m_Structure = structure; } /* \brief Set measurement type for display in the plot */ void SetMeasure(std::string measure) { m_Measure = measure; } /* \brief Draws a bar to indicate were the user clicked in the plot */ void drawBar(int x); /* \brief Returns the values of the group averaged profiles */ std::vector > GetVals() { return m_Vals; } /* \brief Returns the values of the individual subjects profiles */ std::vector > GetIndividualProfiles() { return m_IndividualProfiles; } std::vector GetAverageProfile() { return m_Average; } void SetPlottingFiber(bool b) { m_PlottingFiberBundle = b; } bool IsPlottingFiber() { return m_PlottingFiberBundle; } void PlotFiberBetweenRois(mitk::FiberBundleX *fib, mitk::Image* img, mitk::PlanarFigure* startRoi, mitk::PlanarFigure* endRoi, bool avg=-1, int number=25); // Takes an index which is an x coordinate from the plot and finds the corresponding position in world space mitk::Point3D GetPositionInWorld(int index); void ModifyPlot(int number, bool avg); QwtPlotPicker* m_PlotPicker; protected: mitk::FiberBundleX* m_Fib; std::vector< std::vector > m_Vals; std::vector< std::vector > m_IndividualProfiles; std::vector< double > m_Average; std::vector< std::vector > CalculateGroupProfiles(); std::vector< std::vector > CalculateGroupProfilesFibers(mitk::TbssImage::Pointer tbssImage, mitk::FiberBundleX *fib, mitk::PlanarFigure* startRoi, mitk::PlanarFigure* endRoi, int number); void Plot(std::vector > groupProfiles); void Tokenize(const std::string& str, std::vector& tokens, const std::string& delimiters = " ") { // Skip delimiters at beginning. std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); // Find first "non-delimiter". std::string::size_type pos = str.find_first_of(delimiters, lastPos); while (std::string::npos != pos || std::string::npos != lastPos) { // Found a token, add it to the vector. tokens.push_back(str.substr(lastPos, pos - lastPos)); // Skip delimiters. Note the "not_of" lastPos = str.find_first_not_of(delimiters, pos); // Find next "non-delimiter" pos = str.find_first_of(delimiters, lastPos); } } std::vector< std::pair > m_Groups; VectorImageType::Pointer m_Projections; RoiType m_Roi; std::string m_Structure; std::string m_Measure; bool m_PlottingFiberBundle; // true when the plot results from a fiber tracking result (vtk .fib file) // Resample a collection of tracts so that every tract contains #number equidistant samples TractContainerType ParameterizeTracts(TractContainerType tracts, int number); TractContainerType m_CurrentTracts; mitk::Image* m_CurrentImage; mitk::TbssImage* m_CurrentTbssImage; mitk::PlanarFigure* m_CurrentStartRoi; mitk::PlanarFigure* m_CurrentEndRoi; void DoPlotFiberBundles(mitk::FiberBundleX *fib, mitk::Image* img, mitk::PlanarFigure* startRoi, mitk::PlanarFigure* endRoi, bool avg=false, int number=25); /* \brief Creates tracts from a mitk::FiberBundleX and two planar figures indicating the start end end point */ TractContainerType CreateTracts(mitk::FiberBundleX *fib, mitk::PlanarFigure* startRoi, mitk::PlanarFigure* endRoi); }; #endif diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp index c77cb7fb68..b5d2423b55 100755 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp @@ -1,2035 +1,2035 @@ /*=================================================================== 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. ===================================================================*/ //misc #define _USE_MATH_DEFINES #include // Blueberry #include #include // Qmitk #include "QmitkFiberfoxView.h" // MITK #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "usModuleRegistry.h" #define _USE_MATH_DEFINES #include const std::string QmitkFiberfoxView::VIEW_ID = "org.mitk.views.fiberfoxview"; QmitkFiberfoxView::QmitkFiberfoxView() : QmitkAbstractView() , m_Controls( 0 ) , m_SelectedImage( NULL ) { } // Destructor QmitkFiberfoxView::~QmitkFiberfoxView() { } void QmitkFiberfoxView::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::QmitkFiberfoxViewControls; m_Controls->setupUi( parent ); m_Controls->m_StickWidget1->setVisible(true); m_Controls->m_StickWidget2->setVisible(false); m_Controls->m_ZeppelinWidget1->setVisible(false); m_Controls->m_ZeppelinWidget2->setVisible(false); m_Controls->m_TensorWidget1->setVisible(false); m_Controls->m_TensorWidget2->setVisible(false); m_Controls->m_BallWidget1->setVisible(true); m_Controls->m_BallWidget2->setVisible(false); m_Controls->m_AstrosticksWidget1->setVisible(false); m_Controls->m_AstrosticksWidget2->setVisible(false); m_Controls->m_DotWidget1->setVisible(false); m_Controls->m_DotWidget2->setVisible(false); m_Controls->m_Comp4FractionFrame->setVisible(false); m_Controls->m_DiffusionPropsMessage->setVisible(false); m_Controls->m_GeometryMessage->setVisible(false); m_Controls->m_AdvancedSignalOptionsFrame->setVisible(false); m_Controls->m_AdvancedFiberOptionsFrame->setVisible(false); m_Controls->m_VarianceBox->setVisible(false); m_Controls->m_NoiseFrame->setVisible(false); m_Controls->m_GhostFrame->setVisible(false); m_Controls->m_DistortionsFrame->setVisible(false); m_Controls->m_EddyFrame->setVisible(false); m_Controls->m_SpikeFrame->setVisible(false); m_Controls->m_AliasingFrame->setVisible(false); m_Controls->m_FrequencyMapBox->SetDataStorage(this->GetDataStorage()); mitk::TNodePredicateDataType::Pointer isMitkImage = mitk::TNodePredicateDataType::New(); mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage"); mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage"); mitk::NodePredicateDataType::Pointer isQbi = mitk::NodePredicateDataType::New("QBallImage"); mitk::NodePredicateOr::Pointer isDiffusionImage = mitk::NodePredicateOr::New(isDwi, isDti); isDiffusionImage = mitk::NodePredicateOr::New(isDiffusionImage, isQbi); mitk::NodePredicateNot::Pointer noDiffusionImage = mitk::NodePredicateNot::New(isDiffusionImage); mitk::NodePredicateAnd::Pointer finalPredicate = mitk::NodePredicateAnd::New(isMitkImage, noDiffusionImage); m_Controls->m_FrequencyMapBox->SetPredicate(finalPredicate); connect((QObject*) m_Controls->m_GenerateImageButton, SIGNAL(clicked()), (QObject*) this, SLOT(GenerateImage())); connect((QObject*) m_Controls->m_GenerateFibersButton, SIGNAL(clicked()), (QObject*) this, SLOT(GenerateFibers())); connect((QObject*) m_Controls->m_CircleButton, SIGNAL(clicked()), (QObject*) this, SLOT(OnDrawROI())); connect((QObject*) m_Controls->m_FlipButton, SIGNAL(clicked()), (QObject*) this, SLOT(OnFlipButton())); connect((QObject*) m_Controls->m_JoinBundlesButton, SIGNAL(clicked()), (QObject*) this, SLOT(JoinBundles())); connect((QObject*) m_Controls->m_VarianceBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnVarianceChanged(double))); connect((QObject*) m_Controls->m_DistributionBox, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(OnDistributionChanged(int))); connect((QObject*) m_Controls->m_FiberDensityBox, SIGNAL(valueChanged(int)), (QObject*) this, SLOT(OnFiberDensityChanged(int))); connect((QObject*) m_Controls->m_FiberSamplingBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnFiberSamplingChanged(double))); connect((QObject*) m_Controls->m_TensionBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnTensionChanged(double))); connect((QObject*) m_Controls->m_ContinuityBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnContinuityChanged(double))); connect((QObject*) m_Controls->m_BiasBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnBiasChanged(double))); connect((QObject*) m_Controls->m_AddGibbsRinging, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddGibbsRinging(int))); connect((QObject*) m_Controls->m_AddNoise, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddNoise(int))); connect((QObject*) m_Controls->m_AddGhosts, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddGhosts(int))); connect((QObject*) m_Controls->m_AddDistortions, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddDistortions(int))); connect((QObject*) m_Controls->m_AddEddy, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddEddy(int))); connect((QObject*) m_Controls->m_AddSpikes, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddSpikes(int))); connect((QObject*) m_Controls->m_AddAliasing, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddAliasing(int))); connect((QObject*) m_Controls->m_ConstantRadiusBox, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnConstantRadius(int))); connect((QObject*) m_Controls->m_CopyBundlesButton, SIGNAL(clicked()), (QObject*) this, SLOT(CopyBundles())); connect((QObject*) m_Controls->m_TransformBundlesButton, SIGNAL(clicked()), (QObject*) this, SLOT(ApplyTransform())); connect((QObject*) m_Controls->m_AlignOnGrid, SIGNAL(clicked()), (QObject*) this, SLOT(AlignOnGrid())); connect((QObject*) m_Controls->m_Compartment1Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp1ModelFrameVisibility(int))); connect((QObject*) m_Controls->m_Compartment2Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp2ModelFrameVisibility(int))); connect((QObject*) m_Controls->m_Compartment3Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp3ModelFrameVisibility(int))); connect((QObject*) m_Controls->m_Compartment4Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp4ModelFrameVisibility(int))); connect((QObject*) m_Controls->m_AdvancedOptionsBox, SIGNAL( stateChanged(int)), (QObject*) this, SLOT(ShowAdvancedOptions(int))); connect((QObject*) m_Controls->m_AdvancedOptionsBox_2, SIGNAL( stateChanged(int)), (QObject*) this, SLOT(ShowAdvancedOptions(int))); connect((QObject*) m_Controls->m_SaveParametersButton, SIGNAL(clicked()), (QObject*) this, SLOT(SaveParameters())); connect((QObject*) m_Controls->m_LoadParametersButton, SIGNAL(clicked()), (QObject*) this, SLOT(LoadParameters())); } } void QmitkFiberfoxView::UpdateImageParameters() { m_ImageGenParameters.artifactList.clear(); m_ImageGenParameters.nonFiberModelList.clear(); m_ImageGenParameters.fiberModelList.clear(); m_ImageGenParameters.signalModelString = ""; m_ImageGenParameters.artifactModelString = ""; m_ImageGenParameters.resultNode = mitk::DataNode::New(); m_ImageGenParameters.tissueMaskImage = NULL; m_ImageGenParameters.frequencyMap = NULL; m_ImageGenParameters.gradientDirections.clear(); m_ImageGenParameters.spikes = 0; m_ImageGenParameters.spikeAmplitude = 1; m_ImageGenParameters.wrap = 1; if (m_SelectedDWI.IsNotNull()) // use parameters of selected DWI { mitk::DiffusionImage::Pointer dwi = dynamic_cast*>(m_SelectedDWI->GetData()); m_ImageGenParameters.imageRegion = dwi->GetVectorImage()->GetLargestPossibleRegion(); m_ImageGenParameters.imageSpacing = dwi->GetVectorImage()->GetSpacing(); m_ImageGenParameters.imageOrigin = dwi->GetVectorImage()->GetOrigin(); m_ImageGenParameters.imageDirection = dwi->GetVectorImage()->GetDirection(); m_ImageGenParameters.b_value = dwi->GetB_Value(); mitk::DiffusionImage::GradientDirectionContainerType::Pointer dirs = dwi->GetDirections(); m_ImageGenParameters.numGradients = 0; for (int i=0; iSize(); i++) { DiffusionSignalModel::GradientType g; g[0] = dirs->at(i)[0]; g[1] = dirs->at(i)[1]; g[2] = dirs->at(i)[2]; m_ImageGenParameters.gradientDirections.push_back(g); if (dirs->at(i).magnitude()>0.0001) m_ImageGenParameters.numGradients++; } } else if (m_SelectedImage.IsNotNull()) // use geometry of selected image { mitk::Image::Pointer img = dynamic_cast(m_SelectedImage->GetData()); itk::Image< float, 3 >::Pointer itkImg = itk::Image< float, 3 >::New(); CastToItkImage< itk::Image< float, 3 > >(img, itkImg); m_ImageGenParameters.imageRegion = itkImg->GetLargestPossibleRegion(); m_ImageGenParameters.imageSpacing = itkImg->GetSpacing(); m_ImageGenParameters.imageOrigin = itkImg->GetOrigin(); m_ImageGenParameters.imageDirection = itkImg->GetDirection(); m_ImageGenParameters.numGradients = m_Controls->m_NumGradientsBox->value(); m_ImageGenParameters.gradientDirections = GenerateHalfShell(m_Controls->m_NumGradientsBox->value()); m_ImageGenParameters.b_value = m_Controls->m_BvalueBox->value(); } else // use GUI parameters { m_ImageGenParameters.imageRegion.SetSize(0, m_Controls->m_SizeX->value()); m_ImageGenParameters.imageRegion.SetSize(1, m_Controls->m_SizeY->value()); m_ImageGenParameters.imageRegion.SetSize(2, m_Controls->m_SizeZ->value()); m_ImageGenParameters.imageSpacing[0] = m_Controls->m_SpacingX->value(); m_ImageGenParameters.imageSpacing[1] = m_Controls->m_SpacingY->value(); m_ImageGenParameters.imageSpacing[2] = m_Controls->m_SpacingZ->value(); m_ImageGenParameters.imageOrigin[0] = m_ImageGenParameters.imageSpacing[0]/2; m_ImageGenParameters.imageOrigin[1] = m_ImageGenParameters.imageSpacing[1]/2; m_ImageGenParameters.imageOrigin[2] = m_ImageGenParameters.imageSpacing[2]/2; m_ImageGenParameters.imageDirection.SetIdentity(); m_ImageGenParameters.numGradients = m_Controls->m_NumGradientsBox->value(); m_ImageGenParameters.gradientDirections = GenerateHalfShell(m_Controls->m_NumGradientsBox->value());; m_ImageGenParameters.b_value = m_Controls->m_BvalueBox->value(); } // signal relaxation m_ImageGenParameters.doSimulateRelaxation = m_Controls->m_RelaxationBox->isChecked(); if (m_ImageGenParameters.doSimulateRelaxation) m_ImageGenParameters.artifactModelString += "_RELAX"; // N/2 ghosts if (m_Controls->m_AddGhosts->isChecked()) { m_ImageGenParameters.artifactModelString += "_GHOST"; m_ImageGenParameters.kspaceLineOffset = m_Controls->m_kOffsetBox->value(); } else m_ImageGenParameters.kspaceLineOffset = 0; // Aliasing if (m_Controls->m_AddAliasing->isChecked()) { m_ImageGenParameters.artifactModelString += "_ALIASING"; m_ImageGenParameters.wrap = 1/m_Controls->m_WrapBox->value(); } m_ImageGenParameters.tLine = m_Controls->m_LineReadoutTimeBox->value(); m_ImageGenParameters.tInhom = m_Controls->m_T2starBox->value(); m_ImageGenParameters.tEcho = m_Controls->m_TEbox->value(); m_ImageGenParameters.repetitions = m_Controls->m_RepetitionsBox->value(); m_ImageGenParameters.doDisablePartialVolume = m_Controls->m_EnforcePureFiberVoxelsBox->isChecked(); m_ImageGenParameters.interpolationShrink = m_Controls->m_InterpolationShrink->value(); m_ImageGenParameters.axonRadius = m_Controls->m_FiberRadius->value(); m_ImageGenParameters.signalScale = m_Controls->m_SignalScaleBox->value(); if (m_Controls->m_AddSpikes->isChecked()) { m_ImageGenParameters.spikes = m_Controls->m_SpikeNumBox->value(); m_ImageGenParameters.spikeAmplitude = m_Controls->m_SpikeScaleBox->value(); m_ImageGenParameters.artifactModelString += "_SPIKES"; } // adjust echo time if needed if ( m_ImageGenParameters.tEcho < m_ImageGenParameters.imageRegion.GetSize(1)*m_ImageGenParameters.tLine ) { this->m_Controls->m_TEbox->setValue( m_ImageGenParameters.imageRegion.GetSize(1)*m_ImageGenParameters.tLine ); m_ImageGenParameters.tEcho = m_Controls->m_TEbox->value(); QMessageBox::information( NULL, "Warning", "Echo time is too short! Time not sufficient to read slice. Automaticall adjusted to "+QString::number(m_ImageGenParameters.tEcho)+" ms"); } // check tissue mask if (m_TissueMask.IsNotNull()) { m_ImageGenParameters.tissueMaskImage = ItkUcharImgType::New(); mitk::CastToItkImage(m_TissueMask, m_ImageGenParameters.tissueMaskImage); } // rician noise if (m_Controls->m_AddNoise->isChecked()) { double noiseVariance = m_Controls->m_NoiseLevel->value(); m_ImageGenParameters.ricianNoiseModel.SetNoiseVariance(noiseVariance); m_ImageGenParameters.artifactModelString += "_NOISE"; m_ImageGenParameters.artifactModelString += QString::number(noiseVariance); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Noise-Variance", DoubleProperty::New(noiseVariance)); } else m_ImageGenParameters.ricianNoiseModel.SetNoiseVariance(0); // gibbs ringing m_ImageGenParameters.addGibbsRinging = m_Controls->m_AddGibbsRinging->isChecked(); if (m_Controls->m_AddGibbsRinging->isChecked()) m_ImageGenParameters.artifactModelString += "_RINGING"; // adjusting line readout time to the adapted image size needed for the DFT int y = m_ImageGenParameters.imageRegion.GetSize(1); if ( y%2 == 1 ) y += 1; if ( y>m_ImageGenParameters.imageRegion.GetSize(1) ) m_ImageGenParameters.tLine *= (double)m_ImageGenParameters.imageRegion.GetSize(1)/y; // add distortions if (m_Controls->m_AddDistortions->isChecked() && m_Controls->m_FrequencyMapBox->GetSelectedNode().IsNotNull()) { mitk::DataNode::Pointer fMapNode = m_Controls->m_FrequencyMapBox->GetSelectedNode(); mitk::Image* img = dynamic_cast(fMapNode->GetData()); ItkDoubleImgType::Pointer itkImg = ItkDoubleImgType::New(); CastToItkImage< ItkDoubleImgType >(img, itkImg); if (m_ImageGenParameters.imageRegion.GetSize(0)==itkImg->GetLargestPossibleRegion().GetSize(0) && m_ImageGenParameters.imageRegion.GetSize(1)==itkImg->GetLargestPossibleRegion().GetSize(1) && m_ImageGenParameters.imageRegion.GetSize(2)==itkImg->GetLargestPossibleRegion().GetSize(2)) { m_ImageGenParameters.frequencyMap = itkImg; m_ImageGenParameters.artifactModelString += "_DISTORTED"; } } m_ImageGenParameters.doSimulateEddyCurrents = m_Controls->m_AddEddy->isChecked(); m_ImageGenParameters.eddyStrength = 0; if (m_Controls->m_AddEddy->isChecked()) { m_ImageGenParameters.eddyStrength = m_Controls->m_EddyGradientStrength->value(); m_ImageGenParameters.artifactModelString += "_EDDY"; } // signal models m_ImageGenParameters.comp3Weight = 1; m_ImageGenParameters.comp4Weight = 0; if (m_Controls->m_Compartment4Box->currentIndex()>0) { m_ImageGenParameters.comp4Weight = m_Controls->m_Comp4FractionBox->value(); m_ImageGenParameters.comp3Weight -= m_ImageGenParameters.comp4Weight; } // compartment 1 switch (m_Controls->m_Compartment1Box->currentIndex()) { case 0: m_StickModel1.SetGradientList(m_ImageGenParameters.gradientDirections); m_StickModel1.SetBvalue(m_ImageGenParameters.b_value); m_StickModel1.SetDiffusivity(m_Controls->m_StickWidget1->GetD()); m_StickModel1.SetT2(m_Controls->m_StickWidget1->GetT2()); m_ImageGenParameters.fiberModelList.push_back(&m_StickModel1); m_ImageGenParameters.signalModelString += "Stick"; m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Stick") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment1.D", DoubleProperty::New(m_Controls->m_StickWidget1->GetD()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment1.T2", DoubleProperty::New(m_StickModel1.GetT2()) ); break; case 1: m_ZeppelinModel1.SetGradientList(m_ImageGenParameters.gradientDirections); m_ZeppelinModel1.SetBvalue(m_ImageGenParameters.b_value); m_ZeppelinModel1.SetDiffusivity1(m_Controls->m_ZeppelinWidget1->GetD1()); m_ZeppelinModel1.SetDiffusivity2(m_Controls->m_ZeppelinWidget1->GetD2()); m_ZeppelinModel1.SetDiffusivity3(m_Controls->m_ZeppelinWidget1->GetD2()); m_ZeppelinModel1.SetT2(m_Controls->m_ZeppelinWidget1->GetT2()); m_ImageGenParameters.fiberModelList.push_back(&m_ZeppelinModel1); m_ImageGenParameters.signalModelString += "Zeppelin"; m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Zeppelin") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment1.D1", DoubleProperty::New(m_Controls->m_ZeppelinWidget1->GetD1()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment1.D2", DoubleProperty::New(m_Controls->m_ZeppelinWidget1->GetD2()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment1.T2", DoubleProperty::New(m_ZeppelinModel1.GetT2()) ); break; case 2: m_TensorModel1.SetGradientList(m_ImageGenParameters.gradientDirections); m_TensorModel1.SetBvalue(m_ImageGenParameters.b_value); m_TensorModel1.SetDiffusivity1(m_Controls->m_TensorWidget1->GetD1()); m_TensorModel1.SetDiffusivity2(m_Controls->m_TensorWidget1->GetD2()); m_TensorModel1.SetDiffusivity3(m_Controls->m_TensorWidget1->GetD3()); m_TensorModel1.SetT2(m_Controls->m_TensorWidget1->GetT2()); m_ImageGenParameters.fiberModelList.push_back(&m_TensorModel1); m_ImageGenParameters.signalModelString += "Tensor"; m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Tensor") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment1.D1", DoubleProperty::New(m_Controls->m_TensorWidget1->GetD1()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment1.D2", DoubleProperty::New(m_Controls->m_TensorWidget1->GetD2()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment1.D3", DoubleProperty::New(m_Controls->m_TensorWidget1->GetD3()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment1.T2", DoubleProperty::New(m_ZeppelinModel1.GetT2()) ); break; } // compartment 2 switch (m_Controls->m_Compartment2Box->currentIndex()) { case 0: break; case 1: m_StickModel2.SetGradientList(m_ImageGenParameters.gradientDirections); m_StickModel2.SetBvalue(m_ImageGenParameters.b_value); m_StickModel2.SetDiffusivity(m_Controls->m_StickWidget2->GetD()); m_StickModel2.SetT2(m_Controls->m_StickWidget2->GetT2()); m_ImageGenParameters.fiberModelList.push_back(&m_StickModel2); m_ImageGenParameters.signalModelString += "Stick"; m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment2.Description", StringProperty::New("Inter-axonal compartment") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment2.Model", StringProperty::New("Stick") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment2.D", DoubleProperty::New(m_Controls->m_StickWidget2->GetD()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment2.T2", DoubleProperty::New(m_StickModel2.GetT2()) ); break; case 2: m_ZeppelinModel2.SetGradientList(m_ImageGenParameters.gradientDirections); m_ZeppelinModel2.SetBvalue(m_ImageGenParameters.b_value); m_ZeppelinModel2.SetDiffusivity1(m_Controls->m_ZeppelinWidget2->GetD1()); m_ZeppelinModel2.SetDiffusivity2(m_Controls->m_ZeppelinWidget2->GetD2()); m_ZeppelinModel2.SetDiffusivity3(m_Controls->m_ZeppelinWidget2->GetD2()); m_ZeppelinModel2.SetT2(m_Controls->m_ZeppelinWidget2->GetT2()); m_ImageGenParameters.fiberModelList.push_back(&m_ZeppelinModel2); m_ImageGenParameters.signalModelString += "Zeppelin"; m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment2.Description", StringProperty::New("Inter-axonal compartment") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment2.Model", StringProperty::New("Zeppelin") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment2.D1", DoubleProperty::New(m_Controls->m_ZeppelinWidget2->GetD1()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment2.D2", DoubleProperty::New(m_Controls->m_ZeppelinWidget2->GetD2()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment2.T2", DoubleProperty::New(m_ZeppelinModel2.GetT2()) ); break; case 3: m_TensorModel2.SetGradientList(m_ImageGenParameters.gradientDirections); m_TensorModel2.SetBvalue(m_ImageGenParameters.b_value); m_TensorModel2.SetDiffusivity1(m_Controls->m_TensorWidget2->GetD1()); m_TensorModel2.SetDiffusivity2(m_Controls->m_TensorWidget2->GetD2()); m_TensorModel2.SetDiffusivity3(m_Controls->m_TensorWidget2->GetD3()); m_TensorModel2.SetT2(m_Controls->m_TensorWidget2->GetT2()); m_ImageGenParameters.fiberModelList.push_back(&m_TensorModel2); m_ImageGenParameters.signalModelString += "Tensor"; m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment2.Description", StringProperty::New("Inter-axonal compartment") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment2.Model", StringProperty::New("Tensor") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment2.D1", DoubleProperty::New(m_Controls->m_TensorWidget2->GetD1()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment2.D2", DoubleProperty::New(m_Controls->m_TensorWidget2->GetD2()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment2.D3", DoubleProperty::New(m_Controls->m_TensorWidget2->GetD3()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment2.T2", DoubleProperty::New(m_ZeppelinModel2.GetT2()) ); break; } // compartment 3 switch (m_Controls->m_Compartment3Box->currentIndex()) { case 0: m_BallModel1.SetGradientList(m_ImageGenParameters.gradientDirections); m_BallModel1.SetBvalue(m_ImageGenParameters.b_value); m_BallModel1.SetDiffusivity(m_Controls->m_BallWidget1->GetD()); m_BallModel1.SetT2(m_Controls->m_BallWidget1->GetT2()); m_BallModel1.SetWeight(m_ImageGenParameters.comp3Weight); m_ImageGenParameters.nonFiberModelList.push_back(&m_BallModel1); m_ImageGenParameters.signalModelString += "Ball"; m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Ball") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment3.D", DoubleProperty::New(m_Controls->m_BallWidget1->GetD()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment3.T2", DoubleProperty::New(m_BallModel1.GetT2()) ); break; case 1: m_AstrosticksModel1.SetGradientList(m_ImageGenParameters.gradientDirections); m_AstrosticksModel1.SetBvalue(m_ImageGenParameters.b_value); m_AstrosticksModel1.SetDiffusivity(m_Controls->m_AstrosticksWidget1->GetD()); m_AstrosticksModel1.SetT2(m_Controls->m_AstrosticksWidget1->GetT2()); m_AstrosticksModel1.SetRandomizeSticks(m_Controls->m_AstrosticksWidget1->GetRandomizeSticks()); m_AstrosticksModel1.SetWeight(m_ImageGenParameters.comp3Weight); m_ImageGenParameters.nonFiberModelList.push_back(&m_AstrosticksModel1); m_ImageGenParameters.signalModelString += "Astrosticks"; m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Astrosticks") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment3.D", DoubleProperty::New(m_Controls->m_AstrosticksWidget1->GetD()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment3.T2", DoubleProperty::New(m_AstrosticksModel1.GetT2()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment3.RandomSticks", BoolProperty::New(m_Controls->m_AstrosticksWidget1->GetRandomizeSticks()) ); break; case 2: m_DotModel1.SetGradientList(m_ImageGenParameters.gradientDirections); m_DotModel1.SetT2(m_Controls->m_DotWidget1->GetT2()); m_DotModel1.SetWeight(m_ImageGenParameters.comp3Weight); m_ImageGenParameters.nonFiberModelList.push_back(&m_DotModel1); m_ImageGenParameters.signalModelString += "Dot"; m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Dot") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment3.T2", DoubleProperty::New(m_DotModel1.GetT2()) ); break; } // compartment 4 switch (m_Controls->m_Compartment4Box->currentIndex()) { case 0: break; case 1: m_BallModel2.SetGradientList(m_ImageGenParameters.gradientDirections); m_BallModel2.SetBvalue(m_ImageGenParameters.b_value); m_BallModel2.SetDiffusivity(m_Controls->m_BallWidget2->GetD()); m_BallModel2.SetT2(m_Controls->m_BallWidget2->GetT2()); m_BallModel2.SetWeight(m_ImageGenParameters.comp4Weight); m_ImageGenParameters.nonFiberModelList.push_back(&m_BallModel2); m_ImageGenParameters.signalModelString += "Ball"; m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Ball") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment4.D", DoubleProperty::New(m_Controls->m_BallWidget2->GetD()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment4.T2", DoubleProperty::New(m_BallModel2.GetT2()) ); break; case 2: m_AstrosticksModel2.SetGradientList(m_ImageGenParameters.gradientDirections); m_AstrosticksModel2.SetBvalue(m_ImageGenParameters.b_value); m_AstrosticksModel2.SetDiffusivity(m_Controls->m_AstrosticksWidget2->GetD()); m_AstrosticksModel2.SetT2(m_Controls->m_AstrosticksWidget2->GetT2()); m_AstrosticksModel2.SetRandomizeSticks(m_Controls->m_AstrosticksWidget2->GetRandomizeSticks()); m_AstrosticksModel2.SetWeight(m_ImageGenParameters.comp4Weight); m_ImageGenParameters.nonFiberModelList.push_back(&m_AstrosticksModel2); m_ImageGenParameters.signalModelString += "Astrosticks"; m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Astrosticks") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment4.D", DoubleProperty::New(m_Controls->m_AstrosticksWidget2->GetD()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment4.T2", DoubleProperty::New(m_AstrosticksModel2.GetT2()) ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment4.RandomSticks", BoolProperty::New(m_Controls->m_AstrosticksWidget2->GetRandomizeSticks()) ); break; case 3: m_DotModel2.SetGradientList(m_ImageGenParameters.gradientDirections); m_DotModel2.SetT2(m_Controls->m_DotWidget2->GetT2()); m_DotModel2.SetWeight(m_ImageGenParameters.comp4Weight); m_ImageGenParameters.nonFiberModelList.push_back(&m_DotModel2); m_ImageGenParameters.signalModelString += "Dot"; m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Dot") ); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Compartment4.T2", DoubleProperty::New(m_DotModel2.GetT2()) ); break; } m_ImageGenParameters.resultNode->AddProperty("Fiberfox.InterpolationShrink", IntProperty::New(m_ImageGenParameters.interpolationShrink)); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.SignalScale", IntProperty::New(m_ImageGenParameters.signalScale)); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.FiberRadius", IntProperty::New(m_ImageGenParameters.axonRadius)); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Tinhom", IntProperty::New(m_ImageGenParameters.tInhom)); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Repetitions", IntProperty::New(m_ImageGenParameters.repetitions)); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.b-value", DoubleProperty::New(m_ImageGenParameters.b_value)); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Model", StringProperty::New(m_ImageGenParameters.signalModelString.toStdString())); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.PureFiberVoxels", BoolProperty::New(m_ImageGenParameters.doDisablePartialVolume)); m_ImageGenParameters.resultNode->AddProperty("binary", BoolProperty::New(false)); } void QmitkFiberfoxView::SaveParameters() { UpdateImageParameters(); QString filename = QFileDialog::getSaveFileName( 0, tr("Save Parameters"), QDir::currentPath()+"/param.ffp", tr("Fiberfox Parameters (*.ffp)") ); if(filename.isEmpty() || filename.isNull()) return; if(!filename.endsWith(".ffp")) filename += ".ffp"; boost::property_tree::ptree parameters; // fiber generation parameters parameters.put("fiberfox.fibers.realtime", m_Controls->m_RealTimeFibers->isChecked()); parameters.put("fiberfox.fibers.showadvanced", m_Controls->m_AdvancedOptionsBox->isChecked()); parameters.put("fiberfox.fibers.distribution", m_Controls->m_DistributionBox->currentIndex()); parameters.put("fiberfox.fibers.variance", m_Controls->m_VarianceBox->value()); parameters.put("fiberfox.fibers.density", m_Controls->m_FiberDensityBox->value()); parameters.put("fiberfox.fibers.spline.sampling", m_Controls->m_FiberSamplingBox->value()); parameters.put("fiberfox.fibers.spline.tension", m_Controls->m_TensionBox->value()); parameters.put("fiberfox.fibers.spline.continuity", m_Controls->m_ContinuityBox->value()); parameters.put("fiberfox.fibers.spline.bias", m_Controls->m_BiasBox->value()); parameters.put("fiberfox.fibers.constantradius", m_Controls->m_ConstantRadiusBox->isChecked()); parameters.put("fiberfox.fibers.rotation.x", m_Controls->m_XrotBox->value()); parameters.put("fiberfox.fibers.rotation.y", m_Controls->m_YrotBox->value()); parameters.put("fiberfox.fibers.rotation.z", m_Controls->m_ZrotBox->value()); parameters.put("fiberfox.fibers.translation.x", m_Controls->m_XtransBox->value()); parameters.put("fiberfox.fibers.translation.y", m_Controls->m_YtransBox->value()); parameters.put("fiberfox.fibers.translation.z", m_Controls->m_ZtransBox->value()); parameters.put("fiberfox.fibers.scale.x", m_Controls->m_XscaleBox->value()); parameters.put("fiberfox.fibers.scale.y", m_Controls->m_YscaleBox->value()); parameters.put("fiberfox.fibers.scale.z", m_Controls->m_ZscaleBox->value()); parameters.put("fiberfox.fibers.includeFiducials", m_Controls->m_IncludeFiducials->isChecked()); parameters.put("fiberfox.fibers.includeFiducials", m_Controls->m_IncludeFiducials->isChecked()); // image generation parameters parameters.put("fiberfox.image.basic.size.x", m_ImageGenParameters.imageRegion.GetSize(0)); parameters.put("fiberfox.image.basic.size.y", m_ImageGenParameters.imageRegion.GetSize(1)); parameters.put("fiberfox.image.basic.size.z", m_ImageGenParameters.imageRegion.GetSize(2)); parameters.put("fiberfox.image.basic.spacing.x", m_ImageGenParameters.imageSpacing[0]); parameters.put("fiberfox.image.basic.spacing.y", m_ImageGenParameters.imageSpacing[1]); parameters.put("fiberfox.image.basic.spacing.z", m_ImageGenParameters.imageSpacing[2]); parameters.put("fiberfox.image.basic.numgradients", m_ImageGenParameters.numGradients); parameters.put("fiberfox.image.basic.bvalue", m_ImageGenParameters.b_value); parameters.put("fiberfox.image.showadvanced", m_Controls->m_AdvancedOptionsBox_2->isChecked()); parameters.put("fiberfox.image.repetitions", m_ImageGenParameters.repetitions); parameters.put("fiberfox.image.signalScale", m_ImageGenParameters.signalScale); parameters.put("fiberfox.image.tEcho", m_ImageGenParameters.tEcho); parameters.put("fiberfox.image.tLine", m_Controls->m_LineReadoutTimeBox->value()); parameters.put("fiberfox.image.tInhom", m_ImageGenParameters.tInhom); parameters.put("fiberfox.image.axonRadius", m_ImageGenParameters.axonRadius); parameters.put("fiberfox.image.interpolationShrink", m_ImageGenParameters.interpolationShrink); parameters.put("fiberfox.image.doSimulateRelaxation", m_ImageGenParameters.doSimulateRelaxation); parameters.put("fiberfox.image.doDisablePartialVolume", m_ImageGenParameters.doDisablePartialVolume); parameters.put("fiberfox.image.outputvolumefractions", m_Controls->m_VolumeFractionsBox->isChecked()); parameters.put("fiberfox.image.artifacts.addnoise", m_Controls->m_AddNoise->isChecked()); parameters.put("fiberfox.image.artifacts.noisevariance", m_Controls->m_NoiseLevel->value()); parameters.put("fiberfox.image.artifacts.addghost", m_Controls->m_AddGhosts->isChecked()); parameters.put("fiberfox.image.artifacts.kspaceLineOffset", m_Controls->m_kOffsetBox->value()); parameters.put("fiberfox.image.artifacts.distortions", m_Controls->m_AddDistortions->isChecked()); parameters.put("fiberfox.image.artifacts.addeddy", m_Controls->m_AddEddy->isChecked()); parameters.put("fiberfox.image.artifacts.eddyStrength", m_Controls->m_EddyGradientStrength->value()); parameters.put("fiberfox.image.artifacts.addringing", m_Controls->m_AddGibbsRinging->isChecked()); parameters.put("fiberfox.image.artifacts.addspikes", m_Controls->m_AddSpikes->isChecked()); parameters.put("fiberfox.image.artifacts.spikesnum", m_Controls->m_SpikeNumBox->value()); parameters.put("fiberfox.image.artifacts.spikesscale", m_Controls->m_SpikeScaleBox->value()); parameters.put("fiberfox.image.artifacts.addaliasing", m_Controls->m_AddAliasing->isChecked()); parameters.put("fiberfox.image.artifacts.aliasingfactor", m_Controls->m_WrapBox->value()); parameters.put("fiberfox.image.compartment1.index", m_Controls->m_Compartment1Box->currentIndex()); parameters.put("fiberfox.image.compartment2.index", m_Controls->m_Compartment2Box->currentIndex()); parameters.put("fiberfox.image.compartment3.index", m_Controls->m_Compartment3Box->currentIndex()); parameters.put("fiberfox.image.compartment4.index", m_Controls->m_Compartment4Box->currentIndex()); parameters.put("fiberfox.image.compartment1.stick.d", m_Controls->m_StickWidget1->GetD()); parameters.put("fiberfox.image.compartment1.stick.t2", m_Controls->m_StickWidget1->GetT2()); parameters.put("fiberfox.image.compartment1.zeppelin.d1", m_Controls->m_ZeppelinWidget1->GetD1()); parameters.put("fiberfox.image.compartment1.zeppelin.d2", m_Controls->m_ZeppelinWidget1->GetD2()); parameters.put("fiberfox.image.compartment1.zeppelin.t2", m_Controls->m_ZeppelinWidget1->GetT2()); parameters.put("fiberfox.image.compartment1.tensor.d1", m_Controls->m_TensorWidget1->GetD1()); parameters.put("fiberfox.image.compartment1.tensor.d2", m_Controls->m_TensorWidget1->GetD2()); parameters.put("fiberfox.image.compartment1.tensor.d3", m_Controls->m_TensorWidget1->GetD3()); parameters.put("fiberfox.image.compartment1.tensor.t2", m_Controls->m_TensorWidget1->GetT2()); parameters.put("fiberfox.image.compartment2.stick.d", m_Controls->m_StickWidget2->GetD()); parameters.put("fiberfox.image.compartment2.stick.t2", m_Controls->m_StickWidget2->GetT2()); parameters.put("fiberfox.image.compartment2.zeppelin.d1", m_Controls->m_ZeppelinWidget2->GetD1()); parameters.put("fiberfox.image.compartment2.zeppelin.d2", m_Controls->m_ZeppelinWidget2->GetD2()); parameters.put("fiberfox.image.compartment2.zeppelin.t2", m_Controls->m_ZeppelinWidget2->GetT2()); parameters.put("fiberfox.image.compartment2.tensor.d1", m_Controls->m_TensorWidget2->GetD1()); parameters.put("fiberfox.image.compartment2.tensor.d2", m_Controls->m_TensorWidget2->GetD2()); parameters.put("fiberfox.image.compartment2.tensor.d3", m_Controls->m_TensorWidget2->GetD3()); parameters.put("fiberfox.image.compartment2.tensor.t2", m_Controls->m_TensorWidget2->GetT2()); parameters.put("fiberfox.image.compartment3.ball.d", m_Controls->m_BallWidget1->GetD()); parameters.put("fiberfox.image.compartment3.ball.t2", m_Controls->m_BallWidget1->GetT2()); parameters.put("fiberfox.image.compartment3.astrosticks.d", m_Controls->m_AstrosticksWidget1->GetD()); parameters.put("fiberfox.image.compartment3.astrosticks.t2", m_Controls->m_AstrosticksWidget1->GetT2()); parameters.put("fiberfox.image.compartment3.astrosticks.randomize", m_Controls->m_AstrosticksWidget1->GetRandomizeSticks()); parameters.put("fiberfox.image.compartment3.dot.t2", m_Controls->m_DotWidget1->GetT2()); parameters.put("fiberfox.image.compartment4.ball.d", m_Controls->m_BallWidget2->GetD()); parameters.put("fiberfox.image.compartment4.ball.t2", m_Controls->m_BallWidget2->GetT2()); parameters.put("fiberfox.image.compartment4.astrosticks.d", m_Controls->m_AstrosticksWidget2->GetD()); parameters.put("fiberfox.image.compartment4.astrosticks.t2", m_Controls->m_AstrosticksWidget2->GetT2()); parameters.put("fiberfox.image.compartment4.astrosticks.randomize", m_Controls->m_AstrosticksWidget2->GetRandomizeSticks()); parameters.put("fiberfox.image.compartment4.dot.t2", m_Controls->m_DotWidget2->GetT2()); parameters.put("fiberfox.image.compartment4.weight", m_Controls->m_Comp4FractionBox->value()); boost::property_tree::xml_parser::write_xml(filename.toStdString(), parameters); } void QmitkFiberfoxView::LoadParameters() { QString filename = QFileDialog::getOpenFileName(0, tr("Load Parameters"), QDir::currentPath(), tr("Fiberfox Parameters (*.ffp)") ); if(filename.isEmpty() || filename.isNull()) return; boost::property_tree::ptree parameters; boost::property_tree::xml_parser::read_xml(filename.toStdString(), parameters); BOOST_FOREACH( boost::property_tree::ptree::value_type const& v1, parameters.get_child("fiberfox") ) { if( v1.first == "fibers" ) { m_Controls->m_RealTimeFibers->setChecked(v1.second.get("realtime")); m_Controls->m_AdvancedOptionsBox->setChecked(v1.second.get("showadvanced")); m_Controls->m_DistributionBox->setCurrentIndex(v1.second.get("distribution")); m_Controls->m_VarianceBox->setValue(v1.second.get("variance")); m_Controls->m_FiberDensityBox->setValue(v1.second.get("density")); m_Controls->m_IncludeFiducials->setChecked(v1.second.get("includeFiducials")); m_Controls->m_ConstantRadiusBox->setChecked(v1.second.get("constantradius")); BOOST_FOREACH( boost::property_tree::ptree::value_type const& v2, v1.second ) { if( v2.first == "spline" ) { m_Controls->m_FiberSamplingBox->setValue(v2.second.get("sampling")); m_Controls->m_TensionBox->setValue(v2.second.get("tension")); m_Controls->m_ContinuityBox->setValue(v2.second.get("continuity")); m_Controls->m_BiasBox->setValue(v2.second.get("bias")); } if( v2.first == "rotation" ) { m_Controls->m_XrotBox->setValue(v2.second.get("x")); m_Controls->m_YrotBox->setValue(v2.second.get("y")); m_Controls->m_ZrotBox->setValue(v2.second.get("z")); } if( v2.first == "translation" ) { m_Controls->m_XtransBox->setValue(v2.second.get("x")); m_Controls->m_YtransBox->setValue(v2.second.get("y")); m_Controls->m_ZtransBox->setValue(v2.second.get("z")); } if( v2.first == "scale" ) { m_Controls->m_XscaleBox->setValue(v2.second.get("x")); m_Controls->m_YscaleBox->setValue(v2.second.get("y")); m_Controls->m_ZscaleBox->setValue(v2.second.get("z")); } } } if( v1.first == "image" ) { m_Controls->m_SizeX->setValue(v1.second.get("basic.size.x")); m_Controls->m_SizeY->setValue(v1.second.get("basic.size.y")); m_Controls->m_SizeZ->setValue(v1.second.get("basic.size.z")); m_Controls->m_SpacingX->setValue(v1.second.get("basic.spacing.x")); m_Controls->m_SpacingY->setValue(v1.second.get("basic.spacing.y")); m_Controls->m_SpacingZ->setValue(v1.second.get("basic.spacing.z")); m_Controls->m_NumGradientsBox->setValue(v1.second.get("basic.numgradients")); m_Controls->m_BvalueBox->setValue(v1.second.get("basic.bvalue")); m_Controls->m_AdvancedOptionsBox_2->setChecked(v1.second.get("showadvanced")); m_Controls->m_RepetitionsBox->setValue(v1.second.get("repetitions")); m_Controls->m_SignalScaleBox->setValue(v1.second.get("signalScale")); m_Controls->m_TEbox->setValue(v1.second.get("tEcho")); m_Controls->m_LineReadoutTimeBox->setValue(v1.second.get("tLine")); m_Controls->m_T2starBox->setValue(v1.second.get("tInhom")); m_Controls->m_FiberRadius->setValue(v1.second.get("axonRadius")); m_Controls->m_InterpolationShrink->setValue(v1.second.get("interpolationShrink")); m_Controls->m_RelaxationBox->setChecked(v1.second.get("doSimulateRelaxation")); m_Controls->m_EnforcePureFiberVoxelsBox->setChecked(v1.second.get("doDisablePartialVolume")); m_Controls->m_VolumeFractionsBox->setChecked(v1.second.get("outputvolumefractions")); m_Controls->m_AddNoise->setChecked(v1.second.get("artifacts.addnoise")); m_Controls->m_NoiseLevel->setValue(v1.second.get("artifacts.noisevariance")); m_Controls->m_AddGhosts->setChecked(v1.second.get("artifacts.addghost")); m_Controls->m_kOffsetBox->setValue(v1.second.get("artifacts.kspaceLineOffset")); m_Controls->m_AddAliasing->setChecked(v1.second.get("artifacts.addaliasing")); m_Controls->m_WrapBox->setValue(v1.second.get("artifacts.aliasingfactor")); m_Controls->m_AddDistortions->setChecked(v1.second.get("artifacts.distortions")); m_Controls->m_AddSpikes->setChecked(v1.second.get("artifacts.addspikes")); m_Controls->m_SpikeNumBox->setValue(v1.second.get("artifacts.spikesnum")); m_Controls->m_SpikeScaleBox->setValue(v1.second.get("artifacts.spikesscale")); m_Controls->m_AddEddy->setChecked(v1.second.get("artifacts.addeddy")); m_Controls->m_EddyGradientStrength->setValue(v1.second.get("artifacts.eddyStrength")); m_Controls->m_AddGibbsRinging->setChecked(v1.second.get("artifacts.addringing")); m_Controls->m_Compartment1Box->setCurrentIndex(v1.second.get("compartment1.index")); m_Controls->m_Compartment2Box->setCurrentIndex(v1.second.get("compartment2.index")); m_Controls->m_Compartment3Box->setCurrentIndex(v1.second.get("compartment3.index")); m_Controls->m_Compartment4Box->setCurrentIndex(v1.second.get("compartment4.index")); m_Controls->m_StickWidget1->SetD(v1.second.get("compartment1.stick.d")); m_Controls->m_StickWidget1->SetT2(v1.second.get("compartment1.stick.t2")); m_Controls->m_ZeppelinWidget1->SetD1(v1.second.get("compartment1.zeppelin.d1")); m_Controls->m_ZeppelinWidget1->SetD2(v1.second.get("compartment1.zeppelin.d2")); m_Controls->m_ZeppelinWidget1->SetT2(v1.second.get("compartment1.zeppelin.t2")); m_Controls->m_TensorWidget1->SetD1(v1.second.get("compartment1.tensor.d1")); m_Controls->m_TensorWidget1->SetD2(v1.second.get("compartment1.tensor.d2")); m_Controls->m_TensorWidget1->SetD3(v1.second.get("compartment1.tensor.d3")); m_Controls->m_TensorWidget1->SetT2(v1.second.get("compartment1.tensor.t2")); m_Controls->m_StickWidget2->SetD(v1.second.get("compartment2.stick.d")); m_Controls->m_StickWidget2->SetT2(v1.second.get("compartment2.stick.t2")); m_Controls->m_ZeppelinWidget2->SetD1(v1.second.get("compartment2.zeppelin.d1")); m_Controls->m_ZeppelinWidget2->SetD2(v1.second.get("compartment2.zeppelin.d2")); m_Controls->m_ZeppelinWidget2->SetT2(v1.second.get("compartment2.zeppelin.t2")); m_Controls->m_TensorWidget2->SetD1(v1.second.get("compartment2.tensor.d1")); m_Controls->m_TensorWidget2->SetD2(v1.second.get("compartment2.tensor.d2")); m_Controls->m_TensorWidget2->SetD3(v1.second.get("compartment2.tensor.d3")); m_Controls->m_TensorWidget2->SetT2(v1.second.get("compartment2.tensor.t2")); m_Controls->m_BallWidget1->SetD(v1.second.get("compartment3.ball.d")); m_Controls->m_BallWidget1->SetT2(v1.second.get("compartment3.ball.t2")); m_Controls->m_AstrosticksWidget1->SetD(v1.second.get("compartment3.astrosticks.d")); m_Controls->m_AstrosticksWidget1->SetT2(v1.second.get("compartment3.astrosticks.t2")); m_Controls->m_AstrosticksWidget1->SetRandomizeSticks(v1.second.get("compartment3.astrosticks.randomize")); m_Controls->m_DotWidget1->SetT2(v1.second.get("compartment3.dot.t2")); m_Controls->m_BallWidget2->SetD(v1.second.get("compartment4.ball.d")); m_Controls->m_BallWidget2->SetT2(v1.second.get("compartment4.ball.t2")); m_Controls->m_AstrosticksWidget2->SetD(v1.second.get("compartment4.astrosticks.d")); m_Controls->m_AstrosticksWidget2->SetT2(v1.second.get("compartment4.astrosticks.t2")); m_Controls->m_AstrosticksWidget2->SetRandomizeSticks(v1.second.get("compartment4.astrosticks.randomize")); m_Controls->m_DotWidget2->SetT2(v1.second.get("compartment4.dot.t2")); m_Controls->m_Comp4FractionBox->setValue(v1.second.get("compartment4.weight")); } } UpdateImageParameters(); } void QmitkFiberfoxView::ShowAdvancedOptions(int state) { if (state) { m_Controls->m_AdvancedFiberOptionsFrame->setVisible(true); m_Controls->m_AdvancedSignalOptionsFrame->setVisible(true); m_Controls->m_AdvancedOptionsBox->setChecked(true); m_Controls->m_AdvancedOptionsBox_2->setChecked(true); } else { m_Controls->m_AdvancedFiberOptionsFrame->setVisible(false); m_Controls->m_AdvancedSignalOptionsFrame->setVisible(false); m_Controls->m_AdvancedOptionsBox->setChecked(false); m_Controls->m_AdvancedOptionsBox_2->setChecked(false); } } void QmitkFiberfoxView::Comp1ModelFrameVisibility(int index) { m_Controls->m_StickWidget1->setVisible(false); m_Controls->m_ZeppelinWidget1->setVisible(false); m_Controls->m_TensorWidget1->setVisible(false); switch (index) { case 0: m_Controls->m_StickWidget1->setVisible(true); break; case 1: m_Controls->m_ZeppelinWidget1->setVisible(true); break; case 2: m_Controls->m_TensorWidget1->setVisible(true); break; } } void QmitkFiberfoxView::Comp2ModelFrameVisibility(int index) { m_Controls->m_StickWidget2->setVisible(false); m_Controls->m_ZeppelinWidget2->setVisible(false); m_Controls->m_TensorWidget2->setVisible(false); switch (index) { case 0: break; case 1: m_Controls->m_StickWidget2->setVisible(true); break; case 2: m_Controls->m_ZeppelinWidget2->setVisible(true); break; case 3: m_Controls->m_TensorWidget2->setVisible(true); break; } } void QmitkFiberfoxView::Comp3ModelFrameVisibility(int index) { m_Controls->m_BallWidget1->setVisible(false); m_Controls->m_AstrosticksWidget1->setVisible(false); m_Controls->m_DotWidget1->setVisible(false); switch (index) { case 0: m_Controls->m_BallWidget1->setVisible(true); break; case 1: m_Controls->m_AstrosticksWidget1->setVisible(true); break; case 2: m_Controls->m_DotWidget1->setVisible(true); break; } } void QmitkFiberfoxView::Comp4ModelFrameVisibility(int index) { m_Controls->m_BallWidget2->setVisible(false); m_Controls->m_AstrosticksWidget2->setVisible(false); m_Controls->m_DotWidget2->setVisible(false); m_Controls->m_Comp4FractionFrame->setVisible(false); switch (index) { case 0: break; case 1: m_Controls->m_BallWidget2->setVisible(true); m_Controls->m_Comp4FractionFrame->setVisible(true); break; case 2: m_Controls->m_AstrosticksWidget2->setVisible(true); m_Controls->m_Comp4FractionFrame->setVisible(true); break; case 3: m_Controls->m_DotWidget2->setVisible(true); m_Controls->m_Comp4FractionFrame->setVisible(true); break; } } void QmitkFiberfoxView::OnConstantRadius(int value) { if (value>0 && m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnAddAliasing(int value) { if (value>0) m_Controls->m_AliasingFrame->setVisible(true); else m_Controls->m_AliasingFrame->setVisible(false); } void QmitkFiberfoxView::OnAddSpikes(int value) { if (value>0) m_Controls->m_SpikeFrame->setVisible(true); else m_Controls->m_SpikeFrame->setVisible(false); } void QmitkFiberfoxView::OnAddEddy(int value) { if (value>0) m_Controls->m_EddyFrame->setVisible(true); else m_Controls->m_EddyFrame->setVisible(false); } void QmitkFiberfoxView::OnAddDistortions(int value) { if (value>0) m_Controls->m_DistortionsFrame->setVisible(true); else m_Controls->m_DistortionsFrame->setVisible(false); } void QmitkFiberfoxView::OnAddGhosts(int value) { if (value>0) m_Controls->m_GhostFrame->setVisible(true); else m_Controls->m_GhostFrame->setVisible(false); } void QmitkFiberfoxView::OnAddNoise(int value) { if (value>0) m_Controls->m_NoiseFrame->setVisible(true); else m_Controls->m_NoiseFrame->setVisible(false); } void QmitkFiberfoxView::OnDistributionChanged(int value) { if (value==1) m_Controls->m_VarianceBox->setVisible(true); else m_Controls->m_VarianceBox->setVisible(false); if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnVarianceChanged(double value) { if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnFiberDensityChanged(int value) { if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnFiberSamplingChanged(double value) { if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnTensionChanged(double value) { if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnContinuityChanged(double value) { if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnBiasChanged(double value) { if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::AlignOnGrid() { for (int i=0; i(m_SelectedFiducials.at(i)->GetData()); mitk::Point3D wc0 = pe->GetWorldControlPoint(0); mitk::DataStorage::SetOfObjects::ConstPointer parentFibs = GetDataStorage()->GetSources(m_SelectedFiducials.at(i)); for( mitk::DataStorage::SetOfObjects::const_iterator it = parentFibs->begin(); it != parentFibs->end(); ++it ) { mitk::DataNode::Pointer pFibNode = *it; if ( pFibNode.IsNotNull() && dynamic_cast(pFibNode->GetData()) ) { mitk::DataStorage::SetOfObjects::ConstPointer parentImgs = GetDataStorage()->GetSources(pFibNode); for( mitk::DataStorage::SetOfObjects::const_iterator it2 = parentImgs->begin(); it2 != parentImgs->end(); ++it2 ) { mitk::DataNode::Pointer pImgNode = *it2; if ( pImgNode.IsNotNull() && dynamic_cast(pImgNode->GetData()) ) { mitk::Image::Pointer img = dynamic_cast(pImgNode->GetData()); mitk::Geometry3D::Pointer geom = img->GetGeometry(); itk::Index<3> idx; geom->WorldToIndex(wc0, idx); mitk::Point3D cIdx; cIdx[0]=idx[0]; cIdx[1]=idx[1]; cIdx[2]=idx[2]; mitk::Point3D world; geom->IndexToWorld(cIdx,world); mitk::Vector3D trans = world - wc0; pe->GetGeometry()->Translate(trans); break; } } break; } } } for( int i=0; iGetSources(fibNode); for( mitk::DataStorage::SetOfObjects::const_iterator it = sources->begin(); it != sources->end(); ++it ) { mitk::DataNode::Pointer imgNode = *it; if ( imgNode.IsNotNull() && dynamic_cast(imgNode->GetData()) ) { mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(fibNode); for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations->begin(); it2 != derivations->end(); ++it2 ) { mitk::DataNode::Pointer fiducialNode = *it2; if ( fiducialNode.IsNotNull() && dynamic_cast(fiducialNode->GetData()) ) { mitk::PlanarEllipse::Pointer pe = dynamic_cast(fiducialNode->GetData()); mitk::Point3D wc0 = pe->GetWorldControlPoint(0); mitk::Image::Pointer img = dynamic_cast(imgNode->GetData()); mitk::Geometry3D::Pointer geom = img->GetGeometry(); itk::Index<3> idx; geom->WorldToIndex(wc0, idx); mitk::Point3D cIdx; cIdx[0]=idx[0]; cIdx[1]=idx[1]; cIdx[2]=idx[2]; mitk::Point3D world; geom->IndexToWorld(cIdx,world); mitk::Vector3D trans = world - wc0; pe->GetGeometry()->Translate(trans); } } break; } } } for( int i=0; i(m_SelectedImages.at(i)->GetData()); mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(m_SelectedImages.at(i)); for( mitk::DataStorage::SetOfObjects::const_iterator it = derivations->begin(); it != derivations->end(); ++it ) { mitk::DataNode::Pointer fibNode = *it; if ( fibNode.IsNotNull() && dynamic_cast(fibNode->GetData()) ) { mitk::DataStorage::SetOfObjects::ConstPointer derivations2 = GetDataStorage()->GetDerivations(fibNode); for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations2->begin(); it2 != derivations2->end(); ++it2 ) { mitk::DataNode::Pointer fiducialNode = *it2; if ( fiducialNode.IsNotNull() && dynamic_cast(fiducialNode->GetData()) ) { mitk::PlanarEllipse::Pointer pe = dynamic_cast(fiducialNode->GetData()); mitk::Point3D wc0 = pe->GetWorldControlPoint(0); mitk::Geometry3D::Pointer geom = img->GetGeometry(); itk::Index<3> idx; geom->WorldToIndex(wc0, idx); mitk::Point3D cIdx; cIdx[0]=idx[0]; cIdx[1]=idx[1]; cIdx[2]=idx[2]; mitk::Point3D world; geom->IndexToWorld(cIdx,world); mitk::Vector3D trans = world - wc0; pe->GetGeometry()->Translate(trans); } } } } } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnFlipButton() { if (m_SelectedFiducial.IsNull()) return; std::map::iterator it = m_DataNodeToPlanarFigureData.find(m_SelectedFiducial.GetPointer()); if( it != m_DataNodeToPlanarFigureData.end() ) { QmitkPlanarFigureData& data = it->second; data.m_Flipped += 1; data.m_Flipped %= 2; } if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } QmitkFiberfoxView::GradientListType QmitkFiberfoxView::GenerateHalfShell(int NPoints) { NPoints *= 2; GradientListType pointshell; int numB0 = NPoints/20; if (numB0==0) numB0=1; GradientType g; g.Fill(0.0); for (int i=0; i theta; theta.set_size(NPoints); vnl_vector phi; phi.set_size(NPoints); double C = sqrt(4*M_PI); phi(0) = 0.0; phi(NPoints-1) = 0.0; for(int i=0; i0 && i std::vector > QmitkFiberfoxView::MakeGradientList() { std::vector > retval; vnl_matrix_fixed* U = itk::PointShell >::DistributePointShell(); // Add 0 vector for B0 int numB0 = ndirs/10; if (numB0==0) numB0=1; itk::Vector v; v.Fill(0.0); for (int i=0; i v; v[0] = U->get(0,i); v[1] = U->get(1,i); v[2] = U->get(2,i); retval.push_back(v); } return retval; } void QmitkFiberfoxView::OnAddBundle() { if (m_SelectedImage.IsNull()) return; mitk::DataStorage::SetOfObjects::ConstPointer children = GetDataStorage()->GetDerivations(m_SelectedImage); mitk::FiberBundleX::Pointer bundle = mitk::FiberBundleX::New(); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData( bundle ); QString name = QString("Bundle_%1").arg(children->size()); node->SetName(name.toStdString()); m_SelectedBundles.push_back(node); UpdateGui(); GetDataStorage()->Add(node, m_SelectedImage); } void QmitkFiberfoxView::OnDrawROI() { if (m_SelectedBundles.empty()) OnAddBundle(); if (m_SelectedBundles.empty()) return; mitk::DataStorage::SetOfObjects::ConstPointer children = GetDataStorage()->GetDerivations(m_SelectedBundles.at(0)); mitk::PlanarEllipse::Pointer figure = mitk::PlanarEllipse::New(); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData( figure ); QList nodes = this->GetDataManagerSelection(); for( int i=0; iSetSelected(false); m_SelectedFiducial = node; QString name = QString("Fiducial_%1").arg(children->size()); node->SetName(name.toStdString()); node->SetSelected(true); this->DisableCrosshairNavigation(); mitk::PlanarFigureInteractor::Pointer figureInteractor = dynamic_cast(node->GetDataInteractor().GetPointer()); if(figureInteractor.IsNull()) { figureInteractor = mitk::PlanarFigureInteractor::New(); us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "PlanarFigure" ); figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule ); figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule ); figureInteractor->SetDataNode( node ); } UpdateGui(); GetDataStorage()->Add(node, m_SelectedBundles.at(0)); } bool CompareLayer(mitk::DataNode::Pointer i,mitk::DataNode::Pointer j) { int li = -1; i->GetPropertyValue("layer", li); int lj = -1; j->GetPropertyValue("layer", lj); return liGetSources(m_SelectedFiducial); for( mitk::DataStorage::SetOfObjects::const_iterator it = parents->begin(); it != parents->end(); ++it ) if(dynamic_cast((*it)->GetData())) m_SelectedBundles.push_back(*it); if (m_SelectedBundles.empty()) return; } vector< vector< mitk::PlanarEllipse::Pointer > > fiducials; vector< vector< unsigned int > > fliplist; for (int i=0; iGetDerivations(m_SelectedBundles.at(i)); std::vector< mitk::DataNode::Pointer > childVector; for( mitk::DataStorage::SetOfObjects::const_iterator it = children->begin(); it != children->end(); ++it ) childVector.push_back(*it); sort(childVector.begin(), childVector.end(), CompareLayer); vector< mitk::PlanarEllipse::Pointer > fib; vector< unsigned int > flip; float radius = 1; int count = 0; for( std::vector< mitk::DataNode::Pointer >::const_iterator it = childVector.begin(); it != childVector.end(); ++it ) { mitk::DataNode::Pointer node = *it; if ( node.IsNotNull() && dynamic_cast(node->GetData()) ) { mitk::PlanarEllipse* ellipse = dynamic_cast(node->GetData()); if (m_Controls->m_ConstantRadiusBox->isChecked()) { ellipse->SetTreatAsCircle(true); mitk::Point2D c = ellipse->GetControlPoint(0); mitk::Point2D p = ellipse->GetControlPoint(1); mitk::Vector2D v = p-c; if (count==0) { radius = v.GetVnlVector().magnitude(); ellipse->SetControlPoint(1, p); } else { v.Normalize(); v *= radius; ellipse->SetControlPoint(1, c+v); } } fib.push_back(ellipse); std::map::iterator it = m_DataNodeToPlanarFigureData.find(node.GetPointer()); if( it != m_DataNodeToPlanarFigureData.end() ) { QmitkPlanarFigureData& data = it->second; flip.push_back(data.m_Flipped); } else flip.push_back(0); } count++; } if (fib.size()>1) { fiducials.push_back(fib); fliplist.push_back(flip); } else if (fib.size()>0) m_SelectedBundles.at(i)->SetData( mitk::FiberBundleX::New() ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } itk::FibersFromPlanarFiguresFilter::Pointer filter = itk::FibersFromPlanarFiguresFilter::New(); filter->SetFiducials(fiducials); filter->SetFlipList(fliplist); switch(m_Controls->m_DistributionBox->currentIndex()){ case 0: filter->SetFiberDistribution(itk::FibersFromPlanarFiguresFilter::DISTRIBUTE_UNIFORM); break; case 1: filter->SetFiberDistribution(itk::FibersFromPlanarFiguresFilter::DISTRIBUTE_GAUSSIAN); filter->SetVariance(m_Controls->m_VarianceBox->value()); break; } filter->SetDensity(m_Controls->m_FiberDensityBox->value()); filter->SetTension(m_Controls->m_TensionBox->value()); filter->SetContinuity(m_Controls->m_ContinuityBox->value()); filter->SetBias(m_Controls->m_BiasBox->value()); filter->SetFiberSampling(m_Controls->m_FiberSamplingBox->value()); filter->Update(); vector< mitk::FiberBundleX::Pointer > fiberBundles = filter->GetFiberBundles(); for (unsigned int i=0; iSetData( fiberBundles.at(i) ); if (fiberBundles.at(i)->GetNumFibers()>50000) m_SelectedBundles.at(i)->SetVisibility(false); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkFiberfoxView::GenerateImage() { UpdateImageParameters(); if (m_SelectedBundles.empty()) { if (m_SelectedDWI.IsNotNull()) // add artifacts to existing diffusion weighted image { for (unsigned int i=0; i*>(m_SelectedImages.at(i)->GetData())) continue; m_SelectedDWI = m_SelectedImages.at(i); UpdateImageParameters(); mitk::DiffusionImage::Pointer diffImg = dynamic_cast*>(m_SelectedImages.at(i)->GetData()); mitk::RicianNoiseModel noiseModel; noiseModel.SetNoiseVariance(m_ImageGenParameters.ricianNoiseModel.GetNoiseVariance()); itk::AddArtifactsToDwiImageFilter< short >::Pointer filter = itk::AddArtifactsToDwiImageFilter< short >::New(); filter->SetInput(diffImg->GetVectorImage()); filter->SettLine(m_ImageGenParameters.tLine); filter->SetkOffset(m_ImageGenParameters.kspaceLineOffset); filter->SetNoiseModel(&noiseModel); filter->SetGradientList(m_ImageGenParameters.gradientDirections); filter->SetTE(m_ImageGenParameters.tEcho); filter->SetSimulateEddyCurrents(m_ImageGenParameters.doSimulateEddyCurrents); filter->SetEddyGradientStrength(m_ImageGenParameters.eddyStrength); filter->SetAddGibbsRinging(m_ImageGenParameters.addGibbsRinging); filter->SetFrequencyMap(m_ImageGenParameters.frequencyMap); filter->SetSpikeAmplitude(m_ImageGenParameters.spikeAmplitude); filter->SetSpikes(m_ImageGenParameters.spikes); filter->SetWrap(m_ImageGenParameters.wrap); filter->Update(); mitk::DiffusionImage::Pointer image = mitk::DiffusionImage::New(); image->SetVectorImage( filter->GetOutput() ); image->SetB_Value(diffImg->GetB_Value()); image->SetDirections(diffImg->GetDirections()); image->InitializeFromVectorImage(); m_ImageGenParameters.resultNode->SetData( image ); m_ImageGenParameters.resultNode->SetName(m_SelectedImages.at(i)->GetName()+m_ImageGenParameters.artifactModelString.toStdString()); GetDataStorage()->Add(m_ImageGenParameters.resultNode); } m_SelectedDWI = m_SelectedImages.front(); return; } mitk::Image::Pointer image = mitk::ImageGenerator::GenerateGradientImage( m_Controls->m_SizeX->value(), m_Controls->m_SizeY->value(), m_Controls->m_SizeZ->value(), m_Controls->m_SpacingX->value(), m_Controls->m_SpacingY->value(), m_Controls->m_SpacingZ->value()); mitk::Geometry3D* geom = image->GetGeometry(); geom->SetOrigin(m_ImageGenParameters.imageOrigin); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData( image ); node->SetName("Dummy"); unsigned int window = m_Controls->m_SizeX->value()*m_Controls->m_SizeY->value()*m_Controls->m_SizeZ->value(); unsigned int level = window/2; mitk::LevelWindow lw; lw.SetLevelWindow(level, window); node->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( lw ) ); GetDataStorage()->Add(node); m_SelectedImage = node; mitk::BaseData::Pointer basedata = node->GetData(); if (basedata.IsNotNull()) { mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeSlicedGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } UpdateGui(); return; } for (int i=0; i(m_SelectedBundles.at(i)->GetData()); if (fiberBundle->GetNumFibers()<=0) continue; itk::TractsToDWIImageFilter< short >::Pointer tractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New(); tractsToDwiFilter->SetSimulateEddyCurrents(m_ImageGenParameters.doSimulateEddyCurrents); tractsToDwiFilter->SetEddyGradientStrength(m_ImageGenParameters.eddyStrength); tractsToDwiFilter->SetAddGibbsRinging(m_ImageGenParameters.addGibbsRinging); tractsToDwiFilter->SetSimulateRelaxation(m_ImageGenParameters.doSimulateRelaxation); tractsToDwiFilter->SetImageRegion(m_ImageGenParameters.imageRegion); tractsToDwiFilter->SetSpacing(m_ImageGenParameters.imageSpacing); tractsToDwiFilter->SetOrigin(m_ImageGenParameters.imageOrigin); tractsToDwiFilter->SetDirectionMatrix(m_ImageGenParameters.imageDirection); tractsToDwiFilter->SetFiberBundle(fiberBundle); tractsToDwiFilter->SetFiberModels(m_ImageGenParameters.fiberModelList); tractsToDwiFilter->SetNonFiberModels(m_ImageGenParameters.nonFiberModelList); tractsToDwiFilter->SetNoiseModel(&m_ImageGenParameters.ricianNoiseModel); tractsToDwiFilter->SetKspaceArtifacts(m_ImageGenParameters.artifactList); tractsToDwiFilter->SetkOffset(m_ImageGenParameters.kspaceLineOffset); tractsToDwiFilter->SettLine(m_ImageGenParameters.tLine); tractsToDwiFilter->SettInhom(m_ImageGenParameters.tInhom); tractsToDwiFilter->SetTE(m_ImageGenParameters.tEcho); tractsToDwiFilter->SetNumberOfRepetitions(m_ImageGenParameters.repetitions); tractsToDwiFilter->SetEnforcePureFiberVoxels(m_ImageGenParameters.doDisablePartialVolume); tractsToDwiFilter->SetInterpolationShrink(m_ImageGenParameters.interpolationShrink); tractsToDwiFilter->SetFiberRadius(m_ImageGenParameters.axonRadius); tractsToDwiFilter->SetSignalScale(m_ImageGenParameters.signalScale); if (m_ImageGenParameters.interpolationShrink>0) tractsToDwiFilter->SetUseInterpolation(true); tractsToDwiFilter->SetTissueMask(m_ImageGenParameters.tissueMaskImage); tractsToDwiFilter->SetFrequencyMap(m_ImageGenParameters.frequencyMap); tractsToDwiFilter->SetSpikeAmplitude(m_ImageGenParameters.spikeAmplitude); tractsToDwiFilter->SetSpikes(m_ImageGenParameters.spikes); tractsToDwiFilter->SetWrap(m_ImageGenParameters.wrap); tractsToDwiFilter->Update(); mitk::DiffusionImage::Pointer image = mitk::DiffusionImage::New(); image->SetVectorImage( tractsToDwiFilter->GetOutput() ); image->SetB_Value(m_ImageGenParameters.b_value); image->SetDirections(m_ImageGenParameters.gradientDirections); image->InitializeFromVectorImage(); m_ImageGenParameters.resultNode->SetData( image ); m_ImageGenParameters.resultNode->SetName(m_SelectedBundles.at(i)->GetName() +"_D"+QString::number(m_ImageGenParameters.imageRegion.GetSize(0)).toStdString() +"-"+QString::number(m_ImageGenParameters.imageRegion.GetSize(1)).toStdString() +"-"+QString::number(m_ImageGenParameters.imageRegion.GetSize(2)).toStdString() +"_S"+QString::number(m_ImageGenParameters.imageSpacing[0]).toStdString() +"-"+QString::number(m_ImageGenParameters.imageSpacing[1]).toStdString() +"-"+QString::number(m_ImageGenParameters.imageSpacing[2]).toStdString() +"_b"+QString::number(m_ImageGenParameters.b_value).toStdString() +"_"+m_ImageGenParameters.signalModelString.toStdString() +m_ImageGenParameters.artifactModelString.toStdString()); GetDataStorage()->Add(m_ImageGenParameters.resultNode, m_SelectedBundles.at(i)); m_ImageGenParameters.resultNode->SetProperty( "levelwindow", mitk::LevelWindowProperty::New(tractsToDwiFilter->GetLevelWindow()) ); if (m_Controls->m_VolumeFractionsBox->isChecked()) { std::vector< itk::TractsToDWIImageFilter< short >::ItkDoubleImgType::Pointer > volumeFractions = tractsToDwiFilter->GetVolumeFractions(); for (int k=0; kInitializeByItk(volumeFractions.at(k).GetPointer()); image->SetVolume(volumeFractions.at(k)->GetBufferPointer()); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData( image ); node->SetName(m_SelectedBundles.at(i)->GetName()+"_CompartmentVolume-"+QString::number(k).toStdString()); GetDataStorage()->Add(node, m_SelectedBundles.at(i)); } } mitk::BaseData::Pointer basedata = m_ImageGenParameters.resultNode->GetData(); if (basedata.IsNotNull()) { mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeSlicedGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } } void QmitkFiberfoxView::ApplyTransform() { vector< mitk::DataNode::Pointer > selectedBundles; for( int i=0; iGetDerivations(m_SelectedImages.at(i)); for( mitk::DataStorage::SetOfObjects::const_iterator it = derivations->begin(); it != derivations->end(); ++it ) { mitk::DataNode::Pointer fibNode = *it; if ( fibNode.IsNotNull() && dynamic_cast(fibNode->GetData()) ) selectedBundles.push_back(fibNode); } } if (selectedBundles.empty()) selectedBundles = m_SelectedBundles2; if (!selectedBundles.empty()) { std::vector::const_iterator it = selectedBundles.begin(); for (it; it!=selectedBundles.end(); ++it) { mitk::FiberBundleX::Pointer fib = dynamic_cast((*it)->GetData()); fib->RotateAroundAxis(m_Controls->m_XrotBox->value(), m_Controls->m_YrotBox->value(), m_Controls->m_ZrotBox->value()); fib->TranslateFibers(m_Controls->m_XtransBox->value(), m_Controls->m_YtransBox->value(), m_Controls->m_ZtransBox->value()); fib->ScaleFibers(m_Controls->m_XscaleBox->value(), m_Controls->m_YscaleBox->value(), m_Controls->m_ZscaleBox->value()); // handle child fiducials if (m_Controls->m_IncludeFiducials->isChecked()) { mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(*it); for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations->begin(); it2 != derivations->end(); ++it2 ) { mitk::DataNode::Pointer fiducialNode = *it2; if ( fiducialNode.IsNotNull() && dynamic_cast(fiducialNode->GetData()) ) { mitk::PlanarEllipse* pe = dynamic_cast(fiducialNode->GetData()); mitk::Geometry3D* geom = pe->GetGeometry(); // translate mitk::Vector3D world; world[0] = m_Controls->m_XtransBox->value(); world[1] = m_Controls->m_YtransBox->value(); world[2] = m_Controls->m_ZtransBox->value(); geom->Translate(world); // calculate rotation matrix double x = m_Controls->m_XrotBox->value()*M_PI/180; double y = m_Controls->m_YrotBox->value()*M_PI/180; double z = m_Controls->m_ZrotBox->value()*M_PI/180; - itk::Matrix< float, 3, 3 > rotX; rotX.SetIdentity(); + itk::Matrix< double, 3, 3 > rotX; rotX.SetIdentity(); rotX[1][1] = cos(x); rotX[2][2] = rotX[1][1]; rotX[1][2] = -sin(x); rotX[2][1] = -rotX[1][2]; - itk::Matrix< float, 3, 3 > rotY; rotY.SetIdentity(); + itk::Matrix< double, 3, 3 > rotY; rotY.SetIdentity(); rotY[0][0] = cos(y); rotY[2][2] = rotY[0][0]; rotY[0][2] = sin(y); rotY[2][0] = -rotY[0][2]; - itk::Matrix< float, 3, 3 > rotZ; rotZ.SetIdentity(); + itk::Matrix< double, 3, 3 > rotZ; rotZ.SetIdentity(); rotZ[0][0] = cos(z); rotZ[1][1] = rotZ[0][0]; rotZ[0][1] = -sin(z); rotZ[1][0] = -rotZ[0][1]; - itk::Matrix< float, 3, 3 > rot = rotZ*rotY*rotX; + itk::Matrix< double, 3, 3 > rot = rotZ*rotY*rotX; // transform control point coordinate into geometry translation geom->SetOrigin(pe->GetWorldControlPoint(0)); mitk::Point2D cp; cp.Fill(0.0); pe->SetControlPoint(0, cp); // rotate fiducial geom->GetIndexToWorldTransform()->SetMatrix(rot*geom->GetIndexToWorldTransform()->GetMatrix()); // implicit translation mitk::Vector3D trans; trans[0] = geom->GetOrigin()[0]-fib->GetGeometry()->GetCenter()[0]; trans[1] = geom->GetOrigin()[1]-fib->GetGeometry()->GetCenter()[1]; trans[2] = geom->GetOrigin()[2]-fib->GetGeometry()->GetCenter()[2]; mitk::Vector3D newWc = rot*trans; newWc = newWc-trans; geom->Translate(newWc); } } } } } else { for (int i=0; i(m_SelectedFiducials.at(i)->GetData()); mitk::Geometry3D* geom = pe->GetGeometry(); // translate mitk::Vector3D world; world[0] = m_Controls->m_XtransBox->value(); world[1] = m_Controls->m_YtransBox->value(); world[2] = m_Controls->m_ZtransBox->value(); geom->Translate(world); // calculate rotation matrix double x = m_Controls->m_XrotBox->value()*M_PI/180; double y = m_Controls->m_YrotBox->value()*M_PI/180; double z = m_Controls->m_ZrotBox->value()*M_PI/180; - itk::Matrix< float, 3, 3 > rotX; rotX.SetIdentity(); + itk::Matrix< double, 3, 3 > rotX; rotX.SetIdentity(); rotX[1][1] = cos(x); rotX[2][2] = rotX[1][1]; rotX[1][2] = -sin(x); rotX[2][1] = -rotX[1][2]; - itk::Matrix< float, 3, 3 > rotY; rotY.SetIdentity(); + itk::Matrix< double, 3, 3 > rotY; rotY.SetIdentity(); rotY[0][0] = cos(y); rotY[2][2] = rotY[0][0]; rotY[0][2] = sin(y); rotY[2][0] = -rotY[0][2]; - itk::Matrix< float, 3, 3 > rotZ; rotZ.SetIdentity(); + itk::Matrix< double, 3, 3 > rotZ; rotZ.SetIdentity(); rotZ[0][0] = cos(z); rotZ[1][1] = rotZ[0][0]; rotZ[0][1] = -sin(z); rotZ[1][0] = -rotZ[0][1]; - itk::Matrix< float, 3, 3 > rot = rotZ*rotY*rotX; + itk::Matrix< double, 3, 3 > rot = rotZ*rotY*rotX; // transform control point coordinate into geometry translation geom->SetOrigin(pe->GetWorldControlPoint(0)); mitk::Point2D cp; cp.Fill(0.0); pe->SetControlPoint(0, cp); // rotate fiducial geom->GetIndexToWorldTransform()->SetMatrix(rot*geom->GetIndexToWorldTransform()->GetMatrix()); } if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkFiberfoxView::CopyBundles() { if ( m_SelectedBundles.size()<1 ){ QMessageBox::information( NULL, "Warning", "Select at least one fiber bundle!"); MITK_WARN("QmitkFiberProcessingView") << "Select at least one fiber bundle!"; return; } std::vector::const_iterator it = m_SelectedBundles.begin(); for (it; it!=m_SelectedBundles.end(); ++it) { // find parent image mitk::DataNode::Pointer parentNode; mitk::DataStorage::SetOfObjects::ConstPointer parentImgs = GetDataStorage()->GetSources(*it); for( mitk::DataStorage::SetOfObjects::const_iterator it2 = parentImgs->begin(); it2 != parentImgs->end(); ++it2 ) { mitk::DataNode::Pointer pImgNode = *it2; if ( pImgNode.IsNotNull() && dynamic_cast(pImgNode->GetData()) ) { parentNode = pImgNode; break; } } mitk::FiberBundleX::Pointer fib = dynamic_cast((*it)->GetData()); mitk::FiberBundleX::Pointer newBundle = fib->GetDeepCopy(); QString name((*it)->GetName().c_str()); name += "_copy"; mitk::DataNode::Pointer fbNode = mitk::DataNode::New(); fbNode->SetData(newBundle); fbNode->SetName(name.toStdString()); fbNode->SetVisibility(true); if (parentNode.IsNotNull()) GetDataStorage()->Add(fbNode, parentNode); else GetDataStorage()->Add(fbNode); // copy child fiducials if (m_Controls->m_IncludeFiducials->isChecked()) { mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(*it); for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations->begin(); it2 != derivations->end(); ++it2 ) { mitk::DataNode::Pointer fiducialNode = *it2; if ( fiducialNode.IsNotNull() && dynamic_cast(fiducialNode->GetData()) ) { mitk::PlanarEllipse::Pointer pe = mitk::PlanarEllipse::New(); pe->DeepCopy(dynamic_cast(fiducialNode->GetData())); mitk::DataNode::Pointer newNode = mitk::DataNode::New(); newNode->SetData(pe); newNode->SetName(fiducialNode->GetName()); GetDataStorage()->Add(newNode, fbNode); } } } } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkFiberfoxView::JoinBundles() { if ( m_SelectedBundles.size()<2 ){ QMessageBox::information( NULL, "Warning", "Select at least two fiber bundles!"); MITK_WARN("QmitkFiberProcessingView") << "Select at least two fiber bundles!"; return; } std::vector::const_iterator it = m_SelectedBundles.begin(); mitk::FiberBundleX::Pointer newBundle = dynamic_cast((*it)->GetData()); QString name(""); name += QString((*it)->GetName().c_str()); ++it; for (it; it!=m_SelectedBundles.end(); ++it) { newBundle = newBundle->AddBundle(dynamic_cast((*it)->GetData())); name += "+"+QString((*it)->GetName().c_str()); } mitk::DataNode::Pointer fbNode = mitk::DataNode::New(); fbNode->SetData(newBundle); fbNode->SetName(name.toStdString()); fbNode->SetVisibility(true); GetDataStorage()->Add(fbNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkFiberfoxView::UpdateGui() { m_Controls->m_FiberBundleLabel->setText("mandatory"); m_Controls->m_GeometryFrame->setEnabled(true); m_Controls->m_GeometryMessage->setVisible(false); m_Controls->m_DiffusionPropsMessage->setVisible(false); m_Controls->m_FiberGenMessage->setVisible(true); m_Controls->m_TransformBundlesButton->setEnabled(false); m_Controls->m_CopyBundlesButton->setEnabled(false); m_Controls->m_GenerateFibersButton->setEnabled(false); m_Controls->m_FlipButton->setEnabled(false); m_Controls->m_CircleButton->setEnabled(false); m_Controls->m_BvalueBox->setEnabled(true); m_Controls->m_NumGradientsBox->setEnabled(true); m_Controls->m_JoinBundlesButton->setEnabled(false); m_Controls->m_AlignOnGrid->setEnabled(false); if (m_SelectedFiducial.IsNotNull()) { m_Controls->m_TransformBundlesButton->setEnabled(true); m_Controls->m_FlipButton->setEnabled(true); m_Controls->m_AlignOnGrid->setEnabled(true); } if (m_SelectedImage.IsNotNull() || !m_SelectedBundles.empty()) { m_Controls->m_TransformBundlesButton->setEnabled(true); m_Controls->m_CircleButton->setEnabled(true); m_Controls->m_FiberGenMessage->setVisible(false); m_Controls->m_AlignOnGrid->setEnabled(true); } if (m_TissueMask.IsNotNull() || m_SelectedImage.IsNotNull()) { m_Controls->m_GeometryMessage->setVisible(true); m_Controls->m_GeometryFrame->setEnabled(false); } if (m_SelectedDWI.IsNotNull()) { m_Controls->m_DiffusionPropsMessage->setVisible(true); m_Controls->m_BvalueBox->setEnabled(false); m_Controls->m_NumGradientsBox->setEnabled(false); m_Controls->m_GeometryMessage->setVisible(true); m_Controls->m_GeometryFrame->setEnabled(false); } if (!m_SelectedBundles.empty()) { m_Controls->m_CopyBundlesButton->setEnabled(true); m_Controls->m_GenerateFibersButton->setEnabled(true); m_Controls->m_FiberBundleLabel->setText(m_SelectedBundles.at(0)->GetName().c_str()); if (m_SelectedBundles.size()>1) m_Controls->m_JoinBundlesButton->setEnabled(true); } } void QmitkFiberfoxView::OnSelectionChanged( berry::IWorkbenchPart::Pointer, const QList& nodes ) { m_SelectedBundles2.clear(); m_SelectedImages.clear(); m_SelectedFiducials.clear(); m_SelectedFiducial = NULL; m_TissueMask = NULL; m_SelectedBundles.clear(); m_SelectedImage = NULL; m_SelectedDWI = NULL; m_Controls->m_TissueMaskLabel->setText("optional"); // iterate all selected objects, adjust warning visibility for( int i=0; i*>(node->GetData()) ) { m_SelectedDWI = node; m_SelectedImage = node; m_SelectedImages.push_back(node); } else if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { m_SelectedImages.push_back(node); m_SelectedImage = node; bool isBinary = false; node->GetPropertyValue("binary", isBinary); if (isBinary) { m_TissueMask = dynamic_cast(node->GetData()); m_Controls->m_TissueMaskLabel->setText(node->GetName().c_str()); } } else if ( node.IsNotNull() && dynamic_cast(node->GetData()) ) { m_SelectedBundles2.push_back(node); if (m_Controls->m_RealTimeFibers->isChecked()) { m_SelectedBundles.push_back(node); mitk::FiberBundleX::Pointer newFib = dynamic_cast(node->GetData()); if (newFib->GetNumFibers()!=m_Controls->m_FiberDensityBox->value()) GenerateFibers(); } else m_SelectedBundles.push_back(node); } else if ( node.IsNotNull() && dynamic_cast(node->GetData()) ) { m_SelectedFiducials.push_back(node); m_SelectedFiducial = node; m_SelectedBundles.clear(); mitk::DataStorage::SetOfObjects::ConstPointer parents = GetDataStorage()->GetSources(node); for( mitk::DataStorage::SetOfObjects::const_iterator it = parents->begin(); it != parents->end(); ++it ) { mitk::DataNode::Pointer pNode = *it; if ( pNode.IsNotNull() && dynamic_cast(pNode->GetData()) ) m_SelectedBundles.push_back(pNode); } } } UpdateGui(); } void QmitkFiberfoxView::EnableCrosshairNavigation() { MITK_DEBUG << "EnableCrosshairNavigation"; // enable the crosshair navigation if (mitk::ILinkedRenderWindowPart* linkedRenderWindow = dynamic_cast(this->GetRenderWindowPart())) { MITK_DEBUG << "enabling linked navigation"; linkedRenderWindow->EnableLinkedNavigation(true); // linkedRenderWindow->EnableSlicingPlanes(true); } if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::DisableCrosshairNavigation() { MITK_DEBUG << "DisableCrosshairNavigation"; // disable the crosshair navigation during the drawing if (mitk::ILinkedRenderWindowPart* linkedRenderWindow = dynamic_cast(this->GetRenderWindowPart())) { MITK_DEBUG << "disabling linked navigation"; linkedRenderWindow->EnableLinkedNavigation(false); // linkedRenderWindow->EnableSlicingPlanes(false); } } void QmitkFiberfoxView::NodeRemoved(const mitk::DataNode* node) { mitk::DataNode* nonConstNode = const_cast(node); std::map::iterator it = m_DataNodeToPlanarFigureData.find(nonConstNode); if (dynamic_cast(node->GetData())) { m_SelectedBundles.clear(); m_SelectedBundles2.clear(); } else if (dynamic_cast(node->GetData())) m_SelectedImages.clear(); if( it != m_DataNodeToPlanarFigureData.end() ) { QmitkPlanarFigureData& data = it->second; // remove observers data.m_Figure->RemoveObserver( data.m_EndPlacementObserverTag ); data.m_Figure->RemoveObserver( data.m_SelectObserverTag ); data.m_Figure->RemoveObserver( data.m_StartInteractionObserverTag ); data.m_Figure->RemoveObserver( data.m_EndInteractionObserverTag ); m_DataNodeToPlanarFigureData.erase( it ); } } void QmitkFiberfoxView::NodeAdded( const mitk::DataNode* node ) { // add observer for selection in renderwindow mitk::PlanarFigure* figure = dynamic_cast(node->GetData()); bool isPositionMarker (false); node->GetBoolProperty("isContourMarker", isPositionMarker); if( figure && !isPositionMarker ) { MITK_DEBUG << "figure added. will add interactor if needed."; mitk::PlanarFigureInteractor::Pointer figureInteractor = dynamic_cast(node->GetDataInteractor().GetPointer()); mitk::DataNode* nonConstNode = const_cast( node ); if(figureInteractor.IsNull()) { figureInteractor = mitk::PlanarFigureInteractor::New(); us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "PlanarFigure" ); figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule ); figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule ); figureInteractor->SetDataNode( nonConstNode ); } MITK_DEBUG << "will now add observers for planarfigure"; QmitkPlanarFigureData data; data.m_Figure = figure; // // add observer for event when figure has been placed typedef itk::SimpleMemberCommand< QmitkFiberfoxView > SimpleCommandType; // SimpleCommandType::Pointer initializationCommand = SimpleCommandType::New(); // initializationCommand->SetCallbackFunction( this, &QmitkFiberfoxView::PlanarFigureInitialized ); // data.m_EndPlacementObserverTag = figure->AddObserver( mitk::EndPlacementPlanarFigureEvent(), initializationCommand ); // add observer for event when figure is picked (selected) typedef itk::MemberCommand< QmitkFiberfoxView > MemberCommandType; MemberCommandType::Pointer selectCommand = MemberCommandType::New(); selectCommand->SetCallbackFunction( this, &QmitkFiberfoxView::PlanarFigureSelected ); data.m_SelectObserverTag = figure->AddObserver( mitk::SelectPlanarFigureEvent(), selectCommand ); // add observer for event when interaction with figure starts SimpleCommandType::Pointer startInteractionCommand = SimpleCommandType::New(); startInteractionCommand->SetCallbackFunction( this, &QmitkFiberfoxView::DisableCrosshairNavigation); data.m_StartInteractionObserverTag = figure->AddObserver( mitk::StartInteractionPlanarFigureEvent(), startInteractionCommand ); // add observer for event when interaction with figure starts SimpleCommandType::Pointer endInteractionCommand = SimpleCommandType::New(); endInteractionCommand->SetCallbackFunction( this, &QmitkFiberfoxView::EnableCrosshairNavigation); data.m_EndInteractionObserverTag = figure->AddObserver( mitk::EndInteractionPlanarFigureEvent(), endInteractionCommand ); m_DataNodeToPlanarFigureData[nonConstNode] = data; } } void QmitkFiberfoxView::PlanarFigureSelected( itk::Object* object, const itk::EventObject& ) { mitk::TNodePredicateDataType::Pointer isPf = mitk::TNodePredicateDataType::New(); mitk::DataStorage::SetOfObjects::ConstPointer allPfs = this->GetDataStorage()->GetSubset( isPf ); for ( mitk::DataStorage::SetOfObjects::const_iterator it = allPfs->begin(); it!=allPfs->end(); ++it) { mitk::DataNode* node = *it; if( node->GetData() == object ) { node->SetSelected(true); m_SelectedFiducial = node; } else node->SetSelected(false); } UpdateGui(); this->RequestRenderWindowUpdate(); } void QmitkFiberfoxView::SetFocus() { m_Controls->m_CircleButton->setFocus(); }