diff --git a/Modules/PhotoacousticsLib/MitkPAPhantomGenerator/PAPhantomGenerator.cpp b/Modules/PhotoacousticsLib/MitkPAPhantomGenerator/PAPhantomGenerator.cpp index cb83119f46..89f907acf8 100644 --- a/Modules/PhotoacousticsLib/MitkPAPhantomGenerator/PAPhantomGenerator.cpp +++ b/Modules/PhotoacousticsLib/MitkPAPhantomGenerator/PAPhantomGenerator.cpp @@ -1,230 +1,230 @@ /*=================================================================== 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 #include #include #include using namespace mitk::pa; TissueGeneratorParameters::Pointer CreatePhantom_04_04_18_Parameters() { auto returnParameters = TissueGeneratorParameters::New(); returnParameters->SetAirThicknessInMillimeters(12); returnParameters->SetMinBackgroundAbsorption(0.1); returnParameters->SetMaxBackgroundAbsorption(0.1); returnParameters->SetBackgroundAnisotropy(0.9); returnParameters->SetBackgroundScattering(15); - returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateNewPositionInStraightLine); + returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateNewDirectionVectorInStraightLine); returnParameters->SetDoPartialVolume(true); returnParameters->SetMinNumberOfVessels(1); returnParameters->SetMaxNumberOfVessels(8); returnParameters->SetMinVesselAbsorption(1); returnParameters->SetMaxVesselAbsorption(10); returnParameters->SetMinVesselAnisotropy(0.9); returnParameters->SetMaxVesselAnisotropy(0.9); returnParameters->SetMinVesselBending(0.1); returnParameters->SetMaxVesselBending(0.3); returnParameters->SetMinVesselRadiusInMillimeters(0.25); returnParameters->SetMaxVesselRadiusInMillimeters(4); returnParameters->SetMinVesselScattering(15); returnParameters->SetMaxVesselScattering(15); returnParameters->SetMinVesselZOrigin(1.6); returnParameters->SetMaxVesselZOrigin(4); returnParameters->SetVesselBifurcationFrequency(5000); returnParameters->SetRandomizePhysicalProperties(false); returnParameters->SetSkinThicknessInMillimeters(0); returnParameters->SetUseRngSeed(false); returnParameters->SetVoxelSpacingInCentimeters(0.03); returnParameters->SetXDim(140); returnParameters->SetYDim(100); returnParameters->SetZDim(180); //returnParameters->SetVoxelSpacingInCentimeters(0.015); //returnParameters->SetXDim(280); //returnParameters->SetYDim(200); //returnParameters->SetZDim(360); returnParameters->SetForceVesselsMoveAlongYDirection(true); //returnParameters->SetVoxelSpacingInCentimeters(0.0075); //returnParameters->SetXDim(560); //returnParameters->SetYDim(400); //returnParameters->SetZDim(720); return returnParameters; } struct InputParameters { std::string saveFolderPath; std::string identifyer; std::string exePath; std::string probePath; bool empty; bool verbose; }; InputParameters parseInput(int argc, char* argv[]) { MITK_INFO << "Parsing arguments..."; mitkCommandLineParser parser; parser.setCategory("MITK-Photoacoustics"); parser.setTitle("Mitk Tissue Batch Generator"); parser.setDescription("Creates in silico tissue in batch processing and automatically calculates fluence values for the central slice of the volume."); parser.setContributor("Computer Assisted Medical Interventions, DKFZ"); parser.setArgumentPrefix("--", "-"); parser.beginGroup("Required parameters"); parser.addArgument( "savePath", "s", mitkCommandLineParser::InputDirectory, "Input save folder (directory)", "input save folder", us::Any(), false); parser.addArgument( "mitkMcxyz", "m", mitkCommandLineParser::OutputFile, "MitkMcxyz binary (file)", "path to the MitkMcxyz binary", us::Any(), false); parser.endGroup(); parser.beginGroup("Optional parameters"); parser.addArgument( "probe", "p", mitkCommandLineParser::OutputFile, "xml probe file (file)", "file to the definition of the used probe (*.xml)", us::Any()); parser.addArgument( "verbose", "v", mitkCommandLineParser::Bool, "Verbose Output", "Whether to produce verbose, or rather debug output"); parser.addArgument( "identifyer", "i", mitkCommandLineParser::String, "Generator identifyer (string)", "A unique identifyer for the calculation instance"); parser.addArgument( "empty-volume", "e", mitkCommandLineParser::Bool, "omit vessel structures (boolean flag)", "Whether to create an empty volume with no structures inside."); parser.endGroup(); InputParameters input; std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size() == 0) exit(-1); if (parsedArgs.count("empty-volume")) { input.empty = us::any_cast(parsedArgs["empty-volume"]); } else { input.empty = false; } if (parsedArgs.count("verbose")) { input.verbose = us::any_cast(parsedArgs["verbose"]); } else { input.verbose = false; } if (parsedArgs.count("savePath")) { input.saveFolderPath = us::any_cast(parsedArgs["savePath"]); } if (parsedArgs.count("mitkMcxyz")) { input.exePath = us::any_cast(parsedArgs["mitkMcxyz"]); } if (parsedArgs.count("probe")) { input.probePath = us::any_cast(parsedArgs["probe"]); } if (parsedArgs.count("identifyer")) { input.identifyer = us::any_cast(parsedArgs["identifyer"]); } else { auto uid = mitk::UIDGenerator("", 8); input.identifyer = uid.GetUID(); } MITK_INFO << "Parsing arguments...[Done]"; return input; } int main(int argc, char * argv[]) { auto input = parseInput(argc, argv); auto parameters = CreatePhantom_04_04_18_Parameters(); if (input.empty) { parameters->SetMaxNumberOfVessels(0); parameters->SetMinNumberOfVessels(0); } MITK_INFO(input.verbose) << "Generating tissue.."; auto resultTissue = InSilicoTissueGenerator::GenerateInSilicoData(parameters); MITK_INFO(input.verbose) << "Generating tissue..[Done]"; auto inputfolder = std::string(input.saveFolderPath + "input/"); auto outputfolder = std::string(input.saveFolderPath + "output/"); if (!itksys::SystemTools::FileIsDirectory(inputfolder)) { itksys::SystemTools::MakeDirectory(inputfolder); } if (!itksys::SystemTools::FileIsDirectory(outputfolder)) { itksys::SystemTools::MakeDirectory(outputfolder); } std::string savePath = input.saveFolderPath + "input/Phantom_" + input.identifyer + ".nrrd"; mitk::IOUtil::Save(resultTissue->ConvertToMitkImage(), savePath); std::string outputPath = input.saveFolderPath + "output/Phantom_" + input.identifyer + "/"; resultTissue = nullptr; if (!itksys::SystemTools::FileIsDirectory(outputPath)) { itksys::SystemTools::MakeDirectory(outputPath); } outputPath = outputPath + "Fluence_Phantom_" + input.identifyer; MITK_INFO(input.verbose) << "Simulating fluence.."; int result = -4; std::string cmdString = std::string(input.exePath + " -i " + savePath + " -o " + (outputPath + ".nrrd") + " -yo " + "0" + " -p " + input.probePath + " -n 10000000"); MITK_INFO << "Executing: " << cmdString; result = std::system(cmdString.c_str()); MITK_INFO << result; MITK_INFO(input.verbose) << "Simulating fluence..[Done]"; } diff --git a/Modules/PhotoacousticsLib/MitkTissueBatchGenerator/TissueBatchGenerator.cpp b/Modules/PhotoacousticsLib/MitkTissueBatchGenerator/TissueBatchGenerator.cpp index 61d6b94ab9..c73a6ca22a 100644 --- a/Modules/PhotoacousticsLib/MitkTissueBatchGenerator/TissueBatchGenerator.cpp +++ b/Modules/PhotoacousticsLib/MitkTissueBatchGenerator/TissueBatchGenerator.cpp @@ -1,394 +1,394 @@ /*=================================================================== 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 #include #include using namespace mitk::pa; TissueGeneratorParameters::Pointer CreateMultiHB_13_02_18_Parameters() { auto returnParameters = TissueGeneratorParameters::New(); returnParameters->SetAirThicknessInMillimeters(1.8); returnParameters->SetMinBackgroundAbsorption(0.001); returnParameters->SetMaxBackgroundAbsorption(0.2); returnParameters->SetBackgroundAnisotropy(0.9); returnParameters->SetBackgroundScattering(15); - returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateRandomlyDivergingPosition); + returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); returnParameters->SetDoPartialVolume(true); returnParameters->SetMinNumberOfVessels(1); returnParameters->SetMaxNumberOfVessels(7); returnParameters->SetMinVesselAbsorption(1); returnParameters->SetMaxVesselAbsorption(12); returnParameters->SetMinVesselAnisotropy(0.9); returnParameters->SetMaxVesselAnisotropy(0.9); returnParameters->SetMinVesselBending(0); returnParameters->SetMaxVesselBending(0.2); returnParameters->SetMinVesselRadiusInMillimeters(0.5); returnParameters->SetMaxVesselRadiusInMillimeters(6); returnParameters->SetMinVesselScattering(15); returnParameters->SetMaxVesselScattering(15); returnParameters->SetMinVesselZOrigin(1); returnParameters->SetMaxVesselZOrigin(3); returnParameters->SetVesselBifurcationFrequency(5000); returnParameters->SetRandomizePhysicalProperties(false); returnParameters->SetSkinThicknessInMillimeters(0); returnParameters->SetUseRngSeed(false); returnParameters->SetVoxelSpacingInCentimeters(0.06); returnParameters->SetXDim(70); returnParameters->SetYDim(100); returnParameters->SetZDim(100); returnParameters->SetMCflag(4); return returnParameters; } TissueGeneratorParameters::Pointer CreateBaselineHB_13_02_18_Parameters() { auto returnParameters = TissueGeneratorParameters::New(); returnParameters->SetAirThicknessInMillimeters(1.8); returnParameters->SetMinBackgroundAbsorption(0.001); returnParameters->SetMaxBackgroundAbsorption(0.2); returnParameters->SetBackgroundAnisotropy(0.9); returnParameters->SetBackgroundScattering(15); - returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateRandomlyDivergingPosition); + returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); returnParameters->SetDoPartialVolume(true); returnParameters->SetMinNumberOfVessels(1); returnParameters->SetMaxNumberOfVessels(1); returnParameters->SetMinVesselAbsorption(4.73); returnParameters->SetMaxVesselAbsorption(4.73); returnParameters->SetMinVesselAnisotropy(0.9); returnParameters->SetMaxVesselAnisotropy(0.9); returnParameters->SetMinVesselBending(0); returnParameters->SetMaxVesselBending(0.2); returnParameters->SetMinVesselRadiusInMillimeters(3); returnParameters->SetMaxVesselRadiusInMillimeters(3); returnParameters->SetMinVesselScattering(15); returnParameters->SetMaxVesselScattering(15); returnParameters->SetMinVesselZOrigin(1); returnParameters->SetMaxVesselZOrigin(3); returnParameters->SetVesselBifurcationFrequency(5000); returnParameters->SetRandomizePhysicalProperties(false); returnParameters->SetSkinThicknessInMillimeters(0); returnParameters->SetUseRngSeed(false); returnParameters->SetVoxelSpacingInCentimeters(0.06); returnParameters->SetXDim(70); returnParameters->SetYDim(100); returnParameters->SetZDim(100); returnParameters->SetMCflag(4); return returnParameters; } TissueGeneratorParameters::Pointer CreateSingleVesselHeterogeneousBackground_08_02_18_Parameters() { auto returnParameters = TissueGeneratorParameters::New(); returnParameters->SetAirThicknessInMillimeters(1.8); returnParameters->SetMinBackgroundAbsorption(0.001); returnParameters->SetMaxBackgroundAbsorption(0.2); returnParameters->SetBackgroundAnisotropy(0.9); returnParameters->SetBackgroundScattering(15); - returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateRandomlyDivergingPosition); + returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); returnParameters->SetDoPartialVolume(true); returnParameters->SetMinNumberOfVessels(1); returnParameters->SetMaxNumberOfVessels(1); returnParameters->SetMinVesselAbsorption(1); returnParameters->SetMaxVesselAbsorption(12); returnParameters->SetMinVesselAnisotropy(0.9); returnParameters->SetMaxVesselAnisotropy(0.9); returnParameters->SetMinVesselBending(0); returnParameters->SetMaxVesselBending(0.2); returnParameters->SetMinVesselRadiusInMillimeters(0.5); returnParameters->SetMaxVesselRadiusInMillimeters(6); returnParameters->SetMinVesselScattering(15); returnParameters->SetMaxVesselScattering(15); returnParameters->SetMinVesselZOrigin(1); returnParameters->SetMaxVesselZOrigin(3); returnParameters->SetVesselBifurcationFrequency(5000); returnParameters->SetRandomizePhysicalProperties(false); returnParameters->SetSkinThicknessInMillimeters(0); returnParameters->SetUseRngSeed(false); returnParameters->SetVoxelSpacingInCentimeters(0.06); returnParameters->SetXDim(70); returnParameters->SetYDim(100); returnParameters->SetZDim(100); returnParameters->SetMCflag(4); return returnParameters; } TissueGeneratorParameters::Pointer CreateMultivessel_19_12_17_Parameters() { auto returnParameters = TissueGeneratorParameters::New(); returnParameters->SetAirThicknessInMillimeters(12); returnParameters->SetMinBackgroundAbsorption(0.1); returnParameters->SetMaxBackgroundAbsorption(0.1); returnParameters->SetBackgroundAnisotropy(0.9); returnParameters->SetBackgroundScattering(15); - returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateRandomlyDivergingPosition); + returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); returnParameters->SetDoPartialVolume(true); returnParameters->SetMinNumberOfVessels(1); returnParameters->SetMaxNumberOfVessels(7); returnParameters->SetMinVesselAbsorption(2); returnParameters->SetMaxVesselAbsorption(8); returnParameters->SetMinVesselAnisotropy(0.9); returnParameters->SetMaxVesselAnisotropy(0.9); returnParameters->SetMinVesselBending(0.1); returnParameters->SetMaxVesselBending(0.3); returnParameters->SetMinVesselRadiusInMillimeters(0.5); returnParameters->SetMaxVesselRadiusInMillimeters(4); returnParameters->SetMinVesselScattering(15); returnParameters->SetMaxVesselScattering(15); returnParameters->SetMinVesselZOrigin(2.2); returnParameters->SetMaxVesselZOrigin(4); returnParameters->SetVesselBifurcationFrequency(5000); returnParameters->SetRandomizePhysicalProperties(false); returnParameters->SetSkinThicknessInMillimeters(0); returnParameters->SetUseRngSeed(false); returnParameters->SetVoxelSpacingInCentimeters(0.06); returnParameters->SetXDim(70); returnParameters->SetYDim(100); returnParameters->SetZDim(100); return returnParameters; } TissueGeneratorParameters::Pointer CreateMultivessel_19_10_17_Parameters() { auto returnParameters = TissueGeneratorParameters::New(); returnParameters->SetAirThicknessInMillimeters(12); returnParameters->SetMinBackgroundAbsorption(0.1); returnParameters->SetMaxBackgroundAbsorption(0.1); returnParameters->SetBackgroundAnisotropy(0.9); returnParameters->SetBackgroundScattering(15); - returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateRandomlyDivergingPosition); + returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); returnParameters->SetDoPartialVolume(true); returnParameters->SetMinNumberOfVessels(1); returnParameters->SetMaxNumberOfVessels(7); returnParameters->SetMinVesselAbsorption(2); returnParameters->SetMaxVesselAbsorption(8); returnParameters->SetMinVesselAnisotropy(0.9); returnParameters->SetMaxVesselAnisotropy(0.9); returnParameters->SetMinVesselBending(0.1); returnParameters->SetMaxVesselBending(0.3); returnParameters->SetMinVesselRadiusInMillimeters(0.5); returnParameters->SetMaxVesselRadiusInMillimeters(4); returnParameters->SetMinVesselScattering(15); returnParameters->SetMaxVesselScattering(15); returnParameters->SetMinVesselZOrigin(2.2); returnParameters->SetMaxVesselZOrigin(4); returnParameters->SetVesselBifurcationFrequency(5000); returnParameters->SetRandomizePhysicalProperties(false); returnParameters->SetSkinThicknessInMillimeters(0); returnParameters->SetUseRngSeed(false); returnParameters->SetVoxelSpacingInCentimeters(0.03); returnParameters->SetXDim(140); returnParameters->SetYDim(200); returnParameters->SetZDim(180); return returnParameters; } TissueGeneratorParameters::Pointer CreateSinglevessel_19_10_17_Parameters() { auto returnParameters = TissueGeneratorParameters::New(); returnParameters->SetAirThicknessInMillimeters(12); returnParameters->SetMinBackgroundAbsorption(0.1); returnParameters->SetMaxBackgroundAbsorption(0.1); returnParameters->SetBackgroundAnisotropy(0.9); returnParameters->SetBackgroundScattering(15); - returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateRandomlyDivergingPosition); + returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); returnParameters->SetDoPartialVolume(true); returnParameters->SetMinNumberOfVessels(1); returnParameters->SetMaxNumberOfVessels(1); returnParameters->SetMinVesselAbsorption(2); returnParameters->SetMaxVesselAbsorption(8); returnParameters->SetMinVesselAnisotropy(0.9); returnParameters->SetMaxVesselAnisotropy(0.9); returnParameters->SetMinVesselBending(0.1); returnParameters->SetMaxVesselBending(0.3); returnParameters->SetMinVesselRadiusInMillimeters(0.5); returnParameters->SetMaxVesselRadiusInMillimeters(4); returnParameters->SetMinVesselScattering(15); returnParameters->SetMaxVesselScattering(15); returnParameters->SetMinVesselZOrigin(2.2); returnParameters->SetMaxVesselZOrigin(4); returnParameters->SetVesselBifurcationFrequency(5000); returnParameters->SetRandomizePhysicalProperties(false); returnParameters->SetSkinThicknessInMillimeters(0); returnParameters->SetUseRngSeed(false); returnParameters->SetVoxelSpacingInCentimeters(0.03); returnParameters->SetXDim(140); returnParameters->SetYDim(200); returnParameters->SetZDim(180); return returnParameters; } struct InputParameters { std::string saveFolderPath; std::string identifyer; std::string exePath; std::string probePath; bool verbose; }; InputParameters parseInput(int argc, char* argv[]) { MITK_INFO << "Paring arguments..."; mitkCommandLineParser parser; // set general information parser.setCategory("MITK-Photoacoustics"); parser.setTitle("Mitk Tissue Batch Generator"); parser.setDescription("Creates in silico tissue in batch processing and automatically calculates fluence values for the central slice of the volume."); parser.setContributor("Computer Assisted Medical Interventions, DKFZ"); // how should arguments be prefixed parser.setArgumentPrefix("--", "-"); // add each argument, unless specified otherwise each argument is optional // see mitkCommandLineParser::addArgument for more information parser.beginGroup("Required parameters"); parser.addArgument( "savePath", "s", mitkCommandLineParser::InputDirectory, "Input save folder (directory)", "input save folder", us::Any(), false); parser.addArgument( "mitkMcxyz", "m", mitkCommandLineParser::OutputFile, "MitkMcxyz binary (file)", "path to the MitkMcxyz binary", us::Any(), false); parser.endGroup(); parser.beginGroup("Optional parameters"); parser.addArgument( "probe", "p", mitkCommandLineParser::OutputFile, "xml probe file (file)", "file to the definition of the used probe (*.xml)", us::Any()); parser.addArgument( "verbose", "v", mitkCommandLineParser::Bool, "Verbose Output", "Whether to produce verbose, or rather debug output"); parser.addArgument( "identifyer", "i", mitkCommandLineParser::String, "Generator identifyer (string)", "A unique identifyer for the calculation instance"); InputParameters input; std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size() == 0) exit(-1); if (parsedArgs.count("verbose")) { MITK_INFO << "verbose"; input.verbose = us::any_cast(parsedArgs["verbose"]); } else { input.verbose = false; } if (parsedArgs.count("savePath")) { MITK_INFO << "savePath"; input.saveFolderPath = us::any_cast(parsedArgs["savePath"]); } if (parsedArgs.count("mitkMcxyz")) { MITK_INFO << "mitkMcxyz"; input.exePath = us::any_cast(parsedArgs["mitkMcxyz"]); } if (parsedArgs.count("probe")) { MITK_INFO << "probe"; input.probePath = us::any_cast(parsedArgs["probe"]); } if (parsedArgs.count("identifyer")) { MITK_INFO << "identifyer"; input.identifyer = us::any_cast(parsedArgs["identifyer"]); } else { MITK_INFO << "generating identifyer"; auto uid = mitk::UIDGenerator("", 8); input.identifyer = uid.GetUID(); } MITK_INFO << "Paring arguments...[Done]"; return input; } int main(int argc, char * argv[]) { auto input = parseInput(argc, argv); unsigned int iterationNumber = 0; while (true) { auto parameters = CreateBaselineHB_13_02_18_Parameters(); MITK_INFO(input.verbose) << "Generating tissue.."; auto resultTissue = InSilicoTissueGenerator::GenerateInSilicoData(parameters); MITK_INFO(input.verbose) << "Generating tissue..[Done]"; auto inputfolder = std::string(input.saveFolderPath + "input/"); auto outputfolder = std::string(input.saveFolderPath + "output/"); if (!itksys::SystemTools::FileIsDirectory(inputfolder)) { itksys::SystemTools::MakeDirectory(inputfolder); } if (!itksys::SystemTools::FileIsDirectory(outputfolder)) { itksys::SystemTools::MakeDirectory(outputfolder); } std::string savePath = input.saveFolderPath + "input/BaselineHB_" + input.identifyer + "_" + std::to_string(iterationNumber) + ".nrrd"; mitk::IOUtil::Save(resultTissue->ConvertToMitkImage(), savePath); std::string outputPath = input.saveFolderPath + "output/BaselineHB_" + input.identifyer + "_" + std::to_string(iterationNumber) + "/"; if (!itksys::SystemTools::FileIsDirectory(outputPath)) { itksys::SystemTools::MakeDirectory(outputPath); } outputPath = outputPath + "Fluence_BaselineHB_" + input.identifyer + "_" + std::to_string(iterationNumber); MITK_INFO(input.verbose) << "Simulating fluence.."; for(double yo = -1.8; yo <= 1.81; yo=yo+0.12) { std::string yo_string = std::to_string(round(yo*100)/100.0); int result = -4; if(!input.probePath.empty()) result = std::system(std::string(input.exePath + " -i " + savePath + " -o " + (outputPath + "_yo" + yo_string + ".nrrd") + " -yo " + yo_string + " -p " + input.probePath + " -n 100000000").c_str()); else result = std::system(std::string(input.exePath + " -i " + savePath + " -o " + (outputPath + "_yo" + yo_string + ".nrrd") + " -yo " + yo_string + " -n 100000000").c_str()); MITK_INFO << "yo: " << yo_string << ": " << result; } MITK_INFO(input.verbose) << "Simulating fluence..[Done]"; iterationNumber++; } } diff --git a/Modules/PhotoacousticsLib/include/mitkPATissueGeneratorParameters.h b/Modules/PhotoacousticsLib/include/mitkPATissueGeneratorParameters.h index 2ab5fcf444..2351f24aec 100644 --- a/Modules/PhotoacousticsLib/include/mitkPATissueGeneratorParameters.h +++ b/Modules/PhotoacousticsLib/include/mitkPATissueGeneratorParameters.h @@ -1,217 +1,217 @@ /*=================================================================== 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 MITKPHOTOACOUSTICTISSUEGENERATORPARAMETERS_H #define MITKPHOTOACOUSTICTISSUEGENERATORPARAMETERS_H #include #include //Includes for smart pointer usage #include "mitkCommon.h" #include "itkLightObject.h" namespace mitk { namespace pa { class MITKPHOTOACOUSTICSLIB_EXPORT TissueGeneratorParameters : public itk::Object { public: mitkClassMacroItkParent(TissueGeneratorParameters, itk::Object) itkFactorylessNewMacro(Self) /** * Callback function definition of a VesselMeanderStrategy */ typedef void (VesselMeanderStrategy::*CalculateNewVesselPositionCallback) - (Vector::Pointer, Vector::Pointer, double, std::mt19937*); + (Vector::Pointer, double, std::mt19937*); itkGetMacro(XDim, int) itkGetMacro(YDim, int) itkGetMacro(ZDim, int) itkGetMacro(VoxelSpacingInCentimeters, double) itkGetMacro(DoPartialVolume, bool) itkGetMacro(UseRngSeed, bool) itkGetMacro(RngSeed, long) itkGetMacro(RandomizePhysicalProperties, bool) itkGetMacro(RandomizePhysicalPropertiesPercentage, double) itkGetMacro(ForceVesselsMoveAlongYDirection, bool) itkGetMacro(MinBackgroundAbsorption, double) itkGetMacro(MaxBackgroundAbsorption, double) itkGetMacro(BackgroundScattering, double) itkGetMacro(BackgroundAnisotropy, double) itkGetMacro(AirAbsorption, double) itkGetMacro(AirScattering, double) itkGetMacro(AirAnisotropy, double) itkGetMacro(AirThicknessInMillimeters, double) itkGetMacro(SkinAbsorption, double) itkGetMacro(SkinScattering, double) itkGetMacro(SkinAnisotropy, double) itkGetMacro(SkinThicknessInMillimeters, double) itkGetMacro(CalculateNewVesselPositionCallback, CalculateNewVesselPositionCallback) itkGetMacro(MinNumberOfVessels, int) itkGetMacro(MaxNumberOfVessels, int) itkGetMacro(MinVesselBending, double) itkGetMacro(MaxVesselBending, double) itkGetMacro(MinVesselAbsorption, double) itkGetMacro(MaxVesselAbsorption, double) itkGetMacro(MinVesselRadiusInMillimeters, double) itkGetMacro(MaxVesselRadiusInMillimeters, double) itkGetMacro(VesselBifurcationFrequency, int) itkGetMacro(MinVesselScattering, double) itkGetMacro(MaxVesselScattering, double) itkGetMacro(MinVesselAnisotropy, double) itkGetMacro(MaxVesselAnisotropy, double) itkGetMacro(MinVesselZOrigin, double) itkGetMacro(MaxVesselZOrigin, double) itkGetMacro(MCflag, double) itkGetMacro(MCLaunchflag, double) itkGetMacro(MCBoundaryflag, double) itkGetMacro(MCLaunchPointX, double) itkGetMacro(MCLaunchPointY, double) itkGetMacro(MCLaunchPointZ, double) itkGetMacro(MCFocusPointX, double) itkGetMacro(MCFocusPointY, double) itkGetMacro(MCFocusPointZ, double) itkGetMacro(MCTrajectoryVectorX, double) itkGetMacro(MCTrajectoryVectorY, double) itkGetMacro(MCTrajectoryVectorZ, double) itkGetMacro(MCRadius, double) itkGetMacro(MCWaist, double) itkSetMacro(XDim, int) itkSetMacro(YDim, int) itkSetMacro(ZDim, int) itkSetMacro(VoxelSpacingInCentimeters, double) itkSetMacro(DoPartialVolume, bool) itkSetMacro(UseRngSeed, bool) itkSetMacro(RngSeed, long) itkSetMacro(RandomizePhysicalProperties, bool) itkSetMacro(RandomizePhysicalPropertiesPercentage, double) itkSetMacro(ForceVesselsMoveAlongYDirection, bool) itkSetMacro(MinBackgroundAbsorption, double) itkSetMacro(MaxBackgroundAbsorption, double) itkSetMacro(BackgroundScattering, double) itkSetMacro(BackgroundAnisotropy, double) itkSetMacro(AirAbsorption, double) itkSetMacro(AirScattering, double) itkSetMacro(AirAnisotropy, double) itkSetMacro(AirThicknessInMillimeters, double) itkSetMacro(SkinAbsorption, double) itkSetMacro(SkinScattering, double) itkSetMacro(SkinAnisotropy, double) itkSetMacro(SkinThicknessInMillimeters, double) itkSetMacro(CalculateNewVesselPositionCallback, CalculateNewVesselPositionCallback) itkSetMacro(MinNumberOfVessels, int) itkSetMacro(MaxNumberOfVessels, int) itkSetMacro(MinVesselBending, double) itkSetMacro(MaxVesselBending, double) itkSetMacro(MinVesselAbsorption, double) itkSetMacro(MaxVesselAbsorption, double) itkSetMacro(MinVesselRadiusInMillimeters, double) itkSetMacro(MaxVesselRadiusInMillimeters, double) itkSetMacro(VesselBifurcationFrequency, int) itkSetMacro(MinVesselScattering, double) itkSetMacro(MaxVesselScattering, double) itkSetMacro(MinVesselAnisotropy, double) itkSetMacro(MaxVesselAnisotropy, double) itkSetMacro(MinVesselZOrigin, double) itkSetMacro(MaxVesselZOrigin, double) itkSetMacro(MCflag, double) itkSetMacro(MCLaunchflag, double) itkSetMacro(MCBoundaryflag, double) itkSetMacro(MCLaunchPointX, double) itkSetMacro(MCLaunchPointY, double) itkSetMacro(MCLaunchPointZ, double) itkSetMacro(MCFocusPointX, double) itkSetMacro(MCFocusPointY, double) itkSetMacro(MCFocusPointZ, double) itkSetMacro(MCTrajectoryVectorX, double) itkSetMacro(MCTrajectoryVectorY, double) itkSetMacro(MCTrajectoryVectorZ, double) itkSetMacro(MCRadius, double) itkSetMacro(MCWaist, double) protected: TissueGeneratorParameters(); ~TissueGeneratorParameters(); private: int m_XDim; int m_YDim; int m_ZDim; double m_VoxelSpacingInCentimeters; bool m_DoPartialVolume; bool m_UseRngSeed; long m_RngSeed; bool m_RandomizePhysicalProperties; double m_RandomizePhysicalPropertiesPercentage; bool m_ForceVesselsMoveAlongYDirection; double m_MinBackgroundAbsorption; double m_MaxBackgroundAbsorption; double m_BackgroundScattering; double m_BackgroundAnisotropy; double m_AirAbsorption; double m_AirScattering; double m_AirAnisotropy; double m_AirThicknessInMillimeters; double m_SkinAbsorption; double m_SkinScattering; double m_SkinAnisotropy; double m_SkinThicknessInMillimeters; CalculateNewVesselPositionCallback m_CalculateNewVesselPositionCallback; int m_MinNumberOfVessels; int m_MaxNumberOfVessels; double m_MinVesselBending; double m_MaxVesselBending; double m_MinVesselAbsorption; double m_MaxVesselAbsorption; double m_MinVesselRadiusInMillimeters; double m_MaxVesselRadiusInMillimeters; int m_VesselBifurcationFrequency; double m_MinVesselScattering; double m_MaxVesselScattering; double m_MinVesselAnisotropy; double m_MaxVesselAnisotropy; double m_MinVesselZOrigin; double m_MaxVesselZOrigin; double m_MCflag; double m_MCLaunchflag; double m_MCBoundaryflag; double m_MCLaunchPointX; double m_MCLaunchPointY; double m_MCLaunchPointZ; double m_MCFocusPointX; double m_MCFocusPointY; double m_MCFocusPointZ; double m_MCTrajectoryVectorX; double m_MCTrajectoryVectorY; double m_MCTrajectoryVectorZ; double m_MCRadius; double m_MCWaist; }; } } #endif // MITKPHOTOACOUSTICTISSUEGENERATORPARAMETERS_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAVessel.h b/Modules/PhotoacousticsLib/include/mitkPAVessel.h index 579e3e407e..096c962149 100644 --- a/Modules/PhotoacousticsLib/include/mitkPAVessel.h +++ b/Modules/PhotoacousticsLib/include/mitkPAVessel.h @@ -1,117 +1,117 @@ /*=================================================================== 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 MITKVESSEL_H #define MITKVESSEL_H #include "mitkVector.h" #include "mitkPAVesselMeanderStrategy.h" #include "mitkPAInSilicoTissueVolume.h" #include "mitkPAVector.h" #include "mitkPAVesselProperties.h" #include "mitkPAVesselDrawer.h" #include //Includes for smart pointer usage #include "mitkCommon.h" #include "itkLightObject.h" namespace mitk { namespace pa { class MITKPHOTOACOUSTICSLIB_EXPORT Vessel : public itk::LightObject { public: mitkClassMacroItkParent(Vessel, itk::LightObject) mitkNewMacro1Param(Self, VesselProperties::Pointer) /** * Callback function definition of a VesselMeanderStrategy */ typedef void (VesselMeanderStrategy::*CalculateNewVesselPositionCallback) - (Vector::Pointer, Vector::Pointer, double, std::mt19937*); + (Vector::Pointer, double, std::mt19937*); /** * @brief ExpandVessel makes this Vessel expand one step in its current direction. * After expanding, the vessel will draw itself into the given InSilicoTissueVolume. * * @param volume volume for the vessel to draw itself in * @param calculateNewPosition a callback function of the VesselMeanderStrategy class. * It is used to calculate the final position after taking the step. * @param bendingFactor a metric of how much the Vessel should bend. If set to 0 the vessel will go in a straight line. */ void ExpandVessel(mitk::pa::InSilicoTissueVolume::Pointer volume, CalculateNewVesselPositionCallback calculateNewPosition, double bendingFactor, std::mt19937* rng); /** * @brief CanBifurcate * @return true if the Vessel is ready to Bifurcate() */ bool CanBifurcate(); /** * @brief Bifurcate bifurcates this vessel into two new ones. Makes sure that the volume of the vessels stays the same. * * @return a new vessel split up from the current one. */ Vessel::Pointer Bifurcate(std::mt19937* rng); /** * @brief IsFinished * @return true if the vessel cannot expand any further */ bool IsFinished(); itkGetConstMacro(VesselProperties, VesselProperties::Pointer); protected: Vessel(VesselProperties::Pointer parameters); ~Vessel() override; private: const double MINIMUM_VESSEL_RADIUS = 0.1; const double NEW_RADIUS_MINIMUM_RELATIVE_SIZE = 0.6; const double NEW_RADIUS_MAXIMUM_RELATIVE_SIZE = 0.8; VesselMeanderStrategy::Pointer m_VesselMeanderStrategy; bool m_Finished; double m_WalkedDistance; std::uniform_real_distribution<> m_RangeDistribution; std::uniform_real_distribution<> m_SignDistribution; std::uniform_real_distribution<> m_RadiusRangeDistribution; int GetSign(std::mt19937* rng); VesselProperties::Pointer m_VesselProperties; VesselDrawer::Pointer m_VesselDrawer; }; /** * @brief Equal A function comparing two vessels for beeing equal * * @param rightHandSide A vessel to be compared * @param leftHandSide A vessel to be compared * @param eps tolarence for comparison. You can use mitk::eps in most cases. * @param verbose flag indicating if the user wants detailed console output or not. * @return true, if all subsequent comparisons are true, false otherwise */ MITKPHOTOACOUSTICSLIB_EXPORT bool Equal(const Vessel::Pointer leftHandSide, const Vessel::Pointer rightHandSide, double eps, bool verbose); } } #endif // MITKVESSEL_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAVesselDrawer.h b/Modules/PhotoacousticsLib/include/mitkPAVesselDrawer.h index e201d468a5..0c1082a00d 100644 --- a/Modules/PhotoacousticsLib/include/mitkPAVesselDrawer.h +++ b/Modules/PhotoacousticsLib/include/mitkPAVesselDrawer.h @@ -1,53 +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 MITKVESSELDRAWER_H #define MITKVESSELDRAWER_H #include "mitkVector.h" #include "mitkPAVesselMeanderStrategy.h" #include "mitkPAInSilicoTissueVolume.h" #include "mitkPAVector.h" #include "mitkPAVesselProperties.h" #include //Includes for smart pointer usage #include "mitkCommon.h" #include "itkLightObject.h" namespace mitk { namespace pa { class MITKPHOTOACOUSTICSLIB_EXPORT VesselDrawer : public itk::LightObject { public: mitkClassMacroItkParent(VesselDrawer, itk::LightObject); itkFactorylessNewMacro(Self); - void DrawVesselInVolume( + void ExpandAndDrawVesselInVolume( VesselProperties::Pointer properties, InSilicoTissueVolume::Pointer volume); protected: VesselDrawer(); virtual ~VesselDrawer(); private: }; } } #endif // MITKVESSELDRAWER_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAVesselMeanderStrategy.h b/Modules/PhotoacousticsLib/include/mitkPAVesselMeanderStrategy.h index 0726f30856..600832bbc0 100644 --- a/Modules/PhotoacousticsLib/include/mitkPAVesselMeanderStrategy.h +++ b/Modules/PhotoacousticsLib/include/mitkPAVesselMeanderStrategy.h @@ -1,64 +1,62 @@ /*=================================================================== 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 MITKVESSELMEANDERSTRATEGY_H #define MITKVESSELMEANDERSTRATEGY_H #include "mitkVector.h" #include "mitkPAVector.h" #include //Includes for smart pointer usage #include "mitkCommon.h" #include "itkLightObject.h" namespace mitk { namespace pa { class MITKPHOTOACOUSTICSLIB_EXPORT VesselMeanderStrategy : public itk::LightObject { public: mitkClassMacroItkParent(VesselMeanderStrategy, itk::LightObject) itkFactorylessNewMacro(Self) /** * @brief CalculateNewPositionInStraightLine calculates the new position by just following the direction vector. - * @param position * @param direction * @param bendingFactor */ - void CalculateNewPositionInStraightLine(Vector::Pointer position, Vector::Pointer direction, double bendingFactor, std::mt19937* rng); + void CalculateNewDirectionVectorInStraightLine(Vector::Pointer direction, double bendingFactor, std::mt19937* rng); /** * @brief CalculateRandomlyDivergingPosition calculates the new position by modifying the direction vector randomly, * proportional to the selected bendingFactor. This means, that the vessels will bend in each expansion step, * if bendingFactor > 0. * - * @param position * @param direction * @param bendingFactor */ - void CalculateRandomlyDivergingPosition(Vector::Pointer position, Vector::Pointer direction, double bendingFactor, std::mt19937* rng); + void CalculateNewRandomlyDivergingDirectionVector(Vector::Pointer direction, double bendingFactor, std::mt19937* rng); protected: VesselMeanderStrategy(); ~VesselMeanderStrategy() override; const double RANDOMIZATION_PERCENTAGE = 0.4; }; } } #endif // MITKVESSELMEANDERSTRATEGY_H diff --git a/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVessel.cpp b/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVessel.cpp index c3c98426de..f159e9203f 100644 --- a/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVessel.cpp +++ b/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVessel.cpp @@ -1,115 +1,115 @@ /*=================================================================== 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 "mitkPAVessel.h" #include #include mitk::pa::Vessel::Vessel(VesselProperties::Pointer initialProperties) : m_RangeDistribution(itk::Math::pi / 16, itk::Math::pi / 8), m_SignDistribution(-1, 1) { m_Finished = false; //Copy this so it may be reused for other vessels. m_VesselProperties = VesselProperties::New(initialProperties); m_RadiusRangeDistribution = std::uniform_real_distribution<>(NEW_RADIUS_MINIMUM_RELATIVE_SIZE, NEW_RADIUS_MAXIMUM_RELATIVE_SIZE); m_VesselMeanderStrategy = VesselMeanderStrategy::New(); m_WalkedDistance = 0; m_VesselDrawer = VesselDrawer::New(); } mitk::pa::Vessel::~Vessel() { m_VesselProperties = nullptr; m_VesselMeanderStrategy = nullptr; } void mitk::pa::Vessel::ExpandVessel(InSilicoTissueVolume::Pointer volume, CalculateNewVesselPositionCallback calculateNewPosition, double bendingFactor, std::mt19937* rng) { - m_VesselDrawer->DrawVesselInVolume(m_VesselProperties, volume); - (m_VesselMeanderStrategy->*calculateNewPosition)(m_VesselProperties->GetPositionVector(), m_VesselProperties->GetDirectionVector(), bendingFactor, rng); + m_VesselDrawer->ExpandAndDrawVesselInVolume(m_VesselProperties, volume); + (m_VesselMeanderStrategy->*calculateNewPosition)(m_VesselProperties->GetDirectionVector(), bendingFactor, rng); m_WalkedDistance += (m_VesselProperties->GetDirectionVector()->GetNorm() / volume->GetSpacing()); } bool mitk::pa::Vessel::CanBifurcate() { return m_VesselProperties->GetBifurcationFrequency() < m_WalkedDistance; } int mitk::pa::Vessel::GetSign(std::mt19937 *rng) { if (m_SignDistribution(*rng) < 0) return -1; return 1; } mitk::pa::Vessel::Pointer mitk::pa::Vessel::Bifurcate(std::mt19937* rng) { VesselProperties::Pointer vesselParams = VesselProperties::New(m_VesselProperties); double thetaChange = m_RangeDistribution(*rng) * GetSign(rng); double phiChange = m_RangeDistribution(*rng) * GetSign(rng); vesselParams->GetDirectionVector()->Rotate(thetaChange, phiChange); m_VesselProperties->GetDirectionVector()->Rotate(-thetaChange, -phiChange); double newRadius = m_RadiusRangeDistribution(*rng)*m_VesselProperties->GetRadiusInVoxel(); vesselParams->SetRadiusInVoxel(newRadius); m_VesselProperties->SetRadiusInVoxel( sqrt(m_VesselProperties->GetRadiusInVoxel()*m_VesselProperties->GetRadiusInVoxel() - newRadius*newRadius)); m_WalkedDistance = 0; return Vessel::New(vesselParams); } bool mitk::pa::Vessel::IsFinished() { return m_VesselProperties->GetRadiusInVoxel() < MINIMUM_VESSEL_RADIUS; } bool mitk::pa::Equal(const Vessel::Pointer leftHandSide, const Vessel::Pointer rightHandSide, double eps, bool verbose) { MITK_INFO(verbose) << "=== mitk::pa::Vessel Equal ==="; if (rightHandSide.IsNull() || leftHandSide.IsNull()) { MITK_INFO(verbose) << "Cannot compare nullpointers"; return false; } if (leftHandSide->IsFinished() != rightHandSide->IsFinished()) { MITK_INFO(verbose) << "Not same finished state."; return false; } if (leftHandSide->CanBifurcate() != rightHandSide->CanBifurcate()) { MITK_INFO(verbose) << "Not same bifurcation state."; return false; } if (!Equal(leftHandSide->GetVesselProperties(), rightHandSide->GetVesselProperties(), eps, verbose)) { MITK_INFO(verbose) << "Vesselproperties not equal"; return false; } return true; } diff --git a/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVesselMeanderStrategy.cpp b/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVesselMeanderStrategy.cpp index 14229f6577..10ebdb9e7e 100644 --- a/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVesselMeanderStrategy.cpp +++ b/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVesselMeanderStrategy.cpp @@ -1,47 +1,45 @@ /*=================================================================== 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 "mitkPAVesselMeanderStrategy.h" mitk::pa::VesselMeanderStrategy::VesselMeanderStrategy() { } mitk::pa::VesselMeanderStrategy::~VesselMeanderStrategy() { } -void mitk::pa::VesselMeanderStrategy::CalculateNewPositionInStraightLine( - Vector::Pointer /*position*/, Vector::Pointer direction, double /*bendingFactor*/, std::mt19937* rng) +void mitk::pa::VesselMeanderStrategy::CalculateNewDirectionVectorInStraightLine(Vector::Pointer direction, double /*bendingFactor*/, std::mt19937* rng) { if (direction->GetNorm() <= mitk::eps) { direction->Randomize(rng); } } -void mitk::pa::VesselMeanderStrategy::CalculateRandomlyDivergingPosition( - Vector::Pointer /*position*/, Vector::Pointer direction, double bendingFactor, std::mt19937* rng) +void mitk::pa::VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector(Vector::Pointer direction, double bendingFactor, std::mt19937* rng) { if (direction->GetNorm() <= mitk::eps) { direction->Randomize(rng); } direction->RandomizeByPercentage(RANDOMIZATION_PERCENTAGE, bendingFactor, rng); direction->Normalize(); } diff --git a/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAInSilicoTissueVolume.cpp b/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAInSilicoTissueVolume.cpp index 9c7f308207..6a6ecc8a95 100644 --- a/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAInSilicoTissueVolume.cpp +++ b/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAInSilicoTissueVolume.cpp @@ -1,387 +1,402 @@ /*=================================================================== 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 #include #include mitk::pa::InSilicoTissueVolume::InSilicoTissueVolume(TissueGeneratorParameters::Pointer parameters, std::mt19937* rng) { { unsigned int xDim = parameters->GetXDim(); unsigned int yDim = parameters->GetYDim(); unsigned int zDim = parameters->GetZDim(); - m_TDim = 3; + m_TDim = 4; unsigned int size = xDim * yDim * zDim; auto* absorptionArray = new double[size]; auto* scatteringArray = new double[size]; auto* anisotropyArray = new double[size]; auto* segmentationArray = new double[size]; m_InitialBackgroundAbsorption = (parameters->GetMinBackgroundAbsorption() + parameters->GetMaxBackgroundAbsorption()) / 2; m_Rng = rng; for (unsigned int index = 0; index < size; index++) { absorptionArray[index] = m_InitialBackgroundAbsorption; scatteringArray[index] = parameters->GetBackgroundScattering(); anisotropyArray[index] = parameters->GetBackgroundAnisotropy(); segmentationArray[index] = SegmentationType::BACKGROUND; } m_AbsorptionVolume = Volume::New(absorptionArray, xDim, yDim, zDim, parameters->GetVoxelSpacingInCentimeters()); m_ScatteringVolume = Volume::New(scatteringArray, xDim, yDim, zDim, parameters->GetVoxelSpacingInCentimeters()); m_AnisotropyVolume = Volume::New(anisotropyArray, xDim, yDim, zDim, parameters->GetVoxelSpacingInCentimeters()); m_SegmentationVolume = Volume::New(segmentationArray, xDim, yDim, zDim, parameters->GetVoxelSpacingInCentimeters()); } m_TissueParameters = parameters; m_PropertyList = mitk::PropertyList::New(); UpdatePropertyList(); } void mitk::pa::InSilicoTissueVolume::UpdatePropertyList() { //Set properties AddIntProperty("mcflag", m_TissueParameters->GetMCflag()); AddIntProperty("launchflag", m_TissueParameters->GetMCLaunchflag()); AddIntProperty("boundaryflag", m_TissueParameters->GetMCBoundaryflag()); AddDoubleProperty("launchPointX", m_TissueParameters->GetMCLaunchPointX()); AddDoubleProperty("launchPointY", m_TissueParameters->GetMCLaunchPointY()); AddDoubleProperty("launchPointZ", m_TissueParameters->GetMCLaunchPointZ()); AddDoubleProperty("focusPointX", m_TissueParameters->GetMCFocusPointX()); AddDoubleProperty("focusPointY", m_TissueParameters->GetMCFocusPointY()); AddDoubleProperty("focusPointZ", m_TissueParameters->GetMCFocusPointZ()); AddDoubleProperty("trajectoryVectorX", m_TissueParameters->GetMCTrajectoryVectorX()); AddDoubleProperty("trajectoryVectorY", m_TissueParameters->GetMCTrajectoryVectorY()); AddDoubleProperty("trajectoryVectorZ", m_TissueParameters->GetMCTrajectoryVectorZ()); AddDoubleProperty("radius", m_TissueParameters->GetMCRadius()); AddDoubleProperty("waist", m_TissueParameters->GetMCWaist()); AddDoubleProperty("partialVolume", m_TissueParameters->GetDoPartialVolume()); AddDoubleProperty("standardTissueAbsorptionMin", m_TissueParameters->GetMinBackgroundAbsorption()); AddDoubleProperty("standardTissueAbsorptionMax", m_TissueParameters->GetMaxBackgroundAbsorption()); AddDoubleProperty("standardTissueScattering", m_TissueParameters->GetBackgroundScattering()); AddDoubleProperty("standardTissueAnisotropy", m_TissueParameters->GetBackgroundAnisotropy()); AddDoubleProperty("airThickness", m_TissueParameters->GetAirThicknessInMillimeters()); AddDoubleProperty("skinThickness", m_TissueParameters->GetSkinThicknessInMillimeters()); } mitk::pa::InSilicoTissueVolume::InSilicoTissueVolume( Volume::Pointer absorptionVolume, Volume::Pointer scatteringVolume, Volume::Pointer anisotropyVolume, Volume::Pointer segmentationVolume, TissueGeneratorParameters::Pointer tissueParameters, mitk::PropertyList::Pointer propertyList) { m_AbsorptionVolume = absorptionVolume; m_ScatteringVolume = scatteringVolume; m_AnisotropyVolume = anisotropyVolume; m_SegmentationVolume = segmentationVolume; m_TissueParameters = tissueParameters; m_PropertyList = propertyList; if (m_SegmentationVolume.IsNotNull()) m_TDim = 4; else m_TDim = 3; } double mitk::pa::InSilicoTissueVolume::GetSpacing() { return m_AbsorptionVolume->GetSpacing(); } void mitk::pa::InSilicoTissueVolume::SetSpacing(double spacing) { m_AbsorptionVolume->SetSpacing(spacing); m_ScatteringVolume->SetSpacing(spacing); m_AnisotropyVolume->SetSpacing(spacing); - m_SegmentationVolume->SetSpacing(spacing); + if (m_SegmentationVolume.IsNotNull()) + { + m_SegmentationVolume->SetSpacing(spacing); + } } void mitk::pa::InSilicoTissueVolume::AddDoubleProperty(std::string label, double value) { m_PropertyList->SetDoubleProperty(label.c_str(), value); mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New(label)); } void mitk::pa::InSilicoTissueVolume::AddIntProperty(std::string label, int value) { m_PropertyList->SetIntProperty(label.c_str(), value); mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New(label)); } mitk::Image::Pointer mitk::pa::InSilicoTissueVolume::ConvertToMitkImage() { mitk::Image::Pointer resultImage = mitk::Image::New(); mitk::PixelType TPixel = mitk::MakeScalarPixelType(); auto* dimensionsOfImage = new unsigned int[4]; // Copy dimensions dimensionsOfImage[0] = m_TissueParameters->GetYDim(); dimensionsOfImage[1] = m_TissueParameters->GetXDim(); dimensionsOfImage[2] = m_TissueParameters->GetZDim(); dimensionsOfImage[3] = m_TDim; resultImage->Initialize(TPixel, 4, dimensionsOfImage, 1); mitk::Vector3D spacing; spacing.Fill(m_TissueParameters->GetVoxelSpacingInCentimeters()); resultImage->SetSpacing(spacing); resultImage->SetImportVolume(m_AbsorptionVolume->GetData(), 0, 0, mitk::Image::CopyMemory); resultImage->SetImportVolume(m_ScatteringVolume->GetData(), 1, 0, mitk::Image::CopyMemory); resultImage->SetImportVolume(m_AnisotropyVolume->GetData(), 2, 0, mitk::Image::CopyMemory); - resultImage->SetImportVolume(m_SegmentationVolume->GetData(), 3, 0, mitk::Image::CopyMemory); + if (m_TDim > 3) + { + resultImage->SetImportVolume(m_SegmentationVolume->GetData(), 3, 0, mitk::Image::CopyMemory); + } resultImage->SetPropertyList(m_PropertyList); return resultImage; } mitk::pa::InSilicoTissueVolume::Pointer mitk::pa::InSilicoTissueVolume::New( Volume::Pointer absorptionVolume, Volume::Pointer scatteringVolume, Volume::Pointer anisotropyVolume, Volume::Pointer segmentationVolume, TissueGeneratorParameters::Pointer tissueParameters, mitk::PropertyList::Pointer propertyList) { InSilicoTissueVolume::Pointer smartPtr = new InSilicoTissueVolume( absorptionVolume, scatteringVolume, anisotropyVolume, segmentationVolume, tissueParameters, propertyList); smartPtr->UnRegister(); return smartPtr; } mitk::pa::InSilicoTissueVolume::~InSilicoTissueVolume() { m_AbsorptionVolume = nullptr; m_ScatteringVolume = nullptr; m_AnisotropyVolume = nullptr; m_SegmentationVolume = nullptr; m_TissueParameters = nullptr; m_PropertyList = nullptr; } void mitk::pa::InSilicoTissueVolume::SetVolumeValues(int x, int y, int z, double absorption, double scattering, double anisotropy) { if (IsInsideVolume(x, y, z)) { m_AbsorptionVolume->SetData(absorption, x, y, z); m_ScatteringVolume->SetData(scattering, x, y, z); m_AnisotropyVolume->SetData(anisotropy, x, y, z); } } void mitk::pa::InSilicoTissueVolume::SetVolumeValues(int x, int y, int z, double absorption, double scattering, double anisotropy, SegmentationType segmentType) { if (IsInsideVolume(x, y, z)) { m_AbsorptionVolume->SetData(absorption, x, y, z); m_ScatteringVolume->SetData(scattering, x, y, z); m_AnisotropyVolume->SetData(anisotropy, x, y, z); - m_SegmentationVolume->SetData(segmentType, x, y, z); + if (m_SegmentationVolume.IsNotNull()) + { + m_SegmentationVolume->SetData(segmentType, x, y, z); + } } } bool mitk::pa::InSilicoTissueVolume::IsInsideVolume(int x, int y, int z) { return x >= 0 && x < m_TissueParameters->GetXDim() && y >= 0 && y < m_TissueParameters->GetYDim() && z >= 0 && z < m_TissueParameters->GetZDim(); } mitk::pa::Volume::Pointer mitk::pa::InSilicoTissueVolume::GetAbsorptionVolume() { return m_AbsorptionVolume; } mitk::pa::Volume::Pointer mitk::pa::InSilicoTissueVolume::GetSegmentationVolume() { return m_SegmentationVolume; } void mitk::pa::InSilicoTissueVolume::FinalizeVolume() { AddSkinAndAirLayers(); // If specified, randomize all tissue parameters if (m_TissueParameters->GetRandomizePhysicalProperties()) { RandomizeTissueCoefficients(m_TissueParameters->GetUseRngSeed(), m_TissueParameters->GetRngSeed(), m_TissueParameters->GetRandomizePhysicalPropertiesPercentage()); } unsigned int xDim = m_TissueParameters->GetXDim(); unsigned int yDim = m_TissueParameters->GetYDim(); unsigned int zDim = m_TissueParameters->GetZDim(); std::uniform_real_distribution randomBackgroundAbsorptionDistribution( m_TissueParameters->GetMinBackgroundAbsorption(), m_TissueParameters->GetMaxBackgroundAbsorption()); for (unsigned int z = 0; z < zDim; z++) { for (unsigned int y = 0; y < yDim; y++) { for (unsigned int x = 0; x < xDim; x++) { if (fabs(m_AbsorptionVolume->GetData(x, y, z) - m_InitialBackgroundAbsorption) < mitk::eps) { m_AbsorptionVolume->SetData(randomBackgroundAbsorptionDistribution(*m_Rng), x, y, z); } } } } } void mitk::pa::InSilicoTissueVolume::AddSkinAndAirLayers() { //Calculate the index location according to thickness in cm double airvoxel = (m_TissueParameters->GetAirThicknessInMillimeters() / m_TissueParameters->GetVoxelSpacingInCentimeters()) / 10; double skinvoxel = airvoxel + (m_TissueParameters->GetSkinThicknessInMillimeters() / m_TissueParameters->GetVoxelSpacingInCentimeters()) / 10; for (int y = 0; y < m_TissueParameters->GetYDim(); y++) { for (int x = 0; x < m_TissueParameters->GetXDim(); x++) { // Add air from index 0 to airvoxel if (m_TissueParameters->GetAirThicknessInMillimeters() > mitk::eps) { FillZLayer(x, y, 0, airvoxel, m_TissueParameters->GetAirAbsorption(), m_TissueParameters->GetAirScattering(), m_TissueParameters->GetAirAnisotropy(), SegmentationType::AIR); } //Add skin from index airvoxel to skinvoxel if (m_TissueParameters->GetSkinThicknessInMillimeters() > mitk::eps) { FillZLayer(x, y, airvoxel, skinvoxel, m_TissueParameters->GetSkinAbsorption(), m_TissueParameters->GetSkinScattering(), m_TissueParameters->GetSkinAnisotropy(), SegmentationType::SKIN); } } } } void mitk::pa::InSilicoTissueVolume::FillZLayer(int x, int y, double startIdx, double endIdx, double absorption, double scattering, double anisotropy, SegmentationType segmentationType) { for (int z = startIdx; z < endIdx; z++) { if (IsInsideVolume(x, y, z)) { if (endIdx - z < 1) { //Simulate partial volume effects m_AbsorptionVolume->SetData((1 - (endIdx - z)) * m_AbsorptionVolume->GetData(x, y, z) + (endIdx - z) * absorption, x, y, z); m_ScatteringVolume->SetData((1 - (endIdx - z)) * m_ScatteringVolume->GetData(x, y, z) + (endIdx - z) * scattering, x, y, z); m_AnisotropyVolume->SetData((1 - (endIdx - z)) * m_AnisotropyVolume->GetData(x, y, z) + (endIdx - z) * anisotropy, x, y, z); if (endIdx - z > 0.5) { //Only put the segmentation label if more than half of the partial volume is the wanted tissue type - m_SegmentationVolume->SetData(segmentationType, x, y, z); + if (m_SegmentationVolume.IsNotNull()) + { + m_SegmentationVolume->SetData(segmentationType, x, y, z); + } } } else { m_AbsorptionVolume->SetData(absorption, x, y, z); m_ScatteringVolume->SetData(scattering, x, y, z); m_AnisotropyVolume->SetData(anisotropy, x, y, z); - m_SegmentationVolume->SetData(segmentationType, x, y, z); + if (m_SegmentationVolume.IsNotNull()) + { + m_SegmentationVolume->SetData(segmentationType, x, y, z); + } } } } } void mitk::pa::InSilicoTissueVolume::RandomizeTissueCoefficients(long rngSeed, bool useRngSeed, double percentage) { std::mt19937 rng; std::random_device randomDevice; if (useRngSeed) { rng.seed(rngSeed); } else { if (randomDevice.entropy() > 0.1) { rng.seed(randomDevice()); } else { rng.seed(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); } } std::normal_distribution<> percentageDistribution(1, percentage / 100); for (int y = 0; y < m_TissueParameters->GetYDim(); y++) { for (int x = 0; x < m_TissueParameters->GetXDim(); x++) { for (int z = 0; z < m_TissueParameters->GetZDim(); z++) { m_AbsorptionVolume->SetData(m_AbsorptionVolume->GetData(x, y, z) * percentageDistribution(rng), x, y, z); m_ScatteringVolume->SetData(m_ScatteringVolume->GetData(x, y, z) * percentageDistribution(rng), x, y, z); } } } } mitk::pa::Volume::Pointer mitk::pa::InSilicoTissueVolume::GetScatteringVolume() { return m_ScatteringVolume; } mitk::pa::Volume::Pointer mitk::pa::InSilicoTissueVolume::GetAnisotropyVolume() { return m_AnisotropyVolume; } void mitk::pa::InSilicoTissueVolume::SetAbsorptionVolume(Volume::Pointer volume) { m_AbsorptionVolume = volume; } void mitk::pa::InSilicoTissueVolume::SetScatteringVolume(Volume::Pointer volume) { m_ScatteringVolume = volume; } void mitk::pa::InSilicoTissueVolume::SetAnisotropyVolume(Volume::Pointer volume) { m_AnisotropyVolume = volume; } void mitk::pa::InSilicoTissueVolume::SetSegmentationVolume(Volume::Pointer volume) { m_SegmentationVolume = volume; } diff --git a/Modules/PhotoacousticsLib/src/Utils/mitkPATissueGeneratorParameters.cpp b/Modules/PhotoacousticsLib/src/Utils/mitkPATissueGeneratorParameters.cpp index bcbeed0f2f..7f478d3dda 100644 --- a/Modules/PhotoacousticsLib/src/Utils/mitkPATissueGeneratorParameters.cpp +++ b/Modules/PhotoacousticsLib/src/Utils/mitkPATissueGeneratorParameters.cpp @@ -1,80 +1,80 @@ /*=================================================================== 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 "mitkPATissueGeneratorParameters.h" mitk::pa::TissueGeneratorParameters::TissueGeneratorParameters() { m_XDim = 50; m_YDim = 50; m_ZDim = 50; m_VoxelSpacingInCentimeters = 1; m_DoPartialVolume = false; m_UseRngSeed = false; m_RngSeed = 1337L; m_RandomizePhysicalProperties = false; m_RandomizePhysicalPropertiesPercentage = 0; m_ForceVesselsMoveAlongYDirection = false; m_MinBackgroundAbsorption = 0.1; m_MaxBackgroundAbsorption = 0.1; m_BackgroundScattering = 15; m_BackgroundAnisotropy = 0.9; m_AirAbsorption = 0.0001; m_AirScattering = 1; m_AirAnisotropy = 1; m_AirThicknessInMillimeters = 0; m_SkinAbsorption = 0.1; m_SkinScattering = 15; m_SkinAnisotropy = 0.9; m_SkinThicknessInMillimeters = 0; - m_CalculateNewVesselPositionCallback = &VesselMeanderStrategy::CalculateRandomlyDivergingPosition; + m_CalculateNewVesselPositionCallback = &VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector; m_MinNumberOfVessels = 0; m_MaxNumberOfVessels = 0; m_MinVesselBending = 0; m_MaxVesselBending = 0.1; m_MinVesselAbsorption = 1; m_MaxVesselAbsorption = 8; m_MinVesselRadiusInMillimeters = 1; m_MaxVesselRadiusInMillimeters = 3; m_VesselBifurcationFrequency = 25; m_MinVesselScattering = 15; m_MaxVesselScattering = 15; m_MinVesselAnisotropy = 0.9; m_MaxVesselAnisotropy = 0.9; m_MinVesselZOrigin = 10; m_MaxVesselZOrigin = 40; m_MCflag = 1; m_MCLaunchflag = 0; m_MCBoundaryflag = 2; m_MCLaunchPointX = 25; m_MCLaunchPointY = 25; m_MCLaunchPointZ = 2; m_MCFocusPointX = 25; m_MCFocusPointY = 25; m_MCFocusPointZ = 25; m_MCTrajectoryVectorX = 0; m_MCTrajectoryVectorY = 0; m_MCTrajectoryVectorZ = 1; m_MCRadius = 2; m_MCWaist = 4; } mitk::pa::TissueGeneratorParameters::~TissueGeneratorParameters() { } diff --git a/Modules/PhotoacousticsLib/src/Utils/mitkPAVesselDrawer.cpp b/Modules/PhotoacousticsLib/src/Utils/mitkPAVesselDrawer.cpp index 2f9b266fa0..92c69dff1d 100644 --- a/Modules/PhotoacousticsLib/src/Utils/mitkPAVesselDrawer.cpp +++ b/Modules/PhotoacousticsLib/src/Utils/mitkPAVesselDrawer.cpp @@ -1,82 +1,81 @@ /*=================================================================== 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 "mitkPAVesselDrawer.h" #include "mitkPAVesselProperties.h" mitk::pa::VesselDrawer::VesselDrawer() { } mitk::pa::VesselDrawer::~VesselDrawer() { } -void mitk::pa::VesselDrawer::DrawVesselInVolume( +void mitk::pa::VesselDrawer::ExpandAndDrawVesselInVolume( VesselProperties::Pointer properties, InSilicoTissueVolume::Pointer volume) { Vector::Pointer stepDirection = properties->GetDirectionVector(); Vector::Pointer fromPosition = properties->GetPositionVector()->Clone(); - Vector::Pointer toPosition = properties->GetPositionVector()->Clone(); Vector::Pointer totalWalkingDistance = stepDirection->Clone(); totalWalkingDistance->Scale(1.0 / volume->GetSpacing()); while (totalWalkingDistance->GetNorm() >= 1) { double xPos = fromPosition->GetElement(0); double yPos = fromPosition->GetElement(1); double zPos = fromPosition->GetElement(2); if (!volume->IsInsideVolume(xPos, yPos, zPos)) { properties->SetRadiusInVoxel(0); return; } double radius = properties->GetRadiusInVoxel(); double ceiledRadius = ceil(radius); for (int x = xPos - ceiledRadius; x <= xPos + ceiledRadius; x += 1) for (int y = yPos - ceiledRadius; y <= yPos + ceiledRadius; y += 1) for (int z = zPos - ceiledRadius; z <= zPos + ceiledRadius; z += 1) { if (!volume->IsInsideVolume(x, y, z)) { continue; } double xDiff = x - xPos; double yDiff = y - yPos; double zDiff = z - zPos; double vectorLengthDiff = radius - sqrt(xDiff*xDiff + yDiff*yDiff + zDiff*zDiff); if (vectorLengthDiff > 0) { volume->SetVolumeValues(x, y, z, properties->GetAbsorptionCoefficient(), properties->GetScatteringCoefficient(), properties->GetAnisotopyCoefficient(), mitk::pa::InSilicoTissueVolume::SegmentationType::VESSEL); } } totalWalkingDistance->Subtract(stepDirection); fromPosition->Add(stepDirection); } properties->SetPositionVector(fromPosition); } diff --git a/Modules/PhotoacousticsLib/test/files.cmake b/Modules/PhotoacousticsLib/test/files.cmake index ec5d2cb905..72afa9fe97 100644 --- a/Modules/PhotoacousticsLib/test/files.cmake +++ b/Modules/PhotoacousticsLib/test/files.cmake @@ -1,41 +1,40 @@ set(MODULE_TESTS # IMPORTANT: If you plan to deactivate / comment out a test please write a bug number to the commented out line of code. # # Example: #mitkMyTest #this test is commented out because of bug 12345 # # It is important that the bug is open and that the test will be activated again before the bug is closed. This assures that # no test is forgotten after it was commented out. If there is no bug for your current problem, please add a new one and # mark it as critical. ################## ON THE FENCE TESTS ################################################# # none ################## DISABLED TESTS ##################################################### - #mitkMCThreadHandlerTest.cpp #Timing issue - #mitkPhotoacousticIOTest.cpp - #mitkPhotoacousticVesselMeanderStrategyTest.cpp - #mitkPhotoacousticVesselTest.cpp + # mitkMCThreadHandlerTest.cpp #Timing issue on VMs + # mitkPhotoacousticIOTest.cpp #Not suitable for large scale testing as it performs IO actions. ################# RUNNING TESTS ####################################################### mitkSlicedVolumeGeneratorTest.cpp mitkPhotoacousticTissueGeneratorTest.cpp mitkPhotoacousticVectorTest.cpp mitkPhotoacoustic3dVolumeTest.cpp mitkPhotoacousticVolumeTest.cpp mitkPhotoacousticVesselTreeTest.cpp mitkMcxyzXmlTest.cpp mitkPhotoacousticComposedVolumeTest.cpp mitkPhotoacousticNoiseGeneratorTest.cpp mitkSimulationBatchGeneratorTest.cpp mitkPropertyCalculatorTest.cpp mitkSpectralUnmixingTest.cpp - + mitkPhotoacousticVesselMeanderStrategyTest.cpp + mitkPhotoacousticVesselTest.cpp ) set(RESOURCE_FILES pointsource.xml circlesource.xml rectanglesource.xml twopointsources.xml allsources.xml ) diff --git a/Modules/PhotoacousticsLib/test/mitkPhotoacousticTissueGeneratorTest.cpp b/Modules/PhotoacousticsLib/test/mitkPhotoacousticTissueGeneratorTest.cpp index 0627bfb4b7..a5107c27bc 100644 --- a/Modules/PhotoacousticsLib/test/mitkPhotoacousticTissueGeneratorTest.cpp +++ b/Modules/PhotoacousticsLib/test/mitkPhotoacousticTissueGeneratorTest.cpp @@ -1,85 +1,85 @@ /*=================================================================== 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 "mitkPATissueGenerator.h" class mitkPhotoacousticTissueGeneratorTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkPhotoacousticTissueGeneratorTestSuite); MITK_TEST(testCallWithEmptyParameters); MITK_TEST(testCallWithWorkingParameters); CPPUNIT_TEST_SUITE_END(); private: public: void setUp() override { } mitk::pa::TissueGeneratorParameters::Pointer createRandomTestVolumeParameters() { auto returnParameters = mitk::pa::TissueGeneratorParameters::New(); returnParameters->SetXDim(rand() % 50 + 1); returnParameters->SetYDim(rand() % 50 + 1); returnParameters->SetZDim(rand() % 50 + 1); double absorb = rand() % 100 / 10.0; returnParameters->SetMinBackgroundAbsorption(absorb); returnParameters->SetMaxBackgroundAbsorption(absorb); returnParameters->SetBackgroundScattering(rand() % 100 / 10.0); returnParameters->SetBackgroundAnisotropy(rand() % 100 / 10.0); int min = rand() % 10; returnParameters->SetMinNumberOfVessels(min); returnParameters->SetMaxNumberOfVessels(min + (rand() % 10)); returnParameters->SetCalculateNewVesselPositionCallback( - &mitk::pa::VesselMeanderStrategy::CalculateRandomlyDivergingPosition); + &mitk::pa::VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); returnParameters->SetMinVesselZOrigin(rand() % 3 + 1); returnParameters->SetMaxVesselZOrigin(rand() % 3 + 1); int minRad = rand() % 100; returnParameters->SetMinVesselRadiusInMillimeters(minRad); returnParameters->SetMaxVesselRadiusInMillimeters(minRad + (rand() % 100)); returnParameters->SetVoxelSpacingInCentimeters(1); return returnParameters; } void testCallWithEmptyParameters() { auto parameters = mitk::pa::TissueGeneratorParameters::New(); auto volume = mitk::pa::InSilicoTissueGenerator::GenerateInSilicoData(parameters); CPPUNIT_ASSERT(volume.IsNotNull()); } void testCallWithWorkingParameters() { for (int i = 0; i < 20; i++) { auto parameters = createRandomTestVolumeParameters(); auto volume = mitk::pa::InSilicoTissueGenerator::GenerateInSilicoData(parameters); CPPUNIT_ASSERT(volume.IsNotNull()); } } void tearDown() override { } }; MITK_TEST_SUITE_REGISTRATION(mitkPhotoacousticTissueGenerator) diff --git a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselMeanderStrategyTest.cpp b/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselMeanderStrategyTest.cpp index 82c29f332a..4f87066845 100644 --- a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselMeanderStrategyTest.cpp +++ b/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselMeanderStrategyTest.cpp @@ -1,114 +1,83 @@ /*=================================================================== 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 "mitkPAInSilicoTissueVolume.h" #include "mitkPATissueGenerator.h" #include "mitkPAVesselMeanderStrategy.h" class mitkPhotoacousticVesselMeanderStrategyTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkPhotoacousticVesselMeanderStrategyTestSuite); MITK_TEST(TestCalculateNewPositionInStraightLine); CPPUNIT_TEST_SUITE_END(); private: - mitk::pa::VesselMeanderStrategy::Pointer m_TestVector; - mitk::pa::Vector::Pointer m_TestPostion; + mitk::pa::VesselMeanderStrategy::Pointer m_TestStrategy; mitk::pa::Vector::Pointer m_TestDirection; public: void setUp() override { - m_TestVector = mitk::pa::VesselMeanderStrategy::New(); - m_TestPostion = mitk::pa::Vector::New(); + m_TestStrategy = mitk::pa::VesselMeanderStrategy::New(); m_TestDirection = mitk::pa::Vector::New(); } void TestCalculateNewPositionInStraightLine() { - std::stringstream output; - - int a = 0; - int b = 1; - int c = 2; int d = 3; int e = 4; int f = 5; for (int i = -2; i <= 2; i++) { if (i == 0) { i++; } for (int j = -2; j <= 2; j++) { if (j == 0) { j++; } - m_TestPostion->SetElement(0, a*i); - m_TestPostion->SetElement(1, b*i); - m_TestPostion->SetElement(2, c*i); m_TestDirection->SetElement(0, d*j); m_TestDirection->SetElement(1, e*j); m_TestDirection->SetElement(2, f*j); - m_TestVector->CalculateNewPositionInStraightLine(m_TestPostion, m_TestDirection, 0, nullptr); - - MITK_INFO << "m_TestPosition Element(0) =" << m_TestPostion->GetElement(0); - MITK_INFO << "Data0 =" << (a*i) + (d*j); - MITK_INFO << "m_TestPosition Element(1) =" << m_TestPostion->GetElement(1); - MITK_INFO << "Data1 =" << (b*i) + (e*j); - MITK_INFO << "m_TestPosition Element(2) =" << m_TestPostion->GetElement(2); - MITK_INFO << "Data2 =" << (c*i) + (f*j); - - output << "Element0 from m_TestPosition should be "; - output << a*i + d*j; - CPPUNIT_ASSERT_EQUAL_MESSAGE(output.str(), true, a*i + d*j == m_TestPostion->GetElement(0)); - output.flush(); - - output << "Element1 from m_TestPosition should be "; - output << b*i + e*j; - CPPUNIT_ASSERT_EQUAL_MESSAGE(output.str(), true, b*i + e*j == m_TestPostion->GetElement(1)); - output.flush(); - - output << "Element2 from m_TestPosition should be "; - output << c*i + f*j; - CPPUNIT_ASSERT_EQUAL_MESSAGE(output.str(), true, c*i + f*j == m_TestPostion->GetElement(2)); - output.flush(); + mitk::pa::Vector::Pointer directionBefore = m_TestDirection->Clone(); + m_TestStrategy->CalculateNewDirectionVectorInStraightLine(m_TestDirection, 0, nullptr); + CPPUNIT_ASSERT(mitk::pa::Equal(directionBefore, m_TestDirection, 1e-6, false)); } } } void tearDown() override { - m_TestVector = nullptr; - m_TestPostion = nullptr; + m_TestStrategy = nullptr; m_TestDirection = nullptr; } }; MITK_TEST_SUITE_REGISTRATION(mitkPhotoacousticVesselMeanderStrategy) diff --git a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselTest.cpp b/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselTest.cpp index bf9d2769bb..b31d7ca57e 100644 --- a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselTest.cpp +++ b/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselTest.cpp @@ -1,240 +1,184 @@ /*=================================================================== 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 "mitkPAInSilicoTissueVolume.h" #include "mitkPAVector.h" #include "mitkPAVessel.h" -#include "mitkIOUtil.h" class mitkPhotoacousticVesselTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkPhotoacousticVesselTestSuite); MITK_TEST(testEmptyInitializationProperties); MITK_TEST(testWalkInStraightLine); MITK_TEST(testBifurcate); - MITK_TEST(testPartialVolume); CPPUNIT_TEST_SUITE_END(); private: mitk::pa::Vessel::Pointer m_TestVessel; mitk::pa::Vessel::CalculateNewVesselPositionCallback m_StraightLine; mitk::pa::Vessel::CalculateNewVesselPositionCallback m_Diverging; mitk::pa::InSilicoTissueVolume::Pointer m_TestInSilicoVolume; mitk::pa::TissueGeneratorParameters::Pointer m_TestVolumeParameters; public: void setUp() override { auto params = mitk::pa::VesselProperties::New(); m_TestVessel = mitk::pa::Vessel::New(params); - m_StraightLine = &mitk::pa::VesselMeanderStrategy::CalculateNewPositionInStraightLine; - m_Diverging = &mitk::pa::VesselMeanderStrategy::CalculateRandomlyDivergingPosition; + m_StraightLine = &mitk::pa::VesselMeanderStrategy::CalculateNewDirectionVectorInStraightLine; + m_Diverging = &mitk::pa::VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector; m_TestVolumeParameters = createTestVolumeParameters(); auto rng = std::mt19937(); m_TestInSilicoVolume = mitk::pa::InSilicoTissueVolume::New(m_TestVolumeParameters, &rng); } mitk::pa::TissueGeneratorParameters::Pointer createTestVolumeParameters() { auto returnParameters = mitk::pa::TissueGeneratorParameters::New(); returnParameters->SetXDim(10); returnParameters->SetYDim(10); returnParameters->SetZDim(10); returnParameters->SetMinBackgroundAbsorption(0); returnParameters->SetMaxBackgroundAbsorption(0); returnParameters->SetBackgroundScattering(0); returnParameters->SetBackgroundAnisotropy(0); return returnParameters; } void testEmptyInitializationProperties() { CPPUNIT_ASSERT(m_TestVessel->CanBifurcate() == false); CPPUNIT_ASSERT(m_TestVessel->IsFinished() == true); } - void testPartialVolume() - { - auto testPosition = mitk::pa::Vector::New(); - testPosition->SetElement(0, 0); - testPosition->SetElement(1, 4); - testPosition->SetElement(2, 4); - auto testDirection = mitk::pa::Vector::New(); - testDirection->SetElement(0, 1); - testDirection->SetElement(1, 0); - testDirection->SetElement(2, 0); - auto params = mitk::pa::VesselProperties::New(); - params->SetDoPartialVolume(true); - params->SetRadiusInVoxel(1); - params->SetBifurcationFrequency(100); - params->SetAbsorptionCoefficient(10); - params->SetScatteringCoefficient(10); - params->SetAnisotopyCoefficient(10); - params->SetPositionVector(testPosition); - params->SetDirectionVector(testDirection); - m_TestVessel = mitk::pa::Vessel::New(params); - - CPPUNIT_ASSERT(m_TestVessel->CanBifurcate() == false); - CPPUNIT_ASSERT(m_TestVessel->IsFinished() == false); - - CPPUNIT_ASSERT(std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4)) <= mitk::eps); - - m_TestVessel->ExpandVessel(m_TestInSilicoVolume, m_StraightLine, 0, nullptr); - - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4)), - abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4) - 10) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 5)), - abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 5) - 10) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 3)), - abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 3) - 10) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 5, 4)), - abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 5, 4) - 10) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 3, 4)), - abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 3, 4) - 10) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 5, 5)), - abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 5, 5) - 5.85786438) <= 1e-6); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 3, 3)), - abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 3, 3) - 5.85786438) <= 1e-6); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 5, 3)), - abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 5, 3) - 5.85786438) <= 1e-6); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 3, 5)), - abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 3, 5) - 5.85786438) <= 1e-6); - } - void testWalkInStraightLine() { auto testPosition = mitk::pa::Vector::New(); testPosition->SetElement(0, 0); testPosition->SetElement(1, 4); testPosition->SetElement(2, 4); auto testDirection = mitk::pa::Vector::New(); testDirection->SetElement(0, 1); testDirection->SetElement(1, 0); testDirection->SetElement(2, 0); auto params = mitk::pa::VesselProperties::New(); params->SetDoPartialVolume(false); params->SetRadiusInVoxel(1); params->SetBifurcationFrequency(100); params->SetAbsorptionCoefficient(10); params->SetScatteringCoefficient(10); params->SetAnisotopyCoefficient(10); params->SetPositionVector(testPosition); params->SetDirectionVector(testDirection); m_TestVessel = mitk::pa::Vessel::New(params); CPPUNIT_ASSERT(m_TestVessel->CanBifurcate() == false); CPPUNIT_ASSERT(m_TestVessel->IsFinished() == false); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4)), abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4)) <= mitk::eps); m_TestVessel->ExpandVessel(m_TestInSilicoVolume, m_StraightLine, 0, nullptr); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4)), abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4) - 10) <= mitk::eps); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 5, 4)), abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 5, 4)) <= mitk::eps); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 6, 4)), abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 6, 4)) <= mitk::eps); - - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4)), - abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4) - 10) <= mitk::eps); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 5)), abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 5)) <= mitk::eps); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 6)), abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 6)) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4)), - abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4) - 10) <= mitk::eps); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4)), - abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4) - 10) <= mitk::eps); + abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4)) <= mitk::eps); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(2, 4, 4)), abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(2, 4, 4)) <= mitk::eps); m_TestVessel->ExpandVessel(m_TestInSilicoVolume, m_StraightLine, 0, nullptr); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4)), abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4) - 10) <= mitk::eps); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 5, 4)), abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 5, 4)) <= mitk::eps); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 6, 4)), abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 6, 4)) <= mitk::eps); - - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4)), - abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4) - 10) <= mitk::eps); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 5)), abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 5)) <= mitk::eps); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 6)), abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 6)) <= mitk::eps); + CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4)), + abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4) - 10) <= mitk::eps); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4)), abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4) - 10) <= mitk::eps); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(2, 4, 4)), - abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(2, 4, 4) - 10) <= mitk::eps); + abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(2, 4, 4)) <= mitk::eps); CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(3, 4, 4)), abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(3, 4, 4)) <= mitk::eps); } void testBifurcate() { auto testPosition = mitk::pa::Vector::New(); testPosition->SetElement(0, 0); testPosition->SetElement(1, 4); testPosition->SetElement(2, 4); auto testDirection = mitk::pa::Vector::New(); testDirection->SetElement(0, 1); testDirection->SetElement(1, 0); testDirection->SetElement(2, 0); auto params = mitk::pa::VesselProperties::New(); params->SetRadiusInVoxel(1); params->SetBifurcationFrequency(1); params->SetAbsorptionCoefficient(10); params->SetScatteringCoefficient(10); params->SetAnisotopyCoefficient(10); params->SetPositionVector(testPosition); params->SetDirectionVector(testDirection); m_TestVessel = mitk::pa::Vessel::New(params); CPPUNIT_ASSERT(m_TestVessel->CanBifurcate() == false); CPPUNIT_ASSERT(m_TestVessel->IsFinished() == false); CPPUNIT_ASSERT(std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4)) <= mitk::eps); m_TestVessel->ExpandVessel(m_TestInSilicoVolume, m_StraightLine, 0, nullptr); m_TestVessel->ExpandVessel(m_TestInSilicoVolume, m_StraightLine, 0, nullptr); CPPUNIT_ASSERT(m_TestVessel->CanBifurcate() == true); std::mt19937 rng; auto bifurcationVessel = m_TestVessel->Bifurcate(&rng); CPPUNIT_ASSERT(m_TestVessel->CanBifurcate() == false); CPPUNIT_ASSERT(bifurcationVessel->CanBifurcate() == false); } void tearDown() override { } }; MITK_TEST_SUITE_REGISTRATION(mitkPhotoacousticVessel) diff --git a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselTreeTest.cpp b/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselTreeTest.cpp index 1a022017f3..5afba9ce0d 100644 --- a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselTreeTest.cpp +++ b/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselTreeTest.cpp @@ -1,108 +1,108 @@ /*=================================================================== 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 "mitkPAVesselTree.h" #include "mitkPAInSilicoTissueVolume.h" using namespace mitk::pa; class mitkPhotoacousticVesselTreeTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkPhotoacousticVesselTreeTestSuite); MITK_TEST(testVesselTreeInitialBehavior); MITK_TEST(testCallStepMethod); CPPUNIT_TEST_SUITE_END(); private: public: VesselTree::Pointer m_Tree; VesselProperties::Pointer m_VesselProperties; Vessel::CalculateNewVesselPositionCallback m_StraightLine; InSilicoTissueVolume::Pointer m_TestInSilicoVolume; void setUp() override { m_VesselProperties = VesselProperties::New(); m_Tree = VesselTree::New(m_VesselProperties); - m_StraightLine = &VesselMeanderStrategy::CalculateNewPositionInStraightLine; + m_StraightLine = &VesselMeanderStrategy::CalculateNewDirectionVectorInStraightLine; auto rng = std::mt19937(); m_TestInSilicoVolume = InSilicoTissueVolume::New(createTestVolumeParameters(), &rng); } TissueGeneratorParameters::Pointer createTestVolumeParameters() { auto returnParameters = TissueGeneratorParameters::New(); returnParameters->SetXDim(10); returnParameters->SetYDim(10); returnParameters->SetZDim(10); returnParameters->SetMinBackgroundAbsorption(0); returnParameters->SetMaxBackgroundAbsorption(0); returnParameters->SetBackgroundScattering(0); returnParameters->SetBackgroundAnisotropy(0); return returnParameters; } void testVesselTreeInitialBehavior() { CPPUNIT_ASSERT(m_Tree->IsFinished() == true); } void testCallStepMethod() { //really bad test atm.. The only thing that is tested is that the method can be called without a crash. //But hey - it is something :P m_VesselProperties->SetRadiusInVoxel(2); std::mt19937 rng; rng.seed(1); m_Tree = VesselTree::New(m_VesselProperties); m_Tree->Step(m_TestInSilicoVolume, m_StraightLine, 0, &rng); rng.seed(1); auto secondTree = VesselTree::New(m_VesselProperties); secondTree->Step(m_TestInSilicoVolume, m_StraightLine, 0, &rng); CPPUNIT_ASSERT(Equal(m_Tree, secondTree, 1e-6, true)); secondTree->Step(m_TestInSilicoVolume, m_StraightLine, 0, &rng); CPPUNIT_ASSERT(!Equal(m_Tree, secondTree, 1e-6, true)); int i = 0; for (; i < 1000; i++) { secondTree->Step(m_TestInSilicoVolume, m_StraightLine, 0, &rng); if (secondTree->IsFinished()) break; } CPPUNIT_ASSERT(i < 999); } void tearDown() override { } }; MITK_TEST_SUITE_REGISTRATION(mitkPhotoacousticVesselTree) diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/PASimulator.cpp b/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/PASimulator.cpp index 20109b4428..70042b6ae8 100644 --- a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/PASimulator.cpp +++ b/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/PASimulator.cpp @@ -1,256 +1,256 @@ /*=================================================================== 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. ===================================================================*/ // Blueberry #include #include // Qmitk #include "PASimulator.h" // Qt #include #include #include // mitk #include #include #include #include #include const std::string PASimulator::VIEW_ID = "org.mitk.views.pasimulator"; void PASimulator::SetFocus() { m_Controls.pushButtonShowRandomTissue->setFocus(); } void PASimulator::CreateQtPartControl(QWidget *parent) { m_Controls.setupUi(parent); connect(m_Controls.pushButtonShowRandomTissue, SIGNAL(clicked()), this, SLOT(DoImageProcessing())); connect(m_Controls.pushButtonOpenPath, SIGNAL(clicked()), this, SLOT(OpenFolder())); connect(m_Controls.pushButtonOpenBinary, SIGNAL(clicked()), this, SLOT(OpenBinary())); connect(m_Controls.checkBoxGenerateBatch, SIGNAL(clicked()), this, SLOT(UpdateVisibilityOfBatchCreation())); connect(m_Controls.pushButtonAjustWavelength, SIGNAL(clicked()), this, SLOT(UpdateParametersAccordingToWavelength())); connect(m_Controls.checkBoxRngSeed, SIGNAL(clicked()), this, SLOT(ClickedCheckboxFixedSeed())); connect(m_Controls.checkBoxRandomizeParameters, SIGNAL(clicked()), this, SLOT(ClickedRandomizePhysicalParameters())); auto home = std::getenv("HOME"); std::string home_env = ""; if (home != nullptr) { home_env = std::string(home); } else { home = std::getenv("HOMEPATH"); if (home != nullptr) { home_env = std::string(home); } } m_Controls.label_NrrdFilePath->setText(home_env.c_str()); m_PhotoacousticPropertyCalculator = mitk::pa::PropertyCalculator::New(); UpdateVisibilityOfBatchCreation(); ClickedRandomizePhysicalParameters(); ClickedCheckboxFixedSeed(); } void PASimulator::ClickedRandomizePhysicalParameters() { m_Controls.spinboxRandomizeParameters->setEnabled(m_Controls.checkBoxRandomizeParameters->isChecked()); } void PASimulator::ClickedCheckboxFixedSeed() { m_Controls.spinBoxRngSeed->setEnabled(m_Controls.checkBoxRngSeed->isChecked()); } void PASimulator::UpdateParametersAccordingToWavelength() { int wavelength = m_Controls.spinboxWavelength->value(); double bloodOxygenation = m_Controls.spinboxBloodOxygenSaturation->value() / 100; auto result = m_PhotoacousticPropertyCalculator->CalculatePropertyForSpecificWavelength( mitk::pa::PropertyCalculator::TissueType::BLOOD, wavelength, bloodOxygenation); m_Controls.spinboxMaxAbsorption->setValue(result.mua); m_Controls.spinboxMinAbsorption->setValue(result.mua); m_Controls.spinboxBloodVesselScatteringMinimum->setValue(result.mus); m_Controls.spinboxBloodVesselScatteringMaximum->setValue(result.mus); m_Controls.spinboxBloodVesselAnisotropyMinimum->setValue(result.g); m_Controls.spinboxBloodVesselAnisotropyMaximum->setValue(result.g); result = m_PhotoacousticPropertyCalculator->CalculatePropertyForSpecificWavelength( mitk::pa::PropertyCalculator::TissueType::EPIDERMIS, wavelength, bloodOxygenation); m_Controls.spinboxSkinAbsorption->setValue(result.mua); m_Controls.spinboxSkinScattering->setValue(result.mus); m_Controls.spinboxSkinAnisotropy->setValue(result.g); result = m_PhotoacousticPropertyCalculator->CalculatePropertyForSpecificWavelength( mitk::pa::PropertyCalculator::TissueType::STANDARD_TISSUE, wavelength, bloodOxygenation); m_Controls.spinboxBackgroundAbsorption->setValue(result.mua); m_Controls.spinboxBackgroundScattering->setValue(result.mus); m_Controls.spinboxBackgroundAnisotropy->setValue(result.g); } void PASimulator::UpdateVisibilityOfBatchCreation() { m_Controls.widgetBatchFile->setVisible(m_Controls.checkBoxGenerateBatch->isChecked()); } mitk::pa::TissueGeneratorParameters::Pointer PASimulator::GetParametersFromUIInput() { auto parameters = mitk::pa::TissueGeneratorParameters::New(); // Getting settings from UI // General settings parameters->SetXDim(m_Controls.spinboxXDim->value()); parameters->SetYDim(m_Controls.spinboxYDim->value()); parameters->SetZDim(m_Controls.spinboxZDim->value()); parameters->SetDoPartialVolume(m_Controls.checkBoxPartialVolume->isChecked()); parameters->SetRandomizePhysicalProperties(m_Controls.checkBoxRandomizeParameters->isChecked()); parameters->SetRandomizePhysicalPropertiesPercentage(m_Controls.spinboxRandomizeParameters->value()); parameters->SetVoxelSpacingInCentimeters(m_Controls.spinboxSpacing->value()); parameters->SetUseRngSeed(m_Controls.checkBoxRngSeed->isChecked()); parameters->SetRngSeed(m_Controls.spinBoxRngSeed->value()); // Monte Carlo simulation parameters parameters->SetMCflag(m_Controls.spinboxMcFlag->value()); parameters->SetMCLaunchflag(m_Controls.spinboxLaunchFlag->value()); parameters->SetMCBoundaryflag(m_Controls.spinboxboundaryFlag->value()); parameters->SetMCLaunchPointX(m_Controls.spinboxLaunchpointX->value()); parameters->SetMCLaunchPointY(m_Controls.spinboxLaunchpointY->value()); parameters->SetMCLaunchPointZ(m_Controls.spinboxLaunchpointZ->value()); parameters->SetMCFocusPointX(m_Controls.spinboxFocuspointX->value()); parameters->SetMCFocusPointY(m_Controls.spinboxFocuspointY->value()); parameters->SetMCFocusPointZ(m_Controls.spinboxFocuspointZ->value()); parameters->SetMCTrajectoryVectorX(m_Controls.spinboxTrajectoryVectorX->value()); parameters->SetMCTrajectoryVectorY(m_Controls.spinboxTrajectoryVectorY->value()); parameters->SetMCTrajectoryVectorZ(m_Controls.spinboxTrajectoryVectorZ->value()); parameters->SetMCRadius(m_Controls.spinboxRadius->value()); parameters->SetMCWaist(m_Controls.spinboxWaist->value()); // Vessel settings parameters->SetMaxVesselAbsorption(m_Controls.spinboxMaxAbsorption->value()); parameters->SetMinVesselAbsorption(m_Controls.spinboxMinAbsorption->value()); parameters->SetMaxVesselBending(m_Controls.spinboxMaxBending->value()); parameters->SetMinVesselBending(m_Controls.spinboxMinBending->value()); parameters->SetMaxVesselRadiusInMillimeters(m_Controls.spinboxMaxDiameter->value()); parameters->SetMinVesselRadiusInMillimeters(m_Controls.spinboxMinDiameter->value()); parameters->SetMaxNumberOfVessels(m_Controls.spinboxMaxVessels->value()); parameters->SetMinNumberOfVessels(m_Controls.spinboxMinVessels->value()); parameters->SetMinVesselScattering(m_Controls.spinboxBloodVesselScatteringMinimum->value()); parameters->SetMaxVesselScattering(m_Controls.spinboxBloodVesselScatteringMaximum->value()); parameters->SetMinVesselAnisotropy(m_Controls.spinboxBloodVesselAnisotropyMinimum->value()); parameters->SetMaxVesselAnisotropy(m_Controls.spinboxBloodVesselAnisotropyMaximum->value()); parameters->SetVesselBifurcationFrequency(m_Controls.spinboxBifurcationFrequency->value()); parameters->SetMinVesselZOrigin(m_Controls.spinboxMinSpawnDepth->value()); parameters->SetMaxVesselZOrigin(m_Controls.spinboxMaxSpawnDepth->value()); // Background tissue settings parameters->SetMinBackgroundAbsorption(m_Controls.spinboxBackgroundAbsorption->value()); parameters->SetMaxBackgroundAbsorption(m_Controls.spinboxBackgroundAbsorption->value()); parameters->SetBackgroundScattering(m_Controls.spinboxBackgroundScattering->value()); parameters->SetBackgroundAnisotropy(m_Controls.spinboxBackgroundAnisotropy->value()); // Air settings parameters->SetAirThicknessInMillimeters(m_Controls.spinboxAirThickness->value()); //Skin tissue settings parameters->SetSkinThicknessInMillimeters(m_Controls.spinboxSkinThickness->value()); parameters->SetSkinAbsorption(m_Controls.spinboxSkinAbsorption->value()); parameters->SetSkinScattering(m_Controls.spinboxSkinScattering->value()); parameters->SetSkinAnisotropy(m_Controls.spinboxSkinAnisotropy->value()); - parameters->SetCalculateNewVesselPositionCallback(&mitk::pa::VesselMeanderStrategy::CalculateRandomlyDivergingPosition); + parameters->SetCalculateNewVesselPositionCallback(&mitk::pa::VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); return parameters; } void PASimulator::DoImageProcessing() { int numberOfVolumes = 1; if (m_Controls.checkBoxGenerateBatch->isChecked()) { if (m_Controls.labelBinarypath->text().isNull() || m_Controls.labelBinarypath->text().isEmpty()) { QMessageBox::warning(nullptr, QString("Warning"), QString("You need to specify the binary first!")); return; } numberOfVolumes = m_Controls.spinboxNumberVolumes->value(); if (numberOfVolumes < 1) { QMessageBox::warning(nullptr, QString("Warning"), QString("You need to create at least one volume!")); return; } } auto tissueParameters = GetParametersFromUIInput(); for (int volumeIndex = 0; volumeIndex < numberOfVolumes; volumeIndex++) { mitk::pa::InSilicoTissueVolume::Pointer volume = mitk::pa::InSilicoTissueGenerator::GenerateInSilicoData(tissueParameters); mitk::Image::Pointer tissueVolume = volume->ConvertToMitkImage(); if (m_Controls.checkBoxGenerateBatch->isChecked()) { std::string nrrdFilePath = m_Controls.label_NrrdFilePath->text().toStdString(); std::string tissueName = m_Controls.lineEditTissueName->text().toStdString(); std::string binaryPath = m_Controls.labelBinarypath->text().toStdString(); long numberOfPhotons = m_Controls.spinboxNumberPhotons->value() * 1000L; auto batchParameters = mitk::pa::SimulationBatchGeneratorParameters::New(); batchParameters->SetBinaryPath(binaryPath); batchParameters->SetNrrdFilePath(nrrdFilePath); batchParameters->SetNumberOfPhotons(numberOfPhotons); batchParameters->SetTissueName(tissueName); batchParameters->SetVolumeIndex(volumeIndex); batchParameters->SetYOffsetLowerThresholdInCentimeters(m_Controls.spinboxFromValue->value()); batchParameters->SetYOffsetUpperThresholdInCentimeters(m_Controls.spinboxToValue->value()); batchParameters->SetYOffsetStepInCentimeters(m_Controls.spinboxStepValue->value()); mitk::pa::SimulationBatchGenerator::WriteBatchFileAndSaveTissueVolume(batchParameters, tissueVolume); } else { mitk::DataNode::Pointer dataNode = mitk::DataNode::New(); dataNode->SetData(tissueVolume); dataNode->SetName(m_Controls.lineEditTissueName->text().toStdString()); this->GetDataStorage()->Add(dataNode); mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage()); } } } void PASimulator::OpenFolder() { m_Controls.label_NrrdFilePath->setText(QFileDialog::getExistingDirectory().append("/")); } void PASimulator::OpenBinary() { m_Controls.labelBinarypath->setText(QFileDialog::getOpenFileName()); }