diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.cpp b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.cpp index 374ea1315f..b84c54ffc0 100644 --- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkFibersFromPlanarFiguresFilter.cpp @@ -1,254 +1,251 @@ /*=================================================================== 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); 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; 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< double, 2 > newP; newP[0] = m_2DPoints.at(j)[0]; newP[1] = m_2DPoints.at(j)[1]; double alpha = acos(eDir[0]); if (eDir[1]>0) alpha = 2*M_PI-alpha; 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< 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< 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/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp index 7426885b1d..e0de18d102 100755 --- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp @@ -1,707 +1,705 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "itkTractsToDWIImageFilter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace itk { template< class PixelType > TractsToDWIImageFilter< PixelType >::TractsToDWIImageFilter() : m_CircleDummy(false) , m_VolumeAccuracy(10) , m_AddGibbsRinging(false) , m_NumberOfRepetitions(1) , m_EnforcePureFiberVoxels(false) , m_InterpolationShrink(1000) , m_FiberRadius(0) , m_SignalScale(25) , m_kOffset(0) , m_tLine(1) , m_UseInterpolation(false) , m_SimulateRelaxation(true) , m_tInhom(50) , m_TE(100) , m_FrequencyMap(NULL) , m_EddyGradientStrength(0.001) , m_SimulateEddyCurrents(false) , m_Spikes(0) , m_Wrap(1.0) + , m_NoiseModel(NULL) , m_SpikeAmplitude(1) { m_Spacing.Fill(2.5); m_Origin.Fill(0.0); m_DirectionMatrix.SetIdentity(); m_ImageRegion.SetSize(0, 10); m_ImageRegion.SetSize(1, 10); m_ImageRegion.SetSize(2, 10); } template< class PixelType > TractsToDWIImageFilter< PixelType >::~TractsToDWIImageFilter() { } template< class PixelType > TractsToDWIImageFilter< PixelType >::DoubleDwiType::Pointer TractsToDWIImageFilter< PixelType >::DoKspaceStuff( std::vector< DoubleDwiType::Pointer >& images ) { // create slice object ImageRegion<2> sliceRegion; sliceRegion.SetSize(0, m_UpsampledImageRegion.GetSize()[0]); sliceRegion.SetSize(1, m_UpsampledImageRegion.GetSize()[1]); Vector< double, 2 > sliceSpacing; sliceSpacing[0] = m_UpsampledSpacing[0]; sliceSpacing[1] = m_UpsampledSpacing[1]; // frequency map slice SliceType::Pointer fMapSlice = NULL; if (m_FrequencyMap.IsNotNull()) { fMapSlice = SliceType::New(); ImageRegion<2> region; region.SetSize(0, m_UpsampledImageRegion.GetSize()[0]); region.SetSize(1, m_UpsampledImageRegion.GetSize()[1]); fMapSlice->SetLargestPossibleRegion( region ); fMapSlice->SetBufferedRegion( region ); fMapSlice->SetRequestedRegion( region ); fMapSlice->Allocate(); } DoubleDwiType::Pointer newImage = DoubleDwiType::New(); newImage->SetSpacing( m_Spacing ); newImage->SetOrigin( m_Origin ); newImage->SetDirection( m_DirectionMatrix ); newImage->SetLargestPossibleRegion( m_ImageRegion ); newImage->SetBufferedRegion( m_ImageRegion ); newImage->SetRequestedRegion( m_ImageRegion ); newImage->SetVectorLength( images.at(0)->GetVectorLength() ); newImage->Allocate(); MatrixType transform = m_DirectionMatrix; for (int i=0; i<3; i++) for (int j=0; j<3; j++) { if (j<2) transform[i][j] *= m_UpsampledSpacing[j]; else transform[i][j] *= m_Spacing[j]; } std::vector< int > spikeVolume; for (int i=0; iGetVectorLength()); std::sort (spikeVolume.begin(), spikeVolume.end()); std::reverse (spikeVolume.begin(), spikeVolume.end()); boost::progress_display disp(images.at(0)->GetVectorLength()*images.at(0)->GetLargestPossibleRegion().GetSize(2)); for (unsigned int g=0; gGetVectorLength(); g++) { std::vector< int > spikeSlice; while (!spikeVolume.empty() && spikeVolume.back()==g) { spikeSlice.push_back(rand()%images.at(0)->GetLargestPossibleRegion().GetSize(2)); spikeVolume.pop_back(); } std::sort (spikeSlice.begin(), spikeSlice.end()); std::reverse (spikeSlice.begin(), spikeSlice.end()); for (unsigned int z=0; zGetLargestPossibleRegion().GetSize(2); z++) { std::vector< SliceType::Pointer > compartmentSlices; std::vector< double > t2Vector; for (unsigned int i=0; i* signalModel; if (iSetLargestPossibleRegion( sliceRegion ); slice->SetBufferedRegion( sliceRegion ); slice->SetRequestedRegion( sliceRegion ); slice->SetSpacing(sliceSpacing); slice->Allocate(); slice->FillBuffer(0.0); // extract slice from channel g for (unsigned int y=0; yGetLargestPossibleRegion().GetSize(1); y++) for (unsigned int x=0; xGetLargestPossibleRegion().GetSize(0); x++) { SliceType::IndexType index2D; index2D[0]=x; index2D[1]=y; DoubleDwiType::IndexType index3D; index3D[0]=x; index3D[1]=y; index3D[2]=z; slice->SetPixel(index2D, images.at(i)->GetPixel(index3D)[g]); if (fMapSlice.IsNotNull() && i==0) fMapSlice->SetPixel(index2D, m_FrequencyMap->GetPixel(index3D)); } compartmentSlices.push_back(slice); t2Vector.push_back(signalModel->GetT2()); } // create k-sapce (inverse fourier transform slices) itk::Size<2> outSize; outSize.SetElement(0, m_ImageRegion.GetSize(0)); outSize.SetElement(1, m_ImageRegion.GetSize(1)); itk::KspaceImageFilter< SliceType::PixelType >::Pointer idft = itk::KspaceImageFilter< SliceType::PixelType >::New(); idft->SetCompartmentImages(compartmentSlices); idft->SetT2(t2Vector); idft->SetkOffset(m_kOffset); idft->SettLine(m_tLine); idft->SetTE(m_TE); idft->SetTinhom(m_tInhom); idft->SetSimulateRelaxation(m_SimulateRelaxation); idft->SetSimulateEddyCurrents(m_SimulateEddyCurrents); idft->SetEddyGradientMagnitude(m_EddyGradientStrength); idft->SetZ((double)z-(double)images.at(0)->GetLargestPossibleRegion().GetSize(2)/2.0); idft->SetDirectionMatrix(transform); idft->SetDiffusionGradientDirection(m_FiberModels.at(0)->GetGradientDirection(g)); idft->SetFrequencyMap(fMapSlice); idft->SetSignalScale(m_SignalScale); idft->SetOutSize(outSize); int numSpikes = 0; while (!spikeSlice.empty() && spikeSlice.back()==z) { numSpikes++; spikeSlice.pop_back(); } idft->SetSpikes(numSpikes); idft->SetSpikeAmplitude(m_SpikeAmplitude); idft->Update(); ComplexSliceType::Pointer fSlice; fSlice = idft->GetOutput(); - for (unsigned int i=0; iAddArtifact(fSlice); - // fourier transform slice SliceType::Pointer newSlice; itk::DftImageFilter< SliceType::PixelType >::Pointer dft = itk::DftImageFilter< SliceType::PixelType >::New(); dft->SetInput(fSlice); dft->Update(); newSlice = dft->GetOutput(); // put slice back into channel g for (unsigned int y=0; yGetLargestPossibleRegion().GetSize(1); y++) for (unsigned int x=0; xGetLargestPossibleRegion().GetSize(0); x++) { DoubleDwiType::IndexType index3D; index3D[0]=x; index3D[1]=y; index3D[2]=z; SliceType::IndexType index2D; index2D[0]=x; index2D[1]=y; DoubleDwiType::PixelType pix3D = newImage->GetPixel(index3D); pix3D[g] = newSlice->GetPixel(index2D); newImage->SetPixel(index3D, pix3D); } ++disp; } } return newImage; } template< class PixelType > void TractsToDWIImageFilter< PixelType >::GenerateData() { // check input data if (m_FiberBundle.IsNull()) itkExceptionMacro("Input fiber bundle is NULL!"); int numFibers = m_FiberBundle->GetNumFibers(); if (numFibers<=0) itkExceptionMacro("Input fiber bundle contains no fibers!"); if (m_FiberModels.empty()) itkExceptionMacro("No diffusion model for fiber compartments defined!"); if (m_EnforcePureFiberVoxels) while (m_FiberModels.size()>1) m_FiberModels.pop_back(); if (m_NonFiberModels.empty()) itkExceptionMacro("No diffusion model for non-fiber compartments defined!"); int baselineIndex = m_FiberModels[0]->GetFirstBaselineIndex(); if (baselineIndex<0) itkExceptionMacro("No baseline index found!"); // define output image geometry if (m_TissueMask.IsNotNull()) // if available use mask image geometry { // use input tissue mask m_Spacing = m_TissueMask->GetSpacing(); m_Origin = m_TissueMask->GetOrigin(); m_DirectionMatrix = m_TissueMask->GetDirection(); m_ImageRegion = m_TissueMask->GetLargestPossibleRegion(); MITK_INFO << "Using tissue mask"; } // initialize output dwi image ImageRegion<3> croppedRegion = m_ImageRegion; croppedRegion.SetSize(1, croppedRegion.GetSize(1)*m_Wrap); itk::Point shiftedOrigin = m_Origin; shiftedOrigin[1] += (m_ImageRegion.GetSize(1)-croppedRegion.GetSize(1))*m_Spacing[1]/2; typename OutputImageType::Pointer outImage = OutputImageType::New(); outImage->SetSpacing( m_Spacing ); outImage->SetOrigin( shiftedOrigin ); outImage->SetDirection( m_DirectionMatrix ); outImage->SetLargestPossibleRegion( croppedRegion ); outImage->SetBufferedRegion( croppedRegion ); outImage->SetRequestedRegion( croppedRegion ); outImage->SetVectorLength( m_FiberModels[0]->GetNumGradients() ); outImage->Allocate(); typename OutputImageType::PixelType temp; temp.SetSize(m_FiberModels[0]->GetNumGradients()); temp.Fill(0.0); outImage->FillBuffer(temp); // ADJUST GEOMETRY FOR FURTHER PROCESSING // is input slize size a power of two? unsigned int x=m_ImageRegion.GetSize(0); unsigned int y=m_ImageRegion.GetSize(1); if ( x%2 == 1 ) m_ImageRegion.SetSize(0, x+1); if ( y%2 == 1 ) m_ImageRegion.SetSize(1, y+1); // apply in-plane upsampling double upsampling = 1; if (m_AddGibbsRinging) { MITK_INFO << "Adding ringing artifacts."; upsampling = 2; } m_UpsampledSpacing = m_Spacing; m_UpsampledSpacing[0] /= upsampling; m_UpsampledSpacing[1] /= upsampling; m_UpsampledImageRegion = m_ImageRegion; m_UpsampledImageRegion.SetSize(0, m_ImageRegion.GetSize()[0]*upsampling); m_UpsampledImageRegion.SetSize(1, m_ImageRegion.GetSize()[1]*upsampling); // generate double images to store the individual compartment signals std::vector< DoubleDwiType::Pointer > compartments; for (unsigned int i=0; iSetSpacing( m_UpsampledSpacing ); doubleDwi->SetOrigin( m_Origin ); doubleDwi->SetDirection( m_DirectionMatrix ); doubleDwi->SetLargestPossibleRegion( m_UpsampledImageRegion ); doubleDwi->SetBufferedRegion( m_UpsampledImageRegion ); doubleDwi->SetRequestedRegion( m_UpsampledImageRegion ); doubleDwi->SetVectorLength( m_FiberModels[0]->GetNumGradients() ); doubleDwi->Allocate(); DoubleDwiType::PixelType pix; pix.SetSize(m_FiberModels[0]->GetNumGradients()); pix.Fill(0.0); doubleDwi->FillBuffer(pix); compartments.push_back(doubleDwi); } // initialize volume fraction images m_VolumeFractions.clear(); for (unsigned int i=0; iSetSpacing( m_UpsampledSpacing ); doubleImg->SetOrigin( m_Origin ); doubleImg->SetDirection( m_DirectionMatrix ); doubleImg->SetLargestPossibleRegion( m_UpsampledImageRegion ); doubleImg->SetBufferedRegion( m_UpsampledImageRegion ); doubleImg->SetRequestedRegion( m_UpsampledImageRegion ); doubleImg->Allocate(); doubleImg->FillBuffer(0); m_VolumeFractions.push_back(doubleImg); } // resample mask image and frequency map to fit upsampled geometry if (m_AddGibbsRinging) { if (m_TissueMask.IsNotNull()) { // rescale mask image (otherwise there are problems with the resampling) itk::RescaleIntensityImageFilter::Pointer rescaler = itk::RescaleIntensityImageFilter::New(); rescaler->SetInput(0,m_TissueMask); rescaler->SetOutputMaximum(100); rescaler->SetOutputMinimum(0); rescaler->Update(); // resample mask image itk::ResampleImageFilter::Pointer resampler = itk::ResampleImageFilter::New(); resampler->SetInput(rescaler->GetOutput()); resampler->SetOutputParametersFromImage(m_TissueMask); resampler->SetSize(m_UpsampledImageRegion.GetSize()); resampler->SetOutputSpacing(m_UpsampledSpacing); resampler->Update(); m_TissueMask = resampler->GetOutput(); } // resample frequency map if (m_FrequencyMap.IsNotNull()) { itk::ResampleImageFilter::Pointer resampler = itk::ResampleImageFilter::New(); resampler->SetInput(m_FrequencyMap); resampler->SetOutputParametersFromImage(m_FrequencyMap); resampler->SetSize(m_UpsampledImageRegion.GetSize()); resampler->SetOutputSpacing(m_UpsampledSpacing); resampler->Update(); m_FrequencyMap = resampler->GetOutput(); } } // no input tissue mask is set -> create default if (m_TissueMask.IsNull()) { m_TissueMask = ItkUcharImgType::New(); m_TissueMask->SetSpacing( m_UpsampledSpacing ); m_TissueMask->SetOrigin( m_Origin ); m_TissueMask->SetDirection( m_DirectionMatrix ); m_TissueMask->SetLargestPossibleRegion( m_UpsampledImageRegion ); m_TissueMask->SetBufferedRegion( m_UpsampledImageRegion ); m_TissueMask->SetRequestedRegion( m_UpsampledImageRegion ); m_TissueMask->Allocate(); m_TissueMask->FillBuffer(1); } m_ImageRegion = croppedRegion; x=m_ImageRegion.GetSize(0); y=m_ImageRegion.GetSize(1); if ( x%2 == 1 ) m_ImageRegion.SetSize(0, x+1); if ( y%2 == 1 ) m_ImageRegion.SetSize(1, y+1); // resample fiber bundle for sufficient voxel coverage double segmentVolume = 0.0001; float minSpacing = 1; if(m_UpsampledSpacing[0]GetDeepCopy(); fiberBundle->ResampleFibers(minSpacing/m_VolumeAccuracy); double mmRadius = m_FiberRadius/1000; if (mmRadius>0) segmentVolume = M_PI*mmRadius*mmRadius*minSpacing/m_VolumeAccuracy; double interpFact = 2*atan(-0.5*m_InterpolationShrink); double maxVolume = 0; MITK_INFO << "Generating signal of " << m_FiberModels.size() << " fiber compartments"; vtkSmartPointer fiberPolyData = fiberBundle->GetFiberPolyData(); boost::progress_display disp(numFibers); for( int i=0; iGetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (numPoints<2) continue; for( int j=0; jGetPoint(j); itk::Point vertex = GetItkPoint(temp); itk::Vector v = GetItkVector(temp); itk::Vector dir(3); if (jGetPoint(j+1))-v; else dir = v-GetItkVector(points->GetPoint(j-1)); itk::Index<3> idx; itk::ContinuousIndex contIndex; m_TissueMask->TransformPhysicalPointToIndex(vertex, idx); m_TissueMask->TransformPhysicalPointToContinuousIndex(vertex, contIndex); if (!m_UseInterpolation) // use nearest neighbour interpolation { if (!m_TissueMask->GetLargestPossibleRegion().IsInside(idx) || m_TissueMask->GetPixel(idx)<=0) continue; // generate signal for each fiber compartment for (unsigned int k=0; kSetFiberDirection(dir); DoubleDwiType::PixelType pix = doubleDwi->GetPixel(idx); pix += segmentVolume*m_FiberModels[k]->SimulateMeasurement(); doubleDwi->SetPixel(idx, pix ); if (pix[baselineIndex]>maxVolume) maxVolume = pix[baselineIndex]; } continue; } double frac_x = contIndex[0] - idx[0]; double frac_y = contIndex[1] - idx[1]; double frac_z = contIndex[2] - idx[2]; if (frac_x<0) { idx[0] -= 1; frac_x += 1; } if (frac_y<0) { idx[1] -= 1; frac_y += 1; } if (frac_z<0) { idx[2] -= 1; frac_z += 1; } frac_x = atan((0.5-frac_x)*m_InterpolationShrink)/interpFact + 0.5; frac_y = atan((0.5-frac_y)*m_InterpolationShrink)/interpFact + 0.5; frac_z = atan((0.5-frac_z)*m_InterpolationShrink)/interpFact + 0.5; // use trilinear interpolation itk::Index<3> newIdx; for (int x=0; x<2; x++) { frac_x = 1-frac_x; for (int y=0; y<2; y++) { frac_y = 1-frac_y; for (int z=0; z<2; z++) { frac_z = 1-frac_z; newIdx[0] = idx[0]+x; newIdx[1] = idx[1]+y; newIdx[2] = idx[2]+z; double frac = frac_x*frac_y*frac_z; // is position valid? if (!m_TissueMask->GetLargestPossibleRegion().IsInside(newIdx) || m_TissueMask->GetPixel(newIdx)<=0) continue; // generate signal for each fiber compartment for (unsigned int k=0; kSetFiberDirection(dir); DoubleDwiType::PixelType pix = doubleDwi->GetPixel(newIdx); pix += segmentVolume*frac*m_FiberModels[k]->SimulateMeasurement(); doubleDwi->SetPixel(newIdx, pix ); if (pix[baselineIndex]>maxVolume) maxVolume = pix[baselineIndex]; } } } } } ++disp; } MITK_INFO << "Generating signal of " << m_NonFiberModels.size() << " non-fiber compartments"; ImageRegionIterator it3(m_TissueMask, m_TissueMask->GetLargestPossibleRegion()); boost::progress_display disp3(m_TissueMask->GetLargestPossibleRegion().GetNumberOfPixels()); double voxelVolume = m_UpsampledSpacing[0]*m_UpsampledSpacing[1]*m_UpsampledSpacing[2]; double fact = 1; if (m_FiberRadius<0.0001) fact = voxelVolume/maxVolume; while(!it3.IsAtEnd()) { DoubleDwiType::IndexType index = it3.GetIndex(); if (it3.Get()>0) { // get fiber volume fraction DoubleDwiType::Pointer fiberDwi = compartments.at(0); DoubleDwiType::PixelType fiberPix = fiberDwi->GetPixel(index); // intra axonal compartment if (fact>1) // auto scale intra-axonal if no fiber radius is specified { fiberPix *= fact; fiberDwi->SetPixel(index, fiberPix); } double f = fiberPix[baselineIndex]; if (f>voxelVolume || (f>0.0 && m_EnforcePureFiberVoxels) ) // more fiber than space in voxel? { fiberDwi->SetPixel(index, fiberPix*voxelVolume/f); m_VolumeFractions.at(0)->SetPixel(index, 1); } else { m_VolumeFractions.at(0)->SetPixel(index, f/voxelVolume); double nonf = voxelVolume-f; // non-fiber volume double inter = 0; if (m_FiberModels.size()>1) inter = nonf * f/voxelVolume; // intra-axonal fraction of non fiber compartment scales linearly with f double other = nonf - inter; // rest of compartment double singleinter = inter/(m_FiberModels.size()-1); // adjust non-fiber and intra-axonal signal for (unsigned int i=1; iGetPixel(index); if (pix[baselineIndex]>0) pix /= pix[baselineIndex]; pix *= singleinter; doubleDwi->SetPixel(index, pix); m_VolumeFractions.at(i)->SetPixel(index, singleinter/voxelVolume); } for (unsigned int i=0; iGetPixel(index) + m_NonFiberModels[i]->SimulateMeasurement()*other*m_NonFiberModels[i]->GetWeight(); doubleDwi->SetPixel(index, pix); m_VolumeFractions.at(i+m_FiberModels.size())->SetPixel(index, other/voxelVolume*m_NonFiberModels[i]->GetWeight()); } } } ++it3; ++disp3; } // do k-space stuff DoubleDwiType::Pointer doubleOutImage; - if (m_Spikes>0 || m_FrequencyMap.IsNotNull() || !m_KspaceArtifacts.empty() || m_kOffset>0 || m_SimulateRelaxation || m_SimulateEddyCurrents || m_AddGibbsRinging || m_Wrap<1.0) + if (m_Spikes>0 || m_FrequencyMap.IsNotNull() || m_kOffset>0 || m_SimulateRelaxation || m_SimulateEddyCurrents || m_AddGibbsRinging || m_Wrap<1.0) { MITK_INFO << "Adjusting complex signal"; doubleOutImage = DoKspaceStuff(compartments); m_SignalScale = 1; } else { MITK_INFO << "Summing compartments"; doubleOutImage = compartments.at(0); for (unsigned int i=1; i::Pointer adder = itk::AddImageFilter< DoubleDwiType, DoubleDwiType, DoubleDwiType>::New(); adder->SetInput1(doubleOutImage); adder->SetInput2(compartments.at(i)); adder->Update(); doubleOutImage = adder->GetOutput(); } } MITK_INFO << "Finalizing image"; unsigned int window = 0; unsigned int min = itk::NumericTraits::max(); ImageRegionIterator it4 (outImage, outImage->GetLargestPossibleRegion()); DoubleDwiType::PixelType signal; signal.SetSize(m_FiberModels[0]->GetNumGradients()); boost::progress_display disp4(outImage->GetLargestPossibleRegion().GetNumberOfPixels()); while(!it4.IsAtEnd()) { ++disp4; typename OutputImageType::IndexType index = it4.GetIndex(); signal = doubleOutImage->GetPixel(index)*m_SignalScale; - if (m_NoiseModel->GetNoiseVariance() > 0) + if (m_NoiseModel!=NULL) { DoubleDwiType::PixelType accu = signal; accu.Fill(0.0); for (unsigned int i=0; iAddNoise(temp); accu += temp; } signal = accu/m_NumberOfRepetitions; } for (unsigned int i=0; i0) signal[i] = floor(signal[i]+0.5); else signal[i] = ceil(signal[i]-0.5); if (!m_FiberModels.at(0)->IsBaselineIndex(i) && signal[i]>window) window = signal[i]; if (!m_FiberModels.at(0)->IsBaselineIndex(i) && signal[i]SetNthOutput(0, outImage); } template< class PixelType > itk::Point TractsToDWIImageFilter< PixelType >::GetItkPoint(double point[3]) { itk::Point itkPoint; itkPoint[0] = point[0]; itkPoint[1] = point[1]; itkPoint[2] = point[2]; return itkPoint; } template< class PixelType > itk::Vector TractsToDWIImageFilter< PixelType >::GetItkVector(double point[3]) { itk::Vector itkVector; itkVector[0] = point[0]; itkVector[1] = point[1]; itkVector[2] = point[2]; return itkVector; } template< class PixelType > vnl_vector_fixed TractsToDWIImageFilter< PixelType >::GetVnlVector(double point[3]) { vnl_vector_fixed vnlVector; vnlVector[0] = point[0]; vnlVector[1] = point[1]; vnlVector[2] = point[2]; return vnlVector; } template< class PixelType > vnl_vector_fixed TractsToDWIImageFilter< PixelType >::GetVnlVector(Vector& vector) { vnl_vector_fixed vnlVector; vnlVector[0] = vector[0]; vnlVector[1] = vector[1]; vnlVector[2] = vector[2]; return vnlVector; } } diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.h b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.h index 4d7f6437b7..a58cbd981f 100755 --- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.h +++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.h @@ -1,161 +1,157 @@ /*=================================================================== 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 __itkTractsToDWIImageFilter_h__ #define __itkTractsToDWIImageFilter_h__ // MITK #include #include #include -#include // ITK #include #include #include #include #include #include namespace itk { /** * \brief Generates artificial diffusion weighted image volume from the input fiberbundle using a generic multicompartment model. */ template< class PixelType > class TractsToDWIImageFilter : public ImageSource< itk::VectorImage< PixelType, 3 > > { public: typedef TractsToDWIImageFilter Self; typedef ImageSource< itk::VectorImage< PixelType, 3 > > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; typedef typename Superclass::OutputImageType OutputImageType; typedef itk::Image ItkDoubleImgType; typedef itk::Image ItkFloatImgType; typedef itk::Image ItkUcharImgType; typedef mitk::FiberBundleX::Pointer FiberBundleType; typedef itk::VectorImage< double, 3 > DoubleDwiType; - typedef std::vector< mitk::KspaceArtifact* > KspaceArtifactList; typedef std::vector< mitk::DiffusionSignalModel* > DiffusionModelList; typedef itk::Matrix MatrixType; typedef mitk::DiffusionNoiseModel NoiseModelType; typedef itk::Image< double, 2 > SliceType; typedef itk::VnlForwardFFTImageFilter::OutputImageType ComplexSliceType; typedef itk::Vector< double,3> VectorType; typedef itk::Point< double,3> PointType; itkNewMacro(Self) itkTypeMacro( TractsToDWIImageFilter, ImageToImageFilter ) // input itkSetMacro( SignalScale, double ) itkSetMacro( FiberRadius, double ) itkSetMacro( InterpolationShrink, double ) ///< large values shrink (towards nearest neighbour interpolation), small values strech interpolation function (towards linear interpolation) itkSetMacro( VolumeAccuracy, unsigned int ) ///< determines fiber sampling density and thereby the accuracy of the fiber volume fraction itkSetMacro( FiberBundle, FiberBundleType ) ///< input fiber bundle itkSetMacro( Spacing, VectorType ) ///< output image spacing itkSetMacro( Origin, PointType ) ///< output image origin itkSetMacro( DirectionMatrix, MatrixType ) ///< output image rotation itkSetMacro( EnforcePureFiberVoxels, bool ) ///< treat all voxels containing at least one fiber as fiber-only (actually disable non-fiber compartments for this voxel). itkSetMacro( ImageRegion, ImageRegion<3> ) ///< output image size itkSetMacro( NumberOfRepetitions, unsigned int ) ///< number of acquisition repetitions to reduce noise (default is no additional repetition) itkSetMacro( TissueMask, ItkUcharImgType::Pointer ) ///< voxels outside of this binary mask contain only noise (are treated as air) void SetNoiseModel(NoiseModelType* noiseModel){ m_NoiseModel = noiseModel; } ///< generates the noise added to the image values void SetFiberModels(DiffusionModelList modelList){ m_FiberModels = modelList; } ///< generate signal of fiber compartments void SetNonFiberModels(DiffusionModelList modelList){ m_NonFiberModels = modelList; } ///< generate signal of non-fiber compartments - void SetKspaceArtifacts(KspaceArtifactList artifactList){ m_KspaceArtifacts = artifactList; } mitk::LevelWindow GetLevelWindow(){ return m_LevelWindow; } itkSetMacro( FrequencyMap, ItkDoubleImgType::Pointer ) itkSetMacro( kOffset, double ) itkSetMacro( tLine, double ) itkSetMacro( tInhom, double ) itkSetMacro( TE, double ) itkSetMacro( UseInterpolation, bool ) itkSetMacro( SimulateEddyCurrents, bool ) itkSetMacro( SimulateRelaxation, bool ) itkSetMacro( EddyGradientStrength, double ) itkSetMacro( AddGibbsRinging, bool ) itkSetMacro( Spikes, int ) itkSetMacro( SpikeAmplitude, double ) itkSetMacro( Wrap, double ) // output std::vector< ItkDoubleImgType::Pointer > GetVolumeFractions(){ return m_VolumeFractions; } void GenerateData(); protected: TractsToDWIImageFilter(); virtual ~TractsToDWIImageFilter(); itk::Point GetItkPoint(double point[3]); itk::Vector GetItkVector(double point[3]); vnl_vector_fixed GetVnlVector(double point[3]); vnl_vector_fixed GetVnlVector(Vector< float, 3 >& vector); /** Transform generated image compartment by compartment, channel by channel and slice by slice using FFT and add k-space artifacts. */ DoubleDwiType::Pointer DoKspaceStuff(std::vector< DoubleDwiType::Pointer >& images); // /** Rearrange FFT output to shift low frequencies to the iamge center (correct itk). */ // TractsToDWIImageFilter::ComplexSliceType::Pointer RearrangeSlice(ComplexSliceType::Pointer slice); itk::Vector m_Spacing; ///< output image spacing itk::Vector m_UpsampledSpacing; itk::Point m_Origin; ///< output image origin MatrixType m_DirectionMatrix; ///< output image rotation ImageRegion<3> m_ImageRegion; ///< output image size ImageRegion<3> m_UpsampledImageRegion; ItkUcharImgType::Pointer m_TissueMask; ///< voxels outside of this binary mask contain only noise (are treated as air) ItkDoubleImgType::Pointer m_FrequencyMap; ///< map of the B0 inhomogeneities double m_kOffset; double m_tLine; double m_TE; double m_tInhom; FiberBundleType m_FiberBundle; ///< input fiber bundle DiffusionModelList m_FiberModels; ///< generate signal of fiber compartments DiffusionModelList m_NonFiberModels; ///< generate signal of non-fiber compartments - KspaceArtifactList m_KspaceArtifacts; NoiseModelType* m_NoiseModel; ///< generates the noise added to the image values bool m_CircleDummy; unsigned int m_VolumeAccuracy; bool m_AddGibbsRinging; ///< causes ringing artifacts unsigned int m_NumberOfRepetitions; bool m_EnforcePureFiberVoxels; double m_InterpolationShrink; double m_FiberRadius; double m_SignalScale; mitk::LevelWindow m_LevelWindow; bool m_UseInterpolation; std::vector< ItkDoubleImgType::Pointer > m_VolumeFractions; ///< one double image for each compartment containing the corresponding volume fraction per voxel bool m_SimulateRelaxation; bool m_SimulateEddyCurrents; double m_EddyGradientStrength; int m_Spikes; double m_SpikeAmplitude; double m_Wrap; }; } #include "itkTractsToDWIImageFilter.cpp" #endif diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkChiSquareNoiseModel.cpp b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkChiSquareNoiseModel.cpp new file mode 100644 index 0000000000..d1977bc9a4 --- /dev/null +++ b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkChiSquareNoiseModel.cpp @@ -0,0 +1,39 @@ +/*=================================================================== + +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 +#include +#include + +using namespace mitk; + +template< class ScalarType > +ChiSquareNoiseModel< ScalarType >::ChiSquareNoiseModel() +{ + +} + +template< class ScalarType > +ChiSquareNoiseModel< ScalarType >::~ChiSquareNoiseModel() +{ + +} + +template< class ScalarType > +void ChiSquareNoiseModel< ScalarType >::AddNoise(PixelType& pixel) +{ + for( unsigned int i=0; i #include namespace mitk { /** * \brief Implementation of noise following a rician distribution * */ template< class ScalarType > -class RicianNoiseModel : public DiffusionNoiseModel< ScalarType > +class ChiSquareNoiseModel : public DiffusionNoiseModel< ScalarType > { public: - RicianNoiseModel(); - ~RicianNoiseModel(); + ChiSquareNoiseModel(); + ~ChiSquareNoiseModel(); typedef typename DiffusionNoiseModel< ScalarType >::PixelType PixelType; /** Adds rician noise to the input pixel **/ void AddNoise(PixelType& pixel); -protected: + void SetDOF(double var){ m_Distribution = boost::random::chi_squared_distribution(var); } + double GetNoiseVariance(){ return m_Distribution.n(); } - itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer m_RandGen; +protected: + boost::random::mt19937 m_Randgen; + boost::random::chi_squared_distribution m_Distribution; }; } -#include "mitkRicianNoiseModel.cpp" +#include "mitkChiSquareNoiseModel.cpp" #endif diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkDiffusionNoiseModel.h b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkDiffusionNoiseModel.h index ef545d6511..695f1c312a 100644 --- a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkDiffusionNoiseModel.h +++ b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkDiffusionNoiseModel.h @@ -1,56 +1,53 @@ /*=================================================================== 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 _MITK_DiffusionNoiseModel_H #define _MITK_DiffusionNoiseModel_H #include #include #include #include +#include namespace mitk { /** * \brief Abstract class for diffusion noise models * */ template< class ScalarType > class DiffusionNoiseModel { public: DiffusionNoiseModel(){} ~DiffusionNoiseModel(){} typedef itk::VariableLengthVector< ScalarType > PixelType; /** Adds noise according to model to the input pixel. Has to be implemented in subclass. **/ virtual void AddNoise(PixelType& pixel) = 0; - void SetNoiseVariance(double var){ m_NoiseVariance = var; } - double GetNoiseVariance(){ return m_NoiseVariance; } - protected: - double m_NoiseVariance; ///< variance of underlying distribution }; } #endif diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkKspaceArtifact.h b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkKspaceArtifact.h deleted file mode 100644 index 42d575de35..0000000000 --- a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkKspaceArtifact.h +++ /dev/null @@ -1,64 +0,0 @@ -/*=================================================================== - -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 _MITK_KspaceArtifact_H -#define _MITK_KspaceArtifact_H - -#include -#include -#include - -namespace mitk { - -/** - * \brief Abstract class for diffusion noise models - * - */ - -template< class ScalarType > -class KspaceArtifact -{ -public: - - KspaceArtifact() - : m_TE(100) - , m_Tinhom(50) - , m_LineReadoutTime(1) - { - } - ~KspaceArtifact(){} - - typedef itk::Image< ScalarType, 2 > WorkImageType; - typedef typename itk::VnlForwardFFTImageFilter< WorkImageType >::OutputImageType ComplexSliceType; - - /** Adds artifact according to model to the input slice. Has to be implemented in subclass. **/ - virtual typename ComplexSliceType::Pointer AddArtifact(typename ComplexSliceType::Pointer slice) = 0; - - void SetTline(double LineReadoutTime){ m_LineReadoutTime=LineReadoutTime; } - void SetTE(double TE){ m_TE=TE; } - void SetTinhom(unsigned int Tinhom){ m_Tinhom=Tinhom; } - -protected: - - double m_Tinhom; - double m_TE; - double m_LineReadoutTime; -}; - -} - -#endif - diff --git a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkRicianNoiseModel.h b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkRicianNoiseModel.h index 5fc1260ed4..ae7b9fc82e 100644 --- a/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkRicianNoiseModel.h +++ b/Modules/DiffusionImaging/FiberTracking/SignalModels/mitkRicianNoiseModel.h @@ -1,54 +1,58 @@ /*=================================================================== 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 _MITK_RicianNoiseModel_H #define _MITK_RicianNoiseModel_H #include #include namespace mitk { /** * \brief Implementation of noise following a rician distribution * */ template< class ScalarType > class RicianNoiseModel : public DiffusionNoiseModel< ScalarType > { public: RicianNoiseModel(); ~RicianNoiseModel(); typedef typename DiffusionNoiseModel< ScalarType >::PixelType PixelType; /** Adds rician noise to the input pixel **/ void AddNoise(PixelType& pixel); + void SetNoiseVariance(double var){ m_NoiseVariance = var; } + double GetNoiseVariance(){ return m_NoiseVariance; } + protected: itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer m_RandGen; + double m_NoiseVariance; ///< variance of underlying distribution }; } #include "mitkRicianNoiseModel.cpp" #endif diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/CMakeLists.txt b/Modules/DiffusionImaging/FiberTracking/Testing/CMakeLists.txt index a4a636d3c4..5fbb85bdd8 100644 --- a/Modules/DiffusionImaging/FiberTracking/Testing/CMakeLists.txt +++ b/Modules/DiffusionImaging/FiberTracking/Testing/CMakeLists.txt @@ -1,9 +1,11 @@ MITK_CREATE_MODULE_TESTS() mitkAddCustomModuleTest(mitkFiberBundleXReaderWriterTest mitkFiberBundleXReaderWriterTest ${MITK_DATA_DIR}/DiffusionImaging/fiberBundleX.fib) mitkAddCustomModuleTest(mitkGibbsTrackingTest mitkGibbsTrackingTest ${MITK_DATA_DIR}/DiffusionImaging/qBallImage.qbi ${MITK_DATA_DIR}/DiffusionImaging/diffusionImageMask.nrrd ${MITK_DATA_DIR}/DiffusionImaging/gibbsTrackingParameters.gtp ${MITK_DATA_DIR}/DiffusionImaging/gibbsTractogram.fib) mitkAddCustomModuleTest(mitkStreamlineTrackingTest mitkStreamlineTrackingTest ${MITK_DATA_DIR}/DiffusionImaging/tensorImage.dti ${MITK_DATA_DIR}/DiffusionImaging/diffusionImageMask.nrrd ${MITK_DATA_DIR}/DiffusionImaging/streamlineTractogram.fib) mitkAddCustomModuleTest(mitkPeakExtractionTest mitkPeakExtractionTest ${MITK_DATA_DIR}/DiffusionImaging/qBallImage_SHCoeffs.nrrd ${MITK_DATA_DIR}/DiffusionImaging/diffusionImageMask.nrrd ${MITK_DATA_DIR}/DiffusionImaging/qBallImage_VectorField.fib) mitkAddCustomModuleTest(mitkLocalFiberPlausibilityTest mitkLocalFiberPlausibilityTest ${MITK_DATA_DIR}/DiffusionImaging/streamlineTractogram.fib ${MITK_DATA_DIR}/DiffusionImaging/LDFP_GT_DIRECTION_0.nrrd ${MITK_DATA_DIR}/DiffusionImaging/LDFP_GT_DIRECTION_1.nrrd ${MITK_DATA_DIR}/DiffusionImaging/LDFP_ERROR_IMAGE.nrrd ${MITK_DATA_DIR}/DiffusionImaging/LDFP_NUM_DIRECTIONS.nrrd ${MITK_DATA_DIR}/DiffusionImaging/LDFP_VECTOR_FIELD.fib ${MITK_DATA_DIR}/DiffusionImaging/LDFP_OUT_DIRECTION_0.nrrd ${MITK_DATA_DIR}/DiffusionImaging/LDFP_OUT_DIRECTION_1.nrrd ${MITK_DATA_DIR}/DiffusionImaging/LDFP_OUT_DIRECTION_2.nrrd ${MITK_DATA_DIR}/DiffusionImaging/LDFP_ERROR_IMAGE_IGNORE.nrrd) mitkAddCustomModuleTest(mitkFiberTransformationTest mitkFiberTransformationTest ${MITK_DATA_DIR}/DiffusionImaging/fiberBundleX.fib ${MITK_DATA_DIR}/DiffusionImaging/fiberBundleX_transformed.fib) mitkAddCustomModuleTest(mitkFiberExtractionTest mitkFiberExtractionTest ${MITK_DATA_DIR}/DiffusionImaging/fiberBundleX.fib ${MITK_DATA_DIR}/DiffusionImaging/fiberBundleX_extracted.fib ${MITK_DATA_DIR}/DiffusionImaging/ROI1.pf ${MITK_DATA_DIR}/DiffusionImaging/ROI2.pf ${MITK_DATA_DIR}/DiffusionImaging/ROI3.pf ${MITK_DATA_DIR}/DiffusionImaging/ROIIMAGE.nrrd ${MITK_DATA_DIR}/DiffusionImaging/fiberBundleX_inside.fib ${MITK_DATA_DIR}/DiffusionImaging/fiberBundleX_outside.fib ${MITK_DATA_DIR}/DiffusionImaging/fiberBundleX_passing-mask.fib ${MITK_DATA_DIR}/DiffusionImaging/fiberBundleX_ending-in-mask.fib ${MITK_DATA_DIR}/DiffusionImaging/fiberBundleX-fiberBundleX_extracted.fib) +mitkAddCustomModuleTest(mitkFiberGenerationTest mitkFiberGenerationTest ${MITK_DATA_DIR}/DiffusionImaging/Fiberfox/Fiducial_0.pf ${MITK_DATA_DIR}/DiffusionImaging/Fiberfox/Fiducial_1.pf ${MITK_DATA_DIR}/DiffusionImaging/Fiberfox/Fiducial_2.pf ${MITK_DATA_DIR}/DiffusionImaging/Fiberfox/uniform.fib ${MITK_DATA_DIR}/DiffusionImaging/Fiberfox/gaussian.fib) +# TODO: fiberfox signalgen diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/files.cmake b/Modules/DiffusionImaging/FiberTracking/Testing/files.cmake index 70d4aede2c..64863cfc8f 100644 --- a/Modules/DiffusionImaging/FiberTracking/Testing/files.cmake +++ b/Modules/DiffusionImaging/FiberTracking/Testing/files.cmake @@ -1,11 +1,12 @@ SET(MODULE_CUSTOM_TESTS mitkFiberBundleXReaderWriterTest.cpp mitkGibbsTrackingTest.cpp mitkStreamlineTrackingTest.cpp mitkPeakExtractionTest.cpp mitkLocalFiberPlausibilityTest.cpp mitkFiberTransformationTest.cpp mitkFiberExtractionTest.cpp + mitkFiberGenerationTest.cpp ) diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberGenerationTest.cpp b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberGenerationTest.cpp new file mode 100644 index 0000000000..65634e700e --- /dev/null +++ b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberGenerationTest.cpp @@ -0,0 +1,89 @@ +/*=================================================================== + +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 +#include +#include +#include +#include +#include +#include + +/**Documentation + * Test if fiber transfortaiom methods work correctly + */ +int mitkFiberGenerationTest(int argc, char* argv[]) +{ + MITK_TEST_BEGIN("mitkFiberGenerationTest"); + + MITK_TEST_CONDITION_REQUIRED(argc==6,"check for input data") + + try{ + RegisterFiberTrackingObjectFactory(); + + mitk::PlanarEllipse::Pointer pf1 = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[1])->GetData()); + mitk::PlanarEllipse::Pointer pf2 = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[2])->GetData()); + mitk::PlanarEllipse::Pointer pf3 = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[3])->GetData()); + mitk::FiberBundleX::Pointer uniform = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[4])->GetData()); + mitk::FiberBundleX::Pointer gaussian = dynamic_cast(mitk::IOUtil::LoadDataNode(argv[5])->GetData()); + + + vector< mitk::PlanarEllipse::Pointer > fid; fid.push_back(pf1); fid.push_back(pf2); fid.push_back(pf3); + vector< unsigned int > flip; flip.push_back(0); flip.push_back(0); flip.push_back(0); + vector< vector< mitk::PlanarEllipse::Pointer > > fiducials; + vector< vector< unsigned int > > fliplist; + fiducials.push_back(fid); fliplist.push_back(flip); + + // check uniform fiber distribution + { + itk::FibersFromPlanarFiguresFilter::Pointer filter = itk::FibersFromPlanarFiguresFilter::New(); + filter->SetFiducials(fiducials); + filter->SetFlipList(fliplist); + filter->SetFiberDistribution(itk::FibersFromPlanarFiguresFilter::DISTRIBUTE_UNIFORM); + filter->SetDensity(50); + filter->SetTension(0); + filter->SetContinuity(0); + filter->SetBias(0); + filter->SetFiberSampling(1); + filter->Update(); + vector< mitk::FiberBundleX::Pointer > fiberBundles = filter->GetFiberBundles(); + MITK_TEST_CONDITION_REQUIRED(uniform->Equals(fiberBundles.at(0)),"check uniform bundle") + } + + // check gaussian fiber distribution + { + itk::FibersFromPlanarFiguresFilter::Pointer filter = itk::FibersFromPlanarFiguresFilter::New(); + filter->SetFiducials(fiducials); + filter->SetFlipList(fliplist); + filter->SetFiberDistribution(itk::FibersFromPlanarFiguresFilter::DISTRIBUTE_GAUSSIAN); + filter->SetVariance(0.1); + filter->SetDensity(50); + filter->SetTension(0); + filter->SetContinuity(0); + filter->SetBias(0); + filter->SetFiberSampling(1); + filter->Update(); + vector< mitk::FiberBundleX::Pointer > fiberBundles = filter->GetFiberBundles(); + MITK_TEST_CONDITION_REQUIRED(gaussian->Equals(fiberBundles.at(0)),"check gaussian bundle") + } + } + catch(...) { + return EXIT_FAILURE; + } + + // always end with this! + MITK_TEST_END(); +} diff --git a/Modules/DiffusionImaging/FiberTracking/files.cmake b/Modules/DiffusionImaging/FiberTracking/files.cmake index 8ea747434e..56a3dfe386 100644 --- a/Modules/DiffusionImaging/FiberTracking/files.cmake +++ b/Modules/DiffusionImaging/FiberTracking/files.cmake @@ -1,103 +1,103 @@ set(CPP_FILES # DataStructures -> FiberBundleX IODataStructures/FiberBundleX/mitkFiberBundleX.cpp IODataStructures/FiberBundleX/mitkFiberBundleXWriter.cpp IODataStructures/FiberBundleX/mitkFiberBundleXReader.cpp IODataStructures/FiberBundleX/mitkFiberBundleXIOFactory.cpp IODataStructures/FiberBundleX/mitkFiberBundleXWriterFactory.cpp IODataStructures/FiberBundleX/mitkFiberBundleXSerializer.cpp IODataStructures/FiberBundleX/mitkTrackvis.cpp # IODataStructures/FiberBundleX/mitkFiberBundleXThreadMonitor.cpp # DataStructures -> PlanarFigureComposite IODataStructures/PlanarFigureComposite/mitkPlanarFigureComposite.cpp # DataStructures IODataStructures/mitkFiberTrackingObjectFactory.cpp # Rendering Rendering/mitkFiberBundleXMapper2D.cpp Rendering/mitkFiberBundleXMapper3D.cpp # Rendering/mitkFiberBundleXThreadMonitorMapper3D.cpp #Rendering/mitkPlanarFigureMapper3D.cpp # Interactions Interactions/mitkFiberBundleInteractor.cpp # Tractography Algorithms/GibbsTracking/mitkParticleGrid.cpp Algorithms/GibbsTracking/mitkMetropolisHastingsSampler.cpp Algorithms/GibbsTracking/mitkEnergyComputer.cpp Algorithms/GibbsTracking/mitkGibbsEnergyComputer.cpp Algorithms/GibbsTracking/mitkFiberBuilder.cpp Algorithms/GibbsTracking/mitkSphereInterpolator.cpp ) set(H_FILES # Rendering Rendering/mitkFiberBundleXMapper3D.h Rendering/mitkFiberBundleXMapper2D.h # Rendering/mitkFiberBundleXThreadMonitorMapper3D.h #Rendering/mitkPlanarFigureMapper3D.h # DataStructures -> FiberBundleX IODataStructures/FiberBundleX/mitkFiberBundleX.h IODataStructures/FiberBundleX/mitkFiberBundleXWriter.h IODataStructures/FiberBundleX/mitkFiberBundleXReader.h IODataStructures/FiberBundleX/mitkFiberBundleXIOFactory.h IODataStructures/FiberBundleX/mitkFiberBundleXWriterFactory.h IODataStructures/FiberBundleX/mitkFiberBundleXSerializer.h # IODataStructures/FiberBundleX/mitkFiberBundleXThreadMonitor.h IODataStructures/FiberBundleX/mitkTrackvis.h IODataStructures/mitkFiberTrackingObjectFactory.h # Algorithms Algorithms/itkTractDensityImageFilter.h Algorithms/itkTractsToFiberEndingsImageFilter.h Algorithms/itkTractsToRgbaImageFilter.h Algorithms/itkElectrostaticRepulsionDiffusionGradientReductionFilter.h Algorithms/itkFibersFromPlanarFiguresFilter.h Algorithms/itkTractsToDWIImageFilter.h Algorithms/itkTractsToVectorImageFilter.h Algorithms/itkKspaceImageFilter.h Algorithms/itkDftImageFilter.h Algorithms/itkAddArtifactsToDwiImageFilter.h Algorithms/itkFieldmapGeneratorFilter.h Algorithms/itkEvaluateDirectionImagesFilter.h Algorithms/itkEvaluateTractogramDirectionsFilter.h # (old) Tractography Algorithms/itkGibbsTrackingFilter.h Algorithms/itkStochasticTractographyFilter.h Algorithms/itkStreamlineTrackingFilter.h Algorithms/GibbsTracking/mitkParticle.h Algorithms/GibbsTracking/mitkParticleGrid.h Algorithms/GibbsTracking/mitkMetropolisHastingsSampler.h Algorithms/GibbsTracking/mitkSimpSamp.h Algorithms/GibbsTracking/mitkEnergyComputer.h Algorithms/GibbsTracking/mitkGibbsEnergyComputer.h Algorithms/GibbsTracking/mitkSphereInterpolator.h Algorithms/GibbsTracking/mitkFiberBuilder.h # Signal Models SignalModels/mitkDiffusionSignalModel.h SignalModels/mitkTensorModel.h SignalModels/mitkBallModel.h SignalModels/mitkDotModel.h SignalModels/mitkAstroStickModel.h SignalModels/mitkStickModel.h SignalModels/mitkDiffusionNoiseModel.h SignalModels/mitkRicianNoiseModel.h - SignalModels/mitkKspaceArtifact.h + SignalModels/mitkChiSquareNoiseModel.h ) set(RESOURCE_FILES # Binary directory resources FiberTrackingLUTBaryCoords.bin FiberTrackingLUTIndices.bin # Shaders Shaders/mitkShaderFiberClipping.xml ) diff --git a/Modules/DiffusionImaging/MiniApps/FiberFoxProcessing.cpp b/Modules/DiffusionImaging/MiniApps/FiberFoxProcessing.cpp index 48464741b2..f202e2f69b 100755 --- a/Modules/DiffusionImaging/MiniApps/FiberFoxProcessing.cpp +++ b/Modules/DiffusionImaging/MiniApps/FiberFoxProcessing.cpp @@ -1,550 +1,547 @@ /*=================================================================== 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 "MiniAppManager.h" #include #include #include #include #include #include #include #include //#include "ctkCommandLineParser.h" #include "ctkCommandLineParser.h" #include #include #include #include "boost/property_tree/ptree.hpp" #include "boost/property_tree/xml_parser.hpp" #include "boost/foreach.hpp" #include #include #include #include #include using namespace mitk; struct ImageParameters { itk::ImageRegion<3> imageRegion; itk::Vector imageSpacing; itk::Point imageOrigin; itk::Matrix imageDirection; unsigned int numGradients; double b_value; unsigned int repetitions; double signalScale; double tEcho; double tLine; double tInhom; double axonRadius; unsigned int interpolationShrink; double kspaceLineOffset; double upsampling; double eddyStrength; double comp3Weight; double comp4Weight; int spikes; double spikeAmplitude; bool doSimulateRelaxation; bool doSimulateEddyCurrents; bool doDisablePartialVolume; mitk::RicianNoiseModel ricianNoiseModel; mitk::DiffusionSignalModel::GradientListType gradientDirections; itk::TractsToDWIImageFilter< short >::DiffusionModelList fiberModelList, nonFiberModelList; - itk::TractsToDWIImageFilter< short >::KspaceArtifactList artifactList; std::string signalModelString, artifactModelString; itk::Image::Pointer frequencyMap; itk::Image::Pointer tissueMaskImage; mitk::DataNode::Pointer resultNode; }; void LoadParameters(const std::string & filename, ImageParameters & m_ImageGenParameters, mitk::Image::Pointer m_fImage, mitk::Image::Pointer m_maskImage, mitk::StickModel * m_StickModel1, mitk::StickModel * m_StickModel2, mitk::TensorModel * m_ZeppelinModel1, mitk::TensorModel * m_ZeppelinModel2, mitk::TensorModel * m_TensorModel1, mitk::TensorModel * m_TensorModel2, // extra axonal compartment models mitk::BallModel * m_BallModel1, mitk::BallModel * m_BallModel2, mitk::AstroStickModel * m_AstrosticksModel1, mitk::AstroStickModel * m_AstrosticksModel2, mitk::DotModel * m_DotModel1, mitk::DotModel * m_DotModel2) { MITK_INFO << "Initialize Diffusion Models"; boost::property_tree::ptree parameters; boost::property_tree::xml_parser::read_xml(filename, parameters); - 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; MITK_INFO << "reset params"; BOOST_FOREACH( boost::property_tree::ptree::value_type const& v1, parameters.get_child("fiberfox") ) { if( v1.first == "image" ) { MITK_INFO << "Load image params"; m_ImageGenParameters.tEcho = v1.second.get("tEcho"); m_ImageGenParameters.tLine = v1.second.get("tLine"); m_ImageGenParameters.doSimulateEddyCurrents = v1.second.get("artifacts.addeddy"); m_ImageGenParameters.eddyStrength = 0; if (m_ImageGenParameters.doSimulateEddyCurrents) { m_ImageGenParameters.eddyStrength = v1.second.get("artifacts.eddyStrength"); } // signal relaxation m_ImageGenParameters.doSimulateRelaxation = v1.second.get("doSimulateRelaxation"); if (m_ImageGenParameters.doSimulateRelaxation) // N/2 ghosts if (v1.second.get("artifacts.addghost")) { m_ImageGenParameters.kspaceLineOffset = v1.second.get("artifacts.kspaceLineOffset"); } else { m_ImageGenParameters.kspaceLineOffset = 0; } if (v1.second.get("artifacts.addspikes")) { m_ImageGenParameters.spikes = v1.second.get("artifacts.spikesnum"); m_ImageGenParameters.spikeAmplitude = v1.second.get("artifacts.spikesscale"); } // add distortions if (v1.second.get("artifacts.distortions") && m_fImage) { itk::Image::Pointer itkImg = itk::Image::New(); mitk::CastToItkImage< itk::Image >(m_fImage, 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; } } // rician noise if (v1.second.get("artifacts.addnoise")) m_ImageGenParameters.ricianNoiseModel.SetNoiseVariance(v1.second.get("artifacts.noisevariance")); else m_ImageGenParameters.ricianNoiseModel.SetNoiseVariance(0); // gibbs ringing m_ImageGenParameters.upsampling = 1; if (v1.second.get("artifacts.addringing")) m_ImageGenParameters.upsampling = v1.second.get("artifacts.ringingupsampling"); // 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; // check tissue mask if (m_maskImage.IsNotNull()) { m_ImageGenParameters.tissueMaskImage = itk::Image::New(); mitk::CastToItkImage >(m_maskImage.GetPointer(), m_ImageGenParameters.tissueMaskImage); } // signal models m_ImageGenParameters.comp3Weight = 1; m_ImageGenParameters.comp4Weight = 0; if (v1.second.get("compartment4.index") > 0) { m_ImageGenParameters.comp4Weight = v1.second.get("compartment4.weight"); m_ImageGenParameters.comp3Weight -= m_ImageGenParameters.comp4Weight; } // compartment 1 switch(v1.second.get("compartment1.index")){ case 0: m_StickModel1->SetGradientList(m_ImageGenParameters.gradientDirections); m_StickModel1->SetBvalue(m_ImageGenParameters.b_value); m_StickModel1->SetDiffusivity(v1.second.get("compartment1.stick.d")); m_StickModel1->SetT2(v1.second.get("compartment1.stick.t2")); m_ImageGenParameters.fiberModelList.push_back(m_StickModel1); break; case 1: m_ZeppelinModel1->SetGradientList(m_ImageGenParameters.gradientDirections); m_ZeppelinModel1->SetBvalue(m_ImageGenParameters.b_value); m_ZeppelinModel1->SetDiffusivity1(v1.second.get("compartment1.zeppelin.d1")); m_ZeppelinModel1->SetDiffusivity2(v1.second.get("compartment1.zeppelin.d2")); m_ZeppelinModel1->SetDiffusivity3(v1.second.get("compartment1.zeppelin.d2")); m_ZeppelinModel1->SetT2(v1.second.get("compartment1.zeppelin.t2")); m_ImageGenParameters.fiberModelList.push_back(m_ZeppelinModel1); break; case 2: m_TensorModel1->SetGradientList(m_ImageGenParameters.gradientDirections); m_TensorModel1->SetBvalue(m_ImageGenParameters.b_value); m_TensorModel1->SetDiffusivity1(v1.second.get("compartment1.tensor.d1")); m_TensorModel1->SetDiffusivity2(v1.second.get("compartment1.tensor.d2")); m_TensorModel1->SetDiffusivity3(v1.second.get("compartment1.tensor.d3")); m_TensorModel1->SetT2(v1.second.get("compartment1.tensor.t2")); m_ImageGenParameters.fiberModelList.push_back(m_TensorModel1); break; } // compartment 2 switch(v1.second.get("compartment2.index")){ case 0: m_StickModel2->SetGradientList(m_ImageGenParameters.gradientDirections); m_StickModel2->SetBvalue(m_ImageGenParameters.b_value); m_StickModel2->SetDiffusivity(v1.second.get("compartment2.stick.d")); m_StickModel2->SetT2(v1.second.get("compartment2.stick.t2")); m_ImageGenParameters.fiberModelList.push_back(m_StickModel2); break; case 1: m_ZeppelinModel2->SetGradientList(m_ImageGenParameters.gradientDirections); m_ZeppelinModel2->SetBvalue(m_ImageGenParameters.b_value); m_ZeppelinModel2->SetDiffusivity1(v1.second.get("compartment2.zeppelin.d1")); m_ZeppelinModel2->SetDiffusivity2(v1.second.get("compartment2.zeppelin.d2")); m_ZeppelinModel2->SetDiffusivity3(v1.second.get("compartment2.zeppelin.d2")); m_ZeppelinModel2->SetT2(v1.second.get("compartment2.zeppelin.t2")); m_ImageGenParameters.fiberModelList.push_back(m_ZeppelinModel2); break; case 2: m_TensorModel2->SetGradientList(m_ImageGenParameters.gradientDirections); m_TensorModel2->SetBvalue(m_ImageGenParameters.b_value); m_TensorModel2->SetDiffusivity1(v1.second.get("compartment2.tensor.d1")); m_TensorModel2->SetDiffusivity2(v1.second.get("compartment2.tensor.d2")); m_TensorModel2->SetDiffusivity3(v1.second.get("compartment2.tensor.d3")); m_TensorModel2->SetT2(v1.second.get("compartment2.tensor.t2")); m_ImageGenParameters.fiberModelList.push_back(m_TensorModel2); break; } // compartment 3 switch(v1.second.get("compartment3.index")){ case 0: m_BallModel1->SetGradientList(m_ImageGenParameters.gradientDirections); m_BallModel1->SetBvalue(m_ImageGenParameters.b_value); m_BallModel1->SetDiffusivity(v1.second.get("compartment3.ball.d")); m_BallModel1->SetT2(v1.second.get("compartment3.ball.t2")); m_BallModel1->SetWeight(m_ImageGenParameters.comp3Weight); m_ImageGenParameters.nonFiberModelList.push_back(m_BallModel1); break; case 1: m_AstrosticksModel1->SetGradientList(m_ImageGenParameters.gradientDirections); m_AstrosticksModel1->SetBvalue(m_ImageGenParameters.b_value); m_AstrosticksModel1->SetDiffusivity(v1.second.get("compartment3.astrosticks.d")); m_AstrosticksModel1->SetT2(v1.second.get("compartment3.astrosticks.t2")); m_AstrosticksModel1->SetRandomizeSticks(v1.second.get("compartment3.astrosticks.randomize")); m_AstrosticksModel1->SetWeight(m_ImageGenParameters.comp3Weight); m_ImageGenParameters.nonFiberModelList.push_back(m_AstrosticksModel1); break; case 2: m_DotModel1->SetGradientList(m_ImageGenParameters.gradientDirections); m_DotModel1->SetT2(v1.second.get("compartment3.dot.t2")); m_DotModel1->SetWeight(m_ImageGenParameters.comp3Weight); m_ImageGenParameters.nonFiberModelList.push_back(m_DotModel1); break; } // compartment 4 switch(v1.second.get("compartment4.index")){ case 0: m_BallModel2->SetGradientList(m_ImageGenParameters.gradientDirections); m_BallModel2->SetBvalue(m_ImageGenParameters.b_value); m_BallModel2->SetDiffusivity(v1.second.get("compartment4.ball.d")); m_BallModel2->SetT2(v1.second.get("compartment4.ball.t2")); m_BallModel2->SetWeight(m_ImageGenParameters.comp4Weight); m_ImageGenParameters.nonFiberModelList.push_back(m_BallModel2); break; case 1: m_AstrosticksModel2->SetGradientList(m_ImageGenParameters.gradientDirections); m_AstrosticksModel2->SetBvalue(m_ImageGenParameters.b_value); m_AstrosticksModel2->SetDiffusivity(v1.second.get("compartment4.astrosticks.d")); m_AstrosticksModel2->SetT2(v1.second.get("compartment4.astrosticks.t2")); m_AstrosticksModel2->SetRandomizeSticks(v1.second.get("compartment4.astrosticks.randomize")); m_AstrosticksModel2->SetWeight(m_ImageGenParameters.comp4Weight); m_ImageGenParameters.nonFiberModelList.push_back(m_AstrosticksModel2); break; case 2: m_DotModel2->SetGradientList(m_ImageGenParameters.gradientDirections); m_DotModel2->SetT2(v1.second.get("compartment4.dot.t2")); m_DotModel2->SetWeight(m_ImageGenParameters.comp4Weight); m_ImageGenParameters.nonFiberModelList.push_back(m_DotModel2); break; } m_ImageGenParameters.signalScale = v1.second.get("signalScale"); m_ImageGenParameters.repetitions = v1.second.get("repetitions"); m_ImageGenParameters.tInhom = v1.second.get("tInhom"); m_ImageGenParameters.doDisablePartialVolume = v1.second.get("doDisablePartialVolume"); m_ImageGenParameters.interpolationShrink = v1.second.get("interpolationShrink"); m_ImageGenParameters.axonRadius = v1.second.get("axonRadius"); } /* m_Controls->m_VarianceBox->setValue(v1.second.get("variance")); m_Controls->m_AdvancedOptionsBox->setChecked(v1.second.get("showadvanced")); m_Controls->m_AdvancedOptionsBox_2->setChecked(v1.second.get("showadvanced")); m_Controls->m_VolumeFractionsBox->setChecked(v1.second.get("outputvolumefractions")); m_Controls->m_RealTimeFibers->setChecked(v1.second.get("realtime")); m_Controls->m_DistributionBox->setCurrentIndex(v1.second.get("distribution")); 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")); */ } } int FiberFoxProcessing(int argc, char* argv[]) { ctkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("in", "i", ctkCommandLineParser::String, "input file", us::Any(), false); parser.addArgument("out", "o", ctkCommandLineParser::String, "output file", us::Any(), false); parser.addArgument("fiberbundle", "f", ctkCommandLineParser::String, "defined fiber bundle for signal generation", us::Any(), false); parser.addArgument("loadparameters", "l", ctkCommandLineParser::String, "load fiber fox signal parameter file", us::Any(), false); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments string inName = us::any_cast(parsedArgs["in"]); string outName = us::any_cast(parsedArgs["out"]); string fbName = us::any_cast(parsedArgs["fiberbundle"]); string paramName = us::any_cast(parsedArgs["loadparameters"]); { RegisterDiffusionCoreObjectFactory(); RegisterFiberTrackingObjectFactory(); ImageParameters m_ImageGenParameters; mitk::Image::Pointer m_maskImage = 0; mitk::Image::Pointer m_fImage = 0; MITK_INFO << "Loading " << inName; const std::string s1="", s2=""; std::vector infile = BaseDataIO::LoadBaseDataFromFile( inName, s1, s2, false ); mitk::BaseData::Pointer baseData = infile.at(0); MITK_INFO << "Loading " << fbName; std::vector infile2 = BaseDataIO::LoadBaseDataFromFile( fbName, s1, s2, false ); mitk::BaseData::Pointer baseData2 = infile2.at(0); DiffusionImage::Pointer dwi; FiberBundleX::Pointer fbi; if ( dynamic_cast*>(baseData.GetPointer()) ) dwi = dynamic_cast*>(baseData.GetPointer()); else MITK_ERROR << "LOADING DWI FAILD: " << inName; if ( dynamic_cast(baseData2.GetPointer()) ) fbi = dynamic_cast(baseData2.GetPointer()); else MITK_ERROR << "LOADING FBI FAILD: " << fbName; 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++; } mitk::StickModel m_StickModel1; mitk::StickModel m_StickModel2; mitk::TensorModel m_ZeppelinModel1; mitk::TensorModel m_ZeppelinModel2; mitk::TensorModel m_TensorModel1; mitk::TensorModel m_TensorModel2; // extra axonal compartment models mitk::BallModel m_BallModel1; mitk::BallModel m_BallModel2; mitk::AstroStickModel m_AstrosticksModel1; mitk::AstroStickModel m_AstrosticksModel2; mitk::DotModel m_DotModel1; mitk::DotModel m_DotModel2; LoadParameters(paramName,m_ImageGenParameters,NULL, NULL, &m_StickModel1, &m_StickModel2, &m_ZeppelinModel1, &m_ZeppelinModel2, &m_TensorModel1, &m_TensorModel2, &m_BallModel1, &m_BallModel2, &m_AstrosticksModel1, &m_AstrosticksModel2, &m_DotModel1, &m_DotModel2); MITK_INFO << "Parameter loaded"; itk::TractsToDWIImageFilter< short >::Pointer tractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New(); tractsToDwiFilter->SetSimulateEddyCurrents(m_ImageGenParameters.doSimulateEddyCurrents); tractsToDwiFilter->SetEddyGradientStrength(m_ImageGenParameters.eddyStrength); //tractsToDwiFilter->SetUpsampling(m_ImageGenParameters.upsampling); 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(fbi); 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->Update(); mitk::DiffusionImage::Pointer image = mitk::DiffusionImage::New(); image->SetVectorImage( tractsToDwiFilter->GetOutput() ); image->SetB_Value(dwi->GetB_Value()); image->SetDirections(dwi->GetDirections()); image->InitializeFromVectorImage(); MITK_INFO << "Writing " << outName; NrrdDiffusionImageWriter::Pointer writer = NrrdDiffusionImageWriter::New(); writer->SetFileName(outName); writer->SetInput(image); writer->Update(); } MITK_INFO << "DONE"; return EXIT_SUCCESS; } RegisterDiffusionMiniApp(FiberFoxProcessing); 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 b9c9bcbca0..101a30967b 100644 --- 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,2103 @@ /*=================================================================== 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" +#include #define _USE_MATH_DEFINES #include const std::string QmitkFiberfoxView::VIEW_ID = "org.mitk.views.fiberfoxview"; QmitkFiberfoxView::QmitkFiberfoxView() : QmitkAbstractView() , m_Controls( 0 ) , m_SelectedImage( NULL ) { - + m_ImageGenParameters.noiseModel = NULL; + m_ImageGenParameters.noiseModelShort = NULL; } // Destructor QmitkFiberfoxView::~QmitkFiberfoxView() { - + if (m_ImageGenParameters.noiseModel!=NULL) + delete m_ImageGenParameters.noiseModel; + if (m_ImageGenParameters.noiseModelShort!=NULL) + delete m_ImageGenParameters.noiseModelShort; } 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()) { + if (m_ImageGenParameters.noiseModel!=NULL) + delete m_ImageGenParameters.noiseModel; + if (m_ImageGenParameters.noiseModelShort!=NULL) + delete m_ImageGenParameters.noiseModelShort; + double noiseVariance = m_Controls->m_NoiseLevel->value(); - m_ImageGenParameters.ricianNoiseModel.SetNoiseVariance(noiseVariance); - m_ImageGenParameters.artifactModelString += "_NOISE"; + { + switch (m_Controls->m_NoiseDistributionBox->currentIndex()) + { + case 0: + { + mitk::RicianNoiseModel* rician = new mitk::RicianNoiseModel(); + rician->SetNoiseVariance(noiseVariance); + m_ImageGenParameters.noiseModel = rician; + m_ImageGenParameters.artifactModelString += "_RICIAN"; + break; + } + case 1: + { + mitk::ChiSquareNoiseModel* chiSquare = new mitk::ChiSquareNoiseModel(); + chiSquare->SetDOF(noiseVariance/2); + m_ImageGenParameters.noiseModel = chiSquare; + m_ImageGenParameters.artifactModelString += "_CHISQUARE"; + break; + } + default: + { + mitk::RicianNoiseModel* rician = new mitk::RicianNoiseModel(); + rician->SetNoiseVariance(noiseVariance); + m_ImageGenParameters.noiseModel = rician; + m_ImageGenParameters.artifactModelString += "_RICIAN"; + } + } + } + { + switch (m_Controls->m_NoiseDistributionBox->currentIndex()) + { + case 0: + { + mitk::RicianNoiseModel* rician = new mitk::RicianNoiseModel(); + rician->SetNoiseVariance(noiseVariance); + m_ImageGenParameters.noiseModelShort = rician; + break; + } + case 1: + { + mitk::ChiSquareNoiseModel* chiSquare = new mitk::ChiSquareNoiseModel(); + chiSquare->SetDOF(noiseVariance/2); + m_ImageGenParameters.noiseModelShort = chiSquare; + break; + } + default: + { + mitk::RicianNoiseModel* rician = new mitk::RicianNoiseModel(); + rician->SetNoiseVariance(noiseVariance); + m_ImageGenParameters.noiseModelShort = rician; + } + } + } m_ImageGenParameters.artifactModelString += QString::number(noiseVariance); m_ImageGenParameters.resultNode->AddProperty("Fiberfox.Noise-Variance", DoubleProperty::New(noiseVariance)); } else - m_ImageGenParameters.ricianNoiseModel.SetNoiseVariance(0); + { + if (m_ImageGenParameters.noiseModel!=NULL) + { + delete m_ImageGenParameters.noiseModel; + m_ImageGenParameters.noiseModel = NULL; + } + if (m_ImageGenParameters.noiseModelShort!=NULL) + { + delete m_ImageGenParameters.noiseModelShort; + m_ImageGenParameters.noiseModelShort = NULL; + } + } // 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.noisedistribution", m_Controls->m_NoiseDistributionBox->currentIndex()); 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_NoiseDistributionBox->setCurrentIndex(v1.second.get("artifacts.noisedistribution")); 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 ); + 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->SetNoiseModel(m_ImageGenParameters.noiseModelShort); 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->GetTimeGeometry(), 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->SetNoiseModel(m_ImageGenParameters.noiseModel); 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()); + +"-"+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->GetTimeGeometry(), 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< 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< 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< 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< 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< 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< 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< 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< 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 ); + 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(); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.h index 172b68f5ba..c30361916f 100755 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.h +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.h @@ -1,214 +1,212 @@ /*=================================================================== 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 #include #include #include "ui_QmitkFiberfoxViewControls.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*! \brief View for fiber based diffusion software phantoms (Fiberfox). \sa QmitkFunctionality \ingroup Functionalities */ // Forward Qt class declarations using namespace std; class QmitkFiberfoxView : public QmitkAbstractView { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: static const string VIEW_ID; QmitkFiberfoxView(); virtual ~QmitkFiberfoxView(); virtual void CreateQtPartControl(QWidget *parent); void SetFocus(); typedef itk::Image ItkDoubleImgType; typedef itk::Image ItkUcharImgType; typedef itk::Vector GradientType; typedef vector GradientListType; template vector > MakeGradientList(); protected slots: void LoadParameters(); void SaveParameters(); void OnDrawROI(); ///< adds new ROI, handles interactors etc. void OnAddBundle(); ///< adds new fiber bundle to datastorage void OnFlipButton(); ///< negate one coordinate of the fiber waypoints in the selcted planar figure. needed in case of unresolvable twists void GenerateFibers(); ///< generate fibers from the selected ROIs void GenerateImage(); ///< generate artificial image from the selected fiber bundle void JoinBundles(); ///< merges selcted fiber bundles into one void CopyBundles(); ///< add copy of the selected bundle to the datamanager void ApplyTransform(); ///< rotate and shift selected bundles void AlignOnGrid(); ///< shift selected fiducials to nearest voxel center void Comp1ModelFrameVisibility(int index);///< only show parameters of selected fiber model type void Comp2ModelFrameVisibility(int index);///< only show parameters of selected non-fiber model type void Comp3ModelFrameVisibility(int index);///< only show parameters of selected non-fiber model type void Comp4ModelFrameVisibility(int index);///< only show parameters of selected non-fiber model type void ShowAdvancedOptions(int state); /** update fibers if any parameter changes */ void OnFiberDensityChanged(int value); void OnFiberSamplingChanged(double value); void OnTensionChanged(double value); void OnContinuityChanged(double value); void OnBiasChanged(double value); void OnVarianceChanged(double value); void OnDistributionChanged(int value); void OnAddNoise(int value); void OnAddGhosts(int value); void OnAddDistortions(int value); void OnAddEddy(int value); void OnAddSpikes(int value); void OnAddAliasing(int value); void OnConstantRadius(int value); protected: /// \brief called by QmitkFunctionality when DataManager's selection has changed virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList&); GradientListType GenerateHalfShell(int NPoints); ///< generate vectors distributed over the halfsphere Ui::QmitkFiberfoxViewControls* m_Controls; void UpdateImageParameters(); ///< update iamge generation paaremeter struct void UpdateGui(); ///< enable/disbale buttons etc. according to current datamanager selection void PlanarFigureSelected( itk::Object* object, const itk::EventObject& ); void EnableCrosshairNavigation(); ///< enable crosshair navigation if planar figure interaction ends void DisableCrosshairNavigation(); ///< disable crosshair navigation if planar figure interaction starts void NodeAdded( const mitk::DataNode* node ); ///< add observers void NodeRemoved(const mitk::DataNode* node); ///< remove observers /** structure to keep track of planar figures and observers */ struct QmitkPlanarFigureData { QmitkPlanarFigureData() : m_Figure(0) , m_EndPlacementObserverTag(0) , m_SelectObserverTag(0) , m_StartInteractionObserverTag(0) , m_EndInteractionObserverTag(0) , m_Flipped(0) { } mitk::PlanarFigure* m_Figure; unsigned int m_EndPlacementObserverTag; unsigned int m_SelectObserverTag; unsigned int m_StartInteractionObserverTag; unsigned int m_EndInteractionObserverTag; unsigned int m_Flipped; }; /** structure storing the image generation parameters */ struct ImageParameters { itk::ImageRegion<3> imageRegion; itk::Vector imageSpacing; itk::Point imageOrigin; itk::Matrix imageDirection; unsigned int numGradients; double b_value; unsigned int repetitions; double signalScale; double tEcho; double tLine; double tInhom; double axonRadius; unsigned int interpolationShrink; double kspaceLineOffset; bool addGibbsRinging; double eddyStrength; double comp3Weight; double comp4Weight; int spikes; double spikeAmplitude; double wrap; - bool doSimulateRelaxation; bool doSimulateEddyCurrents; bool doDisablePartialVolume; - mitk::RicianNoiseModel ricianNoiseModel; + mitk::DiffusionNoiseModel* noiseModel; + mitk::DiffusionNoiseModel* noiseModelShort; mitk::DiffusionSignalModel::GradientListType gradientDirections; itk::TractsToDWIImageFilter< short >::DiffusionModelList fiberModelList, nonFiberModelList; - itk::TractsToDWIImageFilter< short >::KspaceArtifactList artifactList; QString signalModelString, artifactModelString; ItkDoubleImgType::Pointer frequencyMap; ItkUcharImgType::Pointer tissueMaskImage; - mitk::DataNode::Pointer resultNode; }; ImageParameters m_ImageGenParameters; std::map m_DataNodeToPlanarFigureData; ///< map each planar figure uniquely to a QmitkPlanarFigureData mitk::Image::Pointer m_TissueMask; ///< mask defining which regions of the image should contain signal and which are containing only noise mitk::DataNode::Pointer m_SelectedFiducial; ///< selected planar ellipse mitk::DataNode::Pointer m_SelectedImage; mitk::DataNode::Pointer m_SelectedDWI; vector< mitk::DataNode::Pointer > m_SelectedBundles; vector< mitk::DataNode::Pointer > m_SelectedBundles2; vector< mitk::DataNode::Pointer > m_SelectedFiducials; vector< mitk::DataNode::Pointer > m_SelectedImages; // intra and inter axonal compartments mitk::StickModel m_StickModel1; mitk::StickModel m_StickModel2; mitk::TensorModel m_ZeppelinModel1; mitk::TensorModel m_ZeppelinModel2; mitk::TensorModel m_TensorModel1; mitk::TensorModel m_TensorModel2; // extra axonal compartment models mitk::BallModel m_BallModel1; mitk::BallModel m_BallModel2; mitk::AstroStickModel m_AstrosticksModel1; mitk::AstroStickModel m_AstrosticksModel2; mitk::DotModel m_DotModel1; mitk::DotModel m_DotModel2; }; diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxViewControls.ui index fd6bb151c9..d5e517255c 100755 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxViewControls.ui @@ -1,2462 +1,2486 @@ QmitkFiberfoxViewControls 0 0 435 - 1792 + 1845 Form Save Parameters 0 Fiber Definition Qt::Vertical 20 40 color: rgb(255, 0, 0); Please select an image or an existing fiber bundle to draw the fiber fiducials. If you can't provide a suitable image, generate one using the "Signal Generation" tab. Qt::AutoText Qt::AlignJustify|Qt::AlignVCenter true Fiducial Options All fiducials are treated as circles with the same radius as the first fiducial. Use Constant Fiducial Radius false false Align selected fiducials with voxel grid. Shifts selected fiducials to nearest voxel center. Align With Grid Operations false Join Bundles QFrame::NoFrame QFrame::Raised 0 0 0 0 Y false Rotation angle (in degree) around x-axis. -360.000000000000000 360.000000000000000 0.100000000000000 Axis: false Rotation angle (in degree) around y-axis. -360.000000000000000 360.000000000000000 0.100000000000000 Translation: false Translation (in mm) in direction of the z-axis. -1000.000000000000000 1000.000000000000000 0.100000000000000 Translation (in mm) in direction of the y-axis. -1000.000000000000000 1000.000000000000000 0.100000000000000 X false Rotation: false Z false Rotation angle (in degree) around z-axis. -360.000000000000000 360.000000000000000 0.100000000000000 Translation (in mm) in direction of the x-axis. -1000.000000000000000 1000.000000000000000 0.100000000000000 Scaling: false Scaling factor for selected fiber bundle along the x-axis. 0.010000000000000 10.000000000000000 0.010000000000000 1.000000000000000 Scaling factor for selected fiber bundle along the y-axis. 0.010000000000000 10.000000000000000 0.010000000000000 1.000000000000000 Scaling factor for selected fiber bundle along the z-axis. 0.010000000000000 10.000000000000000 0.010000000000000 1.000000000000000 false Copy Bundles false Transform Selection If checked, the fiducials belonging to the modified bundle are also modified. Include Fiducials true Fiber Options QFrame::NoFrame QFrame::Raised 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 Tension: false Fiber Sampling: false 3 -1.000000000000000 1.000000000000000 0.100000000000000 0.000000000000000 3 -1.000000000000000 1.000000000000000 0.100000000000000 0.000000000000000 Bias: false Continuity: false 3 -1.000000000000000 1.000000000000000 0.100000000000000 0.000000000000000 Distance of fiber sampling points (in mm) 1 0.100000000000000 0.100000000000000 1.000000000000000 QFrame::NoFrame QFrame::Raised 0 0 0 0 6 #Fibers: false Specify number of fibers to generate for the selected bundle. 1 1000000 100 100 false Generate Fibers QFrame::NoFrame QFrame::Raised 0 0 0 0 Select fiber distribution inside of the fiducials. Uniform Gaussian Fiber Distribution: false Variance of the gaussian 3 0.001000000000000 10.000000000000000 0.010000000000000 0.100000000000000 QFrame::NoFrame QFrame::Raised 0 0 0 0 Disable to only generate fibers if "Generate Fibers" button is pressed. Real Time Fibers true Disable to only generate fibers if "Generate Fibers" button is pressed. Advanced Options false QFrame::NoFrame QFrame::Raised 0 0 0 0 false 30 30 Draw elliptical fiducial. :/QmitkDiffusionImaging/circle.png:/QmitkDiffusionImaging/circle.png 32 32 false true false 30 30 Flip fiber waypoints of selcted fiducial around one axis. :/QmitkDiffusionImaging/refresh.xpm:/QmitkDiffusionImaging/refresh.xpm 32 32 false true Qt::Horizontal 40 20 Signal Generation Data Fiber Bundle: false <html><head/><body><p><span style=" color:#ff0000;">mandatory</span></p></body></html> true Tissue Mask: false <html><head/><body><p><span style=" color:#969696;">optional</span></p></body></html> true Image Settings QFrame::NoFrame QFrame::Raised 0 0 0 0 6 <html><head/><body><p><span style=" font-style:italic;">TE</span>, <span style=" font-style:italic;">T</span><span style=" font-style:italic; vertical-align:sub;">inhom</span> and <span style=" font-style:italic;">T2</span> will have no effect if unchecked.</p></body></html> Simulate Signal Relaxation true Repetitions: T2* relaxation time (in milliseconds). 100.000000000000000 0.100000000000000 1.000000000000000 Fiber Radius: Fiber radius used to calculate volume fractions (in µm). Set to 0 for automatic radius estimation. 0 1000 0 TE in milliseconds 1 10000 1 100 Interpolation Shrink: Line Readout Time: false <html><head/><body><p>Echo Time <span style=" font-style:italic;">TE</span>: </p></body></html> false Disable partial volume. Treat voxel content as fiber-only if at least one fiber is present. Disable Partial Volume Effects false Output one image per compartment containing the corresponding volume fractions per voxel. Output Volume Fractions false <html><head/><body><p><span style=" font-style:italic;">T</span><span style=" font-style:italic; vertical-align:sub;">inhom</span> Relaxation: </p></body></html> false Number of signal averages. Increase to reduce noise. 1 100 1 1 Relaxation time due to magnetic field inhomogeneities (T2', in milliseconds). 1 10000 1 50 TE in milliseconds 1 10000 1 100 <html><head/><body><p>Large values shrink (towards nearest neighbour interpolation), small values strech interpolation function (towards linear interpolation). 1000 equals nearest neighbour interpolation.</p></body></html> 0 10000 0 Signal Scale: color: rgb(255, 0, 0); Using geometry of selected image! color: rgb(255, 0, 0); Using gradients of selected DWI! QFrame::NoFrame QFrame::Raised 0 0 0 0 3 0.100000000000000 50.000000000000000 0.100000000000000 2.000000000000000 Image Spacing: 3 0.100000000000000 50.000000000000000 0.100000000000000 2.000000000000000 3 0.100000000000000 50.000000000000000 0.100000000000000 2.000000000000000 Image Dimensions: Fiber sampling factor which determines the accuracy of the calculated fiber and non-fiber volume fractions. 1 1000 1 11 Fiber sampling factor which determines the accuracy of the calculated fiber and non-fiber volume fractions. 1 1000 1 11 Fiber sampling factor which determines the accuracy of the calculated fiber and non-fiber volume fractions. 1 1000 1 3 QFrame::NoFrame QFrame::Raised 0 0 0 0 6 Gradient Directions: Number of gradient directions distributed over the half sphere. 1 10000 1 30 b-Value: false b-value in mm/s² 0 10000 100 1000 Advanced Options Qt::Vertical 20 40 Noise and other Artifacts Add Distortions false - Add Rician Noise + Add Noise false QFrame::NoFrame QFrame::Raised + + QFormLayout::AllNonFixedFieldsGrow + 0 0 0 0 - + Variance: - + Variance of Rician noise model. 4 0.000000000000000 100000.000000000000000 0.001000000000000 50.000000000000000 + + + + + Rician + + + + + Chi-square + + + + + + + + Distribution: + + + Add ringing artifacts occuring at strong edges in the image. Add Gibbs Ringing false true QFrame::NoFrame QFrame::Raised 6 0 0 0 0 K-Space Line Offset: false A larger offset increases the inensity of the ghost image. 3 1.000000000000000 0.010000000000000 0.250000000000000 !!!EXPERIMENTAL!!! Add Eddy Current Effects false true QFrame::NoFrame QFrame::Raised 6 0 0 0 0 Frequency Map: false Select image specifying the frequency inhomogeneities (in Hz). QFrame::NoFrame QFrame::Raised 0 0 0 0 Num. Spikes: The number of randomly occurring signal spikes. 1 Spike amplitude relative to the largest signal amplitude of the corresponding k-space slice. 0.100000000000000 0.100000000000000 Scale: Add Spikes false Add N/2 Ghosts false true QFrame::NoFrame QFrame::Raised QFormLayout::AllNonFixedFieldsGrow 6 0 0 0 0 Magnitude: false Maximum magnitude of eddy current induced magnetic field inhomogeneities (in mT). 5 1000.000000000000000 0.001000000000000 0.005000000000000 color: rgb(255, 0, 0); Experimental! Add Aliasing false true QFrame::NoFrame QFrame::Raised 6 0 0 0 0 Undersampling: false Shrink FOV by this factor. 3 1.000000000000000 10.000000000000000 0.100000000000000 1.300000000000000 Inter-axonal Compartment Select signal model for intra-axonal compartment. -- Stick Model Zeppelin Model Tensor Model Extra-axonal Compartments Select signal model for extra-axonal compartment. Ball Model Astrosticks Model Dot Model Select signal model for extra-axonal compartment. -- Ball Model Astrosticks Model Dot Model Qt::Horizontal QFrame::NoFrame QFrame::Raised 0 0 0 0 Weighting factor between the two extra-axonal compartments. 1.000000000000000 0.100000000000000 0.300000000000000 Compartment Fraction: true Start DWI generation from selected fiebr bundle. If no fiber bundle is selected, a grayscale image containing a simple gradient is generated. Generate Image Intra-axonal Compartment Select signal model for intra-axonal compartment. Stick Model Zeppelin Model Tensor Model Load Parameters QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h
QmitkTensorModelParametersWidget QWidget
QmitkTensorModelParametersWidget.h
1
QmitkStickModelParametersWidget QWidget
QmitkStickModelParametersWidget.h
1
QmitkZeppelinModelParametersWidget QWidget
QmitkZeppelinModelParametersWidget.h
1
QmitkBallModelParametersWidget QWidget
QmitkBallModelParametersWidget.h
1
QmitkAstrosticksModelParametersWidget QWidget
QmitkAstrosticksModelParametersWidget.h
1
QmitkDotModelParametersWidget QWidget
QmitkDotModelParametersWidget.h
1
m_CircleButton m_FlipButton m_RealTimeFibers m_AdvancedOptionsBox m_DistributionBox m_VarianceBox m_FiberDensityBox m_FiberSamplingBox m_TensionBox m_ContinuityBox m_BiasBox m_GenerateFibersButton m_ConstantRadiusBox m_AlignOnGrid m_XrotBox m_YrotBox m_ZrotBox m_XtransBox m_YtransBox m_ZtransBox m_XscaleBox m_YscaleBox m_ZscaleBox m_TransformBundlesButton m_CopyBundlesButton m_JoinBundlesButton m_IncludeFiducials m_GenerateImageButton m_SizeX m_SizeY m_SizeZ m_SpacingX m_SpacingY m_SpacingZ m_NumGradientsBox m_BvalueBox m_AdvancedOptionsBox_2 m_RepetitionsBox m_SignalScaleBox m_TEbox m_LineReadoutTimeBox m_T2starBox m_FiberRadius m_InterpolationShrink m_RelaxationBox m_EnforcePureFiberVoxelsBox m_VolumeFractionsBox m_Compartment1Box m_Compartment2Box m_Compartment3Box m_Compartment4Box m_Comp4FractionBox m_AddNoise m_NoiseLevel m_AddSpikes m_SpikeNumBox m_SpikeScaleBox m_AddGhosts m_kOffsetBox m_AddDistortions m_FrequencyMapBox m_AddEddy m_EddyGradientStrength m_AddGibbsRinging m_SaveParametersButton m_LoadParametersButton tabWidget