Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkRTDoseReader.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,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 
18 #include "mitkRTDoseReader.h"
19 
20 #include <mitkImageAccessByItk.h>
21 #include <mitkImageCast.h>
23 #include <mitkDICOMFileReader.h>
24 #include <mitkRTConstants.h>
26 #include <mitkIOMimeTypes.h>
27 #include <mitkDICOMTagPath.h>
28 
29 #include "usModuleContext.h"
30 #include "usGetModuleContext.h"
31 
32 #include "dcmtk/dcmrt/drtdose.h"
33 
34 #include <itkShiftScaleImageFilter.h>
35 #include <itkCastImageFilter.h>
36 
37 namespace mitk
38 {
39 
40  RTDoseReader::RTDoseReader() : AbstractFileReader(IOMimeTypes::DICOM_MIMETYPE_NAME(), "DICOM RTDose File Reader") {
41  m_ServiceReg = RegisterService();
42  }
43 
45  {
46 
47  }
48 
50 
51  template<typename TPixel, unsigned int VImageDimension>
52  void RTDoseReader::MultiplyGridScaling(itk::Image<TPixel, VImageDimension>* image, float gridscale)
53  {
54  typedef itk::Image<Float32, VImageDimension> OutputImageType;
55  typedef itk::Image<TPixel, VImageDimension> InputImageType;
56 
57  typedef itk::CastImageFilter<InputImageType, OutputImageType> CastFilterType;
58  typedef itk::ShiftScaleImageFilter<OutputImageType, OutputImageType> ScaleFilterType;
59  typename CastFilterType::Pointer castFilter = CastFilterType::New();
60  typename ScaleFilterType::Pointer scaleFilter = ScaleFilterType::New();
61 
62  castFilter->SetInput(image);
63  scaleFilter->SetInput(castFilter->GetOutput());
64  scaleFilter->SetScale(gridscale);
65  scaleFilter->Update();
66  typename OutputImageType::Pointer scaledOutput = scaleFilter->GetOutput();
67  this->scaledDoseImage = mitk::Image::New();
68 
69  mitk::CastToMitkImage(scaledOutput, this->scaledDoseImage);
70  }
71 
72  mitk::IDICOMTagsOfInterest* RTDoseReader::GetDicomTagsOfInterestService()
73  {
74  mitk::IDICOMTagsOfInterest* result = nullptr;
75 
76  std::vector<us::ServiceReference<mitk::IDICOMTagsOfInterest> > toiRegisters = us::GetModuleContext()->GetServiceReferences<mitk::IDICOMTagsOfInterest>();
77  if (!toiRegisters.empty())
78  {
79  if (toiRegisters.size() > 1)
80  {
81  MITK_WARN << "Multiple DICOM tags of interest services found. Using just one.";
82  }
83  result = us::GetModuleContext()->GetService<mitk::IDICOMTagsOfInterest>(toiRegisters.front());
84  }
85 
86  return result;
87  }
88 
89  std::vector<itk::SmartPointer<BaseData> > RTDoseReader::Read()
90  {
91  std::vector<itk::SmartPointer<mitk::BaseData> > result;
92 
93  DICOMTag referencedRTPlan(0x300c, 0x0002);
94  mitk::IDICOMTagsOfInterest* toiSrv = GetDicomTagsOfInterestService();
95  if (toiSrv)
96  {
97  toiSrv->AddTagOfInterest(referencedRTPlan);
98  }
99 
100  std::string location = GetInputLocation();
102  selector->LoadBuiltIn3DConfigs();
103  selector->SetInputFiles({ location });
104 
105  mitk::DICOMFileReader::Pointer reader = selector->GetFirstReaderWithMinimumNumberOfOutputImages();
106  reader->SetAdditionalTagsOfInterest(toiSrv->GetTagsOfInterest());
107 
108  reader->SetInputFiles({ location });
109  reader->AnalyzeInputFiles();
110  reader->LoadImages();
111 
112  if (reader->GetNumberOfOutputs() == 0){
113  MITK_ERROR << "Could not determine a DICOM reader for this file" << std::endl;
114  return result;
115  }
116 
117  const mitk::DICOMImageBlockDescriptor& desc = reader->GetOutput(0);
118 
119  mitk::Image::Pointer originalImage = desc.GetMitkImage();
120 
121  if (originalImage.IsNull())
122  {
123  MITK_ERROR << "Error reading the RTDOSE file in mitk::DicomFileReader" << std::endl;
124  return result;
125  }
126 
127  DcmFileFormat fileformat;
128  OFCondition outp = fileformat.loadFile(location.c_str(), EXS_Unknown);
129  if (outp.bad())
130  {
131  MITK_ERROR << "Error reading the RTDOSE file in DCMTK" << std::endl;
132  return result;
133  }
134  DcmDataset *dataset = fileformat.getDataset();
135 
136  DRTDoseIOD doseObject;
137  OFCondition DCMTKresult = doseObject.read(*dataset);
138 
139  if (DCMTKresult.bad())
140  {
141  MITK_ERROR << "Error reading the RTDOSE file in DCMTK" << std::endl;
142  return result;
143  }
144 
145  OFString gridScaling;
146  Float32 gridscale;
147 
148  doseObject.getDoseGridScaling(gridScaling);
149  gridscale = OFStandard::atof(gridScaling.c_str());
150 
151  AccessByItk_1(originalImage, MultiplyGridScaling, gridscale);
152 
153  auto statistics = this->scaledDoseImage->GetStatistics();
154  double maxDose = statistics->GetScalarValueMax();
155 
156  this->scaledDoseImage->SetPropertyList(originalImage->GetPropertyList());
157  this->scaledDoseImage->SetProperty(mitk::RTConstants::PRESCRIBED_DOSE_PROPERTY_NAME.c_str(), mitk::GenericProperty<double>::New(0.8*maxDose));
158 
159  result.push_back(this->scaledDoseImage.GetPointer());
160  return result;
161  }
162 
163  RTDoseReader* RTDoseReader::Clone() const
164  {
165  return new RTDoseReader(*this);
166  }
167 
168 }
itk::SmartPointer< Self > Pointer
The IOMimeTypes class.
#define MITK_ERROR
Definition: mitkLogMacros.h:24
RTDoseReader reads DICOM files of modality RTDOSE.
Representation of a DICOM tag.
Definition: mitkDICOMTag.h:37
DataCollection - Class to facilitate loading/accessing structured data.
#define AccessByItk_1(mitkImage, itkImageTypeFunction, arg1)
Interface of DICOM tags of interest service.
void * GetService(const ServiceReferenceBase &reference)
us::ServiceRegistration< IFileReader > RegisterService(us::ModuleContext *context=us::GetModuleContext())
#define MITK_WARN
Definition: mitkLogMacros.h:23
itk::Image< double, 3 > InputImageType
virtual void AddTagOfInterest(const DICOMTagPath &tag, bool makePersistant=true)=0
Add an tag to the TOI. If the tag was already added it will be overwritten with the passed values...
Output descriptor for DICOMFileReader.
virtual std::vector< itk::SmartPointer< BaseData > > Read() override
Reads a path or stream and creates a list of BaseData objects.
static Pointer New()
std::vector< ServiceReferenceU > GetServiceReferences(const std::string &clazz, const std::string &filter=std::string())
Image::Pointer GetMitkImage() const
the 3D mitk::Image that is loaded from the DICOM files of a DICOMImageFrameList
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:78
Base class for creating mitk::BaseData objects from files or streams.
virtual ~RTDoseReader()
Reads a dicom dataset from a RTDOSE file.
static const std::string PRESCRIBED_DOSE_PROPERTY_NAME
virtual DICOMTagPathMapType GetTagsOfInterest() const =0
virtual std::string GetInputLocation() const override
Get the current input location.
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.