Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkDICOMFileReaderSelector.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 
20 
21 #include <usModuleContext.h>
22 #include <usGetModuleContext.h>
23 #include <usModuleResource.h>
24 #include <usModuleResourceStream.h>
25 #include <usModule.h>
26 
29 {
30 }
31 
34 {
35 }
36 
37 std::list<mitk::DICOMFileReader::Pointer>
40 {
41  return m_Readers;
42 }
43 
44 void
46 ::AddConfigsFromResources(const std::string& path)
47 {
48  const std::vector<us::ModuleResource> configs =
49  us::GetModuleContext()->GetModule()->FindResources( path, "*.xml", false );
50 
51  for ( auto iter = configs.cbegin(); iter != configs.cend(); ++iter )
52  {
53  us::ModuleResource resource = *iter;
54  if (resource.IsValid())
55  {
56  us::ModuleResourceStream stream(resource);
57 
58  // read all into string s
59  std::string s;
60 
61  stream.seekg(0, std::ios::end);
62  s.reserve(stream.tellg());
63  stream.seekg(0, std::ios::beg);
64 
65  s.assign((std::istreambuf_iterator<char>(stream)),
66  std::istreambuf_iterator<char>());
67 
68  this->AddConfig(s);
69  }
70  }
71 }
72 
73 void
76 {
77  if (resource.IsValid())
78  {
79  us::ModuleResourceStream stream(resource);
80 
81  // read all into string s
82  std::string s;
83 
84  stream.seekg(0, std::ios::end);
85  s.reserve(stream.tellg());
86  stream.seekg(0, std::ios::beg);
87 
88  s.assign((std::istreambuf_iterator<char>(stream)),
89  std::istreambuf_iterator<char>());
90 
91  this->AddConfig(s);
92  }
93 }
94 
95 void
97 ::AddConfigFromResource(const std::string& resourcename)
98 {
99  us::ModuleResource r = us::GetModuleContext()->GetModule()->GetResource(resourcename);
100  this->AddConfigFromResource(r);
101 }
102 
103 void
106 {
107  if (reader.IsNotNull())
108  {
109  m_Readers.push_back( reader );
110  }
111 }
112 
113 void
116 {
117  //this->AddConfigsFromResources("configurations/3D");
118  // in this order of preference...
119  this->AddConfigFromResource("configurations/3D/instancenumber.xml");
120  this->AddConfigFromResource("configurations/3D/instancenumber_soft.xml");
121  this->AddConfigFromResource("configurations/3D/slicelocation.xml");
122  this->AddConfigFromResource("configurations/3D/imageposition.xml");
123  this->AddConfigFromResource("configurations/3D/imageposition_byacquisition.xml");
124  //this->AddConfigFromResource("configurations/3D/classicreader.xml"); // not the best choice in ANY of the images I came across
125 }
126 
127 void
130 {
131  this->AddConfigsFromResources("configurations/3DnT");
132 }
133 
134 void
136 ::AddConfig(const std::string& xmlDescription)
137 {
139  DICOMFileReader::Pointer reader = configurator->CreateFromUTF8ConfigString(xmlDescription);
140 
141  if (reader.IsNotNull())
142  {
143  m_Readers.push_back( reader );
144  m_PossibleConfigurations.push_back(xmlDescription);
145  }
146  else
147  {
148  std::stringstream ss;
149  ss << "Could not parse reader configuration. Ignoring it.";
150  throw std::invalid_argument( ss.str() );
151  }
152 }
153 
154 void
156 ::AddConfigFile(const std::string& filename)
157 {
158  std::ifstream file(filename.c_str());
159  std::string s;
160 
161  file.seekg(0, std::ios::end);
162  s.reserve(file.tellg());
163  file.seekg(0, std::ios::beg);
164 
165  s.assign((std::istreambuf_iterator<char>(file)),
166  std::istreambuf_iterator<char>());
167 
168  this->AddConfig(s);
169 }
170 
171 void
174 {
175  m_InputFilenames = filenames;
176 }
177 
178 const mitk::StringList&
181 {
182  return m_InputFilenames;
183 }
184 
188 {
189  ReaderList workingCandidates;
190 
191  // do the tag scanning externally and just ONCE
193  gdcmScanner->SetInputFiles( m_InputFilenames );
194 
195  // let all readers analyze the file set
196  for ( auto rIter = m_Readers.cbegin(); rIter != m_Readers.cend(); ++rIter )
197  {
198  gdcmScanner->AddTagPaths((*rIter)->GetTagsOfInterest());
199  }
200 
201  gdcmScanner->Scan();
202 
203  // let all readers analyze the file set
204  unsigned int readerIndex(0);
205  for ( auto rIter = m_Readers.cbegin(); rIter != m_Readers.cend(); ++readerIndex, ++rIter )
206  {
207  (*rIter)->SetInputFiles( m_InputFilenames );
208  (*rIter)->SetTagCache( gdcmScanner->GetScanCache() );
209  try
210  {
211  (*rIter)->AnalyzeInputFiles();
212  workingCandidates.push_back( *rIter );
213  MITK_INFO << "Reader " << readerIndex << " (" << (*rIter)->GetConfigurationLabel() << ") suggests " << (*rIter)->GetNumberOfOutputs() << " 3D blocks";
214  if ((*rIter)->GetNumberOfOutputs() == 1)
215  {
216  MITK_DEBUG << "Early out with reader #" << readerIndex << " (" << (*rIter)->GetConfigurationLabel() << "), less than 1 block is not possible";
217  return *rIter;
218  }
219  }
220  catch ( const std::exception& e )
221  {
222  MITK_ERROR << "Reader " << readerIndex << " (" << (*rIter)->GetConfigurationLabel() << ") threw exception during file analysis, ignoring this reader. Exception: " << e.what();
223  }
224  catch (...)
225  {
226  MITK_ERROR << "Reader " << readerIndex << " (" << (*rIter)->GetConfigurationLabel() << ") threw unknown exception during file analysis, ignoring this reader.";
227  }
228  }
229 
230  DICOMFileReader::Pointer bestReader;
231 
232  unsigned int minimumNumberOfOutputs = std::numeric_limits<unsigned int>::max();
233  readerIndex = 0;
234  unsigned int bestReaderIndex(0);
235  // select the reader with the minimum number of mitk::Images as output
236  for ( auto rIter = workingCandidates.cbegin(); rIter != workingCandidates.cend(); ++readerIndex, ++rIter )
237  {
238  const unsigned int thisReadersNumberOfOutputs = (*rIter)->GetNumberOfOutputs();
239  if ( thisReadersNumberOfOutputs > 0 // we don't count readers that don't actually produce output
240  && thisReadersNumberOfOutputs < minimumNumberOfOutputs )
241  {
242  minimumNumberOfOutputs = (*rIter)->GetNumberOfOutputs();
243  bestReader = *rIter;
244  bestReaderIndex = readerIndex;
245  }
246  }
247 
248  MITK_DEBUG << "Decided for reader #" << bestReaderIndex << " (" << bestReader->GetConfigurationLabel() << ")";
249  MITK_DEBUG << m_PossibleConfigurations[bestReaderIndex];
250 
251  return bestReader;
252 }
itk::SmartPointer< Self > Pointer
#define MITK_INFO
Definition: mitkLogMacros.h:22
void AddConfigFile(const std::string &filename)
Add a configuration as expected by DICOMReaderConfigurator. Configs can only be reset by instantiatin...
#define MITK_ERROR
Definition: mitkLogMacros.h:24
#define MITK_DEBUG
Definition: mitkLogMacros.h:26
std::list< DICOMFileReader::Pointer > ReaderList
void AddConfig(const std::string &xmlDescription)
Add a configuration as expected by DICOMReaderConfigurator. Configs can only be reset by instantiatin...
void SetInputFiles(StringList filenames)
Input files.
void AddConfigFromResource(const std::string &resourcename)
ReaderList GetAllConfiguredReaders() const
Return all the DICOMFileReaders that are currently used for selection by this class. The readers returned by this method depend on what config files have been added earlier (or which of the built-in readers have been loaded)
Module * GetModule() const
static const std::string filename
const StringList & GetInputFiles() const
Input files.
static T max(T x, T y)
Definition: svm.cpp:70
void AddConfigsFromResources(const std::string &path)
std::vector< std::string > StringList
void LoadBuiltIn3DnTConfigs()
Load 3D+t image creating configurations from the MITK module system (see mitk::Module::FindResources)...
DICOMFileReader::Pointer GetFirstReaderWithMinimumNumberOfOutputImages()
Execute the analysis and selection process. The first reader with a minimal number of outputs will be...
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.
void LoadBuiltIn3DConfigs()
Load 3D image creating configurations from the MITK module system (see mitk::Module::FindResources). For a default set of configurations, look into the directory Resources of the DICOMReader module.
void AddFileReaderCanditate(DICOMFileReader::Pointer reader)
Add a whole pre-configured reader to the selection process.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.