diff --git a/Modules/Pharmacokinetics/include/mitkConvertToConcentrationTurboFlashFunctor.h b/Modules/Pharmacokinetics/include/mitkConvertToConcentrationTurboFlashFunctor.h index 7d2015d1f7..7b990088f9 100644 --- a/Modules/Pharmacokinetics/include/mitkConvertToConcentrationTurboFlashFunctor.h +++ b/Modules/Pharmacokinetics/include/mitkConvertToConcentrationTurboFlashFunctor.h @@ -1,67 +1,69 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkConvertToConcentrationTurboFlashFunctor_h #define mitkConvertToConcentrationTurboFlashFunctor_h #include "MitkPharmacokineticsExports.h" namespace mitk { template class MITKPHARMACOKINETICS_EXPORT ConvertToConcentrationTurboFlashFunctor { + private: + double m_Trec; + double m_alpha; + double m_T10; + public: ConvertToConcentrationTurboFlashFunctor() : m_Trec(0), m_alpha(0), m_T10(0) {}; ~ConvertToConcentrationTurboFlashFunctor() {}; void initialize(double relaxationtime, double relaxivity, double recoverytime) { - m_Trec = relaxationtime; + m_Trec = recoverytime; m_alpha = relaxivity; - m_T10 = recoverytime; + m_T10 = relaxationtime; } bool operator!=( const ConvertToConcentrationTurboFlashFunctor & other)const { return !(*this == other); } bool operator==( const ConvertToConcentrationTurboFlashFunctor & other) const { return (this->m_Trec == other.m_Trec) && (this->m_alpha == other.m_alpha) && (this->m_T10 == other.m_T10); } inline TOutputpixel operator()( const TInputPixel1 & value, const TInputPixel2 & baseline) { TOutputpixel concentration(0); //Only for TurboFLASH sequencen if (baseline != 0 && ((double)value/baseline - exp(m_Trec/m_T10) * ((double)value/baseline - 1)) > 0 ) { concentration = -1 / (m_Trec * m_alpha) * log((double)value/baseline - exp(m_Trec/m_T10) * ((double)value/baseline - 1)); } return concentration; } - private: - double m_Trec; - double m_alpha; - double m_T10; + }; } #endif diff --git a/Modules/Pharmacokinetics/test/ConvertToConcentrationTest.cpp b/Modules/Pharmacokinetics/test/ConvertToConcentrationTest.cpp deleted file mode 100644 index 2b8d8ee05d..0000000000 --- a/Modules/Pharmacokinetics/test/ConvertToConcentrationTest.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include "mitkTestingMacros.h" - -#include "itkImage.h" -#include "itkImageRegionIterator.h" - -#include "itkBinaryFunctorImageFilter.h" - -#include "mitkConvertToConcentrationFunctor.h" - - -int ConvertToConcentrationTest(int argc , char* argv[]) -{ - // always start with this! - MITK_TEST_BEGIN("ConvertToConcentration"); - - //Initialization Parameters - double RelaxationTime = 1.2; - double RecoveryTime = 0.125; - double Relaxivity = 4.3; - - - - //Test1: Functor calculation - mitk::ConvertToConcentrationFunctor testFunctor; - testFunctor.initialize(RelaxationTime, Relaxivity, RecoveryTime); - - - double s0 = 197.0; - double sCM = 278.0; - MITK_TEST_CONDITION_REQUIRED(mitk::Equal(0.009,testFunctor(sCM,s0), 1e-6, true)==true,"Check Functor Calculation with Input Value and baseline: 1"); - s0 = 157.0; - sCM = 207.0; - MITK_TEST_CONDITION_REQUIRED(mitk::Equal(0.0069,testFunctor(sCM,s0), 1e-6, true)==true,"Check Functor Calculation with Input Value and baseline: 2"); - s0 = 195.0; - sCM = 270.0; - MITK_TEST_CONDITION_REQUIRED(mitk::Equal(0.0084,testFunctor(sCM,s0), 1e-6, true)==true,"Check Functor Calculation with Input Value and baseline: 3"); - s0 = 177.0; - sCM = 308.0; - MITK_TEST_CONDITION_REQUIRED(mitk::Equal(0.0164,testFunctor(sCM,s0), 1e-6, true)==true,"Check Functor Calculation with Input Value and baseline: 4"); - - //Test2: Filter usage with Functor - - typedef itk::Image ImageType; - typedef mitk::ConvertToConcentrationFunctor ConversionFunctorType; - typedef itk::BinaryFunctorImageFilter FilterType; - - //Definition of testimages - ImageType::Pointer image = ImageType::New(); - ImageType::Pointer BaselineImage = ImageType::New(); - ImageType::IndexType start; - start[0] = 0; // first index on X - start[1] = 0; // first index on Y - start[2] = 0; // first index on Z - ImageType::SizeType size; - size[0] = 2; // size along X - size[1] = 2; // size along Y - size[2] = 2; // size along Z - ImageType::RegionType region; - region.SetSize( size ); - region.SetIndex( start ); - image->SetRegions( region ); - image->Allocate(); - BaselineImage->SetRegions( region ); - BaselineImage->Allocate(); - itk::ImageRegionIterator it = itk::ImageRegionIterator(image,image->GetLargestPossibleRegion()); - itk::ImageRegionIterator Bit = itk::ImageRegionIterator(BaselineImage,BaselineImage->GetLargestPossibleRegion()); - int count = 0; - while (!it.IsAtEnd()&& !Bit.IsAtEnd()) - { - Bit.Set(150); - it.Set(count*50+150); - ++it; - ++Bit; - ++count; - } - //Filterinitialization - FilterType::Pointer ConversionFilter = FilterType::New(); - ConversionFilter->SetFunctor(testFunctor); - ConversionFilter->SetInput1(image); - ConversionFilter->SetInput2(BaselineImage); - - ConversionFilter->Update(); - ImageType::Pointer convertedImage = ImageType::New(); - convertedImage = ConversionFilter->GetOutput(); - - MITK_TEST_EQUAL(image->GetImageDimension(),convertedImage->GetImageDimension(),"Check dimensions of result image"); - - itk::Index<3> idx; - idx[0]=0; - idx[1]=0; - idx[2]=0; - MITK_TEST_EQUAL(0,convertedImage->GetPixel(idx),"Check pixel of converted image index <0,0,0>"); - idx[0]=1; - idx[1]=0; - idx[2]=0; - MITK_TEST_EQUAL(0.0072,convertedImage->GetPixel(idx),"Check pixel of converted image index <1,0,0>"); - idx[0]=0; - idx[1]=1; - idx[2]=0; - MITK_TEST_EQUAL(0.0147,convertedImage->GetPixel(idx),"Check pixel of converted image index <0,1,0>"); - idx[0]=1; - idx[1]=1; - idx[2]=0; - MITK_TEST_EQUAL(0.0225,convertedImage->GetPixel(idx),"Check pixel of converted image index <1,1,0>"); - idx[0]=0; - idx[1]=0; - idx[2]=1; - MITK_TEST_EQUAL(0.0307 ,convertedImage->GetPixel(idx),"Check pixel of converted image index <0,0,1>"); - idx[0]=1; - idx[1]=0; - idx[2]=1; - MITK_TEST_EQUAL(0.0392,convertedImage->GetPixel(idx),"Check pixel of converted image index <1,0,1>"); - idx[0]=0; - idx[1]=1; - idx[2]=1; - MITK_TEST_EQUAL(0.0480,convertedImage->GetPixel(idx),"Check pixel of converted image index <0,1,1>"); - idx[0]=1; - idx[1]=1; - idx[2]=1; - MITK_TEST_EQUAL(0.0574,convertedImage->GetPixel(idx),"Check pixel of converted image index <1,1,1>"); - - - - MITK_TEST_END() -} diff --git a/Modules/Pharmacokinetics/test/files.cmake b/Modules/Pharmacokinetics/test/files.cmake index d6ce07a366..ae3fb37d4a 100644 --- a/Modules/Pharmacokinetics/test/files.cmake +++ b/Modules/Pharmacokinetics/test/files.cmake @@ -1,7 +1,7 @@ SET(MODULE_TESTS mitkDescriptivePharmacokineticBrixModelTest.cpp mitkStandardToftsModelTest.cpp - #ConvertToConcentrationTest.cpp mitkTwoCompartmentExchangeModelTest.cpp mitkExtendedToftsModelTest.cpp + mitkConvertSignalToConcentrationTest.cpp ) diff --git a/Modules/Pharmacokinetics/test/mitkConvertSignalToConcentrationTest.cpp b/Modules/Pharmacokinetics/test/mitkConvertSignalToConcentrationTest.cpp new file mode 100644 index 0000000000..e8324a7dcd --- /dev/null +++ b/Modules/Pharmacokinetics/test/mitkConvertSignalToConcentrationTest.cpp @@ -0,0 +1,197 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +// Testing +#include "mitkTestingMacros.h" +#include "mitkTestFixture.h" + +//MITK includes +#include "mitkConcentrationCurveGenerator.h" +#include "mitkTestDynamicImageGenerator.h" +#include "mitkImagePixelReadAccessor.h" + + +class mitkConvertSignalToConcentrationTestSuite : public mitk::TestFixture +{ + CPPUNIT_TEST_SUITE(mitkConvertSignalToConcentrationTestSuite); + MITK_TEST(GetConvertedImageAbsoluteEnhancementTest); + MITK_TEST(GetConvertedImageAbsoluteEnhancementAveragedBaselineTest); + MITK_TEST(GetConvertedImageRelativeEnhancementTest); + MITK_TEST(GetConvertedImageturboFLASHTest); + MITK_TEST(GetConvertedImageVFATest); + MITK_TEST(GetConvertedImageT2Test); + CPPUNIT_TEST_SUITE_END(); + +private: + mitk::Image::Pointer m_dynamicImage; + mitk::Image::Pointer m_PDWImage; + mitk::Image::Pointer m_convertedImage_0; + mitk::Image::Pointer m_convertedImage_1; + mitk::Image::Pointer m_convertedImage_2; + mitk::Image::Pointer m_convertedImage_3; + mitk::Image::Pointer m_convertedImage_4; + mitk::Image::Pointer m_convertedImage_5; + + itk::Index<4> m_idx_0 = { { 0, 0, 0, 0 } }; + itk::Index<4> m_idx_1 = { { 0, 2, 2, 3 } }; + itk::Index<4> m_idx_2 = { { 2, 2, 1, 9 } }; + itk::Index<4> m_idx_3 = { { 0, 3, 2, 1 } }; + itk::Index<4> m_idx_4 = { { 2, 2, 2, 4 } }; + + +public: + void setUp() override + { + m_dynamicImage = mitk::GenerateDynamicTestImageMITK(); + + // absolute enhancement + mitk::ConcentrationCurveGenerator::Pointer concentrationGen_0 = + mitk::ConcentrationCurveGenerator::New(); + concentrationGen_0->SetDynamicImage(m_dynamicImage); + concentrationGen_0->SetAbsoluteSignalEnhancement(true); + concentrationGen_0->SetFactor(1.0); + concentrationGen_0->SetBaselineStartTimeStep(0); + concentrationGen_0->SetBaselineEndTimeStep(0); + m_convertedImage_0 = concentrationGen_0->GetConvertedImage(); + + // average baseline, absolute enhancement + mitk::ConcentrationCurveGenerator::Pointer concentrationGen_1 = + mitk::ConcentrationCurveGenerator::New(); + concentrationGen_1->SetDynamicImage(m_dynamicImage); + concentrationGen_1->SetAbsoluteSignalEnhancement(true); + concentrationGen_1->SetFactor(1.0); + concentrationGen_1->SetBaselineStartTimeStep(1); + concentrationGen_1->SetBaselineEndTimeStep(3); + m_convertedImage_1 = concentrationGen_1->GetConvertedImage(); + + // relative enhancement + mitk::ConcentrationCurveGenerator::Pointer concentrationGen_2 = + mitk::ConcentrationCurveGenerator::New(); + concentrationGen_2->SetDynamicImage(m_dynamicImage); + concentrationGen_2->SetRelativeSignalEnhancement(true); + concentrationGen_2->SetFactor(1.0); + concentrationGen_2->SetBaselineStartTimeStep(0); + concentrationGen_2->SetBaselineEndTimeStep(0); + m_convertedImage_2 = concentrationGen_2->GetConvertedImage(); + + // turboFLASH + mitk::ConcentrationCurveGenerator::Pointer concentrationGen_3 = + mitk::ConcentrationCurveGenerator::New(); + concentrationGen_3->SetDynamicImage(m_dynamicImage); + concentrationGen_3->SetisTurboFlashSequence(true); + concentrationGen_3->SetRecoveryTime(1.0); + concentrationGen_3->SetRelaxationTime(1.0); + concentrationGen_3->SetRelaxivity(1.0); + concentrationGen_3->SetBaselineStartTimeStep(0); + concentrationGen_3->SetBaselineEndTimeStep(0); + m_convertedImage_3 = concentrationGen_3->GetConvertedImage(); + + // Variable flip angle + mitk::ConcentrationCurveGenerator::Pointer concentrationGen_4 = + mitk::ConcentrationCurveGenerator::New(); + m_PDWImage = mitk::GenerateTestFrame(1.0); + concentrationGen_4->SetDynamicImage(m_dynamicImage); + concentrationGen_4->SetUsingT1Map(true); + concentrationGen_4->SetRecoveryTime(1.0); + concentrationGen_4->SetRelaxivity(1.0); + concentrationGen_4->SetT10Image(m_PDWImage); + concentrationGen_4->SetFlipAngle(1.0); + concentrationGen_4->SetBaselineStartTimeStep(0); + concentrationGen_4->SetBaselineEndTimeStep(0); + m_convertedImage_4 = concentrationGen_4->GetConvertedImage(); + + // T2 + mitk::ConcentrationCurveGenerator::Pointer concentrationGen_5 = + mitk::ConcentrationCurveGenerator::New(); + concentrationGen_5->SetDynamicImage(m_dynamicImage); + concentrationGen_5->SetisT2weightedImage(true); + concentrationGen_5->SetT2Factor(1.0); + concentrationGen_5->SetT2EchoTime(1.0); + concentrationGen_5->SetBaselineStartTimeStep(0); + concentrationGen_5->SetBaselineEndTimeStep(0); + m_convertedImage_5 = concentrationGen_5->GetConvertedImage(); + } + + void tearDown() override + { + } + + void GetConvertedImageAbsoluteEnhancementTest() + { + mitk::ImagePixelReadAccessor readAccess(m_convertedImage_0, m_convertedImage_0->GetSliceData(4)); + + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 0 at pixel m_idx_0.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_0), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 0 at pixel m_idx_1.", mitk::Equal(90.0, readAccess.GetPixelByIndex(m_idx_1), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 0 at pixel m_idx_2.", mitk::Equal(360.0, readAccess.GetPixelByIndex(m_idx_2), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 0 at pixel m_idx_3.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_3), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 0 at pixel m_idx_4.", mitk::Equal(160.0, readAccess.GetPixelByIndex(m_idx_4), 1e-6, true) == true); + } + + void GetConvertedImageAbsoluteEnhancementAveragedBaselineTest() + { + mitk::ImagePixelReadAccessor readAccess(m_convertedImage_1, m_convertedImage_1->GetSliceData(4)); + + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 1 at pixel m_idx_0.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_0), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 1 at pixel m_idx_1.", mitk::Equal(30.0, readAccess.GetPixelByIndex(m_idx_1), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 1 at pixel m_idx_2.", mitk::Equal(280.0, readAccess.GetPixelByIndex(m_idx_2), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 1 at pixel m_idx_3.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_3), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 1 at pixel m_idx_4.", mitk::Equal(80.0, readAccess.GetPixelByIndex(m_idx_4), 1e-6, true) == true); + } + + void GetConvertedImageRelativeEnhancementTest() + { + mitk::ImagePixelReadAccessor readAccess(m_convertedImage_2, m_convertedImage_2->GetSliceData(4)); + + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 2 at pixel m_idx_0.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_0), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 2 at pixel m_idx_1.", mitk::Equal(3.461538, readAccess.GetPixelByIndex(m_idx_1), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 2 at pixel m_idx_2.", mitk::Equal(20.0, readAccess.GetPixelByIndex(m_idx_2), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 2 at pixel m_idx_3.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_3), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 2 at pixel m_idx_4.", mitk::Equal(5.714286, readAccess.GetPixelByIndex(m_idx_4), 1e-6, true) == true); + } + + void GetConvertedImageturboFLASHTest() + { + mitk::ImagePixelReadAccessor readAccess(m_convertedImage_3, m_convertedImage_3->GetSliceData(4)); + + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 3 at pixel m_idx_0.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_0), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 3 at pixel m_idx_1.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_1), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 3 at pixel m_idx_2.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_2), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 3 at pixel m_idx_3.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_3), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 3 at pixel m_idx_4.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_4), 1e-6, true) == true); + } + + void GetConvertedImageVFATest() + { + mitk::ImagePixelReadAccessor readAccess(m_convertedImage_4, m_convertedImage_4->GetSliceData(4)); + + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 4 at pixel m_idx_0.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_0), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 4 at pixel m_idx_1.", mitk::Equal(2.956868, readAccess.GetPixelByIndex(m_idx_1), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 4 at pixel m_idx_2.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_2), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 4 at pixel m_idx_3.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_3), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 4 at pixel m_idx_4.", mitk::Equal(3.989374, readAccess.GetPixelByIndex(m_idx_4), 1e-6, true) == true); + } + + void GetConvertedImageT2Test() + { + mitk::ImagePixelReadAccessor readAccess(m_convertedImage_5, m_convertedImage_5->GetSliceData(4)); + + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 5 at pixel m_idx_0.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_0), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 5 at pixel m_idx_1.", mitk::Equal(-1.495494, readAccess.GetPixelByIndex(m_idx_1), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 5 at pixel m_idx_2.", mitk::Equal(-3.044522, readAccess.GetPixelByIndex(m_idx_2), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 5 at pixel m_idx_3.", mitk::Equal(0.0, readAccess.GetPixelByIndex(m_idx_3), 1e-6, true) == true); + CPPUNIT_ASSERT_MESSAGE("Checking value of converted image 5 at pixel m_idx_4.", mitk::Equal(-1.904237, readAccess.GetPixelByIndex(m_idx_4), 1e-6, true) == true); + } + +}; +MITK_TEST_SUITE_REGISTRATION(mitkConvertSignalToConcentration) + +