4 #include <itkImageRegionIterator.h> 5 #include <itkImageRegionConstIterator.h> 11 #include <boost/lexical_cast.hpp> 12 #include <boost/algorithm/string.hpp> 17 template <
class TPixelScalarType>
19 GMMT2RelaxometryEstimationImageFilter <TPixelScalarType>
20 ::SetGaussianMeans(std::string fileName)
22 std::ifstream fileIn(fileName.c_str());
24 if (!fileIn.is_open())
26 std::string errorMsg =
"Unable to read file: ";
28 throw itk::ExceptionObject(__FILE__,__LINE__,errorMsg,ITK_LOCATION);
31 m_GaussianMeans.clear();
36 fileIn.getline(tmpStr,2048);
38 std::string workStr(tmpStr);
42 boost::algorithm::trim_right(workStr);
43 std::istringstream iss(workStr);
46 m_GaussianMeans.push_back(boost::lexical_cast<double> (shortStr));
52 template <
class TPixelScalarType>
55 ::SetGaussianVariances(std::string fileName)
57 std::ifstream fileIn(fileName.c_str());
59 if (!fileIn.is_open())
61 std::string errorMsg =
"Unable to read file: ";
63 throw itk::ExceptionObject(__FILE__,__LINE__,errorMsg,ITK_LOCATION);
66 m_GaussianVariances.clear();
71 fileIn.getline(tmpStr,2048);
73 std::string workStr(tmpStr);
77 boost::algorithm::trim_right(workStr);
78 std::istringstream iss(workStr);
81 m_GaussianVariances.push_back(boost::lexical_cast<double> (shortStr));
87 template <
class TPixelScalarType>
90 ::BeforeThreadedGenerateData()
92 if (m_GaussianVariances.size() != 3)
93 itkExceptionMacro(
"Number of variance parameters has to be 3...");
95 Superclass::BeforeThreadedGenerateData();
97 this->GetB1OutputImage()->FillBuffer(1.0);
99 m_WeightsImage = VectorOutputImageType::New();
100 m_WeightsImage->Initialize();
101 m_WeightsImage->SetRegions(this->GetInput(0)->GetLargestPossibleRegion());
102 m_WeightsImage->SetSpacing (this->GetInput(0)->GetSpacing());
103 m_WeightsImage->SetOrigin (this->GetInput(0)->GetOrigin());
104 m_WeightsImage->SetDirection (this->GetInput(0)->GetDirection());
105 m_WeightsImage->SetVectorLength(3);
106 m_WeightsImage->Allocate();
110 m_WeightsImage->FillBuffer(zero);
113 template <
class TPixelScalarType>
116 ::CheckComputationMask()
118 if (this->GetComputationMask())
121 typedef itk::ImageRegionConstIterator <InputImageType> IteratorType;
122 typedef itk::ImageRegionIterator <MaskImageType> MaskIteratorType;
124 std::vector <IteratorType> inItrs(this->GetNumberOfIndexedInputs());
125 for (
unsigned int i = 0;i < this->GetNumberOfIndexedInputs();++i)
126 inItrs[i] = IteratorType(this->GetInput(i),this->GetOutput(0)->GetLargestPossibleRegion());
128 typename MaskImageType::Pointer maskImage = MaskImageType::New();
129 maskImage->Initialize();
130 maskImage->SetRegions(this->GetInput(0)->GetLargestPossibleRegion());
131 maskImage->SetSpacing (this->GetInput(0)->GetSpacing());
132 maskImage->SetOrigin (this->GetInput(0)->GetOrigin());
133 maskImage->SetDirection (this->GetInput(0)->GetDirection());
134 maskImage->Allocate();
136 MaskIteratorType maskItr (maskImage,this->GetOutput(0)->GetLargestPossibleRegion());
137 while (!maskItr.IsAtEnd())
139 double averageVal = 0;
140 for (
unsigned int i = 0;i < this->GetNumberOfIndexedInputs();++i)
141 averageVal += inItrs[i].Get();
143 averageVal /= this->GetNumberOfIndexedInputs();
145 bool maskPoint = (averageVal <= m_AverageSignalThreshold);
152 for (
unsigned int i = 0;i < this->GetNumberOfIndexedInputs();++i)
158 this->SetComputationMask(maskImage);
161 template <
class TPixelScalarType>
166 typedef itk::ImageRegionConstIterator <InputImageType> ImageConstIteratorType;
167 typedef itk::ImageRegionIterator <InputImageType> ImageIteratorType;
168 typedef itk::ImageRegionIterator <VectorOutputImageType> VectorImageIteratorType;
170 VectorImageIteratorType outWeightsIterator(this->GetWeightsImage(),outputRegionForThread);
171 ImageIteratorType outM0Iterator(this->GetM0OutputImage(),outputRegionForThread);
172 ImageIteratorType outMWFIterator(this->GetMWFOutputImage(),outputRegionForThread);
173 ImageIteratorType outB1Iterator(this->GetB1OutputImage(),outputRegionForThread);
174 ImageIteratorType outSigmaSqIterator(this->GetSigmaSquareOutputImage(),outputRegionForThread);
176 unsigned int numInputs = this->GetNumberOfIndexedInputs();
177 std::vector <ImageConstIteratorType> inIterators;
178 for (
unsigned int i = 0;i < numInputs;++i)
179 inIterators.push_back(ImageConstIteratorType(this->GetInput(i),outputRegionForThread));
181 typedef itk::ImageRegionIterator <MaskImageType> MaskIteratorType;
182 MaskIteratorType maskItr(this->GetComputationMask(),outputRegionForThread);
184 ImageIteratorType t1MapItr;
186 t1MapItr = ImageIteratorType(m_T1Map,outputRegionForThread);
191 B1OptimizerType::ParametersType signalValues(numInputs);
192 unsigned int numberOfGaussians = m_GaussianMeans.size();
194 B1OptimizerType::ParametersType t2OptimizedWeights(numberOfGaussians);
196 typename B1CostFunctionType::Pointer cost = B1CostFunctionType::New();
197 cost->SetEchoSpacing(m_EchoSpacing);
198 cost->SetExcitationFlipAngle(m_T2ExcitationFlipAngle);
200 unsigned int dimension = cost->GetNumberOfParameters();
201 itk::Array<double> lowerBounds(dimension);
202 itk::Array<double> upperBounds(dimension);
203 B1OptimizerType::ParametersType p(dimension);
204 lowerBounds[0] = 1.0 * m_T2FlipAngles[0];
205 upperBounds[0] = 2.0 * m_T2FlipAngles[0];
207 cost->SetGaussianMeans(m_GaussianMeans);
208 cost->SetGaussianVariances(m_GaussianVariances);
209 cost->SetGaussianIntegralTolerance(m_GaussianIntegralTolerance);
211 while (!maskItr.IsAtEnd())
213 outputT2Weights.Fill(0);
215 if (maskItr.Get() == 0)
217 outWeightsIterator.Set(outputT2Weights);
218 outM0Iterator.Set(0);
219 outMWFIterator.Set(0.0);
220 outB1Iterator.Set(1.0);
221 outSigmaSqIterator.Set(0.0);
224 ++outWeightsIterator;
228 ++outSigmaSqIterator;
230 for (
unsigned int i = 0;i < numInputs;++i)
239 double t1Value = 1000.0;
240 double m0Value = 0.0;
242 for (
unsigned int i = 0;i < numInputs;++i)
243 signalValues[i] = inIterators[i].Get();
247 t1Value = t1MapItr.Get();
252 cost->SetT1Value(t1Value);
253 cost->SetT2RelaxometrySignals(signalValues);
255 B1OptimizerType::Pointer b1Optimizer = B1OptimizerType::New();
256 b1Optimizer->SetAlgorithm(NLOPT_LN_BOBYQA);
257 b1Optimizer->SetCostFunction(cost);
258 b1Optimizer->SetXTolRel(1.0e-5);
259 b1Optimizer->SetFTolRel(1.0e-7);
260 b1Optimizer->SetMaxEval(500);
261 b1Optimizer->SetVectorStorageSize(2000);
262 b1Optimizer->SetLowerBoundParameters(lowerBounds);
263 b1Optimizer->SetUpperBoundParameters(upperBounds);
265 p[0] = 1.1 * m_T2FlipAngles[0];
267 b1Optimizer->SetInitialPosition(p);
268 b1Optimizer->SetCostFunction(cost);
270 b1Optimizer->StartOptimization();
271 p = b1Optimizer->GetCurrentPosition();
273 t2OptimizedWeights = cost->GetOptimalT2Weights();
276 for (
unsigned int i = 0;i < numberOfGaussians;++i)
277 m0Value += t2OptimizedWeights[i];
279 for (
unsigned int i = 0;i < numberOfGaussians;++i)
282 outputT2Weights[i] = t2OptimizedWeights[i] / m0Value;
284 outputT2Weights[i] = 0.0;
287 outM0Iterator.Set(m0Value);
288 outWeightsIterator.Set(outputT2Weights);
290 double mwfValue = outputT2Weights[0];
292 outMWFIterator.Set(mwfValue);
294 double b1Value = p[0] / m_T2FlipAngles[0];
295 outB1Iterator.Set(b1Value);
296 outSigmaSqIterator.Set(cost->GetSigmaSquare());
298 this->IncrementNumberOfProcessedPoints();
300 ++outWeightsIterator;
304 ++outSigmaSqIterator;
306 for (
unsigned int i = 0;i < numInputs;++i)
Cost function for estimating B1 from T2 relaxometry acquisition, following a multi-T2 EPG decay model...
Implements an ITK wrapper for the NLOPT library.
VectorOutputImageType::PixelType OutputVectorType
Superclass::OutputImageRegionType OutputImageRegionType