Medical Imaging Interaction Toolkit  2018.4.99-36d69b77
Medical Imaging Interaction Toolkit
mitkRTDoseReaderService.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 
15 
16 #include <mitkLexicalCast.h>
17 
18 #include <mitkImageAccessByItk.h>
19 #include <mitkImageCast.h>
21 #include <mitkDICOMFileReader.h>
22 #include <mitkRTConstants.h>
24 #include <mitkDICOMTagPath.h>
26 #include <mitkDICOMRTMimeTypes.h>
27 #include <mitkDICOMIOHelper.h>
28 
29 #include <dcmtk/dcmrt/drtdose.h>
30 
31 #include <itkShiftScaleImageFilter.h>
32 #include <itkCastImageFilter.h>
33 
34 namespace mitk
35 {
36 
37  RTDoseReaderService::RTDoseReaderService() : AbstractFileReader(CustomMimeType(mitk::DICOMRTMimeTypes::DICOMRT_DOSE_MIMETYPE_NAME()), mitk::DICOMRTMimeTypes::DICOMRT_DOSE_MIMETYPE_DESCRIPTION()) {
38  m_FileReaderServiceReg = RegisterService();
39  }
40 
42  {
43 
44  }
45 
47 
48  template<typename TPixel, unsigned int VImageDimension>
49  void RTDoseReaderService::MultiplyGridScaling(itk::Image<TPixel, VImageDimension>* image, float gridscale)
50  {
51  typedef itk::Image<Float32, VImageDimension> OutputImageType;
52  typedef itk::Image<TPixel, VImageDimension> InputImageType;
53 
54  typedef itk::CastImageFilter<InputImageType, OutputImageType> CastFilterType;
55  typedef itk::ShiftScaleImageFilter<OutputImageType, OutputImageType> ScaleFilterType;
56  typename CastFilterType::Pointer castFilter = CastFilterType::New();
57  typename ScaleFilterType::Pointer scaleFilter = ScaleFilterType::New();
58 
59  castFilter->SetInput(image);
60  scaleFilter->SetInput(castFilter->GetOutput());
61  scaleFilter->SetScale(gridscale);
62  scaleFilter->Update();
63  typename OutputImageType::Pointer scaledOutput = scaleFilter->GetOutput();
64  this->scaledDoseImage = mitk::Image::New();
65 
66  mitk::CastToMitkImage(scaledOutput, this->scaledDoseImage);
67  }
68 
69  std::vector<itk::SmartPointer<BaseData> > RTDoseReaderService::DoRead()
70  {
71  std::vector<itk::SmartPointer<mitk::BaseData> > result;
72 
73 
75 
76  auto tagsOfInterest = toiSrv->GetTagsOfInterest();
77 
78  DICOMTagPathList tagsOfInterestList;
79  for (const auto& tag : tagsOfInterest) {
80  tagsOfInterestList.push_back(tag.first);
81  }
82 
83  std::string location = GetInputLocation();
84  mitk::DICOMFileReaderSelector::Pointer selector = mitk::DICOMFileReaderSelector::New();
85  selector->LoadBuiltIn3DConfigs();
86  selector->SetInputFiles({ location });
87 
88  mitk::DICOMFileReader::Pointer reader = selector->GetFirstReaderWithMinimumNumberOfOutputImages();
89  reader->SetAdditionalTagsOfInterest(toiSrv->GetTagsOfInterest());
90 
91  reader->SetInputFiles({ location });
92  reader->AnalyzeInputFiles();
93  reader->LoadImages();
94 
95  if (reader->GetNumberOfOutputs() == 0) {
96  MITK_ERROR << "Could not determine a DICOM reader for this file" << std::endl;
97  return result;
98  }
99 
100  mitk::DICOMDCMTKTagScanner::Pointer scanner = mitk::DICOMDCMTKTagScanner::New();
101  scanner->SetInputFiles({ location });
102  scanner->AddTagPaths(tagsOfInterestList);
103  scanner->Scan();
104 
105  mitk::DICOMDatasetAccessingImageFrameList frames = scanner->GetFrameInfoList();
106  if (frames.empty()) {
107  MITK_ERROR << "Error reading the RTDOSE file" << std::endl;
108  return result;
109  }
110 
111  const mitk::DICOMImageBlockDescriptor& desc = reader->GetOutput(0);
112 
113  mitk::Image::Pointer originalImage = desc.GetMitkImage();
114 
115  if (originalImage.IsNull())
116  {
117  MITK_ERROR << "Error reading the RTDOSE file in mitk::DicomFileReader" << std::endl;
118  return result;
119  }
120 
121  DcmFileFormat fileformat;
122  OFCondition outp = fileformat.loadFile(location.c_str(), EXS_Unknown);
123  if (outp.bad())
124  {
125  MITK_ERROR << "Error reading the RTDOSE file in DCMTK" << std::endl;
126  return result;
127  }
128  DcmDataset *dataset = fileformat.getDataset();
129 
130  DRTDoseIOD doseObject;
131  OFCondition DCMTKresult = doseObject.read(*dataset);
132 
133  if (DCMTKresult.bad())
134  {
135  MITK_ERROR << "Error reading the RTDOSE file in DCMTK" << std::endl;
136  return result;
137  }
138 
139  auto findingsGridScaling = frames.front()->GetTagValueAsString(DICOMTagPath(0x3004, 0x000e)); //(0x3004, 0x000e) is grid scaling
140 
141  double gridScaling;
142  if (findingsGridScaling.empty()) {
143  MITK_ERROR << "Could not find DoseGridScaling tag" << std::endl;
144  return result;
145  }
146  else {
147  gridScaling = boost::lexical_cast<double>(findingsGridScaling.front().value);
148  }
149 
150  AccessByItk_1(originalImage, MultiplyGridScaling, gridScaling);
151 
152  auto statistics = this->scaledDoseImage->GetStatistics();
153  double maxDose = statistics->GetScalarValueMax();
154 
155  this->scaledDoseImage->SetPropertyList(originalImage->GetPropertyList());
156  this->scaledDoseImage->SetProperty(mitk::RTConstants::PRESCRIBED_DOSE_PROPERTY_NAME.c_str(), mitk::GenericProperty<double>::New(0.8*maxDose));
157  auto findings = ExtractPathsOfInterest(tagsOfInterestList, frames);
158  SetProperties(this->scaledDoseImage, findings);
159 
160  result.push_back(this->scaledDoseImage.GetPointer());
161  return result;
162  }
163 
164  RTDoseReaderService* RTDoseReaderService::Clone() const
165  {
166  return new RTDoseReaderService(*this);
167  }
168 }
Class is used to identify (nested) attributes in a DICOM dataset. In contrast to the class DICOMTag...
#define MITK_ERROR
Definition: mitkLogMacros.h:20
Image::Pointer GetMitkImage() const
the 3D mitk::Image that is loaded from the DICOM files of a DICOMImageFrameList
DataCollection - Class to facilitate loading/accessing structured data.
#define AccessByItk_1(mitkImage, itkImageTypeFunction, arg1)
Interface of DICOM tags of interest service.
std::vector< itk::SmartPointer< BaseData > > DoRead() override
Reads a dicom dataset from a RTDOSE file The method reads the PixelData from the DicomRT dose file an...
MITKDICOM_EXPORT FindingsListVectorType ExtractPathsOfInterest(const DICOMTagPathList &pathsOfInterest, const DICOMDatasetAccessingImageFrameList &frames)
The CustomMimeType class represents a custom mime-type which may be registered as a service object...
us::ServiceRegistration< IFileReader > RegisterService(us::ModuleContext *context=us::GetModuleContext())
Target lexical_cast(const std::string &arg)
Output descriptor for DICOMFileReader.
mitk::Image::Pointer image
static Pointer New()
std::vector< DICOMTagPath > DICOMTagPathList
MITKDICOM_EXPORT void SetProperties(BaseDataPointer image, const FindingsListVectorType &findings)
std::vector< DICOMDatasetAccessingImageFrameInfo::Pointer > DICOMDatasetAccessingImageFrameList
void CastToMitkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, itk::SmartPointer< mitk::Image > &mitkoutputimage)
Cast an itk::Image (with a specific type) to an mitk::Image.
Definition: mitkImageCast.h:74
Base class for creating mitk::BaseData objects from files or streams.
RTDoseReaderService reads DICOM files of modality RTDOSE.
static const std::string PRESCRIBED_DOSE_PROPERTY_NAME
MITKDICOM_EXPORT mitk::IDICOMTagsOfInterest * GetDicomTagsOfInterestService()
virtual DICOMTagPathMapType GetTagsOfInterest() const =0
std::string GetInputLocation() const override
Get the current input location.