diff --git a/Modules/PhotoacousticSimulation/Testing/mitkPhotoacousticVolumeTest.cpp b/Modules/PhotoacousticSimulation/Testing/mitkPhotoacousticVolumeTest.cpp index 67802356c1..8328eb195b 100644 --- a/Modules/PhotoacousticSimulation/Testing/mitkPhotoacousticVolumeTest.cpp +++ b/Modules/PhotoacousticSimulation/Testing/mitkPhotoacousticVolumeTest.cpp @@ -1,179 +1,181 @@ /*=================================================================== 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 "mitkPhotoacousticVolume.h" #include "mitkPhotoacousticTissueGeneratorParameters.h" class mitkPhotoacousticVolumeTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkPhotoacousticVolumeTestSuite); MITK_TEST(TestInitializedTissueContainsOnlyZeros); MITK_TEST(TestConvertedMitkImageContainsOnlyZerosOrAir); MITK_TEST(TestTissueVolumeContainsCorrectAbsorptionNumber); MITK_TEST(TestTissueVolumeContainsCorrectScatteringNumber); MITK_TEST(TestTissueVolumeContainsCorrectAnisotropyNumber); CPPUNIT_TEST_SUITE_END(); private: mitk::PhotoacousticVolume::Pointer m_PhotoacousticVolume; mitk::PhotoacousticTissueGeneratorParameters::Pointer m_TissueGeneratorParameters; public: void setUp() { m_PhotoacousticVolume = mitk::PhotoacousticVolume::New(); m_TissueGeneratorParameters = mitk::PhotoacousticTissueGeneratorParameters::New(); } void TestInitializedTissueContainsOnlyZeros() { int dims = 30; m_TissueGeneratorParameters->SetXDim(dims); m_TissueGeneratorParameters->SetYDim(dims); m_TissueGeneratorParameters->SetZDim(dims); + m_TissueGeneratorParameters->SetAirThickness(0); + m_TissueGeneratorParameters->SetBackgroundAbsorption(0); m_PhotoacousticVolume->Initialize(m_TissueGeneratorParameters); for(int x = 0; xGetVolumeAbsorptionValue(x, y, z), 0.0); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Every field should be initialized with 0.", abs(m_PhotoacousticVolume->GetVolumeAbsorptionValue(x, y, z)) < mitk::eps, true); } } } } void TestConvertedMitkImageContainsOnlyZerosOrAir() { int dims = 30; m_TissueGeneratorParameters->SetXDim(dims); m_TissueGeneratorParameters->SetYDim(dims); m_TissueGeneratorParameters->SetZDim(dims); m_PhotoacousticVolume->Initialize(m_TissueGeneratorParameters); mitk::Image::Pointer testImage = m_PhotoacousticVolume->ConvertToMitkImage(); mitk::ImageReadAccessor imgMemAcc(testImage); double* imagePointer = (double*)imgMemAcc.GetData(); for(int index = 0; indexSetXDim(dims); m_TissueGeneratorParameters->SetYDim(dims); m_TissueGeneratorParameters->SetZDim(dims); m_PhotoacousticVolume->Initialize(m_TissueGeneratorParameters); m_PhotoacousticVolume->SetVolumeValues(0, 0, 0, 0, 0, 0); m_PhotoacousticVolume->SetVolumeValues(0, 0, 1, 1, 0, 0); m_PhotoacousticVolume->SetVolumeValues(0, 1, 0, 2, 0, 0); m_PhotoacousticVolume->SetVolumeValues(0, 1, 1, 3, 0, 0); m_PhotoacousticVolume->SetVolumeValues(1, 0, 0, 4, 0, 0); m_PhotoacousticVolume->SetVolumeValues(1, 0, 1, 5, 0, 0); m_PhotoacousticVolume->SetVolumeValues(1, 1, 0, 6, 0, 0); m_PhotoacousticVolume->SetVolumeValues(1, 1, 1, 7, 0, 0); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 0.0, m_PhotoacousticVolume->GetVolumeAbsorptionValue(0, 0, 0)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 1.0, m_PhotoacousticVolume->GetVolumeAbsorptionValue(0, 0, 1)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 2.0, m_PhotoacousticVolume->GetVolumeAbsorptionValue(0, 1, 0)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 3.0, m_PhotoacousticVolume->GetVolumeAbsorptionValue(0, 1, 1)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 4.0, m_PhotoacousticVolume->GetVolumeAbsorptionValue(1, 0, 0)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 5.0, m_PhotoacousticVolume->GetVolumeAbsorptionValue(1, 0, 1)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 6.0, m_PhotoacousticVolume->GetVolumeAbsorptionValue(1, 1, 0)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 7.0, m_PhotoacousticVolume->GetVolumeAbsorptionValue(1, 1, 1)); } void TestTissueVolumeContainsCorrectScatteringNumber() { int dims = 2; m_TissueGeneratorParameters->SetXDim(dims); m_TissueGeneratorParameters->SetYDim(dims); m_TissueGeneratorParameters->SetZDim(dims); m_PhotoacousticVolume->Initialize(m_TissueGeneratorParameters); m_PhotoacousticVolume->SetVolumeValues(0, 0, 0, 0, 0, 0); m_PhotoacousticVolume->SetVolumeValues(0, 0, 1, 0, 1, 0); m_PhotoacousticVolume->SetVolumeValues(0, 1, 0, 0, 2, 0); m_PhotoacousticVolume->SetVolumeValues(0, 1, 1, 0, 3, 0); m_PhotoacousticVolume->SetVolumeValues(1, 0, 0, 0, 4, 0); m_PhotoacousticVolume->SetVolumeValues(1, 0, 1, 0, 5, 0); m_PhotoacousticVolume->SetVolumeValues(1, 1, 0, 0, 6, 0); m_PhotoacousticVolume->SetVolumeValues(1, 1, 1, 0, 7, 0); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 0.0, m_PhotoacousticVolume->GetVolumeScatteringValue(0, 0, 0)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 1.0, m_PhotoacousticVolume->GetVolumeScatteringValue(0, 0, 1)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 2.0, m_PhotoacousticVolume->GetVolumeScatteringValue(0, 1, 0)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 3.0, m_PhotoacousticVolume->GetVolumeScatteringValue(0, 1, 1)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 4.0, m_PhotoacousticVolume->GetVolumeScatteringValue(1, 0, 0)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 5.0, m_PhotoacousticVolume->GetVolumeScatteringValue(1, 0, 1)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 6.0, m_PhotoacousticVolume->GetVolumeScatteringValue(1, 1, 0)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 7.0, m_PhotoacousticVolume->GetVolumeScatteringValue(1, 1, 1)); } void TestTissueVolumeContainsCorrectAnisotropyNumber() { int dims = 2; m_TissueGeneratorParameters->SetXDim(dims); m_TissueGeneratorParameters->SetYDim(dims); m_TissueGeneratorParameters->SetZDim(dims); m_PhotoacousticVolume->Initialize(m_TissueGeneratorParameters); m_PhotoacousticVolume->SetVolumeValues(0, 0, 0, 0, 0, 0); m_PhotoacousticVolume->SetVolumeValues(0, 0, 1, 0, 0, 1); m_PhotoacousticVolume->SetVolumeValues(0, 1, 0, 0, 0, 2); m_PhotoacousticVolume->SetVolumeValues(0, 1, 1, 0, 0, 3); m_PhotoacousticVolume->SetVolumeValues(1, 0, 0, 0, 0, 4); m_PhotoacousticVolume->SetVolumeValues(1, 0, 1, 0, 0, 5); m_PhotoacousticVolume->SetVolumeValues(1, 1, 0, 0, 0, 6); m_PhotoacousticVolume->SetVolumeValues(1, 1, 1, 0, 0, 7); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 0.0, m_PhotoacousticVolume->GetVolumeAnisotropyValue(0, 0, 0)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 1.0, m_PhotoacousticVolume->GetVolumeAnisotropyValue(0, 0, 1)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 2.0, m_PhotoacousticVolume->GetVolumeAnisotropyValue(0, 1, 0)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 3.0, m_PhotoacousticVolume->GetVolumeAnisotropyValue(0, 1, 1)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 4.0, m_PhotoacousticVolume->GetVolumeAnisotropyValue(1, 0, 0)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 5.0, m_PhotoacousticVolume->GetVolumeAnisotropyValue(1, 0, 1)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 6.0, m_PhotoacousticVolume->GetVolumeAnisotropyValue(1, 1, 0)); CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 7.0, m_PhotoacousticVolume->GetVolumeAnisotropyValue(1, 1, 1)); } void tearDown() { m_PhotoacousticVolume = nullptr; } }; MITK_TEST_SUITE_REGISTRATION(mitkPhotoacousticVolume) diff --git a/Modules/PhotoacousticSimulation/src/Algorithms/mitkPhotoacousticComposedVolume.h b/Modules/PhotoacousticSimulation/src/Algorithms/mitkPhotoacousticComposedVolume.h index 475b51f596..88cf2a2815 100644 --- a/Modules/PhotoacousticSimulation/src/Algorithms/mitkPhotoacousticComposedVolume.h +++ b/Modules/PhotoacousticSimulation/src/Algorithms/mitkPhotoacousticComposedVolume.h @@ -1,164 +1,167 @@ /*=================================================================== 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 MITKPHOTOACOUSTICCOMPOSEDVOLUME_H #define MITKPHOTOACOUSTICCOMPOSEDVOLUME_H #include #include #include #include //Includes for smart pointer usage #include "mitkCommon.h" #include "itkLightObject.h" namespace mitk { /** - * @brief The PhotoacousticComposedVolume class + * @brief The PhotoacousticComposedVolume class provides the means to systematically collect nrrd files that correspond to + * different simulation slices of the same PhotoacousticVolume. + * + * An instance of this class is needed for the PhotoacousticSlicedVolumeGenerator */ class MITKPHOTOACOUSTICSIMULATION_EXPORT PhotoacousticComposedVolume : public mitk::PhotoacousticVolume { public: mitkClassMacro(mitk::PhotoacousticComposedVolume, mitk::PhotoacousticVolume) itkFactorylessNewMacro(Self) /** * @brief The FluenceValue struct * A simple class struct to make a pair of a data array and a corresponding yOffset. */ struct FluenceValue { double* fluenceValue; double yOffset; int size; FluenceValue() { fluenceValue = nullptr; } ~FluenceValue() { if(fluenceValue!=nullptr) delete[] fluenceValue; fluenceValue = nullptr; } FluenceValue (const FluenceValue &other) { fluenceValue = new double[other.size]; size = other.size; yOffset = other.yOffset; memcpy(fluenceValue, other.fluenceValue, sizeof(double) * size); } const FluenceValue &operator=(const FluenceValue &other) { if(this == &other) return *this; if(fluenceValue!=nullptr) { delete[] fluenceValue; fluenceValue = nullptr; } fluenceValue = new double[other.size]; size = other.size; yOffset = other.yOffset; memcpy(fluenceValue, other.fluenceValue, sizeof(double) * size); return *this; } }; /** * @brief InitializeByNrrd * Initializes this Composed Volume with a ground truth nrrd file. * The given file needs to have equal spacing. * The given file needs all necessary parameters as meta data in the nrrd header. * The given file needs to contain absorption, scattering and anisotrophy coefficients * in the time steps 0, 1, and 2. * * @param nrrdFile path to the nrrd file on hard drive */ void InitializeByNrrd(std::string nrrdFile); /** * @brief AddSlice * Adds a MC Simulation nrrd file to this composed volume. * The given file needs to contain the meta information "y-offset". * This method ensures that all added slices are in the correct order * corresponding to their y-offset. * * @param nrrdFile path to the nrrd file on hard drive */ void AddSlice(std::string nrrdFile); /** * @brief ConvertToMitkImage * Creates an mitk image out of this composed volume. * In ths image, all sliced simulation volumes are put into different * time components. * If you need a 3D Reconstruction, use the mitk::SlicedVolumeGenerator. * * @ref mitkSlicedVolumeGenerator.h * * @return a mitk::Image::Pointer containing the data of the composed volume */ mitk::Image::Pointer ConvertToMitkImage(); /** * @brief GetNumberOfFluenceComponents * @return the number of fluence components encapsuled by this ComposedVolume. */ int GetNumberOfFluenceComponents(); /** * @brief GetFluenceValue * @param fluenceComponent * @param x * @param y * @param z * @return the fluence value for a specific fluence component index at the given 3D location. */ double GetFluenceValue(int fluenceComponent, int x, int y, int z); /** * @brief GetYOffsetForFluenceComponent * @param fluenceComponent * @return the y-offset value for a given fluence component index. */ int GetYOffsetForFluenceComponent(int fluenceComponent); void Sort(); protected: PhotoacousticComposedVolume(); ~PhotoacousticComposedVolume(); private: int m_FluenceComponents; std::vector m_FluenceValues; }; } #endif // MITKPHOTOACOUSTICCOMPOSEDVOLUME_H