diff --git a/Modules/DICOMQI/mitkDICOMQIIOMimeTypes.cpp b/Modules/DICOMQI/mitkDICOMQIIOMimeTypes.cpp index f21818f64a..182579d095 100644 --- a/Modules/DICOMQI/mitkDICOMQIIOMimeTypes.cpp +++ b/Modules/DICOMQI/mitkDICOMQIIOMimeTypes.cpp @@ -1,137 +1,218 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkDICOMQIIOMimeTypes.h" #include "mitkIOMimeTypes.h" #include #include #include #include #include namespace mitk { std::vector MitkDICOMQIIOMimeTypes::Get() { std::vector mimeTypes; // order matters here (descending rank for mime types) mimeTypes.push_back(DICOMSEG_MIMETYPE().Clone()); - //mimeTypes.push_back(DICOMPM_MIMETYPE().Clone()); + mimeTypes.push_back(DICOMPM_MIMETYPE().Clone()); return mimeTypes; } // Mime Types //======= Mime Type DICOM SEG ======= MitkDICOMQIIOMimeTypes::MitkDICOMSEGMimeType::MitkDICOMSEGMimeType() : CustomMimeType(DICOMSEG_MIMETYPE_NAME()) { this->AddExtension("dcm"); this->SetCategory(IOMimeTypes::CATEGORY_IMAGES()); this->SetComment("DICOM SEG"); } bool MitkDICOMQIIOMimeTypes::MitkDICOMSEGMimeType::AppliesTo(const std::string &path) const { std::ifstream myfile; myfile.open(path, std::ios::binary); // myfile.seekg (128); char *buffer = new char[128]; myfile.read(buffer, 128); myfile.read(buffer, 4); if (std::string(buffer).compare("DICM") != 0) { delete[] buffer; return false; } delete[] buffer; bool canRead(CustomMimeType::AppliesTo(path)); // fix for bug 18572 // Currently this function is called for writing as well as reading, in that case // the image information can of course not be read // This is a bug, this function should only be called for reading. if (!itksys::SystemTools::FileExists(path.c_str())) { return canRead; } // end fix for bug 18572 DcmFileFormat dcmFileFormat; OFCondition status = dcmFileFormat.loadFile(path.c_str()); if (status.bad()) { canRead = false; } if (!canRead) { return canRead; } OFString modality; OFString sopClassUID; if (dcmFileFormat.getDataset()->findAndGetOFString(DCM_Modality, modality).good() && dcmFileFormat.getDataset()->findAndGetOFString(DCM_SOPClassUID, sopClassUID).good()) { if (modality.compare("SEG") == 0) {//atm we could read SegmentationStorage files. Other storage classes with "SEG" modality, e.g. SurfaceSegmentationStorage (1.2.840.10008.5.1.4.1.1.66.5), are not supported yet. if (sopClassUID.compare("1.2.840.10008.5.1.4.1.1.66.4") == 0) { canRead = true; } else { canRead = false; } } else { canRead = false; } } return canRead; } MitkDICOMQIIOMimeTypes::MitkDICOMSEGMimeType *MitkDICOMQIIOMimeTypes::MitkDICOMSEGMimeType::Clone() const { return new MitkDICOMSEGMimeType(*this); } MitkDICOMQIIOMimeTypes::MitkDICOMSEGMimeType MitkDICOMQIIOMimeTypes::DICOMSEG_MIMETYPE() { return MitkDICOMSEGMimeType(); } std::string MitkDICOMQIIOMimeTypes::DICOMSEG_MIMETYPE_NAME() { // create a unique and sensible name for this mime type static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".image.dicom.seg"; return name; } //======= Mime Type DICOM PM ======= //... + MitkDICOMQIIOMimeTypes::MitkDICOMPMMimeType::MitkDICOMPMMimeType() : CustomMimeType(DICOMPM_MIMETYPE_NAME()) + { + this->AddExtension("dcm"); + this->SetCategory(IOMimeTypes::CATEGORY_IMAGES()); + this->SetComment("DICOM PM"); + } + + bool MitkDICOMQIIOMimeTypes::MitkDICOMPMMimeType::AppliesTo(const std::string &path) const + { + std::ifstream myfile; + myfile.open(path, std::ios::binary); + // myfile.seekg (128); + char *buffer = new char[128]; + myfile.read(buffer, 128); + myfile.read(buffer, 4); + if (std::string(buffer).compare("DICM") != 0) + { + delete[] buffer; + return false; + } + delete[] buffer; + + bool canRead(CustomMimeType::AppliesTo(path)); + + // fix for bug 18572 + // Currently this function is called for writing as well as reading, in that case + // the image information can of course not be read + // This is a bug, this function should only be called for reading. + if (!itksys::SystemTools::FileExists(path.c_str())) + { + return canRead; + } + // end fix for bug 18572 + DcmFileFormat dcmFileFormat; + OFCondition status = dcmFileFormat.loadFile(path.c_str()); + + if (status.bad()) + { + canRead = false; + } + + if (!canRead) + { + return canRead; + } + + OFString modality; + if (dcmFileFormat.getDataset()->findAndGetOFString(DCM_Modality, modality).good()) + { + if (modality.compare("RWV") == 0) + { + canRead = true; + } + else + { + canRead = false; + } + } + + return canRead; + } + + MitkDICOMQIIOMimeTypes::MitkDICOMPMMimeType *MitkDICOMQIIOMimeTypes::MitkDICOMPMMimeType::Clone() const + { + return new MitkDICOMPMMimeType(*this); + } + + MitkDICOMQIIOMimeTypes::MitkDICOMPMMimeType MitkDICOMQIIOMimeTypes::DICOMPM_MIMETYPE() + { + return MitkDICOMPMMimeType(); + } + + + std::string MitkDICOMQIIOMimeTypes::DICOMPM_MIMETYPE_NAME() + { + // create a unique and sensible name for this mime type + static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".image.dicom.pm"; + return name; + } + + } diff --git a/Modules/DICOMQI/mitkDICOMQIIOMimeTypes.h b/Modules/DICOMQI/mitkDICOMQIIOMimeTypes.h index b0b85eed5a..e3faaf6c33 100644 --- a/Modules/DICOMQI/mitkDICOMQIIOMimeTypes.h +++ b/Modules/DICOMQI/mitkDICOMQIIOMimeTypes.h @@ -1,71 +1,71 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKDICOMQIIOMIMETYPES_H #define MITKDICOMQIIOMIMETYPES_H #include "mitkCustomMimeType.h" #include #include namespace mitk { /// Provides the custom mime types for dicom qi objects loaded with DCMQI class MITKDICOMQI_EXPORT MitkDICOMQIIOMimeTypes { public: /** Mime type that parses dicom files to determine whether they are dicom segmentation objects. */ class MITKDICOMQI_EXPORT MitkDICOMSEGMimeType : public CustomMimeType { public: MitkDICOMSEGMimeType(); bool AppliesTo(const std::string &path) const override; MitkDICOMSEGMimeType *Clone() const override; }; static MitkDICOMSEGMimeType DICOMSEG_MIMETYPE(); static std::string DICOMSEG_MIMETYPE_NAME(); /** Mime type that parses dicom files to determine whether they are dicom pm objects. */ - /* - class MitkDICOMPMMimeType : public CustomMimeType + + class MITKDICOMQI_EXPORT MitkDICOMPMMimeType : public CustomMimeType { public: MitkDICOMPMMimeType(); virtual bool AppliesTo(const std::string &path) const override; virtual MitkDICOMPMMimeType *Clone() const override; }; static MitkDICOMPMMimeType DICOMPM_MIMETYPE(); static std::string DICOMPM_MIMETYPE_NAME(); - */ - + + // Get all Mime Types static std::vector Get(); private: // purposely not implemented MitkDICOMQIIOMimeTypes(); MitkDICOMQIIOMimeTypes(const MitkDICOMQIIOMimeTypes &); }; } #endif // MITKDICOMQIIOMIMETYPES_H diff --git a/Modules/ModelFit/src/Common/mitkModelFitResultHelper.cpp b/Modules/ModelFit/src/Common/mitkModelFitResultHelper.cpp index 4f5c1cb67d..6f44e42aa4 100644 --- a/Modules/ModelFit/src/Common/mitkModelFitResultHelper.cpp +++ b/Modules/ModelFit/src/Common/mitkModelFitResultHelper.cpp @@ -1,274 +1,278 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkModelFitResultHelper.h" #include #include #include "mitkModelTraitsInterface.h" #include "mitkModelFitConstants.h" #include "mitkModelFitInfo.h" + namespace mitk { namespace modelFit { void AdaptDataPropertyToParameter(mitk::BaseData* data, const ModelBase::ParameterNameType& name, modelFit::Parameter::Type dataType, const modelFit::ModelFitInfo* fitInfo) { assert(data); if (!data) { mitkThrow() << "Cannot add model or fit properties to data instance. Passed data instance is null. parameter name:" << name; } if (!fitInfo) { mitkThrow() << "Cannot add model or fit properties to data. Passed fit info instance is null. parameter name:" << name; } data->GetPropertyList()->SetStringProperty(ModelFitConstants::PARAMETER_NAME_PROPERTY_NAME().c_str(),name.c_str()); if (dataType == modelFit::Parameter::ParameterType) { data->GetPropertyList()->SetStringProperty(ModelFitConstants::PARAMETER_TYPE_PROPERTY_NAME().c_str(), ModelFitConstants::PARAMETER_TYPE_VALUE_PARAMETER().c_str()); } else if (dataType == modelFit::Parameter::DerivedType) { data->GetPropertyList()->SetStringProperty(ModelFitConstants::PARAMETER_TYPE_PROPERTY_NAME().c_str(), ModelFitConstants::PARAMETER_TYPE_VALUE_DERIVED_PARAMETER().c_str()); } else if (dataType == modelFit::Parameter::CriterionType) { data->GetPropertyList()->SetStringProperty(ModelFitConstants::PARAMETER_TYPE_PROPERTY_NAME().c_str(), ModelFitConstants::PARAMETER_TYPE_VALUE_CRITERION().c_str()); } else if (dataType == modelFit::Parameter::EvaluationType) { data->GetPropertyList()->SetStringProperty(ModelFitConstants::PARAMETER_TYPE_PROPERTY_NAME().c_str(), ModelFitConstants::PARAMETER_TYPE_VALUE_EVALUATION_PARAMETER().c_str()); } if (dataType == modelFit::Parameter::ParameterType || dataType == modelFit::Parameter::DerivedType) { modelFit::Parameter::ConstPointer param = fitInfo->GetParameter(name,dataType); if (param.IsNull()) { mitkThrow() << "Cannot generate model fit result data. Parameter name is not part of the model fit info. Parameter name: "<unit.empty()) { data->GetPropertyList()->SetStringProperty(ModelFitConstants::PARAMETER_UNIT_PROPERTY_NAME().c_str(), param->unit.c_str()); } if (param->scale != 1.0) { data->GetPropertyList()->SetFloatProperty(ModelFitConstants::PARAMETER_SCALE_PROPERTY_NAME().c_str(), param->scale); } } }; void AdaptDataPropertyToModelFit(mitk::BaseData* data, const modelFit::ModelFitInfo* fitInfo) { assert(data); if (!data) { mitkThrow() << "Cannot add model or fit properties to data. Passed data instance is null."; } if (!fitInfo) { mitkThrow() << "Cannot add model or fit properties to data. Passed model traits instance is null."; } //model section data->GetPropertyList()->SetStringProperty(ModelFitConstants::MODEL_TYPE_PROPERTY_NAME().c_str(), fitInfo->modelType.c_str()); data->GetPropertyList()->SetStringProperty(ModelFitConstants::MODEL_NAME_PROPERTY_NAME().c_str(), fitInfo->modelName.c_str()); data->GetPropertyList()->SetStringProperty(ModelFitConstants::MODEL_FUNCTION_CLASS_PROPERTY_NAME().c_str(), fitInfo->functionClassID.c_str()); if(!(fitInfo->function.empty())) { data->GetPropertyList()->SetStringProperty(ModelFitConstants::MODEL_FUNCTION_PROPERTY_NAME().c_str(), fitInfo->function.c_str()); data->GetPropertyList()->SetStringProperty(ModelFitConstants::MODEL_X_PROPERTY_NAME().c_str(), fitInfo->x.c_str()); } //axis section if (!fitInfo->xAxisName.empty()) { data->GetPropertyList()->SetStringProperty(ModelFitConstants::XAXIS_NAME_PROPERTY_NAME().c_str(), fitInfo->xAxisName.c_str()); } if (!fitInfo->xAxisUnit.empty()) { data->GetPropertyList()->SetStringProperty(ModelFitConstants::XAXIS_UNIT_PROPERTY_NAME().c_str(), fitInfo->xAxisUnit.c_str()); } if (!fitInfo->yAxisName.empty()) { data->GetPropertyList()->SetStringProperty(ModelFitConstants::YAXIS_NAME_PROPERTY_NAME().c_str(), fitInfo->yAxisName.c_str()); } if (!fitInfo->yAxisUnit.empty()) { data->GetPropertyList()->SetStringProperty(ModelFitConstants::YAXIS_UNIT_PROPERTY_NAME().c_str(), fitInfo->yAxisUnit.c_str()); } //fit section data->GetPropertyList()->SetStringProperty(ModelFitConstants::FIT_UID_PROPERTY_NAME().c_str(), fitInfo->uid.c_str()); data->GetPropertyList()->SetStringProperty(ModelFitConstants::FIT_NAME_PROPERTY_NAME().c_str(), fitInfo->fitName.c_str()); data->GetPropertyList()->SetStringProperty(ModelFitConstants::FIT_TYPE_PROPERTY_NAME().c_str(), fitInfo->fitType.c_str()); data->GetPropertyList()->SetStringProperty(ModelFitConstants::FIT_INPUT_IMAGEUID_PROPERTY_NAME().c_str(), fitInfo->inputUID.c_str()); if (fitInfo->inputData.GetLookupTable().size() > 0) { mitk::ScalarListLookupTableProperty::Pointer inputDataProp = mitk::ScalarListLookupTableProperty::New(); inputDataProp->SetValue(fitInfo->inputData); data->SetProperty(ModelFitConstants::FIT_INPUT_DATA_PROPERTY_NAME().c_str(), inputDataProp); } if (!fitInfo->roiUID.empty()) { data->GetPropertyList()->SetStringProperty(ModelFitConstants::FIT_INPUT_ROIUID_PROPERTY_NAME().c_str(), fitInfo->roiUID.c_str()); } data->SetProperty(ModelFitConstants::FIT_STATIC_PARAMETERS_PROPERTY_NAME().c_str(), ConvertStaticParametersToProperty(fitInfo->staticParamMap)); }; mitk::DataNode::Pointer CreateNode(const ModelBase::ParameterNameType& name, Image* parameterImage, const ModelFitInfo* fitInfo) { if (!parameterImage) { mitkThrow() << "Cannot generate model fit result node. Passed parameterImage is null. parameter name: "<SetData(parameterImage); std::string nodeName = name; if (!fitInfo->fitName.empty()) { nodeName = fitInfo->fitName + "_" + nodeName; } result->SetName(nodeName); result->SetVisibility(false); return result; }; } } mitk::ScalarListLookupTableProperty::Pointer mitk::modelFit::ConvertStaticParametersToProperty(const mitk::modelFit::StaticParameterMap& params) { mitk::ScalarListLookupTableProperty::Pointer result = mitk::ScalarListLookupTableProperty::New(); ScalarListLookupTable table; for(mitk::modelFit::StaticParameterMap::const_iterator pos = params.begin(); pos != params.end(); ++pos) { table.SetTableValue(pos->first,pos->second); } result->SetValue(table); return result; }; MITKMODELFIT_EXPORT void mitk::modelFit::SetModelFitDataProperties(mitk::BaseData* data, const ModelBase::ParameterNameType& name, modelFit::Parameter::Type dataType, const modelFit::ModelFitInfo* fitInfo) { AdaptDataPropertyToModelFit(data, fitInfo); AdaptDataPropertyToParameter(data, name, dataType, fitInfo); }; MITKMODELFIT_EXPORT mitk::DataNode::Pointer mitk::modelFit::CreateResultNode( const ModelBase::ParameterNameType& name, modelFit::Parameter::Type nodeType, Image* parameterImage, const ModelFitInfo* modelFitInfo) { if (!parameterImage) { mitkThrow() << "Cannot generate model fit result node. Passed parameterImage is null. parameter name: "<first, modelFit::Parameter::ParameterType, pos->second, fitInfo); nodes.push_back(newNode); } for (ModelFitResultImageMapType::const_iterator pos = derivedResults.begin(); pos!=derivedResults.end(); ++pos) { DataNode::Pointer newNode = CreateResultNode(pos->first, modelFit::Parameter::DerivedType, pos->second, fitInfo); nodes.push_back(newNode); } for (ModelFitResultImageMapType::const_iterator pos = criterionResults.begin(); pos!=criterionResults.end(); ++pos) { DataNode::Pointer newNode = CreateResultNode(pos->first, modelFit::Parameter::CriterionType, pos->second, fitInfo); nodes.push_back(newNode); } for (ModelFitResultImageMapType::const_iterator pos = evaluationResults.begin(); pos!=evaluationResults.end(); ++pos) { DataNode::Pointer newNode = CreateResultNode(pos->first, modelFit::Parameter::EvaluationType, pos->second, fitInfo); nodes.push_back(newNode); } return nodes; }; MITKMODELFIT_EXPORT void mitk::modelFit::StoreResultsInDataStorage(DataStorage* storage, const ModelFitResultNodeVectorType& resultNodes, DataNode* parentNode) { if (!storage) { mitkThrow() << "Cannot store model fit results in data storage. Passed storage is null."; } for (ModelFitResultNodeVectorType::const_iterator pos = resultNodes.begin(); pos!=resultNodes.end(); ++pos) { storage->Add(*pos,parentNode); } + + + }; diff --git a/Modules/Multilabel/mitkDICOMSegmentationPropertyHelper.h b/Modules/Multilabel/mitkDICOMSegmentationPropertyHelper.h index 76c9abbaa0..438f5875f2 100644 --- a/Modules/Multilabel/mitkDICOMSegmentationPropertyHelper.h +++ b/Modules/Multilabel/mitkDICOMSegmentationPropertyHelper.h @@ -1,35 +1,35 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#ifndef DICOMSEGMENTATIONPROPERTYHANDLER_H_ -#define DICOMSEGMENTATIONPROPERTYHANDLER_H_ +#ifndef DICOMPMPROPERTYHANDLER_H_ +#define DICOMPMPROPERTYHANDLER_H_ #include #include #include #include namespace mitk { class MITKMULTILABEL_EXPORT DICOMSegmentationPropertyHandler { public: static void DeriveDICOMSegmentationProperties(LabelSetImage* dicomSegImage); static void SetDICOMSegmentProperties(Label *label); }; } #endif diff --git a/Modules/Pharmacokinetics/CMakeLists.txt b/Modules/Pharmacokinetics/CMakeLists.txt index ee417b64e2..fabbaeb023 100644 --- a/Modules/Pharmacokinetics/CMakeLists.txt +++ b/Modules/Pharmacokinetics/CMakeLists.txt @@ -1,18 +1,19 @@ MITK_CREATE_MODULE(Pharmacokinetics INCLUDE_DIRS PUBLIC ${MITK_BINARY_DIR} PRIVATE src/Common src/Functors src/Models src/DescriptionParameters src/SimulationFramework DEPENDS PUBLIC MitkCore MitkModelFit - PRIVATE MitkMultilabel + PRIVATE MitkMultilabel MitkDICOMQI PACKAGE_DEPENDS PUBLIC ITK|ITKOptimizers PRIVATE Boost ) if(BUILD_TESTING) ADD_SUBDIRECTORY(test) endif(BUILD_TESTING) ADD_SUBDIRECTORY(autoload/Models) +ADD_SUBDIRECTORY(autoload/DICOMPMIO) ADD_SUBDIRECTORY(cmdapps) \ No newline at end of file diff --git a/Modules/Pharmacokinetics/autoload/DICOMPMIO/CMakeLists.txt b/Modules/Pharmacokinetics/autoload/DICOMPMIO/CMakeLists.txt new file mode 100644 index 0000000000..ba23494588 --- /dev/null +++ b/Modules/Pharmacokinetics/autoload/DICOMPMIO/CMakeLists.txt @@ -0,0 +1,6 @@ +MITK_CREATE_MODULE( DICOMPMIO + DEPENDS MitkPharmacokinetics MitkDICOMQI + PACKAGE_DEPENDS + PRIVATE DCMQI DCMTK + AUTOLOAD_WITH MitkCore +) diff --git a/Modules/Pharmacokinetics/autoload/DICOMPMIO/files.cmake b/Modules/Pharmacokinetics/autoload/DICOMPMIO/files.cmake new file mode 100644 index 0000000000..82706c16cd --- /dev/null +++ b/Modules/Pharmacokinetics/autoload/DICOMPMIO/files.cmake @@ -0,0 +1,6 @@ +set(CPP_FILES + mitkDICOMPMIO.cpp + mitkDICOMPMIOActivator.cpp + mitkDICOMPMIOMimeTypes.cpp +) + diff --git a/Modules/Pharmacokinetics/autoload/DICOMPMIO/mitkDICOMPMIO.cpp b/Modules/Pharmacokinetics/autoload/DICOMPMIO/mitkDICOMPMIO.cpp new file mode 100644 index 0000000000..3cf83bf8d5 --- /dev/null +++ b/Modules/Pharmacokinetics/autoload/DICOMPMIO/mitkDICOMPMIO.cpp @@ -0,0 +1,250 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef __mitkDICOMPharmacokineticsIO__cpp +#define __mitkDICOMPharmacokineticsIO__cpp + +#include "mitkDICOMPMIO.h" +#include "mitkDICOMPMIOMimeTypes.h" +#include "mitkDICOMPMConstants.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mitkParamapPresets.h" +#include +#include + +// us +#include +#include + +// model fit parameters +#include "mitkModelFitConstants.h" + + +namespace mitk +{ + DICOMPMIO::DICOMPMIO() + : AbstractFileIO(Image::GetStaticNameOfClass(), + mitk::MitkDICOMPMIOMimeTypes::DICOMPM_MIMETYPE_NAME(), + "DICOM PM") + + { + AbstractFileWriter::SetRanking(10); + AbstractFileReader::SetRanking(10); + this->RegisterService(); + this->AddDICOMTagsToService(); + } + + void DICOMPMIO::AddDICOMTagsToService() + { + IDICOMTagsOfInterest *toiService = GetDicomTagsOfInterestService(); + if (toiService != nullptr) + { + toiService->AddTagOfInterest(DICOMPMConstants::RWVM_SEQUENCE_PATH()); + toiService->AddTagOfInterest(DICOMPMConstants::UNITS_SEQUENCE_PATH()); + toiService->AddTagOfInterest(DICOMPMConstants::UNITS_CODE_VALUE_PATH()); + toiService->AddTagOfInterest(DICOMPMConstants::UNITS_CODE_SCHEME_PATH()); + toiService->AddTagOfInterest(DICOMPMConstants::UNITS_CODE_MEANING_PATH()); + toiService->AddTagOfInterest(DICOMPMConstants::QUANTITY_DEFINITION_SEQUENCE_PATH()); + toiService->AddTagOfInterest(DICOMPMConstants::QUANTITY_DEFINITION_VALUE_TYPE_PATH()); + toiService->AddTagOfInterest(DICOMPMConstants::QUANTITY_DEFINITION_CONCEPT_CODE_SEQUENCE_PATH()); + toiService->AddTagOfInterest(DICOMPMConstants::QUANTITY_DEFINITION_CONCEPT_CODE_VALUE_PATH()); + toiService->AddTagOfInterest(DICOMPMConstants::QUANTITY_DEFINITION_CONCEPT_CODE_SCHEME_PATH()); + toiService->AddTagOfInterest(DICOMPMConstants::QUANTITY_DEFINITION_CONCEPT_CODE_MEANING_PATH()); + } + } + + IFileIO::ConfidenceLevel DICOMPMIO::GetWriterConfidenceLevel() const + { + if (AbstractFileIO::GetWriterConfidenceLevel() == Unsupported) + return Unsupported; + + const Image *PMinput = static_cast(this->GetInput()); + if (PMinput) + return Supported; + else + return Unsupported; + } + + void DICOMPMIO::Write() + { + ValidateOutputLocation(); + mitk::LocaleSwitch localeSwitch("C"); + LocalFile localFile(this); + const std::string path = localFile.GetFileName(); + + auto PMinput = dynamic_cast(this->GetInput()); + if (PMinput == nullptr) + mitkThrow() << "Cannot write non-image data"; + + // Get DICOM information from referenced image + vector dcmDatasets; + + + DcmFileFormat *readFileFormat = new DcmFileFormat(); + try + { + // Generate dcmdataset witk DICOM tags from property list; ATM the source are the filepaths from the + // property list + mitk::StringLookupTableProperty::Pointer filesProp = + dynamic_cast(PMinput->GetProperty("referenceFiles").GetPointer()); + + if (filesProp.IsNull()) + { + mitkThrow() << "No property with dicom file path."; + return; + } + + + // returns a list of all referenced files + StringLookupTable filesLut = filesProp->GetValue(); + const StringLookupTable::LookupTableType &lookUpTableMap = filesLut.GetLookupTable(); + for (auto it : lookUpTableMap) + { + const char *fileName = (it.second).c_str(); + if (readFileFormat->loadFile(fileName, EXS_Unknown).good()) + dcmDatasets.push_back(readFileFormat->getAndRemoveDataset()); + } + } + catch (const std::exception &e) + { + MITK_ERROR << "An error occurred while getting the dicom information: " << e.what() << endl; + return; + } + + mitk::Image *mitkPMImage = const_cast(PMinput); + // Cast input PMinput to itk image + ImageToItk::Pointer PMimageToItkFilter = ImageToItk::New(); + PMimageToItkFilter->SetInput(mitkPMImage); + PMimageToItkFilter->Update(); + + // Cast from original itk type to dcmqi input itk image type + typedef itk::CastImageFilter castItkImageFilterType; + castItkImageFilterType::Pointer castFilter = castItkImageFilterType::New(); + castFilter->SetInput(PMimageToItkFilter->GetOutput()); + castFilter->Update(); + PMitkInternalImageType::Pointer itkParamapImage = castFilter->GetOutput(); + itkParamapImage->DisconnectPipeline(); + + // Create PM meta information + const std::string &tmpMetaInfoFile = this->CreateMetaDataJsonFilePM(); + + // Convert itk PM images to dicom image + MITK_INFO << "Writing PM image: " << path << std::endl; + try + { + dcmqi::ParaMapConverter *PMconverter = new dcmqi::ParaMapConverter(); + DcmDataset *PMresult = PMconverter->itkimage2paramap(itkParamapImage, dcmDatasets, tmpMetaInfoFile); + // Write dicom file + DcmFileFormat dcmFileFormat(PMresult); + std::string filePath = path.substr(0, path.find_last_of(".")); + filePath = filePath + ".dcm"; + dcmFileFormat.saveFile(filePath.c_str(), EXS_LittleEndianExplicit); + // Clean up + if (PMconverter != nullptr) + delete PMconverter; + if (PMresult != nullptr) + delete PMresult; + } + catch (const std::exception &e) + { + MITK_ERROR << "An error occurred during writing the DICOM Paramap: " << e.what() << endl; + return; + } + + //-------------------------------------------------------------// + + // End of image writing; clean up + if (readFileFormat) + delete readFileFormat; + + for (auto obj : dcmDatasets) + delete obj; + dcmDatasets.clear(); + + } + + const std::string mitk::DICOMPMIO::CreateMetaDataJsonFilePM() const + { + const mitk::Image *PMimage = dynamic_cast(this->GetInput()); + dcmqi::JSONParametricMapMetaInformationHandler PMhandler; + + // Get Metadata from modelFitConstants + std::string parameterName; + PMimage->GetPropertyList()->GetStringProperty(ModelFitConstants::PARAMETER_NAME_PROPERTY_NAME().c_str(), parameterName); + std::string modelName; + PMimage->GetPropertyList()->GetStringProperty(ModelFitConstants::MODEL_NAME_PROPERTY_NAME().c_str(), modelName); + + + mitk::ParamapPresets* pmPresets = mitk::ParamapPresets::New(); + // Here the mitkParamapPresets.xml file containing the Coding Schmeme Designator and Code Value are parsed and the relevant values extracted + pmPresets->LoadPreset(); + + auto pmType_parameterName = pmPresets->GetType(parameterName); + auto pmType_modelName = pmPresets->GetType(modelName); + + // Here some other + // mandatory + // TODO: where to get these from? + // TODO: AnatomicRegionSequence from Segmentation? + PMhandler.setAnatomicRegionSequence("T-9200B", "SRT", "Prostate"); + PMhandler.setDerivedPixelContrast("TCS"); + PMhandler.setFrameLaterality("U"); + // optional + PMhandler.setQuantityValueCode(pmType_parameterName.codeValue, pmType_parameterName.codeScheme, parameterName); + PMhandler.setMeasurementMethodCode(pmType_modelName.codeValue, pmType_modelName.codeScheme, modelName); + PMhandler.setSeriesNumber("1"); + PMhandler.setInstanceNumber("1"); + PMhandler.setDerivationCode("110816", "DCM", "Time Course of Signal"); + PMhandler.setMeasurementUnitsCode("/min", "UCUM", "/m"); + PMhandler.setRealWorldValueSlope(1); + + return PMhandler.getJSONOutputAsString(); + } + + + // IKO: not yet implemented, TO DO: write DICOMPMReader + std::vector DICOMPMIO::Read() + { + mitk::LocaleSwitch localeSwitch("C"); + std::vector result; + return result; + } + + // IKO: not yet implemented TO DO: write DICOMPMReaderConfidenceLevel + IFileIO::ConfidenceLevel DICOMPMIO::GetReaderConfidenceLevel() const + { + return Unsupported; + } + + + + DICOMPMIO *DICOMPMIO::IOClone() const { return new DICOMPMIO(*this); } +} // namespace + + + + + + +#endif //__mitkDICOMPharmacokineticsIO__cpp diff --git a/Modules/Pharmacokinetics/autoload/DICOMPMIO/mitkDICOMPMIO.h b/Modules/Pharmacokinetics/autoload/DICOMPMIO/mitkDICOMPMIO.h new file mode 100644 index 0000000000..22435d252c --- /dev/null +++ b/Modules/Pharmacokinetics/autoload/DICOMPMIO/mitkDICOMPMIO.h @@ -0,0 +1,73 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef __mitkDICOMPMIO_h +#define __mitkDICOMPMIO_h + +#include +//#include +#include +#include +#include +#include + + +namespace mitk +{ + /** + * Read and Writes a LabelSetImage to a dcm file + * @ingroup Process + */ + class DICOMPMIO : public mitk::AbstractFileIO + { + public: + + typedef mitk::Image PMInputType; + typedef itk::Image PMitkInputImageType; + typedef IODFloatingPointImagePixelModule::value_type PMFloatPixelType; // input type required for DCMQI + typedef itk::Image PMitkInternalImageType; + + DICOMPMIO(); + + // -------------- AbstractFileReader ------------- + + using AbstractFileReader::Read; + + /** + * @brief Reads a number of DICOM segmentation from the file system + * @return a vector of mitk::LabelSetImages + * @throws throws an mitk::Exception if an error ocurrs + */ + virtual std::vector Read() override; + virtual ConfidenceLevel GetReaderConfidenceLevel() const override; + + // -------------- AbstractFileWriter ------------- + + virtual void Write() override; + virtual ConfidenceLevel GetWriterConfidenceLevel() const override; + + private: + DICOMPMIO *IOClone() const override; + + // -------------- DICOMPMIO specific functions ------------- + + const std::string CreateMetaDataJsonFilePM() const; + + void AddDICOMTagsToService(); + }; +} // end of namespace mitk + +#endif // __mitkDICOMPMIO_h diff --git a/Modules/Pharmacokinetics/autoload/DICOMPMIO/mitkDICOMPMIOActivator.cpp b/Modules/Pharmacokinetics/autoload/DICOMPMIO/mitkDICOMPMIOActivator.cpp new file mode 100644 index 0000000000..f437f94827 --- /dev/null +++ b/Modules/Pharmacokinetics/autoload/DICOMPMIO/mitkDICOMPMIOActivator.cpp @@ -0,0 +1,63 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include +#include +#include +#include +#include + +#include "mitkDICOMPMIO.h" + +#include "mitkDICOMPMIOMimeTypes.h" + +namespace mitk +{ + /** + \brief Registers services for multilabel dicom module. + */ + class DICOMPMIOActivator : public us::ModuleActivator + { + std::vector m_FileIOs; + + public: + void Load(us::ModuleContext * context) override + { + us::ServiceProperties props; + props[us::ServiceConstants::SERVICE_RANKING()] = 10; + + std::vector mimeTypes = mitk::MitkDICOMPMIOMimeTypes::Get(); + for (std::vector::const_iterator mimeTypeIter = mimeTypes.begin(), + iterEnd = mimeTypes.end(); + mimeTypeIter != iterEnd; + ++mimeTypeIter) + { + context->RegisterService(*mimeTypeIter, props); + } + // IKO + m_FileIOs.push_back(new DICOMPMIO()); + } + void Unload(us::ModuleContext *) override + { + for (auto &elem : m_FileIOs) + { + delete elem; + } + } + }; +} + +US_EXPORT_MODULE_ACTIVATOR(mitk::DICOMPMIOActivator) diff --git a/Modules/DICOMQI/mitkDICOMQIIOMimeTypes.cpp b/Modules/Pharmacokinetics/autoload/DICOMPMIO/mitkDICOMPMIOMimeTypes.cpp similarity index 53% copy from Modules/DICOMQI/mitkDICOMQIIOMimeTypes.cpp copy to Modules/Pharmacokinetics/autoload/DICOMPMIO/mitkDICOMPMIOMimeTypes.cpp index f21818f64a..aaf8a51174 100644 --- a/Modules/DICOMQI/mitkDICOMQIIOMimeTypes.cpp +++ b/Modules/Pharmacokinetics/autoload/DICOMPMIO/mitkDICOMPMIOMimeTypes.cpp @@ -1,137 +1,127 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#include "mitkDICOMQIIOMimeTypes.h" +#include "mitkDICOMPMIOMimeTypes.h" #include "mitkIOMimeTypes.h" #include #include + #include -#include -#include +// dcmqi +//IKO: TO DO +#include +#include namespace mitk { - std::vector MitkDICOMQIIOMimeTypes::Get() + std::vector MitkDICOMPMIOMimeTypes::Get() { std::vector mimeTypes; // order matters here (descending rank for mime types) - mimeTypes.push_back(DICOMSEG_MIMETYPE().Clone()); - //mimeTypes.push_back(DICOMPM_MIMETYPE().Clone()); + mimeTypes.push_back(DICOMPM_MIMETYPE().Clone()); return mimeTypes; } // Mime Types - //======= Mime Type DICOM SEG ======= - MitkDICOMQIIOMimeTypes::MitkDICOMSEGMimeType::MitkDICOMSEGMimeType() : CustomMimeType(DICOMSEG_MIMETYPE_NAME()) + MitkDICOMPMIOMimeTypes::MitkDICOMPMMimeType::MitkDICOMPMMimeType() : CustomMimeType(DICOMPM_MIMETYPE_NAME()) { this->AddExtension("dcm"); this->SetCategory(IOMimeTypes::CATEGORY_IMAGES()); - this->SetComment("DICOM SEG"); + this->SetComment("DICOM PM"); } - bool MitkDICOMQIIOMimeTypes::MitkDICOMSEGMimeType::AppliesTo(const std::string &path) const + bool MitkDICOMPMIOMimeTypes::MitkDICOMPMMimeType::AppliesTo(const std::string &path) const { std::ifstream myfile; - myfile.open(path, std::ios::binary); - // myfile.seekg (128); - char *buffer = new char[128]; - myfile.read(buffer, 128); - myfile.read(buffer, 4); - if (std::string(buffer).compare("DICM") != 0) + myfile.open (path, std::ios::binary); +// myfile.seekg (128); + char *buffer = new char [128]; + myfile.read (buffer,128); + myfile.read (buffer,4); + if (std::string(buffer).compare("DICM")!=0) { delete[] buffer; return false; } delete[] buffer; bool canRead(CustomMimeType::AppliesTo(path)); // fix for bug 18572 // Currently this function is called for writing as well as reading, in that case // the image information can of course not be read // This is a bug, this function should only be called for reading. if (!itksys::SystemTools::FileExists(path.c_str())) { return canRead; } // end fix for bug 18572 - - DcmFileFormat dcmFileFormat; OFCondition status = dcmFileFormat.loadFile(path.c_str()); if (status.bad()) { canRead = false; } if (!canRead) { return canRead; } + + OFString modality; - OFString sopClassUID; - if (dcmFileFormat.getDataset()->findAndGetOFString(DCM_Modality, modality).good() && dcmFileFormat.getDataset()->findAndGetOFString(DCM_SOPClassUID, sopClassUID).good()) + if (dcmFileFormat.getDataset()->findAndGetOFString(DCM_Modality, modality).good()) { - if (modality.compare("SEG") == 0) - {//atm we could read SegmentationStorage files. Other storage classes with "SEG" modality, e.g. SurfaceSegmentationStorage (1.2.840.10008.5.1.4.1.1.66.5), are not supported yet. - if (sopClassUID.compare("1.2.840.10008.5.1.4.1.1.66.4") == 0) - { - canRead = true; - } - else - { - canRead = false; - } + if (modality.compare("RWV") == 0) + { + canRead = true; } else { canRead = false; } } return canRead; } - MitkDICOMQIIOMimeTypes::MitkDICOMSEGMimeType *MitkDICOMQIIOMimeTypes::MitkDICOMSEGMimeType::Clone() const + MitkDICOMPMIOMimeTypes::MitkDICOMPMMimeType *MitkDICOMPMIOMimeTypes::MitkDICOMPMMimeType::Clone() const { - return new MitkDICOMSEGMimeType(*this); + return new MitkDICOMPMMimeType(*this); } - MitkDICOMQIIOMimeTypes::MitkDICOMSEGMimeType MitkDICOMQIIOMimeTypes::DICOMSEG_MIMETYPE() + MitkDICOMPMIOMimeTypes::MitkDICOMPMMimeType MitkDICOMPMIOMimeTypes::DICOMPM_MIMETYPE() { - return MitkDICOMSEGMimeType(); + return MitkDICOMPMMimeType(); } - std::string MitkDICOMQIIOMimeTypes::DICOMSEG_MIMETYPE_NAME() + // Names + std::string MitkDICOMPMIOMimeTypes::DICOMPM_MIMETYPE_NAME() { // create a unique and sensible name for this mime type - static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".image.dicom.seg"; + static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".image.dicom.pm"; return name; } - - - //======= Mime Type DICOM PM ======= - //... } diff --git a/Modules/DICOMQI/mitkDICOMQIIOMimeTypes.h b/Modules/Pharmacokinetics/autoload/DICOMPMIO/mitkDICOMPMIOMimeTypes.h similarity index 60% copy from Modules/DICOMQI/mitkDICOMQIIOMimeTypes.h copy to Modules/Pharmacokinetics/autoload/DICOMPMIO/mitkDICOMPMIOMimeTypes.h index b0b85eed5a..3112731e3a 100644 --- a/Modules/DICOMQI/mitkDICOMQIIOMimeTypes.h +++ b/Modules/Pharmacokinetics/autoload/DICOMPMIO/mitkDICOMPMIOMimeTypes.h @@ -1,71 +1,53 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#ifndef MITKDICOMQIIOMIMETYPES_H -#define MITKDICOMQIIOMIMETYPES_H +#ifndef MITKDICOMOMIOMIMETYPES_H +#define MITKDICOMPMIOMIMETYPES_H #include "mitkCustomMimeType.h" -#include - #include namespace mitk { - /// Provides the custom mime types for dicom qi objects loaded with DCMQI - class MITKDICOMQI_EXPORT MitkDICOMQIIOMimeTypes + /// Provides the custom mime types for dicom segmentation objects loaded with DCMQI + class MitkDICOMPMIOMimeTypes { public: /** Mime type that parses dicom files to determine whether they are dicom segmentation objects. */ - class MITKDICOMQI_EXPORT MitkDICOMSEGMimeType : public CustomMimeType - { - public: - MitkDICOMSEGMimeType(); - bool AppliesTo(const std::string &path) const override; - MitkDICOMSEGMimeType *Clone() const override; - }; - - static MitkDICOMSEGMimeType DICOMSEG_MIMETYPE(); - static std::string DICOMSEG_MIMETYPE_NAME(); - - /** Mime type that parses dicom files to determine whether they are dicom pm objects. - */ - /* class MitkDICOMPMMimeType : public CustomMimeType { public: MitkDICOMPMMimeType(); virtual bool AppliesTo(const std::string &path) const override; virtual MitkDICOMPMMimeType *Clone() const override; }; static MitkDICOMPMMimeType DICOMPM_MIMETYPE(); static std::string DICOMPM_MIMETYPE_NAME(); - */ - // Get all Mime Types static std::vector Get(); private: // purposely not implemented - MitkDICOMQIIOMimeTypes(); - MitkDICOMQIIOMimeTypes(const MitkDICOMQIIOMimeTypes &); + MitkDICOMPMIOMimeTypes(); + MitkDICOMPMIOMimeTypes(const MitkDICOMPMIOMimeTypes &); }; } #endif // MITKDICOMQIIOMIMETYPES_H diff --git a/Modules/Pharmacokinetics/files.cmake b/Modules/Pharmacokinetics/files.cmake index b31eb1585c..1b18f9974f 100644 --- a/Modules/Pharmacokinetics/files.cmake +++ b/Modules/Pharmacokinetics/files.cmake @@ -1,60 +1,70 @@ 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 + Common/mitkDICOMPMConstants.cpp + Common/mitkDICOMPMPropertyHandler.cpp + Common/mitkParamapPresets.cpp DescriptionParameters/mitkCurveDescriptionParameterBase.cpp DescriptionParameters/mitkAreaUnderTheCurveDescriptionParameter.cpp DescriptionParameters/mitkAreaUnderFirstMomentDescriptionParameter.cpp DescriptionParameters/mitkMeanResidenceTimeDescriptionParameter.cpp DescriptionParameters/mitkTimeToPeakCurveDescriptionParameter.cpp DescriptionParameters/mitkMaximumCurveDescriptionParameter.cpp Functors/mitkCurveParameterFunctor.cpp Models/mitkAIFBasedModelBase.cpp Models/mitkDescriptivePharmacokineticBrixModel.cpp Models/mitkDescriptivePharmacokineticBrixModelFactory.cpp Models/mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer.cpp Models/mitkDescriptivePharmacokineticBrixModelParameterizer.cpp Models/mitkThreeStepLinearModel.cpp Models/mitkThreeStepLinearModelFactory.cpp Models/mitkThreeStepLinearModelParameterizer.cpp Models/mitkTwoCompartmentExchangeModel.cpp Models/mitkTwoCompartmentExchangeModelFactory.cpp Models/mitkTwoCompartmentExchangeModelParameterizer.cpp Models/mitkNumericTwoCompartmentExchangeModel.cpp Models/mitkNumericTwoCompartmentExchangeModelFactory.cpp Models/mitkNumericTwoCompartmentExchangeModelParameterizer.cpp Models/mitkExtendedToftsModel.cpp Models/mitkExtendedToftsModelFactory.cpp Models/mitkExtendedToftsModelParameterizer.cpp Models/mitkStandardToftsModel.cpp Models/mitkStandardToftsModelFactory.cpp Models/mitkStandardToftsModelParameterizer.cpp Models/mitkOneTissueCompartmentModel.cpp Models/mitkOneTissueCompartmentModelFactory.cpp Models/mitkOneTissueCompartmentModelParameterizer.cpp Models/mitkExtendedOneTissueCompartmentModel.cpp Models/mitkExtendedOneTissueCompartmentModelFactory.cpp Models/mitkExtendedOneTissueCompartmentModelParameterizer.cpp Models/mitkTwoTissueCompartmentModel.cpp Models/mitkTwoTissueCompartmentModelFactory.cpp Models/mitkTwoTissueCompartmentModelParameterizer.cpp Models/mitkTwoTissueCompartmentFDGModel.cpp Models/mitkTwoTissueCompartmentFDGModelFactory.cpp Models/mitkTwoTissueCompartmentFDGModelParameterizer.cpp Models/mitkNumericTwoTissueCompartmentModel.cpp Models/mitkNumericTwoTissueCompartmentModelFactory.cpp Models/mitkNumericTwoTissueCompartmentModelParameterizer.cpp SimulationFramework/mitkPerfusionDataGenerator.cpp SimulationFramework/mitkImageGenerationHelper.cpp ) set(HXX_FILES +mitkDICOMSegmentationConstants.h + ) set(MOC_H_FILES ) + +set(RESOURCE_FILES +mitkParamapPresets.xml +) + diff --git a/Modules/Pharmacokinetics/include/mitkDICOMPMConstants.h b/Modules/Pharmacokinetics/include/mitkDICOMPMConstants.h new file mode 100644 index 0000000000..7fca2d22cb --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkDICOMPMConstants.h @@ -0,0 +1,74 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef MITKDICOMPMCONSTANTS_H_ +#define MITKDICOMPMCONSTANTS_H_ + +#include + +#include + + +namespace mitk +{ + struct MITKPHARMACOKINETICS_EXPORT DICOMPMConstants + { + // IKO + static DICOMTagPath RWVM_SEQUENCE_PATH(); + + static DICOMTagPath UNITS_SEQUENCE_PATH(); + static DICOMTagPath UNITS_CODE_VALUE_PATH(); + static DICOMTagPath UNITS_CODE_SCHEME_PATH(); + static DICOMTagPath UNITS_CODE_MEANING_PATH(); + + static DICOMTagPath QUANTITY_DEFINITION_SEQUENCE_PATH(); + static DICOMTagPath QUANTITY_DEFINITION_VALUE_TYPE_PATH(); + + static DICOMTagPath QUANTITY_DEFINITION_CONCEPT_CODE_SEQUENCE_PATH(); + static DICOMTagPath QUANTITY_DEFINITION_CONCEPT_CODE_VALUE_PATH(); + static DICOMTagPath QUANTITY_DEFINITION_CONCEPT_CODE_SCHEME_PATH(); + static DICOMTagPath QUANTITY_DEFINITION_CONCEPT_CODE_MEANING_PATH(); + + static DICOMTagPath SEGMENT_SEQUENCE_PATH(); + static DICOMTagPath SEGMENT_NUMBER_PATH(); + static DICOMTagPath SEGMENT_LABEL_PATH(); + static DICOMTagPath SEGMENT_ALGORITHM_TYPE_PATH(); + + static DICOMTagPath ANATOMIC_REGION_SEQUENCE_PATH(); + static DICOMTagPath ANATOMIC_REGION_CODE_VALUE_PATH(); + static DICOMTagPath ANATOMIC_REGION_CODE_SCHEME_PATH(); + static DICOMTagPath ANATOMIC_REGION_CODE_MEANING_PATH(); + + static DICOMTagPath SEGMENTED_PROPERTY_CATEGORY_SEQUENCE_PATH(); + static DICOMTagPath SEGMENT_CATEGORY_CODE_VALUE_PATH(); + static DICOMTagPath SEGMENT_CATEGORY_CODE_SCHEME_PATH(); + static DICOMTagPath SEGMENT_CATEGORY_CODE_MEANING_PATH(); + + static DICOMTagPath SEGMENTED_PROPERTY_TYPE_SEQUENCE_PATH(); + static DICOMTagPath SEGMENT_TYPE_CODE_VALUE_PATH(); + static DICOMTagPath SEGMENT_TYPE_CODE_SCHEME_PATH(); + static DICOMTagPath SEGMENT_TYPE_CODE_MEANING_PATH(); + + static DICOMTagPath SEGMENTED_PROPERTY_MODIFIER_SEQUENCE_PATH(); + static DICOMTagPath SEGMENT_MODIFIER_CODE_VALUE_PATH(); + static DICOMTagPath SEGMENT_MODIFIER_CODE_SCHEME_PATH(); + static DICOMTagPath SEGMENT_MODIFIER_CODE_MEANING_PATH(); + + + }; +} + +#endif // MITKDICOMSEGMENTATIONCONSTANTS_H_ diff --git a/Modules/Multilabel/mitkDICOMSegmentationPropertyHelper.h b/Modules/Pharmacokinetics/include/mitkDICOMPMPropertyHandler.h similarity index 53% copy from Modules/Multilabel/mitkDICOMSegmentationPropertyHelper.h copy to Modules/Pharmacokinetics/include/mitkDICOMPMPropertyHandler.h index 76c9abbaa0..bb4030dce3 100644 --- a/Modules/Multilabel/mitkDICOMSegmentationPropertyHelper.h +++ b/Modules/Pharmacokinetics/include/mitkDICOMPMPropertyHandler.h @@ -1,35 +1,38 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef DICOMSEGMENTATIONPROPERTYHANDLER_H_ #define DICOMSEGMENTATIONPROPERTYHANDLER_H_ #include -#include -#include +//#include +//#include -#include +#include namespace mitk { - class MITKMULTILABEL_EXPORT DICOMSegmentationPropertyHandler + class MITKPHARMACOKINETICS_EXPORT DICOMPMPropertyHandler { public: - static void DeriveDICOMSegmentationProperties(LabelSetImage* dicomSegImage); - static void SetDICOMSegmentProperties(Label *label); + static PropertyList::Pointer GetDICOMPMProperties(PropertyList *referencedPropertyList); + static void SetReferenceDICOMProperty(PropertyList *referencedPropertyList, + PropertyList *propertyList, + const DICOMTag &tag, + const std::string &defaultString = ""); }; -} +} // namespace mitk #endif diff --git a/Modules/Pharmacokinetics/include/mitkParamapPresets.h b/Modules/Pharmacokinetics/include/mitkParamapPresets.h new file mode 100644 index 0000000000..01c21e107b --- /dev/null +++ b/Modules/Pharmacokinetics/include/mitkParamapPresets.h @@ -0,0 +1,74 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef PARAMAPRPRESETS_H_HEADER +#define PARAMAPPRESETS_H_HEADER + +#include +#include +#include +#include +#include + +namespace mitk { + +class MITKPHARMACOKINETICS_EXPORT ParamapPresets : public vtkXMLParser +{ +public: + struct Type + { + std::string codeValue; + std::string codeScheme; + Type() = default; + Type(std::string value, std::string scheme) : codeValue(value), codeScheme(scheme){} + }; + + static ParamapPresets *New(); + vtkTypeMacro(ParamapPresets,vtkXMLParser); + + bool LoadPreset(); + bool LoadPreset(const std::string& fileName); + Type GetType(const std::string& name); + std::map const GetTypePresets(); + void NewPresets(std::map& newType); + + +protected: + ParamapPresets() = default; + ~ParamapPresets() override = default; + +private: + //##Documentation + //## @brief method used in XLM-Reading; gets called when a start-tag is read + void StartElement (const char *elementName, const char **atts) override; + + void Save(); + + //##Documentation + //## @brief reads an XML-String-Attribute + std::string ReadXMLStringAttribute(const std::string& name, const char **atts); + + static const std::string PRESET; + static const std::string TYPE; + static const std::string CODE_VALUE; + static const std::string CODE_SCHEME; + + std::string m_presetName; + std::map m_Type; + std::string m_XmlFileName; +}; +} +#endif diff --git a/Modules/Pharmacokinetics/resource/mitkParamapPresets.xml b/Modules/Pharmacokinetics/resource/mitkParamapPresets.xml new file mode 100644 index 0000000000..0e37758a9d --- /dev/null +++ b/Modules/Pharmacokinetics/resource/mitkParamapPresets.xml @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Modules/Pharmacokinetics/src/Common/mitkDICOMPMConstants.cpp b/Modules/Pharmacokinetics/src/Common/mitkDICOMPMConstants.cpp new file mode 100644 index 0000000000..7fb945dedf --- /dev/null +++ b/Modules/Pharmacokinetics/src/Common/mitkDICOMPMConstants.cpp @@ -0,0 +1,243 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkDICOMPMConstants.h" + +namespace mitk +{ + // IKO + DICOMTagPath DICOMPMConstants::RWVM_SEQUENCE_PATH() + { + static DICOMTagPath path = DICOMTagPath().AddElement(0x0040, 0x9096); + return path; + } + // IKO + DICOMTagPath DICOMPMConstants::UNITS_SEQUENCE_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::RWVM_SEQUENCE_PATH()).AddElement(0x0040, 0x08EA); + return path; + } + // IKO + DICOMTagPath DICOMPMConstants::UNITS_CODE_VALUE_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::UNITS_SEQUENCE_PATH()).AddElement(0x0008, 0x0100); + return path; + } + // IKO + DICOMTagPath DICOMPMConstants::UNITS_CODE_SCHEME_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::UNITS_SEQUENCE_PATH()).AddElement(0x0008, 0x0102); + return path; + } + // IKO + DICOMTagPath DICOMPMConstants::UNITS_CODE_MEANING_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::UNITS_SEQUENCE_PATH()).AddElement(0x0008, 0x0104); + return path; + } + + // IKO + DICOMTagPath DICOMPMConstants::QUANTITY_DEFINITION_SEQUENCE_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::RWVM_SEQUENCE_PATH()).AddElement(0x0040, 0x9220); + return path; + } + // IKO + DICOMTagPath DICOMPMConstants::QUANTITY_DEFINITION_VALUE_TYPE_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::QUANTITY_DEFINITION_SEQUENCE_PATH()).AddElement(0x0040, 0xA040); + return path; + } + // IKO + DICOMTagPath DICOMPMConstants::QUANTITY_DEFINITION_CONCEPT_CODE_SEQUENCE_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::QUANTITY_DEFINITION_SEQUENCE_PATH()).AddElement(0x0040, 0xA168); + return path; + } + // IKO + DICOMTagPath DICOMPMConstants::QUANTITY_DEFINITION_CONCEPT_CODE_VALUE_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::QUANTITY_DEFINITION_CONCEPT_CODE_SEQUENCE_PATH()).AddElement(0x0008, 0x0100); + return path; + } + // IKO + DICOMTagPath DICOMPMConstants::QUANTITY_DEFINITION_CONCEPT_CODE_SCHEME_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::QUANTITY_DEFINITION_CONCEPT_CODE_SEQUENCE_PATH()).AddElement(0x0008, 0x0102); + return path; + } + // IKO + DICOMTagPath DICOMPMConstants::QUANTITY_DEFINITION_CONCEPT_CODE_MEANING_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::QUANTITY_DEFINITION_CONCEPT_CODE_SEQUENCE_PATH()).AddElement(0x0008, 0x0104); + return path; + } + + + +/* + DICOMTagPath DICOMPMConstants::SEGMENT_SEQUENCE_PATH() + { + static DICOMTagPath path = DICOMTagPath().AddElement(0x0062, 0x0002); + return path; + } + + DICOMTagPath DICOMPMConstants::SEGMENT_NUMBER_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENT_SEQUENCE_PATH()).AddElement(0x0062, 0x0004); + return path; + } + + DICOMTagPath DICOMPMConstants::SEGMENT_LABEL_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENT_SEQUENCE_PATH()).AddElement(0x0062, 0x0005); + return path; + } + + DICOMTagPath DICOMPMConstants::SEGMENT_ALGORITHM_TYPE_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENT_SEQUENCE_PATH()).AddElement(0x0062, 0x0008); + return path; + } + + DICOMTagPath DICOMPMConstants::ANATOMIC_REGION_SEQUENCE_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENT_SEQUENCE_PATH()).AddElement(0x0008, 0x2218); + return path; + } + + DICOMTagPath DICOMPMConstants::ANATOMIC_REGION_CODE_VALUE_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::ANATOMIC_REGION_SEQUENCE_PATH()).AddElement(0x008, 0x0100); + return path; + } + + DICOMTagPath DICOMPMConstants::ANATOMIC_REGION_CODE_SCHEME_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::ANATOMIC_REGION_SEQUENCE_PATH()).AddElement(0x008, 0x0102); + return path; + } + + DICOMTagPath DICOMPMConstants::ANATOMIC_REGION_CODE_MEANING_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::ANATOMIC_REGION_SEQUENCE_PATH()).AddElement(0x008, 0x0104); + return path; + } + + DICOMTagPath DICOMPMConstants::SEGMENTED_PROPERTY_CATEGORY_SEQUENCE_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENT_SEQUENCE_PATH()).AddElement(0x0062, 0x0003); + return path; + } + + DICOMTagPath DICOMPMConstants::SEGMENT_CATEGORY_CODE_VALUE_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENTED_PROPERTY_CATEGORY_SEQUENCE_PATH()).AddElement(0x008, 0x0100); + return path; + } + + DICOMTagPath DICOMPMConstants::SEGMENT_CATEGORY_CODE_SCHEME_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENTED_PROPERTY_CATEGORY_SEQUENCE_PATH()).AddElement(0x008, 0x0102); + return path; + } + + DICOMTagPath DICOMPMConstants::SEGMENT_CATEGORY_CODE_MEANING_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENTED_PROPERTY_CATEGORY_SEQUENCE_PATH()).AddElement(0x008, 0x0104); + return path; + } + + DICOMTagPath DICOMPMConstants::SEGMENTED_PROPERTY_TYPE_SEQUENCE_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENT_SEQUENCE_PATH()).AddElement(0x0062, 0x000F); + return path; + } + + DICOMTagPath DICOMPMConstants::SEGMENT_TYPE_CODE_VALUE_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENTED_PROPERTY_TYPE_SEQUENCE_PATH()).AddElement(0x008, 0x0100); + return path; + } + + DICOMTagPath DICOMPMConstants::SEGMENT_TYPE_CODE_SCHEME_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENTED_PROPERTY_TYPE_SEQUENCE_PATH()).AddElement(0x008, 0x0102); + return path; + } + + DICOMTagPath DICOMPMConstants::SEGMENT_TYPE_CODE_MEANING_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENTED_PROPERTY_TYPE_SEQUENCE_PATH()).AddElement(0x008, 0x0104); + return path; + } + + DICOMTagPath DICOMPMConstants::SEGMENTED_PROPERTY_MODIFIER_SEQUENCE_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENTED_PROPERTY_TYPE_SEQUENCE_PATH()).AddElement(0x0062, 0x0011); + return path; + } + + DICOMTagPath DICOMPMConstants::SEGMENT_MODIFIER_CODE_VALUE_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENTED_PROPERTY_MODIFIER_SEQUENCE_PATH()).AddElement(0x008, 0x0100); + return path; + } + + DICOMTagPath DICOMPMConstants::SEGMENT_MODIFIER_CODE_SCHEME_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENTED_PROPERTY_MODIFIER_SEQUENCE_PATH()).AddElement(0x008, 0x0102); + return path; + } + + DICOMTagPath DICOMPMConstants::SEGMENT_MODIFIER_CODE_MEANING_PATH() + { + static DICOMTagPath path = + DICOMTagPath(DICOMPMConstants::SEGMENTED_PROPERTY_MODIFIER_SEQUENCE_PATH()).AddElement(0x008, 0x0104); + return path; + } +*/ + + +} diff --git a/Modules/Pharmacokinetics/src/Common/mitkDICOMPMPropertyHandler.cpp b/Modules/Pharmacokinetics/src/Common/mitkDICOMPMPropertyHandler.cpp new file mode 100644 index 0000000000..7389f902b0 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Common/mitkDICOMPMPropertyHandler.cpp @@ -0,0 +1,134 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +// us +#include +#include + +namespace mitk +{ + PropertyList::Pointer DICOMPMPropertyHandler::GetDICOMPMProperties(PropertyList *referencedPropertyList) + { + + PropertyList::Pointer propertyList = PropertyList::New(); + + // Add DICOM Tag (0008, 0060) Modality "SEG" + propertyList->SetProperty(GeneratePropertyNameForDICOMTag(0x0008, 0x0060).c_str(), + TemporoSpatialStringProperty::New("PM")); + // Add DICOM Tag (0008,103E) Series Description + propertyList->SetProperty(GeneratePropertyNameForDICOMTag(0x0008, 0x103E).c_str(), + TemporoSpatialStringProperty::New("MITK Parameter Map")); + // Add DICOM Tag (0070,0084) Content Creator Name + propertyList->SetProperty(GeneratePropertyNameForDICOMTag(0x0070, 0x0084).c_str(), + TemporoSpatialStringProperty::New("MITK")); + // Add DICOM Tag (0012, 0071) Clinical Trial Series ID + propertyList->SetProperty(GeneratePropertyNameForDICOMTag(0x0012, 0x0071).c_str(), + TemporoSpatialStringProperty::New("Session 1")); + // Add DICOM Tag (0012,0050) Clinical Trial Time Point ID + propertyList->SetProperty(GeneratePropertyNameForDICOMTag(0x0012, 0x0050).c_str(), + TemporoSpatialStringProperty::New("0")); + // Add DICOM Tag (0012, 0060) Clinical Trial Coordinating Center Name + propertyList->SetProperty(GeneratePropertyNameForDICOMTag(0x0012, 0x0060).c_str(), + TemporoSpatialStringProperty::New("Unknown")); + + // Check if original image is a DICOM image; if so, store relevant DICOM Tags into the PropertyList of new + // PM image + bool parentIsDICOM = false; + + for (const auto &element : *(referencedPropertyList->GetMap())) + { + if (element.first.find("DICOM") == 0) + { + parentIsDICOM = true; + break; + } + } + + if (!parentIsDICOM) + return propertyList; + + //====== Patient information ====== + + // Add DICOM Tag (0010,0010) patient's name; default "No Name" + DICOMPMPropertyHandler::SetReferenceDICOMProperty( + referencedPropertyList, propertyList, DICOMTag(0x0010, 0x0010), "NO NAME"); + // Add DICOM Tag (0010,0020) patient id; default "No Name" + DICOMPMPropertyHandler::SetReferenceDICOMProperty( + referencedPropertyList, propertyList, DICOMTag(0x0010, 0x0020), "NO NAME"); + // Add DICOM Tag (0010,0030) patient's birth date; no default + DICOMPMPropertyHandler::SetReferenceDICOMProperty(referencedPropertyList, propertyList, DICOMTag(0x0010, 0x0030)); + // Add DICOM Tag (0010,0040) patient's sex; default "U" (Unknown) + DICOMPMPropertyHandler::SetReferenceDICOMProperty( + referencedPropertyList, propertyList, DICOMTag(0x0010, 0x0040), "U"); + + //====== General study ====== + + // Add DICOM Tag (0020,000D) Study Instance UID; no default --> MANDATORY! + DICOMPMPropertyHandler::SetReferenceDICOMProperty(referencedPropertyList, propertyList, DICOMTag(0x0020, 0x000D)); + // Add DICOM Tag (0080,0020) Study Date; no default (think about "today") + DICOMPMPropertyHandler::SetReferenceDICOMProperty(referencedPropertyList, propertyList, DICOMTag(0x0080, 0x0020)); + // Add DICOM Tag (0008,0050) Accession Number; no default + DICOMPMPropertyHandler:: SetReferenceDICOMProperty(referencedPropertyList, propertyList, DICOMTag(0x0008, 0x0050)); + // Add DICOM Tag (0008,1030) Study Description; no default + DICOMPMPropertyHandler::SetReferenceDICOMProperty(referencedPropertyList, propertyList, DICOMTag(0x0008, 0x1030)); + + //====== Reference DICOM data ====== + + // Add reference file paths to referenced DICOM data + BaseProperty::Pointer dcmFilesProp = referencedPropertyList->GetProperty("files"); + if (dcmFilesProp.IsNotNull()) + propertyList->SetProperty("referenceFiles", dcmFilesProp); + + return propertyList; + } + + void DICOMPMPropertyHandler::SetReferenceDICOMProperty(PropertyList *referencedPropertyList, + PropertyList *propertyList, + const DICOMTag &tag, + const std::string &defaultString) + { + + std::string tagString = GeneratePropertyNameForDICOMTag(tag.GetGroup(), tag.GetElement()); + + // Get DICOM property from referenced image + BaseProperty::Pointer originalProperty = referencedPropertyList->GetProperty(tagString.c_str()); + + // if property exists, copy the informtaion to the segmentation + if (originalProperty.IsNotNull()) + propertyList->SetProperty(tagString.c_str(), originalProperty); + else // use the default value, if there is one + { + if (!defaultString.empty()) + propertyList->SetProperty(tagString.c_str(), TemporoSpatialStringProperty::New(defaultString).GetPointer()); + } + + } +} // namespace mitk diff --git a/Modules/Pharmacokinetics/src/Common/mitkParamapPresets.cpp b/Modules/Pharmacokinetics/src/Common/mitkParamapPresets.cpp new file mode 100644 index 0000000000..ef10be3c89 --- /dev/null +++ b/Modules/Pharmacokinetics/src/Common/mitkParamapPresets.cpp @@ -0,0 +1,132 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkParamapPresets.h" +#include + +#include "usGetModuleContext.h" +#include "usModuleContext.h" +#include "usModule.h" +#include "usModuleResource.h" +#include "usModuleResourceStream.h" + +namespace mitk { + + const std::string ParamapPresets::PRESET = "preset"; + const std::string ParamapPresets::TYPE = "type"; + const std::string ParamapPresets::CODE_VALUE = "code_value"; + const std::string ParamapPresets::CODE_SCHEME = "coding_scheme"; + + vtkStandardNewMacro(ParamapPresets); + + bool ParamapPresets::LoadPreset() + { + us::ModuleResource presetResource = us::GetModuleContext()->GetModule()->GetResource("mitkParamapPresets.xml"); + if (!presetResource) return false; + + us::ModuleResourceStream presetStream(presetResource); + vtkXMLParser::SetStream(&presetStream); + if (!vtkXMLParser::Parse()) + { +#ifdef INTERDEBUG + MITK_INFO<<"ParamapPresets::LoadPreset xml file cannot parse!"< const ParamapPresets::GetTypePresets() + { + return m_Type; + } + + + + void ParamapPresets::Save() + { + //Not yet implemented + } + + void ParamapPresets::NewPresets(std::map& newType) + { + m_Type = newType; + this->Save(); + } + +} 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 e197e697c0..49d95576c9 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,1400 +1,1419 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "MRPerfusionView.h" #include "boost/tokenizer.hpp" #include "boost/math/constants/constants.hpp" #include #include "mitkWorkbenchUtil.h" #include "mitkAterialInputFunctionGenerator.h" #include "mitkConcentrationCurveGenerator.h" #include #include #include #include "mitkThreeStepLinearModelFactory.h" #include "mitkThreeStepLinearModelParameterizer.h" #include #include #include #include #include "mitkTwoCompartmentExchangeModelFactory.h" #include "mitkTwoCompartmentExchangeModelParameterizer.h" #include "mitkNumericTwoCompartmentExchangeModelFactory.h" #include "mitkNumericTwoCompartmentExchangeModelParameterizer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Includes for image casting between ITK and MITK #include #include "mitkImageCast.h" #include "mitkITKImageImport.h" #include #include +#include + const std::string MRPerfusionView::VIEW_ID = "org.mitk.gui.qt.pharmacokinetics.mri"; inline double convertToDouble(const std::string& data) { std::istringstream stepStream(data); stepStream.imbue(std::locale("C")); double value = 0.0; if (!(stepStream >> value) || !(stepStream.eof())) { mitkThrow() << "Cannot convert string to double. String: " << data; } return value; } void MRPerfusionView::SetFocus() { m_Controls.btnModelling->setFocus(); } void MRPerfusionView::CreateQtPartControl(QWidget* parent) { m_Controls.setupUi(parent); m_Controls.btnModelling->setEnabled(false); m_Controls.errorMessageLabel->hide(); this->InitModelComboBox(); connect(m_Controls.btnModelling, SIGNAL(clicked()), this, SLOT(OnModellingButtonClicked())); connect(m_Controls.comboModel, SIGNAL(currentIndexChanged(int)), this, SLOT(OnModellSet(int))); connect(m_Controls.radioPixelBased, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); //AIF setting m_Controls.groupAIF->hide(); m_Controls.btnAIFFile->setEnabled(false); m_Controls.btnAIFFile->setEnabled(false); m_Controls.radioAIFImage->setChecked(true); m_Controls.comboAIFMask->SetDataStorage(this->GetDataStorage()); m_Controls.comboAIFMask->SetPredicate(m_IsMaskPredicate); m_Controls.comboAIFMask->setVisible(true); m_Controls.comboAIFMask->setEnabled(true); m_Controls.comboAIFImage->SetDataStorage(this->GetDataStorage()); m_Controls.comboAIFImage->SetPredicate(m_IsNoMaskImagePredicate); m_Controls.comboAIFImage->setEnabled(false); m_Controls.checkDedicatedAIFImage->setEnabled(true); m_Controls.HCLSpinBox->setValue(mitk::AterialInputFunctionGenerator::DEFAULT_HEMATOCRIT_LEVEL); connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.comboAIFMask, SLOT(setVisible(bool))); connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.labelAIFMask, SLOT(setVisible(bool))); connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.checkDedicatedAIFImage, SLOT(setVisible(bool))); connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.comboAIFMask, SLOT(setEnabled(bool))); connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.checkDedicatedAIFImage, SLOT(setEnabled(bool))); connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.checkDedicatedAIFImage, SLOT(setVisible(bool))); connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), m_Controls.comboAIFImage, SLOT(setVisible(bool))); connect(m_Controls.checkDedicatedAIFImage, SIGNAL(toggled(bool)), m_Controls.comboAIFImage, SLOT(setEnabled(bool))); connect(m_Controls.radioAIFImage, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); connect(m_Controls.radioAIFFile, SIGNAL(toggled(bool)), m_Controls.btnAIFFile, SLOT(setEnabled(bool))); connect(m_Controls.radioAIFFile, SIGNAL(toggled(bool)), m_Controls.aifFilePath, SLOT(setEnabled(bool))); connect(m_Controls.radioAIFFile, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); connect(m_Controls.btnAIFFile, SIGNAL(clicked()), this, SLOT(LoadAIFfromFile())); //Brix setting m_Controls.groupDescBrix->hide(); connect(m_Controls.injectiontime, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); //Num2CX setting m_Controls.groupNum2CXM->hide(); connect(m_Controls.odeStepSize, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); //Model fit configuration m_Controls.groupBox_FitConfiguration->hide(); m_Controls.checkBox_Constraints->setEnabled(false); m_Controls.constraintManager->setEnabled(false); m_Controls.initialValuesManager->setEnabled(false); m_Controls.initialValuesManager->setDataStorage(this->GetDataStorage()); connect(m_Controls.radioButton_StartParameters, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); connect(m_Controls.checkBox_Constraints, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); connect(m_Controls.initialValuesManager, SIGNAL(initialValuesChanged(void)), this, SLOT(UpdateGUIControls())); connect(m_Controls.radioButton_StartParameters, SIGNAL(toggled(bool)), m_Controls.initialValuesManager, SLOT(setEnabled(bool))); connect(m_Controls.checkBox_Constraints, SIGNAL(toggled(bool)), m_Controls.constraintManager, SLOT(setEnabled(bool))); connect(m_Controls.checkBox_Constraints, SIGNAL(toggled(bool)), m_Controls.constraintManager, SLOT(setVisible(bool))); //Concentration m_Controls.groupConcentration->hide(); m_Controls.groupBoxTurboFlash->hide(); m_Controls.radioButtonNoConversion->setChecked(true); m_Controls.factorSpinBox->setEnabled(false); m_Controls.groupBox_viaT1Map->hide(); connect(m_Controls.radioButtonTurboFlash, SIGNAL(toggled(bool)), m_Controls.groupBoxTurboFlash, SLOT(setVisible(bool))); connect(m_Controls.radioButtonTurboFlash, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); connect(m_Controls.relaxationtime, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); connect(m_Controls.recoverytime, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); connect(m_Controls.relaxivity, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); connect(m_Controls.radioButton_absoluteEnhancement, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); connect(m_Controls.radioButton_relativeEnchancement, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); connect(m_Controls.radioButton_absoluteEnhancement, SIGNAL(toggled(bool)), m_Controls.factorSpinBox, SLOT(setEnabled(bool))); connect(m_Controls.radioButton_relativeEnchancement, SIGNAL(toggled(bool)), m_Controls.factorSpinBox, SLOT(setEnabled(bool))); connect(m_Controls.factorSpinBox, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); connect(m_Controls.radioButtonUsingT1, SIGNAL(toggled(bool)), m_Controls.groupBox_viaT1Map, SLOT(setVisible(bool))); connect(m_Controls.radioButtonUsingT1, SIGNAL(toggled(bool)), this, SLOT(UpdateGUIControls())); connect(m_Controls.FlipangleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); connect(m_Controls.RelaxivitySpinBox, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); connect(m_Controls.TRSpinBox, SIGNAL(valueChanged(double)), this, SLOT(UpdateGUIControls())); m_Controls.ComboT1Map->SetDataStorage(this->GetDataStorage()); m_Controls.ComboT1Map->SetPredicate(m_IsNoMaskImagePredicate); m_Controls.ComboT1Map->setEnabled(false); connect(m_Controls.radioButtonUsingT1, SIGNAL(toggled(bool)), m_Controls.ComboT1Map, SLOT(setEnabled(bool))); UpdateGUIControls(); } bool MRPerfusionView::IsTurboFlashSequenceFlag() const { return this->m_Controls.radioButtonTurboFlash->isChecked(); }; void MRPerfusionView::UpdateGUIControls() { m_Controls.lineFitName->setPlaceholderText(QString::fromStdString(this->GetDefaultFitName())); m_Controls.lineFitName->setEnabled(!m_FittingInProgress); m_Controls.checkBox_Constraints->setEnabled(m_modelConstraints.IsNotNull()); bool isDescBrixFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL; bool isToftsFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL || dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL; bool is2CXMFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL || dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL; bool isNum2CXMFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL; m_Controls.groupAIF->setVisible(isToftsFactory || is2CXMFactory); m_Controls.groupDescBrix->setVisible(isDescBrixFactory); m_Controls.groupNum2CXM->setVisible(isNum2CXMFactory); m_Controls.groupConcentration->setVisible(isToftsFactory || is2CXMFactory); m_Controls.groupBox_FitConfiguration->setVisible(m_selectedModelFactory); m_Controls.groupBox->setEnabled(!m_FittingInProgress); m_Controls.comboModel->setEnabled(!m_FittingInProgress); m_Controls.groupAIF->setEnabled(!m_FittingInProgress); m_Controls.groupDescBrix->setEnabled(!m_FittingInProgress); m_Controls.groupNum2CXM->setEnabled(!m_FittingInProgress); m_Controls.groupConcentration->setEnabled(!m_FittingInProgress); m_Controls.groupBox_FitConfiguration->setEnabled(!m_FittingInProgress); m_Controls.radioROIbased->setEnabled(m_selectedMask.IsNotNull()); m_Controls.btnModelling->setEnabled(m_selectedImage.IsNotNull() && m_selectedModelFactory.IsNotNull() && !m_FittingInProgress && CheckModelSettings()); } void MRPerfusionView::OnModellSet(int index) { m_selectedModelFactory = NULL; if (index > 0) { if (static_cast(index) <= m_FactoryStack.size() ) { m_selectedModelFactory = m_FactoryStack[index - 1]; } else { MITK_WARN << "Invalid model index. Index outside of the factory stack. Factory stack size: "<< m_FactoryStack.size() << "; invalid index: "<< index; } } if (m_selectedModelFactory) { this->m_modelConstraints = dynamic_cast (m_selectedModelFactory->CreateDefaultConstraints().GetPointer()); m_Controls.initialValuesManager->setInitialValues(m_selectedModelFactory->GetParameterNames(), m_selectedModelFactory->GetDefaultInitialParameterization()); if (this->m_modelConstraints.IsNull()) { this->m_modelConstraints = mitk::SimpleBarrierConstraintChecker::New(); } m_Controls.constraintManager->setChecker(this->m_modelConstraints, this->m_selectedModelFactory->GetParameterNames()); } UpdateGUIControls(); } std::string MRPerfusionView::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()) { mitk::ParameterFitImageGeneratorBase::Pointer generator = NULL; mitk::modelFit::ModelFitInfo::Pointer fitSession = NULL; bool isDescBrixFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL; bool is3LinearFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL; bool isExtToftsFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL; bool isStanToftsFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL; bool is2CXMFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL; bool isNum2CXMFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL; if (isDescBrixFactory) { if (this->m_Controls.radioPixelBased->isChecked()) { GenerateDescriptiveBrixModel_PixelBased(fitSession, generator); } else { GenerateDescriptiveBrixModel_ROIBased(fitSession, generator); } } else if (is3LinearFactory) { if (this->m_Controls.radioPixelBased->isChecked()) { Generate3StepLinearModelFit_PixelBased(fitSession, generator); } else { Generate3StepLinearModelFit_ROIBased(fitSession, generator); } } else if (isStanToftsFactory) { if (this->m_Controls.radioPixelBased->isChecked()) { GenerateAIFbasedModelFit_PixelBased(fitSession, generator); } else { GenerateAIFbasedModelFit_ROIBased(fitSession, generator); } } else if (isExtToftsFactory) { if (this->m_Controls.radioPixelBased->isChecked()) { GenerateAIFbasedModelFit_PixelBased(fitSession, generator); } else { GenerateAIFbasedModelFit_ROIBased(fitSession, generator); } } else if (is2CXMFactory) { if (this->m_Controls.radioPixelBased->isChecked()) { GenerateAIFbasedModelFit_PixelBased(fitSession, generator); } else { GenerateAIFbasedModelFit_ROIBased(fitSession, generator); } } else if (isNum2CXMFactory) { if (this->m_Controls.radioPixelBased->isChecked()) { GenerateAIFbasedModelFit_PixelBased(fitSession, generator); } else { GenerateAIFbasedModelFit_ROIBased(fitSession, generator); } } //add other models with else if if (generator.IsNotNull() && fitSession.IsNotNull()) { m_FittingInProgress = true; UpdateGUIControls(); DoFit(fitSession, generator); } else { QMessageBox box; box.setText("Fitting error!"); box.setInformativeText("Could not establish fitting job. Error when setting ab generator, model parameterizer or session info."); box.setStandardButtons(QMessageBox::Ok); box.setDefaultButton(QMessageBox::Ok); box.setIcon(QMessageBox::Warning); box.exec(); } } else { QMessageBox box; box.setText("Static parameters for model are not set!"); box.setInformativeText("Some static parameters, that are needed for calculation are not set and equal to zero. Modeling not possible"); box.setStandardButtons(QMessageBox::Ok); box.setDefaultButton(QMessageBox::Ok); box.setIcon(QMessageBox::Warning); box.exec(); } } void MRPerfusionView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, const QList& selectedNodes) { m_selectedMaskNode = NULL; m_selectedMask = NULL; m_Controls.errorMessageLabel->setText(""); m_Controls.masklabel->setText("No (valid) mask selected."); m_Controls.timeserieslabel->setText("No (valid) series selected."); QList nodes = selectedNodes; if (nodes.size() > 0 && this->m_IsNoMaskImagePredicate->CheckNode(nodes.front())) { this->m_selectedNode = nodes.front(); auto selectedImage = dynamic_cast(this->m_selectedNode->GetData()); m_Controls.timeserieslabel->setText((this->m_selectedNode->GetName()).c_str()); if (selectedImage != this->m_selectedImage) { if (selectedImage) { this->m_Controls.initialValuesManager->setReferenceImageGeometry(selectedImage->GetGeometry()); } else { this->m_Controls.initialValuesManager->setReferenceImageGeometry(nullptr); } } this->m_selectedImage = selectedImage; nodes.pop_front(); } else { this->m_selectedNode = NULL; this->m_selectedImage = NULL; this->m_Controls.initialValuesManager->setReferenceImageGeometry(nullptr); } if (nodes.size() > 0 && this->m_IsMaskPredicate->CheckNode(nodes.front())) { this->m_selectedMaskNode = nodes.front(); this->m_selectedMask = dynamic_cast(this->m_selectedMaskNode->GetData()); if (this->m_selectedMask->GetTimeSteps() > 1) { MITK_INFO << "Selected mask has multiple timesteps. Only use first timestep to mask model fit. Mask name: " << m_selectedMaskNode->GetName(); mitk::ImageTimeSelector::Pointer maskedImageTimeSelector = mitk::ImageTimeSelector::New(); maskedImageTimeSelector->SetInput(this->m_selectedMask); maskedImageTimeSelector->SetTimeNr(0); maskedImageTimeSelector->UpdateLargestPossibleRegion(); this->m_selectedMask = maskedImageTimeSelector->GetOutput(); } m_Controls.masklabel->setText((this->m_selectedMaskNode->GetName()).c_str()); } if (m_selectedMask.IsNull()) { this->m_Controls.radioPixelBased->setChecked(true); } m_Controls.errorMessageLabel->show(); UpdateGUIControls(); } bool MRPerfusionView::CheckModelSettings() const { bool ok = true; //check wether any model is set at all. Otherwise exit with false if (m_selectedModelFactory.IsNotNull()) { bool isDescBrixFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL; bool is3LinearFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL; bool isToftsFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL|| dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL; bool is2CXMFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL; bool isNum2CXMFactory = dynamic_cast (m_selectedModelFactory.GetPointer()) != NULL; if (isDescBrixFactory) { //if all static parameters for this model are set, exit with true, Otherwise exit with false ok = m_Controls.injectiontime->value() > 0; } else if (is3LinearFactory) { if (this->m_Controls.radioButtonTurboFlash->isChecked()) { ok = ok && (m_Controls.recoverytime->value() > 0); ok = ok && (m_Controls.relaxationtime->value() > 0); ok = ok && (m_Controls.relaxivity->value() > 0); ok = ok && (m_Controls.AifRecoverytime->value() > 0); } else if (this->m_Controls.radioButton_absoluteEnhancement->isChecked() || this->m_Controls.radioButton_relativeEnchancement->isChecked()) { ok = ok && (m_Controls.factorSpinBox->value() > 0); } else if (this->m_Controls.radioButtonUsingT1->isChecked()) { ok = ok && (m_Controls.FlipangleSpinBox->value() > 0); ok = ok && (m_Controls.TRSpinBox->value() > 0); ok = ok && (m_Controls.RelaxivitySpinBox->value() > 0); ok = ok && (m_Controls.ComboT1Map->GetSelectedNode().IsNotNull()); } else if (this->m_Controls.radioButtonNoConversion->isChecked()) { ok = ok; } else { ok = false; } } else if (isToftsFactory || is2CXMFactory || isNum2CXMFactory) { if (this->m_Controls.radioAIFImage->isChecked()) { ok = ok && m_Controls.comboAIFMask->GetSelectedNode().IsNotNull(); if (this->m_Controls.checkDedicatedAIFImage->isChecked()) { ok = ok && m_Controls.comboAIFImage->GetSelectedNode().IsNotNull(); } } else if (this->m_Controls.radioAIFFile->isChecked()) { ok = ok && (this->AIFinputGrid.size() != 0) && (this->AIFinputFunction.size() != 0); } else { ok = false; } if (this->m_Controls.radioButtonTurboFlash->isChecked()) { ok = ok && (m_Controls.recoverytime->value() > 0); ok = ok && (m_Controls.relaxationtime->value() > 0); ok = ok && (m_Controls.relaxivity->value() > 0); ok = ok && (m_Controls.AifRecoverytime->value() > 0); } else if (this->m_Controls.radioButton_absoluteEnhancement->isChecked() || this->m_Controls.radioButton_relativeEnchancement->isChecked()) { ok = ok && (m_Controls.factorSpinBox->value() > 0); } else if (this->m_Controls.radioButtonUsingT1->isChecked()) { ok = ok && (m_Controls.FlipangleSpinBox->value() > 0); ok = ok && (m_Controls.TRSpinBox->value() > 0); ok = ok && (m_Controls.RelaxivitySpinBox->value() > 0); ok = ok && (m_Controls.ComboT1Map->GetSelectedNode().IsNotNull()); } else if (this->m_Controls.radioButtonNoConversion->isChecked()) { ok = ok; } else { ok = false; } if (isNum2CXMFactory) { ok = ok && (this->m_Controls.odeStepSize->value() > 0); } } //add other models as else if and check wether all needed static parameters are set else { ok = false; } if (this->m_Controls.radioButton_StartParameters->isChecked() && !this->m_Controls.initialValuesManager->hasValidInitialValues()) { std::string warning = "Warning. Invalid start parameters. At least one parameter as an invalid image setting as source."; MITK_ERROR << warning; m_Controls.infoBox->append(QString("") + QString::fromStdString(warning) + QString("")); ok = false; }; } else { ok = false; } return ok; } void MRPerfusionView::ConfigureInitialParametersOfParameterizer(mitk::ModelParameterizerBase* parameterizer) const { if (m_Controls.radioButton_StartParameters->isChecked()) { //use user defined initial parameters mitk::InitialParameterizationDelegateBase::Pointer paramDelegate = m_Controls.initialValuesManager->getInitialParametrizationDelegate(); parameterizer->SetInitialParameterizationDelegate(paramDelegate); } } void MRPerfusionView::GenerateDescriptiveBrixModel_PixelBased(mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, mitk::ParameterFitImageGeneratorBase::Pointer& generator) { mitk::PixelBasedParameterFitImageGenerator::Pointer fitGenerator = mitk::PixelBasedParameterFitImageGenerator::New(); mitk::DescriptivePharmacokineticBrixModelParameterizer::Pointer modelParameterizer = mitk::DescriptivePharmacokineticBrixModelParameterizer::New(); //Model configuration (static parameters) can be done now modelParameterizer->SetTau(m_Controls.injectiontime->value()); mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); imageTimeSelector->SetInput(this->m_selectedImage); imageTimeSelector->SetTimeNr(0); imageTimeSelector->UpdateLargestPossibleRegion(); mitk::DescriptivePharmacokineticBrixModelParameterizer::BaseImageType::Pointer baseImage; mitk::CastToItkImage(imageTimeSelector->GetOutput(), baseImage); modelParameterizer->SetBaseImage(baseImage); this->ConfigureInitialParametersOfParameterizer(modelParameterizer); //Specify fitting strategy and criterion parameters mitk::ModelFitFunctorBase::Pointer fitFunctor = CreateDefaultFitFunctor(modelParameterizer); //Parametrize fit generator fitGenerator->SetModelParameterizer(modelParameterizer); std::string roiUID = ""; if (m_selectedMask.IsNotNull()) { fitGenerator->SetMask(m_selectedMask); roiUID = mitk::EnsureModelFitUID(this->m_selectedMaskNode); } fitGenerator->SetDynamicImage(m_selectedImage); fitGenerator->SetFitFunctor(fitFunctor); generator = fitGenerator.GetPointer(); //Create model info modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, m_selectedNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_PIXELBASED(), 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 = mitk::EnsureModelFitUID(this->m_selectedMaskNode); //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); } void MRPerfusionView::Generate3StepLinearModelFit_PixelBased(mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, mitk::ParameterFitImageGeneratorBase::Pointer& generator) { mitk::PixelBasedParameterFitImageGenerator::Pointer fitGenerator = mitk::PixelBasedParameterFitImageGenerator::New(); mitk::ThreeStepLinearModelParameterizer::Pointer modelParameterizer = mitk::ThreeStepLinearModelParameterizer::New(); this->ConfigureInitialParametersOfParameterizer(modelParameterizer); //Specify fitting strategy and criterion parameters mitk::ModelFitFunctorBase::Pointer fitFunctor = CreateDefaultFitFunctor(modelParameterizer); //Parametrize fit generator fitGenerator->SetModelParameterizer(modelParameterizer); std::string roiUID = ""; if (m_selectedMask.IsNotNull()) { fitGenerator->SetMask(m_selectedMask); roiUID = mitk::EnsureModelFitUID(this->m_selectedMaskNode); } fitGenerator->SetDynamicImage(m_selectedImage); fitGenerator->SetFitFunctor(fitFunctor); generator = fitGenerator.GetPointer(); //Create model info modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, m_selectedNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_PIXELBASED(), this->GetFitName(), roiUID); } void MRPerfusionView::Generate3StepLinearModelFit_ROIBased(mitk::modelFit::ModelFitInfo::Pointer& modelFitInfo, mitk::ParameterFitImageGeneratorBase::Pointer& generator) { if (m_selectedMask.IsNull()) { return; } mitk::ROIBasedParameterFitImageGenerator::Pointer fitGenerator = mitk::ROIBasedParameterFitImageGenerator::New(); mitk::ThreeStepLinearModelParameterizer::Pointer modelParameterizer = mitk::ThreeStepLinearModelParameterizer::New(); //Compute ROI signal mitk::MaskedDynamicImageStatisticsGenerator::Pointer signalGenerator = mitk::MaskedDynamicImageStatisticsGenerator::New(); signalGenerator->SetMask(m_selectedMask); signalGenerator->SetDynamicImage(m_selectedImage); signalGenerator->Generate(); mitk::MaskedDynamicImageStatisticsGenerator::ResultType roiSignal = signalGenerator->GetMean(); //Model configuration (static parameters) can be done now this->ConfigureInitialParametersOfParameterizer(modelParameterizer); //Specify fitting strategy and criterion parameters mitk::ModelFitFunctorBase::Pointer fitFunctor = CreateDefaultFitFunctor(modelParameterizer); //Parametrize fit generator fitGenerator->SetModelParameterizer(modelParameterizer); fitGenerator->SetMask(m_selectedMask); fitGenerator->SetFitFunctor(fitFunctor); fitGenerator->SetSignal(roiSignal); fitGenerator->SetTimeGrid(mitk::ExtractTimeGrid(m_selectedImage)); generator = fitGenerator.GetPointer(); std::string roiUID = mitk::EnsureModelFitUID(this->m_selectedMaskNode); //Create model info modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, m_selectedNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_ROIBASED(), 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(); mitk::Image::Pointer concentrationImage; mitk::DataNode::Pointer concentrationNode; GetConcentrationImage(concentrationImage, concentrationNode, false); mitk::AIFBasedModelBase::AterialInputFunctionType aif; mitk::AIFBasedModelBase::AterialInputFunctionType aifTimeGrid; GetAIF(aif, aifTimeGrid); modelParameterizer->SetAIF(aif); modelParameterizer->SetAIFTimeGrid(aifTimeGrid); this->ConfigureInitialParametersOfParameterizer(modelParameterizer); mitk::NumericTwoCompartmentExchangeModelParameterizer* numTCXParametrizer = dynamic_cast (modelParameterizer.GetPointer()); if (numTCXParametrizer) { numTCXParametrizer->SetODEINTStepSize(this->m_Controls.odeStepSize->value()); } //Specify fitting strategy and criterion parameters mitk::ModelFitFunctorBase::Pointer fitFunctor = CreateDefaultFitFunctor(modelParameterizer); //Parametrize fit generator fitGenerator->SetModelParameterizer(modelParameterizer); std::string roiUID = ""; if (m_selectedMask.IsNotNull()) { fitGenerator->SetMask(m_selectedMask); roiUID = mitk::EnsureModelFitUID(this->m_selectedMaskNode); } fitGenerator->SetDynamicImage(concentrationImage); fitGenerator->SetFitFunctor(fitFunctor); generator = fitGenerator.GetPointer(); //Create model info modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, concentrationNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_PIXELBASED(), 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(); mitk::Image::Pointer concentrationImage; mitk::DataNode::Pointer concentrationNode; GetConcentrationImage(concentrationImage, concentrationNode, false); mitk::AIFBasedModelBase::AterialInputFunctionType aif; mitk::AIFBasedModelBase::AterialInputFunctionType aifTimeGrid; GetAIF(aif, aifTimeGrid); modelParameterizer->SetAIF(aif); modelParameterizer->SetAIFTimeGrid(aifTimeGrid); this->ConfigureInitialParametersOfParameterizer(modelParameterizer); mitk::NumericTwoCompartmentExchangeModelParameterizer* numTCXParametrizer = dynamic_cast (modelParameterizer.GetPointer()); if (numTCXParametrizer) { numTCXParametrizer->SetODEINTStepSize(this->m_Controls.odeStepSize->value()); } //Compute ROI signal mitk::MaskedDynamicImageStatisticsGenerator::Pointer signalGenerator = mitk::MaskedDynamicImageStatisticsGenerator::New(); signalGenerator->SetMask(m_selectedMask); signalGenerator->SetDynamicImage(concentrationImage); signalGenerator->Generate(); mitk::MaskedDynamicImageStatisticsGenerator::ResultType roiSignal = signalGenerator->GetMean(); //Specify fitting strategy and criterion parameters mitk::ModelFitFunctorBase::Pointer fitFunctor = CreateDefaultFitFunctor(modelParameterizer); //Parametrize fit generator fitGenerator->SetModelParameterizer(modelParameterizer); fitGenerator->SetMask(m_selectedMask); fitGenerator->SetFitFunctor(fitFunctor); fitGenerator->SetSignal(roiSignal); fitGenerator->SetTimeGrid(mitk::ExtractTimeGrid(concentrationImage)); generator = fitGenerator.GetPointer(); std::string roiUID = mitk::EnsureModelFitUID(this->m_selectedMaskNode); //Create model info modelFitInfo = mitk::modelFit::CreateFitInfoFromModelParameterizer(modelParameterizer, concentrationNode->GetData(), mitk::ModelFitConstants::FIT_TYPE_VALUE_ROIBASED(), 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) { 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); } MRPerfusionView::MRPerfusionView() : m_FittingInProgress(false) { m_selectedImage = NULL; m_selectedMask = NULL; mitk::ModelFactoryBase::Pointer factory = mitk::DescriptivePharmacokineticBrixModelFactory::New().GetPointer(); m_FactoryStack.push_back(factory); factory = mitk::ThreeStepLinearModelFactory::New().GetPointer(); m_FactoryStack.push_back(factory); factory = mitk::StandardToftsModelFactory::New().GetPointer(); m_FactoryStack.push_back(factory); factory = mitk::ExtendedToftsModelFactory::New().GetPointer(); m_FactoryStack.push_back(factory); factory = mitk::TwoCompartmentExchangeModelFactory::New().GetPointer(); m_FactoryStack.push_back(factory); factory = mitk::NumericTwoCompartmentExchangeModelFactory::New().GetPointer(); m_FactoryStack.push_back(factory); mitk::NodePredicateDataType::Pointer isLabelSet = mitk::NodePredicateDataType::New("LabelSetImage"); mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); mitk::NodePredicateAnd::Pointer isLegacyMask = mitk::NodePredicateAnd::New(isImage, isBinary); mitk::NodePredicateOr::Pointer isMask = mitk::NodePredicateOr::New(isLegacyMask, isLabelSet); mitk::NodePredicateAnd::Pointer isNoMask = mitk::NodePredicateAnd::New(isImage, mitk::NodePredicateNot::New(isMask)); this->m_IsMaskPredicate = mitk::NodePredicateAnd::New(isMask, mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))).GetPointer(); this->m_IsNoMaskImagePredicate = mitk::NodePredicateAnd::New(isNoMask, mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))).GetPointer(); } void MRPerfusionView::OnJobFinished() { - this->m_Controls.infoBox->append(QString("Fitting finished")); + this->m_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) { + MITK_INFO << "IKO: OnJobResultsAvailable"; //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()); + + mitk::PropertyList::Pointer dicomPMPropertyList = + mitk::DICOMPMPropertyHandler::GetDICOMPMProperties(pJob->GetParentNode()->GetData()->GetPropertyList()); + + mitk::modelFit::ModelFitResultNodeVectorType::const_iterator pos; + + for (pos = results.begin(); pos != results.end(); pos++) + { + pos->GetPointer()->GetData()->GetPropertyList()->ConcatenatePropertyList(dicomPMPropertyList); + } + + + m_Controls.errorMessageLabel->setText(""); + m_Controls.errorMessageLabel->hide(); + + + + - m_Controls.errorMessageLabel->setText(""); - m_Controls.errorMessageLabel->hide(); }; void MRPerfusionView::OnJobProgress(double progress) { QString report = QString("Progress. ") + QString::number(progress); this->m_Controls.infoBox->append(report); }; void MRPerfusionView::OnJobStatusChanged(QString info) { this->m_Controls.infoBox->append(info); } void MRPerfusionView::InitModelComboBox() const { this->m_Controls.comboModel->clear(); this->m_Controls.comboModel->addItem(tr("No model selected")); for (ModelFactoryStackType::const_iterator pos = m_FactoryStack.begin(); pos != m_FactoryStack.end(); ++pos) { this->m_Controls.comboModel->addItem(QString::fromStdString((*pos)->GetClassID())); } this->m_Controls.comboModel->setCurrentIndex(0); }; mitk::DataNode::Pointer MRPerfusionView::AddConcentrationImage(mitk::Image* image, const std::string& nodeName) const { if (!image) { mitkThrow() << "Cannot generate concentration node. Passed image is null. parameter name: "; } mitk::DataNode::Pointer result = mitk::DataNode::New(); result->SetData(image); result->SetName(nodeName); result->SetVisibility(true); mitk::EnsureModelFitUID(result); this->GetDataStorage()->Add(result, m_selectedNode); return result; }; mitk::Image::Pointer MRPerfusionView::ConvertConcentrationImage(bool AIFMode) { //Compute Concentration image mitk::ConcentrationCurveGenerator::Pointer concentrationGen = mitk::ConcentrationCurveGenerator::New(); if (m_Controls.checkDedicatedAIFImage->isChecked() && AIFMode) { concentrationGen->SetDynamicImage(this->m_selectedAIFImage); } else { concentrationGen->SetDynamicImage(this->m_selectedImage); } concentrationGen->SetisTurboFlashSequence(IsTurboFlashSequenceFlag()); concentrationGen->SetAbsoluteSignalEnhancement(m_Controls.radioButton_absoluteEnhancement->isChecked()); concentrationGen->SetRelativeSignalEnhancement(m_Controls.radioButton_relativeEnchancement->isChecked()); concentrationGen->SetUsingT1Map(m_Controls.radioButtonUsingT1->isChecked()); if (IsTurboFlashSequenceFlag()) { if (AIFMode) { concentrationGen->SetRecoveryTime(m_Controls.AifRecoverytime->value()); } else { concentrationGen->SetRecoveryTime(m_Controls.recoverytime->value()); } concentrationGen->SetRelaxationTime(m_Controls.relaxationtime->value()); concentrationGen->SetRelaxivity(m_Controls.relaxivity->value()); } else if (this->m_Controls.radioButtonUsingT1->isChecked()) { concentrationGen->SetRecoveryTime(m_Controls.TRSpinBox->value()); concentrationGen->SetRelaxivity(m_Controls.RelaxivitySpinBox->value()); concentrationGen->SetT10Image(dynamic_cast(m_Controls.ComboT1Map->GetSelectedNode()->GetData())); //Convert Flipangle from degree to radiant double alpha = m_Controls.FlipangleSpinBox->value()/360*2* boost::math::constants::pi(); concentrationGen->SetFlipAngle(alpha); } else { concentrationGen->SetFactor(m_Controls.factorSpinBox->value()); } mitk::Image::Pointer concentrationImage = concentrationGen->GetConvertedImage(); return concentrationImage; } void MRPerfusionView::GetAIF(mitk::AIFBasedModelBase::AterialInputFunctionType& aif, mitk::AIFBasedModelBase::AterialInputFunctionType& aifTimeGrid) { if (this->m_Controls.radioAIFFile->isChecked()) { aif.clear(); aifTimeGrid.clear(); aif.SetSize(AIFinputFunction.size()); aifTimeGrid.SetSize(AIFinputGrid.size()); aif.fill(0.0); aifTimeGrid.fill(0.0); itk::Array::iterator aifPos = aif.begin(); for (std::vector::const_iterator pos = AIFinputFunction.begin(); pos != AIFinputFunction.end(); ++pos, ++aifPos) { *aifPos = *pos; } itk::Array::iterator gridPos = aifTimeGrid.begin(); for (std::vector::const_iterator pos = AIFinputGrid.begin(); pos != AIFinputGrid.end(); ++pos, ++gridPos) { *gridPos = *pos; } } else if (this->m_Controls.radioAIFImage->isChecked()) { aif.clear(); aifTimeGrid.clear(); mitk::AterialInputFunctionGenerator::Pointer aifGenerator = mitk::AterialInputFunctionGenerator::New(); //Hematocrit level aifGenerator->SetHCL(this->m_Controls.HCLSpinBox->value()); //mask settings this->m_selectedAIFMaskNode = m_Controls.comboAIFMask->GetSelectedNode(); this->m_selectedAIFMask = dynamic_cast(this->m_selectedAIFMaskNode->GetData()); if (this->m_selectedAIFMask->GetTimeSteps() > 1) { MITK_INFO << "Selected AIF mask has multiple timesteps. Only use first timestep to mask model fit. AIF Mask name: " << m_selectedAIFMaskNode->GetName() ; mitk::ImageTimeSelector::Pointer maskedImageTimeSelector = mitk::ImageTimeSelector::New(); maskedImageTimeSelector->SetInput(this->m_selectedAIFMask); maskedImageTimeSelector->SetTimeNr(0); maskedImageTimeSelector->UpdateLargestPossibleRegion(); this->m_selectedAIFMask = maskedImageTimeSelector->GetOutput(); } if (this->m_selectedAIFMask.IsNotNull()) { aifGenerator->SetMask(this->m_selectedAIFMask); } //image settings if (this->m_Controls.checkDedicatedAIFImage->isChecked()) { this->m_selectedAIFImageNode = m_Controls.comboAIFImage->GetSelectedNode(); this->m_selectedAIFImage = dynamic_cast(this->m_selectedAIFImageNode->GetData()); } else { this->m_selectedAIFImageNode = m_selectedNode; this->m_selectedAIFImage = m_selectedImage; } mitk::Image::Pointer concentrationImage; mitk::DataNode::Pointer concentrationNode; this->GetConcentrationImage(concentrationImage, concentrationNode, true); aifGenerator->SetDynamicImage(concentrationImage); aif = aifGenerator->GetAterialInputFunction(); aifTimeGrid = aifGenerator->GetAterialInputFunctionTimeGrid(); } else { mitkThrow() << "Cannot generate AIF. View is in a invalide state. No AIF mode selected."; } } void MRPerfusionView::LoadAIFfromFile() { QFileDialog dialog; dialog.setNameFilter(tr("Images (*.csv")); QString fileName = dialog.getOpenFileName(); m_Controls.aifFilePath->setText(fileName); std::string m_aifFilePath = fileName.toStdString(); //Read Input typedef boost::tokenizer< boost::escaped_list_separator > Tokenizer; ///////////////////////////////////////////////////////////////////////////////////////////////// //AIF Data std::ifstream in1(m_aifFilePath.c_str()); if (!in1.is_open()) { m_Controls.errorMessageLabel->setText("Could not open AIF File!"); } std::vector< std::string > vec1; std::string line1; while (getline(in1, line1)) { Tokenizer tok(line1); vec1.assign(tok.begin(), tok.end()); // if (vec1.size() < 3) continue; this->AIFinputGrid.push_back(convertToDouble(vec1[0])); this->AIFinputFunction.push_back(convertToDouble(vec1[1])); } } void MRPerfusionView::GetConcentrationImage(mitk::Image::Pointer& concentrationImage, mitk::DataNode::Pointer& concentrationNode, bool AIFMode) { if (this->m_Controls.radioButtonNoConversion->isChecked()) { if (this->m_Controls.checkDedicatedAIFImage->isChecked() && AIFMode) { concentrationImage = this->m_selectedAIFImage; concentrationNode = this->m_selectedAIFImageNode; } else { concentrationImage = this->m_selectedImage; concentrationNode = this->m_selectedNode; } } else { if (AIFMode && !IsTurboFlashSequenceFlag() && !this->m_Controls.checkDedicatedAIFImage->isChecked()) { //we can directly use the input image/node for the AIF if (m_inputImage.IsNull()) { mitkThrow() << "Cannot get AIF concentration image. Invalid view state. Input image is not defined yet, but should be."; } concentrationImage = this->m_inputImage; concentrationNode = this->m_inputNode; } else { concentrationImage = this->ConvertConcentrationImage(AIFMode); if (AIFMode) { concentrationNode = AddConcentrationImage(concentrationImage, "AIF Concentration"); } else { concentrationNode = AddConcentrationImage(concentrationImage, "Concentration"); } } } if (AIFMode) { m_inputAIFImage = concentrationImage; m_inputAIFNode = concentrationNode; } else { m_inputImage = concentrationImage; m_inputNode = concentrationNode; } mitk::EnsureModelFitUID(concentrationNode); } mitk::ModelFitFunctorBase::Pointer MRPerfusionView::CreateDefaultFitFunctor( const mitk::ModelParameterizerBase* parameterizer) const { mitk::LevenbergMarquardtModelFitFunctor::Pointer fitFunctor = mitk::LevenbergMarquardtModelFitFunctor::New(); mitk::NormalizedSumOfSquaredDifferencesFitCostFunction::Pointer chi2 = mitk::NormalizedSumOfSquaredDifferencesFitCostFunction::New(); fitFunctor->RegisterEvaluationParameter("Chi^2", chi2); if (m_Controls.checkBox_Constraints->isChecked()) { fitFunctor->SetConstraintChecker(m_modelConstraints); } mitk::ModelBase::Pointer refModel = parameterizer->GenerateParameterizedModel(); ::itk::LevenbergMarquardtOptimizer::ScalesType scales; scales.SetSize(refModel->GetNumberOfParameters()); scales.Fill(1.0); fitFunctor->SetScales(scales); fitFunctor->SetDebugParameterMaps(m_Controls.checkDebug->isChecked()); return fitFunctor.GetPointer(); }