diff --git a/Modules/Pharmacokinetics/autoload/Models/mitkPharmacokineticModelsActivator.cpp b/Modules/Pharmacokinetics/autoload/Models/mitkPharmacokineticModelsActivator.cpp index b3c4088926..f406aa87b1 100644 --- a/Modules/Pharmacokinetics/autoload/Models/mitkPharmacokineticModelsActivator.cpp +++ b/Modules/Pharmacokinetics/autoload/Models/mitkPharmacokineticModelsActivator.cpp @@ -1,77 +1,73 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include #include #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" 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)); } 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); } void Unload(us::ModuleContext* ) override { } private: std::vector > m_RegisteredProviders; }; } US_EXPORT_MODULE_ACTIVATOR(mitk::PharmacokineticModelsActivator) diff --git a/Modules/Pharmacokinetics/files.cmake b/Modules/Pharmacokinetics/files.cmake index 6af6b8dd1c..48ead4c7e1 100644 --- a/Modules/Pharmacokinetics/files.cmake +++ b/Modules/Pharmacokinetics/files.cmake @@ -1,61 +1,55 @@ 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/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/mitkImageGenerationHelper.cpp ) set(HXX_FILES mitkDICOMSegmentationConstants.h ) set(MOC_H_FILES ) diff --git a/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModel.h b/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModel.h deleted file mode 100644 index b8bcc20432..0000000000 --- a/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModel.h +++ /dev/null @@ -1,128 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#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; - - std::string GetModelDisplayName() const override; - - std::string GetModelType() const override; - - itkGetConstReferenceMacro(ODEINTStepSize, double); - itkSetMacro(ODEINTStepSize, double); - - - ParameterNamesType GetParameterNames() const override; - ParametersSizeType GetNumberOfParameters() const override; - - ParamterUnitMapType GetParameterUnits() const override; - - ParameterNamesType GetStaticParameterNames() const override; - ParametersSizeType GetNumberOfStaticParameters() const override; - - - protected: - NumericTwoCompartmentExchangeModel(); - ~NumericTwoCompartmentExchangeModel() override; - - /** - * Actual implementation of the clone method. This method should be reimplemeted - * in subclasses to clone the extra required parameters. - */ - itk::LightObject::Pointer InternalClone() const override; - - ModelResultType ComputeModelfunction(const ParametersType& parameters) const override; - - void SetStaticParameter(const ParameterNameType& name, const StaticParameterValuesType& values) override; - StaticParameterValuesType GetStaticParameterValue(const ParameterNameType& name) const override; - - void PrintSelf(std::ostream& os, ::itk::Indent indent) const override; - - private: - - - - //No copy constructor allowed - NumericTwoCompartmentExchangeModel(const Self& source); - void operator=(const Self&); //purposely not implemented - - double m_ODEINTStepSize; - - - - }; -} - -#endif diff --git a/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModelFactory.h b/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModelFactory.h deleted file mode 100644 index f94e55ef59..0000000000 --- a/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModelFactory.h +++ /dev/null @@ -1,46 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#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 override; - - NumericTwoCompartmentExchangeModelFactory(); - - ~NumericTwoCompartmentExchangeModelFactory() override; - - private: - - //No copy constructor allowed - NumericTwoCompartmentExchangeModelFactory(const Self& source); - void operator=(const Self&); //purposely not implemented - - }; - -} -#endif diff --git a/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModelParameterizer.h b/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModelParameterizer.h deleted file mode 100644 index 076952c6c3..0000000000 --- a/Modules/Pharmacokinetics/include/mitkNumericTwoCompartmentExchangeModelParameterizer.h +++ /dev/null @@ -1,77 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef mitkNumericTwoCompartmentExchangeModelParameterizer_h -#define mitkNumericTwoCompartmentExchangeModelParameterizer_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.*/ - StaticParameterMapType GetGlobalStaticParameters() const override; - - - /** This function returns the default parameterization (e.g. initial parametrization for fitting) - defined by the model developer for for the given model.*/ - ParametersType GetDefaultInitialParameterization() const override; - - protected: - - double m_ODEINTStepSize; - - NumericTwoCompartmentExchangeModelParameterizer(); - - ~NumericTwoCompartmentExchangeModelParameterizer() override; - - 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 deleted file mode 100644 index 74181746b5..0000000000 --- a/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModel.h +++ /dev/null @@ -1,103 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#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; - - static const unsigned int NUMBER_OF_DERIVED_PARAMETERS; - - static const std::string MODEL_TYPE; - - - std::string GetModelDisplayName() const override; - - std::string GetModelType() const override; - - ParameterNamesType GetParameterNames() const override; - ParametersSizeType GetNumberOfParameters() const override; - ParametersSizeType GetNumberOfDerivedParameters() const override; - - ParamterUnitMapType GetParameterUnits() const override; - - protected: - NumericTwoTissueCompartmentModel(); - ~NumericTwoTissueCompartmentModel() override; - - /** - * Actual implementation of the clone method. This method should be reimplemeted - * in subclasses to clone the extra required parameters. - */ - itk::LightObject::Pointer InternalClone() const override; - - ModelResultType ComputeModelfunction(const ParametersType& parameters) const override; - - void PrintSelf(std::ostream& os, ::itk::Indent indent) const override; - - private: - - - //No copy constructor allowed - NumericTwoTissueCompartmentModel(const Self& source); - void operator=(const Self&); //purposely not implemented - - }; -} - -#endif diff --git a/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModelFactory.h b/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModelFactory.h deleted file mode 100644 index 6157d8b36a..0000000000 --- a/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModelFactory.h +++ /dev/null @@ -1,48 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#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(); - - ~NumericTwoTissueCompartmentModelFactory() override; - - private: - - //No copy constructor allowed - NumericTwoTissueCompartmentModelFactory(const Self& source); - void operator=(const Self&); //purposely not implemented - - }; - -} - - -#endif diff --git a/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModelParameterizer.h b/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModelParameterizer.h deleted file mode 100644 index 07f71e2720..0000000000 --- a/Modules/Pharmacokinetics/include/mitkNumericTwoTissueCompartmentModelParameterizer.h +++ /dev/null @@ -1,65 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#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.*/ - ParametersType GetDefaultInitialParameterization() const override; - - protected: - NumericTwoTissueCompartmentModelParameterizer(); - - ~NumericTwoTissueCompartmentModelParameterizer() override; - - private: - - //No copy constructor allowed - NumericTwoTissueCompartmentModelParameterizer(const Self& source); - void operator=(const Self&); //purposely not implemented - }; -} -#endif diff --git a/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModelDifferentialEquations.h b/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModelDifferentialEquations.h deleted file mode 100644 index f9e4b461fa..0000000000 --- a/Modules/Pharmacokinetics/include/mitkTwoCompartmentExchangeModelDifferentialEquations.h +++ /dev/null @@ -1,114 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#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 diff --git a/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModelDifferentialEquations.h b/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModelDifferentialEquations.h deleted file mode 100644 index b892bef899..0000000000 --- a/Modules/Pharmacokinetics/include/mitkTwoTissueCompartmentModelDifferentialEquations.h +++ /dev/null @@ -1,114 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#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 diff --git a/Modules/Pharmacokinetics/src/Models/mitkNumericTwoCompartmentExchangeModel.cpp b/Modules/Pharmacokinetics/src/Models/mitkNumericTwoCompartmentExchangeModel.cpp deleted file mode 100644 index 2d95cd5e57..0000000000 --- a/Modules/Pharmacokinetics/src/Models/mitkNumericTwoCompartmentExchangeModel.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "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 deleted file mode 100644 index ef04fa136a..0000000000 --- a/Modules/Pharmacokinetics/src/Models/mitkNumericTwoCompartmentExchangeModelFactory.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "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 deleted file mode 100644 index 25910af578..0000000000 --- a/Modules/Pharmacokinetics/src/Models/mitkNumericTwoCompartmentExchangeModelParameterizer.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "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 deleted file mode 100644 index 4807a457ff..0000000000 --- a/Modules/Pharmacokinetics/src/Models/mitkNumericTwoTissueCompartmentModel.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "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 = "K_1"; -const std::string mitk::NumericTwoTissueCompartmentModel::NAME_PARAMETER_k2 = "k_2"; -const std::string mitk::NumericTwoTissueCompartmentModel::NAME_PARAMETER_k3 = "k_3"; -const std::string mitk::NumericTwoTissueCompartmentModel::NAME_PARAMETER_k4 = "k_4"; -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; - -const unsigned int mitk::NumericTwoTissueCompartmentModel::NUMBER_OF_DERIVED_PARAMETERS = 0; - -const std::string mitk::NumericTwoTissueCompartmentModel::MODEL_TYPE = "Dynamic.PET"; - -std::string mitk::NumericTwoTissueCompartmentModel::GetModelDisplayName() const -{ - return MODEL_DISPLAY_NAME; -}; - -std::string mitk::NumericTwoTissueCompartmentModel::GetModelType() const -{ - return MODEL_TYPE; -}; - -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::ParametersSizeType -mitk::NumericTwoTissueCompartmentModel::GetNumberOfDerivedParameters() const -{ - return NUMBER_OF_DERIVED_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 deleted file mode 100644 index d00b9d3370..0000000000 --- a/Modules/Pharmacokinetics/src/Models/mitkNumericTwoTissueCompartmentModelFactory.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "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 deleted file mode 100644 index a1c6b1de07..0000000000 --- a/Modules/Pharmacokinetics/src/Models/mitkNumericTwoTissueCompartmentModelParameterizer.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "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() -{ -}; 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 index 66ab43fe57..95b4584c78 100644 --- a/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/MRPerfusionView.cpp +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.mri/src/internal/MRPerfusionView.cpp @@ -1,1409 +1,1362 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "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 #include #include #include #include "mitkTwoCompartmentExchangeModelFactory.h" #include "mitkTwoCompartmentExchangeModelParameterizer.h" -#include "mitkNumericTwoCompartmentExchangeModelFactory.h" -#include "mitkNumericTwoCompartmentExchangeModelParameterizer.h" #include #include #include #include #include #include #include #include "mitkNodePredicateFunction.h" #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.views.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); this->InitModelComboBox(); m_Controls.timeSeriesNodeSelector->SetNodePredicate(this->m_isValidTimeSeriesImagePredicate); m_Controls.timeSeriesNodeSelector->SetDataStorage(this->GetDataStorage()); m_Controls.timeSeriesNodeSelector->SetSelectionIsOptional(false); m_Controls.timeSeriesNodeSelector->SetInvalidInfo("Please select time series."); m_Controls.timeSeriesNodeSelector->SetAutoSelectNewNodes(true); m_Controls.maskNodeSelector->SetNodePredicate(this->m_IsMaskPredicate); m_Controls.maskNodeSelector->SetDataStorage(this->GetDataStorage()); m_Controls.maskNodeSelector->SetSelectionIsOptional(true); m_Controls.maskNodeSelector->SetEmptyInfo("Please select (optional) mask."); 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())); connect(m_Controls.timeSeriesNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &MRPerfusionView::OnNodeSelectionChanged); connect(m_Controls.maskNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &MRPerfusionView::OnNodeSelectionChanged); connect(m_Controls.AIFMaskNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &MRPerfusionView::UpdateGUIControls); connect(m_Controls.AIFImageNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &MRPerfusionView::UpdateGUIControls); //AIF setting m_Controls.groupAIF->hide(); m_Controls.btnAIFFile->setEnabled(false); m_Controls.btnAIFFile->setEnabled(false); m_Controls.radioAIFImage->setChecked(true); m_Controls.AIFMaskNodeSelector->SetDataStorage(this->GetDataStorage()); m_Controls.AIFMaskNodeSelector->SetNodePredicate(m_IsMaskPredicate); m_Controls.AIFMaskNodeSelector->setVisible(true); m_Controls.AIFMaskNodeSelector->setEnabled(true); m_Controls.AIFMaskNodeSelector->SetAutoSelectNewNodes(true); m_Controls.AIFImageNodeSelector->SetDataStorage(this->GetDataStorage()); m_Controls.AIFImageNodeSelector->SetNodePredicate(this->m_isValidTimeSeriesImagePredicate); m_Controls.AIFImageNodeSelector->setEnabled(false); m_Controls.checkDedicatedAIFImage->setEnabled(true); m_Controls.HCLSpinBox->setValue(mitk::AterialInputFunctionGenerator::DEFAULT_HEMATOCRIT_LEVEL); m_Controls.spinBox_baselineEndTimeStep->setMinimum(0); m_Controls.spinBox_baselineStartTimeStep->setMinimum(0); connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.AIFMaskNodeSelector, 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.AIFMaskNodeSelector, 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.AIFImageNodeSelector, SLOT(setVisible(bool))); connect(m_Controls.checkDedicatedAIFImage, SIGNAL(toggled(bool)), m_Controls.AIFImageNodeSelector, 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.groupBoxEnhancement->hide(); m_Controls.groupBoxTurboFlash->hide(); m_Controls.radioButtonNoConversion->setChecked(true); m_Controls.groupBox_T1MapviaVFA->hide(); m_Controls.spinBox_baselineStartTimeStep->setValue(0); m_Controls.spinBox_baselineEndTimeStep->setValue(0); 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.groupBoxEnhancement, SLOT(setVisible(bool))); connect(m_Controls.radioButton_relativeEnchancement, SIGNAL(toggled(bool)), m_Controls.groupBoxEnhancement, SLOT(setVisible(bool))); connect(m_Controls.factorSpinBox, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); connect(m_Controls.spinBox_baselineStartTimeStep, SIGNAL(valueChanged(int)), this, SLOT(UpdateGUIControls())); connect(m_Controls.spinBox_baselineEndTimeStep, SIGNAL(valueChanged(int)), this, SLOT(UpdateGUIControls())); connect(m_Controls.radioButtonUsingT1viaVFA, SIGNAL(toggled(bool)), m_Controls.groupBox_T1MapviaVFA, SLOT(setVisible(bool))); connect(m_Controls.radioButtonUsingT1viaVFA, 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.PDWImageNodeSelector->SetNodePredicate(m_isValidPDWImagePredicate); m_Controls.PDWImageNodeSelector->SetDataStorage(this->GetDataStorage()); m_Controls.PDWImageNodeSelector->SetInvalidInfo("Please select PDW Image."); m_Controls.PDWImageNodeSelector->setEnabled(false); connect(m_Controls.radioButtonUsingT1viaVFA, SIGNAL(toggled(bool)), m_Controls.PDWImageNodeSelector, 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()) != nullptr; bool isToftsFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr || dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; bool is2CXMFactory = dynamic_cast - (m_selectedModelFactory.GetPointer()) != nullptr || - dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; - bool isNum2CXMFactory = dynamic_cast - (m_selectedModelFactory.GetPointer()) != nullptr; 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()); m_Controls.spinBox_baselineStartTimeStep->setEnabled(m_Controls.radioButtonTurboFlash->isChecked() || m_Controls.radioButton_absoluteEnhancement->isChecked() || m_Controls.radioButton_relativeEnchancement->isChecked() || m_Controls.radioButtonUsingT1viaVFA->isChecked()); m_Controls.spinBox_baselineEndTimeStep->setEnabled(m_Controls.radioButton_absoluteEnhancement->isChecked() || m_Controls.radioButton_relativeEnchancement->isChecked() || m_Controls.radioButtonUsingT1viaVFA->isChecked() || m_Controls.radioButtonTurboFlash->isChecked()); } void MRPerfusionView::OnModellSet(int index) { m_selectedModelFactory = nullptr; 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::GetFitName() const { std::string fitName = m_Controls.lineFitName->text().toStdString(); if (fitName.empty()) { fitName = m_Controls.lineFitName->placeholderText().toStdString(); } return fitName; } 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()) { m_HasGeneratedNewInput = false; m_HasGeneratedNewInputAIF = false; mitk::ParameterFitImageGeneratorBase::Pointer generator = nullptr; mitk::modelFit::ModelFitInfo::Pointer fitSession = nullptr; bool isDescBrixFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; bool isExtToftsFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; bool isStanToftsFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; bool is2CXMFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; - bool isNum2CXMFactory = dynamic_cast - (m_selectedModelFactory.GetPointer()) != nullptr; if (isDescBrixFactory) { if (this->m_Controls.radioPixelBased->isChecked()) { GenerateDescriptiveBrixModel_PixelBased(fitSession, generator); } else { GenerateDescriptiveBrixModel_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::OnNodeSelectionChanged(QList/*nodes*/) { m_selectedMaskNode = nullptr; m_selectedMask = nullptr; if (m_Controls.timeSeriesNodeSelector->GetSelectedNode().IsNotNull()) { this->m_selectedNode = m_Controls.timeSeriesNodeSelector->GetSelectedNode(); m_selectedImage = dynamic_cast(m_selectedNode->GetData()); if (m_selectedImage) { this->m_Controls.initialValuesManager->setReferenceImageGeometry(m_selectedImage->GetGeometry()); } else { this->m_Controls.initialValuesManager->setReferenceImageGeometry(nullptr); } } else { this->m_selectedNode = nullptr; this->m_selectedImage = nullptr; this->m_Controls.initialValuesManager->setReferenceImageGeometry(nullptr); } if (m_Controls.maskNodeSelector->GetSelectedNode().IsNotNull()) { this->m_selectedMaskNode = m_Controls.maskNodeSelector->GetSelectedNode(); this->m_selectedMask = dynamic_cast(m_selectedMaskNode->GetData()); if (this->m_selectedMask.IsNotNull() && this->m_selectedMask->GetTimeSteps() > 1) { MITK_INFO << "Selected mask has multiple timesteps. Only use first timestep to mask model fit. Mask name: " << m_Controls.maskNodeSelector->GetSelectedNode()->GetName(); mitk::ImageTimeSelector::Pointer maskedImageTimeSelector = mitk::ImageTimeSelector::New(); maskedImageTimeSelector->SetInput(this->m_selectedMask); maskedImageTimeSelector->SetTimeNr(0); maskedImageTimeSelector->UpdateLargestPossibleRegion(); this->m_selectedMask = maskedImageTimeSelector->GetOutput(); } } if (m_selectedMask.IsNull()) { this->m_Controls.radioPixelBased->setChecked(true); } if (this->m_selectedImage.IsNotNull()) { m_Controls.spinBox_baselineStartTimeStep->setMaximum((this->m_selectedImage->GetDimension(3))-1); m_Controls.spinBox_baselineEndTimeStep->setMaximum((this->m_selectedImage->GetDimension(3)) - 1); } UpdateGUIControls(); } bool MRPerfusionView::CheckModelSettings() const { bool ok = true; //check whether any model is set at all. Otherwise exit with false if (m_selectedModelFactory.IsNotNull()) { bool isDescBrixFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; bool isToftsFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr|| dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; bool is2CXMFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; - bool isNum2CXMFactory = dynamic_cast - (m_selectedModelFactory.GetPointer()) != nullptr; 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 (isToftsFactory || is2CXMFactory || isNum2CXMFactory) + else if (isToftsFactory || is2CXMFactory) { if (this->m_Controls.radioAIFImage->isChecked()) { ok = ok && m_Controls.AIFMaskNodeSelector->GetSelectedNode().IsNotNull(); if (this->m_Controls.checkDedicatedAIFImage->isChecked()) { ok = ok && m_Controls.AIFImageNodeSelector->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); ok = ok && CheckBaselineSelectionSettings(); } else if (this->m_Controls.radioButton_absoluteEnhancement->isChecked() || this->m_Controls.radioButton_relativeEnchancement->isChecked() ) { ok = ok && (m_Controls.factorSpinBox->value() > 0); ok = ok && CheckBaselineSelectionSettings(); } else if (this->m_Controls.radioButtonUsingT1viaVFA->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.PDWImageNodeSelector->GetSelectedNode().IsNotNull()); ok = ok && CheckBaselineSelectionSettings(); } else if (this->m_Controls.radioButtonNoConversion->isChecked()) { ok = ok && true; } else { ok = false; } - if (isNum2CXMFactory) - { - ok = ok && (this->m_Controls.odeStepSize->value() > 0); - } - } //add other models as else if and check whether 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; } bool MRPerfusionView::CheckBaselineSelectionSettings() const { return m_Controls.spinBox_baselineStartTimeStep->value() <= m_Controls.spinBox_baselineEndTimeStep->value(); } 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 = m_selectedMask->GetUID(); } 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(), this->GetFitName(), 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 = this->m_selectedMask->GetUID(); //Create model info modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, m_selectedNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_ROIBASED(), this->GetFitName(), 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::GenerateLinearModelFit_PixelBased(mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, mitk::ParameterFitImageGeneratorBase::Pointer& generator) { mitk::PixelBasedParameterFitImageGenerator::Pointer fitGenerator = mitk::PixelBasedParameterFitImageGenerator::New(); typename TParameterizer::Pointer modelParameterizer = TParameterizer::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 = this->m_selectedMask->GetUID(); } 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(), this->GetFitName(), roiUID); } template void MRPerfusionView::GenerateLinearModelFit_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(); //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 = this->m_selectedMask->GetUID(); //Create model info modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, m_selectedNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_ROIBASED(), this->GetFitName(), 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(); PrepareConcentrationImage(); 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 = this->m_selectedMask->GetUID(); } fitGenerator->SetDynamicImage(this->m_inputImage); fitGenerator->SetFitFunctor(fitFunctor); generator = fitGenerator.GetPointer(); //Create model info modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, this->m_inputImage, mitk::ModelFitConstants::FIT_TYPE_VALUE_PIXELBASED(), this->GetFitName(), 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(); PrepareConcentrationImage(); 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(this->m_inputImage); 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(this->m_inputImage)); generator = fitGenerator.GetPointer(); std::string roiUID = this->m_selectedMask->GetUID(); //Create model info modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, this->m_inputImage, mitk::ModelFitConstants::FIT_TYPE_VALUE_ROIBASED(), this->GetFitName(), 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) { this->m_Controls.infoBox->append(QString("" + QString("Fitting Data Set . . .") + QString (""))); ///////////////////////// //create job and put it into the thread pool mitk::modelFit::ModelFitResultNodeVectorType additionalNodes; if (m_HasGeneratedNewInput) { additionalNodes.push_back(m_inputNode); } if (m_HasGeneratedNewInputAIF) { additionalNodes.push_back(m_inputAIFNode); } ParameterFitBackgroundJob* pJob = new ParameterFitBackgroundJob(generator, fitSession, this->m_selectedNode, additionalNodes); 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_HasGeneratedNewInput(false), m_HasGeneratedNewInputAIF(false) { m_selectedImage = nullptr; m_selectedMask = nullptr; mitk::ModelFactoryBase::Pointer factory = mitk::DescriptivePharmacokineticBrixModelFactory::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::NodePredicateDimension::Pointer is3D = mitk::NodePredicateDimension::New(3); mitk::NodePredicateOr::Pointer isMask = mitk::NodePredicateOr::New(isLegacyMask, isLabelSet); mitk::NodePredicateAnd::Pointer isNoMask = mitk::NodePredicateAnd::New(isImage, mitk::NodePredicateNot::New(isMask)); mitk::NodePredicateAnd::Pointer is3DImage = mitk::NodePredicateAnd::New(isImage, is3D, isNoMask); 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(); auto isDynamicData = mitk::NodePredicateFunction::New([](const mitk::DataNode* node) { return (node && node->GetData() && node->GetData()->GetTimeSteps() > 1); }); auto modelFitResultRelationRule = mitk::ModelFitResultRelationRule::New(); auto isNoModelFitNodePredicate = mitk::NodePredicateNot::New(modelFitResultRelationRule->GetConnectedSourcesDetector()); this->m_isValidPDWImagePredicate = mitk::NodePredicateAnd::New(is3DImage, isNoModelFitNodePredicate); this->m_isValidTimeSeriesImagePredicate = mitk::NodePredicateAnd::New(isDynamicData, isImage, isNoMask); } 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()); //this stores the concentration image and AIF concentration image, if generated for this fit in the storage. //if not generated for this fit, relevant nodes are empty. mitk::modelFit::StoreResultsInDataStorage(this->GetDataStorage(), pJob->GetAdditionalRelevantNodes(), pJob->GetParentNode()); }; 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::GenerateConcentrationNode(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); 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.radioButtonUsingT1viaVFA->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()); concentrationGen->SetBaselineStartTimeStep(m_Controls.spinBox_baselineStartTimeStep->value()); concentrationGen->SetBaselineEndTimeStep(m_Controls.spinBox_baselineEndTimeStep->value()); } else if (this->m_Controls.radioButtonUsingT1viaVFA->isChecked()) { concentrationGen->SetRecoveryTime(m_Controls.TRSpinBox->value()); concentrationGen->SetRelaxivity(m_Controls.RelaxivitySpinBox->value()); concentrationGen->SetT10Image(dynamic_cast(m_Controls.PDWImageNodeSelector->GetSelectedNode()->GetData())); concentrationGen->SetBaselineStartTimeStep(m_Controls.spinBox_baselineStartTimeStep->value()); concentrationGen->SetBaselineEndTimeStep(m_Controls.spinBox_baselineEndTimeStep->value()); //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()); concentrationGen->SetBaselineStartTimeStep(m_Controls.spinBox_baselineStartTimeStep->value()); concentrationGen->SetBaselineEndTimeStep(m_Controls.spinBox_baselineEndTimeStep->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.AIFMaskNodeSelector->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.AIFImageNodeSelector->GetSelectedNode(); this->m_selectedAIFImage = dynamic_cast(this->m_selectedAIFImageNode->GetData()); } else { this->m_selectedAIFImageNode = m_selectedNode; this->m_selectedAIFImage = m_selectedImage; } this->PrepareAIFConcentrationImage(); aifGenerator->SetDynamicImage(this->m_inputAIFImage); aif = aifGenerator->GetAterialInputFunction(); aifTimeGrid = aifGenerator->GetAterialInputFunctionTimeGrid(); } else { mitkThrow() << "Cannot generate AIF. View is in a invalid 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()) { this->m_Controls.infoBox->append(QString("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()); this->AIFinputGrid.push_back(convertToDouble(vec1[0])); this->AIFinputFunction.push_back(convertToDouble(vec1[1])); } } void MRPerfusionView::PrepareConcentrationImage() { mitk::Image::Pointer concentrationImage = this->m_selectedImage; mitk::DataNode::Pointer concentrationNode = this->m_selectedNode; m_HasGeneratedNewInput = false; if (!this->m_Controls.radioButtonNoConversion->isChecked()) { concentrationImage = this->ConvertConcentrationImage(false); concentrationNode = GenerateConcentrationNode(concentrationImage, "Concentration"); m_HasGeneratedNewInput = true; } m_inputImage = concentrationImage; m_inputNode = concentrationNode; } void MRPerfusionView::PrepareAIFConcentrationImage() { mitk::Image::Pointer concentrationImage = this->m_selectedImage; mitk::DataNode::Pointer concentrationNode = this->m_selectedNode; m_HasGeneratedNewInputAIF = false; if (this->m_Controls.checkDedicatedAIFImage->isChecked()) { concentrationImage = this->m_selectedAIFImage; concentrationNode = this->m_selectedAIFImageNode; } if (!this->m_Controls.radioButtonNoConversion->isChecked()) { if (!IsTurboFlashSequenceFlag() && !this->m_Controls.checkDedicatedAIFImage->isChecked()) { if (m_inputImage.IsNull()) { mitkThrow() << "Cannot get AIF concentration image. Invalid view state. Input image is not defined yet, but should be."; } //we can directly use the concentration input image/node (generated by GetConcentrationImage) also for the AIF concentrationImage = this->m_inputImage; concentrationNode = this->m_inputNode; } else { concentrationImage = this->ConvertConcentrationImage(true); concentrationNode = GenerateConcentrationNode(concentrationImage, "AIF Concentration"); m_HasGeneratedNewInputAIF = true; } } m_inputAIFImage = concentrationImage; m_inputAIFNode = 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.pet/src/internal/PETDynamicView.cpp b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/PETDynamicView.cpp index 204d40ef80..5b5eadb97b 100644 --- a/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/PETDynamicView.cpp +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.pet/src/internal/PETDynamicView.cpp @@ -1,946 +1,923 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "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.views.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()) != nullptr; bool isExt1TCMFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; bool isFDGCMFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; bool is2TCMFactory = dynamic_cast - (m_selectedModelFactory.GetPointer()) != nullptr || - dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; 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 = nullptr; 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::GetFitName() const { std::string fitName = m_Controls.lineFitName->text().toStdString(); if (fitName.empty()) { fitName = m_Controls.lineFitName->placeholderText().toStdString(); } return fitName; } 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 = nullptr; mitk::modelFit::ModelFitInfo::Pointer fitSession = nullptr; bool isOTCFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; bool isextOTCFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; bool isFDGFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; bool isTTCFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; - bool isNumTTCFactory = dynamic_cast - (m_selectedModelFactory.GetPointer()) != nullptr; 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 = nullptr; m_selectedMask = nullptr; 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 = nullptr; this->m_selectedImage = nullptr; 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 whether any model is set at all. Otherwise exit with false if (m_selectedModelFactory.IsNotNull()) { bool isOTCFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; bool isextOTCFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; bool isFDGFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; bool isTTCFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != nullptr; - bool isNumTTCFactory = dynamic_cast - (m_selectedModelFactory.GetPointer()) != nullptr; - if (isOTCFactory || isextOTCFactory || isFDGFactory || isTTCFactory || isNumTTCFactory) + if (isOTCFactory || isextOTCFactory || isFDGFactory || isTTCFactory) { 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 whether 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 = m_selectedMask->GetUID(); } 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(), this->GetFitName(), 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 = ""; if (m_selectedMask.IsNotNull()) { roiUID = m_selectedMask->GetUID(); } //Create model info modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, m_selectedNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_ROIBASED(), this->GetFitName(), 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 ParameterFitBackgroundJob* pJob = new ParameterFitBackgroundJob(generator, fitSession, 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 = nullptr; m_selectedMask = nullptr; 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 invalid 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.simulation/src/internal/PerfusionDataSimulationView.cpp b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/PerfusionDataSimulationView.cpp index 35ac6847cf..64cef01de2 100644 --- a/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/PerfusionDataSimulationView.cpp +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/PerfusionDataSimulationView.cpp @@ -1,1000 +1,880 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include #include "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 "mitkModelSignalImageGenerator.h" #include #include #include #include #include "mitkSimpleFunctorBase.h" #include "mitkArbitraryTimeGeometry.h" #include #include const std::string PerfusionDataSimulationView::VIEW_ID = "org.mitk.views.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 = nullptr; 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()) != nullptr; - bool is2CXMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != nullptr || dynamic_cast(m_selectedModelFactory.GetPointer()) != nullptr; + bool is2CXMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != nullptr; bool is2TCMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != nullptr; bool is1TCMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != nullptr; 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()) != nullptr; - bool is2CXMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != nullptr || dynamic_cast(m_selectedModelFactory.GetPointer()) != nullptr; + bool is2CXMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != nullptr; bool is2TCMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != nullptr; bool is1TCMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != nullptr; 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 +/** @todo #2 Same function for 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()) != nullptr; bool isPhysBrixFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != nullptr; - bool isNumPhysBrixFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != nullptr; bool is2TCMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != nullptr; bool is1TCMFactory = dynamic_cast(m_selectedModelFactory.GetPointer()) != nullptr; 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::ModelSignalImageGenerator::Pointer generator = mitk::ModelSignalImageGenerator::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 independent 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); generator->SetParameterizer(modelParameterizer); 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::ModelSignalImageGenerator::Pointer generator = mitk::ModelSignalImageGenerator::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); - -generator->SetParameterizer(modelParameterizer); - -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::ModelSignalImageGenerator::Pointer generator = mitk::ModelSignalImageGenerator::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); generator->SetParameterizer(modelParameterizer); 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::ModelSignalImageGenerator::Pointer generator = mitk::ModelSignalImageGenerator::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); generator->SetParameterizer(modelParameterizer); 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::ModelSignalImageGenerator::Pointer generator = mitk::ModelSignalImageGenerator::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); generator->SetParameterizer(modelParameterizer); 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 = nullptr; 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 index 7956d413f1..27cf365e0a 100644 --- a/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/PerfusionDataSimulationView.h +++ b/Plugins/org.mitk.gui.qt.pharmacokinetics.simulation/src/internal/PerfusionDataSimulationView.h @@ -1,114 +1,112 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef 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) override; /*! * @brief Sets the focus to the plot curve button. Gets called by the framework to set the * focus on the right widget. */ void SetFocus() override; 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(); // 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