Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkDICOMPMIO.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #ifndef __mitkDICOMPMIO__cpp
14 #define __mitkDICOMPMIO__cpp
15 
16 #include "mitkDICOMPMIO.h"
17 #include "mitkDICOMPMIOMimeTypes.h"
19 #include <mitkDICOMIOHelper.h>
20 #include <mitkDICOMProperty.h>
22 #include <mitkImageAccessByItk.h>
23 #include <mitkImageCast.h>
24 #include <mitkLocaleSwitch.h>
25 #include <mitkPropertyNameHelper.h>
26 #include <dcmqi/ParaMapConverter.h>
28 
29 
30 // us
31 #include <usGetModuleContext.h>
32 #include <usModuleContext.h>
33 
34 // model fit parameters
35 #include "mitkModelFitConstants.h"
36 
37 
38 namespace mitk
39 {
41  : AbstractFileIO(Image::GetStaticNameOfClass(),
42  mitk::MitkDICOMPMIOMimeTypes::DICOMPM_MIMETYPE_NAME(),
43  "DICOM PM")
44 
45  {
48  this->RegisterService();
49  }
50 
52  {
54  return Unsupported;
55 
56  const Image *PMinput = static_cast<const Image *>(this->GetInput());
57  if (PMinput)
58  {
59  auto modalityProperty = PMinput->GetProperty(mitk::GeneratePropertyNameForDICOMTag(0x0008, 0x0060).c_str());
60  if (modalityProperty.IsNotNull())
61  {
62  std::string modality = modalityProperty->GetValueAsString();
63  if (modality == "PM")
64  {
65  return Supported;
66  }
67  else return Unsupported;
68  }
69  else return Unsupported;
70  }
71  else return Unsupported;
72  }
73 
75  {
77  mitk::LocaleSwitch localeSwitch("C");
78  LocalFile localFile(this);
79  const std::string path = localFile.GetFileName();
80 
81  auto PMinput = dynamic_cast<const Image *>(this->GetInput());
82  if (PMinput == nullptr)
83  mitkThrow() << "Cannot write non-image data";
84 
85  // Get DICOM information from referenced image
86  vector<std::unique_ptr<DcmDataset>> dcmDatasetsSourceImage;
87  std::unique_ptr<DcmFileFormat> readFileFormat(new DcmFileFormat());
88 
89  try
90  {
91  // Generate dcmdataset witk DICOM tags from property list; ATM the source are the filepaths from the
92  // property list
94  dynamic_cast<mitk::StringLookupTableProperty *>(PMinput->GetProperty("referenceFiles").GetPointer());
95 
96  if (filesProp.IsNull())
97  {
98  mitkThrow() << "No property with dicom file path.";
99  return;
100  }
101 
102  // returns a list of all referenced files
103  StringLookupTable filesLut = filesProp->GetValue();
104 
105  const StringLookupTable::LookupTableType &lookUpTableMap = filesLut.GetLookupTable();
106  for (auto it : lookUpTableMap)
107  {
108  const char *fileName = (it.second).c_str();
109  if (readFileFormat->loadFile(fileName, EXS_Unknown).good())
110  {
111  std::unique_ptr<DcmDataset> readDCMDataset(readFileFormat->getAndRemoveDataset());
112  dcmDatasetsSourceImage.push_back(std::move(readDCMDataset));
113  }
114  }
115  }
116  catch (const std::exception &e)
117  {
118  MITK_ERROR << "An error occurred while getting the dicom information: " << e.what() << endl;
119  return;
120  }
121 
122  mitk::Image *mitkPMImage = const_cast<mitk::Image *>(PMinput);
123  // Cast input PMinput to itk image
125  PMimageToItkFilter->SetInput(mitkPMImage);
126 
127  // Cast from original itk type to dcmqi input itk image type
128  typedef itk::CastImageFilter<PMitkInputImageType, PMitkInternalImageType> castItkImageFilterType;
129  castItkImageFilterType::Pointer castFilter = castItkImageFilterType::New();
130  castFilter->SetInput(PMimageToItkFilter->GetOutput());
131  castFilter->Update();
132  PMitkInternalImageType::Pointer itkParamapImage = castFilter->GetOutput();
133 
134  // Create PM meta information
135  const std::string tmpMetaInfoFile = this->CreateMetaDataJsonFilePM();
136  // Convert itk PM images to dicom image
137  MITK_INFO << "Writing PM image: " << path << std::endl;
138  try
139  {
140  // convert from unique to raw pointer
141  vector<DcmDataset*> rawVecDataset;
142  for ( const auto& dcmDataSet : dcmDatasetsSourceImage ) { rawVecDataset.push_back( dcmDataSet.get() ); }
143 
144  std::unique_ptr<dcmqi::ParaMapConverter> PMconverter(new dcmqi::ParaMapConverter());
145  std::unique_ptr<DcmDataset> PMresult (PMconverter->itkimage2paramap(itkParamapImage, rawVecDataset, tmpMetaInfoFile));
146  // Write dicom file
147  DcmFileFormat dcmFileFormat(PMresult.get());
148  std::string filePath = path.substr(0, path.find_last_of("."));
149  filePath = filePath + ".dcm";
150  dcmFileFormat.saveFile(filePath.c_str(), EXS_LittleEndianExplicit);
151 
152  }
153  catch (const std::exception &e)
154  {
155  MITK_ERROR << "An error occurred during writing the DICOM Paramap: " << e.what() << endl;
156  return;
157  }
158 
159  }
160 
161  const std::string mitk::DICOMPMIO::CreateMetaDataJsonFilePM() const
162  {
163  const mitk::Image *PMimage = dynamic_cast<const mitk::Image *>(this->GetInput());
164  dcmqi::JSONParametricMapMetaInformationHandler PMhandler;
165 
166 
167  // Get Metadata from modelFitConstants
168  std::string parameterName;
169  PMimage->GetPropertyList()->GetStringProperty(ModelFitConstants::PARAMETER_NAME_PROPERTY_NAME().c_str(), parameterName);
170  std::string modelName;
171  PMimage->GetPropertyList()->GetStringProperty(ModelFitConstants::MODEL_NAME_PROPERTY_NAME().c_str(), modelName);
172 
174  // Here the mitkParamapPresets.xml file containing the Coding Schmeme Designator and Code Value are parsed and the relevant values extracted
175  pmPresets->LoadPreset();
176  auto pmType_parameterName = pmPresets->GetType(parameterName);
177  auto pmType_modelName = pmPresets->GetType(modelName);
178 
179  // Pass codes to Paramap Converter
180  PMhandler.setDerivedPixelContrast("TCS");
181  PMhandler.setFrameLaterality("U");
182  PMhandler.setQuantityValueCode(pmType_parameterName.codeValue, pmType_parameterName.codeScheme, parameterName);
183  PMhandler.setMeasurementMethodCode(pmType_modelName.codeValue, pmType_modelName.codeScheme, modelName);
184  PMhandler.setMeasurementUnitsCode("/min", "UCUM", "/m");
185  PMhandler.setSeriesNumber("1");
186  PMhandler.setInstanceNumber("1");
187  PMhandler.setDerivationCode("129104", "DCM", "Perfusion image analysis");
188  PMhandler.setRealWorldValueSlope("1");
189 
190  return PMhandler.getJSONOutputAsString();
191  }
192 
193 
194  std::vector<BaseData::Pointer> DICOMPMIO::Read()
195  {
196  mitk::LocaleSwitch localeSwitch("C");
197  std::vector<BaseData::Pointer> result;
198 
199  return result;
200  }
201 
203  {
204  return Unsupported;
205  }
206 
207 
208 
209  DICOMPMIO *DICOMPMIO::IOClone() const { return new DICOMPMIO(*this); }
210 } // namespace
211 
212 
213 
214 
215 
216 
217 #endif //__mitkDICOMPMIO__cpp
std::map< IdentifierType, ValueType > LookupTableType
#define MITK_INFO
Definition: mitkLogMacros.h:18
#define MITK_ERROR
Definition: mitkLogMacros.h:20
Provides the custom mime types for dicom qi objects loaded with DCMQI.
std::string MITKCORE_EXPORT GeneratePropertyNameForDICOMTag(unsigned int group, unsigned int element)
std::string modelName
DataCollection - Class to facilitate loading/accessing structured data.
static const std::string MODEL_NAME_PROPERTY_NAME()
void SetRanking(int ranking)
Set the service ranking for this file writer.
const LookupTableType & GetLookupTable() const
ConfidenceLevel GetReaderConfidenceLevel() const override
std::vector< BaseData::Pointer > Read() override
Reads a DICOM parametric maps from the file system.
ConfidenceLevel
A confidence level describing the confidence of the reader or writer in handling the given data...
Definition: mitkIFileIO.h:45
Convenience class to temporarily change the current locale.
std::pair< us::ServiceRegistration< IFileReader >, us::ServiceRegistration< IFileWriter > > RegisterService(us::ModuleContext *context=us::GetModuleContext())
#define mitkThrow()
const BaseData * GetInput() const override
Get the input data set via SetInput().
Image class for storing images.
Definition: mitkImage.h:72
A local file representation for streams.
void Write() override
Write the base data to the specified location or output stream.
void SetRanking(int ranking)
Set the service ranking for this file reader.
mitk::PropertyList::Pointer GetPropertyList() const
Get the data&#39;s property list.
static ParamapPresetsParser * New()
mitk::BaseProperty::Pointer GetProperty(const char *propertyKey) const
Get the property (instance of BaseProperty) with key propertyKey from the PropertyList, and set it to this, respectively;.
static Pointer New()
ConfidenceLevel GetWriterConfidenceLevel() const override
ConfidenceLevel GetWriterConfidenceLevel() const override
Abstract class for implementing a reader and writer.
static const std::string PARAMETER_NAME_PROPERTY_NAME()
Type GetType(const std::string &name)