4 #include <itkImageRegionIterator.h> 5 #include <itkImageRegionIteratorWithIndex.h> 6 #include <itkImageRegionConstIterator.h> 7 #include <itkImageRegionConstIteratorWithIndex.h> 8 #include <itkSymmetricEigenAnalysis.h> 10 #include <boost/math/distributions/fisher_f.hpp> 11 #include <boost/math/distributions/chi_squared.hpp> 13 #include <itkTimeProbe.h> 18 template <
class PixelScalarType>
23 Superclass::BeforeThreadedGenerateData();
26 unsigned int nbInputs = this->GetNumberOfIndexedInputs();
29 itkExceptionMacro(
"Error: No inputs available...");
31 unsigned int ndim = this->GetInput(0)->GetNumberOfComponentsPerPixel();
33 if (m_NumEigenValuesPCA > ndim)
34 m_NumEigenValuesPCA = ndim;
36 if (m_DatabaseImages.size() <= this->GetInput(0)->GetNumberOfComponentsPerPixel())
37 itkExceptionMacro(
"Error: Not enough inputs available...");
40 template <
class PixelScalarType>
45 typedef itk::ImageRegionConstIteratorWithIndex< InputImageType > InIteratorType;
47 typedef itk::ImageRegionIteratorWithIndex< OutputImageType > OutRegionIteratorType;
48 typedef itk::ImageRegionConstIteratorWithIndex < MaskImageType > MaskRegionIteratorType;
50 OutRegionIteratorType outIterator(this->GetOutput(0), outputRegionForThread);
51 OutRegionIteratorType outPValIterator(this->GetOutput(1), outputRegionForThread);
52 MaskRegionIteratorType maskIterator (this->GetComputationMask(), outputRegionForThread);
54 unsigned int numSamplesDatabase = m_DatabaseImages.size();
55 std::vector < InIteratorType > databaseIterators;
56 InIteratorType patientIterator(this->GetInput(0), outputRegionForThread);
58 for (
unsigned int i = 0;i < numSamplesDatabase;++i)
59 databaseIterators.push_back(InIteratorType(m_DatabaseImages[i],outputRegionForThread));
61 unsigned int ndim = this->GetInput(0)->GetNumberOfComponentsPerPixel();
65 std::vector < VectorType > databaseValues(numSamplesDatabase);
68 while (!outIterator.IsAtEnd())
70 patientVectorValue = patientIterator.Get();
71 ndim = patientVectorValue.GetSize();
73 if ((maskIterator.Get() == 0)||(this->isZero(patientVectorValue)))
76 outPValIterator.Set(0.0);
82 for (
unsigned int i = 0;i < numSamplesDatabase;++i)
83 ++databaseIterators[i];
88 databaseValues.resize(numSamplesDatabase);
90 unsigned int numEffectiveSamples = 0;
91 for (
unsigned int i = 0;i < numSamplesDatabase;++i)
93 databaseValues[numEffectiveSamples] = databaseIterators[i].Get();
94 if (!this->isZero(databaseValues[numEffectiveSamples]))
95 numEffectiveSamples++;
98 databaseValues.resize(numEffectiveSamples);
100 ndim = this->SampleFromDiffusionModels(databaseValues,patientVectorValue);
101 unsigned int ndim_afterpca = ndim;
103 if ((m_NumEigenValuesPCA < ndim)||(m_ExplainedRatio < 1))
104 ndim_afterpca = this->GetPCAVectorsFromData(databaseValues,patientVectorValue);
106 if (numEffectiveSamples <= ndim_afterpca)
108 outIterator.Set(0.0);
109 outPValIterator.Set(0.0);
115 for (
unsigned int i = 0;i < numSamplesDatabase;++i)
116 ++databaseIterators[i];
121 tmpCovMatrix.set_size(ndim_afterpca,ndim_afterpca);
122 tmpCovMatrix.fill(0);
123 tmpMean.SetSize(ndim_afterpca);
126 for (
unsigned int i = 0;i < numEffectiveSamples;++i)
128 for (
unsigned int j = 0;j < ndim_afterpca;++j)
129 tmpMean[j] += databaseValues[i][j];
132 tmpMean /= numEffectiveSamples;
134 for (
unsigned int i = 0;i < numEffectiveSamples;++i)
136 for (
unsigned int j = 0;j < ndim_afterpca;++j)
137 for (
unsigned int k = j;k < ndim_afterpca;++k)
138 tmpCovMatrix(j,k) += (databaseValues[i][j] - tmpMean[j])*(databaseValues[i][k] - tmpMean[k]);
141 for (
unsigned int j = 0;j < ndim_afterpca;++j)
142 for (
unsigned int k = j;k < ndim_afterpca;++k)
144 tmpCovMatrix(j,k) /= (numEffectiveSamples - 1.0);
146 tmpCovMatrix(k,j) = tmpCovMatrix(j,k);
149 vnl_matrix_inverse <double> matrixInverter(tmpCovMatrix);
150 tmpCovMatrixInv = matrixInverter.inverse();
154 for (
unsigned int i = 0;i < ndim_afterpca;++i)
155 for (
unsigned int j = i;j < ndim_afterpca;++j)
163 resValue += factor*tmpCovMatrixInv(i,j)*(patientVectorValue[i] - tmpMean[i])*(patientVectorValue[j] - tmpMean[j]);
166 switch (m_StatisticalTestType)
170 double testScore = numEffectiveSamples * (numEffectiveSamples - ndim_afterpca) * resValue / ((numEffectiveSamples * numEffectiveSamples - 1) * ndim_afterpca);
171 boost::math::fisher_f_distribution <double> fisherDist(ndim_afterpca,numEffectiveSamples - ndim_afterpca);
172 outPValIterator.Set (1.0 - boost::math::cdf(fisherDist, testScore));
179 boost::math::chi_squared_distribution <double> chiDist(ndim_afterpca);
180 outPValIterator.Set (1.0 - boost::math::cdf(chiDist, resValue));
185 resValue = sqrt(resValue);
189 if (tmpMean[0] > patientVectorValue[0])
193 this->IncrementNumberOfProcessedPoints();
194 outIterator.Set(resValue);
200 for (
unsigned int i = 0;i < numSamplesDatabase;++i)
201 ++databaseIterators[i];
206 template <
class PixelScalarType>
210 itk::VariableLengthVector <double> &patientVectorValue)
212 unsigned int refNDim = patientVectorValue.GetSize();
213 vnl_matrix <double> allCovarianceMatrix(refNDim,refNDim);
215 for (
unsigned int i = 0;i < refNDim;++i)
216 for (
unsigned int j = 0;j < refNDim;++j)
217 allCovarianceMatrix(i,j) = 0;
219 unsigned int numData = databaseVectors.size();
220 std::vector <double> dataMean(refNDim,0);
222 for (
unsigned int i = 0;i < numData;++i)
223 for (
unsigned int j = 0;j < refNDim;++j)
224 dataMean[j] += databaseVectors[i][j];
226 for (
unsigned int j = 0;j < refNDim;++j)
227 dataMean[j] /= numData;
229 for (
unsigned int i = 0;i < numData;++i)
230 for (
unsigned int j = 0;j < refNDim;++j)
231 for (
unsigned int k = j;k < refNDim;++k)
232 allCovarianceMatrix(j,k) += (databaseVectors[i][j] - dataMean[j])*(databaseVectors[i][k] - dataMean[k]);
234 for (
unsigned int j = 0;j < refNDim;++j)
235 for (
unsigned int k = j;k < refNDim;++k)
237 allCovarianceMatrix(j,k) /= (numData - 1.0);
239 allCovarianceMatrix(k,j) = allCovarianceMatrix(j,k);
242 vnl_matrix <double> eigenVectors(refNDim,refNDim);
243 vnl_diag_matrix <double> eigenValues(refNDim);
245 itk::SymmetricEigenAnalysis <vnl_matrix <double>, vnl_diag_matrix <double>, vnl_matrix <double> > EigenAnalysis(refNDim);
246 EigenAnalysis.SetOrderEigenValues(
true);
247 EigenAnalysis.ComputeEigenValuesAndVectors(allCovarianceMatrix,eigenValues,eigenVectors);
249 double sumEigVal = 0;
250 for (
unsigned int i = 0;i < refNDim;++i)
251 sumEigVal += eigenValues[i];
253 unsigned int outNDim = 0;
254 double cumulEigs = 0;
255 while (cumulEigs/sumEigVal < m_ExplainedRatio)
257 cumulEigs += eigenValues[refNDim - 1 - outNDim];
261 if (outNDim < m_NumEigenValuesPCA)
262 outNDim = m_NumEigenValuesPCA;
264 vnl_matrix <double> basisMatrix(outNDim,refNDim);
265 for (
unsigned int i = 0;i < outNDim;++i)
266 for (
unsigned int j = 0;j < refNDim;++j)
267 basisMatrix(i,j) = eigenVectors(refNDim - 1 - i,j);
269 itk::VariableLengthVector <double> tmpVec, resData(outNDim);
270 for (
unsigned int i = 0;i < numData;++i)
272 tmpVec = databaseVectors[i];
273 for (
unsigned int j = 0;j < outNDim;++j)
276 for (
unsigned int k = 0;k < refNDim;++k)
277 resData[j] += basisMatrix(j,k)*(tmpVec[k] - dataMean[k]);
280 databaseVectors[i] = resData;
283 for (
unsigned int j = 0;j < outNDim;++j)
286 for (
unsigned int k = 0;k < refNDim;++k)
287 resData[j] += basisMatrix(j,k)*(patientVectorValue[k] - dataMean[k]);
290 patientVectorValue = resData;
295 template <
class PixelScalarType>
300 unsigned int ndim = vec.Size();
302 for (
unsigned int i = 0;i < ndim;++i)
vnl_matrix< double > CovMatrixType
InputImageType::PixelType VectorType
void DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread) ITK_OVERRIDE
virtual void BeforeThreadedGenerateData() ITK_OVERRIDE
Implements patient to group comparison as in http://dx.doi.org/10.1007/978-3-540-85988-8_116.
Superclass::OutputImageRegionType OutputImageRegionType