Medical Imaging Interaction Toolkit  2018.4.99-f51274ea
Medical Imaging Interaction Toolkit
mitkBaseDICOMReaderService.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 
14 
15 #include <mitkCustomMimeType.h>
16 #include <mitkIOMimeTypes.h>
18 #include <mitkImage.h>
19 #include <mitkDICOMFilesHelper.h>
21 #include <mitkDICOMProperty.h>
24 #include <mitkLocaleSwitch.h>
25 #include "mitkIPropertyProvider.h"
26 #include "mitkPropertyNameHelper.h"
27 #include "mitkPropertyKeyPath.h"
29 
30 #include <iostream>
31 
32 
33 #include <itksys/SystemTools.hxx>
34 #include <itksys/Directory.hxx>
35 
36 namespace mitk
37 {
38 
39  BaseDICOMReaderService::BaseDICOMReaderService(const std::string& description)
40  : AbstractFileReader(CustomMimeType(IOMimeTypes::DICOM_MIMETYPE()), description)
41 {
42 }
43 
44 BaseDICOMReaderService::BaseDICOMReaderService(const mitk::CustomMimeType& customType, const std::string& description)
45  : AbstractFileReader(customType, description)
46 {
47 }
48 
50 {
51  m_OnlyRegardOwnSeries = regard;
52 }
53 
55 {
56  return m_OnlyRegardOwnSeries;
57 }
58 
59 
60 std::vector<itk::SmartPointer<BaseData> > BaseDICOMReaderService::DoRead()
61 {
62  std::vector<BaseData::Pointer> result;
63 
64 
65  const std::string fileName = this->GetLocalFileName();
66  //special handling of Philips 3D US DICOM.
67  //Copied from DICOMSeriesReaderService
69  {
70  MITK_INFO << "it is a Philips3D US Dicom file" << std::endl;
71  mitk::LocaleSwitch localeSwitch("C");
72  std::locale previousCppLocale(std::cin.getloc());
73  std::locale l("C");
74  std::cin.imbue(l);
75 
78  stringvec.push_back(fileName);
79  if (DicomSeriesReader::LoadDicomSeries(stringvec, *node))
80  {
81  BaseData::Pointer data = node->GetData();
82  StringProperty::Pointer nameProp = StringProperty::New(itksys::SystemTools::GetFilenameName(fileName));
83  data->GetPropertyList()->SetProperty("name", nameProp);
84  result.push_back(data);
85  }
86  std::cin.imbue(previousCppLocale);
87  return result;
88  }
89 
90  //Normal DICOM handling (It wasn't a Philips 3D US)
91  mitk::StringList relevantFiles = this->GetDICOMFilesInSameDirectory();
92 
93  if (relevantFiles.empty())
94  {
95  MITK_INFO << "DICOMReader service found no relevant files in specified location. No data is loaded. Location: "<<fileName;
96  }
97  else
98  {
99  bool pathIsDirectory = itksys::SystemTools::FileIsDirectory(fileName);
100 
101  if (!pathIsDirectory && m_OnlyRegardOwnSeries)
102  {
103  relevantFiles = mitk::FilterDICOMFilesForSameSeries(fileName, relevantFiles);
104  }
105 
106  mitk::DICOMFileReader::Pointer reader = this->GetReader(relevantFiles);
107 
108  if(reader.IsNull())
109  {
110  MITK_INFO << "DICOMReader service found no suitable reader configuration for relevant files.";
111  }
112  else
113  {
114  if (!pathIsDirectory)
115  { //we ensure that we only load the relevant image block files
116  const auto nrOfOutputs = reader->GetNumberOfOutputs();
117  for (unsigned int outputIndex = 0; outputIndex < nrOfOutputs; ++outputIndex)
118  {
119  const auto frameList = reader->GetOutput(outputIndex).GetImageFrameList();
120 
121  auto finding = std::find_if(frameList.begin(), frameList.end(), [&](const DICOMImageFrameInfo::Pointer& frame) { return frame->Filename == fileName; });
122 
123  if (finding != frameList.end())
124  { //we have the block containing the fileName -> these are the realy relevant files.
125  relevantFiles.resize(frameList.size());
126  std::transform(frameList.begin(), frameList.end(), relevantFiles.begin(), [](const DICOMImageFrameInfo::Pointer& frame) { return frame->Filename; });
127  break;
128  }
129  }
130  }
131  const unsigned int ntotalfiles = relevantFiles.size();
132 
133  for( unsigned int i=0; i< ntotalfiles; i++)
134  {
135  m_ReadFiles.push_back( relevantFiles.at(i) );
136  }
137 
138  reader->SetAdditionalTagsOfInterest(mitk::GetCurrentDICOMTagsOfInterest());
139  reader->SetTagLookupTableToPropertyFunctor(mitk::GetDICOMPropertyForDICOMValuesFunctor);
140  reader->SetInputFiles(relevantFiles);
141 
142  mitk::DICOMDCMTKTagScanner::Pointer scanner = mitk::DICOMDCMTKTagScanner::New();
143  scanner->AddTagPaths(reader->GetTagsOfInterest());
144  scanner->SetInputFiles(relevantFiles);
145  scanner->Scan();
146 
147  reader->SetTagCache(scanner->GetScanCache());
148  reader->AnalyzeInputFiles();
149  reader->LoadImages();
150 
151  for (unsigned int i = 0; i < reader->GetNumberOfOutputs(); ++i)
152  {
153  const mitk::DICOMImageBlockDescriptor& desc = reader->GetOutput(i);
154  mitk::BaseData::Pointer data = desc.GetMitkImage().GetPointer();
155 
156  std::string nodeName = GenerateNameFromDICOMProperties(&desc);
157 
158  StringProperty::Pointer nameProp = StringProperty::New(nodeName);
159  data->SetProperty("name", nameProp);
160 
162 
163  result.push_back(data);
164  }
165  }
166  }
167 
168  return result;
169 }
170 
172 {
173  std::string fileName = this->GetLocalFileName();
174 
175  mitk::StringList relevantFiles = mitk::GetDICOMFilesInSameDirectory(fileName);
176 
177  return relevantFiles;
178 }
179 
181 {
183 
184  if (Unsupported == abstractConfidence)
185  {
186  if (itksys::SystemTools::FileIsDirectory(this->GetInputLocation().c_str()))
187  {
188  // In principle we support dicom directories
189  return Supported;
190  }
191  }
192 
193  return abstractConfidence;
194 }
195 
197 {
198  std::string nodeName = mitk::DataNode::NO_NAME_VALUE();
199 
200  auto studyProp = provider->GetConstProperty(mitk::GeneratePropertyNameForDICOMTag(0x0008, 0x1030).c_str());
201  if (studyProp.IsNotNull())
202  {
203  nodeName = studyProp->GetValueAsString();
204  }
205 
206  auto seriesProp = provider->GetConstProperty(mitk::GeneratePropertyNameForDICOMTag(0x0008, 0x103E).c_str());
207 
208  if (seriesProp.IsNotNull())
209  {
210  if (studyProp.IsNotNull())
211  {
212  nodeName += " / ";
213  }
214  else
215  {
216  nodeName = "";
217 
218  }
219  nodeName += seriesProp->GetValueAsString();
220  }
221 
222  return nodeName;
223 };
224 
225 }
The IOMimeTypes class.
MITKCORE_EXPORT std::string PropertyKeyPathToPropertyName(const PropertyKeyPath &tagPath)
DICOMTagPathMapType MITKDICOMREADER_EXPORT GetCurrentDICOMTagsOfInterest()
#define MITK_INFO
Definition: mitkLogMacros.h:18
ConfidenceLevel GetConfidenceLevel() const override
The confidence level of the reader or writer implementation.
DICOMFilePathList GetDICOMFilesInSameDirectory(const std::string &filePath)
std::vector< std::string > StringContainer
Lists of filenames.
std::string MITKCORE_EXPORT GeneratePropertyNameForDICOMTag(unsigned int group, unsigned int element)
Image::Pointer GetMitkImage() const
the 3D mitk::Image that is loaded from the DICOM files of a DICOMImageFrameList
static DataNode::Pointer LoadDicomSeries(const StringContainer &filenames, bool sort=true, bool load4D=true, bool correctGantryTilt=true, UpdateCallBackMethod callback=nullptr, itk::SmartPointer< Image > preLoadedImageBlock=nullptr)
DataCollection - Class to facilitate loading/accessing structured data.
virtual BaseProperty::ConstPointer GetConstProperty(const std::string &propertyKey, const std::string &contextName="", bool fallBackOnDefaultContext=true) const =0
Get property by its key.
virtual mitk::DICOMFileReader::Pointer GetReader(const mitk::StringList &relevantFiles) const =0
std::vector< std::string > m_ReadFiles
MITKDICOMREADER_EXPORT mitk::BaseProperty::Pointer GetDICOMPropertyForDICOMValuesFunctor(const DICOMCachedValueLookupTable &cacheLookupTable)
BaseDICOMReaderService(const std::string &description)
static std::string NO_NAME_VALUE()
Definition: mitkDataNode.h:393
The CustomMimeType class represents a custom mime-type which may be registered as a service object...
std::string GetLocalFileName() const
Get a local file name for reading.
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.
static Pointer New()
Output descriptor for DICOMFileReader.
IFileReader::ConfidenceLevel GetConfidenceLevel() const override
The confidence level of the reader or writer implementation.
std::string MITKDICOMREADER_EXPORT GenerateNameFromDICOMProperties(const mitk::IPropertyProvider *provider)
static bool IsPhilips3DDicom(const std::string &filename)
Checks if a specific file is a Philips3D ultrasound DICOM file.
std::vector< itk::SmartPointer< BaseData > > DoRead() override
std::vector< std::string > StringList
mitk::StringList GetDICOMFilesInSameDirectory() const
Base class for creating mitk::BaseData objects from files or streams.
DICOMFilePathList FilterDICOMFilesForSameSeries(const std::string &refFilePath, const DICOMFilePathList &fileList)
std::string GetInputLocation() const override
Get the current input location.
static Pointer New()