diff --git a/Modules/ModuleList.cmake b/Modules/ModuleList.cmake index 33386532dc..f9c90325b7 100644 --- a/Modules/ModuleList.cmake +++ b/Modules/ModuleList.cmake @@ -1,79 +1,81 @@ # The entries in the mitk_modules list must be # ordered according to their dependencies. set(MITK_MODULES Core CommandLine AppUtil RDF LegacyIO DataTypesExt Annotation LegacyGL AlgorithmsExt MapperExt DICOMReader DICOMReaderServices DICOMTesting SceneSerializationBase PlanarFigure ImageDenoising ImageExtraction SceneSerialization Gizmo GraphAlgorithms Multilabel ImageStatistics ContourModel SurfaceInterpolation Segmentation PlanarFigureSegmentation QtWidgets QtWidgetsExt Chart SegmentationUI MatchPointRegistration MatchPointRegistrationUI Classification GPGPU OpenIGTLink IGTBase IGT CameraCalibration OpenCL OpenCVVideoSupport QtOverlays ToFHardware ToFProcessing ToFUI PhotoacousticsHardware PhotoacousticsAlgorithms PhotoacousticsLib US USUI DicomUI Remeshing Python QtPython Persistence OpenIGTLinkUI IGTUI DicomRT RTUI IOExt XNAT TubeGraph BiophotonicsHardware DiffusionImaging TumorInvasionAnalysis BoundingShape RenderWindowManager RenderWindowManagerUI CEST FitMIData FitMIDataUI + Pharmacokinetics + PharmacokineticsUI ) if(MITK_ENABLE_PIC_READER) list(APPEND MITK_MODULES IpPicSupportIO) endif() diff --git a/Modules/Pharmacokinetics/CMakeLists.txt b/Modules/Pharmacokinetics/CMakeLists.txt new file mode 100644 index 0000000000..ca39765a91 --- /dev/null +++ b/Modules/Pharmacokinetics/CMakeLists.txt @@ -0,0 +1,19 @@ +MITK_CREATE_MODULE(Pharmacokinetics + INCLUDE_DIRS + PUBLIC ${MITK_BINARY_DIR} + PRIVATE src/Common src/Functors src/Models src/DescriptionParameters src/SimulationFramework + DEPENDS + PUBLIC MitkCore MitkFitMIData + PRIVATE MitkMultilabel + PACKAGE_DEPENDS + PUBLIC ITK|ITKOptimizers + PRIVATE Boost + WARNINGS_NO_ERRORS +) + +if(BUILD_TESTING) + ADD_SUBDIRECTORY(test) +endif(BUILD_TESTING) + +ADD_SUBDIRECTORY(autoload/Models) +ADD_SUBDIRECTORY(cmdapps) \ No newline at end of file diff --git a/Modules/Pharmacokinetics/autoload/Models/CMakeLists.txt b/Modules/Pharmacokinetics/autoload/Models/CMakeLists.txt new file mode 100644 index 0000000000..415877143b --- /dev/null +++ b/Modules/Pharmacokinetics/autoload/Models/CMakeLists.txt @@ -0,0 +1,6 @@ +MITK_CREATE_MODULE(PharmacokineticModelsServices + DEPENDS + PUBLIC MitkPharmacokinetics + PRIVATE MitkCore + AUTOLOAD_WITH MitkPharmacokinetics +) diff --git a/Modules/Pharmacokinetics/autoload/Models/files.cmake b/Modules/Pharmacokinetics/autoload/Models/files.cmake new file mode 100644 index 0000000000..363c531b12 --- /dev/null +++ b/Modules/Pharmacokinetics/autoload/Models/files.cmake @@ -0,0 +1,12 @@ +set(CPP_FILES + mitkPharmacokineticModelsActivator.cpp +) + +set(H_FILES +) + +set(TPP_FILES +) + +set(MOC_H_FILES +) diff --git a/Modules/Pharmacokinetics/autoload/Models/mitkPharmacokineticModelsActivator.cpp b/Modules/Pharmacokinetics/autoload/Models/mitkPharmacokineticModelsActivator.cpp new file mode 100644 index 0000000000..ef717069a5 --- /dev/null +++ b/Modules/Pharmacokinetics/autoload/Models/mitkPharmacokineticModelsActivator.cpp @@ -0,0 +1,90 @@ +/*=================================================================== + +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 + +//MR perfusion models +#include "mitkDescriptivePharmacokineticBrixModelFactory.h" +#include "mitkExtendedToftsModelFactory.h" +#include "mitkStandardToftsModelFactory.h" +#include "mitkTwoCompartmentExchangeModelFactory.h" +#include "mitkNumericTwoCompartmentExchangeModelFactory.h" + +//PET perfusion models +#include "mitkOneTissueCompartmentModelFactory.h" +#include "mitkExtendedOneTissueCompartmentModelFactory.h" +#include "mitkTwoTissueCompartmentModelFactory.h" +#include "mitkTwoTissueCompartmentFDGModelFactory.h" +#include "mitkNumericTwoTissueCompartmentModelFactory.h" + +//general models +#include "mitkGenericParamModelFactory.h" +#include "mitkLinearModelFactory.h" +#include "mitkT2DecayModelFactory.h" +#include "mitkThreeStepLinearModelFactory.h" + +namespace mitk +{ + +/* + * This is the module activator for the IO aspects of the "pharmacokinetics" module. + */ +class PharmacokineticModelsActivator : public us::ModuleActivator +{ +public: + + template void RegisterProvider(us::ModuleContext* context) + { + auto provider = new TProvider(); + provider->RegisterService(context); + + m_RegisteredProviders.push_back(std::unique_ptr(provider)); + } + + virtual void Load(us::ModuleContext* context) override + { + m_RegisteredProviders.clear(); + RegisterProvider >(context); + RegisterProvider >(context); + RegisterProvider >(context); + RegisterProvider >(context); + RegisterProvider >(context); + RegisterProvider >(context); + RegisterProvider >(context); + RegisterProvider >(context); + RegisterProvider >(context); + RegisterProvider >(context); + RegisterProvider >(context); + RegisterProvider >(context); + RegisterProvider >(context); + RegisterProvider >(context); + } + + virtual void Unload(us::ModuleContext* ) override + { + } + +private: + std::vector > m_RegisteredProviders; +}; + +} + +US_EXPORT_MODULE_ACTIVATOR(mitk::PharmacokineticModelsActivator) diff --git a/Modules/Pharmacokinetics/cmdapps/CMakeLists.txt b/Modules/Pharmacokinetics/cmdapps/CMakeLists.txt new file mode 100644 index 0000000000..8e0922b524 --- /dev/null +++ b/Modules/Pharmacokinetics/cmdapps/CMakeLists.txt @@ -0,0 +1,77 @@ +option(BUILD_PerfusionMiniApps "Build commandline tools for the perfusion module" OFF) + +if(BUILD_PerfusionMiniApps) + + # needed include directories + include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ) + # list of miniapps + # if an app requires additional dependencies + # they are added after a "^^" and separated by "_" + set( miniapps + CurveDescriptorMiniApp^^ + MRPerfusionMiniApp^^ + MRSignal2ConcentrationMiniApp^^ + ) + + foreach(miniapp ${miniapps}) + # extract mini app name and dependencies + string(REPLACE "^^" "\\;" miniapp_info ${miniapp}) + set(miniapp_info_list ${miniapp_info}) + list(GET miniapp_info_list 0 appname) + list(GET miniapp_info_list 1 raw_dependencies) + string(REPLACE "_" "\\;" dependencies "${raw_dependencies}") + set(dependencies_list ${dependencies}) + + mitk_create_executable(${appname} + DEPENDS MitkFitMIData MitkPharmacokinetics MitkCommandLine ${dependencies_list} + PACKAGE_DEPENDS ITK + CPP_FILES ${appname}.cpp + ) + + if(EXECUTABLE_IS_ENABLED) + # On Linux, create a shell script to start a relocatable application + if(UNIX AND NOT APPLE) + install(PROGRAMS "${MITK_SOURCE_DIR}/CMake/RunInstalledApp.sh" DESTINATION "." RENAME ${EXECUTABLE_TARGET}.sh) + endif() + + get_target_property(_is_bundle ${EXECUTABLE_TARGET} MACOSX_BUNDLE) + + if(APPLE) + if(_is_bundle) + set(_target_locations ${EXECUTABLE_TARGET}.app) + set(${_target_locations}_qt_plugins_install_dir ${EXECUTABLE_TARGET}.app/Contents/MacOS) + set(_bundle_dest_dir ${EXECUTABLE_TARGET}.app/Contents/MacOS) + set(_qt_plugins_for_current_bundle ${EXECUTABLE_TARGET}.app/Contents/MacOS) + set(_qt_conf_install_dirs ${EXECUTABLE_TARGET}.app/Contents/Resources) + install(TARGETS ${EXECUTABLE_TARGET} BUNDLE DESTINATION . ) + else() + if(NOT MACOSX_BUNDLE_NAMES) + set(_qt_conf_install_dirs bin) + set(_target_locations bin/${EXECUTABLE_TARGET}) + set(${_target_locations}_qt_plugins_install_dir bin) + install(TARGETS ${EXECUTABLE_TARGET} RUNTIME DESTINATION bin) + else() + foreach(bundle_name ${MACOSX_BUNDLE_NAMES}) + list(APPEND _qt_conf_install_dirs ${bundle_name}.app/Contents/Resources) + set(_current_target_location ${bundle_name}.app/Contents/MacOS/${EXECUTABLE_TARGET}) + list(APPEND _target_locations ${_current_target_location}) + set(${_current_target_location}_qt_plugins_install_dir ${bundle_name}.app/Contents/MacOS) + message( " set(${_current_target_location}_qt_plugins_install_dir ${bundle_name}.app/Contents/MacOS) ") + + install(TARGETS ${EXECUTABLE_TARGET} RUNTIME DESTINATION ${bundle_name}.app/Contents/MacOS/) + endforeach() + endif() + endif() + else() + set(_target_locations bin/${EXECUTABLE_TARGET}${CMAKE_EXECUTABLE_SUFFIX}) + set(${_target_locations}_qt_plugins_install_dir bin) + set(_qt_conf_install_dirs bin) + install(TARGETS ${EXECUTABLE_TARGET} RUNTIME DESTINATION bin) + endif() + endif() + endforeach() + +endif() diff --git a/Modules/Pharmacokinetics/cmdapps/CurveDescriptorMiniApp.cpp b/Modules/Pharmacokinetics/cmdapps/CurveDescriptorMiniApp.cpp new file mode 100644 index 0000000000..7692c86499 --- /dev/null +++ b/Modules/Pharmacokinetics/cmdapps/CurveDescriptorMiniApp.cpp @@ -0,0 +1,246 @@ +/*=================================================================== + +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. + +===================================================================*/ + +// std includes +#include + +// itk includes +#include "itksys/SystemTools.hxx" + +// CTK includes +#include "mitkCommandLineParser.h" + +// MITK includes +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + + +std::string inFilename; +std::string outFileName; +std::string maskFileName; +bool verbose(false); +bool preview(false); +mitk::Image::Pointer image; +mitk::Image::Pointer mask; + + +void onFitEvent(::itk::Object* caller, const itk::EventObject & event, void* /*data*/) +{ + itk::ProgressEvent progressEvent; + + if (progressEvent.CheckEvent(&event)) + { + mitk::PixelBasedDescriptionParameterImageGenerator* castedReporter = dynamic_cast(caller); + std::cout <GetProgress()*100 << "% "; + } +} + + +void setupParser(mitkCommandLineParser& parser) +{ + // set general information about your MiniApp + parser.setCategory("Dynamic Data Analysis Tools"); + parser.setTitle("Curve Descriptor"); + parser.setDescription("MiniApp that allows to generate curve descriptor maps for dynamic image."); + parser.setContributor("DKFZ MIC"); + //! [create parser] + + //! [add arguments] + // 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 I/O parameters"); + parser.addArgument( + "input", "i", mitkCommandLineParser::InputFile, "Input file", "input 3D+t image file", us::Any(), false); + parser.addArgument("output", + "o", + mitkCommandLineParser::OutputFile, + "Output file template", + "where to save the output parameter images. The specified path will be used as template to determine the format (via extension) and the name \"root\". For each parameter a suffix will be added to the name.", + us::Any(), + false); + parser.endGroup(); + + parser.beginGroup("Optional parameters"); + parser.addArgument( + "mask", "m", mitkCommandLineParser::InputFile, "Mask file", "Mask that defines the spatial image region that should be fitted. Must have the same geometry as the input image!", us::Any()); + parser.addArgument( + "verbose", "v", mitkCommandLineParser::Bool, "Verbose Output", "Whether to produce verbose output"); + parser.addArgument( + "preview", "p", mitkCommandLineParser::Bool, "Preview outputs", "The application previews the outputs (filename, type) it would produce with the current settings."); + parser.addArgument("help", "h", mitkCommandLineParser::Bool, "Help:", "Show this help text"); + parser.endGroup(); + //! [add arguments] +} + +bool configureApplicationSettings(std::map parsedArgs) +{ + if (parsedArgs.size() == 0) + return false; + + verbose = false; + if (parsedArgs.count("verbose")) + { + verbose = us::any_cast(parsedArgs["verbose"]); + } + + if (parsedArgs.count("mask")) + { + maskFileName = us::any_cast(parsedArgs["mask"]); + } + + preview = false; + if (parsedArgs.count("preview")) + { + preview = us::any_cast(parsedArgs["preview"]); + } + + inFilename = us::any_cast(parsedArgs["input"]); + outFileName = us::any_cast(parsedArgs["output"]); + + return true; +} + +void ConfigureFunctor(mitk::CurveParameterFunctor* functor) +{ + mitk::CurveDescriptionParameterBase::Pointer parameterFunction = mitk::AreaUnderTheCurveDescriptionParameter::New().GetPointer(); + functor->RegisterDescriptionParameter("AUC", parameterFunction); + + parameterFunction = mitk::AreaUnderFirstMomentDescriptionParameter::New().GetPointer(); + functor->RegisterDescriptionParameter("AUMC", parameterFunction); + + parameterFunction = mitk::MeanResidenceTimeDescriptionParameter::New().GetPointer(); + functor->RegisterDescriptionParameter("MRT", parameterFunction); + + parameterFunction = mitk::TimeToPeakCurveDescriptionParameter::New().GetPointer(); + functor->RegisterDescriptionParameter("TimeToPeak", parameterFunction); +}; + +void doDescription() +{ + mitk::PixelBasedDescriptionParameterImageGenerator::Pointer generator = + mitk::PixelBasedDescriptionParameterImageGenerator::New(); + mitk::CurveParameterFunctor::Pointer functor = mitk::CurveParameterFunctor::New(); + ConfigureFunctor(functor); + functor->SetGrid(mitk::ExtractTimeGrid(image)); + + generator->SetFunctor(functor); + generator->SetDynamicImage(image); + generator->SetMask(mask); + + ::itk::CStyleCommand::Pointer command = ::itk::CStyleCommand::New(); + command->SetCallback(onFitEvent); + + std::cout << "Started curve descriptor computation process..." << std::endl; + generator->AddObserver(::itk::AnyEvent(), command); + generator->Generate(); + std::cout << std::endl << "Finished computation process" << std::endl; + + for (auto imageIterator : generator->GetParameterImages()) + { + mitk::storeParameterResultImage(outFileName, imageIterator.first, imageIterator.second); + } +} + +void doPreview() +{ + mitk::CurveParameterFunctor::Pointer functor = mitk::CurveParameterFunctor::New(); + ConfigureFunctor(functor); + + auto pNames = functor->GetDescriptionParameterNames(); + + for (auto aName : pNames) + { + auto fullPath = mitk::generateModelFitResultImagePath(outFileName, aName); + std::cout << "Store result parameter: " << aName << " -> " << fullPath << std::endl; + } +} + +int main(int argc, char* argv[]) +{ + mitkCommandLineParser parser; + setupParser(parser); + + mitk::PreferenceListReaderOptionsFunctor readerFilterFunctor = mitk::PreferenceListReaderOptionsFunctor({ "MITK DICOM Reader v2 (classic config)" }, { "MITK DICOM Reader" }); + + const std::map& parsedArgs = parser.parseArguments(argc, argv); + if (!configureApplicationSettings(parsedArgs)) + { + return EXIT_FAILURE; + }; + + // Show a help message + if (parsedArgs.count("help") || parsedArgs.count("h")) + { + std::cout << parser.helpText(); + return EXIT_SUCCESS; + } + + //! [do processing] + try + { + if (preview) + { + doPreview(); + } + else + { + image = mitk::IOUtil::Load(inFilename, &readerFilterFunctor); + std::cout << "Input: " << inFilename << std::endl; + + if (!maskFileName.empty()) + { + mask = mitk::IOUtil::Load(maskFileName, &readerFilterFunctor); + std::cout << "Mask: " << maskFileName << std::endl; + } + else + { + std::cout << "Mask: none" << std::endl; + } + + doDescription(); + } + + std::cout << "Processing finished." << std::endl; + + return EXIT_SUCCESS; + } + catch (itk::ExceptionObject e) + { + MITK_ERROR << e; + return EXIT_FAILURE; + } + catch (std::exception e) + { + MITK_ERROR << e.what(); + return EXIT_FAILURE; + } + catch (...) + { + MITK_ERROR << "Unexpected error encountered."; + return EXIT_FAILURE; + } +} diff --git a/Modules/Pharmacokinetics/cmdapps/MRPerfusionMiniApp.cpp b/Modules/Pharmacokinetics/cmdapps/MRPerfusionMiniApp.cpp new file mode 100644 index 0000000000..6faf139dff --- /dev/null +++ b/Modules/Pharmacokinetics/cmdapps/MRPerfusionMiniApp.cpp @@ -0,0 +1,878 @@ +/*=================================================================== + +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. + +===================================================================*/ + +// std includes +#include + +// itk includes +#include "itksys/SystemTools.hxx" + +// CTK includes +#include "mitkCommandLineParser.h" + +// MITK includes +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +std::string inFilename; +std::string outFileName; +std::string maskFileName; +std::string aifMaskFileName; +std::string aifImageFileName; + +mitk::Image::Pointer image; +mitk::Image::Pointer mask; +mitk::Image::Pointer aifImage; +mitk::Image::Pointer aifMask; + +bool useConstraints(false); +bool verbose(false); +bool roibased(false); +bool preview(false); + +std::string modelName; + +float aifHematocritLevel(0); +float brixInjectionTime(0); + +const std::string MODEL_NAME_3SL = "3SL"; +const std::string MODEL_NAME_descriptive = "descriptive"; +const std::string MODEL_NAME_tofts = "tofts"; +const std::string MODEL_NAME_2CX = "2CX"; + +void onFitEvent(::itk::Object* caller, const itk::EventObject & event, void* /*data*/) +{ + itk::ProgressEvent progressEvent; + + if (progressEvent.CheckEvent(&event)) + { + mitk::ParameterFitImageGeneratorBase* castedReporter = dynamic_cast(caller); + std::cout <GetProgress()*100 << "% "; + } +} + + +void setupParser(mitkCommandLineParser& parser) +{ + // set general information about your MiniApp + parser.setCategory("Dynamic Data Analysis Tools"); + parser.setTitle("MR Perfusion"); + parser.setDescription("MiniApp that allows to fit MRI perfusion models and generates the according parameter maps. IMPORTANT!!!: The app assumes that the input images (signal and AIF) are concentration images. If your images do not hold this assumption, convert the image date before using this app (e.g. by using the signal-to-concentration-converter mini app."); + parser.setContributor("DKFZ MIC"); + //! [create parser] + + //! [add arguments] + // 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("Model parameters"); + parser.addArgument( + "model", "l", mitkCommandLineParser::String, "Model function", "Model that should be used to fit the concentration signal. Options are: \""+MODEL_NAME_descriptive+"\" (descriptive pharmacokinetic Brix model),\""+MODEL_NAME_3SL+"\" (three step linear model), \""+MODEL_NAME_tofts+"\" (extended tofts model) or \""+MODEL_NAME_2CX+"\" (two compartment exchange model).", us::Any(std::string(MODEL_NAME_tofts))); + parser.addArgument( + "injectiontime", "j", mitkCommandLineParser::Float, "Injection time [min]", "Injection time of the bolus. This information is needed for the descriptive pharmacokinetic Brix model.", us::Any()); + parser.endGroup(); + parser.beginGroup("Required I/O parameters"); + parser.addArgument( + "input", "i", mitkCommandLineParser::InputFile, "Input file", "input 3D+t image file", us::Any(), false); + parser.addArgument("output", + "o", + mitkCommandLineParser::OutputFile, + "Output file template", + "where to save the output parameter images. The specified path will be used as template to determine the format (via extension) and the name \"root\". For each parameter a suffix will be added to the name.", + us::Any(), + false); + parser.endGroup(); + + parser.beginGroup("AIF parameters"); + parser.addArgument( + "aifmask", "n", mitkCommandLineParser::InputFile, "AIF mask file", "Mask that defines the spatial image region that should be used as AIF for models that need one. Must have the same geometry as the AIF input image!", us::Any()); + parser.addArgument( + "aifimage", "a", mitkCommandLineParser::InputFile, "AIF image file", "3D+t image that defines the image that containes the AIF signal. If this flag is not set and the model needs a AIF, the CLI will assume that the AIF is encoded in the normal image. Must have the same geometry as the AIF mask!", us::Any()); + parser.addArgument( + "hematocrit", "h", mitkCommandLineParser::Float, "Hematocrit Level", "Value needed for correct AIF computation. Only needed if model needs an AIF. Default value is 0.45.", us::Any(0.45)); + parser.endGroup(); + + parser.beginGroup("Optional parameters"); + parser.addArgument( + "mask", "m", mitkCommandLineParser::InputFile, "Mask file", "Mask that defines the spatial image region that should be fitted. Must have the same geometry as the input image!", us::Any()); + parser.addArgument( + "verbose", "v", mitkCommandLineParser::Bool, "Verbose Output", "Whether to produce verbose output"); + parser.addArgument( + "roibased", "r", mitkCommandLineParser::Bool, "Roi based fitting", "Will compute a mean intesity signal over the ROI before fitting it. If this mode is used a mask must be specified."); + parser.addArgument( + "constraints", "c", mitkCommandLineParser::Bool, "Constraints", "Indicates if constraints should be used for the fitting (if flag is set the default contraints will be used.).", us::Any(false)); + parser.addArgument( + "preview", "p", mitkCommandLineParser::Bool, "Preview outputs", "The application previews the outputs (filename, type) it would produce with the current settings."); + parser.addArgument("help", "h", mitkCommandLineParser::Bool, "Help:", "Show this help text"); + parser.endGroup(); + //! [add arguments] +} + +bool configureApplicationSettings(std::map parsedArgs) +{ + if (parsedArgs.size() == 0) + return false; + + // parse, cast and set required arguments + modelName = MODEL_NAME_tofts; + if (parsedArgs.count("model")) + { + modelName = us::any_cast(parsedArgs["model"]); + } + + inFilename = us::any_cast(parsedArgs["input"]); + outFileName = us::any_cast(parsedArgs["output"]); + + if (parsedArgs.count("mask")) + { + maskFileName = us::any_cast(parsedArgs["mask"]); + } + + if (parsedArgs.count("aifimage")) + { + aifImageFileName = us::any_cast(parsedArgs["aifimage"]); + } + + if (parsedArgs.count("aifmask")) + { + aifMaskFileName = us::any_cast(parsedArgs["aifmask"]); + } + + verbose = false; + if (parsedArgs.count("verbose")) + { + verbose = us::any_cast(parsedArgs["verbose"]); + } + + preview = false; + if (parsedArgs.count("preview")) + { + preview = us::any_cast(parsedArgs["preview"]); + } + + roibased = false; + if (parsedArgs.count("roibased")) + { + roibased = us::any_cast(parsedArgs["roibased"]); + } + + useConstraints = false; + if (parsedArgs.count("constraints")) + { + useConstraints = us::any_cast(parsedArgs["constraints"]); + } + + aifHematocritLevel = 0.45; + if (parsedArgs.count("hematocrit")) + { + aifHematocritLevel = us::any_cast(parsedArgs["hematocrit"]); + } + + brixInjectionTime = 0.0; + if (parsedArgs.count("injectiontime")) + { + brixInjectionTime = us::any_cast(parsedArgs["injectiontime"]); + } + return true; +} + +mitk::ModelFitFunctorBase::Pointer createDefaultFitFunctor( + const mitk::ModelParameterizerBase* parameterizer, const mitk::ModelFactoryBase* modelFactory) +{ + mitk::LevenbergMarquardtModelFitFunctor::Pointer fitFunctor = + mitk::LevenbergMarquardtModelFitFunctor::New(); + + mitk::NormalizedSumOfSquaredDifferencesFitCostFunction::Pointer chi2 = + mitk::NormalizedSumOfSquaredDifferencesFitCostFunction::New(); + fitFunctor->RegisterEvaluationParameter("Chi^2", chi2); + + if (useConstraints) + { + fitFunctor->SetConstraintChecker(modelFactory->CreateDefaultConstraints().GetPointer()); + } + + mitk::ModelBase::Pointer refModel = parameterizer->GenerateParameterizedModel(); + + ::itk::LevenbergMarquardtOptimizer::ScalesType scales; + scales.SetSize(refModel->GetNumberOfParameters()); + scales.Fill(1.0); + fitFunctor->SetScales(scales); + + fitFunctor->SetDebugParameterMaps(true); + + return fitFunctor.GetPointer(); +} + +/**Helper that ensures that the mask (if it exists) is always 3D image. If the mask is originally an 4D image, the first +time step will be used.*/ +mitk::Image::Pointer getMask3D() +{ + mitk::Image::Pointer result; + + if (mask.IsNotNull()) + { + result = mask; + + //mask settings + if (mask->GetTimeSteps() > 1) + { + MITK_INFO << "Selected mask has multiple timesteps. Only use first timestep to mask model fit."; + mitk::ImageTimeSelector::Pointer maskedImageTimeSelector = mitk::ImageTimeSelector::New(); + maskedImageTimeSelector->SetInput(mask); + maskedImageTimeSelector->SetTimeNr(0); + maskedImageTimeSelector->UpdateLargestPossibleRegion(); + result = maskedImageTimeSelector->GetOutput(); + } + } + + return result; +} + + +void getAIF(mitk::AIFBasedModelBase::AterialInputFunctionType& aif, + mitk::AIFBasedModelBase::AterialInputFunctionType& aifTimeGrid) +{ + if (aifMask.IsNotNull()) + { + aif.clear(); + aifTimeGrid.clear(); + + mitk::AterialInputFunctionGenerator::Pointer aifGenerator = + mitk::AterialInputFunctionGenerator::New(); + + //Hematocrit level + aifGenerator->SetHCL(aifHematocritLevel); + std::cout << "AIF hematocrit level: " << aifHematocritLevel << std::endl; + + mitk::Image::Pointer selectedAIFMask = aifMask; + + //mask settings + if (aifMask->GetTimeSteps() > 1) + { + MITK_INFO << "Selected AIF mask has multiple timesteps. Only use first timestep to mask model fit."; + mitk::ImageTimeSelector::Pointer maskedImageTimeSelector = mitk::ImageTimeSelector::New(); + maskedImageTimeSelector->SetInput(aifMask); + maskedImageTimeSelector->SetTimeNr(0); + maskedImageTimeSelector->UpdateLargestPossibleRegion(); + aifMask = maskedImageTimeSelector->GetOutput(); + } + + aifGenerator->SetMask(aifMask); + + mitk::Image::Pointer selectedAIFImage = image; + //image settings + if (aifImage.IsNotNull()) + { + selectedAIFImage = aifImage; + } + + aifGenerator->SetDynamicImage(selectedAIFImage); + + aif = aifGenerator->GetAterialInputFunction(); + aifTimeGrid = aifGenerator->GetAterialInputFunctionTimeGrid(); + } + else + { + mitkThrow() << "Cannot generate AIF. AIF mask was not specified or correctly loaded."; + } +} + + +void generateDescriptiveBrixModel_PixelBased(mitk::modelFit::ModelFitInfo::Pointer& + modelFitInfo, mitk::ParameterFitImageGeneratorBase::Pointer& generator) +{ + mitk::PixelBasedParameterFitImageGenerator::Pointer fitGenerator = + mitk::PixelBasedParameterFitImageGenerator::New(); + + mitk::DescriptivePharmacokineticBrixModelParameterizer::Pointer modelParameterizer = + mitk::DescriptivePharmacokineticBrixModelParameterizer::New(); + + mitk::Image::Pointer mask3D = getMask3D(); + + //Model configuration (static parameters) can be done now + modelParameterizer->SetTau(brixInjectionTime); + std::cout << "Injection time [min]: " << brixInjectionTime << std::endl; + + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(image); + imageTimeSelector->SetTimeNr(0); + imageTimeSelector->UpdateLargestPossibleRegion(); + + mitk::DescriptivePharmacokineticBrixModelParameterizer::BaseImageType::Pointer baseImage; + mitk::CastToItkImage(imageTimeSelector->GetOutput(), baseImage); + + modelParameterizer->SetBaseImage(baseImage); + + //Specify fitting strategy and criterion parameters + mitk::ModelFactoryBase::Pointer factory = mitk::DescriptivePharmacokineticBrixModelFactory::New().GetPointer(); + mitk::ModelFitFunctorBase::Pointer fitFunctor = createDefaultFitFunctor(modelParameterizer, factory); + + //Parametrize fit generator + fitGenerator->SetModelParameterizer(modelParameterizer); + std::string roiUID = ""; + + if (mask3D.IsNotNull()) + { + fitGenerator->SetMask(mask3D); + roiUID = mitk::EnsureModelFitUID(mask); + } + + fitGenerator->SetDynamicImage(image); + fitGenerator->SetFitFunctor(fitFunctor); + + generator = fitGenerator.GetPointer(); + + //Create model info + modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, + image, mitk::ModelFitConstants::FIT_TYPE_VALUE_PIXELBASED(), roiUID); +} + +void generateDescriptiveBrixModel_ROIBased(mitk::modelFit::ModelFitInfo::Pointer& + modelFitInfo, mitk::ParameterFitImageGeneratorBase::Pointer& generator) +{ + mitk::Image::Pointer mask3D = getMask3D(); + + if (mask3D.IsNull()) + { + return; + } + + mitk::ROIBasedParameterFitImageGenerator::Pointer fitGenerator = + mitk::ROIBasedParameterFitImageGenerator::New(); + + mitk::DescriptivePharmacokineticBrixModelValueBasedParameterizer::Pointer modelParameterizer = + mitk::DescriptivePharmacokineticBrixModelValueBasedParameterizer::New(); + + //Compute ROI signal + mitk::MaskedDynamicImageStatisticsGenerator::Pointer signalGenerator = + mitk::MaskedDynamicImageStatisticsGenerator::New(); + signalGenerator->SetMask(mask3D); + signalGenerator->SetDynamicImage(image); + signalGenerator->Generate(); + + mitk::MaskedDynamicImageStatisticsGenerator::ResultType roiSignal = signalGenerator->GetMean(); + + //Model configuration (static parameters) can be done now + modelParameterizer->SetTau(brixInjectionTime); + std::cout << "Injection time [min]: " << brixInjectionTime << std::endl; + modelParameterizer->SetBaseValue(roiSignal[0]); + + //Specify fitting strategy and criterion parameters + mitk::ModelFactoryBase::Pointer factory = mitk::DescriptivePharmacokineticBrixModelFactory::New().GetPointer(); + mitk::ModelFitFunctorBase::Pointer fitFunctor = createDefaultFitFunctor(modelParameterizer, factory); + + //Parametrize fit generator + fitGenerator->SetModelParameterizer(modelParameterizer); + fitGenerator->SetMask(mask3D); + fitGenerator->SetFitFunctor(fitFunctor); + fitGenerator->SetSignal(roiSignal); + fitGenerator->SetTimeGrid(mitk::ExtractTimeGrid(image)); + + generator = fitGenerator.GetPointer(); + + std::string roiUID = mitk::EnsureModelFitUID(mask); + + //Create model info + modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, + image, mitk::ModelFitConstants::FIT_TYPE_VALUE_ROIBASED(), roiUID); + mitk::ScalarListLookupTable::ValueType infoSignal; + + for (mitk::MaskedDynamicImageStatisticsGenerator::ResultType::const_iterator pos = + roiSignal.begin(); pos != roiSignal.end(); ++pos) + { + infoSignal.push_back(*pos); + } + + modelFitInfo->inputData.SetTableValue("ROI", infoSignal); +} + + +void Generate3StepLinearModelFit_PixelBased(mitk::modelFit::ModelFitInfo::Pointer& + modelFitInfo, mitk::ParameterFitImageGeneratorBase::Pointer& generator) +{ + mitk::PixelBasedParameterFitImageGenerator::Pointer fitGenerator = + mitk::PixelBasedParameterFitImageGenerator::New(); + + mitk::ThreeStepLinearModelParameterizer::Pointer modelParameterizer = + mitk::ThreeStepLinearModelParameterizer::New(); + + mitk::Image::Pointer mask3D = getMask3D(); + + //Specify fitting strategy and criterion parameters + mitk::ModelFactoryBase::Pointer factory = mitk::ThreeStepLinearModelFactory::New().GetPointer(); + mitk::ModelFitFunctorBase::Pointer fitFunctor = createDefaultFitFunctor(modelParameterizer, factory); + + //Parametrize fit generator + fitGenerator->SetModelParameterizer(modelParameterizer); + std::string roiUID = ""; + + if (mask3D.IsNotNull()) + { + fitGenerator->SetMask(mask3D); + roiUID = mitk::EnsureModelFitUID(mask); + } + + fitGenerator->SetDynamicImage(image); + fitGenerator->SetFitFunctor(fitFunctor); + + generator = fitGenerator.GetPointer(); + + //Create model info + modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, + image, mitk::ModelFitConstants::FIT_TYPE_VALUE_PIXELBASED(), roiUID); +} + +void Generate3StepLinearModelFit_ROIBased(mitk::modelFit::ModelFitInfo::Pointer& + modelFitInfo, mitk::ParameterFitImageGeneratorBase::Pointer& generator) +{ + mitk::Image::Pointer mask3D = getMask3D(); + + if (mask3D.IsNull()) + { + return; + } + + mitk::ROIBasedParameterFitImageGenerator::Pointer fitGenerator = + mitk::ROIBasedParameterFitImageGenerator::New(); + + mitk::ThreeStepLinearModelParameterizer::Pointer modelParameterizer = + mitk::ThreeStepLinearModelParameterizer::New(); + + //Compute ROI signal + mitk::MaskedDynamicImageStatisticsGenerator::Pointer signalGenerator = + mitk::MaskedDynamicImageStatisticsGenerator::New(); + signalGenerator->SetMask(mask3D); + signalGenerator->SetDynamicImage(image); + signalGenerator->Generate(); + + mitk::MaskedDynamicImageStatisticsGenerator::ResultType roiSignal = signalGenerator->GetMean(); + + //Specify fitting strategy and criterion parameters + mitk::ModelFactoryBase::Pointer factory = mitk::ThreeStepLinearModelFactory::New().GetPointer(); + mitk::ModelFitFunctorBase::Pointer fitFunctor = createDefaultFitFunctor(modelParameterizer, factory); + + //Parametrize fit generator + fitGenerator->SetModelParameterizer(modelParameterizer); + fitGenerator->SetMask(mask3D); + fitGenerator->SetFitFunctor(fitFunctor); + fitGenerator->SetSignal(roiSignal); + fitGenerator->SetTimeGrid(mitk::ExtractTimeGrid(image)); + + generator = fitGenerator.GetPointer(); + + std::string roiUID = mitk::EnsureModelFitUID(mask); + + //Create model info + modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, + image, mitk::ModelFitConstants::FIT_TYPE_VALUE_ROIBASED(), roiUID); + mitk::ScalarListLookupTable::ValueType infoSignal; + + for (mitk::MaskedDynamicImageStatisticsGenerator::ResultType::const_iterator pos = + roiSignal.begin(); pos != roiSignal.end(); ++pos) + { + infoSignal.push_back(*pos); + } + + modelFitInfo->inputData.SetTableValue("ROI", infoSignal); +} + +template +void generateAIFbasedModelFit_PixelBased(mitk::modelFit::ModelFitInfo::Pointer& + modelFitInfo, mitk::ParameterFitImageGeneratorBase::Pointer& generator) +{ + mitk::PixelBasedParameterFitImageGenerator::Pointer fitGenerator = + mitk::PixelBasedParameterFitImageGenerator::New(); + + typename TParameterizer::Pointer modelParameterizer = + TParameterizer::New(); + + mitk::AIFBasedModelBase::AterialInputFunctionType aif; + mitk::AIFBasedModelBase::AterialInputFunctionType aifTimeGrid; + getAIF(aif, aifTimeGrid); + + modelParameterizer->SetAIF(aif); + modelParameterizer->SetAIFTimeGrid(aifTimeGrid); + + mitk::Image::Pointer mask3D = getMask3D(); + + //Specify fitting strategy and criterion parameters + mitk::ModelFactoryBase::Pointer factory = TFactory::New().GetPointer(); + mitk::ModelFitFunctorBase::Pointer fitFunctor = createDefaultFitFunctor(modelParameterizer, factory); + + //Parametrize fit generator + fitGenerator->SetModelParameterizer(modelParameterizer); + std::string roiUID = ""; + + if (mask3D.IsNotNull()) + { + fitGenerator->SetMask(mask3D); + roiUID = mitk::EnsureModelFitUID(mask); + } + + fitGenerator->SetDynamicImage(image); + fitGenerator->SetFitFunctor(fitFunctor); + + generator = fitGenerator.GetPointer(); + + //Create model info + modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, + image, mitk::ModelFitConstants::FIT_TYPE_VALUE_PIXELBASED(), + roiUID); + + mitk::ScalarListLookupTable::ValueType infoSignal; + + for (mitk::AIFBasedModelBase::AterialInputFunctionType::const_iterator pos = + aif.begin(); pos != aif.end(); ++pos) + { + infoSignal.push_back(*pos); + } + + modelFitInfo->inputData.SetTableValue("AIF", infoSignal); +} + +template +void generateAIFbasedModelFit_ROIBased( + mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, + mitk::ParameterFitImageGeneratorBase::Pointer& generator) +{ + mitk::Image::Pointer mask3D = getMask3D(); + + if (mask3D.IsNull()) + { + return; + } + + mitk::ROIBasedParameterFitImageGenerator::Pointer fitGenerator = + mitk::ROIBasedParameterFitImageGenerator::New(); + + typename TParameterizer::Pointer modelParameterizer = + TParameterizer::New(); + + mitk::AIFBasedModelBase::AterialInputFunctionType aif; + mitk::AIFBasedModelBase::AterialInputFunctionType aifTimeGrid; + getAIF(aif, aifTimeGrid); + + modelParameterizer->SetAIF(aif); + modelParameterizer->SetAIFTimeGrid(aifTimeGrid); + + //Compute ROI signal + mitk::MaskedDynamicImageStatisticsGenerator::Pointer signalGenerator = + mitk::MaskedDynamicImageStatisticsGenerator::New(); + signalGenerator->SetMask(mask3D); + signalGenerator->SetDynamicImage(image); + signalGenerator->Generate(); + + mitk::MaskedDynamicImageStatisticsGenerator::ResultType roiSignal = signalGenerator->GetMean(); + + //Specify fitting strategy and criterion parameters + mitk::ModelFactoryBase::Pointer factory = TFactory::New().GetPointer(); + mitk::ModelFitFunctorBase::Pointer fitFunctor = createDefaultFitFunctor(modelParameterizer, factory); + + //Parametrize fit generator + fitGenerator->SetModelParameterizer(modelParameterizer); + fitGenerator->SetMask(mask3D); + fitGenerator->SetFitFunctor(fitFunctor); + fitGenerator->SetSignal(roiSignal); + fitGenerator->SetTimeGrid(mitk::ExtractTimeGrid(image)); + + generator = fitGenerator.GetPointer(); + + std::string roiUID = mitk::EnsureModelFitUID(mask); + + //Create model info + modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, + image, mitk::ModelFitConstants::FIT_TYPE_VALUE_ROIBASED(), + roiUID); + + mitk::ScalarListLookupTable::ValueType infoSignal; + + for (mitk::MaskedDynamicImageStatisticsGenerator::ResultType::const_iterator pos = + roiSignal.begin(); pos != roiSignal.end(); ++pos) + { + infoSignal.push_back(*pos); + } + + modelFitInfo->inputData.SetTableValue("ROI", infoSignal); + + infoSignal.clear(); + + for (mitk::AIFBasedModelBase::AterialInputFunctionType::const_iterator pos = + aif.begin(); pos != aif.end(); ++pos) + { + infoSignal.push_back(*pos); + } + + modelFitInfo->inputData.SetTableValue("AIF", infoSignal); +} + + +void storeResultImage(const std::string& name, mitk::Image* image, mitk::modelFit::Parameter::Type nodeType, const mitk::modelFit::ModelFitInfo* modelFitInfo) +{ + mitk::modelFit::SetModelFitDataProperties(image, name, nodeType, modelFitInfo); + + std::string ext = ::itksys::SystemTools::GetFilenameLastExtension(outFileName); + + std::string dir = itksys::SystemTools::GetFilenamePath(outFileName); + dir = itksys::SystemTools::ConvertToOutputPath(dir); + + std::string rootName = itksys::SystemTools::GetFilenameWithoutLastExtension(outFileName); + + std::string fileName = rootName + "_" + name + ext; + + std::vector pathElements; + pathElements.push_back(dir); + pathElements.push_back(fileName); + + std::string fullOutPath = itksys::SystemTools::ConvertToOutputPath(dir + "/" + fileName); + + mitk::IOUtil::Save(image, fullOutPath); + + std::cout << "Store result (parameter: "<(fitSession, generator); + } + else + { + generateAIFbasedModelFit_ROIBased(fitSession, generator); + } + } + else if (is2CXMFactory) + { + std::cout << "Model: two compartment exchange model" << std::endl; + if (!roibased) + { + generateAIFbasedModelFit_PixelBased(fitSession, generator); + } + else + { + generateAIFbasedModelFit_ROIBased(fitSession, generator); + } + } + else + { + std::cerr << "ERROR. Model flag is unknown. Given flag: " << modelName << std::endl; + } +} + +void doFitting() +{ + mitk::ParameterFitImageGeneratorBase::Pointer generator = nullptr; + mitk::modelFit::ModelFitInfo::Pointer fitSession = nullptr; + + ::itk::CStyleCommand::Pointer command = ::itk::CStyleCommand::New(); + command->SetCallback(onFitEvent); + + createFitGenerator(fitSession, generator); + + if (generator.IsNotNull() ) + { + std::cout << "Started fitting process..." << std::endl; + generator->AddObserver(::itk::AnyEvent(), command); + generator->Generate(); + std::cout << std::endl << "Finished fitting process" << std::endl; + + mitk::storeModelFitGeneratorResults(outFileName, generator, fitSession); + } + else + { + mitkThrow() << "Fitting error! Could not initialize fitting job."; + } +} + +void doPreview() +{ + mitk::ParameterFitImageGeneratorBase::Pointer generator = nullptr; + mitk::modelFit::ModelFitInfo::Pointer fitSession = nullptr; + + createFitGenerator(fitSession, generator); + + if (generator.IsNotNull()) + { + mitk::previewModelFitGeneratorResults(outFileName, generator); + } + else + { + mitkThrow() << "Fitting error! Could not initialize fitting job."; + } +} + +int main(int argc, char* argv[]) +{ + mitkCommandLineParser parser; + setupParser(parser); + const std::map& parsedArgs = parser.parseArguments(argc, argv); + + mitk::PreferenceListReaderOptionsFunctor readerFilterFunctor = mitk::PreferenceListReaderOptionsFunctor({ "MITK DICOM Reader v2 (classic config)" }, { "MITK DICOM Reader" }); + + if (!configureApplicationSettings(parsedArgs)) + { + return EXIT_FAILURE; + }; + + // Show a help message + if (parsedArgs.count("help") || parsedArgs.count("h")) + { + std::cout << parser.helpText(); + return EXIT_SUCCESS; + } + + //! [do processing] + try + { + image = mitk::IOUtil::Load(inFilename, &readerFilterFunctor); + std::cout << "Input: " << inFilename << std::endl; + + if (!maskFileName.empty()) + { + mask = mitk::IOUtil::Load(maskFileName, &readerFilterFunctor); + std::cout << "Mask: " << maskFileName << std::endl; + } + else + { + std::cout << "Mask: none" << std::endl; + } + + if (modelName != MODEL_NAME_descriptive && modelName != MODEL_NAME_3SL) + { + if (!aifMaskFileName.empty()) + { + aifMask = mitk::IOUtil::Load(aifMaskFileName, &readerFilterFunctor); + std::cout << "AIF mask: " << aifMaskFileName << std::endl; + } + else + { + mitkThrow() << "Error. Cannot fit. Choosen model needs an AIF. Please specify AIF mask (--aifmask)."; + } + if (!aifImageFileName.empty()) + { + aifImage = mitk::IOUtil::Load(aifImageFileName, &readerFilterFunctor); + std::cout << "AIF image: " << aifImageFileName << std::endl; + } + else + { + std::cout << "AIF image: none (using signal image)" << std::endl; + } + } + + if (roibased && mask.IsNull()) + { + mitkThrow() << "Error. Cannot fit. Please specify mask if you select roi based fitting."; + } + + std::cout << "Style: "; + if (roibased) + { + std::cout << "ROI based"; + } + else + { + std::cout << "pixel based"; + } + std::cout << std::endl; + + if (preview) + { + doPreview(); + } + else + { + doFitting(); + } + + std::cout << "Processing finished." << std::endl; + + return EXIT_SUCCESS; + } + catch (itk::ExceptionObject e) + { + MITK_ERROR << e; + return EXIT_FAILURE; + } + catch (std::exception e) + { + MITK_ERROR << e.what(); + return EXIT_FAILURE; + } + catch (...) + { + MITK_ERROR << "Unexpected error encountered."; + return EXIT_FAILURE; + } +} diff --git a/Modules/Pharmacokinetics/cmdapps/MRSignal2ConcentrationMiniApp.cpp b/Modules/Pharmacokinetics/cmdapps/MRSignal2ConcentrationMiniApp.cpp new file mode 100644 index 0000000000..a7baa2871b --- /dev/null +++ b/Modules/Pharmacokinetics/cmdapps/MRSignal2ConcentrationMiniApp.cpp @@ -0,0 +1,293 @@ +/*=================================================================== + +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. + +===================================================================*/ + +// std includes +#include + +// itk includes +#include "itksys/SystemTools.hxx" + +// CTK includes +#include "mitkCommandLineParser.h" + +// MITK includes +#include +#include +#include +#include +#include + +#include + +std::string inFilename; +std::string outFileName; + +mitk::Image::Pointer image; + +bool verbose(false); + +bool t1_absolute(false); +bool t1_relative(false); +bool t1_flash(false); +bool t2(false); + +float k(1.0); +float te(0); +float rec_time(0); +float relaxivity(0); +float rel_time(0); + +void setupParser(mitkCommandLineParser& parser) +{ + // set general information about your MiniApp + parser.setCategory("Dynamic Data Analysis Tools"); + parser.setTitle("MR Signal to Concentration Converter"); + parser.setDescription("MiniApp that allows to convert a T1 or T2 signal image into a concentration image for perfusion analysis."); + parser.setContributor("DKFZ MIC"); + //! [create parser] + + //! [add arguments] + // 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 I/O parameters"); + parser.addArgument( + "input", "i", mitkCommandLineParser::InputFile, "Input file", "input 3D+t image file", us::Any(), false); + parser.addArgument("output", + "o", + mitkCommandLineParser::OutputFile, + "Output file", + "where to save the output concentration image.", + us::Any(), + false); + parser.endGroup(); + + parser.beginGroup("Conversion parameters"); + parser.addArgument( + "t1-absolute", "", mitkCommandLineParser::Bool, "T1 absolute signal enhancement", "Activate conversion for T1 absolute signal enhancement."); + parser.addArgument( + "t1-relative", "", mitkCommandLineParser::Bool, "T1 relative signal enhancement", "Activate conversion for T1 relative signal enhancement."); + parser.addArgument( + "t1-flash", "", mitkCommandLineParser::Bool, "T1 turbo flash", "Activate specific conversion for T1 turbo flash sequences."); + parser.addArgument( + "t2", "", mitkCommandLineParser::Bool, "T2 signal conversion", "Activate conversion for T2 signal enhancement to concentration."); + + parser.addArgument( + "k", "k", mitkCommandLineParser::Float, "Conversion factor k", "Needed for the following conversion modes: T1-absolute, T1-relative, T2. Default value is 1.", us::Any(1)); + parser.addArgument( + "recovery-time", "", mitkCommandLineParser::Float, "Recovery time", "Needed for the following conversion modes: T1-flash."); + parser.addArgument( + "relaxivity", "", mitkCommandLineParser::Float, "Relaxivity", "Needed for the following conversion modes: T1-flash."); + parser.addArgument( + "relaxation-time", "", mitkCommandLineParser::Float, "Relaxation time", "Needed for the following conversion modes: T1-flash."); + parser.addArgument( + "te", "", mitkCommandLineParser::Float, "Echo time TE", "Needed for the following conversion modes: T2.", us::Any(1)); + + parser.beginGroup("Optional parameters"); + parser.addArgument( + "verbose", "v", mitkCommandLineParser::Bool, "Verbose Output", "Whether to produce verbose output"); + parser.addArgument("help", "h", mitkCommandLineParser::Bool, "Help:", "Show this help text"); + parser.endGroup(); + //! [add arguments] +} + +bool configureApplicationSettings(std::map parsedArgs) +{ + if (parsedArgs.size() == 0) + return false; + + inFilename = us::any_cast(parsedArgs["input"]); + outFileName = us::any_cast(parsedArgs["output"]); + + verbose = false; + if (parsedArgs.count("verbose")) + { + verbose = us::any_cast(parsedArgs["verbose"]); + } + + t1_absolute = false; + if (parsedArgs.count("t1-absolute")) + { + t1_absolute = us::any_cast(parsedArgs["t1-absolute"]); + } + + t1_relative = false; + if (parsedArgs.count("t1-relative")) + { + t1_relative = us::any_cast(parsedArgs["t1-relative"]); + } + + t1_flash = false; + if (parsedArgs.count("t1-flash")) + { + t1_flash = us::any_cast(parsedArgs["t1-flash"]); + } + + t2 = false; + if (parsedArgs.count("t2")) + { + t2 = us::any_cast(parsedArgs["t2"]); + } + + k = 0.0; + if (parsedArgs.count("k")) + { + k = us::any_cast(parsedArgs["k"]); + } + + relaxivity = 0.0; + if (parsedArgs.count("relaxivity")) + { + relaxivity = us::any_cast(parsedArgs["relaxivity"]); + } + + rec_time = 0.0; + if (parsedArgs.count("recovery-time")) + { + rec_time = us::any_cast(parsedArgs["recovery-time"]); + } + + rel_time = 0.0; + if (parsedArgs.count("relaxation-time")) + { + rel_time = us::any_cast(parsedArgs["relaxation-time"]); + } + + te = 0.0; + if (parsedArgs.count("te")) + { + te = us::any_cast(parsedArgs["te"]); + } + + //consistency checks + int modeCount = 0; + if (t1_absolute) ++modeCount; + if (t1_flash) ++modeCount; + if (t1_relative) ++modeCount; + if (t2) ++modeCount; + + if (modeCount==0) + { + mitkThrow() << "Invalid program call. Please select the type of conversion."; + } + + if (modeCount >1) + { + mitkThrow() << "Invalid program call. Please select only ONE type of conversion."; + } + + if (!k && (t2 || t1_absolute || t1_relative)) + { + mitkThrow() << "Invalid program call. Please set 'k', if you use t1-absolute, t1-relative or t2."; + } + + if (!te && t2) + { + mitkThrow() << "Invalid program call. Please set 'te', if you use t2 mode."; + } + + if ((!rec_time||!rel_time||!relaxivity) && t1_flash) + { + mitkThrow() << "Invalid program call. Please set 'recovery-time', 'relaxation-time' and 'relaxivity', if you use t1-flash mode."; + } + + return true; +} + +void doConversion() +{ + mitk::ConcentrationCurveGenerator::Pointer concentrationGen = + mitk::ConcentrationCurveGenerator::New(); + concentrationGen->SetDynamicImage(image); + + concentrationGen->SetisTurboFlashSequence(t1_flash); + concentrationGen->SetAbsoluteSignalEnhancement(t1_absolute); + concentrationGen->SetRelativeSignalEnhancement(t1_relative); + + concentrationGen->SetisT2weightedImage(t2); + + if (t1_flash) + { + concentrationGen->SetRecoveryTime(rec_time); + concentrationGen->SetRelaxationTime(rel_time); + concentrationGen->SetRelaxivity(relaxivity); + } + else if (t2) + { + concentrationGen->SetT2Factor(k); + concentrationGen->SetT2EchoTime(te); + } + else + { + concentrationGen->SetFactor(k); + } + + mitk::Image::Pointer concentrationImage = concentrationGen->GetConvertedImage(); + + mitk::EnsureModelFitUID(concentrationImage); + mitk::IOUtil::Save(concentrationImage, outFileName); + + std::cout << "Store result: " << outFileName << std::endl; +} + +int main(int argc, char* argv[]) +{ + mitkCommandLineParser parser; + setupParser(parser); + const std::map& parsedArgs = parser.parseArguments(argc, argv); + if (!configureApplicationSettings(parsedArgs)) + { + return EXIT_FAILURE; + }; + + mitk::PreferenceListReaderOptionsFunctor readerFilterFunctor = mitk::PreferenceListReaderOptionsFunctor({ "MITK DICOM Reader v2 (classic config)" }, { "MITK DICOM Reader" }); + + // Show a help message + if (parsedArgs.count("help") || parsedArgs.count("h")) + { + std::cout << parser.helpText(); + return EXIT_SUCCESS; + } + + //! [do processing] + try + { + image = mitk::IOUtil::Load(inFilename, &readerFilterFunctor); + std::cout << "Input: " << inFilename << std::endl; + + doConversion(); + + std::cout << "Processing finished." << std::endl; + + return EXIT_SUCCESS; + } + catch (itk::ExceptionObject e) + { + MITK_ERROR << e; + return EXIT_FAILURE; + } + catch (std::exception e) + { + MITK_ERROR << e.what(); + return EXIT_FAILURE; + } + catch (...) + { + MITK_ERROR << "Unexpected error encountered."; + return EXIT_FAILURE; + } +} diff --git a/Modules/Pharmacokinetics/files.cmake b/Modules/Pharmacokinetics/files.cmake new file mode 100644 index 0000000000..b31eb1585c --- /dev/null +++ b/Modules/Pharmacokinetics/files.cmake @@ -0,0 +1,60 @@ +file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") + +set(CPP_FILES + Common/mitkAterialInputFunctionGenerator.cpp + Common/mitkAIFParametrizerHelper.cpp + Common/mitkConcentrationCurveGenerator.cpp + Common/mitkDescriptionParameterImageGeneratorBase.cpp + Common/mitkPixelBasedDescriptionParameterImageGenerator.cpp + DescriptionParameters/mitkCurveDescriptionParameterBase.cpp + DescriptionParameters/mitkAreaUnderTheCurveDescriptionParameter.cpp + DescriptionParameters/mitkAreaUnderFirstMomentDescriptionParameter.cpp + DescriptionParameters/mitkMeanResidenceTimeDescriptionParameter.cpp + DescriptionParameters/mitkTimeToPeakCurveDescriptionParameter.cpp + DescriptionParameters/mitkMaximumCurveDescriptionParameter.cpp + Functors/mitkCurveParameterFunctor.cpp + Models/mitkAIFBasedModelBase.cpp + Models/mitkDescriptivePharmacokineticBrixModel.cpp + Models/mitkDescriptivePharmacokineticBrixModelFactory.cpp + Models/mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer.cpp + Models/mitkDescriptivePharmacokineticBrixModelParameterizer.cpp + Models/mitkThreeStepLinearModel.cpp + Models/mitkThreeStepLinearModelFactory.cpp + Models/mitkThreeStepLinearModelParameterizer.cpp + Models/mitkTwoCompartmentExchangeModel.cpp + Models/mitkTwoCompartmentExchangeModelFactory.cpp + Models/mitkTwoCompartmentExchangeModelParameterizer.cpp + Models/mitkNumericTwoCompartmentExchangeModel.cpp + Models/mitkNumericTwoCompartmentExchangeModelFactory.cpp + Models/mitkNumericTwoCompartmentExchangeModelParameterizer.cpp + Models/mitkExtendedToftsModel.cpp + Models/mitkExtendedToftsModelFactory.cpp + Models/mitkExtendedToftsModelParameterizer.cpp + Models/mitkStandardToftsModel.cpp + Models/mitkStandardToftsModelFactory.cpp + Models/mitkStandardToftsModelParameterizer.cpp + Models/mitkOneTissueCompartmentModel.cpp + Models/mitkOneTissueCompartmentModelFactory.cpp + Models/mitkOneTissueCompartmentModelParameterizer.cpp + Models/mitkExtendedOneTissueCompartmentModel.cpp + Models/mitkExtendedOneTissueCompartmentModelFactory.cpp + Models/mitkExtendedOneTissueCompartmentModelParameterizer.cpp + Models/mitkTwoTissueCompartmentModel.cpp + Models/mitkTwoTissueCompartmentModelFactory.cpp + Models/mitkTwoTissueCompartmentModelParameterizer.cpp + Models/mitkTwoTissueCompartmentFDGModel.cpp + Models/mitkTwoTissueCompartmentFDGModelFactory.cpp + Models/mitkTwoTissueCompartmentFDGModelParameterizer.cpp + Models/mitkNumericTwoTissueCompartmentModel.cpp + Models/mitkNumericTwoTissueCompartmentModelFactory.cpp + Models/mitkNumericTwoTissueCompartmentModelParameterizer.cpp + SimulationFramework/mitkPerfusionDataGenerator.cpp + SimulationFramework/mitkImageGenerationHelper.cpp +) + +set(HXX_FILES +) + + +set(MOC_H_FILES +) diff --git a/Modules/Pharmacokinetics/include/mitkAIFBasedModelBase.h b/Modules/Pharmacokinetics/include/mitkAIFBasedModelBase.h new file mode 100644 index 0000000000..1f9119f189 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkAIFBasedModelBase.h @@ -0,0 +1,118 @@ +/*=================================================================== + +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 AIFBASEDMODELBASE_H +#define AIFBASEDMODELBASE_H + + +#include "MitkPharmacokineticsExports.h" +#include "mitkModelBase.h" +#include "itkArray2D.h" + +namespace mitk +{ + + /** \class AIFBasedModelBase + * \brief Base Class for all physiological perfusion models using an Aterial Input Function + * All AIF based models come with an array of AIF values and the corresponding TimeGrid ( AIF(t)) + * This class provides functions for setting the AIF Values and optionally a specific AIF TimeGrid. + * It also provides a method for interpolation of the AIF source array to a specified Timegrid that differs from + * AIFTimeGrid. The AIF must be set with an itk::Array. If no AIFTimeGrid is specified with the Setter, it is assumed + * that the AIFTimeGrid is the same as the ModelTimegrid (e.g. AIF is derived from data set to be fitted). In this + * case, AIFvalues must have the same length as ModelTimeGrid, otherwise an exception is generated*/ + class MITKPHARMACOKINETICS_EXPORT AIFBasedModelBase : public mitk::ModelBase + { + public: + + typedef AIFBasedModelBase Self; + typedef ModelBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + + /** Run-time type information (and related methods). */ + itkTypeMacro(PhysiologciModelBase, AIFBasedModelBase); + + + static const std::string NAME_STATIC_PARAMETER_AIF; + static const std::string NAME_STATIC_PARAMETER_AIFTimeGrid; + + static const std::string UNIT_STATIC_PARAMETER_AIF; + static const std::string UNIT_STATIC_PARAMETER_AIFTimeGrid; + + /** Typedef for Aterial InputFunction AIF(t)*/ + typedef itk::Array AterialInputFunctionType; + + itkGetConstReferenceMacro(AterialInputFunctionValues, AterialInputFunctionType); + itkGetConstReferenceMacro(AterialInputFunctionTimeGrid, TimeGridType); + + itkSetMacro(AterialInputFunctionValues, AterialInputFunctionType); + itkSetMacro(AterialInputFunctionTimeGrid, TimeGridType); + + virtual std::string GetXAxisName() const override; + + virtual std::string GetXAxisUnit() const override; + + virtual std::string GetYAxisName() const override; + + virtual std::string GetYAxisUnit() const override; + + /** Returns the TimeGrid used for the AIF. Either the externally set AIF time grid + * or the time grid of the model if nothing is set.*/ + const TimeGridType& GetCurrentAterialInputFunctionTimeGrid() const; + + /** Returns the Aterial Input function matching currentTimeGrid + * The original values are interpolated to the passed TimeGrid + * if currentTimeGrid.Size() = 0 , the Original AIF will be returned*/ + const AterialInputFunctionType GetAterialInputFunction(TimeGridType currentTimeGrid) const; + + virtual ParameterNamesType GetStaticParameterNames() const override; + virtual ParametersSizeType GetNumberOfStaticParameters() const override; + virtual ParamterUnitMapType GetStaticParameterUnits() const override; + + + protected: + AIFBasedModelBase(); + virtual ~AIFBasedModelBase(); + + /** Reimplementation that checks if AIF and timegrid settings are valid. + * @param [out] error Set internally to indicate the error reason if method returns false. Is used by GetSignal() for the + * exception comment. + * @return Returns true if the model is valid and can compute a signal. Otherwise it returns false.*/ + virtual bool ValidateModel(std::string& error) const override; + + virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; + + virtual void SetStaticParameter(const ParameterNameType& name, + const StaticParameterValuesType& values) override; + + virtual StaticParameterValuesType GetStaticParameterValue(const ParameterNameType& name) const + override; + + TimeGridType m_AterialInputFunctionTimeGrid; + AterialInputFunctionType m_AterialInputFunctionValues; + + + private: + + + //No copy constructor allowed + AIFBasedModelBase(const Self& source); + void operator=(const Self&); //purposely not implemented + + + }; +} +#endif // AIFBASEDMODELBASE_H diff --git a/Modules/Pharmacokinetics/include/mitkAIFBasedModelParameterizerBase.h b/Modules/Pharmacokinetics/include/mitkAIFBasedModelParameterizerBase.h new file mode 100644 index 0000000000..c6599b9f7f --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkAIFBasedModelParameterizerBase.h @@ -0,0 +1,96 @@ +/*=================================================================== + +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 __AIFBASED_MODEL_PARAMETERIZER_BASE_H +#define __AIFBASED_MODEL_PARAMETERIZER_BASE_H + +#include "mitkConcreteModelParameterizerBase.h" +#include "mitkAIFParametrizerHelper.h" +#include "mitkAIFBasedModelBase.h" + +namespace mitk +{ + /** Base class for model parameterizers for Models using an Aterial Input Function + */ + template + class MITKPHARMACOKINETICS_EXPORT AIFBasedModelParameterizerBase : public ConcreteModelParameterizerBase + + { + public: + typedef AIFBasedModelParameterizerBase Self; + typedef ConcreteModelParameterizerBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkTypeMacro(AIFBasedModelParameterizerBase, ConcreteModelParameterizerBase); + + typedef typename Superclass::ModelBaseType ModelBaseType; + typedef typename Superclass::ModelBasePointer ModelBasePointer; + + typedef typename Superclass::ModelType ModelType; + typedef typename Superclass::ModelPointer ModelPointer; + + typedef typename Superclass::StaticParameterValueType StaticParameterValueType; + typedef typename Superclass::StaticParameterValuesType StaticParameterValuesType; + typedef typename Superclass::StaticParameterMapType StaticParameterMapType; + + + typedef typename Superclass::IndexType IndexType; + + itkSetMacro(AIF, mitk::AIFBasedModelBase::AterialInputFunctionType); + itkGetConstReferenceMacro(AIF, mitk::AIFBasedModelBase::AterialInputFunctionType); + + itkSetMacro(AIFTimeGrid, mitk::ModelBase::TimeGridType); + itkGetConstReferenceMacro(AIFTimeGrid, mitk::ModelBase::TimeGridType); + + + /** Returns the global static parameters for the model. + * @remark this default implementation assumes only AIF and its timegrid as static parameters. + * Reimplement in derived classes to change this behavior.*/ + virtual StaticParameterMapType GetGlobalStaticParameters() const + { + StaticParameterMapType result; + StaticParameterValuesType valuesAIF = mitk::convertArrayToParameter(this->m_AIF); + StaticParameterValuesType valuesAIFGrid = mitk::convertArrayToParameter(this->m_AIFTimeGrid); + + result.insert(std::make_pair(ModelType::NAME_STATIC_PARAMETER_AIF, valuesAIF)); + result.insert(std::make_pair(ModelType::NAME_STATIC_PARAMETER_AIFTimeGrid, valuesAIFGrid)); + + return result; + }; + + + protected: + + AIFBasedModelParameterizerBase() + {}; + + virtual ~AIFBasedModelParameterizerBase() + {}; + + + mitk::AIFBasedModelBase::AterialInputFunctionType m_AIF; + mitk::ModelBase::TimeGridType m_AIFTimeGrid; + + + private: + + //No copy constructor allowed + AIFBasedModelParameterizerBase(const Self& source); + void operator=(const Self&); //purposely not implemented + }; + +} +#endif // __AIFBASED_MODEL_PARAMETERIZER_BASE_H diff --git a/Modules/Pharmacokinetics/include/mitkAIFParametrizerHelper.h b/Modules/Pharmacokinetics/include/mitkAIFParametrizerHelper.h new file mode 100644 index 0000000000..4106064544 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkAIFParametrizerHelper.h @@ -0,0 +1,35 @@ +/*=================================================================== + +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 __MITK_AIF_PARAMETERIZER_HELPER_H_ +#define __MITK_AIF_PARAMETERIZER_HELPER_H_ + +#include "mitkModelBase.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + /* Helper function for conversion of an itk::Array into ModelBase::StaticParameterValuesType(std::vector). + Iterates through array and pushes elements into vector*/ + MITKPHARMACOKINETICS_EXPORT ModelBase::StaticParameterValuesType convertArrayToParameter(itk::Array array); + + /* Helper function for conversion of a ModelBase::StaticParameterValuesType(std::vector) into an itk::Array + * Iterates through vector and sets value as array element.*/ + MITKPHARMACOKINETICS_EXPORT itk::Array convertParameterToArray(ModelBase::StaticParameterValuesType); +} + +#endif diff --git a/Modules/Pharmacokinetics/include/mitkAreaUnderFirstMomentDescriptionParameter.h b/Modules/Pharmacokinetics/include/mitkAreaUnderFirstMomentDescriptionParameter.h new file mode 100644 index 0000000000..e9de05ad23 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkAreaUnderFirstMomentDescriptionParameter.h @@ -0,0 +1,33 @@ +#ifndef MITKAREAUNDERFIRSTMOMENTDESCRIPTIONPARAMETER_H +#define MITKAREAUNDERFIRSTMOMENTDESCRIPTIONPARAMETER_H + +#include "mitkCurveDescriptionParameterBase.h" + +namespace mitk +{ + + /** Description parameter that computes the area under the curve */ + class MITKPHARMACOKINETICS_EXPORT AreaUnderFirstMomentDescriptionParameter : public mitk::CurveDescriptionParameterBase + { + public: + typedef mitk::AreaUnderFirstMomentDescriptionParameter Self; + typedef CurveDescriptionParameterBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + virtual DescriptionParameterNamesType GetDescriptionParameterName() const override; + + protected: + static const std::string PARAMETER_NAME; + + AreaUnderFirstMomentDescriptionParameter(); + virtual ~AreaUnderFirstMomentDescriptionParameter(); + + virtual DescriptionParameterResultsType ComputeCurveDescriptionParameter(const CurveType& curve, const CurveGridType& grid) const override; + + }; +} + +#endif // MITKAREAUNDERFIRSTMOMENTDESCRIPTIONPARAMETER_H diff --git a/Modules/Pharmacokinetics/include/mitkAreaUnderTheCurveDescriptionParameter.h b/Modules/Pharmacokinetics/include/mitkAreaUnderTheCurveDescriptionParameter.h new file mode 100644 index 0000000000..f4e58f4e70 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkAreaUnderTheCurveDescriptionParameter.h @@ -0,0 +1,49 @@ +/*=================================================================== + +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 MITKAREAUNDERTHECURVEDESCRIPTIONPARAMETER_H +#define MITKAREAUNDERTHECURVEDESCRIPTIONPARAMETER_H + +#include "mitkCurveDescriptionParameterBase.h" + +namespace mitk +{ + + /** Description parameter that computes the area under the curve */ + class MITKPHARMACOKINETICS_EXPORT AreaUnderTheCurveDescriptionParameter : public mitk::CurveDescriptionParameterBase + { + public: + typedef mitk::AreaUnderTheCurveDescriptionParameter Self; + typedef CurveDescriptionParameterBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + virtual DescriptionParameterNamesType GetDescriptionParameterName() const override; + + protected: + static const std::string PARAMETER_NAME; + + AreaUnderTheCurveDescriptionParameter(); + virtual ~AreaUnderTheCurveDescriptionParameter(); + + virtual DescriptionParameterResultsType ComputeCurveDescriptionParameter(const CurveType& curve, const CurveGridType& grid) const override; + + }; +} + +#endif // MITKAREAUNDERTHECURVEDESCRIPTIONPARAMETER_H diff --git a/Modules/Pharmacokinetics/include/mitkAterialInputFunctionGenerator.h b/Modules/Pharmacokinetics/include/mitkAterialInputFunctionGenerator.h new file mode 100644 index 0000000000..ee12ecfcc7 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkAterialInputFunctionGenerator.h @@ -0,0 +1,111 @@ +/*=================================================================== + + 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 ATERIALINPUTFUNCTIONGENERATOR_H +#define ATERIALINPUTFUNCTIONGENERATOR_H + +#include +#include "mitkAIFBasedModelBase.h" +#include "MitkPharmacokineticsExports.h" + + +namespace mitk +{ + /** \class AterialInputFunctionGenerator + * \brief Compute the Aterial Input Function from a given dynamic image and a mask defining the tumour supplying artery + * + * The AterialInputFunctionGenerator takes a given 4D dynamic image and a corresponding mask and returns an array of the averaged values and + * an array of the corresponding TimeGrid + * within the mask over time. No conversion is performed, so conversion from signal to concentration has to be performed in advanced + * and the resulting image is fed into the Generator. + * The generator checks wether both image and mask are set and passes them to the itkMaskedNaryStatisticsImageFilter and the mitkExtractTimeGrid, to + * calculate the mean of every time slice within the ROI and extract the corresponding time grid from the date set. + */ + class MITKPHARMACOKINETICS_EXPORT AterialInputFunctionGenerator : public itk::Object + { + public: + + mitkClassMacroItkParent(AterialInputFunctionGenerator, itk::Object); + itkNewMacro(Self); + + /** @brief Setter and Getter for Input Image for calculation of AIF, already converted to concentrations + * Getter calls CheckValidInputs() and CalculateAIFAndGetResult() if HasOutdatedResults() is true */ + itkSetConstObjectMacro(DynamicImage, Image); + itkGetConstObjectMacro(DynamicImage, Image); + + /** @brief Setter and Getter for mask defining the tumour feeding atery + * Getter calls CheckValidInputs() and CalculateAIFAndGetResult() if HasOutdatedResults() is true */ + itkSetConstObjectMacro(Mask, Image); + itkGetConstObjectMacro(Mask, Image); + + /** @brief Setter and Getter for the hematocritlevel, important for conversion to plasma curve*/ + itkSetMacro(HCL, double); + itkGetConstReferenceMacro(HCL, double); + + //Common Value for Hematocrit level is 0.45 + static const double DEFAULT_HEMATOCRIT_LEVEL; + + void SetDefaultHematocritLevel() + { + this->m_HCL = DEFAULT_HEMATOCRIT_LEVEL; + }; + double GetDefaultHematocritLevel() + { + return DEFAULT_HEMATOCRIT_LEVEL; + } + + AIFBasedModelBase::AterialInputFunctionType GetAterialInputFunction(); + ModelBase::TimeGridType GetAterialInputFunctionTimeGrid(); + + protected: + AterialInputFunctionGenerator() + { + m_Mask = NULL; + m_DynamicImage = NULL; + this->SetDefaultHematocritLevel(); + }; + + ~AterialInputFunctionGenerator() {}; + + //template + //void DoCalculateAIF(itk::Image* image); + + /** @brief Passes m_DynamicImage and m_Mask to the itkMaskedNaryStatisticsImageFilter and mitkExtractTimeGrid + * and inserts the result into m_AIFValues and m_AIFTimeGrid and modiefies the Timestamp*/ + virtual void CalculateAIFAndGetResult(); + + /** @brief Makes sure that m_DynamicImage and m_Mask are set */ + virtual void CheckValidInputs() const; + + bool HasOutdatedResults(); + + + itk::TimeStamp m_GenerationTimeStamp; + + private: + Image::ConstPointer m_DynamicImage; + Image::ConstPointer m_Mask; + + + AIFBasedModelBase::AterialInputFunctionType m_AIFValues; + ModelBase::TimeGridType m_AIFTimeGrid; + + double m_HCL; + }; + +} + +#endif // ATERIALINPUTFUNCTIONGENERATOR_H diff --git a/Modules/Pharmacokinetics/include/mitkConcentrationCurveGenerator.h b/Modules/Pharmacokinetics/include/mitkConcentrationCurveGenerator.h new file mode 100644 index 0000000000..2f44a4b1a3 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkConcentrationCurveGenerator.h @@ -0,0 +1,146 @@ +/*=================================================================== + +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 CONCENTRATIONCURVEGENERATOR_H +#define CONCENTRATIONCURVEGENERATOR_H + +#include +#include +#include "mitkConvertToConcentrationAbsoluteFunctor.h" +#include "mitkConvertToConcentrationRelativeFunctor.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk { + +/** \class ConcentrationCurveGenerator +* \brief Converts a given 4D mitk::Image with MR signal values into a 4D mitk::Image with corresponding contrast agent concentration values +* +* From a given 4D image, the Generator takes the 3D image of the first time point as baseline image. It then loops over all time steps, casts +* the current 3D image to itk and passes it to the ConvertToconcentrationFunctor. The returned 3D image has now values of concentration type and is stored at its timepoint +* in the return image. +*/ +class MITKPHARMACOKINETICS_EXPORT ConcentrationCurveGenerator : public itk::Object +{ +public: + + mitkClassMacroItkParent(ConcentrationCurveGenerator, itk::Object); + itkNewMacro(Self); + + //typedef itk::Image ImageType; + typedef itk::Image ConvertedImageType; + + + /** Getter and Setter for 4D mitk::Image*/ + itkSetObjectMacro(DynamicImage,Image); + itkGetConstObjectMacro(DynamicImage,Image); + + /** Parameters Relevant for conversion Calculation; Have to be Set externally (Sequence Dependend)*/ + itkSetMacro(RelaxationTime, double); + itkGetConstReferenceMacro(RelaxationTime, double); + + itkSetMacro(Relaxivity, double); + itkGetConstReferenceMacro(Relaxivity, double); + + itkSetMacro(RecoveryTime, double); + itkGetConstReferenceMacro(RecoveryTime, double); + + itkSetMacro(FlipAngle, double); + itkGetConstReferenceMacro(FlipAngle, double); + + itkSetMacro(Factor, double); + itkGetConstReferenceMacro(Factor, double); + + /** Getter and Setter for T10 Map image*/ + itkSetObjectMacro(T10Image,Image); + itkGetConstObjectMacro(T10Image,Image); + + itkSetMacro(T2Factor, double); + itkGetConstReferenceMacro(T2Factor, double); + + itkSetMacro(T2EchoTime, double); + itkGetConstReferenceMacro(T2EchoTime, double); + + /** @brief Calls Convert and returns the 4D mitk::image in Concentration units*/ + + itkSetMacro(isTurboFlashSequence,bool); + itkGetConstReferenceMacro(isTurboFlashSequence,bool); + + itkSetMacro(AbsoluteSignalEnhancement,bool); + itkGetConstReferenceMacro(AbsoluteSignalEnhancement,bool); + + itkSetMacro(RelativeSignalEnhancement,bool); + itkGetConstReferenceMacro(RelativeSignalEnhancement,bool); + + itkSetMacro(UsingT1Map,bool); + itkGetConstReferenceMacro(UsingT1Map,bool); + + + itkSetMacro(isT2weightedImage,bool); + itkGetConstReferenceMacro(isT2weightedImage,bool); + + Image::Pointer GetConvertedImage(); + +protected: + + ConcentrationCurveGenerator(); + ~ConcentrationCurveGenerator(); + + template + mitk::Image::Pointer convertToConcentration(mitk::Image::Pointer inputImage,mitk::Image::Pointer baselineImage); + + + /** Calls ConvertToconcentrationFunctor for passed 3D itk::image*/ +mitk::Image::Pointer ConvertSignalToConcentrationCurve(mitk::Image::Pointer inputImage, mitk::Image::Pointer baselineImage); + + + + /** @brief Takes the 3D image of the first timepoint to set as baseline image*/ + void PrepareBaselineImage(); + + /** @brief loops over all timepoints, casts the current timepoint 3D mitk::image to itk and passes it to ConvertSignalToConcentrationCurve */ + virtual void Convert(); + + +private: + Image::Pointer m_DynamicImage; + Image::Pointer m_BaselineImage; + Image::Pointer m_T10Image; + + Image::Pointer m_ConvertedImage; + + bool m_isT2weightedImage; + + bool m_isTurboFlashSequence; + bool m_AbsoluteSignalEnhancement; + bool m_RelativeSignalEnhancement; + bool m_UsingT1Map; + + double m_Factor; + //=Repetition Time TR + double m_RecoveryTime; + //= pre-CA T1 time + double m_RelaxationTime; + //= contrast agent relaxivity + double m_Relaxivity; + + double m_FlipAngle; + + double m_T2Factor; + double m_T2EchoTime; +}; + +} +#endif // CONCENTRATIONCURVEGENERATOR_H diff --git a/Modules/Pharmacokinetics/include/mitkConcreteAIFBasedModelFactory.h b/Modules/Pharmacokinetics/include/mitkConcreteAIFBasedModelFactory.h new file mode 100644 index 0000000000..1a4c87d2d4 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkConcreteAIFBasedModelFactory.h @@ -0,0 +1,76 @@ +/*=================================================================== + +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 MITK_CONCRETE_AIF_BASED_MODEL_FACTORY_H +#define MITK_CONCRETE_AIF_BASED_MODEL_FACTORY_H + +#include "mitkConcreteModelFactoryBase.h" +#include "mitkAIFParametrizerHelper.h" + +namespace mitk +{ + + template + class ConcreteAIFBasedModelFactory : public + mitk::ConcreteModelFactoryBase + { + public: + mitkClassMacro(ConcreteAIFBasedModelFactory, + ConcreteModelFactoryBase); + + typedef typename Superclass::ModelType ModelType; + typedef TModelParameterizer ModelParameterizerType; + + protected: + virtual ModelParameterizerBase::Pointer DoCreateParameterizer(const modelFit::ModelFitInfo* fit) + const + { + mitk::ModelParameterizerBase::Pointer result; + + typename ModelParameterizerType::Pointer modelParameterizer = + ModelParameterizerType::New(); + + modelFit::StaticParameterMap::ValueType aif = fit->staticParamMap.Get( + ModelType::NAME_STATIC_PARAMETER_AIF); + + modelParameterizer->SetAIF(mitk::convertParameterToArray(aif)); + + modelFit::StaticParameterMap::ValueType aifGrid = fit->staticParamMap.Get( + ModelType::NAME_STATIC_PARAMETER_AIFTimeGrid); + modelParameterizer->SetAIFTimeGrid(mitk::convertParameterToArray(aifGrid)); + + result = modelParameterizer.GetPointer(); + + return result; + }; + + ConcreteAIFBasedModelFactory() + { + }; + + virtual ~ConcreteAIFBasedModelFactory() + { + }; + + private: + + //No copy constructor allowed + ConcreteAIFBasedModelFactory(const Self& source); + void operator=(const Self&); //purposely not implemented + + }; + +} +#endif // MITKTWOCOMPARTMENTEXCHANGEMODELFACTORY_H diff --git a/Modules/Pharmacokinetics/include/mitkConvertT2ConcentrationFunctor.h b/Modules/Pharmacokinetics/include/mitkConvertT2ConcentrationFunctor.h new file mode 100644 index 0000000000..71034c09a6 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkConvertT2ConcentrationFunctor.h @@ -0,0 +1,50 @@ +#ifndef MITKCONVERTT2CONCENTRATIONFUNCTOR +#define MITKCONVERTT2CONCENTRATIONFUNCTOR + +#include "MitkPharmacokineticsExports.h" + +namespace mitk { + + template + class MITKPHARMACOKINETICS_EXPORT ConvertT2ConcentrationFunctor + { + + public: + ConvertT2ConcentrationFunctor(): m_k(0.0), m_TE(0.0) {} ; + ~ConvertT2ConcentrationFunctor() {}; + + void initialize(double factor, double TE) + { + + this->m_k = factor; + this->m_TE = TE; + } + + bool operator!=( const ConvertT2ConcentrationFunctor & other)const + { + return !(*this == other); + } + bool operator==( const ConvertT2ConcentrationFunctor & other) const + { + return (this->m_k == other.m_k && this->m_TE == other.m_TE); + } + + inline TOutputpixel operator()( const TInputPixel1 & value, const TInputPixel2 & baseline) + { + TOutputpixel concentration(0); + if(value !=0 && baseline != 0) + { + concentration = this->m_k / this->m_TE * log((double)(value- baseline)) ; + } + return concentration; + } + + private: + double m_k; + double m_TE; + + }; + +} +#endif // MITKCONVERTT2CONCENTRATIONFUNCTOR + diff --git a/Modules/Pharmacokinetics/include/mitkConvertToConcentrationAbsoluteFunctor.h b/Modules/Pharmacokinetics/include/mitkConvertToConcentrationAbsoluteFunctor.h new file mode 100644 index 0000000000..45913358c0 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkConvertToConcentrationAbsoluteFunctor.h @@ -0,0 +1,46 @@ +#ifndef mitkConvertToConcentrationAbsoluteFunctor_h +#define mitkConvertToConcentrationAbsoluteFunctor_h + +#include "MitkPharmacokineticsExports.h" + +namespace mitk { + + template + class MITKPHARMACOKINETICS_EXPORT ConvertToConcentrationAbsoluteFunctor + { + + public: + ConvertToConcentrationAbsoluteFunctor(): m_k(0.0) {} ; + ~ConvertToConcentrationAbsoluteFunctor() {}; + + void initialize(double factor) + { + + m_k = factor; + } + + bool operator!=( const ConvertToConcentrationAbsoluteFunctor & other)const + { + return !(*this == other); + } + bool operator==( const ConvertToConcentrationAbsoluteFunctor & other) const + { + return (this->m_k == other.m_k); + } + + inline TOutputpixel operator()( const TInputPixel1 & value, const TInputPixel2 & baseline) + { + TOutputpixel concentration(0); + + concentration = this->m_k * (double)(value- baseline) ; + + return concentration; + } + + private: + double m_k; + + }; + +} +#endif // mitkConvertToConcentrationAbsoluteFunctor_h diff --git a/Modules/Pharmacokinetics/include/mitkConvertToConcentrationRelativeFunctor.h b/Modules/Pharmacokinetics/include/mitkConvertToConcentrationRelativeFunctor.h new file mode 100644 index 0000000000..0958364b64 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkConvertToConcentrationRelativeFunctor.h @@ -0,0 +1,49 @@ +#ifndef mitkConvertToConcentrationRelativeFunctor_h +#define mitkConvertToConcentrationRelativeFunctor_h + +#include "MitkPharmacokineticsExports.h" + +namespace mitk { + + template + class MITKPHARMACOKINETICS_EXPORT ConvertToConcentrationRelativeFunctor + { + + public: + ConvertToConcentrationRelativeFunctor(): m_k(0.0) {} ; + ~ConvertToConcentrationRelativeFunctor() {}; + + void initialize(double factor) + { + + m_k = factor; + } + + bool operator!=( const ConvertToConcentrationRelativeFunctor & other)const + { + return !(*this == other); + } + bool operator==( const ConvertToConcentrationRelativeFunctor & other) const + { + return (this->m_k == other.m_k); + } + + inline TOutputpixel operator()( const TInputPixel1 & value, const TInputPixel2 & baseline) + { + TOutputpixel concentration(0); + + if(baseline != 0) + { + concentration = this->m_k * (double)(value- baseline)/baseline ; + } + + return concentration; + } + + private: + double m_k; + + }; + +} +#endif // mitkConvertToConcentrationRelativeFunctor_h diff --git a/Modules/Pharmacokinetics/include/mitkConvertToConcentrationTurboFlashFunctor.h b/Modules/Pharmacokinetics/include/mitkConvertToConcentrationTurboFlashFunctor.h new file mode 100644 index 0000000000..599bc3a4dc --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkConvertToConcentrationTurboFlashFunctor.h @@ -0,0 +1,55 @@ +#ifndef MITKCONVERTTOCONCENTRATIONTURBOFLASCHFUNCTOR_H +#define MITKCONVERTTOCONCENTRATIONTURBOFLASCHFUNCTOR_H + +#include "MitkPharmacokineticsExports.h" + +namespace mitk { + + template + class MITKPHARMACOKINETICS_EXPORT ConvertToConcentrationTurboFlashFunctor + { + + public: + ConvertToConcentrationTurboFlashFunctor() : m_Trec(0), m_alpha(0), m_T10(0) {}; + ~ConvertToConcentrationTurboFlashFunctor() {}; + + void initialize(double relaxationtime, double relaxivity, double recoverytime) + { + m_Trec = relaxationtime; + m_alpha = relaxivity; + m_T10 = recoverytime; + } + + bool operator!=( const ConvertToConcentrationTurboFlashFunctor & other)const + { + return !(*this == other); + } + bool operator==( const ConvertToConcentrationTurboFlashFunctor & other) const + { + return (this->m_Trec == other.m_Trec) && (this->m_alpha == other.m_alpha) && (this->m_T10 == other.m_T10); + } + + inline TOutputpixel operator()( const TInputPixel1 & value, const TInputPixel2 & baseline) + { + TOutputpixel concentration(0); + + + //Only for TurboFLASH sequencen + if (baseline != 0 && ((double)value/baseline - exp(m_Trec/m_T10) * ((double)value/baseline - 1)) > 0 ) + { + concentration = -1 / (m_Trec * m_alpha) * log((double)value/baseline - exp(m_Trec/m_T10) * ((double)value/baseline - 1)); + } + + + return concentration; + } + + private: + double m_Trec; + double m_alpha; + double m_T10; + }; + +} + +#endif // MITKCONVERTTOCONCENTRATIONTURBOFLASCHFUNCTOR_H diff --git a/Modules/Pharmacokinetics/include/mitkConvertToConcentrationViaT1Functor.h b/Modules/Pharmacokinetics/include/mitkConvertToConcentrationViaT1Functor.h new file mode 100644 index 0000000000..780d6b704d --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkConvertToConcentrationViaT1Functor.h @@ -0,0 +1,67 @@ +#ifndef MITKCONVERTTOCONCENTRATIONVIAT1CALCFUNCTOR_H +#define MITKCONVERTTOCONCENTRATIONVIAT1CALCFUNCTOR_H + +#include "itkMath.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk { + + template + class MITKPHARMACOKINETICS_EXPORT ConvertToConcentrationViaT1CalcFunctor + { + + public: + ConvertToConcentrationViaT1CalcFunctor(): m_relaxivity(0.0), m_TR(0.0), m_flipangle(0.0) {}; + ~ConvertToConcentrationViaT1CalcFunctor() {}; + + void initialize(double relaxivity, double TR, double flipangle) + { + + m_relaxivity = relaxivity; + m_TR = TR; + m_flipangle = flipangle; + } + + bool operator!=( const ConvertToConcentrationViaT1CalcFunctor & other) const + { + return !(*this == other); + + } + bool operator==( const ConvertToConcentrationViaT1CalcFunctor & other) const + { + return (this->m_relaxivity == other.m_relaxivity) && (this->m_TR == other.m_TR) && (this->m_flipangle == other.m_flipangle); + } + + + inline TOutputpixel operator()( const TInputPixel1 & value, const TInputPixel2 & baseline, const TInputPixel3 & nativeT1) + { + TOutputpixel concentration(0); + double R10, R1; + if (baseline !=0 && nativeT1 != 0 && value != 0) + { + double s = (double) value/baseline; + R10 = (double) 1/nativeT1; + double tmp1 = log(1-s + s*exp(-R10*m_TR) - exp(-R10*m_TR)* cos(m_flipangle)); + double tmp2 = (1-s*cos(m_flipangle) + s*exp(-R10*m_TR)*cos(m_flipangle) - exp(-R10*m_TR)* cos(m_flipangle)); + + R1 = (double) -1/m_TR * tmp1/tmp2 ; + + concentration = (double) (R1 - R10)/ m_relaxivity; + } + else + { + concentration = 0; + } + + return concentration; + } + private: + double m_relaxivity; + double m_TR; + double m_flipangle; + + }; + +} +#endif // MITKCONVERTTOCONCENTRATIONVIAT1CALCFUNCTOR_H diff --git a/Modules/Pharmacokinetics/include/mitkConvolutionHelper.h b/Modules/Pharmacokinetics/include/mitkConvolutionHelper.h new file mode 100644 index 0000000000..8c32455899 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkConvolutionHelper.h @@ -0,0 +1,157 @@ +/*=================================================================== + +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 mitkConvolutionHelper_h +#define mitkConvolutionHelper_h + +#include "itkArray.h" +#include "mitkAIFBasedModelBase.h" +#include +#include "MitkPharmacokineticsExports.h" + +namespace mitk { +/** @namespace convolution + * @brief Helper for itk implementation of vnl fourier transformation + * This namespace provides functions for the preperation of vnl_fft_1d, including a wrapper + * for wrapping the convolution kernel (turning it inside out) and a function for zeropadding + * to avoid convolution artefacts. */ + namespace convolution { + + /** Some typedefs concerning data structures needed for vnl_fft_1d, which has vnl_vector< vcl_complex< double > > + * as output typ of the forward transformation fwd_transform. Input is of type vnl_vector< vcl_complex< T > > + * but since itk::Array is derived from vnl_vector, this works as well*/ + + + + /** @brief Function that wraps the kernel */ +inline itk::Array wrap1d(itk::Array kernel) + { + int dim = kernel.GetNumberOfElements(); + itk::Array wrappedKernel(dim); + wrappedKernel.fill(0.); + for(int i=0; i< dim; ++i) + { + wrappedKernel.SetElement(i, kernel.GetElement((i+(dim/2))%dim)); + } + + return wrappedKernel; + } + + /** @brief Fuction for zeropadding (adding zeros) of an Array/vnl_vector, so that is has size paddedDimensions + * @param paddedDimensions Dimensions that the Array should have after padding (convolution dimensions) + * \remark dim = Dimensions of padded image --> PaddedDimension + * \remark m dimensions of larger image + * \remark n dimensions of image to be padded --> InitialDimension*/ + inline itk::Array zeropadding1d(itk::Array unpaddedSpectrum, int paddedDimension) + { + + int initialDimension = unpaddedSpectrum.GetNumberOfElements(); + + itk::Array paddedSpectrum(paddedDimension); + paddedSpectrum.fill(0.); + + if(paddedDimension > initialDimension) + { + unsigned int padding = paddedDimension - initialDimension; + + for(int i=0; i unpadAndScale(itk::Array convolutionResult, int initialDimension) + { + int transformationDimension = convolutionResult.size(); + unsigned int padding = transformationDimension - initialDimension; + + itk::Array scaledResult(initialDimension); + scaledResult.fill(0.0); + + for(int i = 0; i >, ready to + * be entered in fwd_transform*/ + + inline void prepareConvolution(const itk::Array& kernel, const itk::Array& spectrum, itk::Array& preparedKernel, itk::Array& preparedSpectrum ){ + int convolutionDimensions = kernel.GetSize() + spectrum.GetSize(); + +// itk::Array paddedKernel = zeropadding1d(kernel,convolutionDimensions); + preparedKernel=zeropadding1d(kernel,convolutionDimensions); + + preparedSpectrum = zeropadding1d(spectrum,convolutionDimensions); +// preparedKernel = wrap1d(paddedKernel); + } + + } + + inline itk::Array convoluteAIFWithExponential(mitk::ModelBase::TimeGridType timeGrid, mitk::AIFBasedModelBase::AterialInputFunctionType aif, double lambda) + { + /** @brief Iterative Formula to Convolve aif(t) with an exponential Residuefunction R(t) = exp(lambda*t) + **/ + typedef itk::Array ConvolutionResultType; + ConvolutionResultType convolution(timeGrid.GetSize()); + convolution.fill(0.0); + + convolution(0) = 0; + for(int i = 0; i< (timeGrid.GetSize()-1); ++i) + { + double dt = timeGrid(i+1) - timeGrid(i); + double m = (aif(i+1) - aif(i))/dt; + double edt = exp(-lambda *dt); + + convolution(i+1) =edt * convolution(i) + + (aif(i) - m*timeGrid(i))/lambda * (1 - edt ) + + m/(lambda * lambda) * ((lambda * timeGrid(i+1) - 1) - edt*(lambda*timeGrid(i) -1)); + + } + return convolution; + } + + + inline itk::Array convoluteAIFWithConstant(mitk::ModelBase::TimeGridType timeGrid, mitk::AIFBasedModelBase::AterialInputFunctionType aif, double constant) + { + /** @brief Iterative Formula to Convolve aif(t) with a constant value by linear interpolation of the Aif between sampling points + **/ + typedef itk::Array ConvolutionResultType; + ConvolutionResultType convolution(timeGrid.GetSize()); + convolution.fill(0.0); + + convolution(0) = 0; + for(int i = 0; i< (timeGrid.GetSize()-1); ++i) + { + double dt = timeGrid(i+1) - timeGrid(i); + double m = (aif(i+1) - aif(i))/dt; + + convolution(i+1) = convolution(i) + constant * (aif(i)*dt + m*timeGrid(i)*dt + m/2*(timeGrid(i+1)*timeGrid(i+1) - timeGrid(i)*timeGrid(i))); + + } + return convolution; + } + +} + +#endif // mitkConvolutionHelper_h diff --git a/Modules/Pharmacokinetics/include/mitkCurveDescriptionParameterBase.h b/Modules/Pharmacokinetics/include/mitkCurveDescriptionParameterBase.h new file mode 100644 index 0000000000..086f89d029 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkCurveDescriptionParameterBase.h @@ -0,0 +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. + +===================================================================*/ + +#ifndef CURVEDESCRIPTIONPARAMETERBASE_H +#define CURVEDESCRIPTIONPARAMETERBASE_H + +#include + +#include +#include +#include +#include +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + /** Base class for functor that compute descriptive values for + a curve (e.g. like Area under the Curve, Time to peek, maximum,...) + @remark The derived classes must be implemented thread safe because GetCurveDescriptionParameter() + and GetDescriptionParameterName() of one instance may be called in + multi-threaded context (e.g. DescriptionParameterImageGeneratorBase + and derived classes). */ +class MITKPHARMACOKINETICS_EXPORT CurveDescriptionParameterBase : public itk::Object + { + public: + typedef CurveDescriptionParameterBase Self; + typedef itk::Object Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkTypeMacro(CurveDescriptionParameterBase, itk::Object) + + typedef itk::Array CurveType; + typedef itk::Array CurveGridType; + + typedef double CurveDescriptionParameterResultType; + typedef std::string CurveDescriptionParameterNameType; + + typedef std::vector DescriptionParameterResultsType; + typedef std::vector DescriptionParameterNamesType; + + /** Returns the concrete description values for a curve. + * @pre Curve value vector and curve grid must have the same size*/ + DescriptionParameterResultsType GetCurveDescriptionParameter(const CurveType& curve, const CurveGridType& grid) const; + + /**Return the names of all descrition values that will be computed by the class. + * @post The order of names equales the order of the results of GetCurveDescriptionParameter().*/ + virtual DescriptionParameterNamesType GetDescriptionParameterName() const = 0 ; + + protected: + + /** Slot to implement the computation of the descriptor values.*/ + virtual DescriptionParameterResultsType ComputeCurveDescriptionParameter(const CurveType& curve, const CurveGridType& grid) const = 0; + + CurveDescriptionParameterBase(); + virtual ~CurveDescriptionParameterBase(); + + private: + + //No copy constructor allowed + CurveDescriptionParameterBase(const Self& source); + void operator=(const Self&); //purposely not implemented + + }; +} + +#endif // CURVEDESCRIPTIONPARAMETERBASE_H diff --git a/Modules/Pharmacokinetics/include/mitkCurveParameterFunctor.h b/Modules/Pharmacokinetics/include/mitkCurveParameterFunctor.h new file mode 100644 index 0000000000..0ae6ca5ffc --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkCurveParameterFunctor.h @@ -0,0 +1,77 @@ +/*=================================================================== + +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 CURVE_PARAMETER_FUNCTOR_H +#define CURVE_PARAMETER_FUNCTOR_H + +#include "mitkCurveDescriptionParameterBase.h" +#include "mitkSimpleFunctorBase.h" +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + + /**Functor for the curve description values by using the itkMulitOutputNaryImageFilter. + * You may register any number of CurveDescriptionParamterBase instances to the functor. + * The Functor will compute all values. + * @warning the functor must be threadsafe and so must be the registered CurveDescriptionParamterBase instances.*/ + class MITKPHARMACOKINETICS_EXPORT CurveParameterFunctor : public SimpleFunctorBase + { + public: + typedef CurveParameterFunctor Self; + typedef itk::Object Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkFactorylessNewMacro(Self); + itkTypeMacro(CurveParameterFunctor, SimpleFunctorBase); + + typedef CurveDescriptionParameterBase::CurveDescriptionParameterNameType ParameterNameType; + typedef CurveDescriptionParameterBase::DescriptionParameterNamesType ParameterNamesType; + using GridArrayType = SimpleFunctorBase::GridArrayType; + + virtual SimpleFunctorBase::OutputPixelVectorType Compute(const InputPixelVectorType & value) const override; + + virtual unsigned int GetNumberOfOutputs() const override; + + virtual GridArrayType GetGrid() const override; + itkSetMacro(Grid, GridArrayType); + + ParameterNamesType GetDescriptionParameterNames() const; + + /**@warning Teh function is currently not thread safe. + @todo reimplement with shareable lock to allow other class methods to be used parallel but lock this one exclusively.*/ + void ResetDescriptionParameters(); + /**@warning Teh function is currently not thread safe. + @todo reimplement with shareable lock to allow other class methods to be used parallel but lock this one exclusively.*/ + void RegisterDescriptionParameter(const ParameterNameType& parameterName, CurveDescriptionParameterBase* parameterFunction); + /**@warning Teh function is currently not thread safe. + @todo reimplement with shareable lock to allow other class methods to be used parallel but lock this one exclusively.*/ + const CurveDescriptionParameterBase* GetDescriptionParameterFunction(const ParameterNameType& parameterName) const; + + protected: + CurveParameterFunctor(); + ~CurveParameterFunctor(); + + private: + typedef std::map DescriptionParameterMapType; + DescriptionParameterMapType m_DescriptorMap; + GridArrayType m_Grid; + }; + +} + +#endif // CURVE_PARAMETER_FUNCTOR_H diff --git a/Modules/Pharmacokinetics/include/mitkDescriptionParameterImageGeneratorBase.h b/Modules/Pharmacokinetics/include/mitkDescriptionParameterImageGeneratorBase.h new file mode 100644 index 0000000000..1c74f80816 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkDescriptionParameterImageGeneratorBase.h @@ -0,0 +1,67 @@ +/*=================================================================== + +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 __MITK_DESCRIPTION_PARAMETER_IMAGE_GENERATOR_BASE_H_ +#define __MITK_DESCRIPTION_PARAMETER_IMAGE_GENERATOR_BASE_H_ + +#include + +#include "mitkImage.h" + +#include "mitkCurveDescriptionParameterBase.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + class MITKPHARMACOKINETICS_EXPORT DescriptionParameterImageGeneratorBase: public ::itk::Object + { + public: + + mitkClassMacroItkParent(DescriptionParameterImageGeneratorBase, ::itk::Object); + + typedef ScalarType ParameterImagePixelType; + + typedef CurveDescriptionParameterBase::CurveDescriptionParameterNameType ParameterNameType; + + typedef std::map ParameterImageMapType; + + virtual double GetProgress() const = 0; + + void Generate(); + + ParameterImageMapType GetParameterImages(); + + protected: + DescriptionParameterImageGeneratorBase(); + virtual ~DescriptionParameterImageGeneratorBase(); + + virtual bool HasOutdatedResult() const; + + virtual void CheckValidInputs() const; + virtual void DoParameterCalculationAndGetResults(ParameterImageMapType& parameterImages) = 0; + + itk::TimeStamp m_GenerationTimeStamp; + + private: + + ParameterImageMapType m_ParameterImageMap; + + }; + +} + +#endif //__MITK_DESCRIPTION_PARAMETER_IMAGE_GENERATOR_BASE_H_ diff --git a/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModel.h b/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModel.h new file mode 100644 index 0000000000..2473c86144 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModel.h @@ -0,0 +1,135 @@ +/*=================================================================== + +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 DESCRIPTIVEPHARMACOKINETICBRIXMODEL_H +#define DESCRIPTIVEPHARMACOKINETICBRIXMODEL_H + +#include + +#include "mitkModelBase.h" +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + + class MITKPHARMACOKINETICS_EXPORT DescriptivePharmacokineticBrixModel : public ModelBase + { + + public: + typedef DescriptivePharmacokineticBrixModel Self; + typedef ModelBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + /** Method for creation through the object factory. */ + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(DescriptivePharmacokineticBrixModel, ModelBase); + + static const std::string MODEL_DISPLAY_NAME; + + static const std::string NAME_PARAMETER_A; + static const std::string NAME_PARAMETER_kep; + static const std::string NAME_PARAMETER_kel; + static const std::string NAME_PARAMETER_tlag; + static const std::string NAME_STATIC_PARAMETER_Tau; + static const std::string NAME_STATIC_PARAMETER_S0; + + static const std::string UNIT_PARAMETER_A; + static const std::string UNIT_PARAMETER_kep; + static const std::string UNIT_PARAMETER_kel; + static const std::string UNIT_PARAMETER_tlag; + static const std::string UNIT_STATIC_PARAMETER_Tau; + static const std::string UNIT_STATIC_PARAMETER_S0; + + static const unsigned int POSITION_PARAMETER_A; + static const unsigned int POSITION_PARAMETER_kep; + static const unsigned int POSITION_PARAMETER_kel; + + //tlag in minutes + static const unsigned int POSITION_PARAMETER_tlag; + + static const unsigned int NUMBER_OF_PARAMETERS; + + itkSetMacro(Tau, double); + itkGetConstReferenceMacro(Tau, double); + + itkSetMacro(S0, double); + itkGetConstReferenceMacro(S0, double); + + virtual std::string GetModelDisplayName() const override; + + virtual std::string GetModelType() const override; + + virtual std::string GetXAxisName() const override; + + virtual std::string GetXAxisUnit() const override; + + virtual std::string GetYAxisName() const override; + + virtual std::string GetYAxisUnit() const override; + + virtual ParameterNamesType GetParameterNames() const override; + + virtual ParametersSizeType GetNumberOfParameters() const override; + + virtual ParamterUnitMapType GetParameterUnits() const override; + + + virtual ParameterNamesType GetStaticParameterNames() const override; + virtual ParametersSizeType GetNumberOfStaticParameters() const override; + virtual ParamterUnitMapType GetStaticParameterUnits() const override; + + protected: + DescriptivePharmacokineticBrixModel(); + virtual ~DescriptivePharmacokineticBrixModel(); + + /** + * Actual implementation of the clone method. This method should be reimplemeted + * in subclasses to clone the extra required parameters. + */ + virtual itk::LightObject::Pointer InternalClone() const; + + virtual ModelResultType ComputeModelfunction(const ParametersType& parameters) const override; + + virtual void SetStaticParameter(const ParameterNameType& name, + const StaticParameterValuesType& values) override; + virtual StaticParameterValuesType GetStaticParameterValue(const ParameterNameType& name) const + override; + + + virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; + + private: + /**injection time Tau in minutes [min]*/ + double m_Tau; + + /**Value of the first time step, thus base value to scale the signal. + * Default is 1.*/ + double m_S0; + + //No copy constructor allowed + DescriptivePharmacokineticBrixModel(const Self& source); + void operator=(const Self&); //purposely not implemented + + + }; +} + + +#endif //DESCRIPTIVEPHARMACOKINETICBRIXMODEL_H diff --git a/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelFactory.h b/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelFactory.h new file mode 100644 index 0000000000..abf2721d68 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelFactory.h @@ -0,0 +1,57 @@ +/*=================================================================== + +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 __DESCRIPTIVEPHARMACOKINETICBRIXMODEL_FACTORY_H +#define __DESCRIPTIVEPHARMACOKINETICBRIXMODEL_FACTORY_H + +#include + +#include "mitkConcreteModelFactoryBase.h" +#include "mitkDescriptivePharmacokineticBrixModel.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + + class MITKPHARMACOKINETICS_EXPORT DescriptivePharmacokineticBrixModelFactory : public + ConcreteModelFactoryBase + { + public: + mitkClassMacro(DescriptivePharmacokineticBrixModelFactory, + ConcreteModelFactoryBase); + itkFactorylessNewMacro(Self); + + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + virtual ModelParameterizerBase::Pointer DoCreateParameterizer(const modelFit::ModelFitInfo* fit) + const; + + DescriptivePharmacokineticBrixModelFactory(); + + virtual ~DescriptivePharmacokineticBrixModelFactory(); + + private: + + //No copy constructor allowed + DescriptivePharmacokineticBrixModelFactory(const Self& source); + void operator=(const Self&); //purposely not implemented + }; +} + + +#endif //__DESCRIPTIVEPHARMACOKINETICBRIXMODEL_FACTORY_H diff --git a/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelParameterizer.h b/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelParameterizer.h new file mode 100644 index 0000000000..c2c216409c --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelParameterizer.h @@ -0,0 +1,96 @@ +/*=================================================================== + +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 __DESCRIPTIVEPHARMACOKINETICBRIXMODEL_PARAMETERIZER_H +#define __DESCRIPTIVEPHARMACOKINETICBRIXMODEL_PARAMETERIZER_H + +#include "mitkConcreteModelParameterizerBase.h" +#include "mitkDescriptivePharmacokineticBrixModel.h" + +namespace mitk +{ + /** Parameterizer for the DescriptivePharmacokineticBrixModel that use an image + for initializing the model. This parameterizer is amongst others used for pixel based fiting + strategies. + @sa DescriptivePharmacokineticBrixModelParameterizer*/ + class MITKPHARMACOKINETICS_EXPORT DescriptivePharmacokineticBrixModelParameterizer : public + ConcreteModelParameterizerBase + { + public: + typedef DescriptivePharmacokineticBrixModelParameterizer Self; + typedef ConcreteModelParameterizerBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkTypeMacro(ConcreteModelParameterizerBase, ModelParameterizerBase); + itkNewMacro(Self); + + typedef Superclass::ModelBaseType ModelBaseType; + typedef Superclass::ModelBasePointer ModelBasePointer; + + typedef Superclass::ModelType ModelType; + typedef Superclass::ModelPointer ModelPointer; + + typedef Superclass::StaticParameterValueType StaticParameterValueType; + typedef Superclass::StaticParameterValuesType StaticParameterValuesType; + typedef Superclass::StaticParameterMapType StaticParameterMapType; + + typedef itk::Image BaseImageType; + + typedef Superclass::IndexType IndexType; + + itkSetMacro(Tau, double); + itkGetConstReferenceMacro(Tau, double); + + itkSetConstObjectMacro(BaseImage, BaseImageType); + itkGetConstObjectMacro(BaseImage, BaseImageType); + + /* Returns the global static parameters for the model. + * @remark this default implementation assumes no global static parameters exist. + * Thus an empty map is returned.*/ + virtual StaticParameterMapType GetGlobalStaticParameters() const; + + /* Returns the local static parameters for the model at the given index. + * @remark this default implementation assumes no local static parameters exist. + * Thus an empty map is returned.*/ + virtual StaticParameterMapType GetLocalStaticParameters(const IndexType& currentPosition) const; + + /** This function returns the default parameterization (e.g. initial parametrization for fitting) + defined by the model developer for for the given model.*/ + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + + DescriptivePharmacokineticBrixModelParameterizer(); + + virtual ~DescriptivePharmacokineticBrixModelParameterizer(); + + /**injection time Tau in minutes [min]*/ + double m_Tau; + + /**Pointer to the image that containes the values of the first timestep + (base value of the series that should be modelled)*/ + BaseImageType::ConstPointer m_BaseImage; + + private: + + //No copy constructor allowed + DescriptivePharmacokineticBrixModelParameterizer(const Self& source); + void operator=(const Self&); //purposely not implemented + }; +} + +#endif // __DESCRIPTIVEPHARMACOKINETICBRIXMODEL_PARAMETERIZER_H diff --git a/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer.h b/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer.h new file mode 100644 index 0000000000..7c9f0b0b82 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer.h @@ -0,0 +1,94 @@ +/*=================================================================== + +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 __DESCRIPTIVEPHARMACOKINETICBRIXMODEL_VALUEBASED_PARAMETERIZER_H +#define __DESCRIPTIVEPHARMACOKINETICBRIXMODEL_VALUEBASED_PARAMETERIZER_H + +#include "mitkConcreteModelParameterizerBase.h" + +namespace mitk +{ + /** Parameterizer for the DescriptivePharmacokineticBrixModel that don't use an image + for initializing the model but a single signal value. This parameterizer is amongst + others used for ROI based fiting strategies where no complete image is needed/used. + @sa DescriptivePharmacokineticBrixModelParameterizer*/ + class MITKPHARMACOKINETICS_EXPORT DescriptivePharmacokineticBrixModelValueBasedParameterizer : public + ConcreteModelParameterizerBase + { + public: + typedef DescriptivePharmacokineticBrixModelValueBasedParameterizer Self; + typedef ConcreteModelParameterizerBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkTypeMacro(ConcreteModelParameterizerBase, ModelParameterizerBase); + itkNewMacro(Self); + + typedef Superclass::ModelBaseType ModelBaseType; + typedef Superclass::ModelBasePointer ModelBasePointer; + + typedef Superclass::ModelType ModelType; + typedef Superclass::ModelPointer ModelPointer; + + typedef Superclass::StaticParameterValueType StaticParameterValueType; + typedef Superclass::StaticParameterValuesType StaticParameterValuesType; + typedef Superclass::StaticParameterMapType StaticParameterMapType; + + typedef itk::Image BaseImageType; + + typedef Superclass::IndexType IndexType; + + itkSetMacro(Tau, double); + itkGetConstReferenceMacro(Tau, double); + + itkSetMacro(BaseValue, double); + itkGetConstReferenceMacro(BaseValue, double); + + /* Returns the global static parameters for the model. + * @remark this default implementation assumes no global static parameters exist. + * Thus an empty map is returned.*/ + virtual StaticParameterMapType GetGlobalStaticParameters() const; + + /* Returns the local static parameters for the model at the given index. + * @remark this default implementation assumes no local static parameters exist. + * Thus an empty map is returned.*/ + virtual StaticParameterMapType GetLocalStaticParameters(const IndexType& currentPosition) const; + + /** This function returns the default parameterization (e.g. initial parametrization for fitting) + defined by the model developer for for the given model.*/ + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + + DescriptivePharmacokineticBrixModelValueBasedParameterizer(); + + virtual ~DescriptivePharmacokineticBrixModelValueBasedParameterizer(); + + /**injection time Tau in minutes [min]*/ + double m_Tau; + + /** Contains the base value that should be used by the model.*/ + double m_BaseValue; + + private: + + //No copy constructor allowed + DescriptivePharmacokineticBrixModelValueBasedParameterizer(const Self& source); + void operator=(const Self&); //purposely not implemented + }; +} + +#endif // __DESCRIPTIVEPHARMACOKINETICBRIXMODEL_VALUEBASED_PARAMETERIZER_H diff --git a/Modules/Pharmacokinetics/include/mitkExtendedOneTissueCompartmentModel.h b/Modules/Pharmacokinetics/include/mitkExtendedOneTissueCompartmentModel.h new file mode 100644 index 0000000000..cf032ad43c --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkExtendedOneTissueCompartmentModel.h @@ -0,0 +1,84 @@ +#ifndef MITKEXTENDEDONETISSUECOMPARTMENTMODEL_H +#define MITKEXTENDEDONETISSUECOMPARTMENTMODEL_H + +#include "mitkAIFBasedModelBase.h" +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + /** @class OneTissueCompartmentModel + * @brief Implementation of the Model function of the Tofts pharmacokinetic model, using an Aterial Input Function + * The Model calculates the Concentration-Time-Curve as a convolution of the plasma curve Cp (the AIF) and a tissue specific + * residue function (in this case an exponential: R(t) = ktrans * exp(-ktrans/ve * (t)) ). + * C(t) = vp * Cp(t) + conv(Cp(t),R(t)) + * The parameters ktrans, ve and ve are subject to the fitting routine*/ + + class MITKPHARMACOKINETICS_EXPORT ExtendedOneTissueCompartmentModel : public AIFBasedModelBase + { + + public: + typedef ExtendedOneTissueCompartmentModel Self; + typedef AIFBasedModelBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + /** Method for creation through the object factory. */ + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(ExtendedOneTissueCompartmentModel, ModelBase); + + static const std::string MODEL_DISPLAY_NAME; + + static const std::string NAME_PARAMETER_k1; + static const std::string NAME_PARAMETER_k2; + static const std::string NAME_PARAMETER_VB; + + static const std::string UNIT_PARAMETER_k1; + static const std::string UNIT_PARAMETER_k2; + static const std::string UNIT_PARAMETER_VB; + + static const unsigned int POSITION_PARAMETER_k1; + static const unsigned int POSITION_PARAMETER_k2; + static const unsigned int POSITION_PARAMETER_VB; + + static const unsigned int NUMBER_OF_PARAMETERS; + + virtual std::string GetModelDisplayName() const override; + + virtual std::string GetModelType() const override; + + virtual ParameterNamesType GetParameterNames() const override; + virtual ParametersSizeType GetNumberOfParameters() const override; + + virtual ParamterUnitMapType GetParameterUnits() const override; + + protected: + ExtendedOneTissueCompartmentModel(); + virtual ~ExtendedOneTissueCompartmentModel(); + + /** + * Actual implementation of the clone method. This method should be reimplemeted + * in subclasses to clone the extra required parameters. + */ + virtual itk::LightObject::Pointer InternalClone() const; + + virtual ModelResultType ComputeModelfunction(const ParametersType& parameters) const override; + + virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const override; + + private: + + + //No copy constructor allowed + ExtendedOneTissueCompartmentModel(const Self& source); + void operator=(const Self&); //purposely not implemented + + + + + }; +} + +#endif // MITKEXTENDEDONETISSUECOMPARTMENTMODEL_H diff --git a/Modules/Pharmacokinetics/include/mitkExtendedOneTissueCompartmentModelFactory.h b/Modules/Pharmacokinetics/include/mitkExtendedOneTissueCompartmentModelFactory.h new file mode 100644 index 0000000000..cd57c9499d --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkExtendedOneTissueCompartmentModelFactory.h @@ -0,0 +1,58 @@ +/*=================================================================== + +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 MITKEXTENDEDONETISSUECOMPARTMENTMODELFACTORY_H +#define MITKEXTENDEDONETISSUECOMPARTMENTMODELFACTORY_H + +#include "mitkConcreteAIFBasedModelFactory.h" +#include "mitkExtendedOneTissueCompartmentModel.h" +#include "mitkExtendedOneTissueCompartmentModelParameterizer.h" + +namespace mitk +{ + + + class MITKPHARMACOKINETICS_EXPORT ExtendedOneTissueCompartmentModelFactory : public + mitk::ConcreteAIFBasedModelFactory< ExtendedOneTissueCompartmentModelParameterizer> + { + public: + mitkClassMacro(ExtendedOneTissueCompartmentModelFactory, + ConcreteAIFBasedModelFactory); + itkFactorylessNewMacro(Self); + + typedef Superclass::ModelType ModelType; + typedef Superclass::ModelParameterizerType ModelParameterizerType; + + ConstraintCheckerBase::Pointer CreateDefaultConstraints() const override; + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + + ExtendedOneTissueCompartmentModelFactory(); + + virtual ~ExtendedOneTissueCompartmentModelFactory(); + + private: + + //No copy constructor allowed + ExtendedOneTissueCompartmentModelFactory(const Self& source); + void operator=(const Self&); //purposely not implemented + + }; + +} + +#endif // MITKEXTENDEDONETISSUECOMPARTMENTMODELFACTORY_H diff --git a/Modules/Pharmacokinetics/include/mitkExtendedOneTissueCompartmentModelParameterizer.h b/Modules/Pharmacokinetics/include/mitkExtendedOneTissueCompartmentModelParameterizer.h new file mode 100644 index 0000000000..d0d74e03ee --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkExtendedOneTissueCompartmentModelParameterizer.h @@ -0,0 +1,70 @@ +/*=================================================================== + +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 MITKEXTENDEDONETISSUECOMPARTMENTMODELPARAME_H +#define MITKEXTENDEDONETISSUECOMPARTMENTMODELPARAME_H + +#include "mitkAIFBasedModelParameterizerBase.h" +#include "mitkExtendedOneTissueCompartmentModel.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + + class MITKPHARMACOKINETICS_EXPORT ExtendedOneTissueCompartmentModelParameterizer : public + mitk::AIFBasedModelParameterizerBase + { + public: + typedef ExtendedOneTissueCompartmentModelParameterizer Self; + typedef mitk::AIFBasedModelParameterizerBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkTypeMacro(ExtendedOneTissueCompartmentModelParameterizer, + mitk::AIFBasedModelParameterizerBase); + itkFactorylessNewMacro(Self); + + typedef Superclass::ModelBaseType ModelBaseType; + typedef Superclass::ModelBasePointer ModelBasePointer; + + typedef Superclass::ModelType ModelType; + typedef ModelType::Pointer ModelPointer; + + typedef Superclass::StaticParameterValueType StaticParameterValueType; + typedef Superclass::StaticParameterValuesType StaticParameterValuesType; + typedef Superclass::StaticParameterMapType StaticParameterMapType; + + typedef Superclass::IndexType IndexType; + + /** This function returns the default parameterization (e.g. initial parametrization for fitting) + defined by the model developer for for the given model.*/ + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + ExtendedOneTissueCompartmentModelParameterizer(); + + virtual ~ExtendedOneTissueCompartmentModelParameterizer(); + + private: + + //No copy constructor allowed + ExtendedOneTissueCompartmentModelParameterizer(const Self& source); + void operator=(const Self&); //purposely not implemented + }; +} + +#endif // MITKEXTENDEDONETISSUECOMPARTMENTMODELPARAME_H diff --git a/Modules/Pharmacokinetics/include/mitkExtendedToftsModel.h b/Modules/Pharmacokinetics/include/mitkExtendedToftsModel.h new file mode 100644 index 0000000000..cddc64c4e8 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkExtendedToftsModel.h @@ -0,0 +1,94 @@ +#ifndef MITKEXTENDEDTOFTSMODEL_H +#define MITKEXTENDEDTOFTSMODEL_H + +#include "mitkAIFBasedModelBase.h" +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + /** @class ExtendedToftsModel + * @brief Implementation of the Model function of the Tofts pharmacokinetic model, using an Aterial Input Function + * The Model calculates the Concentration-Time-Curve as a convolution of the plasma curve Cp (the AIF) and a tissue specific + * residue function (in this case an exponential: R(t) = ktrans * exp(-ktrans/ve * (t)) ). + * C(t) = vp * Cp(t) + conv(Cp(t),R(t)) + * The parameters ktrans, ve and ve are subject to the fitting routine*/ + + class MITKPHARMACOKINETICS_EXPORT ExtendedToftsModel : public AIFBasedModelBase + { + + public: + typedef ExtendedToftsModel Self; + typedef AIFBasedModelBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + /** Method for creation through the object factory. */ + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(ExtendedToftsModel, ModelBase); + + static const std::string MODEL_DISPLAY_NAME; + + static const std::string NAME_PARAMETER_Ktrans; + static const std::string NAME_PARAMETER_ve; + static const std::string NAME_PARAMETER_vp; + + static const std::string UNIT_PARAMETER_Ktrans; + static const std::string UNIT_PARAMETER_ve; + static const std::string UNIT_PARAMETER_vp; + + static const unsigned int POSITION_PARAMETER_Ktrans; + static const unsigned int POSITION_PARAMETER_ve; + static const unsigned int POSITION_PARAMETER_vp; + + static const unsigned int NUMBER_OF_PARAMETERS; + + virtual std::string GetModelDisplayName() const override; + + virtual std::string GetModelType() const override; + + virtual ParameterNamesType GetParameterNames() const override; + virtual ParametersSizeType GetNumberOfParameters() const override; + + virtual ParamterUnitMapType GetParameterUnits() const override; + + virtual ParameterNamesType GetDerivedParameterNames() const override; + + virtual ParametersSizeType GetNumberOfDerivedParameters() const override; + virtual ParamterUnitMapType GetDerivedParameterUnits() const override; + + + protected: + ExtendedToftsModel(); + virtual ~ExtendedToftsModel(); + + /** + * Actual implementation of the clone method. This method should be reimplemeted + * in subclasses to clone the extra required parameters. + */ + virtual itk::LightObject::Pointer InternalClone() const; + + virtual ModelResultType ComputeModelfunction(const ParametersType& parameters) const override; + + virtual DerivedParameterMapType ComputeDerivedParameters(const mitk::ModelBase::ParametersType& + parameters) const; + + + virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const override; + + private: + + + //No copy constructor allowed + ExtendedToftsModel(const Self& source); + void operator=(const Self&); //purposely not implemented + + + + + }; +} + +#endif // MITKEXTENDEDTOFTSMODEL_H diff --git a/Modules/Pharmacokinetics/include/mitkExtendedToftsModelFactory.h b/Modules/Pharmacokinetics/include/mitkExtendedToftsModelFactory.h new file mode 100644 index 0000000000..e4e5e49e0f --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkExtendedToftsModelFactory.h @@ -0,0 +1,56 @@ +/*=================================================================== + +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 MITKEXTENDEDTOFTSMODELFACTORY_H +#define MITKEXTENDEDTOFTSMODELFACTORY_H + +#include "mitkConcreteAIFBasedModelFactory.h" +#include "mitkExtendedToftsModel.h" +#include "mitkExtendedToftsModelParameterizer.h" + +namespace mitk +{ + + + class MITKPHARMACOKINETICS_EXPORT ExtendedToftsModelFactory : public + mitk::ConcreteAIFBasedModelFactory + { + public: + mitkClassMacro(ExtendedToftsModelFactory, + ConcreteAIFBasedModelFactory); + itkFactorylessNewMacro(Self); + + using ModelType = Superclass::ModelType; + using ModelParameterizerType = Superclass::ModelParameterizerType; + + ConstraintCheckerBase::Pointer CreateDefaultConstraints() const override; + virtual ParametersType GetDefaultInitialParameterization() const override; + + protected: + + ExtendedToftsModelFactory(); + + virtual ~ExtendedToftsModelFactory() override; + + private: + + //No copy constructor allowed + ExtendedToftsModelFactory(const Self& source); + void operator=(const Self&); //purposely not implemented + + }; + +} +#endif // MITKEXTENDEDTOFTSMODELFACTORY_H diff --git a/Modules/Pharmacokinetics/include/mitkExtendedToftsModelParameterizer.h b/Modules/Pharmacokinetics/include/mitkExtendedToftsModelParameterizer.h new file mode 100644 index 0000000000..c43a773193 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkExtendedToftsModelParameterizer.h @@ -0,0 +1,69 @@ +/*=================================================================== + +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 MITKEXTENDEDTOFTSMODELPARAMETRIZER_H +#define MITKEXTENDEDTOFTSMODELPARAMETRIZER_H + +#include "mitkAIFBasedModelParameterizerBase.h" +#include "mitkExtendedToftsModel.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + + class MITKPHARMACOKINETICS_EXPORT ExtendedToftsModelParameterizer : public + mitk::AIFBasedModelParameterizerBase + { + public: + typedef ExtendedToftsModelParameterizer Self; + typedef mitk::AIFBasedModelParameterizerBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkTypeMacro(ExtendedToftsModelParameterizer, + mitk::AIFBasedModelParameterizerBase); + itkFactorylessNewMacro(Self); + + typedef Superclass::ModelBaseType ModelBaseType; + typedef Superclass::ModelBasePointer ModelBasePointer; + + typedef Superclass::ModelType ModelType; + typedef ModelType::Pointer ModelPointer; + + typedef Superclass::StaticParameterValueType StaticParameterValueType; + typedef Superclass::StaticParameterValuesType StaticParameterValuesType; + typedef Superclass::StaticParameterMapType StaticParameterMapType; + + typedef Superclass::IndexType IndexType; + + /** This function returns the default parameterization (e.g. initial parametrization for fitting) + defined by the model developer for for the given model.*/ + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + ExtendedToftsModelParameterizer(); + + virtual ~ExtendedToftsModelParameterizer(); + + private: + + //No copy constructor allowed + ExtendedToftsModelParameterizer(const Self& source); + void operator=(const Self&); //purposely not implemented + }; +} +#endif diff --git a/Modules/Pharmacokinetics/include/mitkImageGenerationHelper.h b/Modules/Pharmacokinetics/include/mitkImageGenerationHelper.h new file mode 100644 index 0000000000..1eb4771a71 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkImageGenerationHelper.h @@ -0,0 +1,77 @@ +/*=================================================================== + +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 __MITK_IMAGEGENERATIONHELPER_H +#define __MITK_IMAGEGENERATIONHELPER_H + +#include "itkImage.h" +#include "itkImageRegionIterator.h" + +#include "mitkImage.h" +#include "mitkImagePixelReadAccessor.h" + + + +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + +/** @todo #3 this is a helper class for generating a 4D dynamic image of dimensions (x,y,z, t) from an itk::Array (t) + * The Array will be set at every (x,y,z), so the result is a homogeneous image in 3D, with the 4th dimension as the Array. + * Function GenerateDynamicImageMITK was copied from TestingHelper/TestArtifactGenerator. Maybe there is a better way to do this. + */ +class MITKPHARMACOKINETICS_EXPORT ImageGenerationHelper : public itk::Object +{ + +public: + mitkClassMacroItkParent(ImageGenerationHelper, ::itk::Object); + + itkNewMacro(Self); + + typedef itk::Image TestImageType; + typedef itk::Array TimeGridType; + typedef itk::Array CurveType; + + itkSetMacro(DimX, unsigned int); + itkSetMacro(DimY, unsigned int); + itkSetMacro(DimZ, unsigned int); + itkGetConstReferenceMacro(DimX, unsigned int); + itkGetConstReferenceMacro(DimY, unsigned int); + itkGetConstReferenceMacro(DimZ, unsigned int); + + itkSetMacro(Grid,TimeGridType); + itkGetConstReferenceMacro(Grid,TimeGridType); + + itkSetMacro(Curve, CurveType); + itkGetConstReferenceMacro(Curve,CurveType) + + Image::Pointer GenerateDynamicImageMITK(); + +private: + ImageGenerationHelper(): m_DimX(0), m_DimY(0), m_DimZ(0) {}; + ~ImageGenerationHelper(){}; + + mitk::Image::Pointer GenerateTestFrame(unsigned int timePointIndex); + unsigned int m_DimX, m_DimY, m_DimZ; + TimeGridType m_Grid; + CurveType m_Curve; + + +}; +} + +#endif //__MITK_IMAGEGENERATIONHELPER_H diff --git a/Modules/Pharmacokinetics/include/mitkMaximumCurveDescriptionParameter.h b/Modules/Pharmacokinetics/include/mitkMaximumCurveDescriptionParameter.h new file mode 100644 index 0000000000..4e8a2690ab --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkMaximumCurveDescriptionParameter.h @@ -0,0 +1,49 @@ +/*=================================================================== + +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 MITKMAXIMUMCURVEDESCRIPTIONPARAMETER_H +#define MITKMAXIMUMCURVEDESCRIPTIONPARAMETER_H + +#include "mitkCurveDescriptionParameterBase.h" + +namespace mitk { + + /** Descriptor computes the maximum of the curve.*/ +class MITKPHARMACOKINETICS_EXPORT MaximumCurveDescriptionParameter : public mitk::CurveDescriptionParameterBase +{ +public: + typedef mitk::MaximumCurveDescriptionParameter Self; + typedef CurveDescriptionParameterBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + virtual DescriptionParameterNamesType GetDescriptionParameterName() const override; + +protected: + static const std::string PARAMETER_NAME; + + MaximumCurveDescriptionParameter(); + virtual ~MaximumCurveDescriptionParameter(); + + virtual DescriptionParameterResultsType ComputeCurveDescriptionParameter(const CurveType& curve, const CurveGridType& grid) const override; +}; + + + +} +#endif // MITKMAXIMUMCONCENTRATIONCURVEDESCRIPTIONPARAMETER_H diff --git a/Modules/Pharmacokinetics/include/mitkMeanResidenceTimeDescriptionParameter.h b/Modules/Pharmacokinetics/include/mitkMeanResidenceTimeDescriptionParameter.h new file mode 100644 index 0000000000..e6da1ddad3 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkMeanResidenceTimeDescriptionParameter.h @@ -0,0 +1,33 @@ +#ifndef MEANRESIDENCETIMEDESCRIPTIONPARAMETER_H +#define MEANRESIDENCETIMEDESCRIPTIONPARAMETER_H + + +#include "mitkCurveDescriptionParameterBase.h" + +namespace mitk +{ + + /** Description parameter that computes the area under the curve */ + class MITKPHARMACOKINETICS_EXPORT MeanResidenceTimeDescriptionParameter : public mitk::CurveDescriptionParameterBase + { + public: + typedef mitk::MeanResidenceTimeDescriptionParameter Self; + typedef CurveDescriptionParameterBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + virtual DescriptionParameterNamesType GetDescriptionParameterName() const override; + + protected: + static const std::string PARAMETER_NAME; + + MeanResidenceTimeDescriptionParameter(); + virtual ~MeanResidenceTimeDescriptionParameter(); + + virtual DescriptionParameterResultsType ComputeCurveDescriptionParameter(const CurveType& curve, const CurveGridType& grid) const override; + + }; +} +#endif // MEANRESIDENCETIMEDESCRIPTIONPARAMETER_H diff --git a/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModel.h b/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModel.h new file mode 100644 index 0000000000..38d6dd181c --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModel.h @@ -0,0 +1,116 @@ +#ifndef MITKNUMERICTWOCOMPARTMENTEXCHANGEMODEL_H +#define MITKNUMERICTWOCOMPARTMENTEXCHANGEMODEL_H + +#include "mitkAIFBasedModelBase.h" +#include "MitkPharmacokineticsExports.h" + + +namespace mitk +{ + /** @class NumericTwoCompartmentExchangeModel + * @brief Implementation of the numeric model function of the 2 Compartment Exchange model, using an Aterial Input Function + * The Model calculates the measured Concentration-Time-Curve from the mass balance equations of the 2-tissue compartent Model + * + * vp * dCp(t)/dt = F * (CA(t) - Cp(t)) - PS * (Cp(t) - Ci(t)) + * ve * dCi(t)/dt = PS * (Cp(t) - Ci(t)) + * + * with concentration curve Cp(t) of the Blood Plasma p and Ce(t) of the Extracellular Extravascular Space(EES)(interstitial volume). CA(t) is the aterial concentration, i.e. the AIF + * Cp(t) and Ce(t) are found numerical via Runge-Kutta methode, implemented in Boosts numeric library ODEINT. Here we use a runge_kutta_cash_karp54 stepper with + * adaptive step size and error controll. + * From the resulting curves Cp(t) and Ce(t) the measured concentration Ctotal(t) is found vial + * + * Ctotal(t) = vp * Cp(t) + ve * Ce(t) + * + * where vp=Vp/VT and ve=Ve/VT are the portion of Plasma/EES volume Vp/Ve of the total volume VT respectively. + * The parameters PS, F, vp and ve are subject to the fitting routine*/ + + class MITKPHARMACOKINETICS_EXPORT NumericTwoCompartmentExchangeModel : public AIFBasedModelBase + { + + public: + typedef NumericTwoCompartmentExchangeModel Self; + typedef AIFBasedModelBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + + /** Method for creation through the object factory. */ + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + /** Run-time type information (and related methods). */ + itkTypeMacro(NumericTwoCompartmentExchangeModel, ModelBase) + + typedef std::vector state_type; + + + static const std::string MODEL_DISPLAY_NAME; + + static const std::string NAME_PARAMETER_F; + static const std::string NAME_PARAMETER_PS; + static const std::string NAME_PARAMETER_ve; + static const std::string NAME_PARAMETER_vp; + static const std::string NAME_STATIC_PARAMETER_ODEINTStepSize; + + static const std::string UNIT_PARAMETER_F; + static const std::string UNIT_PARAMETER_PS; + static const std::string UNIT_PARAMETER_ve; + static const std::string UNIT_PARAMETER_vp; + + static const unsigned int POSITION_PARAMETER_F; + static const unsigned int POSITION_PARAMETER_PS; + static const unsigned int POSITION_PARAMETER_ve; + static const unsigned int POSITION_PARAMETER_vp; + + static const unsigned int NUMBER_OF_PARAMETERS; + + virtual std::string GetModelDisplayName() const override; + + virtual std::string GetModelType() const override; + + itkGetConstReferenceMacro(ODEINTStepSize, double); + itkSetMacro(ODEINTStepSize, double); + + + virtual ParameterNamesType GetParameterNames() const override; + virtual ParametersSizeType GetNumberOfParameters() const override; + + virtual ParamterUnitMapType GetParameterUnits() const override; + + virtual ParameterNamesType GetStaticParameterNames() const; + virtual ParametersSizeType GetNumberOfStaticParameters() const; + + + protected: + NumericTwoCompartmentExchangeModel(); + virtual ~NumericTwoCompartmentExchangeModel(); + + /** + * Actual implementation of the clone method. This method should be reimplemeted + * in subclasses to clone the extra required parameters. + */ + virtual itk::LightObject::Pointer InternalClone() const; + + virtual ModelResultType ComputeModelfunction(const ParametersType& parameters) const override; + + virtual void SetStaticParameter(const ParameterNameType& name, const StaticParameterValuesType& values); + virtual StaticParameterValuesType GetStaticParameterValue(const ParameterNameType& name) const; + + virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; + + private: + + + + //No copy constructor allowed + NumericTwoCompartmentExchangeModel(const Self& source); + void operator=(const Self&); //purposely not implemented + + double m_ODEINTStepSize; + + + + }; +} + +#endif // MITKNUMERICTWOCOMPARTMENTEXCHANGEMODEL_H diff --git a/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModelFactory.h b/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModelFactory.h new file mode 100644 index 0000000000..0d845f7dab --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModelFactory.h @@ -0,0 +1,50 @@ +/*=================================================================== + +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 MITKNUMERICTWOCOMPARTMENTEXCHANGEMODELFACTORY_H +#define MITKNUMERICTWOCOMPARTMENTEXCHANGEMODELFACTORY_H + +#include "mitkTwoCompartmentExchangeModelFactoryBase.h" +#include "mitkNumericTwoCompartmentExchangeModelParameterizer.h" + +namespace mitk +{ + + class MITKPHARMACOKINETICS_EXPORT NumericTwoCompartmentExchangeModelFactory : public + mitk::TwoCompartmentExchangeModelFactoryBase + { + public: + mitkClassMacro(NumericTwoCompartmentExchangeModelFactory, + TwoCompartmentExchangeModelFactoryBase); + itkFactorylessNewMacro(Self); + + protected: + + ModelParameterizerBase::Pointer DoCreateParameterizer(const modelFit::ModelFitInfo* fit) const; + + NumericTwoCompartmentExchangeModelFactory(); + + virtual ~NumericTwoCompartmentExchangeModelFactory(); + + private: + + //No copy constructor allowed + NumericTwoCompartmentExchangeModelFactory(const Self& source); + void operator=(const Self&); //purposely not implemented + + }; + +} +#endif // MITKTWOCOMPARTMENTEXCHANGEMODELFACTORY_H diff --git a/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModelParameterizer.h b/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModelParameterizer.h new file mode 100644 index 0000000000..c548d2a8ba --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModelParameterizer.h @@ -0,0 +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. + +===================================================================*/ + +#ifndef MITKNUMERICTWOCOMPARTMENTEXCHANGEMODELPARAMETRIZER_H +#define MITKNUMERICTWOCOMPARTMENTEXCHANGEMODELPARAMETRIZER_H + +#include "mitkAIFBasedModelParameterizerBase.h" +#include "mitkNumericTwoCompartmentExchangeModel.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + + class MITKPHARMACOKINETICS_EXPORT NumericTwoCompartmentExchangeModelParameterizer : public + mitk::AIFBasedModelParameterizerBase + { + public: + typedef NumericTwoCompartmentExchangeModelParameterizer Self; + typedef mitk::AIFBasedModelParameterizerBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkTypeMacro(NumericTwoCompartmentExchangeModelParameterizer, + mitk::AIFBasedModelParameterizerBase); + itkFactorylessNewMacro(Self); + + typedef Superclass::ModelBaseType ModelBaseType; + typedef Superclass::ModelBasePointer ModelBasePointer; + + typedef Superclass::ModelType ModelType; + typedef ModelType::Pointer ModelPointer; + + typedef Superclass::StaticParameterValueType StaticParameterValueType; + typedef Superclass::StaticParameterValuesType StaticParameterValuesType; + typedef Superclass::StaticParameterMapType StaticParameterMapType; + + typedef Superclass::IndexType IndexType; + + itkSetMacro(ODEINTStepSize, double); + itkGetConstReferenceMacro(ODEINTStepSize, double); + + /** Returns the global static parameters for the model. + * @remark this default implementation assumes only AIF and its timegrid as static parameters. + * Reimplement in derived classes to change this behavior.*/ + virtual StaticParameterMapType GetGlobalStaticParameters() const; + + + /** This function returns the default parameterization (e.g. initial parametrization for fitting) + defined by the model developer for for the given model.*/ + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + + double m_ODEINTStepSize; + + NumericTwoCompartmentExchangeModelParameterizer(); + + virtual ~NumericTwoCompartmentExchangeModelParameterizer(); + + private: + + //No copy constructor allowed + NumericTwoCompartmentExchangeModelParameterizer(const Self& source); + void operator=(const Self&); //purposely not implemented + }; +} +#endif diff --git a/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModel.h b/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModel.h new file mode 100644 index 0000000000..cc7eb67497 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModel.h @@ -0,0 +1,101 @@ +/*=================================================================== + +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 MITKNUMERICTWOTISSUECOMPARTMENTMODEL_H +#define MITKNUMERICTWOTISSUECOMPARTMENTMODEL_H + +#include "mitkAIFBasedModelBase.h" +#include "MitkPharmacokineticsExports.h" + + +namespace mitk +{ + class MITKPHARMACOKINETICS_EXPORT NumericTwoTissueCompartmentModel : public AIFBasedModelBase + { + + public: + typedef NumericTwoTissueCompartmentModel Self; + typedef AIFBasedModelBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + /** Method for creation through the object factory. */ + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + /** Run-time type information (and related methods). */ + itkTypeMacro(NumericTwoTissueCompartmentModel, ModelBase) + + typedef std::vector state_type; + + + /** Model Specifications */ + static const std::string MODEL_DISPLAY_NAME; + + static const std::string NAME_PARAMETER_K1; + static const std::string NAME_PARAMETER_k2; + static const std::string NAME_PARAMETER_k3; + static const std::string NAME_PARAMETER_k4; + static const std::string NAME_PARAMETER_VB; + + static const std::string UNIT_PARAMETER_K1; + static const std::string UNIT_PARAMETER_k2; + static const std::string UNIT_PARAMETER_k3; + static const std::string UNIT_PARAMETER_k4; + static const std::string UNIT_PARAMETER_VB; + + static const unsigned int POSITION_PARAMETER_K1; + static const unsigned int POSITION_PARAMETER_k2; + static const unsigned int POSITION_PARAMETER_k3; + static const unsigned int POSITION_PARAMETER_k4; + static const unsigned int POSITION_PARAMETER_VB; + + static const unsigned int NUMBER_OF_PARAMETERS; + + virtual std::string GetModelDisplayName() const override; + + virtual std::string GetModelType() const override; + + virtual ParameterNamesType GetParameterNames() const override; + virtual ParametersSizeType GetNumberOfParameters() const override; + + virtual ParamterUnitMapType GetParameterUnits() const override; + + protected: + NumericTwoTissueCompartmentModel(); + virtual ~NumericTwoTissueCompartmentModel(); + + /** + * Actual implementation of the clone method. This method should be reimplemeted + * in subclasses to clone the extra required parameters. + */ + virtual itk::LightObject::Pointer InternalClone() const; + + virtual ModelResultType ComputeModelfunction(const ParametersType& parameters) const override; + + virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; + + private: + + + //No copy constructor allowed + NumericTwoTissueCompartmentModel(const Self& source); + void operator=(const Self&); //purposely not implemented + + }; +} + +#endif // MITKNUMERICTWOTISSUECOMPARTMENTMODEL_H diff --git a/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModelFactory.h b/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModelFactory.h new file mode 100644 index 0000000000..bfaedf7d82 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModelFactory.h @@ -0,0 +1,52 @@ +/*=================================================================== + +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 MITKNUMERICTWOTISSUECOMPARTMENTMODELFACTORY_H +#define MITKNUMERICTWOTISSUECOMPARTMENTMODELFACTORY_H + +#include "mitkTwoTissueCompartmentModelFactoryBase.h" +#include "mitkNumericTwoTissueCompartmentModelParameterizer.h" + +namespace mitk +{ + + + class MITKPHARMACOKINETICS_EXPORT NumericTwoTissueCompartmentModelFactory : public + mitk::TwoTissueCompartmentModelFactoryBase + { + public: + mitkClassMacro(NumericTwoTissueCompartmentModelFactory, + TwoTissueCompartmentModelFactoryBase); + itkFactorylessNewMacro(Self); + + protected: + + NumericTwoTissueCompartmentModelFactory(); + + virtual ~NumericTwoTissueCompartmentModelFactory(); + + private: + + //No copy constructor allowed + NumericTwoTissueCompartmentModelFactory(const Self& source); + void operator=(const Self&); //purposely not implemented + + }; + +} + + +#endif // MITKNUMERICTWOTISSUECOMPARTMENTMODELFACTORY_H diff --git a/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModelParameterizer.h b/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModelParameterizer.h new file mode 100644 index 0000000000..dfea16aec5 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModelParameterizer.h @@ -0,0 +1,69 @@ +/*=================================================================== + +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 MITKNUMERICTWOTISSUECOMPARTMENTMODELPARAMETERIZER_H +#define MITKNUMERICTWOTISSUECOMPARTMENTMODELPARAMETERIZER_H + +#include "mitkAIFBasedModelParameterizerBase.h" +#include "mitkNumericTwoTissueCompartmentModel.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + + class MITKPHARMACOKINETICS_EXPORT NumericTwoTissueCompartmentModelParameterizer : public + mitk::AIFBasedModelParameterizerBase + { + public: + typedef NumericTwoTissueCompartmentModelParameterizer Self; + typedef mitk::AIFBasedModelParameterizerBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkTypeMacro(NumericTwoTissueCompartmentModelParameterizer, + mitk::AIFBasedModelParameterizerBase); + itkFactorylessNewMacro(Self); + + typedef Superclass::ModelBaseType ModelBaseType; + typedef Superclass::ModelBasePointer ModelBasePointer; + + typedef Superclass::ModelType ModelType; + typedef ModelType::Pointer ModelPointer; + + typedef Superclass::StaticParameterValueType StaticParameterValueType; + typedef Superclass::StaticParameterValuesType StaticParameterValuesType; + typedef Superclass::StaticParameterMapType StaticParameterMapType; + + typedef Superclass::IndexType IndexType; + + /** This function returns the default parameterization (e.g. initial parametrization for fitting) + defined by the model developer for for the given model.*/ + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + NumericTwoTissueCompartmentModelParameterizer(); + + virtual ~NumericTwoTissueCompartmentModelParameterizer(); + + private: + + //No copy constructor allowed + NumericTwoTissueCompartmentModelParameterizer(const Self& source); + void operator=(const Self&); //purposely not implemented + }; +} +#endif diff --git a/Modules/Pharmacokinetics/include/mitkOneTissueCompartmentModel.h b/Modules/Pharmacokinetics/include/mitkOneTissueCompartmentModel.h new file mode 100644 index 0000000000..b9d2ea989a --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkOneTissueCompartmentModel.h @@ -0,0 +1,82 @@ +#ifndef MITKONETISSUECOMPARTMENTMODEL_H +#define MITKONETISSUECOMPARTMENTMODEL_H + +#include "mitkAIFBasedModelBase.h" +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + /** @class OneTissueCompartmentModel + * @brief Implementation of the Model function of the Tofts pharmacokinetic model, using an Aterial Input Function + * The Model calculates the Concentration-Time-Curve as a convolution of the plasma curve Cp (the AIF) and a tissue specific + * residue function (in this case an exponential: R(t) = ktrans * exp(-ktrans/ve * (t)) ). + * C(t) = vp * Cp(t) + conv(Cp(t),R(t)) + * The parameters ktrans, ve and ve are subject to the fitting routine*/ + + class MITKPHARMACOKINETICS_EXPORT OneTissueCompartmentModel : public AIFBasedModelBase + { + + public: + typedef OneTissueCompartmentModel Self; + typedef AIFBasedModelBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + /** Method for creation through the object factory. */ + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(OneTissueCompartmentModel, ModelBase); + + static const std::string MODEL_DISPLAY_NAME; + + static const std::string NAME_PARAMETER_k1; + static const std::string NAME_PARAMETER_k2; + + static const std::string UNIT_PARAMETER_k1; + static const std::string UNIT_PARAMETER_k2; + + static const unsigned int POSITION_PARAMETER_k1; + static const unsigned int POSITION_PARAMETER_k2; + + static const unsigned int NUMBER_OF_PARAMETERS; + + virtual std::string GetModelDisplayName() const override; + + virtual std::string GetModelType() const override; + + virtual ParameterNamesType GetParameterNames() const override; + virtual ParametersSizeType GetNumberOfParameters() const override; + + virtual ParamterUnitMapType GetParameterUnits() const override; + + + protected: + OneTissueCompartmentModel(); + virtual ~OneTissueCompartmentModel(); + + /** + * Actual implementation of the clone method. This method should be reimplemeted + * in subclasses to clone the extra required parameters. + */ + virtual itk::LightObject::Pointer InternalClone() const; + + virtual ModelResultType ComputeModelfunction(const ParametersType& parameters) const override; + + virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const override; + + private: + + + //No copy constructor allowed + OneTissueCompartmentModel(const Self& source); + void operator=(const Self&); //purposely not implemented + + + + + }; +} + +#endif // MITKONETISSUECOMPARTMENTMODEL_H diff --git a/Modules/Pharmacokinetics/include/mitkOneTissueCompartmentModelFactory.h b/Modules/Pharmacokinetics/include/mitkOneTissueCompartmentModelFactory.h new file mode 100644 index 0000000000..ceae49150c --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkOneTissueCompartmentModelFactory.h @@ -0,0 +1,56 @@ +/*=================================================================== + +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 MITKONETISSUECOMPARTMENTMODELFACTORY_H +#define MITKONETISSUECOMPARTMENTMODELFACTORY_H + +#include "mitkConcreteAIFBasedModelFactory.h" +#include "mitkOneTissueCompartmentModel.h" +#include "mitkOneTissueCompartmentModelParameterizer.h" + +namespace mitk +{ + + + class MITKPHARMACOKINETICS_EXPORT OneTissueCompartmentModelFactory : public + mitk::ConcreteAIFBasedModelFactory + { + public: + mitkClassMacro(OneTissueCompartmentModelFactory, + ConcreteAIFBasedModelFactory); + itkFactorylessNewMacro(Self); + + typedef Superclass::ModelType ModelType; + typedef Superclass::ModelParameterizerType ModelParameterizerType; + + ConstraintCheckerBase::Pointer CreateDefaultConstraints() const override; + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + + OneTissueCompartmentModelFactory(); + + virtual ~OneTissueCompartmentModelFactory(); + + private: + + //No copy constructor allowed + OneTissueCompartmentModelFactory(const Self& source); + void operator=(const Self&); //purposely not implemented + + }; + +} +#endif // MITKONETISSUECOMPARTMENTMODELFACTORY_H diff --git a/Modules/Pharmacokinetics/include/mitkOneTissueCompartmentModelParameterizer.h b/Modules/Pharmacokinetics/include/mitkOneTissueCompartmentModelParameterizer.h new file mode 100644 index 0000000000..616d61f49e --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkOneTissueCompartmentModelParameterizer.h @@ -0,0 +1,69 @@ +/*=================================================================== + +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 MITKONETISSUECOMPARTMENTMODELPARAMETRIZER_H +#define MITKONETISSUECOMPARTMENTMODELPARAMETRIZER_H + +#include "mitkAIFBasedModelParameterizerBase.h" +#include "mitkOneTissueCompartmentModel.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + + class MITKPHARMACOKINETICS_EXPORT OneTissueCompartmentModelParameterizer : public + mitk::AIFBasedModelParameterizerBase + { + public: + typedef OneTissueCompartmentModelParameterizer Self; + typedef mitk::AIFBasedModelParameterizerBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkTypeMacro(OneTissueCompartmentModelParameterizer, + mitk::AIFBasedModelParameterizerBase); + itkFactorylessNewMacro(Self); + + typedef Superclass::ModelBaseType ModelBaseType; + typedef Superclass::ModelBasePointer ModelBasePointer; + + typedef Superclass::ModelType ModelType; + typedef ModelType::Pointer ModelPointer; + + typedef Superclass::StaticParameterValueType StaticParameterValueType; + typedef Superclass::StaticParameterValuesType StaticParameterValuesType; + typedef Superclass::StaticParameterMapType StaticParameterMapType; + + typedef Superclass::IndexType IndexType; + + /** This function returns the default parameterization (e.g. initial parametrization for fitting) + defined by the model developer for for the given model.*/ + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + OneTissueCompartmentModelParameterizer(); + + virtual ~OneTissueCompartmentModelParameterizer(); + + private: + + //No copy constructor allowed + OneTissueCompartmentModelParameterizer(const Self& source); + void operator=(const Self&); //purposely not implemented + }; +} +#endif diff --git a/Modules/Pharmacokinetics/include/mitkPerfusionDataGenerator.h b/Modules/Pharmacokinetics/include/mitkPerfusionDataGenerator.h new file mode 100644 index 0000000000..c675ef7984 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkPerfusionDataGenerator.h @@ -0,0 +1,75 @@ +#ifndef PERFUSIONDATAGENERATOR_H +#define PERFUSIONDATAGENERATOR_H + + +#include "MitkPharmacokineticsExports.h" +#include "mitkModelBase.h" +#include "mitkModelDataGenerationFunctor.h" +#include "mitkSimpleFunctorPolicy.h" +#include "mitkImage.h" + + +namespace mitk { + + class MITKPHARMACOKINETICS_EXPORT PerfusionDataGenerator: public ::itk::Object + { + public: + + mitkClassMacroItkParent(PerfusionDataGenerator, itk::Object); + itkFactorylessNewMacro(Self); + + typedef mitk::Image::Pointer ParameterImageType; + typedef std::vector ParameterNamesType; + typedef unsigned int ParametersIndexType; + typedef std::vector ParameterVectorType; + typedef std::map ParameterMapType; + + + typedef ModelDataGenerationFunctor FunctorType; + typedef mitk::Image::Pointer ResultImageType; + typedef mitk::Image::Pointer MaskType; + + typedef mitk::ModelBase::TimeGridType GridType; + + itkSetObjectMacro(Functor, FunctorType); + itkGetObjectMacro(Functor, FunctorType); + + void SetParameterInputImage(const ParametersIndexType index, ParameterImageType inputParameterImage); + + ResultImageType GetGeneratedImage(); + void Generate(); + + + + protected: + PerfusionDataGenerator() + {}; + ~PerfusionDataGenerator() + {}; + + template + void DoGenerateData(itk::Image* image); + + template + void DoPrepareMask(itk::Image* image); + + private: + ParameterMapType m_ParameterInputMap; + ParameterVectorType m_InputParameterImages; + + void SortParameterImages(); + + + MaskType m_Mask; + + typedef itk::Image InternalMaskType; + InternalMaskType::Pointer m_InternalMask; + + ResultImageType m_ResultImage; + FunctorType::Pointer m_Functor; + + }; +} + + +#endif // MITKPHARMACOKINETICSDATAGENERATOR_H diff --git a/Modules/Pharmacokinetics/include/mitkPixelBasedDescriptionParameterImageGenerator.h b/Modules/Pharmacokinetics/include/mitkPixelBasedDescriptionParameterImageGenerator.h new file mode 100644 index 0000000000..7014be58dd --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkPixelBasedDescriptionParameterImageGenerator.h @@ -0,0 +1,104 @@ +/*=================================================================== + + 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 __MITK_PIXEL_BASED_DESCRIPTION_PARAMETER_IMAGE_GENERATOR_H_ +#define __MITK_PIXEL_BASED_DESCRIPTION_PARAMETER_IMAGE_GENERATOR_H_ + +#include + +#include + +#include "mitkCurveParameterFunctor.h" +#include "mitkDescriptionParameterImageGeneratorBase.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + + /** Class for generating curve descriptor images based on a given 4D mitk image. + * The class uses curve parameter functor to generate the curve description image(s). + * Depending on the chosen functor several images may be generated as output. + * @remark This generator fits every pixel on its own. If you want to fit the mean value of the given mask use + * ROIBasedDescriptionParameterImageGenerator. + */ + class MITKPHARMACOKINETICS_EXPORT PixelBasedDescriptionParameterImageGenerator : public DescriptionParameterImageGeneratorBase + { + public: + mitkClassMacro(PixelBasedDescriptionParameterImageGenerator, DescriptionParameterImageGeneratorBase); + + itkNewMacro(Self); + + + typedef ScalarType ParameterImagePixelType; + typedef std::vector FunctorValueArrayType; + + typedef CurveParameterFunctor FunctorType; + + typedef DescriptionParameterImageGeneratorBase::ParameterNameType ParameterNameType; + typedef DescriptionParameterImageGeneratorBase::ParameterImageMapType ParameterImageMapType; + + itkSetObjectMacro(DynamicImage, Image); + itkGetConstObjectMacro(DynamicImage, Image); + + itkSetObjectMacro(Mask, Image); + itkGetConstObjectMacro(Mask, Image); + + itkSetObjectMacro(Functor, FunctorType); + itkGetObjectMacro(Functor, FunctorType); + + virtual double GetProgress() const override; + + protected: + PixelBasedDescriptionParameterImageGenerator() : m_Progress(0) + { + m_InternalMask = NULL; + m_Mask = NULL; + m_DynamicImage = NULL; + }; + + ~PixelBasedDescriptionParameterImageGenerator() {}; + + template + void DoParameterCalculation(itk::Image* image); + + template + void DoPrepareMask(itk::Image* image); + + void onFitProgressEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); + + virtual bool HasOutdatedResult() const override; + virtual void CheckValidInputs() const override; + virtual void DoParameterCalculationAndGetResults(ParameterImageMapType& parameterImages) override; + + private: + Image::Pointer m_DynamicImage; + Image::Pointer m_Mask; + + typedef itk::Image InternalMaskType; + InternalMaskType::Pointer m_InternalMask; + + FunctorType::Pointer m_Functor; + + + ParameterImageMapType m_TempResultMap; + + double m_Progress; + }; + +} + +#endif // __MITK_PIXEL_BASED_DESCRIPTION_PARAMETER_IMAGE_GENERATOR_H_ diff --git a/Modules/Pharmacokinetics/include/mitkStandardToftsModel.h b/Modules/Pharmacokinetics/include/mitkStandardToftsModel.h new file mode 100644 index 0000000000..255d294093 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkStandardToftsModel.h @@ -0,0 +1,94 @@ +#ifndef MITKSTANDARDTOFTSMODEL_H +#define MITKSTANDARDTOFTSMODEL_H + +#include "mitkAIFBasedModelBase.h" +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + /** @class StandardToftsModel + * @brief Implementation of the Model function of the Tofts pharmacokinetic model, using an Aterial Input Function + * The Model calculates the Concentration-Time-Curve as a convolution of the plasma curve Cp (the AIF) and a tissue specific + * residue function (in this case an exponential: R(t) = ktrans * exp(-ktrans/ve * (t)) ). + * C(t) = vp * Cp(t) + conv(Cp(t),R(t)) + * The parameters ktrans, ve and ve are subject to the fitting routine*/ + + class MITKPHARMACOKINETICS_EXPORT StandardToftsModel : public AIFBasedModelBase + { + + public: + typedef StandardToftsModel Self; + typedef AIFBasedModelBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + /** Method for creation through the object factory. */ + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(StandardToftsModel, ModelBase); + + static const std::string MODEL_DISPLAY_NAME; + + static const std::string NAME_PARAMETER_Ktrans; + static const std::string NAME_PARAMETER_ve; + static const std::string NAME_PARAMETER_vp; + + static const std::string UNIT_PARAMETER_Ktrans; + static const std::string UNIT_PARAMETER_ve; + static const std::string UNIT_PARAMETER_vp; + + static const unsigned int POSITION_PARAMETER_Ktrans; + static const unsigned int POSITION_PARAMETER_ve; + static const unsigned int POSITION_PARAMETER_vp; + + static const unsigned int NUMBER_OF_PARAMETERS; + + virtual std::string GetModelDisplayName() const override; + + virtual std::string GetModelType() const override; + + virtual ParameterNamesType GetParameterNames() const override; + virtual ParametersSizeType GetNumberOfParameters() const override; + + virtual ParamterUnitMapType GetParameterUnits() const override; + + virtual ParameterNamesType GetDerivedParameterNames() const override; + + virtual ParametersSizeType GetNumberOfDerivedParameters() const override; + + virtual ParamterUnitMapType GetDerivedParameterUnits() const override; + + protected: + StandardToftsModel(); + virtual ~StandardToftsModel(); + + /** + * Actual implementation of the clone method. This method should be reimplemeted + * in subclasses to clone the extra required parameters. + */ + virtual itk::LightObject::Pointer InternalClone() const; + + virtual ModelResultType ComputeModelfunction(const ParametersType& parameters) const override; + + virtual DerivedParameterMapType ComputeDerivedParameters(const mitk::ModelBase::ParametersType& + parameters) const; + + + virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const override; + + private: + + + //No copy constructor allowed + StandardToftsModel(const Self& source); + void operator=(const Self&); //purposely not implemented + + + + + }; +} + +#endif // MITKSTANDARDTOFTSMODEL_H diff --git a/Modules/Pharmacokinetics/include/mitkStandardToftsModelFactory.h b/Modules/Pharmacokinetics/include/mitkStandardToftsModelFactory.h new file mode 100644 index 0000000000..e784b6ed07 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkStandardToftsModelFactory.h @@ -0,0 +1,55 @@ +/*=================================================================== + +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 MITKSTANDARDTOFTSMODELFACTORY_H +#define MITKSTANDARDTOFTSMODELFACTORY_H + +#include "mitkConcreteAIFBasedModelFactory.h" +#include "mitkStandardToftsModel.h" +#include "mitkStandardToftsModelParameterizer.h" + +namespace mitk +{ + + + class MITKPHARMACOKINETICS_EXPORT StandardToftsModelFactory : public + mitk::ConcreteAIFBasedModelFactory + { + public: + mitkClassMacro(StandardToftsModelFactory, ConcreteAIFBasedModelFactory); + itkFactorylessNewMacro(Self); + + using ModelType = Superclass::ModelType; + using ModelParameterizerType = Superclass::ModelParameterizerType; + + ConstraintCheckerBase::Pointer CreateDefaultConstraints() const override; + virtual ParametersType GetDefaultInitialParameterization() const override; + + protected: + + StandardToftsModelFactory(); + + virtual ~StandardToftsModelFactory() override; + + private: + + //No copy constructor allowed + StandardToftsModelFactory(const Self& source); + void operator=(const Self&); //purposely not implemented + + }; + +} +#endif // MITKSTANDARDTOFTSMODELFACTORY_H diff --git a/Modules/Pharmacokinetics/include/mitkStandardToftsModelParameterizer.h b/Modules/Pharmacokinetics/include/mitkStandardToftsModelParameterizer.h new file mode 100644 index 0000000000..4b8d710cd9 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkStandardToftsModelParameterizer.h @@ -0,0 +1,69 @@ +/*=================================================================== + +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 MITKSTANDARDTOFTSMODELPARAMETRIZER_H +#define MITKSTANDARDTOFTSMODELPARAMETRIZER_H + +#include "mitkAIFBasedModelParameterizerBase.h" +#include "mitkStandardToftsModel.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + + class MITKPHARMACOKINETICS_EXPORT StandardToftsModelParameterizer : public + mitk::AIFBasedModelParameterizerBase + { + public: + typedef StandardToftsModelParameterizer Self; + typedef mitk::AIFBasedModelParameterizerBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkTypeMacro(StandardToftsModelParameterizer, + mitk::AIFBasedModelParameterizerBase); + itkFactorylessNewMacro(Self); + + typedef Superclass::ModelBaseType ModelBaseType; + typedef Superclass::ModelBasePointer ModelBasePointer; + + typedef Superclass::ModelType ModelType; + typedef ModelType::Pointer ModelPointer; + + typedef Superclass::StaticParameterValueType StaticParameterValueType; + typedef Superclass::StaticParameterValuesType StaticParameterValuesType; + typedef Superclass::StaticParameterMapType StaticParameterMapType; + + typedef Superclass::IndexType IndexType; + + /** This function returns the default parameterization (e.g. initial parametrization for fitting) + defined by the model developer for for the given model.*/ + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + StandardToftsModelParameterizer(); + + virtual ~StandardToftsModelParameterizer(); + + private: + + //No copy constructor allowed + StandardToftsModelParameterizer(const Self& source); + void operator=(const Self&); //purposely not implemented + }; +} +#endif diff --git a/Modules/Pharmacokinetics/include/mitkThreeStepLinearModel.h b/Modules/Pharmacokinetics/include/mitkThreeStepLinearModel.h new file mode 100644 index 0000000000..162aa66043 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkThreeStepLinearModel.h @@ -0,0 +1,111 @@ +#ifndef MITKTHREESTEPLINEARMODEL_H +#define MITKTHREESTEPLINEARMODEL_H + +#include "mitkModelBase.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + + class MITKPHARMACOKINETICS_EXPORT ThreeStepLinearModel : public mitk::ModelBase + { + + public: + typedef ThreeStepLinearModel Self; + typedef mitk::ModelBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + typedef Superclass::ParameterNameType ParameterNameType; + typedef Superclass::ParametersSizeType ParametersSizeType; + + /** Method for creation through the object factory. */ + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(ThreeStepLinearModel, ModelBase) + + static const std::string MODEL_DISPLAY_NAME; + static const std::string NAME_PARAMETER_S0; + static const std::string NAME_PARAMETER_t1; + static const std::string NAME_PARAMETER_t2; + static const std::string NAME_PARAMETER_a1; + static const std::string NAME_PARAMETER_a2; + static const std::string NAME_PARAMETER_b1; + static const std::string NAME_PARAMETER_b2; + + static const std::string UNIT_PARAMETER_S0; + static const std::string UNIT_PARAMETER_t1; + static const std::string UNIT_PARAMETER_t2; + static const std::string UNIT_PARAMETER_a1; + static const std::string UNIT_PARAMETER_a2; + static const std::string UNIT_PARAMETER_b1; + static const std::string UNIT_PARAMETER_b2; + + static const unsigned int POSITION_PARAMETER_S0; + static const unsigned int POSITION_PARAMETER_t1; + static const unsigned int POSITION_PARAMETER_t2; + static const unsigned int POSITION_PARAMETER_a1; + static const unsigned int POSITION_PARAMETER_a2; + static const unsigned int POSITION_PARAMETER_b1; + static const unsigned int POSITION_PARAMETER_b2; + + static const unsigned int NUMBER_OF_PARAMETERS; + + virtual std::string GetModelDisplayName() const override; + + virtual std::string GetModelType() const override; + + virtual FunctionStringType GetFunctionString() const override; + + virtual std::string GetXName() const override; + + virtual ParameterNamesType GetParameterNames() const override; + + virtual ParametersSizeType GetNumberOfParameters() const override; + + virtual ParamterUnitMapType GetParameterUnits() const override; + + virtual ParameterNamesType GetStaticParameterNames() const override; + + virtual ParametersSizeType GetNumberOfStaticParameters() const override; + + virtual ParameterNamesType GetDerivedParameterNames() const override; + + virtual ParametersSizeType GetNumberOfDerivedParameters() const override; + + virtual ParamterUnitMapType GetDerivedParameterUnits() const override; + + + protected: + ThreeStepLinearModel() {}; + virtual ~ThreeStepLinearModel(){}; + + + /** + * Actual implementation of the clone method. This method should be reimplemeted + * in subclasses to clone the extra required parameters. + */ + virtual itk::LightObject::Pointer InternalClone() const; + + virtual ModelResultType ComputeModelfunction(const ParametersType& parameters) const; + virtual DerivedParameterMapType ComputeDerivedParameters(const mitk::ModelBase::ParametersType& + parameters) const; + + virtual void SetStaticParameter(const ParameterNameType& name, + const StaticParameterValuesType& values); + virtual StaticParameterValuesType GetStaticParameterValue(const ParameterNameType& name) const; + + private: + + //No copy constructor allowed + ThreeStepLinearModel(const Self& source); + void operator=(const Self&); //purposely not implemented + + }; +} + + +#endif // MITKTHREESTEPLINEARMODEL_H diff --git a/Modules/Pharmacokinetics/include/mitkThreeStepLinearModelFactory.h b/Modules/Pharmacokinetics/include/mitkThreeStepLinearModelFactory.h new file mode 100644 index 0000000000..432b50dede --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkThreeStepLinearModelFactory.h @@ -0,0 +1,43 @@ +#ifndef MITKTHREESTEPLINEARMODELFACTORY_H +#define MITKTHREESTEPLINEARMODELFACTORY_H + +#include + +#include "mitkConcreteModelFactoryBase.h" +#include "mitkThreeStepLinearModel.h" +#include "mitkThreeStepLinearModelParameterizer.h" + +#include "MitkPharmacokineticsExports.h" +namespace mitk +{ + + + class MITKPHARMACOKINETICS_EXPORT ThreeStepLinearModelFactory : public ConcreteModelFactoryBase + { + public: + mitkClassMacroItkParent(ThreeStepLinearModelFactory, ConcreteModelFactoryBase); + itkFactorylessNewMacro(Self); + + /** This function returns the default parameterization (e.g. initial parametrization for fitting) + defined by the model developer for for the given model.*/ + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + virtual ModelParameterizerBase::Pointer DoCreateParameterizer(const modelFit::ModelFitInfo* fit) + const; + + ThreeStepLinearModelFactory(); + + virtual ~ThreeStepLinearModelFactory(); + + private: + + //No copy constructor allowed + ThreeStepLinearModelFactory(const Self& source); + void operator=(const Self&); //purposely not implemented + + }; + +} + +#endif // MITKTHREESTEPLINEARMODELFACTORY_H diff --git a/Modules/Pharmacokinetics/include/mitkThreeStepLinearModelParameterizer.h b/Modules/Pharmacokinetics/include/mitkThreeStepLinearModelParameterizer.h new file mode 100644 index 0000000000..44d4a860fe --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkThreeStepLinearModelParameterizer.h @@ -0,0 +1,66 @@ +/*=================================================================== + +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 MITKTHREESTEPLINEARMODELPARAMETERIZER_H +#define MITKTHREESTEPLINEARMODELPARAMETERIZER_H + +#include "mitkConcreteModelParameterizerBase.h" +#include "mitkThreeStepLinearModel.h" + +namespace mitk +{ + +class MITKPHARMACOKINETICS_EXPORT ThreeStepLinearModelParameterizer : public + mitk::ConcreteModelParameterizerBase +{ +public: + typedef ThreeStepLinearModelParameterizer Self; + typedef mitk::ConcreteModelParameterizerBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkTypeMacro(ThreeStepLinearModelParameterizer, ConcreteModelParameterizerBase); + itkFactorylessNewMacro(Self); + + typedef Superclass::ModelBaseType ModelBaseType; + typedef Superclass::ModelBasePointer ModelBasePointer; + + typedef Superclass::ModelType ModelType; + typedef Superclass::ModelPointer ModelPointer; + + typedef Superclass::StaticParameterValueType StaticParameterValueType; + typedef Superclass::StaticParameterValuesType StaticParameterValuesType; + typedef Superclass::StaticParameterMapType StaticParameterMapType; + + typedef Superclass::IndexType IndexType; + + /** This function returns the default parameterization (e.g. initial parametrization for fitting) + defined by the model developer for for the given model.*/ + virtual ParametersType GetDefaultInitialParameterization() const; + +protected: + ThreeStepLinearModelParameterizer(){}; + + virtual ~ThreeStepLinearModelParameterizer(){}; + +private: + + //No copy constructor allowed + ThreeStepLinearModelParameterizer(const Self& source); + void operator=(const Self&); //purposely not implemented +};} + +#endif // MITKTHREESTEPLINEARMODELPARAMETERIZER_H diff --git a/Modules/Pharmacokinetics/include/mitkTimeToPeakCurveDescriptionParameter.h b/Modules/Pharmacokinetics/include/mitkTimeToPeakCurveDescriptionParameter.h new file mode 100644 index 0000000000..3e056de79c --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkTimeToPeakCurveDescriptionParameter.h @@ -0,0 +1,52 @@ +/*=================================================================== + +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 MITKTIMETOPEAKCURVEDESCRIPTIONPARAMETER_H +#define MITKTIMETOPEAKCURVEDESCRIPTIONPARAMETER_H +#include "mitkCurveDescriptionParameterBase.h" + +namespace mitk { + +/** Computes the position of the first maximum of the curve. As a secondary + * aspect it also returns the value of the curve.*/ +class MITKPHARMACOKINETICS_EXPORT TimeToPeakCurveDescriptionParameter : public mitk::CurveDescriptionParameterBase +{ +public: + typedef mitk::TimeToPeakCurveDescriptionParameter Self; + typedef CurveDescriptionParameterBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + virtual DescriptionParameterNamesType GetDescriptionParameterName() const override; + + +protected: + static const std::string PARAMETER_PEAK_NAME; + static const std::string PARAMETER_TIME_NAME; + + TimeToPeakCurveDescriptionParameter(); + virtual ~TimeToPeakCurveDescriptionParameter(); + + virtual DescriptionParameterResultsType ComputeCurveDescriptionParameter(const CurveType& curve, const CurveGridType& grid) const override; +}; + + + +} + +#endif // MITKTIMETOPEAKCURVEDESCRIPTIONPARAMETER_H diff --git a/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModel.h b/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModel.h new file mode 100644 index 0000000000..3b8c8faf1a --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModel.h @@ -0,0 +1,118 @@ +/*=================================================================== + +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 MITKTWOCOMPARTMENTEXCHANGEMODEL_H +#define MITKTWOCOMPARTMENTEXCHANGEMODEL_H + +#include "mitkAIFBasedModelBase.h" +#include "MitkPharmacokineticsExports.h" + + +namespace mitk +{ + /** @class TwoCompartmentExchangeModel + * @brief Implementation of the analystical model function of the Physiological Pharmacokinetic Brix model, using an Aterial Input Function + * The Model calculates the Concentration-Time-Curve as a convolution of the Aterial Input funciton CA(t) and a tissue specific + * residue function R(t). The Residue funktion consists of two parts: The Residue funktion Qp(t) of the Blood Plasma p and the residue funktion Qi(t) of the + * interstitial volume I. + * Ctotal(t) = vp * Cp(t) + fi * Ci(t) = [vp * Qp(t) + fi * Qi(t)] conv CA(t) + * = Qtotal(t) conv CA(t) + * where vp=Vp/VT and fi=Vi/VT are the portion of Plasma/interstitial volume Vp/VI of the total volume VT respectively. + * The Residuefunctions are described by + * Qp(t) = F/Vp * PS/Vp * 1/(l2 - l1) *[ µ2 exp(l1*t) - µ1 exp(l2*t)]* sig(t) + * Qi(t) = F/Vp * PS/Vi * 1/(l1 - l2) *[ exp(l1*t) - exp(l2*t)]* sig(t) + * = F/Vp * PS/Vp * vp/fi * 1/(l1 - l2) *[ exp(l1*t) - exp(l2*t)]* sig(t) + * with + * l1/2 = -1/2 (PS/Vp * vp/fi + PS/Vp + F/Vp) +/- sqrt((PS/Vp * vp/fi + PS/Vp + F/Vp)² - 4* F/Vp * PS/Vp * vp/fi) + * µ1/2 = F/Vp * Vp/PS + 1 + Vp/PS* l1/2 + * + * The parameters PS/Vp, F/Vp, vp and fi are subject to the fitting routine*/ + + class MITKPHARMACOKINETICS_EXPORT TwoCompartmentExchangeModel : public AIFBasedModelBase + { + + public: + typedef TwoCompartmentExchangeModel Self; + typedef AIFBasedModelBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + /** Method for creation through the object factory. */ + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + /** Run-time type information (and related methods). */ + itkTypeMacro(TwoCompartmentExchangeModel, ModelBase) + + + /** Model Specifications */ + static const std::string MODEL_DISPLAY_NAME; + + static const std::string NAME_PARAMETER_F; + static const std::string NAME_PARAMETER_PS; + static const std::string NAME_PARAMETER_ve; + static const std::string NAME_PARAMETER_vp; + + static const unsigned int POSITION_PARAMETER_F; + static const unsigned int POSITION_PARAMETER_PS; + static const unsigned int POSITION_PARAMETER_ve; + static const unsigned int POSITION_PARAMETER_vp; + + static const std::string UNIT_PARAMETER_F; + static const std::string UNIT_PARAMETER_PS; + static const std::string UNIT_PARAMETER_ve; + static const std::string UNIT_PARAMETER_vp; + + static const unsigned int NUMBER_OF_PARAMETERS; + + virtual std::string GetModelDisplayName() const override; + + virtual std::string GetModelType() const override; + + virtual ParameterNamesType GetParameterNames() const override; + virtual ParametersSizeType GetNumberOfParameters() const override; + + virtual ParamterUnitMapType GetParameterUnits() const override; + + + protected: + TwoCompartmentExchangeModel(); + virtual ~TwoCompartmentExchangeModel(); + + /** + * Actual implementation of the clone method. This method should be reimplemeted + * in subclasses to clone the extra required parameters. + */ + virtual itk::LightObject::Pointer InternalClone() const; + + virtual ModelResultType ComputeModelfunction(const ParametersType& parameters) const; + + virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; + + private: + + + //No copy constructor allowed + TwoCompartmentExchangeModel(const Self& source); + void operator=(const Self&); //purposely not implemented + + + + + }; +} + +#endif // MITKTWOCOMPARTMENTEXCHANGEMODEL_H diff --git a/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModelDifferentialEquations.h b/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModelDifferentialEquations.h new file mode 100644 index 0000000000..39fc35a1e7 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModelDifferentialEquations.h @@ -0,0 +1,118 @@ +/*=================================================================== + +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 MITKTWOCOMPARTMENTEXCHANGEMODELDIFFERENTIALEQUATIONS_H +#define MITKTWOCOMPARTMENTEXCHANGEMODELDIFFERENTIALEQUATIONS_H + +#include "mitkNumericTwoCompartmentExchangeModel.h" + +namespace mitk{ +/** @class TwoCompartmentExchangeModelDifferentialEquations + * @brief Helper Class for NumericTwoCompartmentExchangeModel: Defines the differential equations (Mass Balance Equations) in the 2 Compartment Exchange model. + * The 2 Compartment Exchange model is defined via the mass balance equations + * vp * dCp(t)/dt = F * (CA(t) - Cp(t)) - PS * (Cp(t) - Ce(t)) + * ve * dCe(t)/dt = PS * (Cp(t) - Ce(t)) + * Boost ODEINT performs a stepwise numeric integration (e.g. via Runge-Kutta method) of the initial value problem + * x' = dx/dt = f(x,t) + * It needs an operator () (a functor) that calculates dx/dt = dxdt for a given x and t. + * Parameters are F, PS, ve and vp and the time dependent Ca(t) =AIF, that is interpolated to the current step t +*/ + +class TwoCompartmentExchangeModelDifferentialEquations +{ +public: + + typedef std::vector< double > AIFType; + + /** @brief Functor for differential equation of Physiological Pharmacokinetic Brix Model + * Takes current state x = x(t) and time t and calculates the corresponding dxdt = dx/dt + */ + void operator() (const mitk::NumericTwoCompartmentExchangeModel::state_type &x, mitk::NumericTwoCompartmentExchangeModel::state_type &dxdt, const double t) + { + double Ca_t = InterpolateAIFToCurrentTimeStep(t); + +// dxdt[0] = -(this->FVP + this->PSVP)*x[0] - this->PSVP*x[1]+this->FVP*Ca_t; + dxdt[0] = (1/this->vp) * ( this->F*(Ca_t - x[0]) - this->PS*(x[0] - x[1]) ); + dxdt[1] = (1/this->ve) * this->PS * (x[0] - x[1]); + + } + + TwoCompartmentExchangeModelDifferentialEquations() : F(0), PS(0), ve(0), vp(0), m_AIF(0), m_AIFTimeGrid(0) + { + } + + /** @brief Initialize class with parameters F/Vp, PS/Vp, fi and fp that are free fit parameters*/ + void initialize(double Fp, double ps, double fi, double fp) + { + this->F = Fp; + this->PS = ps; + this->ve = fi; + this->vp = fp; + } + + + void setAIF(AIFType &aif) + { + this->m_AIF = aif; + } + + + void setAIFTimeGrid(AIFType &grid) + { + this->m_AIFTimeGrid = grid; + } + +private: + + double F; + double PS; + double ve; + double vp; + + AIFType m_AIF; + AIFType m_AIFTimeGrid; + + + /** @brief Internal routine to interpolate the AIF to the current time point t used for integration + * The numerical integration of ODEINT is performed on an adaptive timegrid (adaptive step size dt) different from the time grid of the AIF and model function. + * Thus, the AIF value Ca(t) has to be interpolated from the set AIF + */ + double InterpolateAIFToCurrentTimeStep(double t) + { + double lastValue = m_AIF[0]; + double lastTime = std::numeric_limits::min(); + + AIFType::const_iterator posITime = m_AIFTimeGrid.begin(); + AIFType::const_iterator posValue = m_AIF.begin(); + + while(t > *posITime) + { + lastValue = *posValue; + lastTime = *posITime; + ++posValue; + ++posITime; + } + double weightLast = 1 - (t - lastTime)/(*posITime - lastTime); + double weightNext = 1- (*posITime - t)/(*posITime - lastTime); + double result = weightLast * lastValue + weightNext * (*posValue); + + return result; + } + +}; +} + +#endif // MITKTWOCOMPARTMENTEXCHANGEMODELDIFFERENTIALEQUATIONS_H diff --git a/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModelFactory.h b/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModelFactory.h new file mode 100644 index 0000000000..ae7083f6b9 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModelFactory.h @@ -0,0 +1,47 @@ +/*=================================================================== + +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 MITKTWOCOMPARTMENTEXCHANGEMODELFACTORY_H +#define MITKTWOCOMPARTMENTEXCHANGEMODELFACTORY_H + +#include "mitkTwoCompartmentExchangeModelFactoryBase.h" +#include "mitkTwoCompartmentExchangeModelParameterizer.h" + +namespace mitk +{ + class MITKPHARMACOKINETICS_EXPORT TwoCompartmentExchangeModelFactory : public + mitk::TwoCompartmentExchangeModelFactoryBase + { + public: + mitkClassMacro(TwoCompartmentExchangeModelFactory, + TwoCompartmentExchangeModelFactoryBase); + itkFactorylessNewMacro(Self); + + protected: + + TwoCompartmentExchangeModelFactory(); + + virtual ~TwoCompartmentExchangeModelFactory(); + + private: + + //No copy constructor allowed + TwoCompartmentExchangeModelFactory(const Self& source); + void operator=(const Self&); //purposely not implemented + }; + + +} +#endif // MITKTWOCOMPARTMENTEXCHANGEMODELFACTORY_H diff --git a/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModelFactoryBase.h b/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModelFactoryBase.h new file mode 100644 index 0000000000..235d07d8b2 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModelFactoryBase.h @@ -0,0 +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. + +===================================================================*/ +#ifndef MITKTWOCOMPARTMENTEXCHANGEMODELFACTORYBASE_H +#define MITKTWOCOMPARTMENTEXCHANGEMODELFACTORYBASE_H + +#include "mitkConcreteAIFBasedModelFactory.h" +#include "mitkAIFBasedModelParameterizerBase.h" +#include "mitkSimpleBarrierConstraintChecker.h" + +namespace mitk +{ + template + class TwoCompartmentExchangeModelFactoryBase : public + mitk::ConcreteAIFBasedModelFactory< TModelParameterizer > + { + public: + mitkClassMacro(TwoCompartmentExchangeModelFactoryBase, + ConcreteAIFBasedModelFactory< TModelParameterizer >); + itkFactorylessNewMacro(Self); + + + typedef typename Superclass::ModelType ModelType; + typedef typename Superclass::ModelParameterizerType ModelParameterizerType; + typedef typename Superclass::ParametersType ParametersType; + + ConstraintCheckerBase::Pointer CreateDefaultConstraints() const override + { + SimpleBarrierConstraintChecker::Pointer constraints = SimpleBarrierConstraintChecker::New(); + + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_ve, 0.0); + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_ve, 1.0); + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_vp, 0.0); + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_vp, 1.0); + + SimpleBarrierConstraintChecker::ParameterIndexVectorType indices; + indices.push_back(ModelType::POSITION_PARAMETER_ve); + indices.push_back(ModelType::POSITION_PARAMETER_vp); + + constraints->SetUpperSumBarrier(indices, 1.0); + + return constraints.GetPointer(); + }; + + virtual ParametersType GetDefaultInitialParameterization() const + { + typename ModelParameterizerType::Pointer modelParameterizer = + ModelParameterizerType::New(); + + return modelParameterizer->GetDefaultInitialParameterization(); + }; + + protected: + + TwoCompartmentExchangeModelFactoryBase() + { + }; + + virtual ~TwoCompartmentExchangeModelFactoryBase() + { + }; + + private: + + //No copy constructor allowed + TwoCompartmentExchangeModelFactoryBase(const Self& source); + void operator=(const Self&); //purposely not implemented + }; + +} +#endif // MITKTWOCOMPARTMENTEXCHANGEMODELFACTORY_H diff --git a/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModelParameterizer.h b/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModelParameterizer.h new file mode 100644 index 0000000000..1979057eb4 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModelParameterizer.h @@ -0,0 +1,69 @@ +/*=================================================================== + +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 MITKTWOCOMPARTMENTEXCHANGEMODELPARAMETRIZER_H +#define MITKTWOCOMPARTMENTEXCHANGEMODELPARAMETRIZER_H + +#include "mitkAIFBasedModelParameterizerBase.h" +#include "mitkTwoCompartmentExchangeModel.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + + class MITKPHARMACOKINETICS_EXPORT TwoCompartmentExchangeModelParameterizer : public + mitk::AIFBasedModelParameterizerBase + { + public: + typedef TwoCompartmentExchangeModelParameterizer Self; + typedef mitk::AIFBasedModelParameterizerBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkTypeMacro(TwoCompartmentExchangeModelParameterizer, + mitk::AIFBasedModelParameterizerBase); + itkFactorylessNewMacro(Self); + + typedef Superclass::ModelBaseType ModelBaseType; + typedef Superclass::ModelBasePointer ModelBasePointer; + + typedef Superclass::ModelType ModelType; + typedef ModelType::Pointer ModelPointer; + + typedef Superclass::StaticParameterValueType StaticParameterValueType; + typedef Superclass::StaticParameterValuesType StaticParameterValuesType; + typedef Superclass::StaticParameterMapType StaticParameterMapType; + + typedef Superclass::IndexType IndexType; + + /** This function returns the default parameterization (e.g. initial parametrization for fitting) + defined by the model developer for for the given model.*/ + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + TwoCompartmentExchangeModelParameterizer(); + + virtual ~TwoCompartmentExchangeModelParameterizer(); + + private: + + //No copy constructor allowed + TwoCompartmentExchangeModelParameterizer(const Self& source); + void operator=(const Self&); //purposely not implemented + }; +} +#endif diff --git a/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentFDGModel.h b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentFDGModel.h new file mode 100644 index 0000000000..c3cb903ea7 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentFDGModel.h @@ -0,0 +1,97 @@ +/*=================================================================== + +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 MITKTWOTISSUECOMPARTMENTFDGMODEL_H +#define MITKTWOTISSUECOMPARTMENTFDGMODEL_H + +#include "mitkAIFBasedModelBase.h" +#include "MitkPharmacokineticsExports.h" + + +namespace mitk +{ + class MITKPHARMACOKINETICS_EXPORT TwoTissueCompartmentFDGModel : public AIFBasedModelBase + { + + public: + typedef TwoTissueCompartmentFDGModel Self; + typedef AIFBasedModelBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + /** Method for creation through the object factory. */ + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + /** Run-time type information (and related methods). */ + itkTypeMacro(TwoTissueCompartmentFDGModel, ModelBase) + + + /** Model Specifications */ + static const std::string MODEL_DISPLAY_NAME; + + static const std::string NAME_PARAMETER_K1; + static const std::string NAME_PARAMETER_k2; + static const std::string NAME_PARAMETER_k3; + static const std::string NAME_PARAMETER_VB; + + static const std::string UNIT_PARAMETER_K1; + static const std::string UNIT_PARAMETER_k2; + static const std::string UNIT_PARAMETER_k3; + static const std::string UNIT_PARAMETER_VB; + + static const unsigned int POSITION_PARAMETER_K1; + static const unsigned int POSITION_PARAMETER_k2; + static const unsigned int POSITION_PARAMETER_k3; + static const unsigned int POSITION_PARAMETER_VB; + + static const unsigned int NUMBER_OF_PARAMETERS; + + virtual std::string GetModelDisplayName() const override; + + virtual std::string GetModelType() const override; + + virtual ParameterNamesType GetParameterNames() const override; + virtual ParametersSizeType GetNumberOfParameters() const override; + + virtual ParamterUnitMapType GetParameterUnits() const override; + + + protected: + TwoTissueCompartmentFDGModel(); + virtual ~TwoTissueCompartmentFDGModel(); + + /** + * Actual implementation of the clone method. This method should be reimplemeted + * in subclasses to clone the extra required parameters. + */ + virtual itk::LightObject::Pointer InternalClone() const; + + virtual ModelResultType ComputeModelfunction(const ParametersType& parameters) const override; + + virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; + + private: + + + //No copy constructor allowed + TwoTissueCompartmentFDGModel(const Self& source); + void operator=(const Self&); //purposely not implemented + + }; +} + +#endif // MITKTWOTISSUECOMPARTMENTFDGMODEL_H diff --git a/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentFDGModelFactory.h b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentFDGModelFactory.h new file mode 100644 index 0000000000..02992a958c --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentFDGModelFactory.h @@ -0,0 +1,56 @@ +/*=================================================================== + +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 MITKTWOTISSUECOMPARTMENTFDGMODELFACTORY_H +#define MITKTWOTISSUECOMPARTMENTFDGMODELFACTORY_H + +#include "mitkConcreteAIFBasedModelFactory.h" +#include "mitkTwoTissueCompartmentFDGModel.h" +#include "mitkTwoTissueCompartmentFDGModelParameterizer.h" + +namespace mitk +{ + + + class MITKPHARMACOKINETICS_EXPORT TwoTissueCompartmentFDGModelFactory : public + mitk::ConcreteAIFBasedModelFactory + { + public: + mitkClassMacro(TwoTissueCompartmentFDGModelFactory, + ConcreteAIFBasedModelFactory); + itkFactorylessNewMacro(Self); + + typedef Superclass::ModelType ModelType; + typedef Superclass::ModelParameterizerType ModelParameterizerType; + + ConstraintCheckerBase::Pointer CreateDefaultConstraints() const override; + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + + TwoTissueCompartmentFDGModelFactory(); + + virtual ~TwoTissueCompartmentFDGModelFactory(); + + private: + + //No copy constructor allowed + TwoTissueCompartmentFDGModelFactory(const Self& source); + void operator=(const Self&); //purposely not implemented + + }; + +} +#endif // MITKTWOTISSUECOMPARTMENTFDGMODELFACTORY_H diff --git a/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentFDGModelParameterizer.h b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentFDGModelParameterizer.h new file mode 100644 index 0000000000..df4cee1c8f --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentFDGModelParameterizer.h @@ -0,0 +1,69 @@ +/*=================================================================== + +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 MITKTWOTISSUECOMPARTMENTFDGMODELPARAMETERIZER_H +#define MITKTWOTISSUECOMPARTMENTFDGMODELPARAMETERIZER_H + +#include "mitkAIFBasedModelParameterizerBase.h" +#include "mitkTwoTissueCompartmentFDGModel.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + + class MITKPHARMACOKINETICS_EXPORT TwoTissueCompartmentFDGModelParameterizer : public + mitk::AIFBasedModelParameterizerBase + { + public: + typedef TwoTissueCompartmentFDGModelParameterizer Self; + typedef mitk::AIFBasedModelParameterizerBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkTypeMacro(TwoTissueCompartmentFDGModelParameterizer, + mitk::AIFBasedModelParameterizerBase); + itkFactorylessNewMacro(Self); + + typedef Superclass::ModelBaseType ModelBaseType; + typedef Superclass::ModelBasePointer ModelBasePointer; + + typedef Superclass::ModelType ModelType; + typedef ModelType::Pointer ModelPointer; + + typedef Superclass::StaticParameterValueType StaticParameterValueType; + typedef Superclass::StaticParameterValuesType StaticParameterValuesType; + typedef Superclass::StaticParameterMapType StaticParameterMapType; + + typedef Superclass::IndexType IndexType; + + /** This function returns the default parameterization (e.g. initial parametrization for fitting) + defined by the model developer for for the given model.*/ + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + TwoTissueCompartmentFDGModelParameterizer(); + + virtual ~TwoTissueCompartmentFDGModelParameterizer(); + + private: + + //No copy constructor allowed + TwoTissueCompartmentFDGModelParameterizer(const Self& source); + void operator=(const Self&); //purposely not implemented + }; +} +#endif diff --git a/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModel.h b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModel.h new file mode 100644 index 0000000000..24a20b7834 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModel.h @@ -0,0 +1,99 @@ +/*=================================================================== + +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 MITKTWOTISSUECOMPARTMENTMODEL_H +#define MITKTWOTISSUECOMPARTMENTMODEL_H + +#include "mitkAIFBasedModelBase.h" +#include "MitkPharmacokineticsExports.h" + + +namespace mitk +{ + class MITKPHARMACOKINETICS_EXPORT TwoTissueCompartmentModel : public AIFBasedModelBase + { + + public: + typedef TwoTissueCompartmentModel Self; + typedef AIFBasedModelBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + /** Method for creation through the object factory. */ + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + /** Run-time type information (and related methods). */ + itkTypeMacro(TwoTissueCompartmentModel, ModelBase) + + + /** Model Specifications */ + static const std::string MODEL_DISPLAY_NAME; + + static const std::string NAME_PARAMETER_K1; + static const std::string NAME_PARAMETER_k2; + static const std::string NAME_PARAMETER_k3; + static const std::string NAME_PARAMETER_k4; + static const std::string NAME_PARAMETER_VB; + + static const std::string UNIT_PARAMETER_K1; + static const std::string UNIT_PARAMETER_k2; + static const std::string UNIT_PARAMETER_k3; + static const std::string UNIT_PARAMETER_k4; + static const std::string UNIT_PARAMETER_VB; + + static const unsigned int POSITION_PARAMETER_K1; + static const unsigned int POSITION_PARAMETER_k2; + static const unsigned int POSITION_PARAMETER_k3; + static const unsigned int POSITION_PARAMETER_k4; + static const unsigned int POSITION_PARAMETER_VB; + + static const unsigned int NUMBER_OF_PARAMETERS; + + virtual std::string GetModelDisplayName() const override; + + virtual std::string GetModelType() const override; + + virtual ParameterNamesType GetParameterNames() const override; + virtual ParametersSizeType GetNumberOfParameters() const override; + + virtual ParamterUnitMapType GetParameterUnits() const override; + + protected: + TwoTissueCompartmentModel(); + virtual ~TwoTissueCompartmentModel(); + + /** + * Actual implementation of the clone method. This method should be reimplemeted + * in subclasses to clone the extra required parameters. + */ + virtual itk::LightObject::Pointer InternalClone() const; + + virtual ModelResultType ComputeModelfunction(const ParametersType& parameters) const override; + + virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; + + private: + + + //No copy constructor allowed + TwoTissueCompartmentModel(const Self& source); + void operator=(const Self&); //purposely not implemented + + }; +} + +#endif // MITKTWOTISSUECOMPARTMENTMODEL_H diff --git a/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModelDifferentialEquations.h b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModelDifferentialEquations.h new file mode 100644 index 0000000000..5752317452 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModelDifferentialEquations.h @@ -0,0 +1,118 @@ +/*=================================================================== + +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 MITKTWOTISSUECOMPARTMENTMODELDIFFERENTIALEQUATIONS_H +#define MITKTWOTISSUECOMPARTMENTMODELDIFFERENTIALEQUATIONS_H +#include "mitkNumericTwoTissueCompartmentModel.h" + +namespace mitk{ +/** @class TwoTissueCompartmentModelDifferentialEquations + * @brief Helper Class for NumericTwoTissueCompartment Model: Defines the differential equations (Mass Balance Equations) in the + * 2-tissue-compartment model for dynamic PET data modeling. + * The 2-Tissue Compartment model is defined via the mass balance equations + * dC1(t)/dt = K1*Ca(t) - (k2 + k3)*C1(t) + k4*C2(t) + * dC2(t)/dt = k3*C1(t) - k4*C2(t) + * CT(t) = C_a(t)*VB + (1-VB)*(C1(t)+C2(t) + * where Ca(t) is the plasma concentration(aterial input function) + * Boost ODEINT performs a stepwise numeric integration (e.g. via Runge-Kutta method) of the initial value problem + * x' = dx/dt = f(x,t) + * It needs an operator () (a functor) that calculates dx/dt = dxdt for a given x and t. + * Parameters are K1,k2,k3,k4, VB and the time dependent Ca(t) =AIF, that is interpolated to the current step t +*/ + +class TwoTissueCompartmentModelDifferentialEquations +{ +public: + + typedef std::vector< double > AIFType; + + /** @brief Functor for differential equation of Two Tissue Compartment Model + * Takes current state x = x(t) and time t and calculates the corresponding dxdt = dx/dt + */ + void operator() (const mitk::NumericTwoTissueCompartmentModel::state_type &x, mitk::NumericTwoTissueCompartmentModel::state_type &dxdt, const double t) + { + double Ca_t = InterpolateAIFToCurrentTimeStep(t); + + dxdt[0] = this->K1*Ca_t-(this->k2+this->k3)*x[0] + this->k4*x[1]; + dxdt[1] = this->k3*x[0] - this->k4*x[1]; + } + + TwoTissueCompartmentModelDifferentialEquations() : K1(0), k2(0), k3(0), k4(0), m_AIF(0), m_AIFTimeGrid(0) + { + } + + /** @brief Initialize class with parameters K1, k2, k3 and k4 that are free fit parameters*/ + void initialize(double k_1, double k_2, double k_3, double k_4) + { + this->K1 = k_1; + this->k2 = k_2; + this->k3 = k_3; + this->k4 = k_4; + } + + + void setAIF(AIFType &aif) + { + this->m_AIF = aif; + } + + + void setAIFTimeGrid(AIFType &grid) + { + this->m_AIFTimeGrid = grid; + } + +private: + + double K1; + double k2; + double k3; + double k4; + + AIFType m_AIF; + AIFType m_AIFTimeGrid; + + + /** @brief Internal routine to interpolate the AIF to the current time point t used for integration + * The numerical integration of ODEINT is performed on an adaptive timegrid (adaptive step size dt) different from the time grid of the AIF and model function. + * Thus, the AIF value Ca(t) has to be interpolated from the set AIF + */ + double InterpolateAIFToCurrentTimeStep(double t) + { + double lastValue = m_AIF[0]; + double lastTime = std::numeric_limits::min(); + + AIFType::const_iterator posITime = m_AIFTimeGrid.begin(); + AIFType::const_iterator posValue = m_AIF.begin(); + + while(t > *posITime) + { + lastValue = *posValue; + lastTime = *posITime; + ++posValue; + ++posITime; + } + double weightLast = 1 - (t - lastTime)/(*posITime - lastTime); + double weightNext = 1- (*posITime - t)/(*posITime - lastTime); + double result = weightLast * lastValue + weightNext * (*posValue); + + return result; + } + +}; +} + +#endif // MITKTWOTISSUECOMPARTMENTMODELDIFFERENTIALEQUATIONS_H diff --git a/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModelFactory.h b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModelFactory.h new file mode 100644 index 0000000000..ce54c2584a --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModelFactory.h @@ -0,0 +1,51 @@ +/*=================================================================== + +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 MITKTWOTISSUECOMPARTMENTMODELFACTORY_H +#define MITKTWOTISSUECOMPARTMENTMODELFACTORY_H + +#include "mitkTwoTissueCompartmentModelFactoryBase.h" +#include "mitkTwoTissueCompartmentModelParameterizer.h" + +namespace mitk +{ + + + class MITKPHARMACOKINETICS_EXPORT TwoTissueCompartmentModelFactory : public + mitk::TwoTissueCompartmentModelFactoryBase + { + public: + mitkClassMacro(TwoTissueCompartmentModelFactory, + TwoTissueCompartmentModelFactoryBase); + itkFactorylessNewMacro(Self); + + protected: + + TwoTissueCompartmentModelFactory(); + + virtual ~TwoTissueCompartmentModelFactory(); + + private: + + //No copy constructor allowed + TwoTissueCompartmentModelFactory(const Self& source); + void operator=(const Self&); //purposely not implemented + + }; + +} + +#endif // MITKTWOTISSUECOMPARTMENTMODELFACTORY_H diff --git a/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModelFactoryBase.h b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModelFactoryBase.h new file mode 100644 index 0000000000..83db60e14f --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModelFactoryBase.h @@ -0,0 +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. + +===================================================================*/ +#ifndef MITKTWOTISSUECOMPARTMENTFACTORYBASE_H +#define MITKTWOTISSUECOMPARTMENTFACTORYBASE_H + +#include "mitkConcreteAIFBasedModelFactory.h" +#include "mitkAIFBasedModelParameterizerBase.h" +#include "mitkSimpleBarrierConstraintChecker.h" + +namespace mitk +{ + template + class TwoTissueCompartmentModelFactoryBase : public + mitk::ConcreteAIFBasedModelFactory< TModelParameterizer > + { + public: + mitkClassMacro(TwoTissueCompartmentModelFactoryBase, + ConcreteAIFBasedModelFactory< TModelParameterizer >); + itkFactorylessNewMacro(Self); + + typedef typename Superclass::ModelType ModelType; + typedef typename Superclass::ModelParameterizerType ModelParameterizerType; + typedef typename Superclass::ParametersType ParametersType; + + ConstraintCheckerBase::Pointer CreateDefaultConstraints() const override + { + SimpleBarrierConstraintChecker::Pointer constraints = SimpleBarrierConstraintChecker::New(); + + /**@TODO: Mit Charlie klaren ob es eine sinnvolle default Einstellung gibt.*/ + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_K1, 0, 0); + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_k2, 0, 0); + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_k3, 0, 0); + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_k4, 0, 0); + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_VB, 0, 0); + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_VB, 1, 0); + + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_K1, 1.0, 0); + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_k2, 1.0, 0); + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_k3, 1.0, 0); + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_k4, 1.0, 0); + + + return constraints.GetPointer(); + }; + + virtual ParametersType GetDefaultInitialParameterization() const + { + typename ModelParameterizerType::Pointer modelParameterizer = + ModelParameterizerType::New(); + + return modelParameterizer->GetDefaultInitialParameterization(); + }; + + protected: + + TwoTissueCompartmentModelFactoryBase() + { + }; + + virtual ~TwoTissueCompartmentModelFactoryBase() + { + }; + + private: + + //No copy constructor allowed + TwoTissueCompartmentModelFactoryBase(const Self& source); + void operator=(const Self&); //purposely not implemented + }; + +} +#endif // MITKTWOCOMPARTMENTEXCHANGEMODELFACTORY_H diff --git a/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModelParameterizer.h b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModelParameterizer.h new file mode 100644 index 0000000000..3034cbf555 --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModelParameterizer.h @@ -0,0 +1,69 @@ +/*=================================================================== + +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 MITKTWOTISSUECOMPARTMENTMODELPARAMETERIZER_H +#define MITKTWOTISSUECOMPARTMENTMODELPARAMETERIZER_H + +#include "mitkAIFBasedModelParameterizerBase.h" +#include "mitkTwoTissueCompartmentModel.h" + +#include "MitkPharmacokineticsExports.h" + +namespace mitk +{ + + class MITKPHARMACOKINETICS_EXPORT TwoTissueCompartmentModelParameterizer : public + mitk::AIFBasedModelParameterizerBase + { + public: + typedef TwoTissueCompartmentModelParameterizer Self; + typedef mitk::AIFBasedModelParameterizerBase Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkTypeMacro(TwoTissueCompartmentModelParameterizer, + mitk::AIFBasedModelParameterizerBase); + itkFactorylessNewMacro(Self); + + typedef Superclass::ModelBaseType ModelBaseType; + typedef Superclass::ModelBasePointer ModelBasePointer; + + typedef Superclass::ModelType ModelType; + typedef ModelType::Pointer ModelPointer; + + typedef Superclass::StaticParameterValueType StaticParameterValueType; + typedef Superclass::StaticParameterValuesType StaticParameterValuesType; + typedef Superclass::StaticParameterMapType StaticParameterMapType; + + typedef Superclass::IndexType IndexType; + + /** This function returns the default parameterization (e.g. initial parametrization for fitting) + defined by the model developer for for the given model.*/ + virtual ParametersType GetDefaultInitialParameterization() const; + + protected: + TwoTissueCompartmentModelParameterizer(); + + virtual ~TwoTissueCompartmentModelParameterizer(); + + private: + + //No copy constructor allowed + TwoTissueCompartmentModelParameterizer(const Self& source); + void operator=(const Self&); //purposely not implemented + }; +} +#endif diff --git a/Modules/Pharmacokinetics/src/Common/mitkAIFParametrizerHelper.cpp b/Modules/Pharmacokinetics/src/Common/mitkAIFParametrizerHelper.cpp new file mode 100644 index 0000000000..9d0b924691 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Common/mitkAIFParametrizerHelper.cpp @@ -0,0 +1,23 @@ +#include "mitkAIFParametrizerHelper.h" + +mitk::ModelBase::StaticParameterValuesType mitk::convertArrayToParameter(itk::Array array) +{ + ModelBase::StaticParameterValuesType parameter; + for(itk::Array::const_iterator pos = array.begin(); pos != array.end(); ++pos) + { + parameter.push_back(*pos); + } + return parameter; +} + +itk::Array mitk::convertParameterToArray(ModelBase::StaticParameterValuesType parameter) +{ + itk::Array array(parameter.size()); + array.fill(0.0); + itk::Array::iterator arrayPos = array.begin(); + for(ModelBase::StaticParameterValuesType::const_iterator pos = parameter.begin(); pos != parameter.end(); ++pos, ++arrayPos) + { + *arrayPos = *pos; + } + return array; +} diff --git a/Modules/Pharmacokinetics/src/Common/mitkAterialInputFunctionGenerator.cpp b/Modules/Pharmacokinetics/src/Common/mitkAterialInputFunctionGenerator.cpp new file mode 100644 index 0000000000..c0a2065d78 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Common/mitkAterialInputFunctionGenerator.cpp @@ -0,0 +1,141 @@ +/*=================================================================== + + 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 "mitkAterialInputFunctionGenerator.h" + +#include "mitkMaskedDynamicImageStatisticsGenerator.h" +#include "mitkImageTimeSelector.h" +#include "mitkImageCast.h" +#include "itkArray2D.h" +#include "mitkImageAccessByItk.h" +#include "mitkExtractTimeGrid.h" +#include "mitkAIFBasedModelBase.h" +#include "mitkImageCast.h" + +#include +#include + +const double mitk::AterialInputFunctionGenerator::DEFAULT_HEMATOCRIT_LEVEL = 0.45; + +mitk::AIFBasedModelBase::AterialInputFunctionType mitk::AterialInputFunctionGenerator::GetAterialInputFunction() +{ + if(this->HasOutdatedResults()) + { + CheckValidInputs(); + CalculateAIFAndGetResult(); + } + return this->m_AIFValues; + +} + +mitk::ModelBase::TimeGridType mitk::AterialInputFunctionGenerator::GetAterialInputFunctionTimeGrid() +{ + if(this->HasOutdatedResults()){ + CheckValidInputs(); + CalculateAIFAndGetResult(); + } + return this->m_AIFTimeGrid; + +} + + + + +void mitk::AterialInputFunctionGenerator::CalculateAIFAndGetResult() +{ + + mitk::MaskedDynamicImageStatisticsGenerator::Pointer signalGenerator = mitk::MaskedDynamicImageStatisticsGenerator::New(); + + + + m_AIFValues.SetSize(this->m_DynamicImage->GetTimeSteps()); + m_AIFValues.Fill(0.); + m_AIFTimeGrid.SetSize(this->m_DynamicImage->GetTimeSteps()); + m_AIFTimeGrid.Fill(0.); + + + // = not defined for array??? + mitk::ModelBase::TimeGridType timeGrid = ExtractTimeGrid(m_DynamicImage); + m_AIFTimeGrid = timeGrid; + + + signalGenerator->SetDynamicImage(m_DynamicImage); + signalGenerator->SetMask(m_Mask); + signalGenerator->Generate(); + + + //Convert from aterial curve Ca to Plasma curve Cp + // m_AIFValues = signalGenerator->GetMean()/(1-this->m_HCL); + mitk::MaskedDynamicImageStatisticsGenerator::ResultType temp = signalGenerator->GetMean(); + + + mitk::AIFBasedModelBase::AterialInputFunctionType::iterator aif = this->m_AIFValues.begin(); + for( mitk::MaskedDynamicImageStatisticsGenerator::ResultType::const_iterator pos = temp.begin(); pos != temp.end(); ++pos, ++aif) + { + *aif = *pos /(1-this->m_HCL); + + } + + + this->m_GenerationTimeStamp.Modified(); + +} + + + +void + mitk::AterialInputFunctionGenerator::CheckValidInputs() const +{ + + if (m_DynamicImage.IsNull()) + { + mitkThrow() << "Cannot generate Aterial Input Function. Input dynamic image is not set."; + } + if (m_Mask.IsNull()) + { + mitkThrow() << "Cannot generate Aterial Input Function. ROI is not set."; + } +} + +bool mitk::AterialInputFunctionGenerator::HasOutdatedResults() +{ + bool result = false; + + if (m_DynamicImage.IsNull()) + { + result = true; + } + else + { + if (m_DynamicImage->GetMTime() > this->m_GenerationTimeStamp) + { + result = true; + } + } + + if (m_Mask.IsNull()) + { + result = true; + } + else + { + if (m_Mask->GetMTime() > this->m_GenerationTimeStamp) + { + result = true; + } + } + return result; +}; diff --git a/Modules/Pharmacokinetics/src/Common/mitkConcentrationCurveGenerator.cpp b/Modules/Pharmacokinetics/src/Common/mitkConcentrationCurveGenerator.cpp new file mode 100644 index 0000000000..d17529ef06 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Common/mitkConcentrationCurveGenerator.cpp @@ -0,0 +1,265 @@ +#include "mitkConcentrationCurveGenerator.h" +#include "mitkConvertToConcentrationTurboFlashFunctor.h" +#include "mitkConvertT2ConcentrationFunctor.h" +#include "mitkConvertToConcentrationViaT1Functor.h" +#include "mitkImageTimeSelector.h" +#include "mitkImageCast.h" +#include "mitkITKImageImport.h" +#include "mitkModelBase.h" +#include "mitkExtractTimeGrid.h" +#include "mitkArbitraryTimeGeometry.h" +#include "itkImageIOBase.h" + +#include "itkBinaryFunctorImageFilter.h" +#include "itkTernaryFunctorImageFilter.h" + +mitk::ConcentrationCurveGenerator::ConcentrationCurveGenerator() : m_isT2weightedImage(false), m_UsingT1Map(false), m_isTurboFlashSequence(false), + m_AbsoluteSignalEnhancement(false), m_RelativeSignalEnhancement(0.0), m_Factor(0.0), m_RecoveryTime(0.0), m_RelaxationTime(0.0), + m_Relaxivity(0.0), m_T2Factor(0.0), m_T2EchoTime(0.0), m_FlipAngle(0.0) +{ +} + +mitk::ConcentrationCurveGenerator::~ConcentrationCurveGenerator() +{ + +} + +mitk::Image::Pointer mitk::ConcentrationCurveGenerator::GetConvertedImage() +{ + if(this->m_DynamicImage.IsNull()) + { + itkExceptionMacro( << "Dynamic Image not set!"); + } + else { + Convert(); + } + return m_ConvertedImage; + +} + +void mitk::ConcentrationCurveGenerator::Convert() +{ + + mitk::Image::Pointer tempImage = mitk::Image::New(); + mitk::PixelType pixeltype = mitk::MakeScalarPixelType(); + + tempImage->Initialize(pixeltype,*this->m_DynamicImage->GetTimeGeometry()); + + mitk::TimeGeometry::Pointer timeGeometry = (this->m_DynamicImage->GetTimeGeometry())->Clone(); + tempImage->SetTimeGeometry(timeGeometry); + + + PrepareBaselineImage(); + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(this->m_DynamicImage); + + + + for(unsigned int i = 0; i< this->m_DynamicImage->GetTimeSteps(); ++i) + { + imageTimeSelector->SetTimeNr(i); + imageTimeSelector->UpdateLargestPossibleRegion(); + + mitk::Image::Pointer mitkInputImage = imageTimeSelector->GetOutput(); + mitk::Image::Pointer outputImage = mitk::Image::New(); + + outputImage = ConvertSignalToConcentrationCurve(mitkInputImage,this->m_BaselineImage); + + mitk::ImageReadAccessor accessor(outputImage); + tempImage->SetVolume(accessor.GetData(), i); + } + + this->m_ConvertedImage = tempImage; + +} + +void mitk::ConcentrationCurveGenerator::PrepareBaselineImage() +{ + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(this->m_DynamicImage); + imageTimeSelector->SetTimeNr(0); + imageTimeSelector->UpdateLargestPossibleRegion(); + + this->m_BaselineImage = imageTimeSelector->GetOutput(); + +} + +mitk::Image::Pointer mitk::ConcentrationCurveGenerator::ConvertSignalToConcentrationCurve(mitk::Image::Pointer inputImage,mitk::Image::Pointer baselineImage) +{ + + + + mitk::PixelType m_PixelType = inputImage->GetPixelType(); + mitk::Image::Pointer outputImage; + + if(inputImage->GetPixelType().GetComponentType() != baselineImage->GetPixelType().GetComponentType()) + { + mitkThrow() << "Input Image and Baseline Image have different Pixel Types. Data not supported"; + } + + + if(m_PixelType.GetComponentType() == itk::ImageIOBase::USHORT) + { + outputImage = convertToConcentration(inputImage, baselineImage); + } + else if(m_PixelType.GetComponentType() == itk::ImageIOBase::UINT) + { + outputImage = convertToConcentration(inputImage, baselineImage); + } + else if(m_PixelType.GetComponentType() == itk::ImageIOBase::INT) + { + outputImage = convertToConcentration(inputImage, baselineImage); + } + else if(m_PixelType.GetComponentType() == itk::ImageIOBase::SHORT) + { + outputImage = convertToConcentration(inputImage, baselineImage); + } + /*else if(m_PixelType.GetComponentType() == itk::ImageIOBase::ULONG) + { + outputImage = convertToConcentration(inputImage, baselineImage); + } + else if(m_PixelType.GetComponentType() == itk::ImageIOBase::LONG) + { + outputImage = convertToConcentration(inputImage, baselineImage); + }*/ + else if(m_PixelType.GetComponentType() == itk::ImageIOBase::DOUBLE) + { + outputImage = convertToConcentration(inputImage, baselineImage); + } + else if(m_PixelType.GetComponentType() == itk::ImageIOBase::FLOAT) + { + outputImage = convertToConcentration(inputImage, baselineImage); + } + else + { + mitkThrow() << "PixelType is "< +mitk::Image::Pointer mitk::ConcentrationCurveGenerator::convertToConcentration(mitk::Image::Pointer inputImage,mitk::Image::Pointer baselineImage) +{ + typedef itk::Image InputImageType; + + typename InputImageType::Pointer itkInputImage = InputImageType::New(); + typename InputImageType::Pointer itkBaselineImage = InputImageType::New(); + + mitk::CastToItkImage(inputImage, itkInputImage ); + mitk::CastToItkImage(baselineImage, itkBaselineImage ); + + + + mitk::Image::Pointer outputImage; + if(this->m_isT2weightedImage) + { + typedef mitk::ConvertT2ConcentrationFunctor ConversionFunctorT2Type; + typedef itk::BinaryFunctorImageFilter FilterT2Type; + + ConversionFunctorT2Type ConversionT2Functor; + ConversionT2Functor.initialize(this->m_T2Factor, this->m_T2EchoTime); + + typename FilterT2Type::Pointer ConversionT2Filter = FilterT2Type::New(); + + ConversionT2Filter->SetFunctor(ConversionT2Functor); + ConversionT2Filter->SetInput1(itkInputImage); + ConversionT2Filter->SetInput2(itkBaselineImage); + + ConversionT2Filter->Update(); + + outputImage = mitk::ImportItkImage(ConversionT2Filter->GetOutput())->Clone(); + } + + else + { + if(this->m_isTurboFlashSequence) + { + typedef mitk::ConvertToConcentrationTurboFlashFunctor ConversionFunctorTurboFlashType; + typedef itk::BinaryFunctorImageFilter FilterTurboFlashType; + + ConversionFunctorTurboFlashType ConversionTurboFlashFunctor; + ConversionTurboFlashFunctor.initialize(this->m_RelaxationTime, this->m_Relaxivity, this->m_RecoveryTime); + + typename FilterTurboFlashType::Pointer ConversionTurboFlashFilter = FilterTurboFlashType::New(); + + ConversionTurboFlashFilter->SetFunctor(ConversionTurboFlashFunctor); + ConversionTurboFlashFilter->SetInput1(itkInputImage); + ConversionTurboFlashFilter->SetInput2(itkBaselineImage); + + ConversionTurboFlashFilter->Update(); + outputImage = mitk::ImportItkImage(ConversionTurboFlashFilter->GetOutput())->Clone(); + + + } + else if(this->m_UsingT1Map) + { + typename InputImageType::Pointer itkT10Image = InputImageType::New(); + mitk::CastToItkImage(m_T10Image, itkT10Image); + + typedef mitk::ConvertToConcentrationViaT1CalcFunctor ConvertToConcentrationViaT1CalcFunctorType; + typedef itk::TernaryFunctorImageFilter FilterT1MapType; + + ConvertToConcentrationViaT1CalcFunctorType ConversionT1MapFunctor; + ConversionT1MapFunctor.initialize(this->m_Relaxivity, this->m_RecoveryTime, this->m_FlipAngle); + + typename FilterT1MapType::Pointer ConversionT1MapFilter = FilterT1MapType::New(); + + ConversionT1MapFilter->SetFunctor(ConversionT1MapFunctor); + ConversionT1MapFilter->SetInput1(itkInputImage); + ConversionT1MapFilter->SetInput2(itkBaselineImage); + ConversionT1MapFilter->SetInput3(itkT10Image); + + ConversionT1MapFilter->Update(); + outputImage = mitk::ImportItkImage(ConversionT1MapFilter->GetOutput())->Clone(); + + + } + + else if(this->m_AbsoluteSignalEnhancement) + { + typedef mitk::ConvertToConcentrationAbsoluteFunctor ConversionFunctorAbsoluteType; + typedef itk::BinaryFunctorImageFilter FilterAbsoluteType; + + ConversionFunctorAbsoluteType ConversionAbsoluteFunctor; + ConversionAbsoluteFunctor.initialize(this->m_Factor); + + typename FilterAbsoluteType::Pointer ConversionAbsoluteFilter = FilterAbsoluteType::New(); + + ConversionAbsoluteFilter->SetFunctor(ConversionAbsoluteFunctor); + ConversionAbsoluteFilter->SetInput1(itkInputImage); + ConversionAbsoluteFilter->SetInput2(itkBaselineImage); + + ConversionAbsoluteFilter->Update(); + + outputImage = mitk::ImportItkImage(ConversionAbsoluteFilter->GetOutput())->Clone(); + } + + else if(this->m_RelativeSignalEnhancement) + { + typedef mitk::ConvertToConcentrationRelativeFunctor ConversionFunctorRelativeType; + typedef itk::BinaryFunctorImageFilter FilterRelativeType; + + ConversionFunctorRelativeType ConversionRelativeFunctor; + ConversionRelativeFunctor.initialize(this->m_Factor); + + typename FilterRelativeType::Pointer ConversionRelativeFilter = FilterRelativeType::New(); + + ConversionRelativeFilter->SetFunctor(ConversionRelativeFunctor); + ConversionRelativeFilter->SetInput1(itkInputImage); + ConversionRelativeFilter->SetInput2(itkBaselineImage); + + ConversionRelativeFilter->Update(); + + outputImage = mitk::ImportItkImage(ConversionRelativeFilter->GetOutput())->Clone(); + } + } + + + + return outputImage; + +} + + diff --git a/Modules/Pharmacokinetics/src/Common/mitkDescriptionParameterImageGeneratorBase.cpp b/Modules/Pharmacokinetics/src/Common/mitkDescriptionParameterImageGeneratorBase.cpp new file mode 100644 index 0000000000..831b736f3c --- /dev/null +++ b/Modules/Pharmacokinetics/src/Common/mitkDescriptionParameterImageGeneratorBase.cpp @@ -0,0 +1,66 @@ +/*=================================================================== + +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 "mitkDescriptionParameterImageGeneratorBase.h" + +mitk::DescriptionParameterImageGeneratorBase::DescriptionParameterImageGeneratorBase() = default; +mitk::DescriptionParameterImageGeneratorBase::~DescriptionParameterImageGeneratorBase() = default; + +bool + mitk::DescriptionParameterImageGeneratorBase::HasOutdatedResult() const +{ + bool result = this->GetMTime() > this->m_GenerationTimeStamp; + + return result; +}; + +void + mitk::DescriptionParameterImageGeneratorBase::CheckValidInputs() const +{ +}; + + +void + mitk::DescriptionParameterImageGeneratorBase::Generate() +{ + CheckValidInputs(); + + if (!this->HasOutdatedResult()) + { //still up to date -> nothing to do + return; + } + + ParameterImageMapType paramImages; + + DoParameterCalculationAndGetResults(paramImages); + + m_ParameterImageMap = paramImages; + + this->m_GenerationTimeStamp.Modified(); +}; + +mitk::DescriptionParameterImageGeneratorBase::ParameterImageMapType + mitk::DescriptionParameterImageGeneratorBase::GetParameterImages() +{ + if (this->HasOutdatedResult()) + { + Generate(); + } + + + return m_ParameterImageMap; +}; + diff --git a/Modules/Pharmacokinetics/src/Common/mitkPixelBasedDescriptionParameterImageGenerator.cpp b/Modules/Pharmacokinetics/src/Common/mitkPixelBasedDescriptionParameterImageGenerator.cpp new file mode 100644 index 0000000000..c4f240d5c6 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Common/mitkPixelBasedDescriptionParameterImageGenerator.cpp @@ -0,0 +1,195 @@ +/*=================================================================== + +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 "itkCommand.h" +#include "itkMultiOutputNaryFunctorImageFilter.h" + +#include "mitkPixelBasedDescriptionParameterImageGenerator.h" +#include "mitkImageTimeSelector.h" +#include "mitkImageAccessByItk.h" +#include "mitkImageCast.h" +#include "mitkSimpleFunctorPolicy.h" +#include "mitkModelBase.h" + +void + mitk::PixelBasedDescriptionParameterImageGenerator:: + onFitProgressEvent(::itk::Object* caller, const ::itk::EventObject& /*eventObject*/) +{ + this->InvokeEvent(::itk::ProgressEvent()); + + itk::ProcessObject* process = dynamic_cast(caller); + if (process) + { + this->m_Progress = process->GetProgress(); + } +}; + +template +void + mitk::PixelBasedDescriptionParameterImageGenerator::DoPrepareMask(itk::Image* image) +{ + m_InternalMask = dynamic_cast(image); + + if (m_InternalMask.IsNull()) + { + MITK_INFO << "Parameter Fit Generator. Need to cast mask for parameter fit."; + typedef itk::Image InputImageType; + typedef itk::CastImageFilter< InputImageType, InternalMaskType > CastFilterType; + typename CastFilterType::Pointer spImageCaster = CastFilterType::New(); + + spImageCaster->SetInput(image); + + m_InternalMask = spImageCaster->GetOutput(); + spImageCaster->Update(); + } +} + +template +mitk::PixelBasedDescriptionParameterImageGenerator::ParameterImageMapType StoreResultImages(const mitk::CurveParameterFunctor::ParameterNamesType ¶mNames, itk::ImageSource* source) +{ + if (source->GetNumberOfOutputs() != paramNames.size()) + { + mitkThrow() << "Error while generating fitted parameter images. Number of sources does not match expected parameter number. Output size: " << source->GetNumberOfOutputs() << "; number of param names: " << paramNames.size(); + } + + mitk::PixelBasedDescriptionParameterImageGenerator::ParameterImageMapType result; + for (mitk::CurveParameterFunctor::ParameterNamesType::size_type j = 0; j < paramNames.size(); ++j) + { + mitk::Image::Pointer paramImage = mitk::Image::New(); + typename TImage::ConstPointer outputImg = source->GetOutput(j); + mitk::CastToMitkImage(outputImg, paramImage); + + result.insert(std::make_pair(paramNames[j],paramImage)); + } + + return result; +} + +template +void + mitk::PixelBasedDescriptionParameterImageGenerator::DoParameterCalculation(itk::Image* /*image*/) +{ + typedef itk::Image InputFrameImageType; + typedef itk::Image ParameterImageType; + + typedef itk::MultiOutputNaryFunctorImageFilter DescriptorFilterType; + + typename DescriptorFilterType::Pointer descFilter = DescriptorFilterType::New(); + + typename ::itk::MemberCommand::Pointer spProgressCommand = ::itk::MemberCommand::New(); + spProgressCommand->SetCallbackFunction(this, &Self::onFitProgressEvent); + descFilter->AddObserver(::itk::ProgressEvent(), spProgressCommand); + + //add the time frames to the descriptor filter + std::vector frameCache; + for (unsigned int i = 0; i < this->m_DynamicImage->GetTimeSteps(); ++i) + { + typename InputFrameImageType::Pointer frameImage; + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(this->m_DynamicImage); + imageTimeSelector->SetTimeNr(i); + imageTimeSelector->UpdateLargestPossibleRegion(); + + Image::Pointer frameMITKImage = imageTimeSelector->GetOutput(); + frameCache.push_back(frameMITKImage); + mitk::CastToItkImage(frameMITKImage, frameImage); + descFilter->SetInput(i,frameImage); + } + + + SimpleFunctorPolicy functor; + + functor.SetFunctor(this->m_Functor); + descFilter->SetFunctor(functor); + if (this->m_InternalMask.IsNotNull()) + { + descFilter->SetMask(this->m_InternalMask); + } + + //generate the fits + descFilter->Update(); + + //convert the outputs into mitk images and fill the parameter image map + CurveParameterFunctor::ParameterNamesType paramNames = this->m_Functor->GetDescriptionParameterNames(); + + if (descFilter->GetNumberOfOutputs() != (paramNames.size())) + { + mitkThrow() << "Error while generating fitted parameter images. Fit filter output size does not match expected parameter number. Output size: "<< descFilter->GetNumberOfOutputs(); + } + + this->m_TempResultMap = StoreResultImages(paramNames,descFilter); +} + +bool + mitk::PixelBasedDescriptionParameterImageGenerator::HasOutdatedResult() const +{ + bool result = Superclass::HasOutdatedResult(); + + if (m_DynamicImage.IsNotNull()) + { + if (m_DynamicImage->GetMTime() > this->m_GenerationTimeStamp) + { + result = true; + } + } + + if (m_Mask.IsNotNull()) + { + if (m_Mask->GetMTime() > this->m_GenerationTimeStamp) + { + result = true; + } + } + + return result; + +}; + +void + mitk::PixelBasedDescriptionParameterImageGenerator::CheckValidInputs() const +{ + Superclass::CheckValidInputs(); + + if (m_DynamicImage.IsNull()) + { + mitkThrow() << "Cannot generate fitted parameter images. Input dynamic image is not set."; + } + +}; + +void mitk::PixelBasedDescriptionParameterImageGenerator::DoParameterCalculationAndGetResults(ParameterImageMapType& parameterImages) +{ + this->m_Progress = 0; + + if(this->m_Mask.IsNotNull()) + { + AccessFixedDimensionByItk(m_Mask, mitk::PixelBasedDescriptionParameterImageGenerator::DoPrepareMask, 3); + } + else + { + this->m_InternalMask = NULL; + } + + AccessFixedDimensionByItk(m_DynamicImage, mitk::PixelBasedDescriptionParameterImageGenerator::DoParameterCalculation, 4); + + parameterImages = this->m_TempResultMap; + }; + +double + mitk::PixelBasedDescriptionParameterImageGenerator::GetProgress() const +{ + return m_Progress; +}; diff --git a/Modules/Pharmacokinetics/src/DescriptionParameters/mitkAreaUnderFirstMomentDescriptionParameter.cpp b/Modules/Pharmacokinetics/src/DescriptionParameters/mitkAreaUnderFirstMomentDescriptionParameter.cpp new file mode 100644 index 0000000000..f72b4173f3 --- /dev/null +++ b/Modules/Pharmacokinetics/src/DescriptionParameters/mitkAreaUnderFirstMomentDescriptionParameter.cpp @@ -0,0 +1,38 @@ +#include "mitkAreaUnderFirstMomentDescriptionParameter.h" + +const std::string mitk::AreaUnderFirstMomentDescriptionParameter::PARAMETER_NAME = "AreaUnderFirstMoment"; + +mitk::AreaUnderFirstMomentDescriptionParameter::AreaUnderFirstMomentDescriptionParameter() +{ +} + +mitk::AreaUnderFirstMomentDescriptionParameter::~AreaUnderFirstMomentDescriptionParameter() +{ +} + +mitk::CurveDescriptionParameterBase::DescriptionParameterNamesType mitk::AreaUnderFirstMomentDescriptionParameter::GetDescriptionParameterName() const +{ + DescriptionParameterNamesType result = { PARAMETER_NAME }; + return result; +} + +mitk::CurveDescriptionParameterBase::DescriptionParameterResultsType mitk::AreaUnderFirstMomentDescriptionParameter::ComputeCurveDescriptionParameter(const CurveType &curve, const CurveGridType &grid) const +{ + DescriptionParameterResultsType results; + CurveDescriptionParameterResultType aumc = 0; + int steps = grid.GetSize(); + + for (CurveGridType::size_type i = 0; i < steps - 1; ++i) + { + double deltaX = grid(i + 1) - grid(i); + double deltaY = curve(i + 1)*grid(i + 1) - curve(i)*grid(i); + double Yi = curve(i)*grid(i); + + double intI = 1 / 2 * deltaX * deltaY + Yi * deltaX; + + aumc += std::abs(intI); + + } + results.push_back(aumc); + return results; +} diff --git a/Modules/Pharmacokinetics/src/DescriptionParameters/mitkAreaUnderTheCurveDescriptionParameter.cpp b/Modules/Pharmacokinetics/src/DescriptionParameters/mitkAreaUnderTheCurveDescriptionParameter.cpp new file mode 100644 index 0000000000..2c558707fd --- /dev/null +++ b/Modules/Pharmacokinetics/src/DescriptionParameters/mitkAreaUnderTheCurveDescriptionParameter.cpp @@ -0,0 +1,55 @@ +/*=================================================================== + +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 "mitkAreaUnderTheCurveDescriptionParameter.h" + +const std::string mitk::AreaUnderTheCurveDescriptionParameter::PARAMETER_NAME = "AreaUnderCurve"; + +mitk::AreaUnderTheCurveDescriptionParameter::AreaUnderTheCurveDescriptionParameter() +{ +} + +mitk::AreaUnderTheCurveDescriptionParameter::~AreaUnderTheCurveDescriptionParameter() +{ +} + +mitk::CurveDescriptionParameterBase::DescriptionParameterNamesType mitk::AreaUnderTheCurveDescriptionParameter::GetDescriptionParameterName() const +{ + DescriptionParameterNamesType result = { PARAMETER_NAME }; + return result; +} + +mitk::CurveDescriptionParameterBase::DescriptionParameterResultsType mitk::AreaUnderTheCurveDescriptionParameter::ComputeCurveDescriptionParameter(const CurveType &curve, const CurveGridType &grid) const +{ + DescriptionParameterResultsType results; + CurveDescriptionParameterResultType auc = 0; + int steps = grid.GetSize(); + + for (CurveGridType::size_type i = 0; i < steps - 1; ++i) + { + double deltaX = grid(i + 1) - grid(i); + double deltaY = curve(i + 1) - curve(i); + double Yi = curve(i); + + double intI = 1 / 2 * deltaX * deltaY + Yi * deltaX; + + auc += std::abs(intI); + + } + results.push_back(auc); + return results; +} diff --git a/Modules/Pharmacokinetics/src/DescriptionParameters/mitkCurveDescriptionParameterBase.cpp b/Modules/Pharmacokinetics/src/DescriptionParameters/mitkCurveDescriptionParameterBase.cpp new file mode 100644 index 0000000000..7b0c29cbf5 --- /dev/null +++ b/Modules/Pharmacokinetics/src/DescriptionParameters/mitkCurveDescriptionParameterBase.cpp @@ -0,0 +1,44 @@ +/*=================================================================== + +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 "mitkCurveDescriptionParameterBase.h" +#include "itkMacro.h" + +#include + + +mitk::CurveDescriptionParameterBase::CurveDescriptionParameterBase() +{ +} + +mitk::CurveDescriptionParameterBase::~CurveDescriptionParameterBase() +{ +} + +mitk::CurveDescriptionParameterBase::DescriptionParameterResultsType mitk::CurveDescriptionParameterBase::GetCurveDescriptionParameter(const CurveType& curve, const CurveGridType& grid) const +{ + if(curve.GetSize() != grid.GetSize()) + { + itkExceptionMacro("Cannot calculate Curve Description Parameter. Signal and Time Grid do not match!"); + } + + DescriptionParameterResultsType parameter = ComputeCurveDescriptionParameter(curve, grid); + + return parameter; +} + + + diff --git a/Modules/Pharmacokinetics/src/DescriptionParameters/mitkMaximumCurveDescriptionParameter.cpp b/Modules/Pharmacokinetics/src/DescriptionParameters/mitkMaximumCurveDescriptionParameter.cpp new file mode 100644 index 0000000000..aed8579d5d --- /dev/null +++ b/Modules/Pharmacokinetics/src/DescriptionParameters/mitkMaximumCurveDescriptionParameter.cpp @@ -0,0 +1,49 @@ +/*=================================================================== + +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 "mitkMaximumCurveDescriptionParameter.h" +#include + +const std::string mitk::MaximumCurveDescriptionParameter::PARAMETER_NAME = "MaximumConcentrationUptake"; + +mitk::MaximumCurveDescriptionParameter::MaximumCurveDescriptionParameter() +{ +} + +mitk::MaximumCurveDescriptionParameter::~MaximumCurveDescriptionParameter() +{ +} + +mitk::CurveDescriptionParameterBase::DescriptionParameterNamesType mitk::MaximumCurveDescriptionParameter::GetDescriptionParameterName() const +{ + DescriptionParameterNamesType result = { PARAMETER_NAME }; + return result; +} + +mitk::CurveDescriptionParameterBase::DescriptionParameterResultsType mitk::MaximumCurveDescriptionParameter::ComputeCurveDescriptionParameter(const CurveType &curve, const CurveGridType &grid) const +{ + DescriptionParameterResultsType results; + CurveDescriptionParameterResultType maximum = itk::NumericTraits::NonpositiveMin(); + int steps = grid.GetSize(); + + for (int i = 0; i < steps - 1; ++i) + { + maximum = std::max(maximum, curve(i)); + } + + results.push_back(maximum); + return results; +} diff --git a/Modules/Pharmacokinetics/src/DescriptionParameters/mitkMeanResidenceTimeDescriptionParameter.cpp b/Modules/Pharmacokinetics/src/DescriptionParameters/mitkMeanResidenceTimeDescriptionParameter.cpp new file mode 100644 index 0000000000..26d74b549f --- /dev/null +++ b/Modules/Pharmacokinetics/src/DescriptionParameters/mitkMeanResidenceTimeDescriptionParameter.cpp @@ -0,0 +1,51 @@ +#include "mitkMeanResidenceTimeDescriptionParameter.h" + +const std::string mitk::MeanResidenceTimeDescriptionParameter::PARAMETER_NAME = "MeanResidenceTime"; + +mitk::MeanResidenceTimeDescriptionParameter::MeanResidenceTimeDescriptionParameter() +{ +} + +mitk::MeanResidenceTimeDescriptionParameter::~MeanResidenceTimeDescriptionParameter() +{ +} + +mitk::CurveDescriptionParameterBase::DescriptionParameterNamesType mitk::MeanResidenceTimeDescriptionParameter::GetDescriptionParameterName() const +{ + DescriptionParameterNamesType result = { PARAMETER_NAME }; + return result; +} + +mitk::CurveDescriptionParameterBase::DescriptionParameterResultsType mitk::MeanResidenceTimeDescriptionParameter::ComputeCurveDescriptionParameter(const CurveType &curve, const CurveGridType &grid) const +{ + DescriptionParameterResultsType results; + CurveDescriptionParameterResultType aumc = 0; + CurveDescriptionParameterResultType auc = 0; + CurveDescriptionParameterResultType mrt = 0; + + int steps = grid.GetSize(); + + for (CurveGridType::size_type i = 0; i < steps - 1; ++i) + { + double deltaX = grid(i + 1) - grid(i); + + double deltaY1 = curve(i + 1)*grid(i + 1) - curve(i)*grid(i); + double Y1 = curve(i)*grid(i); + double intI1 = 1 / 2 * deltaX * deltaY1 + Y1 * deltaX; + aumc += std::abs(intI1); + + + double deltaY2 = curve(i + 1) - curve(i); + double Y2 = curve(i); + double intI2 = 1 / 2 * deltaX * deltaY2 + Y2 * deltaX; + auc += std::abs(intI2); + + + } + if(auc != 0) + { + mrt = aumc/auc; + } + results.push_back(mrt); + return results; +} diff --git a/Modules/Pharmacokinetics/src/DescriptionParameters/mitkTimeToPeakCurveDescriptionParameter.cpp b/Modules/Pharmacokinetics/src/DescriptionParameters/mitkTimeToPeakCurveDescriptionParameter.cpp new file mode 100644 index 0000000000..214581c0d7 --- /dev/null +++ b/Modules/Pharmacokinetics/src/DescriptionParameters/mitkTimeToPeakCurveDescriptionParameter.cpp @@ -0,0 +1,55 @@ +/*=================================================================== + +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 "mitkTimeToPeakCurveDescriptionParameter.h" + +const std::string mitk::TimeToPeakCurveDescriptionParameter::PARAMETER_PEAK_NAME = "Peak"; +const std::string mitk::TimeToPeakCurveDescriptionParameter::PARAMETER_TIME_NAME = "Time"; + +mitk::TimeToPeakCurveDescriptionParameter::TimeToPeakCurveDescriptionParameter() +{ +} + +mitk::TimeToPeakCurveDescriptionParameter::~TimeToPeakCurveDescriptionParameter() +{ +} + +mitk::CurveDescriptionParameterBase::DescriptionParameterNamesType mitk::TimeToPeakCurveDescriptionParameter::GetDescriptionParameterName() const +{ + DescriptionParameterNamesType result = { PARAMETER_TIME_NAME, PARAMETER_PEAK_NAME }; + return result; +} + +mitk::CurveDescriptionParameterBase::DescriptionParameterResultsType mitk::TimeToPeakCurveDescriptionParameter::ComputeCurveDescriptionParameter(const CurveType &curve, const CurveGridType &grid) const +{ + DescriptionParameterResultsType result; + CurveDescriptionParameterResultType time = itk::NumericTraits::NonpositiveMin(); + CurveDescriptionParameterResultType maximum = itk::NumericTraits::NonpositiveMin(); + int steps = grid.GetSize(); + + for (int i = 0; i < steps - 1; ++i) + { + if (curve(i) > maximum) + { + maximum = curve(i); + time = grid(i); + } + } + + result.push_back(time); + result.push_back(maximum); + return result; +} diff --git a/Modules/Pharmacokinetics/src/Functors/mitkCurveParameterFunctor.cpp b/Modules/Pharmacokinetics/src/Functors/mitkCurveParameterFunctor.cpp new file mode 100644 index 0000000000..af7f89376c --- /dev/null +++ b/Modules/Pharmacokinetics/src/Functors/mitkCurveParameterFunctor.cpp @@ -0,0 +1,141 @@ +/*=================================================================== + +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 "mitkCurveParameterFunctor.h" + +mitk::SimpleFunctorBase::OutputPixelVectorType +mitk::CurveParameterFunctor::Compute(const mitk::SimpleFunctorBase::InputPixelVectorType& value) +const +{ + if (this->m_Grid.GetSize() == 0) + { + itkExceptionMacro("Error. Cannot compute Curve Description Parameters. No Curve Grid set!"); + } + + if (this->m_DescriptorMap.size() == 0) + { + itkGenericExceptionMacro( << + "Error. Cannot compute Curve Description Parameters. No Parameters registered!"); + } + + CurveDescriptionParameterBase::CurveType sample(value.size()); + + for (CurveDescriptionParameterBase::CurveType::SizeValueType i = 0; i < sample.Size(); ++i) + { + sample[i] = value [i]; + } + + mitk::SimpleFunctorBase::OutputPixelVectorType result; + result.reserve(m_DescriptorMap.size()); //we will have at least this number of values + + unsigned int i = 0; + + for (DescriptionParameterMapType::const_iterator pos = m_DescriptorMap.begin(); + pos != m_DescriptorMap.end(); ++pos, ++i) + { + CurveDescriptionParameterBase* paramFct = const_cast + (pos->second.GetPointer()); + + CurveDescriptionParameterBase::DescriptionParameterResultsType fctResults = + paramFct->GetCurveDescriptionParameter(sample, this->m_Grid); + result.insert(result.end(), fctResults.begin(), fctResults.end()); + } + + if (this->GetDescriptionParameterNames().size() != result.size()) + { + itkGenericExceptionMacro( << + "Error. Curve parameter functor has an invalid state. Number of parameter names and number of computed values does not match. Names count: " + << this->GetDescriptionParameterNames().size() << "; value count: " << result.size()); + } + + return result; +}; + +unsigned int +mitk::CurveParameterFunctor::GetNumberOfOutputs() const +{ + return GetDescriptionParameterNames().size(); +}; + +mitk::CurveParameterFunctor::GridArrayType +mitk::CurveParameterFunctor::GetGrid() const +{ + return m_Grid; +}; + +void +mitk::CurveParameterFunctor::ResetDescriptionParameters() +{ + m_DescriptorMap.clear(); +}; + +void +mitk::CurveParameterFunctor::RegisterDescriptionParameter(const std::string& parameterName, + CurveDescriptionParameterBase* parameterFunction) +{ + CurveDescriptionParameterBase::Pointer paramFunctPtr = parameterFunction; + + m_DescriptorMap.insert(std::make_pair(parameterName, paramFunctPtr)); +}; + +mitk::CurveParameterFunctor::ParameterNamesType +mitk::CurveParameterFunctor::GetDescriptionParameterNames() const +{ + ParameterNamesType result; + + for (auto descriptor : m_DescriptorMap) + { + CurveDescriptionParameterBase::DescriptionParameterNamesType fctResults = + descriptor.second->GetDescriptionParameterName(); + + if (fctResults.size() > 1) + { + for (auto fctName : fctResults) + { + result.push_back(descriptor.first + "_" + fctName); + } + } + else + { //if the descriptor has only one parameter just use the registered descriptor name. + result.push_back(descriptor.first); + } + } + + return result; +}; + +const mitk::CurveDescriptionParameterBase* +mitk::CurveParameterFunctor::GetDescriptionParameterFunction(const std::string& parameterName) const +{ + const CurveDescriptionParameterBase* result = NULL; + + DescriptionParameterMapType::const_iterator pos = m_DescriptorMap.find(parameterName); + + if (pos != m_DescriptorMap.end()) + { + result = (pos->second).GetPointer(); + } + + return result; +}; + +mitk::CurveParameterFunctor:: +CurveParameterFunctor() +{}; + +mitk::CurveParameterFunctor:: +~CurveParameterFunctor() {}; + diff --git a/Modules/Pharmacokinetics/src/Models/mitkAIFBasedModelBase.cpp b/Modules/Pharmacokinetics/src/Models/mitkAIFBasedModelBase.cpp new file mode 100644 index 0000000000..374a81ca1c --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkAIFBasedModelBase.cpp @@ -0,0 +1,171 @@ +#include "mitkAIFBasedModelBase.h" +#include "mitkTimeGridHelper.h" +#include "mitkAIFParametrizerHelper.h" + +#include "itkArray2D.h" + + +const std::string mitk::AIFBasedModelBase::NAME_STATIC_PARAMETER_AIF = "Aterial Input Function"; +const std::string mitk::AIFBasedModelBase::NAME_STATIC_PARAMETER_AIFTimeGrid = + "Aterial Input Function Timegrid"; + +//Assumed AIF is always extracted from concentration image +const std::string mitk::AIFBasedModelBase::UNIT_STATIC_PARAMETER_AIF = "C"; +const std::string mitk::AIFBasedModelBase::UNIT_STATIC_PARAMETER_AIFTimeGrid = + "s"; + +std::string mitk::AIFBasedModelBase::GetXAxisName() const +{ + return "Time"; +}; + +std::string mitk::AIFBasedModelBase::GetXAxisUnit() const +{ + return "s"; +} + +std::string mitk::AIFBasedModelBase::GetYAxisName() const +{ + return ""; +}; + +std::string mitk::AIFBasedModelBase::GetYAxisUnit() const +{ + return ""; +} + +mitk::AIFBasedModelBase::AIFBasedModelBase() +{ +} + +mitk::AIFBasedModelBase::~AIFBasedModelBase() +{ +} + +const mitk::AIFBasedModelBase::TimeGridType& +mitk::AIFBasedModelBase::GetCurrentAterialInputFunctionTimeGrid() const +{ + if (!m_AterialInputFunctionTimeGrid.empty()) + { + return m_AterialInputFunctionTimeGrid; + } + else + { + return m_TimeGrid; + } +}; + +const mitk::AIFBasedModelBase::AterialInputFunctionType +mitk::AIFBasedModelBase::GetAterialInputFunction(TimeGridType CurrentTimeGrid) const +{ + if (CurrentTimeGrid.GetSize() == 0) + { + return this->m_AterialInputFunctionValues; + } + else + { + return mitk::InterpolateSignalToNewTimeGrid(m_AterialInputFunctionValues, + GetCurrentAterialInputFunctionTimeGrid(), CurrentTimeGrid); + } +} + +mitk::AIFBasedModelBase::ParameterNamesType mitk::AIFBasedModelBase::GetStaticParameterNames() const +{ + ParameterNamesType result; + + result.push_back(NAME_STATIC_PARAMETER_AIF); + result.push_back(NAME_STATIC_PARAMETER_AIFTimeGrid); + + return result; +} + +mitk::AIFBasedModelBase::ParametersSizeType mitk::AIFBasedModelBase::GetNumberOfStaticParameters() +const +{ + return 2; +} + +mitk::AIFBasedModelBase::ParamterUnitMapType +mitk::AIFBasedModelBase::GetStaticParameterUnits() const +{ + ParamterUnitMapType result; + + result.insert(std::make_pair(NAME_STATIC_PARAMETER_AIF, UNIT_STATIC_PARAMETER_AIF)); + result.insert(std::make_pair(NAME_STATIC_PARAMETER_AIFTimeGrid, UNIT_STATIC_PARAMETER_AIFTimeGrid)); + + return result; +}; + + +void mitk::AIFBasedModelBase::SetStaticParameter(const ParameterNameType& name, + const StaticParameterValuesType& values) +{ + if (name == NAME_STATIC_PARAMETER_AIF) + { + AterialInputFunctionType aif = mitk::convertParameterToArray(values); + + SetAterialInputFunctionValues(aif); + } + + if (name == NAME_STATIC_PARAMETER_AIFTimeGrid) + { + TimeGridType timegrid = mitk::convertParameterToArray(values); + + SetAterialInputFunctionTimeGrid(timegrid); + } +}; + +mitk::AIFBasedModelBase::StaticParameterValuesType mitk::AIFBasedModelBase::GetStaticParameterValue( + const ParameterNameType& name) const +{ + StaticParameterValuesType result; + + if (name == NAME_STATIC_PARAMETER_AIF) + { + result = mitk::convertArrayToParameter(this->m_AterialInputFunctionValues); + } + + if (name == NAME_STATIC_PARAMETER_AIFTimeGrid) + { + result = mitk::convertArrayToParameter(this->m_AterialInputFunctionTimeGrid); + } + + return result; +}; + +bool mitk::AIFBasedModelBase::ValidateModel(std::string& error) const +{ + bool result = Superclass::ValidateModel(error); + + if (result) + { + if (m_AterialInputFunctionTimeGrid.empty()) + { + if (this->m_TimeGrid.GetSize() != m_AterialInputFunctionValues.GetSize()) + { + result = false; + error = "Number of elements of Model Time Grid does not match number of elements in Aterial Input Function! Set valid aif or aif time grid."; + } + } + else + { + if (m_AterialInputFunctionTimeGrid.GetSize() != m_AterialInputFunctionValues.GetSize()) + { + result = false; + error = "Number of elements of Aterial Input Function Time Grid does not match number of elements of Aterial Input Function Values! Set valid curve"; + } + } + } + + return result; +}; + +void mitk::AIFBasedModelBase::PrintSelf(std::ostream& os, ::itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + + os << indent << "Aterial Input Function: " << m_AterialInputFunctionValues; + os << indent << "Aterial Input Function Time Grid: " << m_AterialInputFunctionTimeGrid; +}; + + diff --git a/Modules/Pharmacokinetics/src/Models/mitkDescriptivePharmacokineticBrixModel.cpp b/Modules/Pharmacokinetics/src/Models/mitkDescriptivePharmacokineticBrixModel.cpp new file mode 100644 index 0000000000..c6b2d6c32a --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkDescriptivePharmacokineticBrixModel.cpp @@ -0,0 +1,262 @@ +/*=================================================================== + +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 "mitkDescriptivePharmacokineticBrixModel.h" + +const std::string mitk::DescriptivePharmacokineticBrixModel::MODEL_DISPLAY_NAME = + "Descriptive Pharmacokinetic Brix Model"; + +const std::string mitk::DescriptivePharmacokineticBrixModel::NAME_PARAMETER_A = "A"; +const std::string mitk::DescriptivePharmacokineticBrixModel::NAME_PARAMETER_kep = "kep"; +const std::string mitk::DescriptivePharmacokineticBrixModel::NAME_PARAMETER_kel = "kel"; +//tlag in minutes +const std::string mitk::DescriptivePharmacokineticBrixModel::NAME_PARAMETER_tlag = "tlag"; + +const std::string mitk::DescriptivePharmacokineticBrixModel::UNIT_PARAMETER_A = "a.u."; +const std::string mitk::DescriptivePharmacokineticBrixModel::UNIT_PARAMETER_kep = "1/min"; +const std::string mitk::DescriptivePharmacokineticBrixModel::UNIT_PARAMETER_kel = "1/min"; +//tlag in minutes +const std::string mitk::DescriptivePharmacokineticBrixModel::UNIT_PARAMETER_tlag = "min"; + +const std::string mitk::DescriptivePharmacokineticBrixModel::NAME_STATIC_PARAMETER_Tau = "Tau"; +const std::string mitk::DescriptivePharmacokineticBrixModel::NAME_STATIC_PARAMETER_S0 = "S0"; + +const std::string mitk::DescriptivePharmacokineticBrixModel::UNIT_STATIC_PARAMETER_Tau = "min"; +const std::string mitk::DescriptivePharmacokineticBrixModel::UNIT_STATIC_PARAMETER_S0 = "I"; + +const unsigned int mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_A = 0; +const unsigned int mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_kep = 1; +const unsigned int mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_kel = 2; +const unsigned int mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_tlag = 3; + +const unsigned int mitk::DescriptivePharmacokineticBrixModel::NUMBER_OF_PARAMETERS = 4; + +std::string mitk::DescriptivePharmacokineticBrixModel::GetModelDisplayName() const +{ + return MODEL_DISPLAY_NAME; +}; + +std::string mitk::DescriptivePharmacokineticBrixModel::GetModelType() const +{ + return "Perfusion.MR"; +}; + +std::string mitk::DescriptivePharmacokineticBrixModel::GetXAxisName() const +{ + return "Time"; +}; + +std::string mitk::DescriptivePharmacokineticBrixModel::GetXAxisUnit() const +{ + return "s"; +} + +std::string mitk::DescriptivePharmacokineticBrixModel::GetYAxisName() const +{ + return ""; +}; + +std::string mitk::DescriptivePharmacokineticBrixModel::GetYAxisUnit() const +{ + return ""; +} + +mitk::DescriptivePharmacokineticBrixModel::DescriptivePharmacokineticBrixModel(): m_Tau(0), m_S0(1) +{ + +} + +mitk::DescriptivePharmacokineticBrixModel::~DescriptivePharmacokineticBrixModel() +{ + +} + +mitk::DescriptivePharmacokineticBrixModel::ParameterNamesType +mitk::DescriptivePharmacokineticBrixModel::GetParameterNames() const +{ + ParameterNamesType result; + + result.push_back(NAME_PARAMETER_A); + result.push_back(NAME_PARAMETER_kep); + result.push_back(NAME_PARAMETER_kel); + result.push_back(NAME_PARAMETER_tlag); + + return result; +} + +mitk::DescriptivePharmacokineticBrixModel::ParametersSizeType +mitk::DescriptivePharmacokineticBrixModel::GetNumberOfParameters() const +{ + return NUMBER_OF_PARAMETERS; +} + +mitk::DescriptivePharmacokineticBrixModel::ParamterUnitMapType +mitk::DescriptivePharmacokineticBrixModel::GetParameterUnits() const +{ + ParamterUnitMapType result; + + result.insert(std::make_pair(NAME_PARAMETER_A, UNIT_PARAMETER_A)); + result.insert(std::make_pair(NAME_PARAMETER_kep, UNIT_PARAMETER_kep)); + result.insert(std::make_pair(NAME_PARAMETER_kel, UNIT_PARAMETER_kel)); + result.insert(std::make_pair(NAME_PARAMETER_tlag, UNIT_PARAMETER_tlag)); + + return result; +}; + +mitk::DescriptivePharmacokineticBrixModel::ParameterNamesType +mitk::DescriptivePharmacokineticBrixModel::GetStaticParameterNames() const +{ + ParameterNamesType result; + + result.push_back(NAME_STATIC_PARAMETER_Tau); + result.push_back(NAME_STATIC_PARAMETER_S0); + + return result; +} + +mitk::DescriptivePharmacokineticBrixModel::ParamterUnitMapType +mitk::DescriptivePharmacokineticBrixModel::GetStaticParameterUnits() const +{ + ParamterUnitMapType result; + + result.insert(std::make_pair(NAME_STATIC_PARAMETER_Tau, UNIT_STATIC_PARAMETER_Tau)); + result.insert(std::make_pair(NAME_STATIC_PARAMETER_S0, UNIT_STATIC_PARAMETER_S0)); + + return result; +}; + +mitk::DescriptivePharmacokineticBrixModel::ParametersSizeType +mitk::DescriptivePharmacokineticBrixModel::GetNumberOfStaticParameters() const +{ + return 1; +} + + +mitk::DescriptivePharmacokineticBrixModel::ModelResultType +mitk::DescriptivePharmacokineticBrixModel::ComputeModelfunction(const ParametersType& parameters) +const +{ + if (m_TimeGrid.GetSize() == 0) + { + itkExceptionMacro("No Time Grid Set! Cannot Calculate Signal"); + } + + if (m_Tau == 0) + { + itkExceptionMacro("Injection time is 0! Cannot Calculate Signal"); + } + + unsigned int timeSteps = m_TimeGrid.GetSize(); + ModelResultType signal(m_TimeGrid.GetSize()); + + double tx = 0; + double amplitude = parameters[POSITION_PARAMETER_A]; + double kel = parameters[POSITION_PARAMETER_kel]; + double kep = parameters[POSITION_PARAMETER_kep]; + double tlag = parameters[POSITION_PARAMETER_tlag]; + + TimeGridType::const_iterator timeGridEnd = m_TimeGrid.end(); + ModelResultType::iterator signalPos = signal.begin(); + + for (TimeGridType::const_iterator gridPos = m_TimeGrid.begin(); gridPos != timeGridEnd; + ++gridPos, ++signalPos) + { + double t = (*gridPos) / 60.0; //convert from [sec] to [min] + + + if (t <= tlag) + { + tx = 0; + } + else if ((t > tlag) && (t < (m_Tau + tlag))) + { + tx = t - tlag; + } + else if (t >= (m_Tau + tlag)) + { + tx = m_Tau; + } + + double kDiff = kep - kel; + double tDiff = t - tlag; + + double expkel = (kep * exp(-kel * tDiff)); + double expkeltx = exp(kel * tx); + double expkep = exp(-kep * tDiff); + double expkeptx = exp(kep * tx); + + double value = 1 + (amplitude / m_Tau) * (((expkel / (kel * kDiff)) * (expkeltx - 1)) - (( + expkep / kDiff) * (expkeptx - 1))); + + *signalPos = value * m_S0; + } + + return signal; + +} + +void mitk::DescriptivePharmacokineticBrixModel::SetStaticParameter(const ParameterNameType& name, + const StaticParameterValuesType& values) +{ + if (name == NAME_STATIC_PARAMETER_Tau) + { + SetTau(values[0]); + } + + if (name == NAME_STATIC_PARAMETER_S0) + { + SetS0(values[0]); + } +}; + +mitk::DescriptivePharmacokineticBrixModel::StaticParameterValuesType +mitk::DescriptivePharmacokineticBrixModel::GetStaticParameterValue(const ParameterNameType& name) +const +{ + StaticParameterValuesType result; + + if (name == NAME_STATIC_PARAMETER_Tau) + { + result.push_back(GetTau()); + } + + if (name == NAME_STATIC_PARAMETER_S0) + { + result.push_back(GetS0()); + } + + return result; +}; + +itk::LightObject::Pointer mitk::DescriptivePharmacokineticBrixModel::InternalClone() const +{ + DescriptivePharmacokineticBrixModel::Pointer newClone = DescriptivePharmacokineticBrixModel::New(); + + newClone->SetTimeGrid(this->m_TimeGrid); + newClone->SetTau(this->m_Tau); + newClone->SetS0(this->m_S0); + + return newClone.GetPointer(); +}; + +void mitk::DescriptivePharmacokineticBrixModel::PrintSelf(std::ostream& os, + ::itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + + os << indent << "Tau (injection time): " << m_Tau; + os << indent << "S0 (base value): " << m_S0; +}; diff --git a/Modules/Pharmacokinetics/src/Models/mitkDescriptivePharmacokineticBrixModelFactory.cpp b/Modules/Pharmacokinetics/src/Models/mitkDescriptivePharmacokineticBrixModelFactory.cpp new file mode 100644 index 0000000000..4b6fffe0f8 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkDescriptivePharmacokineticBrixModelFactory.cpp @@ -0,0 +1,94 @@ +/*=================================================================== + +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 "mitkDescriptivePharmacokineticBrixModelFactory.h" +#include "mitkDescriptivePharmacokineticBrixModelParameterizer.h" +#include "mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer.h" + +mitk::DescriptivePharmacokineticBrixModelFactory::DescriptivePharmacokineticBrixModelFactory() +{ +}; + +mitk::DescriptivePharmacokineticBrixModelFactory::~DescriptivePharmacokineticBrixModelFactory() +{ +}; + +mitk::ModelParameterizerBase::ParametersType +mitk::DescriptivePharmacokineticBrixModelFactory::GetDefaultInitialParameterization() const +{ + return DescriptivePharmacokineticBrixModelParameterizer::New()->GetDefaultInitialParameterization(); +}; + +mitk::ModelParameterizerBase::Pointer +mitk::DescriptivePharmacokineticBrixModelFactory::DoCreateParameterizer( + const mitk::modelFit::ModelFitInfo* fit) const +{ + mitk::ModelParameterizerBase::Pointer result; + + if (fit->fitType == ModelFitConstants::FIT_TYPE_VALUE_PIXELBASED()) + { + DescriptivePharmacokineticBrixModelParameterizer::Pointer modelParameterizer = + DescriptivePharmacokineticBrixModelParameterizer::New(); + + modelFit::StaticParameterMap::ValueType tau = fit->staticParamMap.Get( + DescriptivePharmacokineticBrixModel::NAME_STATIC_PARAMETER_Tau); + modelParameterizer->SetTau(tau[0]); + + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(fit->inputImage); + imageTimeSelector->SetTimeNr(0); + imageTimeSelector->UpdateLargestPossibleRegion(); + + mitk::DescriptivePharmacokineticBrixModelParameterizer::BaseImageType::Pointer baseImage; + mitk::CastToItkImage(imageTimeSelector->GetOutput(), baseImage); + + modelParameterizer->SetBaseImage(baseImage); + + result = modelParameterizer.GetPointer(); + } + else if (fit->fitType == ModelFitConstants::FIT_TYPE_VALUE_ROIBASED()) + { + DescriptivePharmacokineticBrixModelValueBasedParameterizer::Pointer modelParameterizer = + DescriptivePharmacokineticBrixModelValueBasedParameterizer::New(); + + modelFit::StaticParameterMap::ValueType tau = fit->staticParamMap.Get( + DescriptivePharmacokineticBrixModel::NAME_STATIC_PARAMETER_Tau); + modelParameterizer->SetTau(tau[0]); + + if (!fit->inputData.ValueExists("ROI")) + { + mitkThrow() << + "Cannot generate parameterizer for fit of type ROIbased. Input data with the lable \"ROI\" is missing in fit."; + } + + ScalarListLookupTable::ValueType signal = fit->inputData.GetTableValue("ROI"); + + if (signal.empty()) + { + mitkThrow() << + "Cannot generate parameterizer for fit of type ROIbased. Input data with the lable \"ROI\" is invalid: No values available."; + } + + modelParameterizer->SetBaseValue(signal[0]); + + result = modelParameterizer.GetPointer(); + } + + return result; +}; \ No newline at end of file diff --git a/Modules/Pharmacokinetics/src/Models/mitkDescriptivePharmacokineticBrixModelParameterizer.cpp b/Modules/Pharmacokinetics/src/Models/mitkDescriptivePharmacokineticBrixModelParameterizer.cpp new file mode 100644 index 0000000000..ac5a5ec38b --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkDescriptivePharmacokineticBrixModelParameterizer.cpp @@ -0,0 +1,66 @@ +/*=================================================================== + +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 "mitkDescriptivePharmacokineticBrixModel.h" +#include "mitkDescriptivePharmacokineticBrixModelParameterizer.h" + +mitk::DescriptivePharmacokineticBrixModelParameterizer::StaticParameterMapType +mitk::DescriptivePharmacokineticBrixModelParameterizer::GetGlobalStaticParameters() const +{ + StaticParameterMapType result; + StaticParameterValuesType values; + values.push_back(m_Tau); + result.insert(std::make_pair(ModelType::NAME_STATIC_PARAMETER_Tau, values)); + return result; +}; + +mitk::DescriptivePharmacokineticBrixModelParameterizer::StaticParameterMapType +mitk::DescriptivePharmacokineticBrixModelParameterizer::GetLocalStaticParameters( + const IndexType& currentPosition) const +{ + StaticParameterMapType result; + + double s0 = m_BaseImage->GetPixel(currentPosition); + + StaticParameterValuesType values; + values.push_back(s0); + result.insert(std::make_pair(ModelType::NAME_STATIC_PARAMETER_S0, values)); + + return result; +}; + +mitk::DescriptivePharmacokineticBrixModelParameterizer::ParametersType +mitk::DescriptivePharmacokineticBrixModelParameterizer::GetDefaultInitialParameterization() const +{ + ParametersType initialParameters; + initialParameters.SetSize(4); + initialParameters[mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_A] = 1.0; + initialParameters[mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_kep] = 4.0; + initialParameters[mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_kel] = 0.2; + initialParameters[mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_tlag] = 1.0; + + return initialParameters; +} + +mitk::DescriptivePharmacokineticBrixModelParameterizer::DescriptivePharmacokineticBrixModelParameterizer() +{ +}; + +mitk::DescriptivePharmacokineticBrixModelParameterizer::~DescriptivePharmacokineticBrixModelParameterizer() +{ +}; diff --git a/Modules/Pharmacokinetics/src/Models/mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer.cpp b/Modules/Pharmacokinetics/src/Models/mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer.cpp new file mode 100644 index 0000000000..82a7bc23b9 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer.cpp @@ -0,0 +1,65 @@ +/*=================================================================== + +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 "mitkDescriptivePharmacokineticBrixModel.h" +#include "mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer.h" + +mitk::DescriptivePharmacokineticBrixModelValueBasedParameterizer::StaticParameterMapType +mitk::DescriptivePharmacokineticBrixModelValueBasedParameterizer::GetGlobalStaticParameters() const +{ + StaticParameterMapType result; + StaticParameterValuesType values; + values.push_back(m_Tau); + result.insert(std::make_pair(ModelType::NAME_STATIC_PARAMETER_Tau, values)); + return result; +}; + +mitk::DescriptivePharmacokineticBrixModelValueBasedParameterizer::StaticParameterMapType +mitk::DescriptivePharmacokineticBrixModelValueBasedParameterizer::GetLocalStaticParameters( + const IndexType& currentPosition) const +{ + StaticParameterMapType result; + + StaticParameterValuesType values; + values.push_back(m_BaseValue); + result.insert(std::make_pair(ModelType::NAME_STATIC_PARAMETER_S0, values)); + + return result; +}; + +mitk::DescriptivePharmacokineticBrixModelValueBasedParameterizer::ParametersType +mitk::DescriptivePharmacokineticBrixModelValueBasedParameterizer::GetDefaultInitialParameterization() +const +{ + ParametersType initialParameters; + initialParameters.SetSize(4); + initialParameters[mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_A] = 1.0; + initialParameters[mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_kep] = 4.0; + initialParameters[mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_kel] = 0.2; + initialParameters[mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_tlag] = 1.0; + + return initialParameters; +} + +mitk::DescriptivePharmacokineticBrixModelValueBasedParameterizer::DescriptivePharmacokineticBrixModelValueBasedParameterizer() +{ +}; + +mitk::DescriptivePharmacokineticBrixModelValueBasedParameterizer::~DescriptivePharmacokineticBrixModelValueBasedParameterizer() +{ +}; diff --git a/Modules/Pharmacokinetics/src/Models/mitkExtendedOneTissueCompartmentModel.cpp b/Modules/Pharmacokinetics/src/Models/mitkExtendedOneTissueCompartmentModel.cpp new file mode 100644 index 0000000000..fcfd70e6e1 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkExtendedOneTissueCompartmentModel.cpp @@ -0,0 +1,151 @@ +/*=================================================================== + +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 "mitkExtendedOneTissueCompartmentModel.h" +#include "mitkConvolutionHelper.h" +#include +#include + +const std::string mitk::ExtendedOneTissueCompartmentModel::MODEL_DISPLAY_NAME = "Extended One Tissue Compartment Model (with blood volume)"; + +const std::string mitk::ExtendedOneTissueCompartmentModel::NAME_PARAMETER_k1 = "K1"; +const std::string mitk::ExtendedOneTissueCompartmentModel::NAME_PARAMETER_k2 = "k2"; +const std::string mitk::ExtendedOneTissueCompartmentModel::NAME_PARAMETER_VB = "VB"; + +const std::string mitk::ExtendedOneTissueCompartmentModel::UNIT_PARAMETER_k1 = "1/min"; +const std::string mitk::ExtendedOneTissueCompartmentModel::UNIT_PARAMETER_k2 = "1/min"; +const std::string mitk::ExtendedOneTissueCompartmentModel::UNIT_PARAMETER_VB = "ml/ml"; + +const unsigned int mitk::ExtendedOneTissueCompartmentModel::POSITION_PARAMETER_k1 = 0; +const unsigned int mitk::ExtendedOneTissueCompartmentModel::POSITION_PARAMETER_k2 = 1; +const unsigned int mitk::ExtendedOneTissueCompartmentModel::POSITION_PARAMETER_VB = 2; + +const unsigned int mitk::ExtendedOneTissueCompartmentModel::NUMBER_OF_PARAMETERS = 3; + +std::string mitk::ExtendedOneTissueCompartmentModel::GetModelDisplayName() const +{ + return MODEL_DISPLAY_NAME; +}; + +std::string mitk::ExtendedOneTissueCompartmentModel::GetModelType() const +{ + return "Dynamic.PET"; +}; + +mitk::ExtendedOneTissueCompartmentModel::ExtendedOneTissueCompartmentModel() +{ + +} + +mitk::ExtendedOneTissueCompartmentModel::~ExtendedOneTissueCompartmentModel() +{ + +} + +mitk::ExtendedOneTissueCompartmentModel::ParameterNamesType mitk::ExtendedOneTissueCompartmentModel::GetParameterNames() const +{ + ParameterNamesType result; + + result.push_back(NAME_PARAMETER_k1); + result.push_back(NAME_PARAMETER_k2); + result.push_back(NAME_PARAMETER_VB); + + return result; +} + +mitk::ExtendedOneTissueCompartmentModel::ParametersSizeType mitk::ExtendedOneTissueCompartmentModel::GetNumberOfParameters() +const +{ + return NUMBER_OF_PARAMETERS; +} + +mitk::ExtendedOneTissueCompartmentModel::ParamterUnitMapType +mitk::ExtendedOneTissueCompartmentModel::GetParameterUnits() const +{ + ParamterUnitMapType result; + + result.insert(std::make_pair(NAME_PARAMETER_k1, UNIT_PARAMETER_k1)); + result.insert(std::make_pair(NAME_PARAMETER_k2, UNIT_PARAMETER_k2)); + result.insert(std::make_pair(NAME_PARAMETER_VB, UNIT_PARAMETER_VB)); + + return result; +}; + +mitk::ExtendedOneTissueCompartmentModel::ModelResultType mitk::ExtendedOneTissueCompartmentModel::ComputeModelfunction( + const ParametersType& parameters) const +{ + typedef itk::Array ResidueFunctionType; + + + if (this->m_TimeGrid.GetSize() == 0) + { + itkExceptionMacro("No Time Grid Set! Cannot Calculate Signal"); + } + + AterialInputFunctionType aterialInputFunction; + aterialInputFunction = GetAterialInputFunction(this->m_TimeGrid); + + + + unsigned int timeSteps = this->m_TimeGrid.GetSize(); + + //Model Parameters + double K1 = (double) parameters[POSITION_PARAMETER_k1] / 60.0; + double k2 = (double) parameters[POSITION_PARAMETER_k2] / 60.0; + double VB = parameters[POSITION_PARAMETER_VB]; + + + + mitk::ModelBase::ModelResultType convolution = mitk::convoluteAIFWithExponential(this->m_TimeGrid, + aterialInputFunction, k2); + + //Signal that will be returned by ComputeModelFunction + mitk::ModelBase::ModelResultType signal(timeSteps); + signal.fill(0.0); + + mitk::ModelBase::ModelResultType::iterator signalPos = signal.begin(); + + AterialInputFunctionType::const_iterator aifPos = aterialInputFunction.begin(); + + + for (mitk::ModelBase::ModelResultType::const_iterator res = convolution.begin(); res != convolution.end(); ++res, ++signalPos, ++aifPos) + { + *signalPos = VB * (*aifPos) + (1 - VB) * K1 * (*res); + } + + return signal; + +} + + + + +itk::LightObject::Pointer mitk::ExtendedOneTissueCompartmentModel::InternalClone() const +{ + ExtendedOneTissueCompartmentModel::Pointer newClone = ExtendedOneTissueCompartmentModel::New(); + + newClone->SetTimeGrid(this->m_TimeGrid); + + return newClone.GetPointer(); +}; + +void mitk::ExtendedOneTissueCompartmentModel::PrintSelf(std::ostream& os, ::itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + + +}; + diff --git a/Modules/Pharmacokinetics/src/Models/mitkExtendedOneTissueCompartmentModelFactory.cpp b/Modules/Pharmacokinetics/src/Models/mitkExtendedOneTissueCompartmentModelFactory.cpp new file mode 100644 index 0000000000..add04aae08 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkExtendedOneTissueCompartmentModelFactory.cpp @@ -0,0 +1,41 @@ +#include "mitkExtendedOneTissueCompartmentModelFactory.h" + +#include +#include +#include + +mitk::ConstraintCheckerBase::Pointer +mitk::ExtendedOneTissueCompartmentModelFactory::CreateDefaultConstraints() const +{ + SimpleBarrierConstraintChecker::Pointer constraints = SimpleBarrierConstraintChecker::New(); + + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_k1, 0.0); + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_k2, 0.0); + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_VB, 0.0); + + constraints->SetUpperBarrier (ModelType::POSITION_PARAMETER_k1, 1.0); + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_k2, 1.0); + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_VB, 1.0); + + SimpleBarrierConstraintChecker::ParameterIndexVectorType indices; + indices.push_back(ModelType::POSITION_PARAMETER_k1); + indices.push_back(ModelType::POSITION_PARAMETER_k2); + indices.push_back(ModelType::POSITION_PARAMETER_VB); + + return constraints.GetPointer(); +}; + +mitk::ModelParameterizerBase::ParametersType +mitk::ExtendedOneTissueCompartmentModelFactory::GetDefaultInitialParameterization() const +{ + return ExtendedOneTissueCompartmentModelParameterizer::New()->GetDefaultInitialParameterization(); +}; + +mitk::ExtendedOneTissueCompartmentModelFactory::ExtendedOneTissueCompartmentModelFactory() +{ +}; + +mitk::ExtendedOneTissueCompartmentModelFactory::~ExtendedOneTissueCompartmentModelFactory() +{ +}; + diff --git a/Modules/Pharmacokinetics/src/Models/mitkExtendedOneTissueCompartmentModelParameterizer.cpp b/Modules/Pharmacokinetics/src/Models/mitkExtendedOneTissueCompartmentModelParameterizer.cpp new file mode 100644 index 0000000000..37acff1b21 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkExtendedOneTissueCompartmentModelParameterizer.cpp @@ -0,0 +1,38 @@ +/*=================================================================== + +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 "mitkExtendedOneTissueCompartmentModelParameterizer.h" + +mitk::ExtendedOneTissueCompartmentModelParameterizer::ParametersType +mitk::ExtendedOneTissueCompartmentModelParameterizer::GetDefaultInitialParameterization() const +{ + ParametersType initialParameters; + initialParameters.SetSize(3); + initialParameters[mitk::ExtendedOneTissueCompartmentModel::POSITION_PARAMETER_k1] = 0.5; + initialParameters[mitk::ExtendedOneTissueCompartmentModel::POSITION_PARAMETER_k2] = 0.5; + initialParameters[mitk::ExtendedOneTissueCompartmentModel::POSITION_PARAMETER_VB] = 0.5; + + return initialParameters; +}; + +mitk::ExtendedOneTissueCompartmentModelParameterizer::ExtendedOneTissueCompartmentModelParameterizer() +{ +}; + +mitk::ExtendedOneTissueCompartmentModelParameterizer::~ExtendedOneTissueCompartmentModelParameterizer() +{ +}; + diff --git a/Modules/Pharmacokinetics/src/Models/mitkExtendedToftsModel.cpp b/Modules/Pharmacokinetics/src/Models/mitkExtendedToftsModel.cpp new file mode 100644 index 0000000000..0f8a483fd9 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkExtendedToftsModel.cpp @@ -0,0 +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 "mitkExtendedToftsModel.h" +#include "mitkConvolutionHelper.h" +#include +#include + +const std::string mitk::ExtendedToftsModel::MODEL_DISPLAY_NAME = "Tofts Model"; + +const std::string mitk::ExtendedToftsModel::NAME_PARAMETER_Ktrans = "KTrans"; +const std::string mitk::ExtendedToftsModel::NAME_PARAMETER_ve = "ve"; +const std::string mitk::ExtendedToftsModel::NAME_PARAMETER_vp = "vp"; + +const std::string mitk::ExtendedToftsModel::UNIT_PARAMETER_Ktrans = "ml/min/100ml"; +const std::string mitk::ExtendedToftsModel::UNIT_PARAMETER_ve = "ml/ml"; +const std::string mitk::ExtendedToftsModel::UNIT_PARAMETER_vp = "ml/ml"; + +const unsigned int mitk::ExtendedToftsModel::POSITION_PARAMETER_Ktrans = 0; +const unsigned int mitk::ExtendedToftsModel::POSITION_PARAMETER_ve = 1; +const unsigned int mitk::ExtendedToftsModel::POSITION_PARAMETER_vp = 2; + +const unsigned int mitk::ExtendedToftsModel::NUMBER_OF_PARAMETERS = 3; + +std::string mitk::ExtendedToftsModel::GetModelDisplayName() const +{ + return MODEL_DISPLAY_NAME; +}; + +std::string mitk::ExtendedToftsModel::GetModelType() const +{ + return "Perfusion.MR"; +}; + +mitk::ExtendedToftsModel::ExtendedToftsModel() +{ + +} + +mitk::ExtendedToftsModel::~ExtendedToftsModel() +{ + +} + +mitk::ExtendedToftsModel::ParameterNamesType mitk::ExtendedToftsModel::GetParameterNames() const +{ + ParameterNamesType result; + + result.push_back(NAME_PARAMETER_Ktrans); + result.push_back(NAME_PARAMETER_ve); + result.push_back(NAME_PARAMETER_vp); + + return result; +} + +mitk::ExtendedToftsModel::ParametersSizeType mitk::ExtendedToftsModel::GetNumberOfParameters() +const +{ + return NUMBER_OF_PARAMETERS; +} + +mitk::ExtendedToftsModel::ParamterUnitMapType +mitk::ExtendedToftsModel::GetParameterUnits() const +{ + ParamterUnitMapType result; + + result.insert(std::make_pair(NAME_PARAMETER_Ktrans, UNIT_PARAMETER_Ktrans)); + result.insert(std::make_pair(NAME_PARAMETER_vp, UNIT_PARAMETER_vp)); + result.insert(std::make_pair(NAME_PARAMETER_ve, UNIT_PARAMETER_ve)); + + return result; +}; + + + +mitk::ExtendedToftsModel::ParameterNamesType +mitk::ExtendedToftsModel::GetDerivedParameterNames() const +{ + ParameterNamesType result; + result.push_back("kep"); + return result; +}; + +mitk::ExtendedToftsModel::ParametersSizeType +mitk::ExtendedToftsModel::GetNumberOfDerivedParameters() const +{ + return 1; +}; + +mitk::ExtendedToftsModel::ParamterUnitMapType mitk::ExtendedToftsModel::GetDerivedParameterUnits() const +{ + ParamterUnitMapType result; + + result.insert(std::make_pair("kep", "1/min")); + + return result; +}; + +mitk::ExtendedToftsModel::ModelResultType mitk::ExtendedToftsModel::ComputeModelfunction( + const ParametersType& parameters) const +{ + typedef itk::Array ResidueFunctionType; + + + if (this->m_TimeGrid.GetSize() == 0) + { + itkExceptionMacro("No Time Grid Set! Cannot Calculate Signal"); + } + + AterialInputFunctionType aterialInputFunction; + aterialInputFunction = GetAterialInputFunction(this->m_TimeGrid); + + + + unsigned int timeSteps = this->m_TimeGrid.GetSize(); + + //Model Parameters + double ktrans = parameters[POSITION_PARAMETER_Ktrans] / 6000.0; + double ve = parameters[POSITION_PARAMETER_ve]; + double vp = parameters[POSITION_PARAMETER_vp]; + + + double lambda = ktrans / ve; + + mitk::ModelBase::ModelResultType convolution = mitk::convoluteAIFWithExponential(this->m_TimeGrid, + aterialInputFunction, lambda); + + //Signal that will be returned by ComputeModelFunction + mitk::ModelBase::ModelResultType signal(timeSteps); + signal.fill(0.0); + + mitk::ModelBase::ModelResultType::iterator signalPos = signal.begin(); + mitk::ModelBase::ModelResultType::const_iterator res = convolution.begin(); + + + for (AterialInputFunctionType::iterator Cp = aterialInputFunction.begin(); + Cp != aterialInputFunction.end(); ++res, ++signalPos, ++Cp) + { + *signalPos = (*Cp) * vp + ktrans * (*res); + } + + return signal; + +} + + +mitk::ModelBase::DerivedParameterMapType mitk::ExtendedToftsModel::ComputeDerivedParameters( + const mitk::ModelBase::ParametersType& parameters) const +{ + DerivedParameterMapType result; + double kep = parameters[POSITION_PARAMETER_Ktrans] / parameters[POSITION_PARAMETER_ve]; + result.insert(std::make_pair("kep", kep)); + return result; +}; + +itk::LightObject::Pointer mitk::ExtendedToftsModel::InternalClone() const +{ + ExtendedToftsModel::Pointer newClone = ExtendedToftsModel::New(); + + newClone->SetTimeGrid(this->m_TimeGrid); + + return newClone.GetPointer(); +}; + +void mitk::ExtendedToftsModel::PrintSelf(std::ostream& os, ::itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + + +}; + diff --git a/Modules/Pharmacokinetics/src/Models/mitkExtendedToftsModelFactory.cpp b/Modules/Pharmacokinetics/src/Models/mitkExtendedToftsModelFactory.cpp new file mode 100644 index 0000000000..ba3c3088bc --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkExtendedToftsModelFactory.cpp @@ -0,0 +1,36 @@ +#include "mitkExtendedToftsModelFactory.h" + +#include +#include +#include + +mitk::ConstraintCheckerBase::Pointer +mitk::ExtendedToftsModelFactory::CreateDefaultConstraints() const +{ + SimpleBarrierConstraintChecker::Pointer constraints = SimpleBarrierConstraintChecker::New(); + + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_ve, 0.0); + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_ve, 1.0); + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_vp, 0.0); + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_vp, 1.0); + + SimpleBarrierConstraintChecker::ParameterIndexVectorType indices; + indices.push_back(ModelType::POSITION_PARAMETER_ve); + indices.push_back(ModelType::POSITION_PARAMETER_vp); + + constraints->SetUpperSumBarrier(indices, 1.0); + + return constraints.GetPointer(); +}; + +mitk::ModelParameterizerBase::ParametersType +mitk::ExtendedToftsModelFactory::GetDefaultInitialParameterization() const +{ + return ExtendedToftsModelParameterizer::New()->GetDefaultInitialParameterization(); +}; + +mitk::ExtendedToftsModelFactory::ExtendedToftsModelFactory() += default; + +mitk::ExtendedToftsModelFactory::~ExtendedToftsModelFactory() += default; diff --git a/Modules/Pharmacokinetics/src/Models/mitkExtendedToftsModelParameterizer.cpp b/Modules/Pharmacokinetics/src/Models/mitkExtendedToftsModelParameterizer.cpp new file mode 100644 index 0000000000..538a643d8a --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkExtendedToftsModelParameterizer.cpp @@ -0,0 +1,37 @@ +/*=================================================================== + +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 "mitkExtendedToftsModelParameterizer.h" + +mitk::ExtendedToftsModelParameterizer::ParametersType +mitk::ExtendedToftsModelParameterizer::GetDefaultInitialParameterization() const +{ + ParametersType initialParameters; + initialParameters.SetSize(3); + initialParameters[mitk::ExtendedToftsModel::POSITION_PARAMETER_Ktrans] = 15; + initialParameters[mitk::ExtendedToftsModel::POSITION_PARAMETER_ve] = 0.5; + initialParameters[mitk::ExtendedToftsModel::POSITION_PARAMETER_vp] = 0.05; + + return initialParameters; +}; + +mitk::ExtendedToftsModelParameterizer::ExtendedToftsModelParameterizer() +{ +}; + +mitk::ExtendedToftsModelParameterizer::~ExtendedToftsModelParameterizer() +{ +}; diff --git a/Modules/Pharmacokinetics/src/Models/mitkNumericTwoCompartmentExchangeModel.cpp b/Modules/Pharmacokinetics/src/Models/mitkNumericTwoCompartmentExchangeModel.cpp new file mode 100644 index 0000000000..8d6fe16622 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkNumericTwoCompartmentExchangeModel.cpp @@ -0,0 +1,290 @@ +/*=================================================================== + +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 "mitkNumericTwoCompartmentExchangeModel.h" +#include "mitkAIFParametrizerHelper.h" +#include "mitkTimeGridHelper.h" +#include "mitkTwoCompartmentExchangeModelDifferentialEquations.h" +#include +#include +#include + +const std::string mitk::NumericTwoCompartmentExchangeModel::MODEL_DISPLAY_NAME = + "Numeric Two Compartment Exchange Model"; + +const std::string mitk::NumericTwoCompartmentExchangeModel::NAME_PARAMETER_F = "F"; +const std::string mitk::NumericTwoCompartmentExchangeModel::NAME_PARAMETER_PS = "PS"; +const std::string mitk::NumericTwoCompartmentExchangeModel::NAME_PARAMETER_ve = "ve"; +const std::string mitk::NumericTwoCompartmentExchangeModel::NAME_PARAMETER_vp = "vp"; + +const std::string mitk::NumericTwoCompartmentExchangeModel::UNIT_PARAMETER_F = "ml/min/100ml"; +const std::string mitk::NumericTwoCompartmentExchangeModel::UNIT_PARAMETER_PS = "ml/min/100ml"; +const std::string mitk::NumericTwoCompartmentExchangeModel::UNIT_PARAMETER_ve = "ml/ml"; +const std::string mitk::NumericTwoCompartmentExchangeModel::UNIT_PARAMETER_vp = "ml/ml"; + +const unsigned int mitk::NumericTwoCompartmentExchangeModel::POSITION_PARAMETER_F = 0; +const unsigned int mitk::NumericTwoCompartmentExchangeModel::POSITION_PARAMETER_PS = 1; +const unsigned int mitk::NumericTwoCompartmentExchangeModel::POSITION_PARAMETER_ve = 2; +const unsigned int mitk::NumericTwoCompartmentExchangeModel::POSITION_PARAMETER_vp = 3; + +const unsigned int mitk::NumericTwoCompartmentExchangeModel::NUMBER_OF_PARAMETERS = 4; + +const std::string mitk::NumericTwoCompartmentExchangeModel::NAME_STATIC_PARAMETER_ODEINTStepSize = "ODEIntStepSize"; + + +std::string mitk::NumericTwoCompartmentExchangeModel::GetModelDisplayName() const +{ + return MODEL_DISPLAY_NAME; +}; + +std::string mitk::NumericTwoCompartmentExchangeModel::GetModelType() const +{ + return "Perfusion.MR"; +}; + + +mitk::NumericTwoCompartmentExchangeModel::NumericTwoCompartmentExchangeModel() +{ + +} + +mitk::NumericTwoCompartmentExchangeModel::~NumericTwoCompartmentExchangeModel() +{ + +} + +mitk::NumericTwoCompartmentExchangeModel::ParameterNamesType mitk::NumericTwoCompartmentExchangeModel::GetStaticParameterNames() const +{ + ParameterNamesType result; + + result.push_back(NAME_STATIC_PARAMETER_AIF); + result.push_back(NAME_STATIC_PARAMETER_AIFTimeGrid); + result.push_back(NAME_STATIC_PARAMETER_ODEINTStepSize); + + return result; +} + +mitk::NumericTwoCompartmentExchangeModel::ParametersSizeType mitk::NumericTwoCompartmentExchangeModel::GetNumberOfStaticParameters() +const +{ + return 3; +} + + +void mitk::NumericTwoCompartmentExchangeModel::SetStaticParameter(const ParameterNameType& name, + const StaticParameterValuesType& values) +{ + if (name == NAME_STATIC_PARAMETER_AIF) + { + AterialInputFunctionType aif = mitk::convertParameterToArray(values); + + SetAterialInputFunctionValues(aif); + } + + if (name == NAME_STATIC_PARAMETER_AIFTimeGrid) + { + TimeGridType timegrid = mitk::convertParameterToArray(values); + + SetAterialInputFunctionTimeGrid(timegrid); + } + + if (name == NAME_STATIC_PARAMETER_ODEINTStepSize) + { + SetODEINTStepSize(values[0]); + } +}; + +mitk::NumericTwoCompartmentExchangeModel::StaticParameterValuesType mitk::NumericTwoCompartmentExchangeModel::GetStaticParameterValue( + const ParameterNameType& name) const +{ + StaticParameterValuesType result; + + if (name == NAME_STATIC_PARAMETER_AIF) + { + result = mitk::convertArrayToParameter(this->m_AterialInputFunctionValues); + } + + if (name == NAME_STATIC_PARAMETER_AIFTimeGrid) + { + result = mitk::convertArrayToParameter(this->m_AterialInputFunctionTimeGrid); + } + if (name == NAME_STATIC_PARAMETER_ODEINTStepSize) + { + result.push_back(GetODEINTStepSize()); + } + + return result; +}; + + +mitk::NumericTwoCompartmentExchangeModel::ParameterNamesType +mitk::NumericTwoCompartmentExchangeModel::GetParameterNames() const +{ + ParameterNamesType result; + + result.push_back(NAME_PARAMETER_F); + result.push_back(NAME_PARAMETER_PS); + result.push_back(NAME_PARAMETER_ve); + result.push_back(NAME_PARAMETER_vp); + + return result; +} + +mitk::NumericTwoCompartmentExchangeModel::ParametersSizeType +mitk::NumericTwoCompartmentExchangeModel::GetNumberOfParameters() const +{ + return NUMBER_OF_PARAMETERS; +} + + +mitk::NumericTwoCompartmentExchangeModel::ParamterUnitMapType +mitk::NumericTwoCompartmentExchangeModel::GetParameterUnits() const +{ + ParamterUnitMapType result; + + result.insert(std::make_pair(NAME_PARAMETER_F, UNIT_PARAMETER_F)); + result.insert(std::make_pair(NAME_PARAMETER_PS, UNIT_PARAMETER_PS)); + result.insert(std::make_pair(NAME_PARAMETER_vp, UNIT_PARAMETER_vp)); + result.insert(std::make_pair(NAME_PARAMETER_ve, UNIT_PARAMETER_ve)); + + return result; +}; + +mitk::NumericTwoCompartmentExchangeModel::ModelResultType +mitk::NumericTwoCompartmentExchangeModel::ComputeModelfunction(const ParametersType& parameters) +const +{ + typedef itk::Array ConcentrationCurveType; + typedef std::vector ConcentrationVectorType; + + if (this->m_TimeGrid.GetSize() == 0) + { + itkExceptionMacro("No Time Grid Set! Cannot Calculate Signal"); + } + + AterialInputFunctionType aterialInputFunction; + aterialInputFunction = GetAterialInputFunction(this->m_TimeGrid); + + unsigned int timeSteps = this->m_TimeGrid.GetSize(); + + /** @brief Boost::numeric::odeint works with type std::vector thus, aif and grid are converted to ModelParameters( of type std::vector) + */ + mitk::TwoCompartmentExchangeModelDifferentialEquations::AIFType aif = mitk::convertArrayToParameter( + aterialInputFunction); + mitk::TwoCompartmentExchangeModelDifferentialEquations::AIFType grid = + mitk::convertArrayToParameter(m_TimeGrid); + + mitk::TwoCompartmentExchangeModelDifferentialEquations::AIFType aifODE = aif; + aifODE.push_back(aif[timeSteps - 1]); + mitk::TwoCompartmentExchangeModelDifferentialEquations::AIFType gridODE = grid; + gridODE.push_back(grid[timeSteps - 1] + (grid[timeSteps - 1] - grid[timeSteps - 2])); + + + + //Model Parameters + double F = (double) parameters[POSITION_PARAMETER_F] / 6000.0; + double PS = (double) parameters[POSITION_PARAMETER_PS] / 6000.0; + double ve = (double) parameters[POSITION_PARAMETER_ve]; + double vp = (double) parameters[POSITION_PARAMETER_vp]; + + + /** @brief Initialize class TwoCompartmentExchangeModelDifferentialEquations defining the differential equations. AIF and Grid must be set so that at step t the aterial Concentration Ca(t) can be interpolated from AIF*/ + mitk::TwoCompartmentExchangeModelDifferentialEquations ode; + ode.initialize(F, PS, ve, vp); + ode.setAIF(aifODE); + ode.setAIFTimeGrid(gridODE); + + state_type x(2); + x[0] = 0.0; + x[1] = 0.0; + typedef boost::numeric::odeint::runge_kutta_cash_karp54 error_stepper_type; + //typedef boost::numeric::odeint::runge_kutta4< state_type > stepper_type; + + /** @brief Results of odeeint x[0] and x[1]*/ + ConcentrationVectorType Cp; + ConcentrationVectorType Ce; + ConcentrationVectorType odeTimeGrid; + + error_stepper_type stepper; + + + /** @brief Stepsize. Should be adapted by stepper (runge_kutta_cash_karp54) */ +// const double dt = 0.05; + const double dt = this->m_ODEINTStepSize; + + + /** @brief perform Step t -> t+dt to calculate approximate value x(t+dt)*/ + for (double t = 0.0; t < this->m_TimeGrid(this->m_TimeGrid.GetSize() - 1) - 2*dt; t += dt) + { + stepper.do_step(ode, x, t, dt); + Cp.push_back(x[0]); + Ce.push_back(x[1]); + odeTimeGrid.push_back(t); + } + + /** @brief transfom result of Differential equations back to itk::Array and interpolate to m_TimeGrid (they are calculated on a different grid defined by stepsize of odeint)*/ + ConcentrationCurveType plasmaConcentration = mitk::convertParameterToArray(Cp); + ConcentrationCurveType EESConcentration = mitk::convertParameterToArray(Ce); + ConcentrationCurveType rungeKuttaTimeGrid = mitk::convertParameterToArray(odeTimeGrid); + + mitk::ModelBase::ModelResultType C_Plasma = mitk::InterpolateSignalToNewTimeGrid(plasmaConcentration, rungeKuttaTimeGrid, m_TimeGrid); + mitk::ModelBase::ModelResultType C_EES = mitk::InterpolateSignalToNewTimeGrid(EESConcentration, rungeKuttaTimeGrid, m_TimeGrid); + + + //Signal that will be returned by ComputeModelFunction + mitk::ModelBase::ModelResultType signal(timeSteps); + signal.fill(0.0); + + mitk::ModelBase::ModelResultType::iterator signalPos = signal.begin(); + mitk::ModelBase::ModelResultType::const_iterator CePos = C_EES.begin(); + + mitk::ModelBase::ModelResultType::const_iterator t = this->m_TimeGrid.begin(); + mitk::ModelBase::ModelResultType::const_iterator Cin = aterialInputFunction.begin(); + + + + for (mitk::ModelBase::ModelResultType::const_iterator CpPos = C_Plasma.begin(); + CpPos != C_Plasma.end(); ++CpPos, ++CePos, ++signalPos, ++t, ++Cin) + { + *signalPos = vp * (*CpPos) + ve * (*CePos); + + } + + return signal; + +} + + + + +itk::LightObject::Pointer mitk::NumericTwoCompartmentExchangeModel::InternalClone() const +{ + NumericTwoCompartmentExchangeModel::Pointer newClone = NumericTwoCompartmentExchangeModel::New(); + + newClone->SetTimeGrid(this->m_TimeGrid); + + return newClone.GetPointer(); +} + +void mitk::NumericTwoCompartmentExchangeModel::PrintSelf(std::ostream& os, + ::itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + + +} + + diff --git a/Modules/Pharmacokinetics/src/Models/mitkNumericTwoCompartmentExchangeModelFactory.cpp b/Modules/Pharmacokinetics/src/Models/mitkNumericTwoCompartmentExchangeModelFactory.cpp new file mode 100644 index 0000000000..9a80c9c274 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkNumericTwoCompartmentExchangeModelFactory.cpp @@ -0,0 +1,58 @@ +/*=================================================================== + +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 "mitkNumericTwoCompartmentExchangeModelFactory.h" + + +#include "mitkNumericTwoCompartmentExchangeModelParameterizer.h" +#include "mitkAIFParametrizerHelper.h" + +mitk::NumericTwoCompartmentExchangeModelFactory::NumericTwoCompartmentExchangeModelFactory() +{ +}; + +mitk::NumericTwoCompartmentExchangeModelFactory::~NumericTwoCompartmentExchangeModelFactory() +{ +}; + +mitk::ModelParameterizerBase::Pointer +mitk::NumericTwoCompartmentExchangeModelFactory::DoCreateParameterizer( + const modelFit::ModelFitInfo* fit) +const +{ + mitk::ModelParameterizerBase::Pointer result; + + ModelParameterizerType::Pointer modelParameterizer = + ModelParameterizerType::New(); + + modelFit::StaticParameterMap::ValueType aif = fit->staticParamMap.Get( + ModelType::NAME_STATIC_PARAMETER_AIF); + + modelParameterizer->SetAIF(mitk::convertParameterToArray(aif)); + + modelFit::StaticParameterMap::ValueType aifGrid = fit->staticParamMap.Get( + ModelType::NAME_STATIC_PARAMETER_AIFTimeGrid); + modelParameterizer->SetAIFTimeGrid(mitk::convertParameterToArray(aifGrid)); + + modelFit::StaticParameterMap::ValueType odeStepSize = fit->staticParamMap.Get( + ModelType::NAME_STATIC_PARAMETER_ODEINTStepSize); + modelParameterizer->SetODEINTStepSize(odeStepSize[0]); + + + result = modelParameterizer.GetPointer(); + + return result; +}; diff --git a/Modules/Pharmacokinetics/src/Models/mitkNumericTwoCompartmentExchangeModelParameterizer.cpp b/Modules/Pharmacokinetics/src/Models/mitkNumericTwoCompartmentExchangeModelParameterizer.cpp new file mode 100644 index 0000000000..40a6a83dc0 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkNumericTwoCompartmentExchangeModelParameterizer.cpp @@ -0,0 +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. + +===================================================================*/ + +#include "mitkNumericTwoCompartmentExchangeModelParameterizer.h" + +mitk::NumericTwoCompartmentExchangeModelParameterizer::ParametersType +mitk::NumericTwoCompartmentExchangeModelParameterizer::GetDefaultInitialParameterization() const +{ + ParametersType initialParameters; + initialParameters.SetSize(4); + initialParameters[mitk::NumericTwoCompartmentExchangeModel::POSITION_PARAMETER_PS] = 5.0; + initialParameters[mitk::NumericTwoCompartmentExchangeModel::POSITION_PARAMETER_F] = 20.0; + initialParameters[mitk::NumericTwoCompartmentExchangeModel::POSITION_PARAMETER_ve] = 0.1; + initialParameters[mitk::NumericTwoCompartmentExchangeModel::POSITION_PARAMETER_vp] = 0.04; + + return initialParameters; +}; + +mitk::NumericTwoCompartmentExchangeModelParameterizer::NumericTwoCompartmentExchangeModelParameterizer() +{ +}; + +mitk::NumericTwoCompartmentExchangeModelParameterizer::~NumericTwoCompartmentExchangeModelParameterizer() +{ +}; + +mitk::NumericTwoCompartmentExchangeModelParameterizer::StaticParameterMapType mitk::NumericTwoCompartmentExchangeModelParameterizer::GetGlobalStaticParameters() const +{ + StaticParameterMapType result; + StaticParameterValuesType valuesAIF = mitk::convertArrayToParameter(this->m_AIF); + StaticParameterValuesType valuesAIFGrid = mitk::convertArrayToParameter(this->m_AIFTimeGrid); + StaticParameterValuesType values; + values.push_back(m_ODEINTStepSize); + + result.insert(std::make_pair(ModelType::NAME_STATIC_PARAMETER_AIF, valuesAIF)); + result.insert(std::make_pair(ModelType::NAME_STATIC_PARAMETER_AIFTimeGrid, valuesAIFGrid)); + result.insert(std::make_pair(ModelType::NAME_STATIC_PARAMETER_ODEINTStepSize, values)); + + return result; +}; diff --git a/Modules/Pharmacokinetics/src/Models/mitkNumericTwoTissueCompartmentModel.cpp b/Modules/Pharmacokinetics/src/Models/mitkNumericTwoTissueCompartmentModel.cpp new file mode 100644 index 0000000000..0da93c4115 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkNumericTwoTissueCompartmentModel.cpp @@ -0,0 +1,220 @@ +/*=================================================================== + +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 "mitkNumericTwoTissueCompartmentModel.h" +#include "mitkAIFParametrizerHelper.h" +#include "mitkTimeGridHelper.h" +#include "mitkTwoTissueCompartmentModelDifferentialEquations.h" +#include +#include +#include + +const std::string mitk::NumericTwoTissueCompartmentModel::MODEL_DISPLAY_NAME = + "Numeric Two Tissue Compartment Model"; + +const std::string mitk::NumericTwoTissueCompartmentModel::NAME_PARAMETER_K1 = "K1"; +const std::string mitk::NumericTwoTissueCompartmentModel::NAME_PARAMETER_k2 = "k2"; +const std::string mitk::NumericTwoTissueCompartmentModel::NAME_PARAMETER_k3 = "k3"; +const std::string mitk::NumericTwoTissueCompartmentModel::NAME_PARAMETER_k4 = "k4"; +const std::string mitk::NumericTwoTissueCompartmentModel::NAME_PARAMETER_VB = "V_B"; + +const std::string mitk::NumericTwoTissueCompartmentModel::UNIT_PARAMETER_K1 = "1/min"; +const std::string mitk::NumericTwoTissueCompartmentModel::UNIT_PARAMETER_k2 = "1/min"; +const std::string mitk::NumericTwoTissueCompartmentModel::UNIT_PARAMETER_k3 = "1/min"; +const std::string mitk::NumericTwoTissueCompartmentModel::UNIT_PARAMETER_k4 = "1/min"; +const std::string mitk::NumericTwoTissueCompartmentModel::UNIT_PARAMETER_VB = "ml/ml"; + +const unsigned int mitk::NumericTwoTissueCompartmentModel::POSITION_PARAMETER_K1 = 0; +const unsigned int mitk::NumericTwoTissueCompartmentModel::POSITION_PARAMETER_k2 = 1; +const unsigned int mitk::NumericTwoTissueCompartmentModel::POSITION_PARAMETER_k3 = 2; +const unsigned int mitk::NumericTwoTissueCompartmentModel::POSITION_PARAMETER_k4 = 3; +const unsigned int mitk::NumericTwoTissueCompartmentModel::POSITION_PARAMETER_VB = 4; + +const unsigned int mitk::NumericTwoTissueCompartmentModel::NUMBER_OF_PARAMETERS = 5; + + +std::string mitk::NumericTwoTissueCompartmentModel::GetModelDisplayName() const +{ + return MODEL_DISPLAY_NAME; +}; + +std::string mitk::NumericTwoTissueCompartmentModel::GetModelType() const +{ + return "Dynamic.PET"; +}; + +mitk::NumericTwoTissueCompartmentModel::NumericTwoTissueCompartmentModel() +{ + +} + +mitk::NumericTwoTissueCompartmentModel::~NumericTwoTissueCompartmentModel() +{ + +} + +mitk::NumericTwoTissueCompartmentModel::ParameterNamesType +mitk::NumericTwoTissueCompartmentModel::GetParameterNames() const +{ + ParameterNamesType result; + + result.push_back(NAME_PARAMETER_K1); + result.push_back(NAME_PARAMETER_k2); + result.push_back(NAME_PARAMETER_k3); + result.push_back(NAME_PARAMETER_k4); + result.push_back(NAME_PARAMETER_VB); + + return result; +} + +mitk::NumericTwoTissueCompartmentModel::ParametersSizeType +mitk::NumericTwoTissueCompartmentModel::GetNumberOfParameters() const +{ + return NUMBER_OF_PARAMETERS; +} + +mitk::NumericTwoTissueCompartmentModel::ParamterUnitMapType +mitk::NumericTwoTissueCompartmentModel::GetParameterUnits() const +{ + ParamterUnitMapType result; + + result.insert(std::make_pair(NAME_PARAMETER_K1, UNIT_PARAMETER_K1)); + result.insert(std::make_pair(NAME_PARAMETER_k2, UNIT_PARAMETER_k2)); + result.insert(std::make_pair(NAME_PARAMETER_k3, UNIT_PARAMETER_k3)); + result.insert(std::make_pair(NAME_PARAMETER_k4, UNIT_PARAMETER_k4)); + result.insert(std::make_pair(NAME_PARAMETER_VB, UNIT_PARAMETER_VB)); + + return result; +}; + + +mitk::NumericTwoTissueCompartmentModel::ModelResultType +mitk::NumericTwoTissueCompartmentModel::ComputeModelfunction(const ParametersType& parameters) const +{ + typedef itk::Array ConcentrationCurveType; + typedef std::vector ConcentrationVectorType; + + if (this->m_TimeGrid.GetSize() == 0) + { + itkExceptionMacro("No Time Grid Set! Cannot Calculate Signal"); + } + + AterialInputFunctionType aterialInputFunction; + aterialInputFunction = GetAterialInputFunction(this->m_TimeGrid); + + unsigned int timeSteps = this->m_TimeGrid.GetSize(); + + /** @brief Boost::numeric::odeint works with type std::vector thus, aif and grid are converted to ModelParameters( of type std::vector) + */ + mitk::TwoTissueCompartmentModelDifferentialEquations::AIFType aif = mitk::convertArrayToParameter( + aterialInputFunction); + mitk::TwoTissueCompartmentModelDifferentialEquations::AIFType grid = mitk::convertArrayToParameter( + m_TimeGrid); + + mitk::TwoTissueCompartmentModelDifferentialEquations::AIFType aifODE = aif; + aifODE.push_back(aif[timeSteps - 1]); + mitk::TwoTissueCompartmentModelDifferentialEquations::AIFType gridODE = grid; + gridODE.push_back(grid[timeSteps - 1] + (grid[timeSteps - 1] - grid[timeSteps - 2])); + + //Model Parameters + double K1 = (double)parameters[POSITION_PARAMETER_K1] / 60.0; + double k2 = (double)parameters[POSITION_PARAMETER_k2] / 60.0; + double k3 = (double)parameters[POSITION_PARAMETER_k3] / 60.0; + double k4 = (double)parameters[POSITION_PARAMETER_k4] / 60.0; + double VB = parameters[POSITION_PARAMETER_VB]; + + + /** @brief Initialize class TwpTissueCompartmentModelDifferentialEquations defining the differential equations. AIF and Grid must be set so that at step t the aterial Concentration Ca(t) can be interpolated from AIF*/ + mitk::TwoTissueCompartmentModelDifferentialEquations ode; + ode.initialize(K1, k2, k3, k4); + ode.setAIF(aifODE); + ode.setAIFTimeGrid(gridODE); + + state_type x(2); + x[0] = 0.0; + x[1] = 0.0; + typedef boost::numeric::odeint::runge_kutta_cash_karp54 error_stepper_type; + //typedef boost::numeric::odeint::runge_kutta4< state_type > stepper_type; + + /** @brief Results of odeeint x[0] and x[1]*/ + ConcentrationVectorType C1; + ConcentrationVectorType C2; + ConcentrationVectorType odeTimeGrid; + + error_stepper_type stepper; + /** @brief Stepsize. Should be adapted by stepper (runge_kutta_cash_karp54) */ + const double dt = 0.1; + /** @brief perform Step t -> t+dt to calculate approximate value x(t+dt)*/ + + double T = this->m_TimeGrid(timeSteps - 1) + (grid[timeSteps - 1] - grid[timeSteps - 2]); + + for (double t = 0.0; t < T; t += dt) + { + stepper.do_step(ode, x, t, dt); + C1.push_back(x[0]); + C2.push_back(x[1]); + odeTimeGrid.push_back(t); + + } + + /** @brief transfom result of Differential equations back to itk::Array and interpolate to m_TimeGrid (they are calculated on a different grid defined by stepsize of odeint)*/ + ConcentrationCurveType ConcentrationCompartment1 = mitk::convertParameterToArray(C1); + ConcentrationCurveType ConcentrationCompartment2 = mitk::convertParameterToArray(C2); + ConcentrationCurveType rungeKuttaTimeGrid = mitk::convertParameterToArray(odeTimeGrid); + + mitk::ModelBase::ModelResultType C_1 = mitk::InterpolateSignalToNewTimeGrid( + ConcentrationCompartment1, rungeKuttaTimeGrid, m_TimeGrid); + mitk::ModelBase::ModelResultType C_2 = mitk::InterpolateSignalToNewTimeGrid( + ConcentrationCompartment2, rungeKuttaTimeGrid, m_TimeGrid); + + + //Signal that will be returned by ComputeModelFunction + mitk::ModelBase::ModelResultType signal(timeSteps); + signal.fill(0.0); + mitk::ModelBase::ModelResultType::iterator signalPos = signal.begin(); + mitk::ModelBase::ModelResultType::const_iterator C1Pos = C_1.begin(); + mitk::ModelBase::ModelResultType::const_iterator C2Pos = C_2.begin(); + + + for (AterialInputFunctionType::const_iterator aifpos = aterialInputFunction.begin(); + aifpos != aterialInputFunction.end(); ++aifpos, ++C1Pos, ++C2Pos, ++signalPos) + { + *signalPos = VB * (*aifpos) + (1 - VB) * (*C1Pos + *C2Pos); + } + + return signal; + +} + +itk::LightObject::Pointer mitk::NumericTwoTissueCompartmentModel::InternalClone() const +{ + NumericTwoTissueCompartmentModel::Pointer newClone = NumericTwoTissueCompartmentModel::New(); + + newClone->SetTimeGrid(this->m_TimeGrid); + + return newClone.GetPointer(); +} + +void mitk::NumericTwoTissueCompartmentModel::PrintSelf(std::ostream& os, ::itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + + +} + + + + diff --git a/Modules/Pharmacokinetics/src/Models/mitkNumericTwoTissueCompartmentModelFactory.cpp b/Modules/Pharmacokinetics/src/Models/mitkNumericTwoTissueCompartmentModelFactory.cpp new file mode 100644 index 0000000000..446cd7dccd --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkNumericTwoTissueCompartmentModelFactory.cpp @@ -0,0 +1,29 @@ +/*=================================================================== + +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 "mitkNumericTwoTissueCompartmentModelFactory.h" + +#include "mitkNumericTwoTissueCompartmentModelParameterizer.h" +#include "mitkAIFParametrizerHelper.h" + +mitk::NumericTwoTissueCompartmentModelFactory::NumericTwoTissueCompartmentModelFactory() +{ +}; + +mitk::NumericTwoTissueCompartmentModelFactory::~NumericTwoTissueCompartmentModelFactory() +{ +}; + diff --git a/Modules/Pharmacokinetics/src/Models/mitkNumericTwoTissueCompartmentModelParameterizer.cpp b/Modules/Pharmacokinetics/src/Models/mitkNumericTwoTissueCompartmentModelParameterizer.cpp new file mode 100644 index 0000000000..6274fe8497 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkNumericTwoTissueCompartmentModelParameterizer.cpp @@ -0,0 +1,39 @@ +/*=================================================================== + +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 "mitkNumericTwoTissueCompartmentModelParameterizer.h" + +mitk::NumericTwoTissueCompartmentModelParameterizer::ParametersType +mitk::NumericTwoTissueCompartmentModelParameterizer::GetDefaultInitialParameterization() const +{ + ParametersType initialParameters; + initialParameters.SetSize(5); + initialParameters[mitk::NumericTwoTissueCompartmentModel::POSITION_PARAMETER_K1] = 0.23; + initialParameters[mitk::NumericTwoTissueCompartmentModel::POSITION_PARAMETER_k2] = 0.4; + initialParameters[mitk::NumericTwoTissueCompartmentModel::POSITION_PARAMETER_k3] = 0.13; + initialParameters[mitk::NumericTwoTissueCompartmentModel::POSITION_PARAMETER_k4] = 0.15; + initialParameters[mitk::NumericTwoTissueCompartmentModel::POSITION_PARAMETER_VB] = 0.03; + + return initialParameters; +}; + +mitk::NumericTwoTissueCompartmentModelParameterizer::NumericTwoTissueCompartmentModelParameterizer() +{ +}; + +mitk::NumericTwoTissueCompartmentModelParameterizer::~NumericTwoTissueCompartmentModelParameterizer() +{ +}; \ No newline at end of file diff --git a/Modules/Pharmacokinetics/src/Models/mitkOneTissueCompartmentModel.cpp b/Modules/Pharmacokinetics/src/Models/mitkOneTissueCompartmentModel.cpp new file mode 100644 index 0000000000..3514eeaef2 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkOneTissueCompartmentModel.cpp @@ -0,0 +1,145 @@ +/*=================================================================== + +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 "mitkOneTissueCompartmentModel.h" +#include "mitkConvolutionHelper.h" +#include +#include + +const std::string mitk::OneTissueCompartmentModel::MODEL_DISPLAY_NAME = "One Tissue Compartment Model"; + +const std::string mitk::OneTissueCompartmentModel::NAME_PARAMETER_k1 = "K1"; +const std::string mitk::OneTissueCompartmentModel::NAME_PARAMETER_k2 = "k2"; + +const std::string mitk::OneTissueCompartmentModel::UNIT_PARAMETER_k1 = "1/min"; +const std::string mitk::OneTissueCompartmentModel::UNIT_PARAMETER_k2 = "1/min"; + +const unsigned int mitk::OneTissueCompartmentModel::POSITION_PARAMETER_k1 = 0; +const unsigned int mitk::OneTissueCompartmentModel::POSITION_PARAMETER_k2 = 1; + +const unsigned int mitk::OneTissueCompartmentModel::NUMBER_OF_PARAMETERS = 2; + +std::string mitk::OneTissueCompartmentModel::GetModelDisplayName() const +{ + return MODEL_DISPLAY_NAME; +}; + +std::string mitk::OneTissueCompartmentModel::GetModelType() const +{ + return "Dynamic.PET"; +}; + +mitk::OneTissueCompartmentModel::OneTissueCompartmentModel() +{ + +} + +mitk::OneTissueCompartmentModel::~OneTissueCompartmentModel() +{ + +} + +mitk::OneTissueCompartmentModel::ParameterNamesType mitk::OneTissueCompartmentModel::GetParameterNames() const +{ + ParameterNamesType result; + + result.push_back(NAME_PARAMETER_k1); + result.push_back(NAME_PARAMETER_k2); + + return result; +} + +mitk::OneTissueCompartmentModel::ParametersSizeType mitk::OneTissueCompartmentModel::GetNumberOfParameters() +const +{ + return NUMBER_OF_PARAMETERS; +} + + +mitk::OneTissueCompartmentModel::ParamterUnitMapType +mitk::OneTissueCompartmentModel::GetParameterUnits() const +{ + ParamterUnitMapType result; + + result.insert(std::make_pair(NAME_PARAMETER_k1, UNIT_PARAMETER_k1)); + result.insert(std::make_pair(NAME_PARAMETER_k2, UNIT_PARAMETER_k2)); + + return result; +}; + +mitk::OneTissueCompartmentModel::ModelResultType mitk::OneTissueCompartmentModel::ComputeModelfunction( + const ParametersType& parameters) const +{ + typedef itk::Array ResidueFunctionType; + + + if (this->m_TimeGrid.GetSize() == 0) + { + itkExceptionMacro("No Time Grid Set! Cannot Calculate Signal"); + } + + AterialInputFunctionType aterialInputFunction; + aterialInputFunction = GetAterialInputFunction(this->m_TimeGrid); + + + + unsigned int timeSteps = this->m_TimeGrid.GetSize(); + + //Model Parameters + double K1 = (double) parameters[POSITION_PARAMETER_k1] / 60.0; + double k2 = (double) parameters[POSITION_PARAMETER_k2] / 60.0; + + + + mitk::ModelBase::ModelResultType convolution = mitk::convoluteAIFWithExponential(this->m_TimeGrid, + aterialInputFunction, k2); + + //Signal that will be returned by ComputeModelFunction + mitk::ModelBase::ModelResultType signal(timeSteps); + signal.fill(0.0); + + mitk::ModelBase::ModelResultType::iterator signalPos = signal.begin(); + + + + for (mitk::ModelBase::ModelResultType::const_iterator res = convolution.begin(); res != convolution.end(); ++res, ++signalPos) + { + *signalPos = K1 * (*res); + } + + return signal; + +} + + + + +itk::LightObject::Pointer mitk::OneTissueCompartmentModel::InternalClone() const +{ + OneTissueCompartmentModel::Pointer newClone = OneTissueCompartmentModel::New(); + + newClone->SetTimeGrid(this->m_TimeGrid); + + return newClone.GetPointer(); +}; + +void mitk::OneTissueCompartmentModel::PrintSelf(std::ostream& os, ::itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + + +}; + diff --git a/Modules/Pharmacokinetics/src/Models/mitkOneTissueCompartmentModelFactory.cpp b/Modules/Pharmacokinetics/src/Models/mitkOneTissueCompartmentModelFactory.cpp new file mode 100644 index 0000000000..af01348e94 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkOneTissueCompartmentModelFactory.cpp @@ -0,0 +1,34 @@ +#include "mitkOneTissueCompartmentModelFactory.h" + +#include +#include +#include + +mitk::ConstraintCheckerBase::Pointer +mitk::OneTissueCompartmentModelFactory::CreateDefaultConstraints() const +{ + SimpleBarrierConstraintChecker::Pointer constraints = SimpleBarrierConstraintChecker::New(); + + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_k1, 0.0); + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_k2, 0.0); + + constraints->SetUpperBarrier (ModelType::POSITION_PARAMETER_k1, 1.0); + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_k2, 1.0); + + + return constraints.GetPointer(); +}; + +mitk::ModelParameterizerBase::ParametersType +mitk::OneTissueCompartmentModelFactory::GetDefaultInitialParameterization() const +{ + return OneTissueCompartmentModelParameterizer::New()->GetDefaultInitialParameterization(); +}; + +mitk::OneTissueCompartmentModelFactory::OneTissueCompartmentModelFactory() +{ +}; + +mitk::OneTissueCompartmentModelFactory::~OneTissueCompartmentModelFactory() +{ +}; diff --git a/Modules/Pharmacokinetics/src/Models/mitkOneTissueCompartmentModelParameterizer.cpp b/Modules/Pharmacokinetics/src/Models/mitkOneTissueCompartmentModelParameterizer.cpp new file mode 100644 index 0000000000..b1030c1ad1 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkOneTissueCompartmentModelParameterizer.cpp @@ -0,0 +1,36 @@ +/*=================================================================== + +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 "mitkOneTissueCompartmentModelParameterizer.h" + +mitk::OneTissueCompartmentModelParameterizer::ParametersType +mitk::OneTissueCompartmentModelParameterizer::GetDefaultInitialParameterization() const +{ + ParametersType initialParameters; + initialParameters.SetSize(2); + initialParameters[mitk::OneTissueCompartmentModel::POSITION_PARAMETER_k1] = 0.5; + initialParameters[mitk::OneTissueCompartmentModel::POSITION_PARAMETER_k2] = 0.5; + + return initialParameters; +}; + +mitk::OneTissueCompartmentModelParameterizer::OneTissueCompartmentModelParameterizer() +{ +}; + +mitk::OneTissueCompartmentModelParameterizer::~OneTissueCompartmentModelParameterizer() +{ +}; diff --git a/Modules/Pharmacokinetics/src/Models/mitkStandardToftsModel.cpp b/Modules/Pharmacokinetics/src/Models/mitkStandardToftsModel.cpp new file mode 100644 index 0000000000..b9df013da2 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkStandardToftsModel.cpp @@ -0,0 +1,175 @@ +/*=================================================================== + +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 "mitkStandardToftsModel.h" +#include "mitkConvolutionHelper.h" +#include +#include + +const std::string mitk::StandardToftsModel::MODEL_DISPLAY_NAME = "Standard Tofts Model"; + +const std::string mitk::StandardToftsModel::NAME_PARAMETER_Ktrans = "KTrans"; +const std::string mitk::StandardToftsModel::NAME_PARAMETER_ve = "ve"; + +const std::string mitk::StandardToftsModel::UNIT_PARAMETER_Ktrans = "ml/min/100ml"; +const std::string mitk::StandardToftsModel::UNIT_PARAMETER_ve = "ml/ml"; + +const unsigned int mitk::StandardToftsModel::POSITION_PARAMETER_Ktrans = 0; +const unsigned int mitk::StandardToftsModel::POSITION_PARAMETER_ve = 1; + +const unsigned int mitk::StandardToftsModel::NUMBER_OF_PARAMETERS = 2; + +std::string mitk::StandardToftsModel::GetModelDisplayName() const +{ + return MODEL_DISPLAY_NAME; +}; + +std::string mitk::StandardToftsModel::GetModelType() const +{ + return "Perfusion.MR"; +}; + +mitk::StandardToftsModel::StandardToftsModel() +{ + +} + +mitk::StandardToftsModel::~StandardToftsModel() +{ + +} + +mitk::StandardToftsModel::ParameterNamesType mitk::StandardToftsModel::GetParameterNames() const +{ + ParameterNamesType result; + + result.push_back(NAME_PARAMETER_Ktrans); + result.push_back(NAME_PARAMETER_ve); + + return result; +} + +mitk::StandardToftsModel::ParametersSizeType mitk::StandardToftsModel::GetNumberOfParameters() +const +{ + return NUMBER_OF_PARAMETERS; +} + +mitk::StandardToftsModel::ParamterUnitMapType mitk::StandardToftsModel::GetParameterUnits() const +{ + ParamterUnitMapType result; + + result.insert(std::make_pair(NAME_PARAMETER_Ktrans, UNIT_PARAMETER_Ktrans)); + result.insert(std::make_pair(NAME_PARAMETER_ve, UNIT_PARAMETER_ve)); + + return result; +}; + +mitk::StandardToftsModel::ParameterNamesType +mitk::StandardToftsModel::GetDerivedParameterNames() const +{ + ParameterNamesType result; + result.push_back("kep"); + return result; +}; + +mitk::StandardToftsModel::ParametersSizeType +mitk::StandardToftsModel::GetNumberOfDerivedParameters() const +{ + return 1; +}; + +mitk::StandardToftsModel::ParamterUnitMapType mitk::StandardToftsModel::GetDerivedParameterUnits() const +{ + ParamterUnitMapType result; + + result.insert(std::make_pair("kep", "1/min")); + + return result; +}; + +mitk::StandardToftsModel::ModelResultType mitk::StandardToftsModel::ComputeModelfunction( + const ParametersType& parameters) const +{ + typedef itk::Array ResidueFunctionType; + + + if (this->m_TimeGrid.GetSize() == 0) + { + itkExceptionMacro("No Time Grid Set! Cannot Calculate Signal"); + } + + AterialInputFunctionType aterialInputFunction; + aterialInputFunction = GetAterialInputFunction(this->m_TimeGrid); + + + + unsigned int timeSteps = this->m_TimeGrid.GetSize(); + + //Model Parameters + double ktrans = parameters[POSITION_PARAMETER_Ktrans] / 6000.0; + double ve = parameters[POSITION_PARAMETER_ve]; + + + double lambda = ktrans / ve; + + mitk::ModelBase::ModelResultType convolution = mitk::convoluteAIFWithExponential(this->m_TimeGrid, + aterialInputFunction, lambda); + + //Signal that will be returned by ComputeModelFunction + mitk::ModelBase::ModelResultType signal(timeSteps); + signal.fill(0.0); + + mitk::ModelBase::ModelResultType::iterator signalPos = signal.begin(); + mitk::ModelBase::ModelResultType::const_iterator res = convolution.begin(); + + + for (AterialInputFunctionType::iterator Cp = aterialInputFunction.begin(); + Cp != aterialInputFunction.end(); ++res, ++signalPos, ++Cp) + { + *signalPos = ktrans * (*res); + } + + return signal; + +} + + +mitk::ModelBase::DerivedParameterMapType mitk::StandardToftsModel::ComputeDerivedParameters( + const mitk::ModelBase::ParametersType& parameters) const +{ + DerivedParameterMapType result; + double kep = parameters[POSITION_PARAMETER_Ktrans] / parameters[POSITION_PARAMETER_ve]; + result.insert(std::make_pair("kep", kep)); + return result; +}; + +itk::LightObject::Pointer mitk::StandardToftsModel::InternalClone() const +{ + StandardToftsModel::Pointer newClone = StandardToftsModel::New(); + + newClone->SetTimeGrid(this->m_TimeGrid); + + return newClone.GetPointer(); +}; + +void mitk::StandardToftsModel::PrintSelf(std::ostream& os, ::itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + + +}; + diff --git a/Modules/Pharmacokinetics/src/Models/mitkStandardToftsModelFactory.cpp b/Modules/Pharmacokinetics/src/Models/mitkStandardToftsModelFactory.cpp new file mode 100644 index 0000000000..0eaf64f087 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkStandardToftsModelFactory.cpp @@ -0,0 +1,28 @@ +#include "mitkStandardToftsModelFactory.h" + +#include +#include +#include + +mitk::ConstraintCheckerBase::Pointer +mitk::StandardToftsModelFactory::CreateDefaultConstraints() const +{ + SimpleBarrierConstraintChecker::Pointer constraints = SimpleBarrierConstraintChecker::New(); + + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_ve, 0.0); + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_ve, 1.0); + + return constraints.GetPointer(); +}; + +mitk::ModelParameterizerBase::ParametersType +mitk::StandardToftsModelFactory::GetDefaultInitialParameterization() const +{ + return StandardToftsModelParameterizer::New()->GetDefaultInitialParameterization(); +}; + +mitk::StandardToftsModelFactory::StandardToftsModelFactory() += default; + +mitk::StandardToftsModelFactory::~StandardToftsModelFactory() += default; diff --git a/Modules/Pharmacokinetics/src/Models/mitkStandardToftsModelParameterizer.cpp b/Modules/Pharmacokinetics/src/Models/mitkStandardToftsModelParameterizer.cpp new file mode 100644 index 0000000000..b4d54e0018 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkStandardToftsModelParameterizer.cpp @@ -0,0 +1,36 @@ +/*=================================================================== + +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 "mitkStandardToftsModelParameterizer.h" + +mitk::StandardToftsModelParameterizer::ParametersType +mitk::StandardToftsModelParameterizer::GetDefaultInitialParameterization() const +{ + ParametersType initialParameters; + initialParameters.SetSize(2); + initialParameters[mitk::StandardToftsModel::POSITION_PARAMETER_Ktrans] = 15; + initialParameters[mitk::StandardToftsModel::POSITION_PARAMETER_ve] = 0.5; + + return initialParameters; +}; + +mitk::StandardToftsModelParameterizer::StandardToftsModelParameterizer() +{ +}; + +mitk::StandardToftsModelParameterizer::~StandardToftsModelParameterizer() +{ +}; diff --git a/Modules/Pharmacokinetics/src/Models/mitkThreeStepLinearModel.cpp b/Modules/Pharmacokinetics/src/Models/mitkThreeStepLinearModel.cpp new file mode 100644 index 0000000000..ff7d3af9f0 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkThreeStepLinearModel.cpp @@ -0,0 +1,227 @@ +#include "mitkThreeStepLinearModel.h" + +const std::string mitk::ThreeStepLinearModel::MODEL_DISPLAY_NAME = "Three Step Linear Model"; + +const std::string mitk::ThreeStepLinearModel::NAME_PARAMETER_S0 = "Baseline"; +const std::string mitk::ThreeStepLinearModel::NAME_PARAMETER_t1 = "Time_point_1"; +const std::string mitk::ThreeStepLinearModel::NAME_PARAMETER_t2 = "Time_point_2"; +const std::string mitk::ThreeStepLinearModel::NAME_PARAMETER_a1 = "Slope_1"; +const std::string mitk::ThreeStepLinearModel::NAME_PARAMETER_a2 = "Slope_2"; + +// Assuming that Model is calculated on Signal intensities I +const std::string mitk::ThreeStepLinearModel::UNIT_PARAMETER_S0 = "I"; +const std::string mitk::ThreeStepLinearModel::UNIT_PARAMETER_t1 = "s"; +const std::string mitk::ThreeStepLinearModel::UNIT_PARAMETER_t2 = "s"; +const std::string mitk::ThreeStepLinearModel::UNIT_PARAMETER_a1 = "I/s"; +const std::string mitk::ThreeStepLinearModel::UNIT_PARAMETER_a2 = "I/s"; + +const unsigned int mitk::ThreeStepLinearModel::POSITION_PARAMETER_S0 = 0; +const unsigned int mitk::ThreeStepLinearModel::POSITION_PARAMETER_t1 = 1; +const unsigned int mitk::ThreeStepLinearModel::POSITION_PARAMETER_t2 = 2; +const unsigned int mitk::ThreeStepLinearModel::POSITION_PARAMETER_a1 = 3; +const unsigned int mitk::ThreeStepLinearModel::POSITION_PARAMETER_a2 = 4; + +const unsigned int mitk::ThreeStepLinearModel::NUMBER_OF_PARAMETERS = 5; + +std::string mitk::ThreeStepLinearModel::GetModelDisplayName() const +{ + return MODEL_DISPLAY_NAME; +}; + +std::string mitk::ThreeStepLinearModel::GetModelType() const +{ + return "Generic"; +}; + +mitk::ThreeStepLinearModel::FunctionStringType mitk::ThreeStepLinearModel::GetFunctionString() const +{ + return "Baseline if t= t1 && (*gridPos) <= t2) + { + *signalPos = a1*(*gridPos)+b1; + } + else + { + *signalPos = a2*(*gridPos)+b2; + } + } + + return signal; +}; + +mitk::ThreeStepLinearModel::ParameterNamesType mitk::ThreeStepLinearModel::GetStaticParameterNames() const +{ + ParameterNamesType result; + + return result; +} + +mitk::ThreeStepLinearModel::ParametersSizeType mitk::ThreeStepLinearModel::GetNumberOfStaticParameters() const +{ + return 0; +} + +void mitk::ThreeStepLinearModel::SetStaticParameter(const ParameterNameType& name, + const StaticParameterValuesType& values) +{ + //do nothing +}; + +mitk::ThreeStepLinearModel::StaticParameterValuesType mitk::ThreeStepLinearModel::GetStaticParameterValue( + const ParameterNameType& name) const +{ + StaticParameterValuesType result; + + //do nothing + + return result; +}; + +mitk::ModelBase::DerivedParameterMapType mitk::ThreeStepLinearModel::ComputeDerivedParameters( + const mitk::ModelBase::ParametersType& parameters) const +{ + double S0 = (double) parameters[POSITION_PARAMETER_S0]; + double tau = (double) parameters[POSITION_PARAMETER_t1] ; + double tmax = (double) parameters[POSITION_PARAMETER_t2] ; + double s1 = (double) parameters[POSITION_PARAMETER_a1] ; + double s2 = (double) parameters[POSITION_PARAMETER_a2] ; + + unsigned int timeSteps = m_TimeGrid.GetSize(); + + double Taq = 0; + Taq = m_TimeGrid.GetElement(timeSteps-1); + + double b1 = S0-s1*tau; + double Smax = s1*tmax+b1; + double b2 = Smax-s2*tmax; + double AUC = s1/2*(tmax*tmax-tau*tau) + +(b1-S0)*(tmax-tau) + +s2/2*(Taq*Taq-tmax*tmax) + +(b2-S0)*(Taq-tmax); + double Sfin = s2*Taq+b2; + + DerivedParameterMapType result; + + result.insert(std::make_pair("AUC", AUC)); + result.insert(std::make_pair("FinalTimePoint", Taq)); + result.insert(std::make_pair("FinalUptake", Sfin)); + result.insert(std::make_pair("Smax", Smax)); + result.insert(std::make_pair("y-intercept1", b1)); + result.insert(std::make_pair("y-intercept2", b2)); + + return result; +}; + +itk::LightObject::Pointer mitk::ThreeStepLinearModel::InternalClone() const +{ + ThreeStepLinearModel::Pointer newClone = ThreeStepLinearModel::New(); + + newClone->SetTimeGrid(this->m_TimeGrid); + + return newClone.GetPointer(); +}; diff --git a/Modules/Pharmacokinetics/src/Models/mitkThreeStepLinearModelFactory.cpp b/Modules/Pharmacokinetics/src/Models/mitkThreeStepLinearModelFactory.cpp new file mode 100644 index 0000000000..e1b7bfdbc4 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkThreeStepLinearModelFactory.cpp @@ -0,0 +1,38 @@ +/*=================================================================== + +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 "mitkThreeStepLinearModelFactory.h" +#include "mitkConcreteModelParameterizerBase.h" + +mitk::ThreeStepLinearModelFactory::ThreeStepLinearModelFactory() +{ +}; + +mitk::ThreeStepLinearModelFactory::~ThreeStepLinearModelFactory() +{ +}; + +mitk::ModelParameterizerBase::ParametersType +mitk::ThreeStepLinearModelFactory::GetDefaultInitialParameterization() const +{ + return ThreeStepLinearModelParameterizer::New()->GetDefaultInitialParameterization(); +}; + +mitk::ModelParameterizerBase::Pointer mitk::ThreeStepLinearModelFactory::DoCreateParameterizer( + const modelFit::ModelFitInfo* fit) const +{ + return ConcreteModelParameterizerBase::New().GetPointer(); +}; diff --git a/Modules/Pharmacokinetics/src/Models/mitkThreeStepLinearModelParameterizer.cpp b/Modules/Pharmacokinetics/src/Models/mitkThreeStepLinearModelParameterizer.cpp new file mode 100644 index 0000000000..0a90d90627 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkThreeStepLinearModelParameterizer.cpp @@ -0,0 +1,33 @@ +/*=================================================================== + +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 "mitkThreeStepLinearModelParameterizer.h" + +mitk::ThreeStepLinearModelParameterizer::ParametersType +mitk::ThreeStepLinearModelParameterizer::GetDefaultInitialParameterization() const +{ + ParametersType initialParameters; + initialParameters.SetSize(5); + initialParameters[mitk:: ThreeStepLinearModel::POSITION_PARAMETER_S0] = 0.0; + initialParameters[mitk:: ThreeStepLinearModel::POSITION_PARAMETER_t1] = 50; + initialParameters[mitk:: ThreeStepLinearModel::POSITION_PARAMETER_t2] = 100; + initialParameters[mitk:: ThreeStepLinearModel::POSITION_PARAMETER_a1] = 1.0; + initialParameters[mitk:: ThreeStepLinearModel::POSITION_PARAMETER_a2] = -1.0; + + return initialParameters; +}; + + diff --git a/Modules/Pharmacokinetics/src/Models/mitkTwoCompartmentExchangeModel.cpp b/Modules/Pharmacokinetics/src/Models/mitkTwoCompartmentExchangeModel.cpp new file mode 100644 index 0000000000..eb56b6252d --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkTwoCompartmentExchangeModel.cpp @@ -0,0 +1,185 @@ +/*=================================================================== + +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 "mitkTwoCompartmentExchangeModel.h" +#include "mitkConvolutionHelper.h" +#include + +const std::string mitk::TwoCompartmentExchangeModel::MODEL_DISPLAY_NAME = + "Two Compartment Exchange Model"; + +const std::string mitk::TwoCompartmentExchangeModel::NAME_PARAMETER_F = "F"; +const std::string mitk::TwoCompartmentExchangeModel::NAME_PARAMETER_PS = "PS"; +const std::string mitk::TwoCompartmentExchangeModel::NAME_PARAMETER_ve = "ve"; +const std::string mitk::TwoCompartmentExchangeModel::NAME_PARAMETER_vp = "vp"; + +const std::string mitk::TwoCompartmentExchangeModel::UNIT_PARAMETER_F = "ml/min/100ml"; +const std::string mitk::TwoCompartmentExchangeModel::UNIT_PARAMETER_PS = "ml/min/100ml"; +const std::string mitk::TwoCompartmentExchangeModel::UNIT_PARAMETER_ve = "ml/ml"; +const std::string mitk::TwoCompartmentExchangeModel::UNIT_PARAMETER_vp = "ml/ml"; + +const unsigned int mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_F = 0; +const unsigned int mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_PS = 1; +const unsigned int mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_ve = 2; +const unsigned int mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_vp = 3; + +const unsigned int mitk::TwoCompartmentExchangeModel::NUMBER_OF_PARAMETERS = 4; + + +inline double square(double a) +{ + return a * a; +} + +std::string mitk::TwoCompartmentExchangeModel::GetModelDisplayName() const +{ + return MODEL_DISPLAY_NAME; +}; + +std::string mitk::TwoCompartmentExchangeModel::GetModelType() const +{ + return "Perfusion.MR"; +}; + +mitk::TwoCompartmentExchangeModel::TwoCompartmentExchangeModel() +{ + +} + +mitk::TwoCompartmentExchangeModel::~TwoCompartmentExchangeModel() +{ + +} + +mitk::TwoCompartmentExchangeModel::ParameterNamesType +mitk::TwoCompartmentExchangeModel::GetParameterNames() const +{ + ParameterNamesType result; + + result.push_back(NAME_PARAMETER_F); + result.push_back(NAME_PARAMETER_PS); + result.push_back(NAME_PARAMETER_ve); + result.push_back(NAME_PARAMETER_vp); + + return result; +} + +mitk::TwoCompartmentExchangeModel::ParametersSizeType +mitk::TwoCompartmentExchangeModel::GetNumberOfParameters() const +{ + return NUMBER_OF_PARAMETERS; +} + +mitk::TwoCompartmentExchangeModel::ParamterUnitMapType +mitk::TwoCompartmentExchangeModel::GetParameterUnits() const +{ + ParamterUnitMapType result; + + result.insert(std::make_pair(NAME_PARAMETER_F, UNIT_PARAMETER_F)); + result.insert(std::make_pair(NAME_PARAMETER_PS, UNIT_PARAMETER_PS)); + result.insert(std::make_pair(NAME_PARAMETER_vp, UNIT_PARAMETER_vp)); + result.insert(std::make_pair(NAME_PARAMETER_ve, UNIT_PARAMETER_ve)); + + return result; +}; + + +mitk::TwoCompartmentExchangeModel::ModelResultType +mitk::TwoCompartmentExchangeModel::ComputeModelfunction(const ParametersType& parameters) const +{ + typedef itk::Array ResidueFunctionType; + typedef mitk::ModelBase::ModelResultType ConvolutionResultType; + + if (this->m_TimeGrid.GetSize() == 0) + { + itkExceptionMacro("No Time Grid Set! Cannot Calculate Signal"); + } + + AterialInputFunctionType aterialInputFunction; + aterialInputFunction = GetAterialInputFunction(this->m_TimeGrid); + + unsigned int timeSteps = this->m_TimeGrid.GetSize(); + mitk::ModelBase::ModelResultType signal(timeSteps); + signal.fill(0.0); + + //Model Parameters + double F = parameters[POSITION_PARAMETER_F] / 6000.0; + double PS = parameters[POSITION_PARAMETER_PS] / 6000.0; + double ve = parameters[POSITION_PARAMETER_ve]; + double vp = parameters[POSITION_PARAMETER_vp]; + + if(PS != 0) + { + double Tp = vp/(PS + F); + double Te = ve/PS; + double Tb = vp/F; + + double Kp = 0.5 *( 1/Tp + 1/Te + sqrt(( 1/Tp + 1/Te )*( 1/Tp + 1/Te ) - 4 * 1/Te*1/Tb) ); + double Km = 0.5 *( 1/Tp + 1/Te - sqrt(( 1/Tp + 1/Te )*( 1/Tp + 1/Te ) - 4 * 1/Te*1/Tb) ); + + double E = ( Kp - 1/Tb )/( Kp - Km ); + + + + ConvolutionResultType expp = mitk::convoluteAIFWithExponential(this->m_TimeGrid, aterialInputFunction,Kp); + ConvolutionResultType expm = mitk::convoluteAIFWithExponential(this->m_TimeGrid, aterialInputFunction,Km); + + //Signal that will be returned by ComputeModelFunction + + mitk::ModelBase::ModelResultType::const_iterator exppPos = expp.begin(); + mitk::ModelBase::ModelResultType::const_iterator expmPos = expm.begin(); + + for( mitk::ModelBase::ModelResultType::iterator signalPos = signal.begin(); signalPos!=signal.end(); ++exppPos,++expmPos, ++signalPos) + { + *signalPos = F * ( *exppPos + E*(*expmPos - *exppPos) ); + } + } + + + else + { + double Kp = F/vp; + ConvolutionResultType exp = mitk::convoluteAIFWithExponential(this->m_TimeGrid, aterialInputFunction,Kp); + mitk::ModelBase::ModelResultType::const_iterator expPos = exp.begin(); + + for( mitk::ModelBase::ModelResultType::iterator signalPos = signal.begin(); signalPos!=signal.end(); ++expPos, ++signalPos) + { + *signalPos = F * ( *expPos ); + } + + } + + return signal; +} + + +itk::LightObject::Pointer mitk::TwoCompartmentExchangeModel::InternalClone() const +{ + TwoCompartmentExchangeModel::Pointer newClone = TwoCompartmentExchangeModel::New(); + + newClone->SetTimeGrid(this->m_TimeGrid); + + return newClone.GetPointer(); +} + +void mitk::TwoCompartmentExchangeModel::PrintSelf(std::ostream& os, ::itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + + +} + + diff --git a/Modules/Pharmacokinetics/src/Models/mitkTwoCompartmentExchangeModelFactory.cpp b/Modules/Pharmacokinetics/src/Models/mitkTwoCompartmentExchangeModelFactory.cpp new file mode 100644 index 0000000000..dd4572ebec --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkTwoCompartmentExchangeModelFactory.cpp @@ -0,0 +1,29 @@ +/*=================================================================== + +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 "mitkTwoCompartmentExchangeModelFactory.h" + +#include "mitkTwoCompartmentExchangeModelParameterizer.h" +#include "mitkAIFParametrizerHelper.h" + + +mitk::TwoCompartmentExchangeModelFactory::TwoCompartmentExchangeModelFactory() +{ +}; + +mitk::TwoCompartmentExchangeModelFactory::~TwoCompartmentExchangeModelFactory() +{ +}; + diff --git a/Modules/Pharmacokinetics/src/Models/mitkTwoCompartmentExchangeModelParameterizer.cpp b/Modules/Pharmacokinetics/src/Models/mitkTwoCompartmentExchangeModelParameterizer.cpp new file mode 100644 index 0000000000..5841e78903 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkTwoCompartmentExchangeModelParameterizer.cpp @@ -0,0 +1,38 @@ +/*=================================================================== + +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 "mitkTwoCompartmentExchangeModelParameterizer.h" + +mitk::TwoCompartmentExchangeModelParameterizer::ParametersType +mitk::TwoCompartmentExchangeModelParameterizer::GetDefaultInitialParameterization() const +{ + ParametersType initialParameters; + initialParameters.SetSize(4); + initialParameters[mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_PS] = 5.0; + initialParameters[mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_F] = 20.0; + initialParameters[mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_ve] = 0.1; + initialParameters[mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_vp] = 0.04; + + return initialParameters; +}; + +mitk::TwoCompartmentExchangeModelParameterizer::TwoCompartmentExchangeModelParameterizer() +{ +}; + +mitk::TwoCompartmentExchangeModelParameterizer::~TwoCompartmentExchangeModelParameterizer() +{ +}; diff --git a/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentFDGModel.cpp b/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentFDGModel.cpp new file mode 100644 index 0000000000..550b3f17a7 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentFDGModel.cpp @@ -0,0 +1,162 @@ +/*=================================================================== + +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 "mitkTwoTissueCompartmentFDGModel.h" +#include "mitkConvolutionHelper.h" +#include +const std::string mitk::TwoTissueCompartmentFDGModel::MODEL_DISPLAY_NAME = "Two Tissue Compartment Model for FDG (Sokoloff Model)"; + +const std::string mitk::TwoTissueCompartmentFDGModel::NAME_PARAMETER_K1 = "K1"; +const std::string mitk::TwoTissueCompartmentFDGModel::NAME_PARAMETER_k2 = "k2"; +const std::string mitk::TwoTissueCompartmentFDGModel::NAME_PARAMETER_k3 = "k3"; +const std::string mitk::TwoTissueCompartmentFDGModel::NAME_PARAMETER_VB = "V_B"; + +const std::string mitk::TwoTissueCompartmentFDGModel::UNIT_PARAMETER_K1 = "1/min"; +const std::string mitk::TwoTissueCompartmentFDGModel::UNIT_PARAMETER_k2 = "1/min"; +const std::string mitk::TwoTissueCompartmentFDGModel::UNIT_PARAMETER_k3 = "1/min"; +const std::string mitk::TwoTissueCompartmentFDGModel::UNIT_PARAMETER_VB = "ml/ml"; + +const unsigned int mitk::TwoTissueCompartmentFDGModel::POSITION_PARAMETER_K1 = 0; +const unsigned int mitk::TwoTissueCompartmentFDGModel::POSITION_PARAMETER_k2 = 1; +const unsigned int mitk::TwoTissueCompartmentFDGModel::POSITION_PARAMETER_k3 = 2; +const unsigned int mitk::TwoTissueCompartmentFDGModel::POSITION_PARAMETER_VB = 3; + +const unsigned int mitk::TwoTissueCompartmentFDGModel::NUMBER_OF_PARAMETERS = 4; + +std::string mitk::TwoTissueCompartmentFDGModel::GetModelDisplayName() const +{ + return MODEL_DISPLAY_NAME; +}; + +std::string mitk::TwoTissueCompartmentFDGModel::GetModelType() const +{ + return "Dynamic.PET"; +}; + +mitk::TwoTissueCompartmentFDGModel::TwoTissueCompartmentFDGModel() +{ + +} + +mitk::TwoTissueCompartmentFDGModel::~TwoTissueCompartmentFDGModel() +{ + +} + +mitk::TwoTissueCompartmentFDGModel::ParameterNamesType +mitk::TwoTissueCompartmentFDGModel::GetParameterNames() const +{ + ParameterNamesType result; + + result.push_back(NAME_PARAMETER_K1); + result.push_back(NAME_PARAMETER_k2); + result.push_back(NAME_PARAMETER_k3); + result.push_back(NAME_PARAMETER_VB); + + return result; +} + +mitk::TwoTissueCompartmentFDGModel::ParametersSizeType +mitk::TwoTissueCompartmentFDGModel::GetNumberOfParameters() const +{ + return NUMBER_OF_PARAMETERS; +} + +mitk::TwoTissueCompartmentFDGModel::ParamterUnitMapType +mitk::TwoTissueCompartmentFDGModel::GetParameterUnits() const +{ + ParamterUnitMapType result; + + result.insert(std::make_pair(NAME_PARAMETER_K1, UNIT_PARAMETER_K1)); + result.insert(std::make_pair(NAME_PARAMETER_k2, UNIT_PARAMETER_k2)); + result.insert(std::make_pair(NAME_PARAMETER_k3, UNIT_PARAMETER_k3)); + result.insert(std::make_pair(NAME_PARAMETER_VB, UNIT_PARAMETER_VB)); + + return result; +}; + +mitk::TwoTissueCompartmentFDGModel::ModelResultType +mitk::TwoTissueCompartmentFDGModel::ComputeModelfunction(const ParametersType& parameters) const +{ + typedef itk::Array ResidueFunctionType; + + if (this->m_TimeGrid.GetSize() == 0) + { + itkExceptionMacro("No Time Grid Set! Cannot Calculate Signal"); + } + + AterialInputFunctionType aterialInputFunction; + aterialInputFunction = GetAterialInputFunction(this->m_TimeGrid); + + + unsigned int timeSteps = this->m_TimeGrid.GetSize(); + + //Model Parameters + double k1 = (double)parameters[POSITION_PARAMETER_K1] / 60.0; + double k2 = (double)parameters[POSITION_PARAMETER_k2] / 60.0; + double k3 = (double)parameters[POSITION_PARAMETER_k3] / 60.0; + double VB = parameters[POSITION_PARAMETER_VB]; + + + + + double lambda = k2+k3; + //double lambda2 = -alpha2; + mitk::ModelBase::ModelResultType exp = mitk::convoluteAIFWithExponential(this->m_TimeGrid, + aterialInputFunction, lambda); + mitk::ModelBase::ModelResultType CA = mitk::convoluteAIFWithConstant(this->m_TimeGrid, aterialInputFunction, k3); + + + //Signal that will be returned by ComputeModelFunction + mitk::ModelBase::ModelResultType signal(timeSteps); + signal.fill(0.0); + + mitk::ModelBase::ModelResultType::const_iterator expPos = exp.begin(); + mitk::ModelBase::ModelResultType::const_iterator CAPos = CA.begin(); + AterialInputFunctionType::const_iterator aifPos = aterialInputFunction.begin(); + + for (mitk::ModelBase::ModelResultType::iterator signalPos = signal.begin(); + signalPos != signal.end(); ++expPos, ++signalPos, ++aifPos) + { + double Ci = k1 * k2 /lambda *(*expPos) + k1*k3/lambda*(*CAPos); + *signalPos = VB * (*aifPos) + (1 - VB) * Ci; + } + + return signal; + +} + + + + +itk::LightObject::Pointer mitk::TwoTissueCompartmentFDGModel::InternalClone() const +{ + TwoTissueCompartmentFDGModel::Pointer newClone = TwoTissueCompartmentFDGModel::New(); + + newClone->SetTimeGrid(this->m_TimeGrid); + + return newClone.GetPointer(); +} + +void mitk::TwoTissueCompartmentFDGModel::PrintSelf(std::ostream& os, ::itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + + +} + + + diff --git a/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentFDGModelFactory.cpp b/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentFDGModelFactory.cpp new file mode 100644 index 0000000000..25469d559f --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentFDGModelFactory.cpp @@ -0,0 +1,38 @@ +#include "mitkTwoTissueCompartmentFDGModelFactory.h" + +#include +#include +#include + +mitk::ConstraintCheckerBase::Pointer +mitk::TwoTissueCompartmentFDGModelFactory::CreateDefaultConstraints() const +{ + SimpleBarrierConstraintChecker::Pointer constraints = SimpleBarrierConstraintChecker::New(); + + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_K1, 0.0); + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_k2, 0, 0); + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_k3, 0, 0); + constraints->SetLowerBarrier(ModelType::POSITION_PARAMETER_VB, 0, 0); + + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_K1, 1.0, 0); + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_k2, 1.0, 0); + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_k3, 1.0, 0); + constraints->SetUpperBarrier(ModelType::POSITION_PARAMETER_VB, 1, 0); + + + return constraints.GetPointer(); +}; + +mitk::ModelParameterizerBase::ParametersType +mitk::TwoTissueCompartmentFDGModelFactory::GetDefaultInitialParameterization() const +{ + return TwoTissueCompartmentFDGModelParameterizer::New()->GetDefaultInitialParameterization(); +}; + +mitk::TwoTissueCompartmentFDGModelFactory::TwoTissueCompartmentFDGModelFactory() +{ +}; + +mitk::TwoTissueCompartmentFDGModelFactory::~TwoTissueCompartmentFDGModelFactory() +{ +}; diff --git a/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentFDGModelParameterizer.cpp b/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentFDGModelParameterizer.cpp new file mode 100644 index 0000000000..982440c4aa --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentFDGModelParameterizer.cpp @@ -0,0 +1,38 @@ +/*=================================================================== + +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 "mitkTwoTissueCompartmentFDGModelParameterizer.h" + +mitk::TwoTissueCompartmentFDGModelParameterizer::ParametersType +mitk::TwoTissueCompartmentFDGModelParameterizer::GetDefaultInitialParameterization() const +{ + ParametersType initialParameters; + initialParameters.SetSize(4); + initialParameters[mitk::TwoTissueCompartmentFDGModel::POSITION_PARAMETER_K1] = 0.5; + initialParameters[mitk::TwoTissueCompartmentFDGModel::POSITION_PARAMETER_k2] = 0.5; + initialParameters[mitk::TwoTissueCompartmentFDGModel::POSITION_PARAMETER_k3] = 0.5; + initialParameters[mitk::TwoTissueCompartmentFDGModel::POSITION_PARAMETER_VB] = 0.5; + + return initialParameters; +}; + +mitk::TwoTissueCompartmentFDGModelParameterizer::TwoTissueCompartmentFDGModelParameterizer() +{ +}; + +mitk::TwoTissueCompartmentFDGModelParameterizer::~TwoTissueCompartmentFDGModelParameterizer() +{ +}; diff --git a/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentModel.cpp b/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentModel.cpp new file mode 100644 index 0000000000..c314fac87c --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentModel.cpp @@ -0,0 +1,178 @@ +/*=================================================================== + +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 "mitkTwoTissueCompartmentModel.h" +#include "mitkConvolutionHelper.h" +#include +const std::string mitk::TwoTissueCompartmentModel::MODEL_DISPLAY_NAME = "Two Tissue Compartment Model"; + +const std::string mitk::TwoTissueCompartmentModel::NAME_PARAMETER_K1 = "K1"; +const std::string mitk::TwoTissueCompartmentModel::NAME_PARAMETER_k2 = "k2"; +const std::string mitk::TwoTissueCompartmentModel::NAME_PARAMETER_k3 = "k3"; +const std::string mitk::TwoTissueCompartmentModel::NAME_PARAMETER_k4 = "k4"; +const std::string mitk::TwoTissueCompartmentModel::NAME_PARAMETER_VB = "V_B"; + +const std::string mitk::TwoTissueCompartmentModel::UNIT_PARAMETER_K1 = "1/min"; +const std::string mitk::TwoTissueCompartmentModel::UNIT_PARAMETER_k2 = "1/min"; +const std::string mitk::TwoTissueCompartmentModel::UNIT_PARAMETER_k3 = "1/min"; +const std::string mitk::TwoTissueCompartmentModel::UNIT_PARAMETER_k4 = "1/min"; +const std::string mitk::TwoTissueCompartmentModel::UNIT_PARAMETER_VB = "ml/ml"; + +const unsigned int mitk::TwoTissueCompartmentModel::POSITION_PARAMETER_K1 = 0; +const unsigned int mitk::TwoTissueCompartmentModel::POSITION_PARAMETER_k2 = 1; +const unsigned int mitk::TwoTissueCompartmentModel::POSITION_PARAMETER_k3 = 2; +const unsigned int mitk::TwoTissueCompartmentModel::POSITION_PARAMETER_k4 = 3; +const unsigned int mitk::TwoTissueCompartmentModel::POSITION_PARAMETER_VB = 4; + +const unsigned int mitk::TwoTissueCompartmentModel::NUMBER_OF_PARAMETERS = 5; + + +inline double square(double a) +{ + return a * a; +} + +std::string mitk::TwoTissueCompartmentModel::GetModelDisplayName() const +{ + return MODEL_DISPLAY_NAME; +}; + +std::string mitk::TwoTissueCompartmentModel::GetModelType() const +{ + return "Dynamic.PET"; +}; + +mitk::TwoTissueCompartmentModel::TwoTissueCompartmentModel() +{ + +} + +mitk::TwoTissueCompartmentModel::~TwoTissueCompartmentModel() +{ + +} + +mitk::TwoTissueCompartmentModel::ParameterNamesType +mitk::TwoTissueCompartmentModel::GetParameterNames() const +{ + ParameterNamesType result; + + result.push_back(NAME_PARAMETER_K1); + result.push_back(NAME_PARAMETER_k2); + result.push_back(NAME_PARAMETER_k3); + result.push_back(NAME_PARAMETER_k4); + result.push_back(NAME_PARAMETER_VB); + + return result; +} + +mitk::TwoTissueCompartmentModel::ParametersSizeType +mitk::TwoTissueCompartmentModel::GetNumberOfParameters() const +{ + return NUMBER_OF_PARAMETERS; +} + +mitk::TwoTissueCompartmentModel::ParamterUnitMapType +mitk::TwoTissueCompartmentModel::GetParameterUnits() const +{ + ParamterUnitMapType result; + + result.insert(std::make_pair(NAME_PARAMETER_K1, UNIT_PARAMETER_K1)); + result.insert(std::make_pair(NAME_PARAMETER_k2, UNIT_PARAMETER_k2)); + result.insert(std::make_pair(NAME_PARAMETER_k3, UNIT_PARAMETER_k3)); + result.insert(std::make_pair(NAME_PARAMETER_k4, UNIT_PARAMETER_k4)); + result.insert(std::make_pair(NAME_PARAMETER_VB, UNIT_PARAMETER_VB)); + + return result; +}; + +mitk::TwoTissueCompartmentModel::ModelResultType +mitk::TwoTissueCompartmentModel::ComputeModelfunction(const ParametersType& parameters) const +{ + typedef itk::Array ResidueFunctionType; + + if (this->m_TimeGrid.GetSize() == 0) + { + itkExceptionMacro("No Time Grid Set! Cannot Calculate Signal"); + } + + AterialInputFunctionType aterialInputFunction; + aterialInputFunction = GetAterialInputFunction(this->m_TimeGrid); + + + unsigned int timeSteps = this->m_TimeGrid.GetSize(); + + //Model Parameters + double k1 = (double)parameters[POSITION_PARAMETER_K1] / 60.0; + double k2 = (double)parameters[POSITION_PARAMETER_k2] / 60.0; + double k3 = (double)parameters[POSITION_PARAMETER_k3] / 60.0; + double k4 = (double)parameters[POSITION_PARAMETER_k4] / 60.0; + double VB = parameters[POSITION_PARAMETER_VB]; + + + + double alpha1 = 0.5 * ((k2 + k3 + k4) - sqrt(square(k2 + k3 + k4) - 4 * k2 * k4)); + double alpha2 = 0.5 * ((k2 + k3 + k4) + sqrt(square(k2 + k3 + k4) - 4 * k2 * k4)); + + //double lambda1 = -alpha1; + //double lambda2 = -alpha2; + mitk::ModelBase::ModelResultType exp1 = mitk::convoluteAIFWithExponential(this->m_TimeGrid, + aterialInputFunction, alpha1); + mitk::ModelBase::ModelResultType exp2 = mitk::convoluteAIFWithExponential(this->m_TimeGrid, + aterialInputFunction, alpha2); + + + //Signal that will be returned by ComputeModelFunction + mitk::ModelBase::ModelResultType signal(timeSteps); + signal.fill(0.0); + + mitk::ModelBase::ModelResultType::const_iterator exp1Pos = exp1.begin(); + mitk::ModelBase::ModelResultType::const_iterator exp2Pos = exp2.begin(); + AterialInputFunctionType::const_iterator aifPos = aterialInputFunction.begin(); + + for (mitk::ModelBase::ModelResultType::iterator signalPos = signal.begin(); + signalPos != signal.end(); ++exp1Pos, ++exp2Pos, ++signalPos, ++aifPos) + { + double Ci = k1 / (alpha2 - alpha1) * ((k4 - alpha1 + k3) * (*exp1Pos) + (alpha2 - k4 - k3) * + (*exp2Pos)); + *signalPos = VB * (*aifPos) + (1 - VB) * Ci; + } + + return signal; + +} + + + + +itk::LightObject::Pointer mitk::TwoTissueCompartmentModel::InternalClone() const +{ + TwoTissueCompartmentModel::Pointer newClone = TwoTissueCompartmentModel::New(); + + newClone->SetTimeGrid(this->m_TimeGrid); + + return newClone.GetPointer(); +} + +void mitk::TwoTissueCompartmentModel::PrintSelf(std::ostream& os, ::itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + + +} + + + diff --git a/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentModelFactory.cpp b/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentModelFactory.cpp new file mode 100644 index 0000000000..2c5f08dc86 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentModelFactory.cpp @@ -0,0 +1,28 @@ +/*=================================================================== + +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 "mitkTwoTissueCompartmentModelFactory.h" + +#include "mitkTwoTissueCompartmentModelParameterizer.h" +#include "mitkAIFParametrizerHelper.h" + +mitk::TwoTissueCompartmentModelFactory::TwoTissueCompartmentModelFactory() +{ +}; + +mitk::TwoTissueCompartmentModelFactory::~TwoTissueCompartmentModelFactory() +{ +}; \ No newline at end of file diff --git a/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentModelParameterizer.cpp b/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentModelParameterizer.cpp new file mode 100644 index 0000000000..a2a187e556 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Models/mitkTwoTissueCompartmentModelParameterizer.cpp @@ -0,0 +1,39 @@ +/*=================================================================== + +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 "mitkTwoTissueCompartmentModelParameterizer.h" + +mitk::TwoTissueCompartmentModelParameterizer::ParametersType +mitk::TwoTissueCompartmentModelParameterizer::GetDefaultInitialParameterization() const +{ + ParametersType initialParameters; + initialParameters.SetSize(5); + initialParameters[mitk::TwoTissueCompartmentModel::POSITION_PARAMETER_K1] = 0.5; + initialParameters[mitk::TwoTissueCompartmentModel::POSITION_PARAMETER_k2] = 0.5; + initialParameters[mitk::TwoTissueCompartmentModel::POSITION_PARAMETER_k3] = 0.5; + initialParameters[mitk::TwoTissueCompartmentModel::POSITION_PARAMETER_k4] = 0.5; + initialParameters[mitk::TwoTissueCompartmentModel::POSITION_PARAMETER_VB] = 0.5; + + return initialParameters; +}; + +mitk::TwoTissueCompartmentModelParameterizer::TwoTissueCompartmentModelParameterizer() +{ +}; + +mitk::TwoTissueCompartmentModelParameterizer::~TwoTissueCompartmentModelParameterizer() +{ +}; diff --git a/Modules/Pharmacokinetics/src/SimulationFramework/mitkImageGenerationHelper.cpp b/Modules/Pharmacokinetics/src/SimulationFramework/mitkImageGenerationHelper.cpp new file mode 100644 index 0000000000..fcd69410a9 --- /dev/null +++ b/Modules/Pharmacokinetics/src/SimulationFramework/mitkImageGenerationHelper.cpp @@ -0,0 +1,142 @@ +/*=================================================================== + +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 "mitkImageGenerationHelper.h" +#include "mitkArbitraryTimeGeometry.h" +#include "mitkImageCast.h" + + + typedef itk::Image FrameITKImageType; + typedef itk::Image DynamicITKImageType; + + + mitk::Image::Pointer mitk::ImageGenerationHelper::GenerateTestFrame(unsigned int timePointIndex) + { + FrameITKImageType::Pointer image = FrameITKImageType::New(); + + FrameITKImageType::IndexType start; + start[0] = 0; // first index on X + start[1] = 0; // first index on Y + start[2] = 0; // first index on Z + + FrameITKImageType::SizeType size; + size[0] = this->m_DimX; // size along X + size[1] = this->m_DimY; // size along Y + size[2] = this->m_DimZ; // size along Z + + FrameITKImageType::RegionType region; + region.SetSize( size ); + region.SetIndex( start ); + + image->SetRegions( region ); + image->Allocate(); + + itk::ImageRegionIterator it = itk::ImageRegionIterator(image,image->GetLargestPossibleRegion()); + + while (!it.IsAtEnd()) + { + it.Set(this->m_Curve[timePointIndex]); + ++it; + } + + mitk::Image::Pointer mitkImage = mitk::Image::New(); + mitkImage->InitializeByItk( image.GetPointer() ); + mitkImage->SetVolume( image->GetBufferPointer() ); + + return mitkImage; + } + + + + + mitk::Image::Pointer mitk::ImageGenerationHelper::GenerateDynamicImageMITK() + { + + unsigned int timeSteps = this->m_Grid.GetSize(); + + if(this->m_Curve.GetSize() != this->m_Grid.GetSize()) + { + itkExceptionMacro("Error. TimeGrid and ConcentrationCurve do not have same size. No Image Generation possible!"); + + } + if(this->m_DimX == 0 && this->m_DimY == 0 && this->m_DimZ == 0) + { + itkExceptionMacro("Error. No Dimensions for Image Set!"); + + } + if(this->m_Curve.GetSize() == 0 || this->m_Grid.GetSize() == 0) + { + itkExceptionMacro("Error. No Curve/Grid set!"); + + } + + mitk::Image::Pointer tempImage = GenerateTestFrame(0); + mitk::Image::Pointer dynamicImage = mitk::Image::New(); + + DynamicITKImageType::Pointer dynamicITKImage = DynamicITKImageType::New(); + DynamicITKImageType::RegionType dynamicITKRegion; + DynamicITKImageType::PointType dynamicITKOrigin; + DynamicITKImageType::IndexType dynamicITKIndex; + DynamicITKImageType::SpacingType dynamicITKSpacing; + + dynamicITKSpacing[0] = tempImage->GetGeometry()->GetSpacing()[0]; + dynamicITKSpacing[1] = tempImage->GetGeometry()->GetSpacing()[1]; + dynamicITKSpacing[2] = tempImage->GetGeometry()->GetSpacing()[2]; + dynamicITKSpacing[3] = 1.0; + + dynamicITKIndex[0] = 0; // The first pixel of the REGION + dynamicITKIndex[1] = 0; + dynamicITKIndex[2] = 0; + dynamicITKIndex[3] = 0; + + dynamicITKRegion.SetSize( 0,tempImage->GetDimension(0)); + dynamicITKRegion.SetSize( 1,tempImage->GetDimension(1)); + dynamicITKRegion.SetSize( 2,tempImage->GetDimension(2)); + dynamicITKRegion.SetSize( 3,timeSteps); + + dynamicITKRegion.SetIndex( dynamicITKIndex ); + + dynamicITKOrigin[0]=tempImage->GetGeometry()->GetOrigin()[0]; + dynamicITKOrigin[1]=tempImage->GetGeometry()->GetOrigin()[1]; + dynamicITKOrigin[2]=tempImage->GetGeometry()->GetOrigin()[2]; + + dynamicITKImage->SetOrigin(dynamicITKOrigin); + dynamicITKImage->SetSpacing(dynamicITKSpacing); + dynamicITKImage->SetRegions( dynamicITKRegion); + dynamicITKImage->Allocate(); + dynamicITKImage->FillBuffer(0); //not sure if this is necessary + + // Convert + mitk::CastToMitkImage(dynamicITKImage, dynamicImage); + + ArbitraryTimeGeometry::Pointer timeGeometry = ArbitraryTimeGeometry::New(); + timeGeometry->ClearAllGeometries(); + + + for (int i = 0; iSetVolume(frameImage->GetVolumeData()->GetData(),i); + + timeGeometry->AppendNewTimeStepClone(frameImage->GetGeometry(),this->m_Grid(i),this->m_Grid(i+1)); + } + + dynamicImage->SetTimeGeometry(timeGeometry); + + return dynamicImage; + } + + diff --git a/Modules/Pharmacokinetics/src/SimulationFramework/mitkPerfusionDataGenerator.cpp b/Modules/Pharmacokinetics/src/SimulationFramework/mitkPerfusionDataGenerator.cpp new file mode 100644 index 0000000000..31ebb2749e --- /dev/null +++ b/Modules/Pharmacokinetics/src/SimulationFramework/mitkPerfusionDataGenerator.cpp @@ -0,0 +1,252 @@ +#include "mitkPerfusionDataGenerator.h" +#include "itkMultiOutputNaryFunctorImageFilter.h" +#include "mitkArbitraryTimeGeometry.h" +#include "mitkImageCast.h" +#include "mitkImageAccessByItk.h" +#include "mitkITKImageImport.h" + + +void mitk::PerfusionDataGenerator::SetParameterInputImage(const ParametersIndexType parameterIndex, ParameterImageType parameterImage) +{ + m_ParameterInputMap.insert(std::make_pair(parameterIndex,parameterImage)); + +} + +mitk::PerfusionDataGenerator::ResultImageType mitk::PerfusionDataGenerator::GetGeneratedImage() +{ + Generate(); + return m_ResultImage; +} + +template +void + mitk::PerfusionDataGenerator::DoPrepareMask(itk::Image* image) +{ + m_InternalMask = dynamic_cast(image); + + if (m_InternalMask.IsNull()) + { + MITK_INFO << "Parameter Fit Generator. Need to cast mask for parameter fit."; + typedef itk::Image InputImageType; + typedef itk::CastImageFilter< InputImageType, InternalMaskType > CastFilterType; + typename CastFilterType::Pointer spImageCaster = CastFilterType::New(); + + spImageCaster->SetInput(image); + + m_InternalMask = spImageCaster->GetOutput(); + spImageCaster->Update(); + } +} + +template +void mitk::PerfusionDataGenerator::DoGenerateData(itk::Image* image) +{ + typedef itk::Image InputFrameImageType; + typedef itk::Image OutputImageType; + + typedef itk::MultiOutputNaryFunctorImageFilter FilterType; + typename FilterType::Pointer filter; + + + for(unsigned int i=0; im_ParameterInputMap.size(); ++i) + { + typename InputFrameImageType::Pointer frameImage; + Image::Pointer parameterImage = m_InputParameterImages.at(i); + + mitk::CastToItkImage(parameterImage, frameImage); + filter->SetInput(i,frameImage); + + } + + SimpleFunctorPolicy functor; + functor.SetFunctor(this->m_Functor); + filter->SetFunctor(functor); + if (this->m_InternalMask.IsNotNull()) + { + filter->SetMask(this->m_InternalMask); + } + filter->Update(); + + + ArbitraryTimeGeometry::Pointer timeGeometry = ArbitraryTimeGeometry::New(); + timeGeometry->ClearAllGeometries(); + Image::Pointer dynamicImage= Image::New(); + + if(filter->GetNumberOfOutputs() != this->m_Functor->GetGrid().GetSize()) + { + itkExceptionMacro("Error. Number of computed output Images does not match Grid size!"); + } + + auto m_Grid = this->m_Functor->GetGrid(); + for (GridType::size_type i = 0; iGetOutput(i))->Clone(); + + dynamicImage->SetVolume(frameImage->GetVolumeData()->GetData(),i); + + auto currentTimePoint = m_Grid[i]; + auto nextTimePoint = m_Grid[i]; + if (i+1AppendNewTimeStepClone(frameImage->GetGeometry(), currentTimePoint, nextTimePoint); + } + + dynamicImage->SetTimeGeometry(timeGeometry); + + this->m_ResultImage = dynamicImage; +} + + + +void mitk::PerfusionDataGenerator::SortParameterImages() +{ + ParameterVectorType inputImages(this->m_ParameterInputMap.size()); + + unsigned int i = 0; + for (ParameterMapType::const_iterator pos = m_ParameterInputMap.begin(); pos != m_ParameterInputMap.end(); ++pos) + { + + i = pos->first; + inputImages[i] = pos->second; + } + + this->m_InputParameterImages = inputImages; + + +} + +void mitk::PerfusionDataGenerator::Generate() +{ + SortParameterImages(); + + if(this->m_Mask.IsNotNull()) + { + AccessFixedDimensionByItk(m_Mask, mitk::PerfusionDataGenerator::DoPrepareMask, 3); + } + else + { + this->m_InternalMask = NULL; + } + + /** @todo #1 This did not work! The Access-Routine would be a much nicer solution, but for some reasons, the handling did not work. + * Thats why the code for Generation the Data was pasted below + */ +// mitk::Image::Pointer firstParameterImage = this->m_InputParameterImages[0]; +// AccessFixedDimensionByItk(firstParameterImage, mitk::PerfusionDataGenerator::DoGenerateData, 3); + + + typedef itk::Image InputFrameImageType; + typedef itk::Image OutputImageType; + + typedef itk::MultiOutputNaryFunctorImageFilter FilterType; + /** @todo #3 The ParameterFitImageGenerator uses a typename instead of new. But this did not work somehow + */ + FilterType::Pointer filter = FilterType::New(); + + + for(unsigned int i=0; im_ParameterInputMap.size(); ++i) + { + /** @todo #3 The ParameterFitImageGenerator uses a typename instead of new. But this did not work somehow + */ + InputFrameImageType::Pointer frameImage = InputFrameImageType::New(); + Image::Pointer parameterImage = m_InputParameterImages.at(i); + + mitk::CastToItkImage(parameterImage, frameImage); + filter->SetInput(i,frameImage); + + } + + SimpleFunctorPolicy functor; + functor.SetFunctor(this->m_Functor); + filter->SetFunctor(functor); + if (this->m_InternalMask.IsNotNull()) + { + filter->SetMask(this->m_InternalMask); + } + filter->Update(); + + if (filter->GetNumberOfOutputs() != this->m_Functor->GetGrid().GetSize()) + { + itkExceptionMacro("Error. Number of computed output Images does not match Grid size!"); + } + + /** @todo #1 Better solution than all this code! + * This was copied from TestingHelper/TestArtifactGenerator. Just instantiating a mitk::Image and setting its Volumes + * in the for-loop did not work somehow. + * This was a work around + */ + + typedef itk::Image DynamicITKImageType; + + Image::Pointer dynamicImage= Image::New(); + mitk::Image::Pointer tempImage = mitk::ImportItkImage(filter->GetOutput(0))->Clone(); + + DynamicITKImageType::Pointer dynamicITKImage = DynamicITKImageType::New(); + DynamicITKImageType::RegionType dynamicITKRegion; + DynamicITKImageType::PointType dynamicITKOrigin; + DynamicITKImageType::IndexType dynamicITKIndex; + DynamicITKImageType::SpacingType dynamicITKSpacing; + + dynamicITKSpacing[0] = tempImage->GetGeometry()->GetSpacing()[0]; + dynamicITKSpacing[1] = tempImage->GetGeometry()->GetSpacing()[1]; + dynamicITKSpacing[2] = tempImage->GetGeometry()->GetSpacing()[2]; + dynamicITKSpacing[3] = 3.0; + + dynamicITKIndex[0] = 0; // The first pixel of the REGION + dynamicITKIndex[1] = 0; + dynamicITKIndex[2] = 0; + dynamicITKIndex[3] = 0; + + dynamicITKRegion.SetSize( 0,tempImage->GetDimension(0)); + dynamicITKRegion.SetSize( 1,tempImage->GetDimension(1)); + dynamicITKRegion.SetSize( 2,tempImage->GetDimension(2)); + dynamicITKRegion.SetSize(3, filter->GetNumberOfOutputs()); + + dynamicITKRegion.SetIndex( dynamicITKIndex ); + + dynamicITKOrigin[0]=tempImage->GetGeometry()->GetOrigin()[0]; + dynamicITKOrigin[1]=tempImage->GetGeometry()->GetOrigin()[1]; + dynamicITKOrigin[2]=tempImage->GetGeometry()->GetOrigin()[2]; + + dynamicITKImage->SetOrigin(dynamicITKOrigin); + dynamicITKImage->SetSpacing(dynamicITKSpacing); + dynamicITKImage->SetRegions( dynamicITKRegion); + dynamicITKImage->Allocate(); + dynamicITKImage->FillBuffer(0); //not sure if this is necessary + + // Convert + mitk::CastToMitkImage(dynamicITKImage, dynamicImage); + + + + ArbitraryTimeGeometry::Pointer timeGeometry = ArbitraryTimeGeometry::New(); + timeGeometry->ClearAllGeometries(); + + auto nrOfOutputs = filter->GetNumberOfOutputs(); + auto grid = this->m_Functor->GetGrid(); + for (unsigned int i = 0; iGetOutput(i))->Clone(); + + dynamicImage->SetVolume(frame->GetVolumeData()->GetData(),i); + + double tmax = 0; + if (i<(nrOfOutputs - 1)) + { + tmax = grid[i + 1] * 1000; + } + else + { + tmax = grid[i] * 1000; + } + timeGeometry->AppendNewTimeStepClone(frame->GetGeometry(), grid[i] * 1000, tmax); + } + + dynamicImage->SetTimeGeometry(timeGeometry); + + this->m_ResultImage = dynamicImage->Clone(); + +} diff --git a/Modules/Pharmacokinetics/test/CMakeLists.txt b/Modules/Pharmacokinetics/test/CMakeLists.txt new file mode 100644 index 0000000000..d45daf111d --- /dev/null +++ b/Modules/Pharmacokinetics/test/CMakeLists.txt @@ -0,0 +1 @@ +MITK_CREATE_MODULE_TESTS() \ No newline at end of file diff --git a/Modules/Pharmacokinetics/test/ConvertToConcentrationTest.cpp b/Modules/Pharmacokinetics/test/ConvertToConcentrationTest.cpp new file mode 100644 index 0000000000..3d82434113 --- /dev/null +++ b/Modules/Pharmacokinetics/test/ConvertToConcentrationTest.cpp @@ -0,0 +1,142 @@ +/*=================================================================== + +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 "mitkTestingMacros.h" + +#include "itkImage.h" +#include "itkImageRegionIterator.h" + +#include "itkBinaryFunctorImageFilter.h" + +#include "mitkConvertToConcentrationFunctor.h" + + +int ConvertToConcentrationTest(int argc , char* argv[]) +{ + // always start with this! + MITK_TEST_BEGIN("ConvertToConcentration"); + + //Initialization Parameters + double RelaxationTime = 1.2; + double RecoveryTime = 0.125; + double Relaxivity = 4.3; + + + + //Test1: Functor calculation + mitk::ConvertToConcentrationFunctor testFunctor; + testFunctor.initialize(RelaxationTime, Relaxivity, RecoveryTime); + + + double s0 = 197.0; + double sCM = 278.0; + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(0.009,testFunctor(sCM,s0), 1e-6, true)==true,"Check Functor Calculation with Input Value and baseline: 1"); + s0 = 157.0; + sCM = 207.0; + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(0.0069,testFunctor(sCM,s0), 1e-6, true)==true,"Check Functor Calculation with Input Value and baseline: 2"); + s0 = 195.0; + sCM = 270.0; + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(0.0084,testFunctor(sCM,s0), 1e-6, true)==true,"Check Functor Calculation with Input Value and baseline: 3"); + s0 = 177.0; + sCM = 308.0; + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(0.0164,testFunctor(sCM,s0), 1e-6, true)==true,"Check Functor Calculation with Input Value and baseline: 4"); + + //Test2: Filter usage with Functor + + typedef itk::Image ImageType; + typedef mitk::ConvertToConcentrationFunctor ConversionFunctorType; + typedef itk::BinaryFunctorImageFilter FilterType; + + //Definition of testimages + ImageType::Pointer image = ImageType::New(); + ImageType::Pointer BaselineImage = ImageType::New(); + ImageType::IndexType start; + start[0] = 0; // first index on X + start[1] = 0; // first index on Y + start[2] = 0; // first index on Z + ImageType::SizeType size; + size[0] = 2; // size along X + size[1] = 2; // size along Y + size[2] = 2; // size along Z + ImageType::RegionType region; + region.SetSize( size ); + region.SetIndex( start ); + image->SetRegions( region ); + image->Allocate(); + BaselineImage->SetRegions( region ); + BaselineImage->Allocate(); + itk::ImageRegionIterator it = itk::ImageRegionIterator(image,image->GetLargestPossibleRegion()); + itk::ImageRegionIterator Bit = itk::ImageRegionIterator(BaselineImage,BaselineImage->GetLargestPossibleRegion()); + int count = 0; + while (!it.IsAtEnd()&& !Bit.IsAtEnd()) + { + Bit.Set(150); + it.Set(count*50+150); + ++it; + ++Bit; + ++count; + } + //Filterinitialization + FilterType::Pointer ConversionFilter = FilterType::New(); + ConversionFilter->SetFunctor(testFunctor); + ConversionFilter->SetInput1(image); + ConversionFilter->SetInput2(BaselineImage); + + ConversionFilter->Update(); + ImageType::Pointer convertedImage = ImageType::New(); + convertedImage = ConversionFilter->GetOutput(); + + MITK_TEST_EQUAL(image->GetImageDimension(),convertedImage->GetImageDimension(),"Check dimensions of result image"); + + itk::Index<3> idx; + idx[0]=0; + idx[1]=0; + idx[2]=0; + MITK_TEST_EQUAL(0,convertedImage->GetPixel(idx),"Check pixel of converted image index <0,0,0>"); + idx[0]=1; + idx[1]=0; + idx[2]=0; + MITK_TEST_EQUAL(0.0072,convertedImage->GetPixel(idx),"Check pixel of converted image index <1,0,0>"); + idx[0]=0; + idx[1]=1; + idx[2]=0; + MITK_TEST_EQUAL(0.0147,convertedImage->GetPixel(idx),"Check pixel of converted image index <0,1,0>"); + idx[0]=1; + idx[1]=1; + idx[2]=0; + MITK_TEST_EQUAL(0.0225,convertedImage->GetPixel(idx),"Check pixel of converted image index <1,1,0>"); + idx[0]=0; + idx[1]=0; + idx[2]=1; + MITK_TEST_EQUAL(0.0307 ,convertedImage->GetPixel(idx),"Check pixel of converted image index <0,0,1>"); + idx[0]=1; + idx[1]=0; + idx[2]=1; + MITK_TEST_EQUAL(0.0392,convertedImage->GetPixel(idx),"Check pixel of converted image index <1,0,1>"); + idx[0]=0; + idx[1]=1; + idx[2]=1; + MITK_TEST_EQUAL(0.0480,convertedImage->GetPixel(idx),"Check pixel of converted image index <0,1,1>"); + idx[0]=1; + idx[1]=1; + idx[2]=1; + MITK_TEST_EQUAL(0.0574,convertedImage->GetPixel(idx),"Check pixel of converted image index <1,1,1>"); + + + + MITK_TEST_END() +} diff --git a/Modules/Pharmacokinetics/test/files.cmake b/Modules/Pharmacokinetics/test/files.cmake new file mode 100644 index 0000000000..713e14913f --- /dev/null +++ b/Modules/Pharmacokinetics/test/files.cmake @@ -0,0 +1,4 @@ +SET(MODULE_TESTS + mitkDescriptivePharmacokineticBrixModelTest.cpp + #ConvertToConcentrationTest.cpp +) diff --git a/Modules/Pharmacokinetics/test/mitkDescriptivePharmacokineticBrixModelTest.cpp b/Modules/Pharmacokinetics/test/mitkDescriptivePharmacokineticBrixModelTest.cpp new file mode 100644 index 0000000000..fede48176f --- /dev/null +++ b/Modules/Pharmacokinetics/test/mitkDescriptivePharmacokineticBrixModelTest.cpp @@ -0,0 +1,48 @@ +#include "mitkTestingMacros.h" +#include "mitkVector.h" + +#include "mitkDescriptivePharmacokineticBrixModel.h" + + + +int mitkDescriptivePharmacokineticBrixModelTest(int /*argc*/ , char*[] /*argv[]*/){ + + MITK_TEST_BEGIN("DescriptivePharmacokineticBrixModel") + + mitk::ModelBase::TimeGridType grid(22); + mitk::ModelBase::ModelResultType output; + mitk::ModelBase::ParametersType testparameters(4); + + testparameters[mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_A] = 1.25; + testparameters(mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_kep) = 3.89; + testparameters(mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_kel) = 0.12; + testparameters(mitk::DescriptivePharmacokineticBrixModel::POSITION_PARAMETER_tlag) = 1.14; + + + + for (int i = 0; i<22; ++i) + { + // time grid in seconds, 14s between frames + grid[i]=(double) 14*i; + } + //injection time in minutes --> 60s + double injectiontime = 0.5; + mitk::DescriptivePharmacokineticBrixModel::Pointer testmodel = mitk::DescriptivePharmacokineticBrixModel::New(); + testmodel->SetTimeGrid(grid); + testmodel->SetTau(injectiontime); + + CPPUNIT_ASSERT_MESSAGE("Check number of parameters in Model.", 4 == testmodel->GetNumberOfParameters()); + output = testmodel->GetSignal(testparameters); + //precision of output ? + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(1,output[0], 1e-6, true)==true,"Check Output signal values - 0"); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(1,output[4], 1e-6, true)==true,"Check Output signal values - 4"); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(1.003338,output[5], 1e-6, true)==true,"Check Output signal values - 5"); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(1.238392,output[6], 1e-6, true)==true,"Check Output signal values - 6"); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(1.669835,output[7], 1e-6, true)==true,"Check Output signal values - 7"); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(1.982948,output[8], 1e-6, true)==true,"Check Output signal values - 8"); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(2.089685,output[9], 1e-6, true)==true,"Check Output signal values - 9"); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(2.113611,output[10], 1e-6, true)==true,"Check Output signal values - 10"); + + MITK_TEST_END() + +} diff --git a/Modules/PharmacokineticsUI/CMakeLists.txt b/Modules/PharmacokineticsUI/CMakeLists.txt new file mode 100644 index 0000000000..a407d55023 --- /dev/null +++ b/Modules/PharmacokineticsUI/CMakeLists.txt @@ -0,0 +1,6 @@ +MITK_CREATE_MODULE(PharmacokineticsUI + INCLUDE_DIRS Common Qmitk + DEPENDS MitkPharmacokinetics MitkQtWidgets MitkQtWidgetsExt + PACKAGE_DEPENDS Qt5|Core CTK|CTKWidgets Boost +WARNINGS_NO_ERRORS +) diff --git a/Modules/PharmacokineticsUI/Qmitk/QmitkDescriptionParameterBackgroundJob.cpp b/Modules/PharmacokineticsUI/Qmitk/QmitkDescriptionParameterBackgroundJob.cpp new file mode 100644 index 0000000000..0040e4d63a --- /dev/null +++ b/Modules/PharmacokineticsUI/Qmitk/QmitkDescriptionParameterBackgroundJob.cpp @@ -0,0 +1,129 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Software Development for +Integrated Diagnostic and Therapy. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + + +#include "QmitkDescriptionParameterBackgroundJob.h" +#include "mitkModelFitInfo.h" + +void DescriptionParameterBackgroundJob::OnComputeEvent(::itk::Object* caller, + const itk::EventObject& event) +{ + itk::ProgressEvent progressEvent; + itk::InitializeEvent initEvent; + itk::StartEvent startEvent; + itk::EndEvent endEvent; + + if (progressEvent.CheckEvent(&event)) + { + mitk::DescriptionParameterImageGeneratorBase* castedReporter = + dynamic_cast(caller); + emit JobProgress(castedReporter->GetProgress()); + } + else if (initEvent.CheckEvent(&event)) + { + emit JobStatusChanged(QString("Initializing description parameter generator")); + } + else if (startEvent.CheckEvent(&event)) + { + emit JobStatusChanged(QString("Started parameter computation process.")); + } + else if (endEvent.CheckEvent(&event)) + { + emit JobStatusChanged(QString("Finished parameter computation process.")); + } +} + +DescriptionParameterBackgroundJob:: +DescriptionParameterBackgroundJob(mitk::DescriptionParameterImageGeneratorBase* generator, + mitk::DataNode* parentNode) +{ + if (!generator) + { + mitkThrow() << "Cannot create description parameter background job. Passed fit generator is NULL."; + } + + m_Generator = generator; + m_ParentNode = parentNode; + + m_spCommand = ::itk::MemberCommand::New(); + m_spCommand->SetCallbackFunction(this, &DescriptionParameterBackgroundJob::OnComputeEvent); + m_ObserverID = m_Generator->AddObserver(::itk::AnyEvent(), m_spCommand); +}; + +mitk::DataNode* +DescriptionParameterBackgroundJob:: +GetParentNode() const +{ + return m_ParentNode; +}; + +DescriptionParameterBackgroundJob:: +~DescriptionParameterBackgroundJob() +{ + m_Generator->RemoveObserver(m_ObserverID); +}; + +mitk::modelFit::ModelFitResultNodeVectorType DescriptionParameterBackgroundJob::CreateResultNodes( + const mitk::DescriptionParameterImageGeneratorBase::ParameterImageMapType& paramimages) +{ + mitk::modelFit::ModelFitResultNodeVectorType results; + + for (auto image : paramimages) + { + if (image.second.IsNull()) + { + mitkThrow() << "Cannot generate result node. Passed parameterImage is null. parameter name: " << + image.first; + } + + mitk::DataNode::Pointer result = mitk::DataNode::New(); + result->SetData(image.second); + result->SetName(image.first); + result->SetVisibility(true); + results.push_back(result); + } + + return results; +}; + +void +DescriptionParameterBackgroundJob:: +run() +{ + try + { + emit JobStatusChanged(QString("Started session...")); + + m_Generator->Generate(); + + emit JobStatusChanged(QString("Generate result nodes.")); + + m_Results = CreateResultNodes(m_Generator->GetParameterImages()); + + emit ResultsAreAvailable(m_Results, this); + } + catch (::std::exception& e) + { + emit Error(QString("Error while processing data. Details: ") + QString::fromLatin1(e.what())); + } + catch (...) + { + emit Error(QString("Unkown error when processing the data.")); + } + + emit Finished(); +}; diff --git a/Modules/PharmacokineticsUI/Qmitk/QmitkDescriptionParameterBackgroundJob.h b/Modules/PharmacokineticsUI/Qmitk/QmitkDescriptionParameterBackgroundJob.h new file mode 100644 index 0000000000..a543fbc242 --- /dev/null +++ b/Modules/PharmacokineticsUI/Qmitk/QmitkDescriptionParameterBackgroundJob.h @@ -0,0 +1,79 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Software Development for +Integrated Diagnostic and Therapy. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + + +#ifndef __QMITK_DESCRIPTION_PARAMETER_BACKGROUND_JOB_H +#define __QMITK_DESCRIPTION_PARAMETER_BACKGROUND_JOB_H + + +//QT +#include +#include + +//MITK +#include + +#include +#include +#include + +// ITK +#include + +#include "MitkPharmacokineticsUIExports.h" + +class MITKPHARMACOKINETICSUI_EXPORT DescriptionParameterBackgroundJob : public QObject, public QRunnable +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + +public: + DescriptionParameterBackgroundJob(mitk::DescriptionParameterImageGeneratorBase* generator, mitk::DataNode* parentNode = NULL); + ~DescriptionParameterBackgroundJob(); + + void run(); + + /**Returns the node (if defined), that is the parent object for the results of the job. + May be null.*/ + mitk::DataNode* GetParentNode() const; + +signals: + void Finished(); + void Error(QString err); + void ResultsAreAvailable(mitk::modelFit::ModelFitResultNodeVectorType resultMap, const DescriptionParameterBackgroundJob* pJob); + void JobProgress(double progress); + void JobStatusChanged(QString info); + +protected: + static mitk::modelFit::ModelFitResultNodeVectorType CreateResultNodes(const mitk::DescriptionParameterImageGeneratorBase::ParameterImageMapType& paramimages); + + //Inputs + mitk::DescriptionParameterImageGeneratorBase::Pointer m_Generator; + mitk::DataNode::Pointer m_ParentNode; + + // Results + mitk::modelFit::ModelFitResultNodeVectorType m_Results; + + ::itk::MemberCommand::Pointer m_spCommand; + unsigned long m_ObserverID; + + void OnComputeEvent(::itk::Object *, const itk::EventObject &event); +}; + +#endif + diff --git a/Modules/PharmacokineticsUI/files.cmake b/Modules/PharmacokineticsUI/files.cmake new file mode 100644 index 0000000000..afb8e68b31 --- /dev/null +++ b/Modules/PharmacokineticsUI/files.cmake @@ -0,0 +1,16 @@ +set(CPP_FILES + Qmitk/QmitkDescriptionParameterBackgroundJob.cpp +) + +set(H_FILES +) + +set(TPP_FILES +) + +set(UI_FILES +) + +set(MOC_H_FILES + Qmitk/QmitkDescriptionParameterBackgroundJob.h +) diff --git a/Plugins/PluginList.cmake b/Plugins/PluginList.cmake index 3b75d76cb8..b32aa7bd48 100644 --- a/Plugins/PluginList.cmake +++ b/Plugins/PluginList.cmake @@ -1,105 +1,110 @@ # Plug-ins must be ordered according to their dependencies set(MITK_PLUGINS org.blueberry.core.runtime:ON org.blueberry.core.expressions:OFF org.blueberry.core.commands:OFF org.blueberry.core.jobs:OFF org.blueberry.ui.qt:OFF org.blueberry.ui.qt.help:ON org.blueberry.ui.qt.log:ON org.blueberry.ui.qt.objectinspector:OFF #org.blueberry.test:ON #org.blueberry.uitest:ON #Testing/org.blueberry.core.runtime.tests:ON #Testing/org.blueberry.osgi.tests:ON org.mitk.core.services:ON org.mitk.gui.common:ON org.mitk.planarfigure:ON org.mitk.core.ext:OFF org.mitk.core.jobs:OFF org.mitk.gui.qt.application:ON org.mitk.gui.qt.coreapplication:OFF org.mitk.gui.qt.ext:OFF org.mitk.gui.qt.extapplication:OFF org.mitk.gui.qt.common:ON org.mitk.gui.qt.stdmultiwidgeteditor:ON org.mitk.gui.qt.common.legacy:OFF org.mitk.gui.qt.cmdlinemodules:OFF org.mitk.gui.qt.diffusionimagingapp:OFF org.mitk.gui.qt.datamanager:ON org.mitk.gui.qt.datamanagerlight:OFF org.mitk.gui.qt.properties:ON org.mitk.gui.qt.basicimageprocessing:OFF org.mitk.gui.qt.dicom:OFF org.mitk.gui.qt.dicominspector:OFF org.mitk.gui.qt.diffusionimaging:OFF org.mitk.gui.qt.diffusionimaging.connectomics:OFF org.mitk.gui.qt.diffusionimaging.denoising:OFF org.mitk.gui.qt.diffusionimaging.fiberfox:OFF org.mitk.gui.qt.diffusionimaging.fiberprocessing:OFF org.mitk.gui.qt.diffusionimaging.ivim:OFF org.mitk.gui.qt.diffusionimaging.odfpeaks:OFF org.mitk.gui.qt.diffusionimaging.partialvolume:OFF org.mitk.gui.qt.diffusionimaging.preprocessing:OFF org.mitk.gui.qt.diffusionimaging.reconstruction:OFF org.mitk.gui.qt.diffusionimaging.registration:OFF org.mitk.gui.qt.diffusionimaging.tbss:OFF org.mitk.gui.qt.diffusionimaging.tractography:OFF org.mitk.gui.qt.diffusionimaging.python:OFF org.mitk.gui.qt.dosevisualization:OFF org.mitk.gui.qt.geometrytools:OFF org.mitk.gui.qt.igtexamples:OFF org.mitk.gui.qt.igttracking:OFF org.mitk.gui.qt.lasercontrol:OFF org.mitk.gui.qt.openigtlink:OFF org.mitk.gui.qt.imagecropper:OFF org.mitk.gui.qt.imagenavigator:ON org.mitk.gui.qt.viewnavigator:OFF org.mitk.gui.qt.materialeditor:OFF org.mitk.gui.qt.measurementtoolbox:OFF org.mitk.gui.qt.moviemaker:OFF org.mitk.gui.qt.pointsetinteraction:OFF org.mitk.gui.qt.pointsetinteractionmultispectrum:OFF org.mitk.gui.qt.python:OFF org.mitk.gui.qt.remeshing:OFF org.mitk.gui.qt.segmentation:OFF org.mitk.gui.qt.aicpregistration:OFF org.mitk.gui.qt.renderwindowmanager:OFF org.mitk.gui.qt.toftutorial:OFF org.mitk.gui.qt.tofutil:OFF org.mitk.gui.qt.tubegraph:OFF org.mitk.gui.qt.ugvisualization:OFF org.mitk.gui.qt.photoacoustics.pausviewer:OFF org.mitk.gui.qt.photoacoustics.imageprocessing:OFF org.mitk.gui.qt.photoacoustics.simulation:OFF org.mitk.gui.qt.ultrasound:OFF org.mitk.gui.qt.volumevisualization:OFF org.mitk.gui.qt.eventrecorder:OFF org.mitk.gui.qt.xnat:OFF org.mitk.gui.qt.igt.app.echotrack:OFF org.mitk.gui.qt.spectrocamrecorder:OFF org.mitk.gui.qt.classificationsegmentation:OFF org.mitk.gui.qt.overlaymanager:OFF org.mitk.gui.qt.igt.app.hummelprotocolmeasurements:OFF org.mitk.gui.qt.multilabelsegmentation:OFF org.mitk.matchpoint.core.helper:OFF org.mitk.gui.qt.matchpoint.algorithm.browser:OFF org.mitk.gui.qt.matchpoint.algorithm.control:OFF org.mitk.gui.qt.matchpoint.algorithm.batch:OFF org.mitk.gui.qt.matchpoint.mapper:OFF org.mitk.gui.qt.matchpoint.framereg:OFF org.mitk.gui.qt.matchpoint.visualizer:OFF org.mitk.gui.qt.matchpoint.evaluator:OFF org.mitk.gui.qt.matchpoint.manipulator:OFF org.mitk.gui.qt.preprocessing.resampling:OFF org.mitk.gui.qt.cest:OFF org.mitk.gui.qt.fit.demo:ON org.mitk.gui.qt.fit.inspector:ON org.mitk.gui.qt.fit.genericfitting:ON + org.mitk.gui.qt.pharmacokinetics.mri:ON + org.mitk.gui.qt.pharmacokinetics.pet:ON + org.mitk.gui.qt.pharmacokinetics.simulation:ON + org.mitk.gui.qt.pharmacokinetics.curvedescriptor:ON + org.mitk.gui.qt.pharmacokinetics.concentration.mri:ON ) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/CMakeLists.txt b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/CMakeLists.txt new file mode 100644 index 0000000000..840fc6a0da --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/CMakeLists.txt @@ -0,0 +1,9 @@ +project(org_mitk_gui_qt_pharmacokinetics_concentration_mri) + +mitk_create_plugin( + EXPORT_DIRECTIVE CONCENTRATIONCURVECONVERTER_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgetsExt MitkPharmacokinetics + PACKAGE_DEPENDS ITK|ITKOptimizers + +) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..8bb4491add --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/documentation/UserManual/Manual.dox @@ -0,0 +1,10 @@ +/** +\page org_mitk_gui_qt_pharmacokinetics_concentration_mri The Concentration Curve Converter View + +\li \ref org_mitk_gui_qt_pharmacokinetics_concentration_mri_Introduction + +\section org_mitk_gui_qt_pharmacokinetics_concentration_mri_Introduction Introduction +This view offers the to posibility to convert MRI image signals into concentration images. +Theses concentration images can e.g. be used for perfusion model fitting. + +*/ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..571345107f --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk_gui_qt_pharmacokinetics_concentration_mri org.mitk.gui.qt.pharmacokinetics.concentration.mri + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup org_mitk_gui_qt_pharmacokinetics_concentration_mri_internal Internal + \ingroup org_mitk_gui_qt_pharmacokinetics_concentration_mri + + \brief This subcategory includes the internal classes of the org.mitk.gui.qt.pharmacokinetics.concentration.mri plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/files.cmake b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/files.cmake new file mode 100644 index 0000000000..17c9dffd99 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/files.cmake @@ -0,0 +1,42 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_ConcentrationCurveConverterView_Activator.cpp + ConcentrationCurveConverterView.cpp +) + +set(UI_FILES + src/internal/ConcentrationCurveConverterViewControls.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_ConcentrationCurveConverterView_Activator.h + src/internal/ConcentrationCurveConverterView.h +) + +# list of resource files which can be used by the plug-in +# system without loading the plug-ins shared library, +# for example the icon used in the menu and tabs for the +# plug-in views in the workbench +set(CACHED_RESOURCE_FILES + resources/Convert.png + plugin.xml +) + +# list of Qt .qrc files which contain additional resources +# specific to this plugin +set(QRC_FILES + +) + +set(CPP_FILES ) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/manifest_headers.cmake new file mode 100644 index 0000000000..2266f968b7 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "Concentration Curve Converter Plugin") +set(Plugin-Version "1.0") +set(Plugin-Vendor "DKFZ, Software Development For Integrated Diagnostics and Therapy") +set(Plugin-ContactAddress "c.debus@dkfz.de") +set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/plugin.xml b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/plugin.xml new file mode 100644 index 0000000000..fead26d528 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/resources/Convert.png b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/resources/Convert.png new file mode 100644 index 0000000000..5c18097572 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/resources/Convert.png differ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/src/internal/ConcentrationCurveConverterView.cpp b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/src/internal/ConcentrationCurveConverterView.cpp new file mode 100644 index 0000000000..829114a84c --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/src/internal/ConcentrationCurveConverterView.cpp @@ -0,0 +1,401 @@ +/*=================================================================== + +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 "mitkWorkbenchUtil.h" + +#include "ConcentrationCurveConverterView.h" +#include "mitkConcentrationCurveGenerator.h" +#include "mitkNodePredicateDataType.h" +#include "mitkConvertToConcentrationTurboFlashFunctor.h" +#include "mitkConvertToConcentrationAbsoluteFunctor.h" +#include "mitkConvertToConcentrationRelativeFunctor.h" +#include "itkBinaryFunctorImageFilter.h" + + + +// Includes for image casting between ITK and MITK +#include "mitkImageTimeSelector.h" +#include "mitkImageCast.h" +#include "mitkITKImageImport.h" +#include + +#include + +const std::string ConcentrationCurveConverterView::VIEW_ID = "org.mitk.ConcentrationCurveConverterView"; + +void ConcentrationCurveConverterView::SetFocus() +{ + m_Controls.btnConvertToConcentration->setFocus(); +} + +void ConcentrationCurveConverterView::CreateQtPartControl(QWidget* parent) +{ + m_Controls.setupUi(parent); + m_Controls.btnConvertToConcentration->setEnabled(false); + + connect(m_Controls.btnConvertToConcentration, SIGNAL(clicked()), this, SLOT(OnConvertToConcentrationButtonClicked())); + + m_Controls.groupBox_T1->hide(); + m_Controls.groupBox_T2->hide(); + m_Controls.groupBox3D->hide(); + m_Controls.groupBox4D->hide(); + m_Controls.groupBoxTurboFlash->hide(); + m_Controls.factorSpinBox->setEnabled(false); + m_Controls.groupBox_ConcentrationParameters->hide(); + + connect(m_Controls.radioButton_T1, SIGNAL(toggled(bool)),this, SLOT(OnSettingChanged())); + connect(m_Controls.radioButton_T2, SIGNAL(toggled(bool)),this, SLOT(OnSettingChanged())); + + connect(m_Controls.radioButton3D, SIGNAL(toggled(bool)),this, SLOT(OnSettingChanged())); + connect(m_Controls.radioButton4D, SIGNAL(toggled(bool)),this, SLOT(OnSettingChanged())); + + connect(m_Controls.radioButtonTurboFlash, SIGNAL(toggled(bool)), m_Controls.groupBoxTurboFlash, + SLOT(setVisible(bool))); + + connect(m_Controls.radioButtonTurboFlash, SIGNAL(toggled(bool)), this, + SLOT(OnSettingChanged())); + connect(m_Controls.relaxationTime, SIGNAL(valueChanged(double)), this, + SLOT(OnSettingChanged())); + connect(m_Controls.recoveryTime, SIGNAL(valueChanged(double)), this, SLOT(OnSettingChanged())); + connect(m_Controls.relaxivity, SIGNAL(valueChanged(double)), this, SLOT(OnSettingChanged())); + + connect(m_Controls.radioButton_absoluteEnhancement, SIGNAL(toggled(bool)), this, + SLOT(OnSettingChanged())); + connect(m_Controls.radioButton_relativeEnchancement, SIGNAL(toggled(bool)), this, + SLOT(OnSettingChanged())); + connect(m_Controls.radioButton_absoluteEnhancement, SIGNAL(toggled(bool)), m_Controls.factorSpinBox, + SLOT(setEnabled(bool))); + connect(m_Controls.radioButton_relativeEnchancement, SIGNAL(toggled(bool)), + m_Controls.factorSpinBox, + SLOT(setEnabled(bool))); + connect(m_Controls.factorSpinBox, SIGNAL(valueChanged(double)), this, + SLOT(OnSettingChanged())); + +} + + +void ConcentrationCurveConverterView::OnSettingChanged() +{ + bool ok = true; + m_Controls.groupBox_T1->setVisible(m_Controls.radioButton_T1->isChecked()); + m_Controls.groupBox_T2->setVisible(m_Controls.radioButton_T2->isChecked()); + + if(m_Controls.radioButton_T1->isChecked()) + { + m_Controls.groupBox_ConcentrationParameters->setVisible(true); + m_Controls.groupBox3D->setVisible(m_Controls.radioButton3D->isChecked()); + m_Controls.groupBox4D->setVisible(m_Controls.radioButton4D->isChecked()); + + if(m_Controls.radioButton4D->isChecked()) + { + ok = m_selectedImage.IsNotNull() && CheckSettings(); + } + else if(m_Controls.radioButton3D->isChecked()) + { + ok = m_selectedImage.IsNotNull() && m_selectedBaselineImage.IsNotNull() && CheckSettings(); + + } + } + else if (m_Controls.radioButton_T2->isChecked()) + { + m_Controls.groupBox_ConcentrationParameters->setVisible(false); + + ok = m_selectedImage.IsNotNull() && CheckSettings(); + + } + + m_Controls.btnConvertToConcentration->setEnabled(ok); +} + + +bool ConcentrationCurveConverterView::CheckSettings() const +{ + bool ok = true; + + if(m_Controls.radioButton_T1->isChecked()) + { + if (this->m_Controls.radioButtonTurboFlash->isChecked()) + { + ok = ok && (m_Controls.recoveryTime->value() > 0); + ok = ok && (m_Controls.relaxationTime->value() > 0); + ok = ok && (m_Controls.relaxivity->value() > 0); + + } + else if (this->m_Controls.radioButton_absoluteEnhancement->isChecked() + || this->m_Controls.radioButton_relativeEnchancement->isChecked()) + { + ok = ok && (m_Controls.factorSpinBox->value() > 0); + } + else + { + ok = false; + } + } + else if (this->m_Controls.radioButton_T2->isChecked()) + { + ok = ok && m_Controls.T2EchoTimeSpinBox->value() > 0; + ok = ok && m_Controls.T2FactorSpinBox->value() > 0; + } + else + { + ok=false; + } + + + return ok; +} + +void ConcentrationCurveConverterView::OnConvertToConcentrationButtonClicked() +{ + + mitk::Image::Pointer concentrationImage; + mitk::DataNode::Pointer concentrationNode; + + if(m_Controls.radioButton_T1->isChecked()) + { + if(m_Controls.radioButton4D->isChecked()) + { + concentrationImage = this->Convert4DConcentrationImage(this->m_selectedImage); + } + else if(m_Controls.radioButton3D->isChecked()) + { + concentrationImage = Convert3DConcentrationImage(this->m_selectedImage, this->m_selectedBaselineImage); + } + } + else if(m_Controls.radioButton_T2->isChecked()) + { + concentrationImage = this->ConvertT2ConcentrationImgage(this->m_selectedImage); + } + std::string nameOfResultImage = m_selectedNode->GetName(); + nameOfResultImage.append("_Concentration"); + + concentrationNode = AddConcentrationImage(concentrationImage,nameOfResultImage); + +} + + +mitk::Image::Pointer ConcentrationCurveConverterView::Convert3DConcentrationImage(mitk::Image::Pointer inputImage,mitk::Image::Pointer baselineImage) + { + typedef itk::Image InputImageType; + + InputImageType::Pointer itkInputImage = InputImageType::New(); + InputImageType::Pointer itkBaselineImage = InputImageType::New(); + + mitk::CastToItkImage(inputImage, itkInputImage ); + mitk::CastToItkImage(baselineImage, itkBaselineImage ); + + + mitk::Image::Pointer outputImage; + + if(this->m_Controls.radioButtonTurboFlash->isChecked()) + { + typedef mitk::ConvertToConcentrationTurboFlashFunctor ConversionFunctorTurboFlashType; + typedef itk::BinaryFunctorImageFilter FilterTurboFlashType; + + ConversionFunctorTurboFlashType ConversionTurboFlashFunctor; + ConversionTurboFlashFunctor.initialize(m_Controls.relaxationTime->value(), m_Controls.relaxivity->value(), m_Controls.recoveryTime->value()); + + FilterTurboFlashType::Pointer ConversionTurboFlashFilter = FilterTurboFlashType::New(); + + ConversionTurboFlashFilter->SetFunctor(ConversionTurboFlashFunctor); + ConversionTurboFlashFilter->SetInput1(itkInputImage); + ConversionTurboFlashFilter->SetInput2(itkBaselineImage); + + ConversionTurboFlashFilter->Update(); + outputImage = mitk::ImportItkImage(ConversionTurboFlashFilter->GetOutput())->Clone(); + + + } + else if(this->m_Controls.radioButton_absoluteEnhancement->isChecked()) + { + typedef mitk::ConvertToConcentrationAbsoluteFunctor ConversionFunctorAbsoluteType; + typedef itk::BinaryFunctorImageFilter FilterAbsoluteType; + + ConversionFunctorAbsoluteType ConversionAbsoluteFunctor; + ConversionAbsoluteFunctor.initialize(m_Controls.factorSpinBox->value()); + + FilterAbsoluteType::Pointer ConversionAbsoluteFilter = FilterAbsoluteType::New(); + + ConversionAbsoluteFilter->SetFunctor(ConversionAbsoluteFunctor); + ConversionAbsoluteFilter->SetInput1(itkInputImage); + ConversionAbsoluteFilter->SetInput2(itkBaselineImage); + + ConversionAbsoluteFilter->Update(); + + outputImage = mitk::ImportItkImage(ConversionAbsoluteFilter->GetOutput())->Clone(); + } + + else if(m_Controls.radioButton_relativeEnchancement->isChecked()) + { + typedef mitk::ConvertToConcentrationRelativeFunctor ConversionFunctorRelativeType; + typedef itk::BinaryFunctorImageFilter FilterRelativeType; + + ConversionFunctorRelativeType ConversionRelativeFunctor; + ConversionRelativeFunctor.initialize(m_Controls.factorSpinBox->value()); + + FilterRelativeType::Pointer ConversionRelativeFilter = FilterRelativeType::New(); + + ConversionRelativeFilter->SetFunctor(ConversionRelativeFunctor); + ConversionRelativeFilter->SetInput1(itkInputImage); + ConversionRelativeFilter->SetInput2(itkBaselineImage); + + ConversionRelativeFilter->Update(); + + outputImage = mitk::ImportItkImage(ConversionRelativeFilter->GetOutput())->Clone(); + } + + + + return outputImage; +} + + +mitk::DataNode::Pointer ConcentrationCurveConverterView::AddConcentrationImage(mitk::Image* image, std::string nodeName) const +{ + if (!image) + { + mitkThrow() << "Cannot generate concentration node. Passed image is null. parameter name: "; + } + + mitk::DataNode::Pointer result = mitk::DataNode::New(); + + result->SetData(image); + + result->SetName(nodeName); + + result->SetVisibility(true); + + + this->GetDataStorage()->Add(result, m_selectedNode); + + return result; +}; + + +mitk::Image::Pointer ConcentrationCurveConverterView::Convert4DConcentrationImage(mitk::Image::Pointer inputImage) +{ + //Compute Concentration image + mitk::ConcentrationCurveGenerator::Pointer concentrationGen = + mitk::ConcentrationCurveGenerator::New(); + concentrationGen->SetDynamicImage(inputImage); + + concentrationGen->SetisTurboFlashSequence(m_Controls.radioButtonTurboFlash->isChecked()); + concentrationGen->SetAbsoluteSignalEnhancement(m_Controls.radioButton_absoluteEnhancement->isChecked()); + concentrationGen->SetRelativeSignalEnhancement(m_Controls.radioButton_relativeEnchancement->isChecked()); + + concentrationGen->SetisT2weightedImage(false); + + if (m_Controls.radioButtonTurboFlash->isChecked()) + { + concentrationGen->SetRecoveryTime(m_Controls.recoveryTime->value()); + concentrationGen->SetRelaxationTime(m_Controls.relaxationTime->value()); + concentrationGen->SetRelaxivity(m_Controls.relaxivity->value()); + } + + else + { + concentrationGen->SetFactor(m_Controls.factorSpinBox->value()); + } + + mitk::Image::Pointer concentrationImage = concentrationGen->GetConvertedImage(); + + return concentrationImage; +} + + +mitk::Image::Pointer ConcentrationCurveConverterView::ConvertT2ConcentrationImgage(mitk::Image::Pointer inputImage) +{ + //Compute Concentration image + mitk::ConcentrationCurveGenerator::Pointer concentrationGen = + mitk::ConcentrationCurveGenerator::New(); + concentrationGen->SetDynamicImage(inputImage); + + concentrationGen->SetisTurboFlashSequence(false); + concentrationGen->SetAbsoluteSignalEnhancement(false); + concentrationGen->SetRelativeSignalEnhancement(false); + + concentrationGen->SetisT2weightedImage(true); + + + concentrationGen->SetT2Factor(m_Controls.T2FactorSpinBox->value()); + concentrationGen->SetT2EchoTime(m_Controls.T2EchoTimeSpinBox->value()); + + + mitk::Image::Pointer concentrationImage = concentrationGen->GetConvertedImage(); + + return concentrationImage; +} + +void ConcentrationCurveConverterView::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*source*/,const QList& selectedNodes ){ + + m_selectedNode = NULL; + m_selectedImage = NULL; + m_selectedBaselineNode = NULL; + m_selectedBaselineImage = NULL; + + m_Controls.timeserieslabel->setText("No (valid) series selected."); + m_Controls.BaselineImageLabel->setText("No (valid) baseline image selected."); + m_Controls.ImageLabel->setText("No (valid) image selected."); + m_Controls.T2_SeriesLabel->setText("No (valid) series selected."); + + m_Controls.btnConvertToConcentration->setEnabled(false); + + QList nodes = selectedNodes; + mitk::NodePredicateDataType::Pointer imagePredicate = mitk::NodePredicateDataType::New("Image"); + + if(m_Controls.radioButton_T1->isChecked()) + { + if (nodes.size() > 0 && imagePredicate->CheckNode(nodes.front())) + { + this->m_selectedNode = nodes.front(); + this->m_selectedImage = dynamic_cast(this->m_selectedNode->GetData()); + m_Controls.timeserieslabel->setText((this->m_selectedNode->GetName()).c_str()); + nodes.pop_front(); + } + + if (nodes.size() > 0 && imagePredicate->CheckNode(nodes.front())) + { + + this->m_selectedBaselineNode = nodes.front(); + this->m_selectedBaselineImage = dynamic_cast(this->m_selectedBaselineNode->GetData()); + this->m_Controls.BaselineImageLabel->setText((this->m_selectedBaselineNode->GetName()).c_str()); + } + } + else if(m_Controls.radioButton_T2->isChecked()) + { + if (nodes.size() > 0 && imagePredicate->CheckNode(nodes.front())) + { + this->m_selectedNode = nodes.front(); + this->m_selectedImage = dynamic_cast(this->m_selectedNode->GetData()); + m_Controls.T2_SeriesLabel->setText((this->m_selectedNode->GetName()).c_str()); + nodes.pop_front(); + } + } + + + m_Controls.btnConvertToConcentration->setEnabled(m_selectedImage.IsNotNull() && CheckSettings()); + + + +} + + + +ConcentrationCurveConverterView::ConcentrationCurveConverterView() +{ +} diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/src/internal/ConcentrationCurveConverterView.h b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/src/internal/ConcentrationCurveConverterView.h new file mode 100644 index 0000000000..0574104ef8 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/src/internal/ConcentrationCurveConverterView.h @@ -0,0 +1,103 @@ +/*=================================================================== + +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 ConcentrationCurveConverterView_h +#define ConcentrationCurveConverterView_h + +#include + +#include +#include "ui_ConcentrationCurveConverterViewControls.h" + +#include + + +/*! + * @brief Test Plugin for SUV calculations of PET images + */ +class ConcentrationCurveConverterView : public QmitkAbstractView +{ + Q_OBJECT + +public: +// typedef itk::Image ImageType; + typedef itk::Image ConvertedImageType; + + + /*! @brief The view's unique ID - required by MITK */ + static const std::string VIEW_ID; + + ConcentrationCurveConverterView(); + +protected slots: + + /*! + * @brief Is triggered of the update button is clicked and the selected node should get the (new) iso level set. + */ + void OnConvertToConcentrationButtonClicked(); + void OnSettingChanged(); + bool CheckSettings() const; + + + +protected: + + // Overridden base class functions + + /*! + * @brief Sets up the UI controls and connects the slots and signals. Gets + * called by the framework to create the GUI at the right time. + * @param[in,out] parent The parent QWidget, as this class itself is not a QWidget + * subclass. + */ + void CreateQtPartControl(QWidget* parent); + + /*! + * @brief Sets the focus to the plot curve button. Gets called by the framework to set the + * focus on the right widget. + */ + void SetFocus(); + + /*! Helper method that adds an concentration image as child node to the current m_selectedNode and returns this new child node.*/ + mitk::DataNode::Pointer AddConcentrationImage(mitk::Image* image, std::string nodeName) const; + + + /*! \brief called by QmitkFunctionality when DataManager's selection has changed + */ + virtual void OnSelectionChanged( berry::IWorkbenchPart::Pointer source, + const QList& nodes); + + // Variables + + /*! @brief The view's UI controls */ + Ui::ConcentrationCurveConverterViewControls m_Controls; + + mitk::DataNode::Pointer m_selectedNode; + mitk::Image::Pointer m_selectedImage; + mitk::DataNode::Pointer m_selectedBaselineNode; + mitk::Image::Pointer m_selectedBaselineImage; + +private: + + /**Converts the selected image to a concentration image based on the given gui settings.*/ + mitk::Image::Pointer Convert4DConcentrationImage(mitk::Image::Pointer inputImage); + mitk::Image::Pointer Convert3DConcentrationImage(mitk::Image::Pointer inputImage, mitk::Image::Pointer baselineImage); + + mitk::Image::Pointer ConvertT2ConcentrationImgage(mitk::Image::Pointer inputImage); + +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/src/internal/ConcentrationCurveConverterViewControls.ui b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/src/internal/ConcentrationCurveConverterViewControls.ui new file mode 100644 index 0000000000..15dec472cf --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/src/internal/ConcentrationCurveConverterViewControls.ui @@ -0,0 +1,354 @@ + + + ConcentrationCurveConverterViewControls + + + + 0 + 0 + 475 + 671 + + + + + 0 + 0 + + + + QmitkTemplate + + + + + + 10 + + + + + T1 weighted MRI + + + + + + + T2 weighted MRI + + + + + + + + + T1 weighted images + + + + + + 10 + + + 10 + + + + + 10 + + + + + 3D Image + + + + + + + 4D Image + + + + + + + + + 4D Image + + + + + + Selected Time Series: + + + + + + + No series selected + + + + + + + + + + 3D Image + + + + + + Selected 3D Image + + + + + + + No Image selected + + + + + + + Baseline Image (without CA): + + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + No Baseline Image selected + + + + + + + + + + + + Configuration + + + + + + 10 + + + 10 + + + + + Relative Signal Enhancement + + + + + + + Absolute Signal Enhancement + + + + + + + Conversion Faktor k: + + + + + + + + + + + + 10 + + + 10 + + + + + Turbo FLASH Sequence + + + + + + + 20 + + + + + Turbo FLASH Parameters: + + + + + + + + + Relaxivity + + + + + + + + + + + + + Recovery Time + + + + + + + Relaxation Time + + + + + + + true + + + + 0 + 0 + + + + [s] + + + + + + + [] + + + + + + + [s] + + + + + + + + + + + + + + + + + + + + T2 weighted images + + + + + + + + + + + + Conversion Factor k + + + + + + + Echo Time TE + + + + + + + Selected Time Series: + + + + + + + No Series Selected + + + + + + + + + + Convert To Concentration + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/src/internal/org_mitk_ConcentrationCurveConverterView_Activator.cpp b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/src/internal/org_mitk_ConcentrationCurveConverterView_Activator.cpp new file mode 100644 index 0000000000..58fabbeab1 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/src/internal/org_mitk_ConcentrationCurveConverterView_Activator.cpp @@ -0,0 +1,29 @@ +/*=================================================================== + +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 "org_mitk_ConcentrationCurveConverterView_Activator.h" + +#include "ConcentrationCurveConverterView.h" + + void org_mitk_ConcentrationCurveConverterView_Activator::start(ctkPluginContext* context) + { + BERRY_REGISTER_EXTENSION_CLASS(ConcentrationCurveConverterView, context); + } + + void org_mitk_ConcentrationCurveConverterView_Activator::stop(ctkPluginContext* context) + { + Q_UNUSED(context); + } \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/src/internal/org_mitk_ConcentrationCurveConverterView_Activator.h b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/src/internal/org_mitk_ConcentrationCurveConverterView_Activator.h new file mode 100644 index 0000000000..85b05bf091 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.concentration.mri/src/internal/org_mitk_ConcentrationCurveConverterView_Activator.h @@ -0,0 +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. + +===================================================================*/ + +#ifndef org_mitk_ConcentrationCurveConverterView_Activator_h +#define org_mitk_ConcentrationCurveConverterView_Activator_h + +#include + + + class org_mitk_ConcentrationCurveConverterView_Activator : public QObject, public ctkPluginActivator + { + Q_OBJECT + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_pharmacokinetics_concentration_mri") + Q_INTERFACES(ctkPluginActivator) + public: + + /*! + * @brief Registers the plug-in. Gets called by the framework when the plug-in is + * first loaded. + * @param context The corresponding CTK plug-in context in which the plug-in is loaded. + */ + void start(ctkPluginContext* context); + + /*! + * @brief Deregisters the plug-in. Gets called by the framework when the plug-in + * is unloaded. + * @param context The corresponding CTK plug-in context in which the plug-in was loaded. + */ + void stop(ctkPluginContext* context); + }; + +#endif diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/CMakeLists.txt b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/CMakeLists.txt new file mode 100644 index 0000000000..25ffc25f99 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/CMakeLists.txt @@ -0,0 +1,8 @@ +project(org_mitk_gui_qt_pharmacokinetics_curvedescriptor) + +mitk_create_plugin( + EXPORT_DIRECTIVE CURVEDESCRIPTORS_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS + PRIVATE MitkQtWidgetsExt MitkPharmacokinetics MitkFitMIDataUI MitkPharmacokineticsUI +) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..494b785680 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/documentation/UserManual/Manual.dox @@ -0,0 +1,4 @@ +/** +\page org_mitk_gui_qt_pharmacokinetics_curvedescriptor The Perfusion Curve Description Parameters View + +*/ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..2175fe0a9c --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk_gui_qt_pharmacokinetics_curvedescriptor org.mitk.gui.qt.pharmacokinetics.curvedescriptor + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup org_mitk_gui_qt_pharmacokinetics_curvedescriptor_internal Internal + \ingroup org_mitk_gui_qt_pharmacokinetics_curvedescriptor + + \brief This subcategory includes the internal classes of the org.mitk.gui.qt.pharmacokinetics.curvedescriptor plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/files.cmake b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/files.cmake new file mode 100644 index 0000000000..4d3cf1bb68 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/files.cmake @@ -0,0 +1,42 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_PerfusionCurveDescriptionParameterView_Activator.cpp + PerfusionCurveDescriptionParameterView.cpp +) + +set(UI_FILES + src/internal/PerfusionCurveDescriptionParameterViewControls.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_PerfusionCurveDescriptionParameterView_Activator.h + src/internal/PerfusionCurveDescriptionParameterView.h +) + +# list of resource files which can be used by the plug-in +# system without loading the plug-ins shared library, +# for example the icon used in the menu and tabs for the +# plug-in views in the workbench +set(CACHED_RESOURCE_FILES + resources/icon.png + plugin.xml +) + +# list of Qt .qrc files which contain additional resources +# specific to this plugin +set(QRC_FILES + +) + +set(CPP_FILES ) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/manifest_headers.cmake new file mode 100644 index 0000000000..3323290acb --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "Perfusion Curve Description Parameter Plugin") +set(Plugin-Version "1.0") +set(Plugin-Vendor "DKFZ, Software Development For Integrated Diagnostics and Therapy") +set(Plugin-ContactAddress "c.debus@dkfz.de") +set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/plugin.xml b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/plugin.xml new file mode 100644 index 0000000000..42dadcd43e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/resources/icon.png b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/resources/icon.png new file mode 100644 index 0000000000..08673d42f2 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/resources/icon.png differ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/resources/icon_PerfusionCurveDescriptors.png b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/resources/icon_PerfusionCurveDescriptors.png new file mode 100644 index 0000000000..fb87d9e608 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/resources/icon_PerfusionCurveDescriptors.png differ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/resources/petsuv.png b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/resources/petsuv.png new file mode 100644 index 0000000000..2dc586dfd4 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/resources/petsuv.png differ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/src/internal/PerfusionCurveDescriptionParameterView.cpp b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/src/internal/PerfusionCurveDescriptionParameterView.cpp new file mode 100644 index 0000000000..06be4190d6 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/src/internal/PerfusionCurveDescriptionParameterView.cpp @@ -0,0 +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. + +===================================================================*/ + +#include +#include + +#include "mitkWorkbenchUtil.h" + +#include "PerfusionCurveDescriptionParameterView.h" +#include "QmitkDescriptionParameterBackgroundJob.h" +#include "mitkAreaUnderTheCurveDescriptionParameter.h" +#include "mitkAreaUnderFirstMomentDescriptionParameter.h" +#include "mitkMeanResidenceTimeDescriptionParameter.h" +#include "mitkTimeToPeakCurveDescriptionParameter.h" +#include "mitkMaximumCurveDescriptionParameter.h" +#include "mitkPixelBasedDescriptionParameterImageGenerator.h" +#include "mitkCurveParameterFunctor.h" +#include "mitkExtractTimeGrid.h" + +#include + +const std::string PerfusionCurveDescriptionParameterView::VIEW_ID = + "org.mitk.gui.qt.pharmacokinetics.curvedescriptor"; + +void PerfusionCurveDescriptionParameterView::SetFocus() +{ + m_Controls.btnCalculateParameters->setFocus(); +} + +void PerfusionCurveDescriptionParameterView::CreateQtPartControl(QWidget* parent) +{ + m_Controls.setupUi(parent); + m_Controls.btnCalculateParameters->setEnabled(false); + + + + connect(m_Controls.btnCalculateParameters, SIGNAL(clicked()), this, + SLOT(OnCalculateParametersButtonClicked())); + + + InitParameterList(); +} + + +void PerfusionCurveDescriptionParameterView::OnSelectionChanged( + berry::IWorkbenchPart::Pointer /*source*/, const QList& /*nodes*/) +{ + + m_Controls.btnCalculateParameters->setEnabled(false); + + + + QList dataNodes = this->GetDataManagerSelection(); + + if (dataNodes.empty()) + { + m_selectedNode = NULL; + m_selectedImage = NULL; + } + else + { + m_selectedNode = dataNodes[0]; + m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + } + + if (m_selectedImage.IsNotNull()) + { + if (m_selectedImage->GetTimeGeometry()->CountTimeSteps() > 1) + { + m_Controls.btnCalculateParameters->setEnabled(true); + } + else + { + this->OnJobStatusChanged("Cannot compute parameters. Selected image must have multiple time steps."); + } + } + else if (m_selectedNode.IsNotNull()) + { + this->OnJobStatusChanged("Cannot compute parameters. Selected node is not an image."); + } + else + { + this->OnJobStatusChanged("Cannot compute parameters. No node selected."); + } +} + +PerfusionCurveDescriptionParameterView::PerfusionCurveDescriptionParameterView() +{ + m_selectedNode = NULL; + m_selectedImage = NULL; + m_selectedMask = NULL; +} + +void PerfusionCurveDescriptionParameterView::InitParameterList() +{ + m_ParameterMap.clear(); + + mitk::CurveDescriptionParameterBase::Pointer parameterFunction = + mitk::AreaUnderTheCurveDescriptionParameter::New().GetPointer(); + m_ParameterMap.insert(std::make_pair(ParameterNameType("AUC"), parameterFunction)); + parameterFunction = mitk::AreaUnderFirstMomentDescriptionParameter::New().GetPointer(); + m_ParameterMap.insert(std::make_pair(ParameterNameType("AUMC"), parameterFunction)); + parameterFunction = mitk::MeanResidenceTimeDescriptionParameter::New().GetPointer(); + m_ParameterMap.insert(std::make_pair(ParameterNameType("MRT"), parameterFunction)); + parameterFunction = mitk::MaximumCurveDescriptionParameter::New().GetPointer(); + m_ParameterMap.insert(std::make_pair(ParameterNameType("Maximum"), parameterFunction)); + parameterFunction = mitk::TimeToPeakCurveDescriptionParameter::New().GetPointer(); + m_ParameterMap.insert(std::make_pair(ParameterNameType("TimeToPeak"), parameterFunction)); + + for (ParameterMapType::const_iterator pos = m_ParameterMap.begin(); pos != m_ParameterMap.end(); + ++pos) + { + QListWidgetItem* item = new QListWidgetItem(QString::fromStdString(pos->first), + this->m_Controls.parameterlist); + item->setFlags(item->flags() | Qt::ItemIsUserCheckable); + item->setCheckState(Qt::Unchecked); + } +}; + +void PerfusionCurveDescriptionParameterView::ConfigureFunctor(mitk::CurveParameterFunctor* functor) +const +{ + functor->SetGrid(mitk::ExtractTimeGrid(m_selectedImage)); + + for (int pos = 0; pos < this->m_Controls.parameterlist->count(); ++pos) + { + QListWidgetItem* item = this->m_Controls.parameterlist->item(pos); + mitk::CurveDescriptionParameterBase::Pointer parameterFunction = m_ParameterMap.at( + item->text().toStdString()); + + if (item->checkState() == Qt::Checked) + { + functor->RegisterDescriptionParameter(item->text().toStdString(), parameterFunction); + } + } +} + +void PerfusionCurveDescriptionParameterView::OnCalculateParametersButtonClicked() +{ + mitk::PixelBasedDescriptionParameterImageGenerator::Pointer generator = + mitk::PixelBasedDescriptionParameterImageGenerator::New(); + mitk::CurveParameterFunctor::Pointer functor = mitk::CurveParameterFunctor::New(); + this->ConfigureFunctor(functor); + + + + generator->SetFunctor(functor); + generator->SetDynamicImage(m_selectedImage); + generator->SetMask(m_selectedMask); + + + ///////////////////////// + //create job and put it into the thread pool + DescriptionParameterBackgroundJob* pJob = new DescriptionParameterBackgroundJob(generator, + this->m_selectedNode); + pJob->setAutoDelete(true); + + connect(pJob, SIGNAL(Error(QString)), this, SLOT(OnJobError(QString))); + connect(pJob, SIGNAL(Finished()), this, SLOT(OnJobFinished())); + connect(pJob, SIGNAL(ResultsAreAvailable(mitk::modelFit::ModelFitResultNodeVectorType, + const DescriptionParameterBackgroundJob*)), this, + SLOT(OnJobResultsAreAvailable(mitk::modelFit::ModelFitResultNodeVectorType, + const DescriptionParameterBackgroundJob*)), Qt::BlockingQueuedConnection); + + connect(pJob, SIGNAL(JobProgress(double)), this, SLOT(OnJobProgress(double))); + connect(pJob, SIGNAL(JobStatusChanged(QString)), this, SLOT(OnJobStatusChanged(QString))); + + QThreadPool* threadPool = QThreadPool::globalInstance(); + threadPool->start(pJob); +} + +void PerfusionCurveDescriptionParameterView::OnJobFinished() +{ + this->m_Controls.infoBox->append(QString("Fitting finished")); +}; + +void PerfusionCurveDescriptionParameterView::OnJobError(QString err) +{ + MITK_ERROR << err.toStdString().c_str(); + m_Controls.infoBox->append(QString("") + err + QString("")); +}; + +void PerfusionCurveDescriptionParameterView::OnJobResultsAreAvailable( + mitk::modelFit::ModelFitResultNodeVectorType results, const DescriptionParameterBackgroundJob* pJob) +{ + for (auto image : results) + { + this->GetDataStorage()->Add(image, pJob->GetParentNode()); + } +}; + +void PerfusionCurveDescriptionParameterView::OnJobProgress(double progress) +{ + this->m_Controls.progressBar->setValue(100 * progress); + QString report = QString("Progress. ") + QString::number(progress); + this->m_Controls.infoBox->append(report); +}; + +void PerfusionCurveDescriptionParameterView::OnJobStatusChanged(QString info) +{ + this->m_Controls.infoBox->append(info); + MITK_INFO << info.toStdString().c_str(); +} + diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/src/internal/PerfusionCurveDescriptionParameterView.h b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/src/internal/PerfusionCurveDescriptionParameterView.h new file mode 100644 index 0000000000..b7ef3c55b0 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/src/internal/PerfusionCurveDescriptionParameterView.h @@ -0,0 +1,110 @@ +/*=================================================================== + +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 PerfusionCurveDescriptionParameterView_h +#define PerfusionCurveDescriptionParameterView_h + +#include + +#include +#include "ui_PerfusionCurveDescriptionParameterViewControls.h" +#include "mitkCurveDescriptionParameterBase.h" +#include + +#include + +namespace mitk +{ + class CurveParameterFunctor; +} + +/*! + * @brief Test Plugin for SUV calculations of PET images + */ +class PerfusionCurveDescriptionParameterView : public QmitkAbstractView +{ + Q_OBJECT + +public: + + typedef mitk::CurveDescriptionParameterBase::CurveDescriptionParameterNameType ParameterNameType; + + /*! @brief The view's unique ID - required by MITK */ + static const std::string VIEW_ID; + + PerfusionCurveDescriptionParameterView(); + +protected slots: + + void InitParameterList(); + + void OnJobFinished(); + void OnJobError(QString err); + void OnJobResultsAreAvailable(mitk::modelFit::ModelFitResultNodeVectorType results, + const DescriptionParameterBackgroundJob* pJob); + void OnJobProgress(double progress); + void OnJobStatusChanged(QString info); + + /*! + * @brief Is triggered of the update button is clicked and the selected node should get the (new) iso level set. + */ + void OnCalculateParametersButtonClicked(); + +protected: + + // Overridden base class functions + + /*! + * @brief Sets up the UI controls and connects the slots and signals. Gets + * called by the framework to create the GUI at the right time. + * @param[in,out] parent The parent QWidget, as this class itself is not a QWidget + * subclass. + */ + void CreateQtPartControl(QWidget* parent); + + /*! + * @brief Sets the focus to the plot curve button. Gets called by the framework to set the + * focus on the right widget. + */ + void SetFocus(); + + /** Configures the passed functor according to the selected image and parameters*/ + void ConfigureFunctor(mitk::CurveParameterFunctor* functor) const; + + /*! \brief called by QmitkFunctionality when DataManager's selection has changed + */ + virtual void OnSelectionChanged( berry::IWorkbenchPart::Pointer source, + const QList& nodes) override; + + // Variables + + /*! @brief The view's UI controls */ + Ui::PerfusionCurveDescriptionParameterViewControls m_Controls; + mitk::DataNode::Pointer m_selectedNode; + +private: + + + + typedef std::map ParameterMapType; + + ParameterMapType m_ParameterMap; + + mitk::Image::Pointer m_selectedImage; + mitk::Image::Pointer m_selectedMask; +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/src/internal/PerfusionCurveDescriptionParameterViewControls.ui b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/src/internal/PerfusionCurveDescriptionParameterViewControls.ui new file mode 100644 index 0000000000..90af6e4802 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/src/internal/PerfusionCurveDescriptionParameterViewControls.ui @@ -0,0 +1,85 @@ + + + PerfusionCurveDescriptionParameterViewControls + + + + 0 + 0 + 390 + 671 + + + + + 0 + 0 + + + + QmitkTemplate + + + + + + + + Selected Time Series: + + + + + + + No Series Selected! + + + + + + + + + QAbstractItemView::NoEditTriggers + + + false + + + true + + + + + + + Calculate Parameters + + + + + + + Status: + + + + + + 0 + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/src/internal/org_mitk_PerfusionCurveDescriptionParameterView_Activator.cpp b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/src/internal/org_mitk_PerfusionCurveDescriptionParameterView_Activator.cpp new file mode 100644 index 0000000000..5a630a529a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/src/internal/org_mitk_PerfusionCurveDescriptionParameterView_Activator.cpp @@ -0,0 +1,32 @@ +/*=================================================================== + +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 "org_mitk_PerfusionCurveDescriptionParameterView_Activator.h" + +#include "PerfusionCurveDescriptionParameterView.h" + +namespace mitk +{ + void org_mitk_PerfusionCurveDescriptionParameterView_Activator::start(ctkPluginContext* context) + { + BERRY_REGISTER_EXTENSION_CLASS(PerfusionCurveDescriptionParameterView, context); + } + + void org_mitk_PerfusionCurveDescriptionParameterView_Activator::stop(ctkPluginContext* context) + { + Q_UNUSED(context); + } +} diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/src/internal/org_mitk_PerfusionCurveDescriptionParameterView_Activator.h b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/src/internal/org_mitk_PerfusionCurveDescriptionParameterView_Activator.h new file mode 100644 index 0000000000..7f9c25b53c --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.curvedescriptor/src/internal/org_mitk_PerfusionCurveDescriptionParameterView_Activator.h @@ -0,0 +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 org_mitk_PerfusionCurveDescriptionParameterView_Activator_h +#define org_mitk_PerfusionCurveDescriptionParameterView_Activator_h + +#include + +namespace mitk +{ + /*! + * @brief Activator class for the @ref CurveDescriptorParameterView. + * @details This small helper class is necessary for the integration as a CTK plug-in. + * @author Sascha Diatschuk + */ + class org_mitk_PerfusionCurveDescriptionParameterView_Activator : public QObject, public ctkPluginActivator + { + Q_OBJECT + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_pharmacokinetics_curvedescriptor") + Q_INTERFACES(ctkPluginActivator) + + public: + + /*! + * @brief Registers the plug-in. Gets called by the framework when the plug-in is + * first loaded. + * @param context The corresponding CTK plug-in context in which the plug-in is loaded. + */ + void start(ctkPluginContext* context); + + /*! + * @brief Deregisters the plug-in. Gets called by the framework when the plug-in + * is unloaded. + * @param context The corresponding CTK plug-in context in which the plug-in was loaded. + */ + void stop(ctkPluginContext* context); + }; +} + +#endif diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/CMakeLists.txt b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/CMakeLists.txt new file mode 100644 index 0000000000..dbe09d95dc --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/CMakeLists.txt @@ -0,0 +1,9 @@ +project(org_mitk_gui_qt_pharmacokinetics_mri) + +mitk_create_plugin( + EXPORT_DIRECTIVE MRPERFUSION_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgetsExt MitkPharmacokinetics MitkFitMIDataUI + PACKAGE_DEPENDS + PRIVATE Boost +) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..b5529a4a2e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/documentation/UserManual/Manual.dox @@ -0,0 +1,8 @@ +/** +\page org_mitk_gui_qt_pharmacokinetics_mri The DCE MR Perfusion Datafit View + +\section org_mitk_gui_qt_pharmacokinetics_mri_Overview Overview + +This plug-in offers the possibilities to fit several pharmacokinetic modells onto DCE MR perfusion images. + +*/ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..3d5cc3aea5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk_gui_qt_pharmacokinetics_mri org.mitk.gui.qt.pharmacokinetics.mri + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup org_mitk_gui_qt_pharmacokinetics_mri_internal Internal + \ingroup org_mitk_gui_qt_pharmacokinetics_mri + + \brief This subcategory includes the internal classes of the org.mitk.gui.qt.pharmacokinetics.mri plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/files.cmake b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/files.cmake new file mode 100644 index 0000000000..d3b5a6f4ce --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/files.cmake @@ -0,0 +1,42 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_MRPerfusionView_Activator.cpp + MRPerfusionView.cpp +) + +set(UI_FILES + src/internal/MRPerfusionViewControls.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_MRPerfusionView_Activator.h + src/internal/MRPerfusionView.h +) + +# list of resource files which can be used by the plug-in +# system without loading the plug-ins shared library, +# for example the icon used in the menu and tabs for the +# plug-in views in the workbench +set(CACHED_RESOURCE_FILES + resources/DCEMRI.png + plugin.xml +) + +# list of Qt .qrc files which contain additional resources +# specific to this plugin +set(QRC_FILES + +) + +set(CPP_FILES ) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/manifest_headers.cmake new file mode 100644 index 0000000000..e3fff30e06 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "DCE MR Perfusion Datafit Plugin") +set(Plugin-Version "1.0") +set(Plugin-Vendor "DKFZ, Software Development For Integrated Diagnostics and Therapy") +set(Plugin-ContactAddress "c.debus@dkfz.de") +set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/plugin.xml b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/plugin.xml new file mode 100644 index 0000000000..672a061a8a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/resources/DCEMRI.png b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/resources/DCEMRI.png new file mode 100644 index 0000000000..3a91919a13 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/resources/DCEMRI.png differ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/MRPerfusionView.cpp b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/MRPerfusionView.cpp new file mode 100644 index 0000000000..dd56a085c6 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/MRPerfusionView.cpp @@ -0,0 +1,1396 @@ +/*=================================================================== + +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 "MRPerfusionView.h" + +#include "boost/tokenizer.hpp" +#include "boost/math/constants/constants.hpp" +#include + +#include "mitkWorkbenchUtil.h" + +#include "mitkAterialInputFunctionGenerator.h" +#include "mitkConcentrationCurveGenerator.h" + +#include +#include +#include +#include "mitkThreeStepLinearModelFactory.h" +#include "mitkThreeStepLinearModelParameterizer.h" +#include +#include +#include +#include +#include "mitkTwoCompartmentExchangeModelFactory.h" +#include "mitkTwoCompartmentExchangeModelParameterizer.h" +#include "mitkNumericTwoCompartmentExchangeModelFactory.h" +#include "mitkNumericTwoCompartmentExchangeModelParameterizer.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +// Includes for image casting between ITK and MITK +#include +#include "mitkImageCast.h" +#include "mitkITKImageImport.h" +#include +#include + + +const std::string MRPerfusionView::VIEW_ID = "org.mitk.gui.qt.pharmacokinetics.mri"; + +inline double convertToDouble(const std::string& data) +{ + std::istringstream stepStream(data); + stepStream.imbue(std::locale("C")); + double value = 0.0; + + if (!(stepStream >> value) || !(stepStream.eof())) + { + mitkThrow() << "Cannot convert string to double. String: " << data; + } + return value; +} + +void MRPerfusionView::SetFocus() +{ + m_Controls.btnModelling->setFocus(); +} + +void MRPerfusionView::CreateQtPartControl(QWidget* parent) +{ + m_Controls.setupUi(parent); + + m_Controls.btnModelling->setEnabled(false); + m_Controls.errorMessageLabel->hide(); + + this->InitModelComboBox(); + + connect(m_Controls.btnModelling, SIGNAL(clicked()), this, SLOT(OnModellingButtonClicked())); + + connect(m_Controls.comboModel, SIGNAL(currentIndexChanged(int)), this, SLOT(OnModellSet(int))); + connect(m_Controls.radioPixelBased, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); + + //AIF setting + m_Controls.groupAIF->hide(); + m_Controls.btnAIFFile->setEnabled(false); + m_Controls.btnAIFFile->setEnabled(false); + m_Controls.radioAIFImage->setChecked(true); + m_Controls.comboAIFMask->SetDataStorage(this->GetDataStorage()); + m_Controls.comboAIFMask->SetPredicate(m_IsMaskPredicate); + m_Controls.comboAIFMask->setVisible(true); + m_Controls.comboAIFMask->setEnabled(true); + m_Controls.comboAIFImage->SetDataStorage(this->GetDataStorage()); + m_Controls.comboAIFImage->SetPredicate(m_IsNoMaskImagePredicate); + m_Controls.comboAIFImage->setEnabled(false); + m_Controls.checkDedicatedAIFImage->setEnabled(true); + m_Controls.HCLSpinBox->setValue(mitk::AterialInputFunctionGenerator::DEFAULT_HEMATOCRIT_LEVEL); + + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.comboAIFMask, SLOT(setVisible(bool))); + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.labelAIFMask, SLOT(setVisible(bool))); + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.checkDedicatedAIFImage, SLOT(setVisible(bool))); + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.comboAIFMask, SLOT(setEnabled(bool))); + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.checkDedicatedAIFImage, SLOT(setEnabled(bool))); + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.checkDedicatedAIFImage, SLOT(setVisible(bool))); + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.comboAIFImage, SLOT(setVisible(bool))); + connect(m_Controls.checkDedicatedAIFImage, SIGNAL(toggled(bool)), m_Controls.comboAIFImage, SLOT(setEnabled(bool))); + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); + connect(m_Controls.radioAIFFile, SIGNAL(toggled(bool)), m_Controls.btnAIFFile, SLOT(setEnabled(bool))); + connect(m_Controls.radioAIFFile, SIGNAL(toggled(bool)), m_Controls.aifFilePath, SLOT(setEnabled(bool))); + connect(m_Controls.radioAIFFile, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); + + connect(m_Controls.btnAIFFile, SIGNAL(clicked()), this, SLOT(LoadAIFfromFile())); + + //Brix setting + m_Controls.groupDescBrix->hide(); + connect(m_Controls.injectiontime, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); + + //Num2CX setting + m_Controls.groupNum2CXM->hide(); + connect(m_Controls.odeStepSize, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); + + //Model fit configuration + m_Controls.groupBox_FitConfiguration->hide(); + + m_Controls.checkBox_Constraints->setEnabled(false); + m_Controls.constraintManager->setEnabled(false); + m_Controls.initialValuesManager->setEnabled(false); + m_Controls.initialValuesManager->setDataStorage(this->GetDataStorage()); + + connect(m_Controls.radioButton_StartParameters, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); + connect(m_Controls.checkBox_Constraints, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); + connect(m_Controls.initialValuesManager, SIGNAL(initialValuesChanged(void)), this, SLOT(UpdateGUIControls())); + + + connect(m_Controls.radioButton_StartParameters, SIGNAL(toggled(bool)), m_Controls.initialValuesManager, SLOT(setEnabled(bool))); + connect(m_Controls.checkBox_Constraints, SIGNAL(toggled(bool)), m_Controls.constraintManager, SLOT(setEnabled(bool))); + connect(m_Controls.checkBox_Constraints, SIGNAL(toggled(bool)), m_Controls.constraintManager, SLOT(setVisible(bool))); + + //Concentration + m_Controls.groupConcentration->hide(); + m_Controls.groupBoxTurboFlash->hide(); + m_Controls.radioButtonNoConversion->setChecked(true); + m_Controls.factorSpinBox->setEnabled(false); + m_Controls.groupBox_viaT1Map->hide(); + + connect(m_Controls.radioButtonTurboFlash, SIGNAL(toggled(bool)), m_Controls.groupBoxTurboFlash, SLOT(setVisible(bool))); + connect(m_Controls.radioButtonTurboFlash, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); + connect(m_Controls.relaxationtime, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); + connect(m_Controls.recoverytime, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); + connect(m_Controls.relaxivity, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); + + connect(m_Controls.radioButton_absoluteEnhancement, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); + connect(m_Controls.radioButton_relativeEnchancement, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); + connect(m_Controls.radioButton_absoluteEnhancement, SIGNAL(toggled(bool)), m_Controls.factorSpinBox, SLOT(setEnabled(bool))); + connect(m_Controls.radioButton_relativeEnchancement, SIGNAL(toggled(bool)), m_Controls.factorSpinBox, SLOT(setEnabled(bool))); + connect(m_Controls.factorSpinBox, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); + + connect(m_Controls.radioButtonUsingT1, SIGNAL(toggled(bool)), m_Controls.groupBox_viaT1Map, SLOT(setVisible(bool))); + connect(m_Controls.radioButtonUsingT1, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); + connect(m_Controls.FlipangleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); + connect(m_Controls.RelaxivitySpinBox, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); + connect(m_Controls.TRSpinBox, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); + m_Controls.ComboT1Map->SetDataStorage(this->GetDataStorage()); + m_Controls.ComboT1Map->SetPredicate(m_IsNoMaskImagePredicate); + m_Controls.ComboT1Map->setEnabled(false); + connect(m_Controls.radioButtonUsingT1, SIGNAL(toggled(bool)), m_Controls.ComboT1Map, SLOT(setEnabled(bool))); + + UpdateGUIControls(); +} + +bool MRPerfusionView::IsTurboFlashSequenceFlag() const +{ + return this->m_Controls.radioButtonTurboFlash->isChecked(); +}; + + + +void MRPerfusionView::UpdateGUIControls() +{ + m_Controls.lineFitName->setPlaceholderText(QString::fromStdString(this->GetDefaultFitName())); + m_Controls.lineFitName->setEnabled(!m_FittingInProgress); + + m_Controls.checkBox_Constraints->setEnabled(m_modelConstraints.IsNotNull()); + + bool isDescBrixFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool isToftsFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL || + dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool is2CXMFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL || + dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + + bool isNum2CXMFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + + m_Controls.groupAIF->setVisible(isToftsFactory || is2CXMFactory); + m_Controls.groupDescBrix->setVisible(isDescBrixFactory); + m_Controls.groupNum2CXM->setVisible(isNum2CXMFactory); + m_Controls.groupConcentration->setVisible(isToftsFactory || is2CXMFactory); + + m_Controls.groupBox_FitConfiguration->setVisible(m_selectedModelFactory); + + m_Controls.groupBox->setEnabled(!m_FittingInProgress); + m_Controls.comboModel->setEnabled(!m_FittingInProgress); + m_Controls.groupAIF->setEnabled(!m_FittingInProgress); + m_Controls.groupDescBrix->setEnabled(!m_FittingInProgress); + m_Controls.groupNum2CXM->setEnabled(!m_FittingInProgress); + m_Controls.groupConcentration->setEnabled(!m_FittingInProgress); + m_Controls.groupBox_FitConfiguration->setEnabled(!m_FittingInProgress); + + m_Controls.radioROIbased->setEnabled(m_selectedMask.IsNotNull()); + + m_Controls.btnModelling->setEnabled(m_selectedImage.IsNotNull() + && m_selectedModelFactory.IsNotNull() && !m_FittingInProgress && CheckModelSettings()); +} + +void MRPerfusionView::OnModellSet(int index) +{ + m_selectedModelFactory = NULL; + + if (index > 0) + { + if (static_cast(index) <= m_FactoryStack.size() ) + { + m_selectedModelFactory = m_FactoryStack[index - 1]; + } + else + { + MITK_WARN << "Invalid model index. Index outside of the factory stack. Factory stack size: "<< m_FactoryStack.size() << "; invalid index: "<< index; + } + } + + if (m_selectedModelFactory) + { + this->m_modelConstraints = dynamic_cast + (m_selectedModelFactory->CreateDefaultConstraints().GetPointer()); + + m_Controls.initialValuesManager->setInitialValues(m_selectedModelFactory->GetParameterNames(), + m_selectedModelFactory->GetDefaultInitialParameterization()); + + if (this->m_modelConstraints.IsNull()) + { + this->m_modelConstraints = mitk::SimpleBarrierConstraintChecker::New(); + } + + m_Controls.constraintManager->setChecker(this->m_modelConstraints, + this->m_selectedModelFactory->GetParameterNames()); + + } + + UpdateGUIControls(); +} + +std::string MRPerfusionView::GetDefaultFitName() const +{ + std::string defaultName = "undefined model"; + + if (this->m_selectedModelFactory.IsNotNull()) + { + defaultName = this->m_selectedModelFactory->GetClassID(); + } + + if (this->m_Controls.radioPixelBased->isChecked()) + { + defaultName += "_pixel"; + } + else + { + defaultName += "_roi"; + } + + return defaultName; +} + +void MRPerfusionView::OnModellingButtonClicked() +{ + //check if all static parameters set + if (m_selectedModelFactory.IsNotNull() && CheckModelSettings()) + { + mitk::ParameterFitImageGeneratorBase::Pointer generator = NULL; + mitk::modelFit::ModelFitInfo::Pointer fitSession = NULL; + + bool isDescBrixFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool is3LinearFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool isExtToftsFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool isStanToftsFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool is2CXMFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool isNum2CXMFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + + if (isDescBrixFactory) + { + if (this->m_Controls.radioPixelBased->isChecked()) + { + GenerateDescriptiveBrixModel_PixelBased(fitSession, generator); + } + else + { + GenerateDescriptiveBrixModel_ROIBased(fitSession, generator); + } + } + else if (is3LinearFactory) + { + if (this->m_Controls.radioPixelBased->isChecked()) + { + Generate3StepLinearModelFit_PixelBased(fitSession, generator); + } + else + { + Generate3StepLinearModelFit_ROIBased(fitSession, generator); + } + } + else if (isStanToftsFactory) + { + if (this->m_Controls.radioPixelBased->isChecked()) + { + GenerateAIFbasedModelFit_PixelBased(fitSession, generator); + } + else + { + GenerateAIFbasedModelFit_ROIBased(fitSession, generator); + } + } + else if (isExtToftsFactory) + { + if (this->m_Controls.radioPixelBased->isChecked()) + { + GenerateAIFbasedModelFit_PixelBased(fitSession, generator); + } + else + { + GenerateAIFbasedModelFit_ROIBased(fitSession, generator); + } + } + else if (is2CXMFactory) + { + if (this->m_Controls.radioPixelBased->isChecked()) + { + GenerateAIFbasedModelFit_PixelBased(fitSession, generator); + } + else + { + GenerateAIFbasedModelFit_ROIBased(fitSession, generator); + } + } + else if (isNum2CXMFactory) + { + if (this->m_Controls.radioPixelBased->isChecked()) + { + GenerateAIFbasedModelFit_PixelBased(fitSession, + generator); + } + else + { + GenerateAIFbasedModelFit_ROIBased(fitSession, + generator); + } + } + + //add other models with else if + + if (generator.IsNotNull() && fitSession.IsNotNull()) + { + m_FittingInProgress = true; + UpdateGUIControls(); + DoFit(fitSession, generator); + } + else + { + QMessageBox box; + box.setText("Fitting error!"); + box.setInformativeText("Could not establish fitting job. Error when setting ab generator, model parameterizer or session info."); + box.setStandardButtons(QMessageBox::Ok); + box.setDefaultButton(QMessageBox::Ok); + box.setIcon(QMessageBox::Warning); + box.exec(); + } + + } + else + { + QMessageBox box; + box.setText("Static parameters for model are not set!"); + box.setInformativeText("Some static parameters, that are needed for calculation are not set and equal to zero. Modeling not possible"); + box.setStandardButtons(QMessageBox::Ok); + box.setDefaultButton(QMessageBox::Ok); + box.setIcon(QMessageBox::Warning); + box.exec(); + } +} + + +void MRPerfusionView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, + const QList& selectedNodes) +{ + m_selectedMaskNode = NULL; + m_selectedMask = NULL; + + m_Controls.errorMessageLabel->setText(""); + m_Controls.masklabel->setText("No (valid) mask selected."); + m_Controls.timeserieslabel->setText("No (valid) series selected."); + + QList nodes = selectedNodes; + + if (nodes.size() > 0 && this->m_IsNoMaskImagePredicate->CheckNode(nodes.front())) + { + this->m_selectedNode = nodes.front(); + auto selectedImage = dynamic_cast(this->m_selectedNode->GetData()); + m_Controls.timeserieslabel->setText((this->m_selectedNode->GetName()).c_str()); + + if (selectedImage != this->m_selectedImage) + { + if (selectedImage) + { + this->m_Controls.initialValuesManager->setReferenceImageGeometry(selectedImage->GetGeometry()); + } + else + { + this->m_Controls.initialValuesManager->setReferenceImageGeometry(nullptr); + } + } + this->m_selectedImage = selectedImage; + nodes.pop_front(); + } + else + { + this->m_selectedNode = NULL; + this->m_selectedImage = NULL; + this->m_Controls.initialValuesManager->setReferenceImageGeometry(nullptr); + } + + if (nodes.size() > 0 && this->m_IsMaskPredicate->CheckNode(nodes.front())) + { + this->m_selectedMaskNode = nodes.front(); + this->m_selectedMask = dynamic_cast(this->m_selectedMaskNode->GetData()); + + if (this->m_selectedMask->GetTimeSteps() > 1) + { + MITK_INFO << + "Selected mask has multiple timesteps. Only use first timestep to mask model fit. Mask name: " << + m_selectedMaskNode->GetName(); + mitk::ImageTimeSelector::Pointer maskedImageTimeSelector = mitk::ImageTimeSelector::New(); + maskedImageTimeSelector->SetInput(this->m_selectedMask); + maskedImageTimeSelector->SetTimeNr(0); + maskedImageTimeSelector->UpdateLargestPossibleRegion(); + this->m_selectedMask = maskedImageTimeSelector->GetOutput(); + } + + m_Controls.masklabel->setText((this->m_selectedMaskNode->GetName()).c_str()); + } + + if (m_selectedMask.IsNull()) + { + this->m_Controls.radioPixelBased->setChecked(true); + } + + m_Controls.errorMessageLabel->show(); + + UpdateGUIControls(); +} + +bool MRPerfusionView::CheckModelSettings() const +{ + bool ok = true; + + //check wether any model is set at all. Otherwise exit with false + if (m_selectedModelFactory.IsNotNull()) + { + bool isDescBrixFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool is3LinearFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool isToftsFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL|| + dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool is2CXMFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool isNum2CXMFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + + if (isDescBrixFactory) + { + //if all static parameters for this model are set, exit with true, Otherwise exit with false + ok = m_Controls.injectiontime->value() > 0; + } + else if (is3LinearFactory) + { + if (this->m_Controls.radioButtonTurboFlash->isChecked()) + { + ok = ok && (m_Controls.recoverytime->value() > 0); + ok = ok && (m_Controls.relaxationtime->value() > 0); + ok = ok && (m_Controls.relaxivity->value() > 0); + ok = ok && (m_Controls.AifRecoverytime->value() > 0); + + } + else if (this->m_Controls.radioButton_absoluteEnhancement->isChecked() + || this->m_Controls.radioButton_relativeEnchancement->isChecked()) + { + ok = ok && (m_Controls.factorSpinBox->value() > 0); + } + else if (this->m_Controls.radioButtonUsingT1->isChecked()) + { + ok = ok && (m_Controls.FlipangleSpinBox->value() > 0); + ok = ok && (m_Controls.TRSpinBox->value() > 0); + ok = ok && (m_Controls.RelaxivitySpinBox->value() > 0); + ok = ok && (m_Controls.ComboT1Map->GetSelectedNode().IsNotNull()); + + } + else if (this->m_Controls.radioButtonNoConversion->isChecked()) + { + ok = ok; + } + else + { + ok = false; + } + } + else if (isToftsFactory || is2CXMFactory || isNum2CXMFactory) + { + if (this->m_Controls.radioAIFImage->isChecked()) + { + ok = ok && m_Controls.comboAIFMask->GetSelectedNode().IsNotNull(); + + if (this->m_Controls.checkDedicatedAIFImage->isChecked()) + { + ok = ok && m_Controls.comboAIFImage->GetSelectedNode().IsNotNull(); + } + } + else if (this->m_Controls.radioAIFFile->isChecked()) + { + ok = ok && (this->AIFinputGrid.size() != 0) && (this->AIFinputFunction.size() != 0); + } + else + { + ok = false; + } + + if (this->m_Controls.radioButtonTurboFlash->isChecked()) + { + ok = ok && (m_Controls.recoverytime->value() > 0); + ok = ok && (m_Controls.relaxationtime->value() > 0); + ok = ok && (m_Controls.relaxivity->value() > 0); + ok = ok && (m_Controls.AifRecoverytime->value() > 0); + + } + else if (this->m_Controls.radioButton_absoluteEnhancement->isChecked() + || this->m_Controls.radioButton_relativeEnchancement->isChecked()) + { + ok = ok && (m_Controls.factorSpinBox->value() > 0); + } + else if (this->m_Controls.radioButtonUsingT1->isChecked()) + { + ok = ok && (m_Controls.FlipangleSpinBox->value() > 0); + ok = ok && (m_Controls.TRSpinBox->value() > 0); + ok = ok && (m_Controls.RelaxivitySpinBox->value() > 0); + ok = ok && (m_Controls.ComboT1Map->GetSelectedNode().IsNotNull()); + + } + else if (this->m_Controls.radioButtonNoConversion->isChecked()) + { + ok = ok; + } + else + { + ok = false; + } + + if (isNum2CXMFactory) + { + ok = ok && (this->m_Controls.odeStepSize->value() > 0); + } + + } + //add other models as else if and check wether all needed static parameters are set + else + { + ok = false; + } + + if (this->m_Controls.radioButton_StartParameters->isChecked() && !this->m_Controls.initialValuesManager->hasValidInitialValues()) + { + std::string warning = "Warning. Invalid start parameters. At least one parameter as an invalid image setting as source."; + MITK_ERROR << warning; + m_Controls.infoBox->append(QString("") + QString::fromStdString(warning) + QString("")); + + ok = false; + }; + } + else + { + ok = false; + } + + return ok; +} + +void MRPerfusionView::ConfigureInitialParametersOfParameterizer(mitk::ModelParameterizerBase* + parameterizer) const +{ + if (m_Controls.radioButton_StartParameters->isChecked()) + { + //use user defined initial parameters + mitk::InitialParameterizationDelegateBase::Pointer paramDelegate = m_Controls.initialValuesManager->getInitialParametrizationDelegate(); + parameterizer->SetInitialParameterizationDelegate(paramDelegate); + } +} + +void MRPerfusionView::GenerateDescriptiveBrixModel_PixelBased(mitk::modelFit::ModelFitInfo::Pointer& + modelFitInfo, mitk::ParameterFitImageGeneratorBase::Pointer& generator) +{ + mitk::PixelBasedParameterFitImageGenerator::Pointer fitGenerator = + mitk::PixelBasedParameterFitImageGenerator::New(); + + mitk::DescriptivePharmacokineticBrixModelParameterizer::Pointer modelParameterizer = + mitk::DescriptivePharmacokineticBrixModelParameterizer::New(); + + //Model configuration (static parameters) can be done now + modelParameterizer->SetTau(m_Controls.injectiontime->value()); + + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(this->m_selectedImage); + imageTimeSelector->SetTimeNr(0); + imageTimeSelector->UpdateLargestPossibleRegion(); + + mitk::DescriptivePharmacokineticBrixModelParameterizer::BaseImageType::Pointer baseImage; + mitk::CastToItkImage(imageTimeSelector->GetOutput(), baseImage); + + modelParameterizer->SetBaseImage(baseImage); + this->ConfigureInitialParametersOfParameterizer(modelParameterizer); + + //Specify fitting strategy and criterion parameters + mitk::ModelFitFunctorBase::Pointer fitFunctor = CreateDefaultFitFunctor(modelParameterizer); + + //Parametrize fit generator + fitGenerator->SetModelParameterizer(modelParameterizer); + std::string roiUID = ""; + + if (m_selectedMask.IsNotNull()) + { + fitGenerator->SetMask(m_selectedMask); + roiUID = mitk::EnsureModelFitUID(this->m_selectedMaskNode); + } + + fitGenerator->SetDynamicImage(m_selectedImage); + fitGenerator->SetFitFunctor(fitFunctor); + + generator = fitGenerator.GetPointer(); + + //Create model info + modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, + m_selectedNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_PIXELBASED(), roiUID); +} + +void MRPerfusionView::GenerateDescriptiveBrixModel_ROIBased(mitk::modelFit::ModelFitInfo::Pointer& + modelFitInfo, mitk::ParameterFitImageGeneratorBase::Pointer& generator) +{ + if (m_selectedMask.IsNull()) + { + return; + } + + mitk::ROIBasedParameterFitImageGenerator::Pointer fitGenerator = + mitk::ROIBasedParameterFitImageGenerator::New(); + + mitk::DescriptivePharmacokineticBrixModelValueBasedParameterizer::Pointer modelParameterizer = + mitk::DescriptivePharmacokineticBrixModelValueBasedParameterizer::New(); + + //Compute ROI signal + mitk::MaskedDynamicImageStatisticsGenerator::Pointer signalGenerator = + mitk::MaskedDynamicImageStatisticsGenerator::New(); + signalGenerator->SetMask(m_selectedMask); + signalGenerator->SetDynamicImage(m_selectedImage); + signalGenerator->Generate(); + + mitk::MaskedDynamicImageStatisticsGenerator::ResultType roiSignal = signalGenerator->GetMean(); + + //Model configuration (static parameters) can be done now + modelParameterizer->SetTau(m_Controls.injectiontime->value()); + modelParameterizer->SetBaseValue(roiSignal[0]); + this->ConfigureInitialParametersOfParameterizer(modelParameterizer); + + //Specify fitting strategy and criterion parameters + mitk::ModelFitFunctorBase::Pointer fitFunctor = CreateDefaultFitFunctor(modelParameterizer); + + //Parametrize fit generator + fitGenerator->SetModelParameterizer(modelParameterizer); + fitGenerator->SetMask(m_selectedMask); + fitGenerator->SetFitFunctor(fitFunctor); + fitGenerator->SetSignal(roiSignal); + fitGenerator->SetTimeGrid(mitk::ExtractTimeGrid(m_selectedImage)); + + generator = fitGenerator.GetPointer(); + + std::string roiUID = mitk::EnsureModelFitUID(this->m_selectedMaskNode); + + //Create model info + modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, + m_selectedNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_ROIBASED(), roiUID); + mitk::ScalarListLookupTable::ValueType infoSignal; + + for (mitk::MaskedDynamicImageStatisticsGenerator::ResultType::const_iterator pos = + roiSignal.begin(); pos != roiSignal.end(); ++pos) + { + infoSignal.push_back(*pos); + } + + modelFitInfo->inputData.SetTableValue("ROI", infoSignal); +} + +void MRPerfusionView::Generate3StepLinearModelFit_PixelBased(mitk::modelFit::ModelFitInfo::Pointer& + modelFitInfo, mitk::ParameterFitImageGeneratorBase::Pointer& generator) +{ + mitk::PixelBasedParameterFitImageGenerator::Pointer fitGenerator = + mitk::PixelBasedParameterFitImageGenerator::New(); + + mitk::ThreeStepLinearModelParameterizer::Pointer modelParameterizer = + mitk::ThreeStepLinearModelParameterizer::New(); + + this->ConfigureInitialParametersOfParameterizer(modelParameterizer); + + //Specify fitting strategy and criterion parameters + mitk::ModelFitFunctorBase::Pointer fitFunctor = CreateDefaultFitFunctor(modelParameterizer); + + //Parametrize fit generator + fitGenerator->SetModelParameterizer(modelParameterizer); + std::string roiUID = ""; + + if (m_selectedMask.IsNotNull()) + { + fitGenerator->SetMask(m_selectedMask); + roiUID = mitk::EnsureModelFitUID(this->m_selectedMaskNode); + } + + fitGenerator->SetDynamicImage(m_selectedImage); + fitGenerator->SetFitFunctor(fitFunctor); + + generator = fitGenerator.GetPointer(); + + //Create model info + modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, + m_selectedNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_PIXELBASED(), roiUID); +} + +void MRPerfusionView::Generate3StepLinearModelFit_ROIBased(mitk::modelFit::ModelFitInfo::Pointer& + modelFitInfo, mitk::ParameterFitImageGeneratorBase::Pointer& generator) +{ + if (m_selectedMask.IsNull()) + { + return; + } + + mitk::ROIBasedParameterFitImageGenerator::Pointer fitGenerator = + mitk::ROIBasedParameterFitImageGenerator::New(); + + mitk::ThreeStepLinearModelParameterizer::Pointer modelParameterizer = + mitk::ThreeStepLinearModelParameterizer::New(); + + //Compute ROI signal + mitk::MaskedDynamicImageStatisticsGenerator::Pointer signalGenerator = + mitk::MaskedDynamicImageStatisticsGenerator::New(); + signalGenerator->SetMask(m_selectedMask); + signalGenerator->SetDynamicImage(m_selectedImage); + signalGenerator->Generate(); + + mitk::MaskedDynamicImageStatisticsGenerator::ResultType roiSignal = signalGenerator->GetMean(); + + //Model configuration (static parameters) can be done now + this->ConfigureInitialParametersOfParameterizer(modelParameterizer); + + //Specify fitting strategy and criterion parameters + mitk::ModelFitFunctorBase::Pointer fitFunctor = CreateDefaultFitFunctor(modelParameterizer); + + //Parametrize fit generator + fitGenerator->SetModelParameterizer(modelParameterizer); + fitGenerator->SetMask(m_selectedMask); + fitGenerator->SetFitFunctor(fitFunctor); + fitGenerator->SetSignal(roiSignal); + fitGenerator->SetTimeGrid(mitk::ExtractTimeGrid(m_selectedImage)); + + generator = fitGenerator.GetPointer(); + + std::string roiUID = mitk::EnsureModelFitUID(this->m_selectedMaskNode); + + //Create model info + modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, + m_selectedNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_ROIBASED(), roiUID); + mitk::ScalarListLookupTable::ValueType infoSignal; + + for (mitk::MaskedDynamicImageStatisticsGenerator::ResultType::const_iterator pos = + roiSignal.begin(); pos != roiSignal.end(); ++pos) + { + infoSignal.push_back(*pos); + } + + modelFitInfo->inputData.SetTableValue("ROI", infoSignal); +} + +template +void MRPerfusionView::GenerateAIFbasedModelFit_PixelBased(mitk::modelFit::ModelFitInfo::Pointer& + modelFitInfo, mitk::ParameterFitImageGeneratorBase::Pointer& generator) +{ + mitk::PixelBasedParameterFitImageGenerator::Pointer fitGenerator = + mitk::PixelBasedParameterFitImageGenerator::New(); + + typename TParameterizer::Pointer modelParameterizer = + TParameterizer::New(); + + mitk::Image::Pointer concentrationImage; + mitk::DataNode::Pointer concentrationNode; + GetConcentrationImage(concentrationImage, concentrationNode, false); + + mitk::AIFBasedModelBase::AterialInputFunctionType aif; + mitk::AIFBasedModelBase::AterialInputFunctionType aifTimeGrid; + GetAIF(aif, aifTimeGrid); + + modelParameterizer->SetAIF(aif); + modelParameterizer->SetAIFTimeGrid(aifTimeGrid); + + this->ConfigureInitialParametersOfParameterizer(modelParameterizer); + + mitk::NumericTwoCompartmentExchangeModelParameterizer* numTCXParametrizer = + dynamic_cast + (modelParameterizer.GetPointer()); + + if (numTCXParametrizer) + { + numTCXParametrizer->SetODEINTStepSize(this->m_Controls.odeStepSize->value()); + } + + //Specify fitting strategy and criterion parameters + mitk::ModelFitFunctorBase::Pointer fitFunctor = CreateDefaultFitFunctor(modelParameterizer); + + //Parametrize fit generator + fitGenerator->SetModelParameterizer(modelParameterizer); + std::string roiUID = ""; + + if (m_selectedMask.IsNotNull()) + { + fitGenerator->SetMask(m_selectedMask); + roiUID = mitk::EnsureModelFitUID(this->m_selectedMaskNode); + } + + fitGenerator->SetDynamicImage(concentrationImage); + fitGenerator->SetFitFunctor(fitFunctor); + + generator = fitGenerator.GetPointer(); + + //Create model info + modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, + concentrationNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_PIXELBASED(), + roiUID); + + mitk::ScalarListLookupTable::ValueType infoSignal; + + for (mitk::AIFBasedModelBase::AterialInputFunctionType::const_iterator pos = + aif.begin(); pos != aif.end(); ++pos) + { + infoSignal.push_back(*pos); + } + + modelFitInfo->inputData.SetTableValue("AIF", infoSignal); +} + +template +void MRPerfusionView::GenerateAIFbasedModelFit_ROIBased( + mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, + mitk::ParameterFitImageGeneratorBase::Pointer& generator) +{ + if (m_selectedMask.IsNull()) + { + return; + } + + mitk::ROIBasedParameterFitImageGenerator::Pointer fitGenerator = + mitk::ROIBasedParameterFitImageGenerator::New(); + + typename TParameterizer::Pointer modelParameterizer = + TParameterizer::New(); + + mitk::Image::Pointer concentrationImage; + mitk::DataNode::Pointer concentrationNode; + GetConcentrationImage(concentrationImage, concentrationNode, false); + + mitk::AIFBasedModelBase::AterialInputFunctionType aif; + mitk::AIFBasedModelBase::AterialInputFunctionType aifTimeGrid; + GetAIF(aif, aifTimeGrid); + + modelParameterizer->SetAIF(aif); + modelParameterizer->SetAIFTimeGrid(aifTimeGrid); + + this->ConfigureInitialParametersOfParameterizer(modelParameterizer); + + mitk::NumericTwoCompartmentExchangeModelParameterizer* numTCXParametrizer = + dynamic_cast + (modelParameterizer.GetPointer()); + + if (numTCXParametrizer) + { + numTCXParametrizer->SetODEINTStepSize(this->m_Controls.odeStepSize->value()); + } + + //Compute ROI signal + mitk::MaskedDynamicImageStatisticsGenerator::Pointer signalGenerator = + mitk::MaskedDynamicImageStatisticsGenerator::New(); + signalGenerator->SetMask(m_selectedMask); + signalGenerator->SetDynamicImage(concentrationImage); + signalGenerator->Generate(); + + mitk::MaskedDynamicImageStatisticsGenerator::ResultType roiSignal = signalGenerator->GetMean(); + + //Specify fitting strategy and criterion parameters + mitk::ModelFitFunctorBase::Pointer fitFunctor = CreateDefaultFitFunctor(modelParameterizer); + + //Parametrize fit generator + fitGenerator->SetModelParameterizer(modelParameterizer); + fitGenerator->SetMask(m_selectedMask); + fitGenerator->SetFitFunctor(fitFunctor); + fitGenerator->SetSignal(roiSignal); + fitGenerator->SetTimeGrid(mitk::ExtractTimeGrid(concentrationImage)); + + generator = fitGenerator.GetPointer(); + + std::string roiUID = mitk::EnsureModelFitUID(this->m_selectedMaskNode); + + //Create model info + modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, + concentrationNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_ROIBASED(), + roiUID); + + mitk::ScalarListLookupTable::ValueType infoSignal; + + for (mitk::MaskedDynamicImageStatisticsGenerator::ResultType::const_iterator pos = + roiSignal.begin(); pos != roiSignal.end(); ++pos) + { + infoSignal.push_back(*pos); + } + + modelFitInfo->inputData.SetTableValue("ROI", infoSignal); + + infoSignal.clear(); + + for (mitk::AIFBasedModelBase::AterialInputFunctionType::const_iterator pos = + aif.begin(); pos != aif.end(); ++pos) + { + infoSignal.push_back(*pos); + } + + modelFitInfo->inputData.SetTableValue("AIF", infoSignal); +} + + +void MRPerfusionView::DoFit(const mitk::modelFit::ModelFitInfo* fitSession, + mitk::ParameterFitImageGeneratorBase* generator) +{ + std::stringstream message; + message << "" << "Fitting Data Set . . ." << ""; + m_Controls.errorMessageLabel->setText(message.str().c_str()); + m_Controls.errorMessageLabel->show(); + + ///////////////////////// + //create job and put it into the thread pool + std::string fitName = m_Controls.lineFitName->text().toStdString(); + if (fitName.empty()) + { + fitName = m_Controls.lineFitName->placeholderText().toStdString(); + } + + ParameterFitBackgroundJob* pJob = new ParameterFitBackgroundJob(generator, fitSession, fitName, + this->m_selectedNode); + pJob->setAutoDelete(true); + + connect(pJob, SIGNAL(Error(QString)), this, SLOT(OnJobError(QString))); + connect(pJob, SIGNAL(Finished()), this, SLOT(OnJobFinished())); + connect(pJob, SIGNAL(ResultsAreAvailable(mitk::modelFit::ModelFitResultNodeVectorType, + const ParameterFitBackgroundJob*)), this, + SLOT(OnJobResultsAreAvailable(mitk::modelFit::ModelFitResultNodeVectorType, + const ParameterFitBackgroundJob*)), Qt::BlockingQueuedConnection); + + connect(pJob, SIGNAL(JobProgress(double)), this, SLOT(OnJobProgress(double))); + connect(pJob, SIGNAL(JobStatusChanged(QString)), this, SLOT(OnJobStatusChanged(QString))); + + QThreadPool* threadPool = QThreadPool::globalInstance(); + threadPool->start(pJob); +} + +MRPerfusionView::MRPerfusionView() : m_FittingInProgress(false) +{ + m_selectedImage = NULL; + m_selectedMask = NULL; + + mitk::ModelFactoryBase::Pointer factory = + mitk::DescriptivePharmacokineticBrixModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + factory = mitk::ThreeStepLinearModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + factory = mitk::StandardToftsModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + factory = mitk::ExtendedToftsModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + factory = mitk::TwoCompartmentExchangeModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + factory = mitk::NumericTwoCompartmentExchangeModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + + mitk::NodePredicateDataType::Pointer isLabelSet = mitk::NodePredicateDataType::New("LabelSetImage"); + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); + mitk::NodePredicateAnd::Pointer isLegacyMask = mitk::NodePredicateAnd::New(isImage, isBinary); + + mitk::NodePredicateOr::Pointer isMask = mitk::NodePredicateOr::New(isLegacyMask, isLabelSet); + mitk::NodePredicateAnd::Pointer isNoMask = mitk::NodePredicateAnd::New(isImage, mitk::NodePredicateNot::New(isMask)); + + this->m_IsMaskPredicate = mitk::NodePredicateAnd::New(isMask, mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))).GetPointer(); + + this->m_IsNoMaskImagePredicate = mitk::NodePredicateAnd::New(isNoMask, mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))).GetPointer(); +} + +void MRPerfusionView::OnJobFinished() +{ + this->m_Controls.infoBox->append(QString("Fitting finished")); + this->m_FittingInProgress = false; + this->UpdateGUIControls(); +}; + +void MRPerfusionView::OnJobError(QString err) +{ + MITK_ERROR << err.toStdString().c_str(); + + m_Controls.infoBox->append(QString("") + err + QString("")); +}; + +void MRPerfusionView::OnJobResultsAreAvailable(mitk::modelFit::ModelFitResultNodeVectorType results, + const ParameterFitBackgroundJob* pJob) +{ + //Store the resulting parameter fit image via convenience helper function in data storage + //(handles the correct generation of the nodes and their properties) + mitk::modelFit::StoreResultsInDataStorage(this->GetDataStorage(), results, pJob->GetParentNode()); + + m_Controls.errorMessageLabel->setText(""); + m_Controls.errorMessageLabel->hide(); +}; + +void MRPerfusionView::OnJobProgress(double progress) +{ + QString report = QString("Progress. ") + QString::number(progress); + this->m_Controls.infoBox->append(report); +}; + +void MRPerfusionView::OnJobStatusChanged(QString info) +{ + this->m_Controls.infoBox->append(info); +} + + +void MRPerfusionView::InitModelComboBox() const +{ + this->m_Controls.comboModel->clear(); + this->m_Controls.comboModel->addItem(tr("No model selected")); + + for (ModelFactoryStackType::const_iterator pos = m_FactoryStack.begin(); + pos != m_FactoryStack.end(); ++pos) + { + this->m_Controls.comboModel->addItem(QString::fromStdString((*pos)->GetClassID())); + } + + this->m_Controls.comboModel->setCurrentIndex(0); +}; + +mitk::DataNode::Pointer MRPerfusionView::AddConcentrationImage(mitk::Image* image, + const std::string& nodeName) const +{ + if (!image) + { + mitkThrow() << "Cannot generate concentration node. Passed image is null. parameter name: "; + } + + mitk::DataNode::Pointer result = mitk::DataNode::New(); + + result->SetData(image); + + result->SetName(nodeName); + + result->SetVisibility(true); + + mitk::EnsureModelFitUID(result); + + this->GetDataStorage()->Add(result, m_selectedNode); + + return result; +}; + + +mitk::Image::Pointer MRPerfusionView::ConvertConcentrationImage(bool AIFMode) +{ + //Compute Concentration image + mitk::ConcentrationCurveGenerator::Pointer concentrationGen = + mitk::ConcentrationCurveGenerator::New(); + + if (m_Controls.checkDedicatedAIFImage->isChecked() && AIFMode) + { + concentrationGen->SetDynamicImage(this->m_selectedAIFImage); + } + else + { + concentrationGen->SetDynamicImage(this->m_selectedImage); + } + + concentrationGen->SetisTurboFlashSequence(IsTurboFlashSequenceFlag()); + concentrationGen->SetAbsoluteSignalEnhancement(m_Controls.radioButton_absoluteEnhancement->isChecked()); + concentrationGen->SetRelativeSignalEnhancement(m_Controls.radioButton_relativeEnchancement->isChecked()); + concentrationGen->SetUsingT1Map(m_Controls.radioButtonUsingT1->isChecked()); + + + if (IsTurboFlashSequenceFlag()) + { + if (AIFMode) + { + concentrationGen->SetRecoveryTime(m_Controls.AifRecoverytime->value()); + } + else + { + concentrationGen->SetRecoveryTime(m_Controls.recoverytime->value()); + } + + concentrationGen->SetRelaxationTime(m_Controls.relaxationtime->value()); + concentrationGen->SetRelaxivity(m_Controls.relaxivity->value()); + } + else if (this->m_Controls.radioButtonUsingT1->isChecked()) + { + concentrationGen->SetRecoveryTime(m_Controls.TRSpinBox->value()); + concentrationGen->SetRelaxivity(m_Controls.RelaxivitySpinBox->value()); + concentrationGen->SetT10Image(dynamic_cast(m_Controls.ComboT1Map->GetSelectedNode()->GetData())); + + //Convert Flipangle from degree to radiant + double alpha = m_Controls.FlipangleSpinBox->value()/360*2* boost::math::constants::pi(); + concentrationGen->SetFlipAngle(alpha); + } + else + { + concentrationGen->SetFactor(m_Controls.factorSpinBox->value()); + } + + mitk::Image::Pointer concentrationImage = concentrationGen->GetConvertedImage(); + + return concentrationImage; +} + +void MRPerfusionView::GetAIF(mitk::AIFBasedModelBase::AterialInputFunctionType& aif, + mitk::AIFBasedModelBase::AterialInputFunctionType& aifTimeGrid) +{ + if (this->m_Controls.radioAIFFile->isChecked()) + { + aif.clear(); + aifTimeGrid.clear(); + + aif.SetSize(AIFinputFunction.size()); + aifTimeGrid.SetSize(AIFinputGrid.size()); + + aif.fill(0.0); + aifTimeGrid.fill(0.0); + + itk::Array::iterator aifPos = aif.begin(); + + for (std::vector::const_iterator pos = AIFinputFunction.begin(); + pos != AIFinputFunction.end(); ++pos, ++aifPos) + { + *aifPos = *pos; + } + + itk::Array::iterator gridPos = aifTimeGrid.begin(); + + for (std::vector::const_iterator pos = AIFinputGrid.begin(); pos != AIFinputGrid.end(); + ++pos, ++gridPos) + { + *gridPos = *pos; + } + } + else if (this->m_Controls.radioAIFImage->isChecked()) + { + aif.clear(); + aifTimeGrid.clear(); + + mitk::AterialInputFunctionGenerator::Pointer aifGenerator = + mitk::AterialInputFunctionGenerator::New(); + + //Hematocrit level + aifGenerator->SetHCL(this->m_Controls.HCLSpinBox->value()); + + //mask settings + this->m_selectedAIFMaskNode = m_Controls.comboAIFMask->GetSelectedNode(); + this->m_selectedAIFMask = dynamic_cast(this->m_selectedAIFMaskNode->GetData()); + + if (this->m_selectedAIFMask->GetTimeSteps() > 1) + { + MITK_INFO << + "Selected AIF mask has multiple timesteps. Only use first timestep to mask model fit. AIF Mask name: " + << + m_selectedAIFMaskNode->GetName() ; + mitk::ImageTimeSelector::Pointer maskedImageTimeSelector = mitk::ImageTimeSelector::New(); + maskedImageTimeSelector->SetInput(this->m_selectedAIFMask); + maskedImageTimeSelector->SetTimeNr(0); + maskedImageTimeSelector->UpdateLargestPossibleRegion(); + this->m_selectedAIFMask = maskedImageTimeSelector->GetOutput(); + } + + if (this->m_selectedAIFMask.IsNotNull()) + { + aifGenerator->SetMask(this->m_selectedAIFMask); + } + + //image settings + if (this->m_Controls.checkDedicatedAIFImage->isChecked()) + { + this->m_selectedAIFImageNode = m_Controls.comboAIFImage->GetSelectedNode(); + this->m_selectedAIFImage = dynamic_cast(this->m_selectedAIFImageNode->GetData()); + } + else + { + this->m_selectedAIFImageNode = m_selectedNode; + this->m_selectedAIFImage = m_selectedImage; + } + + mitk::Image::Pointer concentrationImage; + mitk::DataNode::Pointer concentrationNode; + this->GetConcentrationImage(concentrationImage, concentrationNode, true); + + aifGenerator->SetDynamicImage(concentrationImage); + + aif = aifGenerator->GetAterialInputFunction(); + aifTimeGrid = aifGenerator->GetAterialInputFunctionTimeGrid(); + } + else + { + mitkThrow() << "Cannot generate AIF. View is in a invalide state. No AIF mode selected."; + } + +} + + +void MRPerfusionView::LoadAIFfromFile() +{ + QFileDialog dialog; + dialog.setNameFilter(tr("Images (*.csv")); + + QString fileName = dialog.getOpenFileName(); + + m_Controls.aifFilePath->setText(fileName); + + std::string m_aifFilePath = fileName.toStdString(); + //Read Input + typedef boost::tokenizer< boost::escaped_list_separator > Tokenizer; + ///////////////////////////////////////////////////////////////////////////////////////////////// + //AIF Data + + std::ifstream in1(m_aifFilePath.c_str()); + + if (!in1.is_open()) + { + m_Controls.errorMessageLabel->setText("Could not open AIF File!"); + } + + + std::vector< std::string > vec1; + std::string line1; + + while (getline(in1, line1)) + { + Tokenizer tok(line1); + vec1.assign(tok.begin(), tok.end()); + + // if (vec1.size() < 3) continue; + + this->AIFinputGrid.push_back(convertToDouble(vec1[0])); + this->AIFinputFunction.push_back(convertToDouble(vec1[1])); + + } + +} + +void MRPerfusionView::GetConcentrationImage(mitk::Image::Pointer& concentrationImage, + mitk::DataNode::Pointer& concentrationNode, bool AIFMode) +{ + if (this->m_Controls.radioButtonNoConversion->isChecked()) + { + if (this->m_Controls.checkDedicatedAIFImage->isChecked() && AIFMode) + { + concentrationImage = this->m_selectedAIFImage; + concentrationNode = this->m_selectedAIFImageNode; + } + else + { + concentrationImage = this->m_selectedImage; + concentrationNode = this->m_selectedNode; + } + } + else + { + if (AIFMode && !IsTurboFlashSequenceFlag() && !this->m_Controls.checkDedicatedAIFImage->isChecked()) + { + //we can directly use the input image/node for the AIF + if (m_inputImage.IsNull()) + { + mitkThrow() << + "Cannot get AIF concentration image. Invalid view state. Input image is not defined yet, but should be."; + } + + concentrationImage = this->m_inputImage; + concentrationNode = this->m_inputNode; + } + else + { + concentrationImage = this->ConvertConcentrationImage(AIFMode); + + if (AIFMode) + { + concentrationNode = AddConcentrationImage(concentrationImage, "AIF Concentration"); + } + else + { + concentrationNode = AddConcentrationImage(concentrationImage, "Concentration"); + } + } + } + + if (AIFMode) + { + m_inputAIFImage = concentrationImage; + m_inputAIFNode = concentrationNode; + } + else + { + m_inputImage = concentrationImage; + m_inputNode = concentrationNode; + } + + mitk::EnsureModelFitUID(concentrationNode); +} + +mitk::ModelFitFunctorBase::Pointer MRPerfusionView::CreateDefaultFitFunctor( + const mitk::ModelParameterizerBase* parameterizer) const +{ + mitk::LevenbergMarquardtModelFitFunctor::Pointer fitFunctor = + mitk::LevenbergMarquardtModelFitFunctor::New(); + + mitk::NormalizedSumOfSquaredDifferencesFitCostFunction::Pointer chi2 = + mitk::NormalizedSumOfSquaredDifferencesFitCostFunction::New(); + fitFunctor->RegisterEvaluationParameter("Chi^2", chi2); + + if (m_Controls.checkBox_Constraints->isChecked()) + { + fitFunctor->SetConstraintChecker(m_modelConstraints); + } + + mitk::ModelBase::Pointer refModel = parameterizer->GenerateParameterizedModel(); + + ::itk::LevenbergMarquardtOptimizer::ScalesType scales; + scales.SetSize(refModel->GetNumberOfParameters()); + scales.Fill(1.0); + fitFunctor->SetScales(scales); + + fitFunctor->SetDebugParameterMaps(m_Controls.checkDebug->isChecked()); + + return fitFunctor.GetPointer(); +} diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/MRPerfusionView.h b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/MRPerfusionView.h new file mode 100644 index 0000000000..2924dbeadb --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/MRPerfusionView.h @@ -0,0 +1,203 @@ +/*=================================================================== + +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 MRPerfusionView_h +#define MRPerfusionView_h + +#include + +#include "QmitkAbstractView.h" + +#include "itkCommand.h" + +#include "ui_MRPerfusionViewControls.h" +#include "mitkModelBase.h" +#include "QmitkParameterFitBackgroundJob.h" +#include "mitkModelFitResultHelper.h" +#include "mitkModelFactoryBase.h" +#include "mitkLevenbergMarquardtModelFitFunctor.h" +#include "mitkSimpleBarrierConstraintChecker.h" +#include "mitkAIFBasedModelBase.h" + + + +/*! +* @brief Test Plugin for SUV calculations of PET images +*/ +class MRPerfusionView : public QmitkAbstractView +{ + Q_OBJECT + +public: + + /*! @brief The view's unique ID - required by MITK */ + static const std::string VIEW_ID; + + MRPerfusionView(); + +protected slots: + + void OnModellingButtonClicked(); + + void OnJobFinished(); + void OnJobError(QString err); + void OnJobResultsAreAvailable(mitk::modelFit::ModelFitResultNodeVectorType results, + const ParameterFitBackgroundJob* pJob); + void OnJobProgress(double progress); + void OnJobStatusChanged(QString info); + + void OnModellSet(int); + void LoadAIFfromFile(); + + /**Sets visibility and enabled state of the GUI depending on the settings and workflow state.*/ + void UpdateGUIControls(); + +protected: + typedef QList SelectedDataNodeVectorType; + + // Overridden base class functions + + /*! + * @brief Sets up the UI controls and connects the slots and signals. Gets + * called by the framework to create the GUI at the right time. + * @param[in,out] parent The parent QWidget, as this class itself is not a QWidget + * subclass. + */ + void CreateQtPartControl(QWidget* parent); + + /*! + * @brief Sets the focus to the plot curve button. Gets called by the framework to set the + * focus on the right widget. + */ + void SetFocus(); + + /*! @brief Generates a configured fit generator and the corresponding modelinfo for a descriptive brix model with pixel based strategy. + * @remark add GenerateFunction for each model in the Combo box*/ + void GenerateDescriptiveBrixModel_PixelBased(mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, + mitk::ParameterFitImageGeneratorBase::Pointer& generator); + void GenerateDescriptiveBrixModel_ROIBased(mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, + mitk::ParameterFitImageGeneratorBase::Pointer& generator); + + void Generate3StepLinearModelFit_PixelBased(mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, + mitk::ParameterFitImageGeneratorBase::Pointer& generator); + void Generate3StepLinearModelFit_ROIBased(mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, + mitk::ParameterFitImageGeneratorBase::Pointer& generator); + + + template + void GenerateAIFbasedModelFit_ROIBased(mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, + mitk::ParameterFitImageGeneratorBase::Pointer& generator); + + template + void GenerateAIFbasedModelFit_PixelBased(mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, + mitk::ParameterFitImageGeneratorBase::Pointer& generator); + + /** Helper function that configures the initial parameter strategy of a parameterizer + according to the settings of the GUI.*/ + void ConfigureInitialParametersOfParameterizer(mitk::ModelParameterizerBase* parameterizer) const; + + /*! Starts the fitting job with the passed generator and session info*/ + void DoFit(const mitk::modelFit::ModelFitInfo* fitSession, + mitk::ParameterFitImageGeneratorBase* generator); + + /**Checks if the settings in the GUI are valid for the chosen model.*/ + bool CheckModelSettings() const; + + void InitModelComboBox() const; + + /*! Helper method that adds an concentration image as child node to the current m_selectedNode and returns this new child node.*/ + mitk::DataNode::Pointer AddConcentrationImage(mitk::Image* image, const std::string& nodeName) const; + + + + /*! \brief called by QmitkFunctionality when DataManager's selection has changed + */ + virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer source, + const QList& selectedNodes); + + // Variables + + /*! @brief The view's UI controls */ + Ui::MRPerfusionViewControls m_Controls; + + /* Nodes selected by user/ui for the fit */ + mitk::DataNode::Pointer m_selectedNode; + mitk::DataNode::Pointer m_selectedMaskNode; + mitk::DataNode::Pointer m_selectedAIFMaskNode; + mitk::DataNode::Pointer m_selectedAIFImageNode; + + /* Images selected by user/ui for the fit */ + mitk::Image::Pointer m_selectedImage; + mitk::Image::Pointer m_selectedMask; + mitk::Image::Pointer m_selectedAIFMask; + mitk::Image::Pointer m_selectedAIFImage; + + /* Node used for the fit (my be the selected image + or converted ones (depending on the ui settings */ + mitk::DataNode::Pointer m_inputNode; + mitk::DataNode::Pointer m_inputAIFNode; + + /* Image used for the fit (my be the selected image + or converted ones (depending on the ui settings */ + mitk::Image::Pointer m_inputImage; + mitk::Image::Pointer m_inputAIFImage; + + mitk::ModelFactoryBase::Pointer m_selectedModelFactory; + + mitk::SimpleBarrierConstraintChecker::Pointer m_modelConstraints; + +private: + bool IsTurboFlashSequenceFlag() const; + + bool m_FittingInProgress; + + typedef std::vector ModelFactoryStackType; + ModelFactoryStackType m_FactoryStack; + + /**Converts the selected image to a concentration image based on the given gui settings. + AIFMode controls if the concentration image for the fit input or the AIF will be converted.*/ + mitk::Image::Pointer ConvertConcentrationImage(bool AIFMode); + + /**Helper function that (depending on the gui settings) directly pass back the selected image/node + or the newly generated concentration image/node. The result is always what should be used as input for + the fitting. If AIFMode is true the function will generate the data for the AIF.*/ + void GetConcentrationImage(mitk::Image::Pointer& concentrationImage, + mitk::DataNode::Pointer& concentrationNode, bool AIFMode); + + /**Helper function that (depending on the gui settings) generates and passes back the AIF and its time grid + that should be used for fitting. + @remark the parameters aif and aifTimeGrid will be initialized accordingly if the method returns.*/ + void GetAIF(mitk::AIFBasedModelBase::AterialInputFunctionType& aif, + mitk::AIFBasedModelBase::AterialInputFunctionType& aifTimeGrid); + + /**Helper function that generates a default fitting functor + * default is a levenberg marquart based optimizer with all scales set to 1.0. + * Constraint setter will be set based on the gui setting and a evaluation parameter + * "sum of squared differences" will always be set.*/ + mitk::ModelFitFunctorBase::Pointer CreateDefaultFitFunctor(const mitk::ModelParameterizerBase* + parameterizer) const; + + /**Returns the default fit name, derived from the current GUI settings.*/ + std::string GetDefaultFitName() const; + + std::vector AIFinputGrid; + std::vector AIFinputFunction; + + mitk::NodePredicateBase::Pointer m_IsNoMaskImagePredicate; + mitk::NodePredicateBase::Pointer m_IsMaskPredicate; +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/MRPerfusionViewControls.ui b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/MRPerfusionViewControls.ui new file mode 100644 index 0000000000..7202a701b1 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/MRPerfusionViewControls.ui @@ -0,0 +1,680 @@ + + + MRPerfusionViewControls + + + + 0 + 0 + 556 + 1124 + + + + + 0 + 0 + + + + QmitkTemplate + + + + + + + + + + Selected Time Series: + + + + + + + No series selected. + + + + + + + + + + + Selected Mask: + + + + + + + No mask selected. + + + + + + + + + Fitting strategy + + + + 5 + + + 5 + + + + + Pixel based + + + true + + + + + + + ROI based + + + + + + + + + + + + Message + + + + + + + - + + + + + + + + + + + + Select pharmacokinetic modell... + + + + + + + + AIF Mask: + + + + + + Select AIF from Image: + + + + + + + 20 + + + + + + 0 + 0 + + + + + + + + AIF Mask: + + + + + + + false + + + Dedicated AIF Image: + + + + + + + false + + + + 0 + 0 + + + + + + + + + + 0 + + + + + Select AIF from File: + + + + + + + + + + false + + + Browse + + + + + + + + + 5 + + + + + Hematocrit Level [ ]: + + + + + + + 1.000000000000000 + + + 0.010000000000000 + + + + + + + + + + + + Descriptive Brix-Model Parameters: + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Injection Time [min]: + + + + + + + + + + + + + Numeric Two Compartment Exchange Model Parameters: + + + + + + ODE Int Step Size [s]: + + + + + + + 3 + + + 0.001000000000000 + + + 0.050000000000000 + + + + + + + + + + + 0 + 0 + + + + Model Fit Configuration + + + + + + + 0 + 0 + + + + + + 0 + 0 + 512 + 73 + + + + Start parameter + + + + + + Enter Fit Starting Parameters + + + + + + + + 0 + 0 + + + + + + + + + + 0 + 0 + 303 + 246 + + + + Constraints + + + + + + Enter Constraints for Fit Parameters + + + + + + + + 0 + 0 + + + + + 0 + 200 + + + + + + + + + + 0 + -34 + 499 + 516 + + + + Conversion: Signal to Concentration + + + + 9 + + + + + No Signal Conversion + + + true + + + + + + + 10 + + + + + Using T1 Map + + + + + + + 10 + + + + + Parameters: + + + + + + Flip Angle [ ° ] : + + + + + + + Repetition Time TR [ms] : + + + + + + + T1 Map [ms] : + + + + + + + + + + 10000.000000000000000 + + + + + + + Relaxivity [mM⁻¹ s⁻¹] : + + + + + + + + + + + + + + + + + + + + 6 + + + + + Relative Signal Enhancement + + + + + + + Absolute Signal Enhancement + + + + + + + + + + Conversion Factor k: + + + + + + + + + 2 + + + + + TurboFLASH Sequence + + + + + + + 5 + + + 20 + + + + + true + + + Turbo FLASH Parameters: + + + + + + Recovery Time [s]: + + + + + + + + + + Relaxation Time [s]: + + + + + + + + + + Relaxivity [ ]: + + + + + + + + + + AIF Recovery Time [s]: + + + + + + + + + + + + + + + + + + + + + + + + 5 + + + + + Fitting name: + + + + + + + <html><head/><body><p>Name/prefix that should be used for the fitting results.</p><p>May be explicitly defined by the user.</p></body></html> + + + + + + default fit name + + + + + + + + + Start Modelling + + + + + + + Generate debug parameter images + + + + + + + + 0 + 0 + + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + QmitkSimpleBarrierManagerWidget + QWidget +
QmitkSimpleBarrierManagerWidget.h
+
+ + QmitkInitialValuesManagerWidget + QWidget +
QmitkInitialValuesManagerWidget.h
+
+ + QmitkDataStorageComboBox + QWidget +
QmitkDataStorageComboBox.h
+
+
+ + +
diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/org_mitk_MRPerfusionView_Activator.cpp b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/org_mitk_MRPerfusionView_Activator.cpp new file mode 100644 index 0000000000..3364241759 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/org_mitk_MRPerfusionView_Activator.cpp @@ -0,0 +1,29 @@ +/*=================================================================== + +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 "org_mitk_MRPerfusionView_Activator.h" + +#include "MRPerfusionView.h" + +void org_mitk_MRPerfusionView_Activator::start(ctkPluginContext* context) + { + BERRY_REGISTER_EXTENSION_CLASS(MRPerfusionView, context); + } + + void org_mitk_MRPerfusionView_Activator::stop(ctkPluginContext* context) + { + Q_UNUSED(context); + } diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/org_mitk_MRPerfusionView_Activator.h b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/org_mitk_MRPerfusionView_Activator.h new file mode 100644 index 0000000000..9fb289d5b9 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/org_mitk_MRPerfusionView_Activator.h @@ -0,0 +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. + +===================================================================*/ + +#ifndef org_mitk_MRPerfusionView_Activator_h +#define org_mitk_MRPerfusionView_Activator_h + +#include + + class org_mitk_MRPerfusionView_Activator : public QObject, public ctkPluginActivator + { + Q_OBJECT + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_pharmacokinetics_mri") + Q_INTERFACES(ctkPluginActivator) + + public: + + /*! + * @brief Registers the plug-in. Gets called by the framework when the plug-in is + * first loaded. + * @param context The corresponding CTK plug-in context in which the plug-in is loaded. + */ + void start(ctkPluginContext* context); + + /*! + * @brief Deregisters the plug-in. Gets called by the framework when the plug-in + * is unloaded. + * @param context The corresponding CTK plug-in context in which the plug-in was loaded. + */ + void stop(ctkPluginContext* context); + }; + +#endif diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/CMakeLists.txt b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/CMakeLists.txt new file mode 100644 index 0000000000..7fc3f1427a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/CMakeLists.txt @@ -0,0 +1,7 @@ +project(org_mitk_gui_qt_pharmacokinetics_pet) + +mitk_create_plugin( + EXPORT_DIRECTIVE MRPERFUSION_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgetsExt MitkFitMIDataUI MitkPharmacokinetics +) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..7e19a3b864 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/documentation/UserManual/Manual.dox @@ -0,0 +1,7 @@ +/** +\page org_mitk_gui_qt_pharmacokinetics_pet The Dynamic PET DataFit View + +\section org_mitk_gui_qt_pharmacokinetics_pet_Overview Overview +This plug-in allows to fit dynamic PET images to different given models. + +*/ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..06c7ca3583 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk_gui_qt_pharmacokinetics_pet org.mitk.gui.qt.pharmacokinetics.pet + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup org_mitk_gui_qt_pharmacokinetics_pet_internal Internal + \ingroup org_mitk_gui_qt_pharmacokinetics_pet + + \brief This subcategory includes the internal classes of the org.mitk.gui.qt.pharmacokinetics.pet. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/files.cmake b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/files.cmake new file mode 100644 index 0000000000..6ff409c29e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/files.cmake @@ -0,0 +1,42 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_PETDynamicView_Activator.cpp + PETDynamicView.cpp +) + +set(UI_FILES + src/internal/PETDynamicViewControls.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_PETDynamicView_Activator.h + src/internal/PETDynamicView.h +) + +# list of resource files which can be used by the plug-in +# system without loading the plug-ins shared library, +# for example the icon used in the menu and tabs for the +# plug-in views in the workbench +set(CACHED_RESOURCE_FILES + resources/PETDynamic.png + plugin.xml +) + +# list of Qt .qrc files which contain additional resources +# specific to this plugin +set(QRC_FILES + +) + +set(CPP_FILES ) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/manifest_headers.cmake new file mode 100644 index 0000000000..87c3fac8ac --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "PET Dynamic DataFit Plugin") +set(Plugin-Version "1.0") +set(Plugin-Vendor "DKFZ, Software Development For Integrated Diagnostics and Therapy") +set(Plugin-ContactAddress "c.debus@dkfz.de") +set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/plugin.xml b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/plugin.xml new file mode 100644 index 0000000000..3631159e50 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/resources/PETDynamic.png b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/resources/PETDynamic.png new file mode 100644 index 0000000000..36aec5f5bd Binary files /dev/null and b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/resources/PETDynamic.png differ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/PETDynamicView.cpp b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/PETDynamicView.cpp new file mode 100644 index 0000000000..63bcebd4dc --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/PETDynamicView.cpp @@ -0,0 +1,942 @@ +/*=================================================================== + +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 "PETDynamicView.h" + +#include "mitkWorkbenchUtil.h" + + +#include "mitkAterialInputFunctionGenerator.h" + +#include "mitkOneTissueCompartmentModelFactory.h" +#include "mitkOneTissueCompartmentModelParameterizer.h" +#include "mitkExtendedOneTissueCompartmentModelFactory.h" +#include "mitkExtendedOneTissueCompartmentModelParameterizer.h" +#include "mitkTwoTissueCompartmentFDGModelFactory.h" +#include "mitkTwoTissueCompartmentFDGModelParameterizer.h" +#include "mitkTwoTissueCompartmentModelFactory.h" +#include "mitkTwoTissueCompartmentModelParameterizer.h" +#include "mitkNumericTwoTissueCompartmentModelFactory.h" +#include "mitkNumericTwoTissueCompartmentModelParameterizer.h" + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +// Includes for image casting between ITK and MITK +#include +#include "mitkImageCast.h" +#include "mitkITKImageImport.h" +#include +#include +#include + + +const std::string PETDynamicView::VIEW_ID = "org.mitk.gui.qt.pharmacokinetics.pet"; + +inline double convertToDouble(const std::string& data) +{ + std::istringstream stepStream(data); + double value = 0.0; + stepStream >> value; + return value; +} + +void PETDynamicView::SetFocus() +{ + m_Controls.btnModelling->setFocus(); +} + +void PETDynamicView::CreateQtPartControl(QWidget* parent) +{ + m_Controls.setupUi(parent); + + m_Controls.btnModelling->setEnabled(false); + m_Controls.errorMessageLabel->hide(); + + this->InitModelComboBox(); + + connect(m_Controls.btnModelling, SIGNAL(clicked()), this, SLOT(OnModellingButtonClicked())); + + connect(m_Controls.comboModel, SIGNAL(currentIndexChanged(int)), this, SLOT(OnModellSet(int))); + connect(m_Controls.radioPixelBased, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); + + //AIF setting + m_Controls.groupAIF->hide(); + m_Controls.btnAIFFile->setEnabled(false); + m_Controls.btnAIFFile->setEnabled(false); + m_Controls.radioAIFImage->setChecked(true); + m_Controls.comboAIFMask->SetDataStorage(this->GetDataStorage()); + m_Controls.comboAIFMask->SetPredicate(m_IsMaskPredicate); + m_Controls.comboAIFMask->setVisible(true); + m_Controls.comboAIFMask->setEnabled(true); + m_Controls.comboAIFImage->SetDataStorage(this->GetDataStorage()); + m_Controls.comboAIFImage->SetPredicate(m_IsNoMaskImagePredicate); + m_Controls.comboAIFImage->setEnabled(false); + m_Controls.checkDedicatedAIFImage->setEnabled(true); + m_Controls.HCLSpinBox->setValue(0.0); + + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.comboAIFMask, + SLOT(setVisible(bool))); + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.labelAIFMask, + SLOT(setVisible(bool))); + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.checkDedicatedAIFImage, + SLOT(setVisible(bool))); + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.comboAIFMask, + SLOT(setEnabled(bool))); + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.checkDedicatedAIFImage, + SLOT(setEnabled(bool))); + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.checkDedicatedAIFImage, + SLOT(setVisible(bool))); + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.comboAIFImage, + SLOT(setVisible(bool))); + connect(m_Controls.checkDedicatedAIFImage, SIGNAL(toggled(bool)), m_Controls.comboAIFImage, + SLOT(setEnabled(bool))); + connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); + connect(m_Controls.radioAIFFile, SIGNAL(toggled(bool)), m_Controls.btnAIFFile, + SLOT(setEnabled(bool))); + connect(m_Controls.radioAIFFile, SIGNAL(toggled(bool)), m_Controls.aifFilePath, + SLOT(setEnabled(bool))); + connect(m_Controls.radioAIFFile, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); + + connect(m_Controls.btnAIFFile, SIGNAL(clicked()), this, SLOT(LoadAIFfromFile())); + + //Model fit configuration + m_Controls.groupBox_FitConfiguration->hide(); + + m_Controls.checkBox_Constraints->setEnabled(false); + m_Controls.constraintManager->setEnabled(false); + m_Controls.initialValuesManager->setEnabled(false); + m_Controls.initialValuesManager->setDataStorage(this->GetDataStorage()); + + connect(m_Controls.radioButton_StartParameters, SIGNAL(toggled(bool)), this, + SLOT(UpdateGUIControls())); + connect(m_Controls.checkBox_Constraints, SIGNAL(toggled(bool)), this, + SLOT(UpdateGUIControls())); + connect(m_Controls.initialValuesManager, SIGNAL(initialValuesChanged(void)), this, SLOT(UpdateGUIControls())); + + + connect(m_Controls.radioButton_StartParameters, SIGNAL(toggled(bool)), + m_Controls.initialValuesManager, + SLOT(setEnabled(bool))); + connect(m_Controls.checkBox_Constraints, SIGNAL(toggled(bool)), m_Controls.constraintManager, + SLOT(setEnabled(bool))); + connect(m_Controls.checkBox_Constraints, SIGNAL(toggled(bool)), m_Controls.constraintManager, + SLOT(setVisible(bool))); + + + UpdateGUIControls(); + +} + +void PETDynamicView::UpdateGUIControls() +{ + m_Controls.lineFitName->setPlaceholderText(QString::fromStdString(this->GetDefaultFitName())); + m_Controls.lineFitName->setEnabled(!m_FittingInProgress); + + m_Controls.checkBox_Constraints->setEnabled(m_modelConstraints.IsNotNull()); + + bool is1TCMFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool isExt1TCMFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool isFDGCMFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + + bool is2TCMFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL || + dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + + + m_Controls.groupAIF->setVisible(is1TCMFactory || isExt1TCMFactory || isFDGCMFactory || is2TCMFactory); + + m_Controls.groupBox_FitConfiguration->setVisible(m_selectedModelFactory); + + m_Controls.groupBox->setEnabled(!m_FittingInProgress); + m_Controls.comboModel->setEnabled(!m_FittingInProgress); + m_Controls.groupAIF->setEnabled(!m_FittingInProgress); + m_Controls.groupBox_FitConfiguration->setEnabled(!m_FittingInProgress); + + m_Controls.radioROIbased->setEnabled(m_selectedMask.IsNotNull()); + + m_Controls.btnModelling->setEnabled(m_selectedImage.IsNotNull() + && m_selectedModelFactory.IsNotNull() && !m_FittingInProgress && CheckModelSettings()); +} + +//void PETDynamicView::OnModelSettingChanged() +//{ +// bool ok = m_selectedImage.IsNotNull() && m_selectedModelFactory.IsNotNull() && !m_FittingInProgress && CheckModelSettings(); + +// m_Controls.btnModelling->setEnabled(ok); +//} + + +void PETDynamicView::OnModellSet(int index) +{ + m_selectedModelFactory = NULL; + + if (index > 0) + { + if (static_cast(index) <= m_FactoryStack.size() ) + { + m_selectedModelFactory = m_FactoryStack[index - 1]; + } + else + { + MITK_WARN << "Invalid model index. Index outside of the factory stack. Factory stack size: "<< m_FactoryStack.size() << "; invalid index: "<< index; + } + } + + if (m_selectedModelFactory) + { + this->m_modelConstraints = dynamic_cast + (m_selectedModelFactory->CreateDefaultConstraints().GetPointer()); + + m_Controls.initialValuesManager->setInitialValues(m_selectedModelFactory->GetParameterNames(), + m_selectedModelFactory->GetDefaultInitialParameterization()); + + if (this->m_modelConstraints.IsNull()) + { + this->m_modelConstraints = mitk::SimpleBarrierConstraintChecker::New(); + } + + m_Controls.constraintManager->setChecker(this->m_modelConstraints, + this->m_selectedModelFactory->GetParameterNames()); + } + + m_Controls.checkBox_Constraints->setEnabled(m_modelConstraints.IsNotNull()); + + + UpdateGUIControls(); +} + +std::string PETDynamicView::GetDefaultFitName() const +{ + std::string defaultName = "undefined model"; + + if (this->m_selectedModelFactory.IsNotNull()) + { + defaultName = this->m_selectedModelFactory->GetClassID(); + } + + if (this->m_Controls.radioPixelBased->isChecked()) + { + defaultName += "_pixel"; + } + else + { + defaultName += "_roi"; + } + + return defaultName; +} + + +void PETDynamicView::OnModellingButtonClicked() +{ + //check if all static parameters set + if (m_selectedModelFactory.IsNotNull() && CheckModelSettings()) + { + mitk::ParameterFitImageGeneratorBase::Pointer generator = NULL; + mitk::modelFit::ModelFitInfo::Pointer fitSession = NULL; + + + bool isOTCFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool isextOTCFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + + bool isFDGFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + + bool isTTCFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool isNumTTCFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + + + if (isOTCFactory) + { + if (this->m_Controls.radioPixelBased->isChecked()) + { + GenerateModelFit_PixelBased(fitSession, generator); + } + else + { + GenerateModelFit_ROIBased(fitSession, generator); + } + } + + else if (isextOTCFactory) + { + if (this->m_Controls.radioPixelBased->isChecked()) + { + GenerateModelFit_PixelBased(fitSession, generator); + } + else + { + GenerateModelFit_ROIBased(fitSession, generator); + } + } + else if (isFDGFactory) + { + if (this->m_Controls.radioPixelBased->isChecked()) + { + GenerateModelFit_PixelBased(fitSession, generator); + } + else + { + GenerateModelFit_ROIBased(fitSession, generator); + } + } + + + else if (isTTCFactory) + { + if (this->m_Controls.radioPixelBased->isChecked()) + { + GenerateModelFit_PixelBased(fitSession, generator); + } + else + { + GenerateModelFit_ROIBased(fitSession, generator); + } + } + + else if (isNumTTCFactory) + { + if (this->m_Controls.radioPixelBased->isChecked()) + { + GenerateModelFit_PixelBased(fitSession, + generator); + } + else + { + GenerateModelFit_ROIBased(fitSession, + generator); + } + } + + //add other models with else if + + if (generator.IsNotNull() && fitSession.IsNotNull()) + { + m_FittingInProgress = true; + DoFit(fitSession, generator); + } + else + { + QMessageBox box; + box.setText("Fitting error!"); + box.setInformativeText("Could not establish fitting job. Error when setting ab generator, model parameterizer or session info."); + box.setStandardButtons(QMessageBox::Ok); + box.setDefaultButton(QMessageBox::Ok); + box.setIcon(QMessageBox::Warning); + box.exec(); + } + + } + else + { + QMessageBox box; + box.setText("Static parameters for model are not set!"); + box.setInformativeText("Some static parameters, that are needed for calculation are not set and equal to zero. Modeling not possible"); + box.setStandardButtons(QMessageBox::Ok); + box.setDefaultButton(QMessageBox::Ok); + box.setIcon(QMessageBox::Warning); + box.exec(); + } +} + + +void PETDynamicView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, + const QList& selectedNodes) +{ + m_selectedMaskNode = NULL; + m_selectedMask = NULL; + + m_Controls.errorMessageLabel->setText(""); + m_Controls.masklabel->setText("No (valid) mask selected."); + m_Controls.timeserieslabel->setText("No (valid) series selected."); + + QList nodes = selectedNodes; + + if (nodes.size() > 0 && this->m_IsNoMaskImagePredicate->CheckNode(nodes.front())) + { + this->m_selectedNode = nodes.front(); + auto selectedImage = dynamic_cast(this->m_selectedNode->GetData()); + m_Controls.timeserieslabel->setText((this->m_selectedNode->GetName()).c_str()); + + if (selectedImage != this->m_selectedImage) + { + if (selectedImage) + { + this->m_Controls.initialValuesManager->setReferenceImageGeometry(selectedImage->GetGeometry()); + } + else + { + this->m_Controls.initialValuesManager->setReferenceImageGeometry(nullptr); + } + } + this->m_selectedImage = selectedImage; + nodes.pop_front(); + } + else + { + this->m_selectedNode = NULL; + this->m_selectedImage = NULL; + this->m_Controls.initialValuesManager->setReferenceImageGeometry(nullptr); + } + + if (nodes.size() > 0 && this->m_IsMaskPredicate->CheckNode(nodes.front())) + { + this->m_selectedMaskNode = nodes.front(); + this->m_selectedMask = dynamic_cast(this->m_selectedMaskNode->GetData()); + + if (this->m_selectedMask->GetTimeSteps() > 1) + { + MITK_INFO << + "Selected mask has multiple timesteps. Only use first timestep to mask model fit. Mask name: " << + m_selectedMaskNode->GetName(); + mitk::ImageTimeSelector::Pointer maskedImageTimeSelector = mitk::ImageTimeSelector::New(); + maskedImageTimeSelector->SetInput(this->m_selectedMask); + maskedImageTimeSelector->SetTimeNr(0); + maskedImageTimeSelector->UpdateLargestPossibleRegion(); + this->m_selectedMask = maskedImageTimeSelector->GetOutput(); + } + + m_Controls.masklabel->setText((this->m_selectedMaskNode->GetName()).c_str()); + } + + if (m_selectedMask.IsNull()) + { + this->m_Controls.radioPixelBased->setChecked(true); + } + + m_Controls.errorMessageLabel->show(); + + UpdateGUIControls(); +} + +bool PETDynamicView::CheckModelSettings() const +{ + bool ok = true; + + //check wether any model is set at all. Otherwise exit with false + if (m_selectedModelFactory.IsNotNull()) + { + + bool isOTCFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool isextOTCFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool isFDGFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool isTTCFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + bool isNumTTCFactory = dynamic_cast + (m_selectedModelFactory.GetPointer()) != NULL; + + if (isOTCFactory || isextOTCFactory || isFDGFactory || isTTCFactory || isNumTTCFactory) + { + if (this->m_Controls.radioAIFImage->isChecked()) + { + ok = ok && m_Controls.comboAIFMask->GetSelectedNode().IsNotNull(); + + if (this->m_Controls.checkDedicatedAIFImage->isChecked()) + { + ok = ok && m_Controls.comboAIFImage->GetSelectedNode().IsNotNull(); + } + } + else if (this->m_Controls.radioAIFFile->isChecked()) + { + ok = ok && (this->AIFinputGrid.size() != 0) && (this->AIFinputFunction.size() != 0); + } + else + { + ok = false; + } + + } + //add other models as else if and check wether all needed static parameters are set + else + { + ok = false; + } + + if (this->m_Controls.radioButton_StartParameters->isChecked() && !this->m_Controls.initialValuesManager->hasValidInitialValues()) + { + std::string warning = "Warning. Invalid start parameters. At least one parameter as an invalid image setting as source."; + MITK_ERROR << warning; + m_Controls.infoBox->append(QString("") + QString::fromStdString(warning) + QString("")); + + ok = false; + }; + } + else + { + ok = false; + } + + return ok; +} + +void PETDynamicView::ConfigureInitialParametersOfParameterizer(mitk::ModelParameterizerBase* + parameterizer) const +{ + if (m_Controls.radioButton_StartParameters->isChecked()) + { + //use user defined initial parameters + mitk::InitialParameterizationDelegateBase::Pointer paramDelegate = m_Controls.initialValuesManager->getInitialParametrizationDelegate(); + parameterizer->SetInitialParameterizationDelegate(paramDelegate); + } +} + +template +void PETDynamicView::GenerateModelFit_PixelBased( + mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, + mitk::ParameterFitImageGeneratorBase::Pointer& generator) +{ + mitk::PixelBasedParameterFitImageGenerator::Pointer fitGenerator = + mitk::PixelBasedParameterFitImageGenerator::New(); + + typename TParameterizer::Pointer modelParameterizer = + TParameterizer::New(); + + + mitk::AIFBasedModelBase::AterialInputFunctionType aif; + mitk::AIFBasedModelBase::TimeGridType aifTimeGrid; + + GetAIF(aif, aifTimeGrid); + + //Model configuration (static parameters) can be done now + modelParameterizer->SetAIF(aif); + modelParameterizer->SetAIFTimeGrid(aifTimeGrid); + this->ConfigureInitialParametersOfParameterizer(modelParameterizer); + + //Specify fitting strategy and criterion parameters + mitk::ModelFitFunctorBase::Pointer fitFunctor = CreateDefaultFitFunctor(modelParameterizer); + + //Parametrize fit generator + fitGenerator->SetModelParameterizer(modelParameterizer); + std::string roiUID = ""; + + if (m_selectedMask.IsNotNull()) + { + fitGenerator->SetMask(m_selectedMask); + roiUID = mitk::EnsureModelFitUID(this->m_selectedMaskNode); + } + + fitGenerator->SetDynamicImage(this->m_selectedImage); + fitGenerator->SetFitFunctor(fitFunctor); + + generator = fitGenerator.GetPointer(); + + //Create model info + modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, + m_selectedNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_PIXELBASED(), roiUID); + + mitk::ScalarListLookupTable::ValueType infoSignal; + + for (mitk::AIFBasedModelBase::AterialInputFunctionType::const_iterator pos = aif.begin(); + pos != aif.end(); ++pos) + { + infoSignal.push_back(*pos); + } + + modelFitInfo->inputData.SetTableValue("AIF", infoSignal); +} + + +template +void PETDynamicView::GenerateModelFit_ROIBased( + mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, + mitk::ParameterFitImageGeneratorBase::Pointer& generator) +{ + mitk::ROIBasedParameterFitImageGenerator::Pointer fitGenerator = + mitk::ROIBasedParameterFitImageGenerator::New(); + + typename TParameterizer::Pointer modelParameterizer = + TParameterizer::New(); + + + //Compute AIF + mitk::AterialInputFunctionGenerator::Pointer aifGenerator = + mitk::AterialInputFunctionGenerator::New(); + aifGenerator->SetDynamicImage(this->m_selectedImage); + aifGenerator->SetMask(this->m_selectedAIFMask); + + mitk::AIFBasedModelBase::AterialInputFunctionType aif = aifGenerator->GetAterialInputFunction(); + mitk::AIFBasedModelBase::TimeGridType aifTimeGrid = aifGenerator->GetAterialInputFunctionTimeGrid(); + + //Model configuration (static parameters) can be done now + modelParameterizer->SetAIF(aif); + modelParameterizer->SetAIFTimeGrid(aifTimeGrid); + + this->ConfigureInitialParametersOfParameterizer(modelParameterizer); + + //Compute ROI signal + mitk::MaskedDynamicImageStatisticsGenerator::Pointer signalGenerator = + mitk::MaskedDynamicImageStatisticsGenerator::New(); + signalGenerator->SetMask(m_selectedMask); + signalGenerator->SetDynamicImage(m_selectedImage); + signalGenerator->Generate(); + + mitk::MaskedDynamicImageStatisticsGenerator::ResultType roiSignal = signalGenerator->GetMean(); + + //Specify fitting strategy and criterion parameters + mitk::ModelFitFunctorBase::Pointer fitFunctor = CreateDefaultFitFunctor(modelParameterizer); + + //Parametrize fit generator + fitGenerator->SetModelParameterizer(modelParameterizer); + fitGenerator->SetMask(m_selectedMask); + fitGenerator->SetFitFunctor(fitFunctor); + fitGenerator->SetSignal(roiSignal); + fitGenerator->SetTimeGrid(mitk::ExtractTimeGrid(m_selectedImage)); + + generator = fitGenerator.GetPointer(); + + std::string roiUID = mitk::EnsureModelFitUID(this->m_selectedMaskNode); + + //Create model info + modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, + m_selectedNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_ROIBASED(), roiUID); + + mitk::ScalarListLookupTable::ValueType infoSignal; + + for (mitk::MaskedDynamicImageStatisticsGenerator::ResultType::const_iterator pos = + roiSignal.begin(); pos != roiSignal.end(); ++pos) + { + infoSignal.push_back(*pos); + } + + modelFitInfo->inputData.SetTableValue("ROI", infoSignal); + + infoSignal.clear(); + + for (mitk::AIFBasedModelBase::AterialInputFunctionType::const_iterator pos = aif.begin(); + pos != aif.end(); ++pos) + { + infoSignal.push_back(*pos); + } + + modelFitInfo->inputData.SetTableValue("AIF", infoSignal); +} + +void PETDynamicView::DoFit(const mitk::modelFit::ModelFitInfo* fitSession, + mitk::ParameterFitImageGeneratorBase* generator) +{ + std::stringstream message; + message << "" << "Fitting Data Set . . ." << ""; + m_Controls.errorMessageLabel->setText(message.str().c_str()); + m_Controls.errorMessageLabel->show(); + + ///////////////////////// + //create job and put it into the thread pool + std::string fitName = m_Controls.lineFitName->text().toStdString(); + if (fitName.empty()) + { + fitName = m_Controls.lineFitName->placeholderText().toStdString(); + } + + ParameterFitBackgroundJob* pJob = new ParameterFitBackgroundJob(generator, fitSession, fitName, + this->m_selectedNode); + + pJob->setAutoDelete(true); + + connect(pJob, SIGNAL(Error(QString)), this, SLOT(OnJobError(QString))); + connect(pJob, SIGNAL(Finished()), this, SLOT(OnJobFinished())); + connect(pJob, SIGNAL(ResultsAreAvailable(mitk::modelFit::ModelFitResultNodeVectorType, + const ParameterFitBackgroundJob*)), this, + SLOT(OnJobResultsAreAvailable(mitk::modelFit::ModelFitResultNodeVectorType, + const ParameterFitBackgroundJob*)), Qt::BlockingQueuedConnection); + + connect(pJob, SIGNAL(JobProgress(double)), this, SLOT(OnJobProgress(double))); + connect(pJob, SIGNAL(JobStatusChanged(QString)), this, SLOT(OnJobStatusChanged(QString))); + + QThreadPool* threadPool = QThreadPool::globalInstance(); + threadPool->start(pJob); +} + +PETDynamicView::PETDynamicView() : m_FittingInProgress(false) +{ + m_selectedImage = NULL; + m_selectedMask = NULL; + + mitk::ModelFactoryBase::Pointer factory = + mitk::OneTissueCompartmentModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + factory = mitk::ExtendedOneTissueCompartmentModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + factory = mitk::TwoTissueCompartmentModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + factory = mitk::TwoTissueCompartmentFDGModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + factory = mitk::NumericTwoTissueCompartmentModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + + mitk::NodePredicateDataType::Pointer isLabelSet = mitk::NodePredicateDataType::New("LabelSetImage"); + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); + mitk::NodePredicateAnd::Pointer isLegacyMask = mitk::NodePredicateAnd::New(isImage, isBinary); + + mitk::NodePredicateOr::Pointer isMask = mitk::NodePredicateOr::New(isLegacyMask, isLabelSet); + mitk::NodePredicateAnd::Pointer isNoMask = mitk::NodePredicateAnd::New(isImage, mitk::NodePredicateNot::New(isMask)); + + this->m_IsMaskPredicate = mitk::NodePredicateAnd::New(isMask, mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))).GetPointer(); + + this->m_IsNoMaskImagePredicate = mitk::NodePredicateAnd::New(isNoMask, mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))).GetPointer(); + +} + +void PETDynamicView::OnJobFinished() +{ + this->m_Controls.infoBox->append(QString("Fitting finished")); + this->m_FittingInProgress = false; +}; + +void PETDynamicView::OnJobError(QString err) +{ + MITK_ERROR << err.toStdString().c_str(); + + m_Controls.infoBox->append(QString("") + err + QString("")); + +}; + +void PETDynamicView::OnJobResultsAreAvailable(mitk::modelFit::ModelFitResultNodeVectorType results, + const ParameterFitBackgroundJob* pJob) +{ + //Store the resulting parameter fit image via convenience helper function in data storage + //(handles the correct generation of the nodes and their properties) + mitk::modelFit::StoreResultsInDataStorage(this->GetDataStorage(), results, pJob->GetParentNode()); + + m_Controls.errorMessageLabel->setText(""); + m_Controls.errorMessageLabel->hide(); +}; + +void PETDynamicView::OnJobProgress(double progress) +{ + QString report = QString("Progress. ") + QString::number(progress); + this->m_Controls.infoBox->append(report); +}; + +void PETDynamicView::OnJobStatusChanged(QString info) +{ + this->m_Controls.infoBox->append(info); +} + + +void PETDynamicView::InitModelComboBox() const +{ + this->m_Controls.comboModel->clear(); + this->m_Controls.comboModel->addItem(tr("No model selected")); + + for (ModelFactoryStackType::const_iterator pos = m_FactoryStack.begin(); + pos != m_FactoryStack.end(); ++pos) + { + this->m_Controls.comboModel->addItem(QString::fromStdString((*pos)->GetClassID())); + } + + this->m_Controls.comboModel->setCurrentIndex(0); +}; + +mitk::ModelFitFunctorBase::Pointer PETDynamicView::CreateDefaultFitFunctor( + const mitk::ModelParameterizerBase* parameterizer) const +{ + mitk::LevenbergMarquardtModelFitFunctor::Pointer fitFunctor = + mitk::LevenbergMarquardtModelFitFunctor::New(); + mitk::SumOfSquaredDifferencesFitCostFunction::Pointer evaluation = + mitk::SumOfSquaredDifferencesFitCostFunction::New(); + + fitFunctor->RegisterEvaluationParameter("sum_diff^2", evaluation); + + mitk::ChiSquareFitCostFunction::Pointer chi2 = + mitk::ChiSquareFitCostFunction::New(); + fitFunctor->RegisterEvaluationParameter("Chi^2", chi2); + + mitk::ReducedChiSquareFitCostFunction::Pointer redchi2 = + mitk::ReducedChiSquareFitCostFunction::New(); + fitFunctor->RegisterEvaluationParameter("redChi^2", redchi2); + + + + if (m_Controls.checkBox_Constraints->isChecked()) + { + fitFunctor->SetConstraintChecker(m_modelConstraints); + } + + mitk::ModelBase::Pointer refModel = parameterizer->GenerateParameterizedModel(); + + ::itk::LevenbergMarquardtOptimizer::ScalesType scales; + scales.SetSize(refModel->GetNumberOfParameters()); + scales.Fill(1.0); + fitFunctor->SetScales(scales); + + return fitFunctor.GetPointer(); +} + +void PETDynamicView::GetAIF(mitk::AIFBasedModelBase::AterialInputFunctionType& aif, + mitk::AIFBasedModelBase::AterialInputFunctionType& aifTimeGrid) +{ + if (this->m_Controls.radioAIFFile->isChecked()) + { + aif.clear(); + aifTimeGrid.clear(); + + aif.SetSize(AIFinputFunction.size()); + aifTimeGrid.SetSize(AIFinputGrid.size()); + + aif.fill(0.0); + aifTimeGrid.fill(0.0); + + itk::Array::iterator aifPos = aif.begin(); + + for (std::vector::const_iterator pos = AIFinputFunction.begin(); + pos != AIFinputFunction.end(); ++pos, ++aifPos) + { + *aifPos = *pos; + } + + itk::Array::iterator gridPos = aifTimeGrid.begin(); + + for (std::vector::const_iterator pos = AIFinputGrid.begin(); pos != AIFinputGrid.end(); + ++pos, ++gridPos) + { + *gridPos = *pos; + } + } + else if (this->m_Controls.radioAIFImage->isChecked()) + { + aif.clear(); + aifTimeGrid.clear(); + + mitk::AterialInputFunctionGenerator::Pointer aifGenerator = + mitk::AterialInputFunctionGenerator::New(); + + //Hematocrit level + aifGenerator->SetHCL(this->m_Controls.HCLSpinBox->value()); + + //mask settings + this->m_selectedAIFMaskNode = m_Controls.comboAIFMask->GetSelectedNode(); + this->m_selectedAIFMask = dynamic_cast(this->m_selectedAIFMaskNode->GetData()); + + if (this->m_selectedAIFMask->GetTimeSteps() > 1) + { + MITK_INFO << + "Selected AIF mask has multiple timesteps. Only use first timestep to mask model fit. AIF Mask name: " + << + m_selectedAIFMaskNode->GetName() ; + mitk::ImageTimeSelector::Pointer maskedImageTimeSelector = mitk::ImageTimeSelector::New(); + maskedImageTimeSelector->SetInput(this->m_selectedAIFMask); + maskedImageTimeSelector->SetTimeNr(0); + maskedImageTimeSelector->UpdateLargestPossibleRegion(); + this->m_selectedAIFMask = maskedImageTimeSelector->GetOutput(); + } + + if (this->m_selectedAIFMask.IsNotNull()) + { + aifGenerator->SetMask(this->m_selectedAIFMask); + } + + //image settings + if (this->m_Controls.checkDedicatedAIFImage->isChecked()) + { + this->m_selectedAIFImageNode = m_Controls.comboAIFImage->GetSelectedNode(); + this->m_selectedAIFImage = dynamic_cast(this->m_selectedAIFImageNode->GetData()); + } + else + { + this->m_selectedAIFImageNode = m_selectedNode; + this->m_selectedAIFImage = m_selectedImage; + } + + + aifGenerator->SetDynamicImage(this->m_selectedAIFImage); + + aif = aifGenerator->GetAterialInputFunction(); + aifTimeGrid = aifGenerator->GetAterialInputFunctionTimeGrid(); + } + else + { + mitkThrow() << "Cannot generate AIF. View is in a invalide state. No AIF mode selected."; + } + +} + + +void PETDynamicView::LoadAIFfromFile() +{ + QFileDialog dialog; + dialog.setNameFilter(tr("Images (*.csv")); + + QString fileName = dialog.getOpenFileName(); + + m_Controls.aifFilePath->setText(fileName); + + std::string m_aifFilePath = fileName.toStdString(); + //Read Input + typedef boost::tokenizer< boost::escaped_list_separator > Tokenizer; + ///////////////////////////////////////////////////////////////////////////////////////////////// + //AIF Data + + std::ifstream in1(m_aifFilePath.c_str()); + + if (!in1.is_open()) + { + m_Controls.errorMessageLabel->setText("Could not open AIF File!"); + } + + + std::vector< std::string > vec1; + std::string line1; + + while (getline(in1, line1)) + { + Tokenizer tok(line1); + vec1.assign(tok.begin(), tok.end()); + + // if (vec1.size() < 3) continue; + + this->AIFinputGrid.push_back(convertToDouble(vec1[0])); + this->AIFinputFunction.push_back(convertToDouble(vec1[1])); + + } + +} diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/PETDynamicView.h b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/PETDynamicView.h new file mode 100644 index 0000000000..0e6ab0e70e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/PETDynamicView.h @@ -0,0 +1,174 @@ +/*=================================================================== + +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 PETDynamicView_h +#define PETDynamicView_h + +#include + +#include "QmitkAbstractView.h" + +#include "itkCommand.h" + +#include "ui_PETDynamicViewControls.h" +#include "mitkModelBase.h" +#include "QmitkParameterFitBackgroundJob.h" +#include "mitkModelFitResultHelper.h" +#include "mitkModelFactoryBase.h" +#include "mitkLevenbergMarquardtModelFitFunctor.h" +#include "mitkSimpleBarrierConstraintChecker.h" +#include "mitkAIFBasedModelBase.h" + +/*! +* @brief Test Plugin for SUV calculations of PET images +*/ +class PETDynamicView : public QmitkAbstractView +{ + Q_OBJECT + +public: + + /*! @brief The view's unique ID - required by MITK */ + static const std::string VIEW_ID; + + PETDynamicView(); + +protected slots: + + + void OnModellingButtonClicked(); + + void OnJobFinished(); + void OnJobError(QString err); + void OnJobResultsAreAvailable(mitk::modelFit::ModelFitResultNodeVectorType results, + const ParameterFitBackgroundJob* pJob); + void OnJobProgress(double progress); + void OnJobStatusChanged(QString info); + + void OnModellSet(int); + void LoadAIFfromFile(); + +// void OnModelSettingChanged(); + void UpdateGUIControls(); + +protected: + typedef QList SelectedDataNodeVectorType; + + // Overridden base class functions + + /*! + * @brief Sets up the UI controls and connects the slots and signals. Gets + * called by the framework to create the GUI at the right time. + * @param[in,out] parent The parent QWidget, as this class itself is not a QWidget + * subclass. + */ + void CreateQtPartControl(QWidget* parent); + + /*! + * @brief Sets the focus to the plot curve button. Gets called by the framework to set the + * focus on the right widget. + */ + void SetFocus(); + + /*! @brief Generates a configured fit generator and the corresponding modelinfo for a descriptive brix model with pixel based strategy. + * @remark add GenerateFunction for each model in the Combo box*/ + + template + void GenerateModelFit_ROIBased(mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, + mitk::ParameterFitImageGeneratorBase::Pointer& generator); + + template + void GenerateModelFit_PixelBased(mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, + mitk::ParameterFitImageGeneratorBase::Pointer& generator); + + /** Helper function that configures the initial parameter strategy of a parameterizer + according to the settings of the GUI.*/ + void ConfigureInitialParametersOfParameterizer(mitk::ModelParameterizerBase* parameterizer) const; + + /*! Starts the fitting job with the passed generator and session info*/ + void DoFit(const mitk::modelFit::ModelFitInfo* fitSession, + mitk::ParameterFitImageGeneratorBase* generator); + + bool CheckModelSettings() const; + + void InitModelComboBox() const; + + /*! \brief called by QmitkFunctionality when DataManager's selection has changed + */ + virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer source, + const QList& selectedNodes); + + + /*! @brief The view's UI controls */ + Ui::PETDynamicViewControls m_Controls; + + mitk::DataNode::Pointer m_selectedNode; + mitk::DataNode::Pointer m_selectedMaskNode; + mitk::DataNode::Pointer m_selectedAIFMaskNode; + mitk::DataNode::Pointer m_selectedAIFImageNode; + + mitk::Image::Pointer m_selectedImage; + mitk::Image::Pointer m_selectedMask; + mitk::Image::Pointer m_selectedAIFMask; + mitk::Image::Pointer m_selectedAIFImage; + + /* Node used for the fit (my be the selected image + or converted ones (depending on the ui settings */ + mitk::DataNode::Pointer m_inputNode; + mitk::DataNode::Pointer m_inputAIFNode; + + /* Image used for the fit (my be the selected image + or converted ones (depending on the ui settings */ + mitk::Image::Pointer m_inputImage; + mitk::Image::Pointer m_inputAIFImage; + + mitk::ModelFactoryBase::Pointer m_selectedModelFactory; + + mitk::SimpleBarrierConstraintChecker::Pointer m_modelConstraints; + + +private: + bool m_FittingInProgress; + + + typedef std::vector ModelFactoryStackType; + ModelFactoryStackType m_FactoryStack; + + /**Helper function that (depending on the gui settings) generates and passes back the AIF and its time grid + that should be used for fitting. + @remark the parameters aif and aifTimeGrid will be initialized accordingly if the method returns.*/ + void GetAIF(mitk::AIFBasedModelBase::AterialInputFunctionType& aif, + mitk::AIFBasedModelBase::AterialInputFunctionType& aifTimeGrid); + + /**Helper function that generates a default fitting functor + * default is a levenberg marquart based optimizer with all scales set to 1.0. + * Constraint setter will be set based on the gui setting and a evaluation parameter + * "sum of squared differences" will always be set.*/ + mitk::ModelFitFunctorBase::Pointer CreateDefaultFitFunctor(const mitk::ModelParameterizerBase* + parameterizer) const; + + /**Returns the default fit name, derived from the current GUI settings.*/ + std::string GetDefaultFitName() const; + + std::vector AIFinputGrid; + std::vector AIFinputFunction; + + mitk::NodePredicateBase::Pointer m_IsNoMaskImagePredicate; + mitk::NodePredicateBase::Pointer m_IsMaskPredicate; + +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/PETDynamicViewControls.ui b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/PETDynamicViewControls.ui new file mode 100644 index 0000000000..7d15ec19da --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/PETDynamicViewControls.ui @@ -0,0 +1,325 @@ + + + PETDynamicViewControls + + + + 0 + 0 + 745 + 898 + + + + + 0 + 0 + + + + QmitkTemplate + + + + + + + + + + Selected Time Series: + + + + + + + No series selected. + + + + + + + + + + + Selected Mask: + + + + + + + No mask selected. + + + + + + + + + Fitting strategy + + + + 5 + + + 5 + + + + + Pixel based + + + true + + + + + + + ROI based + + + + + + + + + + + + Message + + + + + + + - + + + + + + + + + + + + Select pharmacokinetic modell... + + + + + + + + AIF Mask: + + + + + + Select AIF from Image: + + + + + + + + + AIF Mask: + + + + + + + Dedicated AIF Image: + + + + + + + + + + + + + + + + + Select AIF from File: + + + + + + + + + + Browse + + + + + + + + + + + Whole Blood to Plasma Correction: + + + + + + + + + + + + + + + Model Fit Configuration + + + + + + 1 + + + + + 0 + 0 + 701 + 129 + + + + + + + + + + Start Parameters + + + + + + Enter parameter starting values manually: + + + + + + + + + + + + 0 + 0 + 701 + 129 + + + + Constraints + + + + + + Enter Constraints for Fit Parameters + + + + + + + + + + + + + + + + + 0 + + + 0 + + + + + Fitting name: + + + + + + + + + + + + Start Modelling + + + + + + + true + + + + + + + + + QmitkSimpleBarrierManagerWidget + QWidget +
QmitkSimpleBarrierManagerWidget.h
+
+ + QmitkInitialValuesManagerWidget + QWidget +
QmitkInitialValuesManagerWidget.h
+
+ + QmitkDataStorageComboBox + QWidget +
QmitkDataStorageComboBox.h
+
+
+ + +
diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/org_mitk_PETDynamicView_Activator.cpp b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/org_mitk_PETDynamicView_Activator.cpp new file mode 100644 index 0000000000..2af122c47b --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/org_mitk_PETDynamicView_Activator.cpp @@ -0,0 +1,29 @@ +/*=================================================================== + +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 "org_mitk_PETDynamicView_Activator.h" + +#include "PETDynamicView.h" + + void org_mitk_PETDynamicView_Activator::start(ctkPluginContext* context) + { + BERRY_REGISTER_EXTENSION_CLASS(PETDynamicView, context); + } + + void org_mitk_PETDynamicView_Activator::stop(ctkPluginContext* context) + { + Q_UNUSED(context); + } diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/org_mitk_PETDynamicView_Activator.h b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/org_mitk_PETDynamicView_Activator.h new file mode 100644 index 0000000000..8d365615ee --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/org_mitk_PETDynamicView_Activator.h @@ -0,0 +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. + +===================================================================*/ + +#ifndef org_mitk_PETDynamicView_Activator_h +#define org_mitk_PETDynamicView_Activator_h + +#include + + class org_mitk_PETDynamicView_Activator : public QObject, public ctkPluginActivator + { + Q_OBJECT + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_pharmacokinetics_pet") + Q_INTERFACES(ctkPluginActivator) + + public: + + /*! + * @brief Registers the plug-in. Gets called by the framework when the plug-in is + * first loaded. + * @param context The corresponding CTK plug-in context in which the plug-in is loaded. + */ + void start(ctkPluginContext* context); + + /*! + * @brief Deregisters the plug-in. Gets called by the framework when the plug-in + * is unloaded. + * @param context The corresponding CTK plug-in context in which the plug-in was loaded. + */ + void stop(ctkPluginContext* context); + }; + +#endif diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/CMakeLists.txt b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/CMakeLists.txt new file mode 100644 index 0000000000..945352fc13 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/CMakeLists.txt @@ -0,0 +1,9 @@ +project(org_mitk_gui_qt_pharmacokinetics_simulation) + +mitk_create_plugin( + EXPORT_DIRECTIVE PERFUSIONDATASIMULATION_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgetsExt MitkPharmacokinetics + PACKAGE_DEPENDS + PRIVATE Boost +) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..667143d2b5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/documentation/UserManual/Manual.dox @@ -0,0 +1,5 @@ +/** +\page org_mitk_gui_qt_pharmacokinetics_simulation The Perfusion Data Simulation View + + +*/ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..f949cca550 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk_gui_qt_pharmacokinetics_simulation org.mitk.gui.qt.pharmacokinetics.simulation + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup org_mitk_gui_qt_pharmacokinetics_simulation_internal Internal + \ingroup org_mitk_gui_qt_pharmacokinetics_simulation + + \brief This subcategory includes the internal classes of the org.mitk.gui.qt.pharmacokinetics.simulation plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/files.cmake b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/files.cmake new file mode 100644 index 0000000000..f1b410b7ce --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/files.cmake @@ -0,0 +1,43 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_PerfusionDataSimulationView_Activator.cpp + PerfusionDataSimulationView.cpp + +) + +set(UI_FILES + src/internal/PerfusionDataSimulationViewControls.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_PerfusionDataSimulationView_Activator.h + src/internal/PerfusionDataSimulationView.h +) + +# list of resource files which can be used by the plug-in +# system without loading the plug-ins shared library, +# for example the icon used in the menu and tabs for the +# plug-in views in the workbench +set(CACHED_RESOURCE_FILES + resources/icon_PerfusionDataGeneration.png + plugin.xml +) + +# list of Qt .qrc files which contain additional resources +# specific to this plugin +set(QRC_FILES + +) + +set(CPP_FILES ) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/manifest_headers.cmake new file mode 100644 index 0000000000..4134f6923e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "Perfusion Data Simulation Plugin") +set(Plugin-Version "1.0") +set(Plugin-Vendor "DKFZ, Software Development For Integrated Diagnostics and Therapy") +set(Plugin-ContactAddress "c.debus@dkfz.de") +set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/plugin.xml b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/plugin.xml new file mode 100644 index 0000000000..8528041735 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/resources/icon_PerfusionDataGeneration.png b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/resources/icon_PerfusionDataGeneration.png new file mode 100644 index 0000000000..14a7784dd2 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/resources/icon_PerfusionDataGeneration.png differ diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/PerfusionDataSimulationView.cpp b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/PerfusionDataSimulationView.cpp new file mode 100644 index 0000000000..b2d30bc4a9 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/PerfusionDataSimulationView.cpp @@ -0,0 +1,1024 @@ +/*=================================================================== + +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 "mitkWorkbenchUtil.h" + +#include "PerfusionDataSimulationView.h" + +#include "itkUnaryFunctorImageFilter.h" +#include +#include "mitkImageCast.h" +#include "mitkImageTimeSelector.h" +#include "mitkITKImageImport.h" +#include "mitkGaussianNoiseFunctor.h" +#include "mitkTwoCompartmentExchangeModel.h" +#include "mitkTwoCompartmentExchangeModelParameterizer.h" +#include "mitkTwoCompartmentExchangeModelFactory.h" +#include "mitkNumericTwoCompartmentExchangeModel.h" +#include "mitkNumericTwoCompartmentExchangeModelParameterizer.h" +#include "mitkNumericTwoCompartmentExchangeModelFactory.h" +#include "mitkExtendedToftsModel.h" +#include "mitkExtendedToftsModelFactory.h" +#include "mitkExtendedToftsModelParameterizer.h" +#include "mitkTwoTissueCompartmentModel.h" +#include "mitkTwoTissueCompartmentModelParameterizer.h" +#include "mitkTwoTissueCompartmentModelFactory.h" +#include "mitkOneTissueCompartmentModel.h" +#include "mitkOneTissueCompartmentModelParameterizer.h" +#include "mitkOneTissueCompartmentModelFactory.h" +#include "mitkPerfusionDataGenerator.h" +#include +#include +#include +#include +#include "mitkSimpleFunctorBase.h" +#include "mitkArbitraryTimeGeometry.h" +#include + #include + +const std::string PerfusionDataSimulationView::VIEW_ID = "org.mitk.gui.qt.pharmacokinetics.simulation"; + +inline double convertToDouble(const std::string& data) +{ + std::istringstream stepStream(data); + stepStream.imbue(std::locale("C")); + double value = 0.0; + + if (!(stepStream >> value) || !(stepStream.eof())) + { + mitkThrow() << "Cannot convert string to double. String: " << data; + } + return value; +} + +inline double FindeMaxConcentration(std::vector Concentration) +{ + double maximum = Concentration[0]; + for (std::vector::size_type i =0; isetFocus(); +} + +void PerfusionDataSimulationView::CreateQtPartControl(QWidget* parent) +{ + m_Controls.setupUi(parent); + m_Controls.GenerateBtn->setEnabled(false); + + m_Controls.groupBox_TM->hide(); + m_Controls.groupBox_2CXM->hide(); + m_Controls.groupBox_2TCM->hide(); + m_Controls.groupBox_1TCM->hide(); + m_Controls.groupBox_CNR->hide(); + + this->InitModelComboBox(); + /** #2 @todo Reduce code ? + */ + + m_Controls.comboBox_F->SetDataStorage(this->GetDataStorage()); + m_Controls.comboBox_F->SetPredicate(m_IsNotABinaryImagePredicate); + + m_Controls.comboBox_PS->SetDataStorage(this->GetDataStorage()); + m_Controls.comboBox_PS->SetPredicate(m_IsNotABinaryImagePredicate); + + m_Controls.comboBox_fp->SetDataStorage(this->GetDataStorage()); + m_Controls.comboBox_fp->SetPredicate(m_IsNotABinaryImagePredicate); + + m_Controls.comboBox_fi->SetDataStorage(this->GetDataStorage()); + m_Controls.comboBox_fi->SetPredicate(m_IsNotABinaryImagePredicate); + + m_Controls.comboBox_Ktrans->SetDataStorage(this->GetDataStorage()); + m_Controls.comboBox_Ktrans->SetPredicate(m_IsNotABinaryImagePredicate); + + m_Controls.comboBox_vp->SetDataStorage(this->GetDataStorage()); + m_Controls.comboBox_vp->SetPredicate(m_IsNotABinaryImagePredicate); + + m_Controls.comboBox_ve->SetDataStorage(this->GetDataStorage()); + m_Controls.comboBox_ve->SetPredicate(m_IsNotABinaryImagePredicate); + + m_Controls.comboBox_K1->SetDataStorage(this->GetDataStorage()); + m_Controls.comboBox_K1->SetPredicate(m_IsNotABinaryImagePredicate); + + m_Controls.comboBox_K2->SetDataStorage(this->GetDataStorage()); + m_Controls.comboBox_K2->SetPredicate(m_IsNotABinaryImagePredicate); + + m_Controls.comboBox_K3->SetDataStorage(this->GetDataStorage()); + m_Controls.comboBox_K3->SetPredicate(m_IsNotABinaryImagePredicate); + + m_Controls.comboBox_K4->SetDataStorage(this->GetDataStorage()); + m_Controls.comboBox_K4->SetPredicate(m_IsNotABinaryImagePredicate); + + m_Controls.comboBox_VB->SetDataStorage(this->GetDataStorage()); + m_Controls.comboBox_VB->SetPredicate(m_IsNotABinaryImagePredicate); + + m_Controls.comboBox_k1->SetDataStorage(this->GetDataStorage()); + m_Controls.comboBox_k1->SetPredicate(m_IsNotABinaryImagePredicate); + + m_Controls.comboBox_k2->SetDataStorage(this->GetDataStorage()); + m_Controls.comboBox_k2->SetPredicate(m_IsNotABinaryImagePredicate); + + connect(m_Controls.AifFileBtn, SIGNAL(clicked()), this, SLOT(LoadAIFFile())); + connect(m_Controls.ModelSelection, SIGNAL(currentIndexChanged(int)), this, SLOT(OnModellSet(int))); + connect(m_Controls.GenerateBtn, SIGNAL(clicked()), this, SLOT(OnGenerateDataButtonClicked())); + connect(m_Controls.comboBox_F, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSimulationConfigurationChanged())); + connect(m_Controls.comboBox_PS, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSimulationConfigurationChanged())); + connect(m_Controls.comboBox_fp, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSimulationConfigurationChanged())); + connect(m_Controls.comboBox_fi, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSimulationConfigurationChanged())); + connect(m_Controls.comboBox_VB, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSimulationConfigurationChanged())); + connect(m_Controls.comboBox_K1, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSimulationConfigurationChanged())); + connect(m_Controls.comboBox_K2, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSimulationConfigurationChanged())); + connect(m_Controls.comboBox_K3, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSimulationConfigurationChanged())); + connect(m_Controls.comboBox_K4, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSimulationConfigurationChanged())); + connect(m_Controls.comboBox_k1, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSimulationConfigurationChanged())); + connect(m_Controls.comboBox_k2, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSimulationConfigurationChanged())); + connect(m_Controls.comboBox_Ktrans, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSimulationConfigurationChanged())); + connect(m_Controls.comboBox_vp, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSimulationConfigurationChanged())); + connect(m_Controls.comboBox_ve, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSimulationConfigurationChanged())); + connect(m_Controls.CNRSpinBox, SIGNAL(valueChanged(double)),this, SLOT(OnSimulationConfigurationChanged())); + connect(m_Controls.NoiseCheckBox, SIGNAL(stateChanged(int)),this, SLOT(OnSimulationConfigurationChanged())); + +// UpdateDataSelection(); + + } + +void PerfusionDataSimulationView::UpdateDataSelection() +{ + + +} + +//void PerfusionDataSimulationView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, +// const QList& selectedNodes) +//{ +// UpdateDataSelection(); +// m_Controls.GenerateBtn->setEnabled(CheckModelSettings()); + +//} + +void PerfusionDataSimulationView::OnSimulationConfigurationChanged() +{ +// UpdateDataSelection(); + + m_Controls.groupBox_CNR->setVisible(m_Controls.NoiseCheckBox->isChecked()); + + this->m_CNR = m_Controls.CNRSpinBox->value(); + + m_Controls.GenerateBtn->setEnabled( CheckModelSettings() ); + + +} + + +void PerfusionDataSimulationView::OnModellSet(int index) +{ + m_selectedModelFactory = NULL; + + if (index > 0) + { + if (static_cast(index) <= m_FactoryStack.size() ) + { + m_selectedModelFactory = m_FactoryStack[index - 1]; + } + else + { + MITK_WARN << "Invalid model index. Index outside of the factory stack. Factory stack size: "<< m_FactoryStack.size() << "; invalid index: "<< index; + } + } + + bool isToftsFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != NULL; + bool is2CXMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != NULL || dynamic_cast(m_selectedModelFactory.GetPointer()) != NULL; + bool is2TCMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != NULL; + bool is1TCMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != NULL; + + m_Controls.groupBox_TM->setVisible(isToftsFactory); + m_Controls.groupBox_2CXM->setVisible(is2CXMFactory ); + m_Controls.groupBox_2TCM->setVisible(is2TCMFactory ); + m_Controls.groupBox_1TCM->setVisible(is1TCMFactory ); + + + m_Controls.GenerateBtn->setEnabled( CheckModelSettings() ); +// UpdateDataSelection(); + + +} + +bool PerfusionDataSimulationView::CheckModelSettings() +{ + bool ok = true; + if(m_selectedModelFactory.IsNull()) + { + return false; + } + + if(this->m_AterialInputFunction.GetSize() == 0 || this->m_TimeGrid.GetSize() == 0) + { + return false; + + } + + bool isToftsFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != NULL; + bool is2CXMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != NULL || dynamic_cast(m_selectedModelFactory.GetPointer()) != NULL; + bool is2TCMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != NULL; + bool is1TCMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != NULL; + + + if(isToftsFactory) + { + ok = ok && m_Controls.comboBox_Ktrans->GetSelectedNode().IsNotNull(); + ok = ok && m_Controls.comboBox_vp->GetSelectedNode().IsNotNull(); + ok = ok && m_Controls.comboBox_ve->GetSelectedNode().IsNotNull(); + } + else if(is2CXMFactory) + { + ok = ok && m_Controls.comboBox_F->GetSelectedNode().IsNotNull(); + ok = ok && m_Controls.comboBox_PS->GetSelectedNode().IsNotNull(); + ok = ok && m_Controls.comboBox_fp->GetSelectedNode().IsNotNull(); + ok = ok && m_Controls.comboBox_fi->GetSelectedNode().IsNotNull(); + } + + else if(is2TCMFactory) + { + ok = ok && m_Controls.comboBox_K1->GetSelectedNode().IsNotNull(); + ok = ok && m_Controls.comboBox_K2->GetSelectedNode().IsNotNull(); + ok = ok && m_Controls.comboBox_K3->GetSelectedNode().IsNotNull(); + ok = ok && m_Controls.comboBox_K4->GetSelectedNode().IsNotNull(); + ok = ok && m_Controls.comboBox_VB->GetSelectedNode().IsNotNull(); + } + else if(is1TCMFactory) + { + ok = ok && m_Controls.comboBox_k1->GetSelectedNode().IsNotNull(); + ok = ok && m_Controls.comboBox_k2->GetSelectedNode().IsNotNull(); + } + + else + { + return false; + + } + if(m_Controls.NoiseCheckBox->isChecked()) + { + if(m_CNR !=0 && m_MaxConcentration !=0) + { + this->m_Sigma = m_MaxConcentration/m_CNR; + } + if(m_Sigma==0) + { + return false; + } + } + + + + return ok; + +} + + +void PerfusionDataSimulationView::InitModelComboBox() const +{ + this->m_Controls.ModelSelection->clear(); + this->m_Controls.ModelSelection->addItem(tr("No model selected")); + + for (ModelFactoryStackType::const_iterator pos = m_FactoryStack.begin(); pos != m_FactoryStack.end(); ++pos) + { + this->m_Controls.ModelSelection->addItem(QString::fromStdString((*pos)->GetClassID())); + } + this->m_Controls.ModelSelection->setCurrentIndex(0); +}; + + +void PerfusionDataSimulationView::LoadAIFFile() +{ + QFileDialog dialog; + dialog.setNameFilter(tr("Images (*.csv")); + + QString fileName = dialog.getOpenFileName(); + + m_Controls.AifFilePath->setText( fileName ); + + std::string aifFilePath = fileName.toStdString(); + + //Read Input + typedef boost::tokenizer< boost::escaped_list_separator > Tokenizer; + ///////////////////////////////////////////////////////////////////////////////////////////////// + //AIF Data + + std::vector inputFunction; + std::vector inputGrid; + + std::ifstream in1(aifFilePath.c_str()); + + if(!in1.is_open()) + { + m_Controls.errorMessageLabel->setText("Could not open AIF File!"); + } + + + std::vector< std::string > vec1; + std::string line1; + + while (getline(in1,line1)) + { + Tokenizer tok(line1); + vec1.assign(tok.begin(),tok.end()); + +// if (vec1.size() < 3) continue; + + inputGrid.push_back(convertToDouble(vec1[0])); + inputFunction.push_back(convertToDouble(vec1[1])); + + } + + this->m_MaxConcentration = FindeMaxConcentration(inputFunction); + + itk::Array aif; + itk::Array grid; + + aif.SetSize(inputFunction.size()); + grid.SetSize(inputGrid.size()); + + aif.fill(0.0); + grid.fill(0.0); + + itk::Array::iterator aifPos = aif.begin(); + for(std::vector::const_iterator pos = inputFunction.begin(); pos != inputFunction.end(); ++pos, ++aifPos) + { + *aifPos = *pos; + } + itk::Array::iterator gridPos = grid.begin(); + for(std::vector::const_iterator pos = inputGrid.begin(); pos != inputGrid.end(); ++pos, ++gridPos) + { + *gridPos = *pos; + } + + this->m_AterialInputFunction = aif; + this->m_TimeGrid = grid; + + + m_Controls.GenerateBtn->setEnabled( CheckModelSettings() ); +// UpdateDataSelection(); + + + +} +/** @todo #2 Same function for Numeric and analytic version of FillParameterMap2CXM + */ +void PerfusionDataSimulationView::FillParameterMap2CXM() +{ + ParameterMapType stack; + + mitk::DataNode::Pointer m_selectedNode = m_Controls.comboBox_F->GetSelectedNode(); + mitk::Image::Pointer m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::TwoCompartmentExchangeModel::NAME_PARAMETER_F,m_selectedImage)); + + m_selectedNode = m_Controls.comboBox_PS->GetSelectedNode(); + m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::TwoCompartmentExchangeModel::NAME_PARAMETER_PS,m_selectedImage)); + + m_selectedNode = m_Controls.comboBox_fp->GetSelectedNode(); + m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::TwoCompartmentExchangeModel::NAME_PARAMETER_vp,m_selectedImage)); + + m_selectedNode = m_Controls.comboBox_fi->GetSelectedNode(); + m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::TwoCompartmentExchangeModel::NAME_PARAMETER_ve,m_selectedImage)); + + this->m_ParameterImageMap = stack; + +} + + +void PerfusionDataSimulationView::FillParameterMapNumeric2CXM() +{ + ParameterMapType stack; + + mitk::DataNode::Pointer m_selectedNode = m_Controls.comboBox_F->GetSelectedNode(); + mitk::Image::Pointer m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::NumericTwoCompartmentExchangeModel::NAME_PARAMETER_F,m_selectedImage)); + + m_selectedNode = m_Controls.comboBox_PS->GetSelectedNode(); + m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::NumericTwoCompartmentExchangeModel::NAME_PARAMETER_PS,m_selectedImage)); + + m_selectedNode = m_Controls.comboBox_fp->GetSelectedNode(); + m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::NumericTwoCompartmentExchangeModel::NAME_PARAMETER_vp,m_selectedImage)); + + m_selectedNode = m_Controls.comboBox_fi->GetSelectedNode(); + m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::NumericTwoCompartmentExchangeModel::NAME_PARAMETER_ve,m_selectedImage)); + + this->m_ParameterImageMap = stack; + +} + + +void PerfusionDataSimulationView::FillParameterMapETM() +{ + ParameterMapType stack; + + mitk::DataNode::Pointer m_selectedNode = m_Controls.comboBox_Ktrans->GetSelectedNode(); + mitk::Image::Pointer m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::ExtendedToftsModel::NAME_PARAMETER_Ktrans,m_selectedImage)); + + m_selectedNode = m_Controls.comboBox_vp->GetSelectedNode(); + m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::ExtendedToftsModel::NAME_PARAMETER_vp,m_selectedImage)); + + m_selectedNode = m_Controls.comboBox_ve->GetSelectedNode(); + m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::ExtendedToftsModel::NAME_PARAMETER_ve,m_selectedImage)); + + + this->m_ParameterImageMap = stack; + +} + +void PerfusionDataSimulationView::FillParameterMap2TCM() +{ + ParameterMapType stack; + + mitk::DataNode::Pointer m_selectedNode = m_Controls.comboBox_K1->GetSelectedNode(); + mitk::Image::Pointer m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::TwoTissueCompartmentModel::NAME_PARAMETER_K1,m_selectedImage)); + + m_selectedNode = m_Controls.comboBox_K2->GetSelectedNode(); + m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::TwoTissueCompartmentModel::NAME_PARAMETER_k2,m_selectedImage)); + + m_selectedNode = m_Controls.comboBox_K3->GetSelectedNode(); + m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::TwoTissueCompartmentModel::NAME_PARAMETER_k3,m_selectedImage)); + + m_selectedNode = m_Controls.comboBox_K4->GetSelectedNode(); + m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::TwoTissueCompartmentModel::NAME_PARAMETER_k4,m_selectedImage)); + + m_selectedNode = m_Controls.comboBox_VB->GetSelectedNode(); + m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::TwoTissueCompartmentModel::NAME_PARAMETER_VB,m_selectedImage)); + + this->m_ParameterImageMap = stack; + +} + +void PerfusionDataSimulationView::FillParameterMap1TCM() +{ + ParameterMapType stack; + + mitk::DataNode::Pointer m_selectedNode = m_Controls.comboBox_k1->GetSelectedNode(); + mitk::Image::Pointer m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::OneTissueCompartmentModel::NAME_PARAMETER_k1,m_selectedImage)); + + m_selectedNode = m_Controls.comboBox_k2->GetSelectedNode(); + m_selectedImage = dynamic_cast(m_selectedNode->GetData()); + stack.insert(std::make_pair(mitk::OneTissueCompartmentModel::NAME_PARAMETER_k2,m_selectedImage)); + + this->m_ParameterImageMap = stack; + +} + +void PerfusionDataSimulationView::OnGenerateDataButtonClicked() +{ + mitk::Image::Pointer m_DynamicImage = mitk::Image::New(); + + bool isToftsFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != NULL; + bool isPhysBrixFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != NULL; + bool isNumPhysBrixFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != NULL; + bool is2TCMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != NULL; + bool is1TCMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != NULL; + + + if(isToftsFactory) + { + this->FillParameterMapETM(); + m_DynamicImage = this->GenerateETModelData(); + } + + if (isPhysBrixFactory) + { + this->FillParameterMap2CXM(); + m_DynamicImage = this->Generate2CXModelData(); + } + + if (isNumPhysBrixFactory) + { + this->FillParameterMapNumeric2CXM(); + m_DynamicImage = this->GenerateNumeric2CXModelData(); + } + + if (is2TCMFactory) + { + this->FillParameterMap2TCM(); + m_DynamicImage = this->Generate2TCModelData(); + } + if (is1TCMFactory) + { + this->FillParameterMap1TCM(); + m_DynamicImage = this->Generate1TCModelData(); + } + + + + mitk::DataNode::Pointer resultNode = mitk::DataNode::New(); + std::string nameOfResultImage = "SimulationData_"; + nameOfResultImage.append(m_selectedModelFactory->GetModelDisplayName()); + resultNode->SetProperty("name", mitk::StringProperty::New(nameOfResultImage) ); + resultNode->SetData(m_DynamicImage); // set data of new node + this->GetDataStorage()->Add(resultNode); + + +} + +mitk::Image::Pointer PerfusionDataSimulationView::Generate2CXModelData() +{ +mitk::PerfusionDataGenerator::Pointer generator = mitk::PerfusionDataGenerator::New(); +mitk::TwoCompartmentExchangeModelParameterizer::Pointer modelParameterizer = mitk::TwoCompartmentExchangeModelParameterizer::New(); + +/** @todo #2 necessary? Generator need to have a map with Parameters in order of Model in order to pass vector parameters correctly to Model. + * I wanted to make it independend from the order the images are passed on + */ +for(ParameterMapType::const_iterator pos = this->m_ParameterImageMap.begin(); pos != this->m_ParameterImageMap.end(); ++pos) +{ + if(pos->first == mitk::TwoCompartmentExchangeModel::NAME_PARAMETER_F) + { + generator->SetParameterInputImage(mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_F, pos->second); + } + if(pos->first == mitk::TwoCompartmentExchangeModel::NAME_PARAMETER_PS) + { + generator->SetParameterInputImage(mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_PS, pos->second); + } + if(pos->first == mitk::TwoCompartmentExchangeModel::NAME_PARAMETER_ve) + { + generator->SetParameterInputImage(mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_ve, pos->second); + } + if(pos->first == mitk::TwoCompartmentExchangeModel::NAME_PARAMETER_vp) + { + generator->SetParameterInputImage(mitk::TwoCompartmentExchangeModel::POSITION_PARAMETER_vp, pos->second); + } +} + +modelParameterizer->SetAIF(this->m_AterialInputFunction); +modelParameterizer->SetAIFTimeGrid(this->m_TimeGrid); +modelParameterizer->SetDefaultTimeGrid(this->m_TimeGrid); + +mitk::ModelDataGenerationFunctor::Pointer m_ComputationFunctor = mitk::ModelDataGenerationFunctor::New(); + +m_ComputationFunctor->SetModelParameterizer(modelParameterizer); + +generator->SetFunctor(m_ComputationFunctor); + +mitk::Image::Pointer generatedImage = generator->GetGeneratedImage(); + + mitk::Image::Pointer resultImage = mitk::Image::New(); +if(m_Controls.NoiseCheckBox->isChecked()) +{ + typedef itk::Image ImageType; + + mitk::Image::Pointer tempImage = mitk::Image::New(); + tempImage->Initialize(generatedImage); + + mitk::ArbitraryTimeGeometry* timeGeometry = dynamic_cast (generatedImage->GetTimeGeometry()); + + tempImage->SetTimeGeometry(timeGeometry); + + ImageType::Pointer itkImage = ImageType::New(); + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(generatedImage); + + for(unsigned int i = 0; i< generatedImage->GetTimeSteps(); ++i) + { + imageTimeSelector->SetTimeNr(i); + imageTimeSelector->UpdateLargestPossibleRegion(); + + mitk::Image::Pointer mitkInputImage = imageTimeSelector->GetOutput(); + + mitk::CastToItkImage(mitkInputImage, itkImage ); + + typedef mitk::GaussianNoiseFunctor NoiseFunctorType; + typedef itk::UnaryFunctorImageFilter NoiseFilterType; + NoiseFilterType::Pointer noiseFilter = NoiseFilterType::New(); + NoiseFunctorType noiseFunctor; + noiseFunctor.SetMean(0.0); + noiseFunctor.SetSigma(this->m_Sigma); + noiseFilter->SetFunctor(noiseFunctor); + + noiseFilter->SetInput(itkImage); + + mitk::Image::Pointer outputImage = mitk::ImportItkImage(noiseFilter->GetOutput())->Clone(); + + mitk::ImageReadAccessor accessor(outputImage); + tempImage->SetVolume(accessor.GetData(), i); + } + + resultImage = tempImage->Clone(); +} +else +{ + resultImage = generatedImage; +} +return resultImage; +} + + +/** @todo #2 Synergie? Function implementation for every Model to complicated? + */ +mitk::Image::Pointer PerfusionDataSimulationView::GenerateNumeric2CXModelData() +{ +mitk::PerfusionDataGenerator::Pointer generator = mitk::PerfusionDataGenerator::New(); +mitk::NumericTwoCompartmentExchangeModelParameterizer::Pointer modelParameterizer = mitk::NumericTwoCompartmentExchangeModelParameterizer::New(); + +for(ParameterMapType::const_iterator pos = this->m_ParameterImageMap.begin(); pos != this->m_ParameterImageMap.end(); ++pos) +{ + if(pos->first == mitk::NumericTwoCompartmentExchangeModel::NAME_PARAMETER_F) + { + generator->SetParameterInputImage(mitk::NumericTwoCompartmentExchangeModel::POSITION_PARAMETER_F, pos->second); + } + if(pos->first == mitk::NumericTwoCompartmentExchangeModel::NAME_PARAMETER_PS) + { + generator->SetParameterInputImage(mitk::NumericTwoCompartmentExchangeModel::POSITION_PARAMETER_PS, pos->second); + } + if(pos->first == mitk::NumericTwoCompartmentExchangeModel::NAME_PARAMETER_ve) + { + generator->SetParameterInputImage(mitk::NumericTwoCompartmentExchangeModel::POSITION_PARAMETER_ve, pos->second); + } + if(pos->first == mitk::NumericTwoCompartmentExchangeModel::NAME_PARAMETER_vp) + { + generator->SetParameterInputImage(mitk::NumericTwoCompartmentExchangeModel::POSITION_PARAMETER_vp, pos->second); + } +} + +modelParameterizer->SetAIF(this->m_AterialInputFunction); +modelParameterizer->SetAIFTimeGrid(this->m_TimeGrid); +modelParameterizer->SetDefaultTimeGrid(this->m_TimeGrid); +modelParameterizer->SetODEINTStepSize(0.05); + +mitk::ModelDataGenerationFunctor::Pointer m_ComputationFunctor = mitk::ModelDataGenerationFunctor::New(); + +m_ComputationFunctor->SetModelParameterizer(modelParameterizer); + +generator->SetFunctor(m_ComputationFunctor); + +mitk::Image::Pointer generatedImage = generator->GetGeneratedImage(); + + +mitk::Image::Pointer resultImage = mitk::Image::New(); +if(m_Controls.NoiseCheckBox->isChecked()) +{ + typedef itk::Image ImageType; + + mitk::Image::Pointer tempImage = mitk::Image::New(); + tempImage->Initialize(generatedImage); + + mitk::ArbitraryTimeGeometry* timeGeometry = dynamic_cast (generatedImage->GetTimeGeometry()); + + tempImage->SetTimeGeometry(timeGeometry); + + ImageType::Pointer itkImage = ImageType::New(); + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(generatedImage); + + for(unsigned int i = 0; i< generatedImage->GetTimeSteps(); ++i) + { + imageTimeSelector->SetTimeNr(i); + imageTimeSelector->UpdateLargestPossibleRegion(); + + mitk::Image::Pointer mitkInputImage = imageTimeSelector->GetOutput(); + + mitk::CastToItkImage(mitkInputImage, itkImage ); + + typedef mitk::GaussianNoiseFunctor NoiseFunctorType; + typedef itk::UnaryFunctorImageFilter NoiseFilterType; + NoiseFilterType::Pointer noiseFilter = NoiseFilterType::New(); + NoiseFunctorType noiseFunctor; + noiseFunctor.SetMean(0.0); + noiseFunctor.SetSigma(this->m_Sigma); + noiseFilter->SetFunctor(noiseFunctor); + + noiseFilter->SetInput(itkImage); + + mitk::Image::Pointer outputImage = mitk::ImportItkImage(noiseFilter->GetOutput())->Clone(); + + mitk::ImageReadAccessor accessor(outputImage); + tempImage->SetVolume(accessor.GetData(), i); + } + + resultImage = tempImage->Clone(); +} +else +{ + resultImage = generatedImage; +} +return resultImage; +} + +mitk::Image::Pointer PerfusionDataSimulationView::GenerateETModelData() +{ +mitk::PerfusionDataGenerator::Pointer generator = mitk::PerfusionDataGenerator::New(); +mitk::ExtendedToftsModelParameterizer::Pointer modelParameterizer = mitk::ExtendedToftsModelParameterizer::New(); + +for(ParameterMapType::const_iterator pos = this->m_ParameterImageMap.begin(); pos != this->m_ParameterImageMap.end(); ++pos) +{ + if(pos->first == mitk::ExtendedToftsModel::NAME_PARAMETER_Ktrans) + { + generator->SetParameterInputImage(mitk::ExtendedToftsModel::POSITION_PARAMETER_Ktrans, pos->second); + } + if(pos->first == mitk::ExtendedToftsModel::NAME_PARAMETER_vp) + { + generator->SetParameterInputImage(mitk::ExtendedToftsModel::POSITION_PARAMETER_vp, pos->second); + } + if(pos->first == mitk::ExtendedToftsModel::NAME_PARAMETER_ve) + { + generator->SetParameterInputImage(mitk::ExtendedToftsModel::POSITION_PARAMETER_ve, pos->second); + } + +} + +modelParameterizer->SetAIF(this->m_AterialInputFunction); +modelParameterizer->SetAIFTimeGrid(this->m_TimeGrid); +modelParameterizer->SetDefaultTimeGrid(this->m_TimeGrid); + +mitk::ModelDataGenerationFunctor::Pointer m_ComputationFunctor = mitk::ModelDataGenerationFunctor::New(); + +m_ComputationFunctor->SetModelParameterizer(modelParameterizer); + +generator->SetFunctor(m_ComputationFunctor); + +mitk::Image::Pointer generatedImage = generator->GetGeneratedImage(); + + +mitk::Image::Pointer resultImage = mitk::Image::New(); +if(m_Controls.NoiseCheckBox->isChecked()) +{ + typedef itk::Image ImageType; + + mitk::Image::Pointer tempImage = mitk::Image::New(); + tempImage->Initialize(generatedImage); + + mitk::ArbitraryTimeGeometry* timeGeometry = dynamic_cast (generatedImage->GetTimeGeometry()); + + tempImage->SetTimeGeometry(timeGeometry); + + ImageType::Pointer itkImage = ImageType::New(); + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(generatedImage); + + for(unsigned int i = 0; i< generatedImage->GetTimeSteps(); ++i) + { + imageTimeSelector->SetTimeNr(i); + imageTimeSelector->UpdateLargestPossibleRegion(); + + mitk::Image::Pointer mitkInputImage = imageTimeSelector->GetOutput(); + + mitk::CastToItkImage(mitkInputImage, itkImage ); + + typedef mitk::GaussianNoiseFunctor NoiseFunctorType; + typedef itk::UnaryFunctorImageFilter NoiseFilterType; + NoiseFilterType::Pointer noiseFilter = NoiseFilterType::New(); + NoiseFunctorType noiseFunctor; + noiseFunctor.SetMean(0.0); + noiseFunctor.SetSigma(this->m_Sigma); + noiseFilter->SetFunctor(noiseFunctor); + + noiseFilter->SetInput(itkImage); + + mitk::Image::Pointer outputImage = mitk::ImportItkImage(noiseFilter->GetOutput())->Clone(); + + mitk::ImageReadAccessor accessor(outputImage); + tempImage->SetVolume(accessor.GetData(), i); + } + + resultImage = tempImage->Clone(); +} +else +{ + resultImage = generatedImage; +} +return resultImage; +} + + +mitk::Image::Pointer PerfusionDataSimulationView::Generate2TCModelData() +{ +mitk::PerfusionDataGenerator::Pointer generator = mitk::PerfusionDataGenerator::New(); +mitk::TwoTissueCompartmentModelParameterizer::Pointer modelParameterizer = mitk::TwoTissueCompartmentModelParameterizer::New(); + + +for(ParameterMapType::const_iterator pos = this->m_ParameterImageMap.begin(); pos != this->m_ParameterImageMap.end(); ++pos) +{ + if(pos->first == mitk::TwoTissueCompartmentModel::NAME_PARAMETER_K1) + { + generator->SetParameterInputImage(mitk::TwoTissueCompartmentModel::POSITION_PARAMETER_K1, pos->second); + } + if(pos->first == mitk::TwoTissueCompartmentModel::NAME_PARAMETER_k2) + { + generator->SetParameterInputImage(mitk::TwoTissueCompartmentModel::POSITION_PARAMETER_k2, pos->second); + } + if(pos->first == mitk::TwoTissueCompartmentModel::NAME_PARAMETER_k3) + { + generator->SetParameterInputImage(mitk::TwoTissueCompartmentModel::POSITION_PARAMETER_k3, pos->second); + } + if(pos->first == mitk::TwoTissueCompartmentModel::NAME_PARAMETER_k4) + { + generator->SetParameterInputImage(mitk::TwoTissueCompartmentModel::POSITION_PARAMETER_k4, pos->second); + } + if(pos->first == mitk::TwoTissueCompartmentModel::NAME_PARAMETER_VB) + { + generator->SetParameterInputImage(mitk::TwoTissueCompartmentModel::POSITION_PARAMETER_VB, pos->second); + } + +} + +modelParameterizer->SetAIF(this->m_AterialInputFunction); +modelParameterizer->SetAIFTimeGrid(this->m_TimeGrid); +modelParameterizer->SetDefaultTimeGrid(this->m_TimeGrid); + +mitk::ModelDataGenerationFunctor::Pointer m_ComputationFunctor = mitk::ModelDataGenerationFunctor::New(); + +m_ComputationFunctor->SetModelParameterizer(modelParameterizer); + +generator->SetFunctor(m_ComputationFunctor); + +mitk::Image::Pointer generatedImage = generator->GetGeneratedImage(); + + mitk::Image::Pointer resultImage = mitk::Image::New(); +if(m_Controls.NoiseCheckBox->isChecked()) +{ + typedef itk::Image ImageType; + + mitk::Image::Pointer tempImage = mitk::Image::New(); + tempImage->Initialize(generatedImage); + + mitk::ArbitraryTimeGeometry* timeGeometry = dynamic_cast (generatedImage->GetTimeGeometry()); + + tempImage->SetTimeGeometry(timeGeometry); + + ImageType::Pointer itkImage = ImageType::New(); + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(generatedImage); + + for(unsigned int i = 0; i< generatedImage->GetTimeSteps(); ++i) + { + imageTimeSelector->SetTimeNr(i); + imageTimeSelector->UpdateLargestPossibleRegion(); + + mitk::Image::Pointer mitkInputImage = imageTimeSelector->GetOutput(); + + mitk::CastToItkImage(mitkInputImage, itkImage ); + + typedef mitk::GaussianNoiseFunctor NoiseFunctorType; + typedef itk::UnaryFunctorImageFilter NoiseFilterType; + NoiseFilterType::Pointer noiseFilter = NoiseFilterType::New(); + NoiseFunctorType noiseFunctor; + noiseFunctor.SetMean(0.0); + noiseFunctor.SetSigma(this->m_Sigma); + noiseFilter->SetFunctor(noiseFunctor); + + noiseFilter->SetInput(itkImage); + + mitk::Image::Pointer outputImage = mitk::ImportItkImage(noiseFilter->GetOutput())->Clone(); + + mitk::ImageReadAccessor accessor(outputImage); + tempImage->SetVolume(accessor.GetData(), i); + } + + resultImage = tempImage->Clone(); +} +else +{ + resultImage = generatedImage; +} +return resultImage; +} + + +mitk::Image::Pointer PerfusionDataSimulationView::Generate1TCModelData() +{ +mitk::PerfusionDataGenerator::Pointer generator = mitk::PerfusionDataGenerator::New(); +mitk::OneTissueCompartmentModelParameterizer::Pointer modelParameterizer = mitk::OneTissueCompartmentModelParameterizer::New(); + + +for(ParameterMapType::const_iterator pos = this->m_ParameterImageMap.begin(); pos != this->m_ParameterImageMap.end(); ++pos) +{ + if(pos->first == mitk::OneTissueCompartmentModel::NAME_PARAMETER_k1) + { + generator->SetParameterInputImage(mitk::OneTissueCompartmentModel::POSITION_PARAMETER_k1, pos->second); + } + if(pos->first == mitk::OneTissueCompartmentModel::NAME_PARAMETER_k2) + { + generator->SetParameterInputImage(mitk::OneTissueCompartmentModel::POSITION_PARAMETER_k2, pos->second); + } + +} + +modelParameterizer->SetAIF(this->m_AterialInputFunction); +modelParameterizer->SetAIFTimeGrid(this->m_TimeGrid); +modelParameterizer->SetDefaultTimeGrid(this->m_TimeGrid); + +mitk::ModelDataGenerationFunctor::Pointer m_ComputationFunctor = mitk::ModelDataGenerationFunctor::New(); + +m_ComputationFunctor->SetModelParameterizer(modelParameterizer); + +generator->SetFunctor(m_ComputationFunctor); + +mitk::Image::Pointer generatedImage = generator->GetGeneratedImage(); + + mitk::Image::Pointer resultImage = mitk::Image::New(); +if(m_Controls.NoiseCheckBox->isChecked()) +{ + typedef itk::Image ImageType; + + mitk::Image::Pointer tempImage = mitk::Image::New(); + tempImage->Initialize(generatedImage); + + mitk::ArbitraryTimeGeometry* timeGeometry = dynamic_cast (generatedImage->GetTimeGeometry()); + + tempImage->SetTimeGeometry(timeGeometry); + + ImageType::Pointer itkImage = ImageType::New(); + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(generatedImage); + + for(unsigned int i = 0; i< generatedImage->GetTimeSteps(); ++i) + { + imageTimeSelector->SetTimeNr(i); + imageTimeSelector->UpdateLargestPossibleRegion(); + + mitk::Image::Pointer mitkInputImage = imageTimeSelector->GetOutput(); + + mitk::CastToItkImage(mitkInputImage, itkImage ); + + typedef mitk::GaussianNoiseFunctor NoiseFunctorType; + typedef itk::UnaryFunctorImageFilter NoiseFilterType; + NoiseFilterType::Pointer noiseFilter = NoiseFilterType::New(); + NoiseFunctorType noiseFunctor; + noiseFunctor.SetMean(0.0); + noiseFunctor.SetSigma(this->m_Sigma); + noiseFilter->SetFunctor(noiseFunctor); + + noiseFilter->SetInput(itkImage); + + mitk::Image::Pointer outputImage = mitk::ImportItkImage(noiseFilter->GetOutput())->Clone(); + + mitk::ImageReadAccessor accessor(outputImage); + tempImage->SetVolume(accessor.GetData(), i); + } + + resultImage = tempImage->Clone(); +} +else +{ + resultImage = generatedImage; +} +return resultImage; +} + + +PerfusionDataSimulationView::PerfusionDataSimulationView() +{ + m_Sigma = 0; + m_CNR=0; + m_MaxConcentration=0; + m_selectedModelFactory = NULL; + + + mitk::ModelFactoryBase::Pointer factory = mitk::ExtendedToftsModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + factory = mitk::TwoCompartmentExchangeModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + factory = mitk::NumericTwoCompartmentExchangeModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + factory = mitk::TwoTissueCompartmentModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + factory = mitk::OneTissueCompartmentModelFactory::New().GetPointer(); + m_FactoryStack.push_back(factory); + + + + m_IsNotABinaryImagePredicate = mitk::NodePredicateAnd::New( + mitk::TNodePredicateDataType::New(), + mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true))), + mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))).GetPointer(); + +} diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/PerfusionDataSimulationView.h b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/PerfusionDataSimulationView.h new file mode 100644 index 0000000000..3c90e4fd22 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/PerfusionDataSimulationView.h @@ -0,0 +1,133 @@ +/*=================================================================== + +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 PerfusionDataSimulationView_h +#define PerfusionDataSimulationView_h + +#include + +#include +#include "ui_PerfusionDataSimulationViewControls.h" +#include "mitkModelBase.h" +#include + +#include "itkArray.h" +#include "mitkImage.h" + + +#include + + +/*! + * @brief Test Plugin for SUV calculations of PET images + */ +class PerfusionDataSimulationView : public QmitkAbstractView +{ + Q_OBJECT + +public: + + /*! @brief The view's unique ID - required by MITK */ + static const std::string VIEW_ID; + + PerfusionDataSimulationView(); + +protected slots: + + /*! + * @brief Is triggered of the update button is clicked and the selected node should get the (new) iso level set. + */ + void OnGenerateDataButtonClicked(); + void LoadAIFFile(); + void OnModellSet(int); + + void OnSimulationConfigurationChanged(); + + void UpdateDataSelection(); + + +protected: + typedef std::map ParameterMapType; + + // Overridden base class functions + + /*! + * @brief Sets up the UI controls and connects the slots and signals. Gets + * called by the framework to create the GUI at the right time. + * @param[in,out] parent The parent QWidget, as this class itself is not a QWidget + * subclass. + */ + void CreateQtPartControl(QWidget* parent); + + /*! + * @brief Sets the focus to the plot curve button. Gets called by the framework to set the + * focus on the right widget. + */ + void SetFocus(); + + + void InitModelComboBox() const; + + + mitk::Image::Pointer Generate2CXModelData(); + mitk::Image::Pointer GenerateNumeric2CXModelData(); + mitk::Image::Pointer GenerateETModelData(); + void FillParameterMap2CXM(); + void FillParameterMapNumeric2CXM(); + void FillParameterMapETM(); + + + + ///////////////////// dynamic PET Models/////////////// + mitk::Image::Pointer Generate2TCModelData(); + mitk::Image::Pointer Generate1TCModelData(); + void FillParameterMap2TCM(); + void FillParameterMap1TCM(); + + + bool CheckModelSettings(); + + + /*! \brief called by QmitkFunctionality when DataManager's selection has changed + */ +// virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer source, +// const QList& selectedNodes); + + + // Variables + + /*! @brief The view's UI controls */ + Ui::PerfusionDataSimulationViewControls m_Controls; + mitk::DataNode::Pointer m_selectedNode; + + ParameterMapType m_ParameterImageMap; + itk::Array m_AterialInputFunction; + itk::Array m_TimeGrid; + + mitk::ModelFactoryBase::Pointer m_selectedModelFactory; + + +private: + + typedef std::vector ModelFactoryStackType; + ModelFactoryStackType m_FactoryStack; + mitk::NodePredicateBase::Pointer m_IsNotABinaryImagePredicate; + + double m_CNR, m_MaxConcentration, m_Sigma; + +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/PerfusionDataSimulationViewControls.ui b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/PerfusionDataSimulationViewControls.ui new file mode 100644 index 0000000000..7936e1fdf5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/PerfusionDataSimulationViewControls.ui @@ -0,0 +1,346 @@ + + + PerfusionDataSimulationViewControls + + + + 0 + 0 + 555 + 1037 + + + + + 0 + 0 + + + + QmitkTemplate + + + + + + + + + + Message: + + + + + + + TextLabel + + + + + + + + + Model + + + + + + Select a Model for Data Generation: + + + + + + + + + + + + + Aterial Input Function + + + + + + + + + Browse + + + + + + + Select AIF & Time Grid File + + + + + + + + + + Parameter Images + + + + + + 2 Compartment Exchange Model: + + + + + + vi + + + + + + + vp + + + + + + + F + + + + + + + PS + + + + + + + + + + + + + + + + + + + + + + Extended Tofts Model: + + + + + + ve + + + + + + + vp + + + + + + + KTrans + + + + + + + + + + + + + + + + + + + 2 Tissue Compartment Model + + + + + + K1 + + + + + + + + + + k2 + + + + + + + k4 + + + + + + + k3 + + + + + + + VB + + + + + + + + + + + + + + + + + + + + + + 1 Tissue Compartment Model + + + + + + k1 + + + + + + + + + + k2 + + + + + + + + + + + + + + + + Noise Settings + + + + + + Use Noise? + + + + + + + + + + + + + Contrast-To-Noise Ratio + + + + + + + 1000.000000000000000 + + + + + + + + + + + + + Generate Data + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + QmitkDataStorageComboBox + QComboBox +
QmitkDataStorageComboBox.h
+
+
+ + +
diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/org_mitk_PerfusionDataSimulationView_Activator.cpp b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/org_mitk_PerfusionDataSimulationView_Activator.cpp new file mode 100644 index 0000000000..2fa919c8ee --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/org_mitk_PerfusionDataSimulationView_Activator.cpp @@ -0,0 +1,31 @@ +/*=================================================================== + +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 "org_mitk_PerfusionDataSimulationView_Activator.h" + +#include + +#include "PerfusionDataSimulationView.h" + + void org_mitk_PerfusionDataSimulationView_Activator::start(ctkPluginContext* context) + { + BERRY_REGISTER_EXTENSION_CLASS(PerfusionDataSimulationView, context); + } + + void org_mitk_PerfusionDataSimulationView_Activator::stop(ctkPluginContext* context) + { + Q_UNUSED(context); + } diff --git a/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/org_mitk_PerfusionDataSimulationView_Activator.h b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/org_mitk_PerfusionDataSimulationView_Activator.h new file mode 100644 index 0000000000..faa534d6db --- /dev/null +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/org_mitk_PerfusionDataSimulationView_Activator.h @@ -0,0 +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. + +===================================================================*/ + +#ifndef org_mitk_PerfusionDataSimulationView_Activator_h +#define org_mitk_PerfusionDataSimulationView_Activator_h + +#include + + class org_mitk_PerfusionDataSimulationView_Activator : public QObject, public ctkPluginActivator + { + Q_OBJECT + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_pharmacokinetics_simulation") + Q_INTERFACES(ctkPluginActivator) + + public: + + /*! + * @brief Registers the plug-in. Gets called by the framework when the plug-in is + * first loaded. + * @param context The corresponding CTK plug-in context in which the plug-in is loaded. + */ + void start(ctkPluginContext* context); + + /*! + * @brief Deregisters the plug-in. Gets called by the framework when the plug-in + * is unloaded. + * @param context The corresponding CTK plug-in context in which the plug-in was loaded. + */ + void stop(ctkPluginContext* context); + }; + +#endif