Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkMAPRegistrationWrapperIO.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 #include <iostream>
14 #include <fstream>
15 
16 #include <clocale>
17 
18 #include "mapRegistration.h"
19 #include "mapRegistrationFileWriter.h"
20 #include "mapRegistrationFileReader.h"
21 #include "mapLazyFileFieldKernelLoader.h"
22 
23 #include <mitkCustomMimeType.h>
24 #include <mitkIOMimeTypes.h>
25 
28 
29 namespace mitk
30 {
31 
34  struct LocaleSwitch
35  {
36  LocaleSwitch(const std::string& newLocale)
37  : m_OldLocale(std::setlocale(LC_ALL, nullptr))
38  , m_NewLocale(newLocale)
39  {
40  if (m_OldLocale == nullptr)
41  {
42  m_OldLocale = "";
43  }
44  else if (m_NewLocale != m_OldLocale)
45  {
46  // set the locale
47  if (std::setlocale(LC_ALL, m_NewLocale.c_str()) == nullptr)
48  {
49  MITK_INFO << "Could not set locale " << m_NewLocale;
50  m_OldLocale = nullptr;
51  }
52  }
53  }
54 
56  {
57  if (m_OldLocale != nullptr && std::setlocale(LC_ALL, m_OldLocale) == nullptr)
58  {
59  MITK_INFO << "Could not reset locale " << m_OldLocale;
60  }
61  }
62 
63  private:
64  const char* m_OldLocale;
65  const std::string m_NewLocale;
66  };
67 
73  template< unsigned int i, unsigned int j, template < unsigned int, unsigned int> class TFunctor>
74  class DimHelperSub
75  {
76  public:
77  static bool Execute(const mitk::MAPRegistrationWrapper* obj, const map::core::String& data)
78  {
79  if (TFunctor<i,j>::Execute(obj, data))
80  {
81  return true;
82  }
83  return DimHelperSub<i,j-1,TFunctor>::Execute(obj, data);
84  }
85  };
86 
90  template< unsigned int i, template < unsigned int, unsigned int> class TFunctor>
91  class DimHelperSub<i,1,TFunctor >
92  {
93  public:
94  static bool Execute(const mitk::MAPRegistrationWrapper*, const map::core::String&)
95  {
96  //just unwind. Go to the next "row" with DimHelper
97  return false;
98  }
99  };
100 
109  template< unsigned int i, unsigned int j, template < unsigned int, unsigned int> class TFunctor>
110  class DimHelper{
111  public:
112  static bool Execute(const mitk::MAPRegistrationWrapper* obj, const map::core::String& data = "")
113  {
114  if (DimHelperSub<i,j,TFunctor>::Execute(obj, data))
115  {
116  return true;
117  }
118  return DimHelper<i-1,j,TFunctor>::Execute(obj, data);
119  }
120  };
121 
125  template< unsigned int j, template < unsigned int, unsigned int> class TFunctor>
126  class DimHelper<1,j, TFunctor >
127  {
128  public:
129  static bool Execute(const mitk::MAPRegistrationWrapper*, const map::core::String&)
130  {
131  //just unwind. We are done.
132  return false;
133  }
134  };
135 
139  template<unsigned int i, unsigned int j>
140  class CanWrite
141  {
142  public:
143  static bool Execute(const mitk::MAPRegistrationWrapper* obj, const map::core::String& = "")
144  {
145  bool result = false;
146 
147  result = dynamic_cast<const map::core::Registration<i,j> *>(obj->GetRegistration()) != nullptr;
148 
149  return result;
150  }
151  };
152 
155  template<unsigned int i, unsigned int j>
156  class WriteReg
157  {
158  public:
159  static bool Execute(const mitk::MAPRegistrationWrapper* obj, const map::core::String& data)
160  {
161  const map::core::Registration<i,j>* pReg = dynamic_cast<const map::core::Registration<i,j>*>(obj->GetRegistration());
162  if (pReg == nullptr)
163  {
164  return false;
165  }
166 
167  typedef map::io::RegistrationFileWriter<i,j> WriterType;
168  typename WriterType::Pointer writer = WriterType::New();
169 
170  writer->setExpandLazyKernels(false);
171 
172  try
173  {
174  writer->write(pReg,data);
175  }
176  catch (const itk::ExceptionObject& e)
177  {
178  std::cout << e.what() << std::endl;
179  throw;
180  }
181 
182  return true;
183  }
184  };
185 
187  : AbstractFileIO(other)
188  {
189  }
190 
192  {
193  std::string category = "MatchPoint Registration File";
194  CustomMimeType customMimeType;
195  customMimeType.SetCategory(category);
196  customMimeType.AddExtension("mapr");
197  this->AbstractFileIOWriter::SetMimeType(customMimeType);
198  this->AbstractFileIOWriter::SetDescription(category);
199 
200  customMimeType.AddExtension("mapr.xml");
201  customMimeType.AddExtension("MAPR");
202  customMimeType.AddExtension("MAPR.XML");
203  this->AbstractFileIOReader::SetMimeType(customMimeType);
204  this->AbstractFileIOReader::SetDescription(category);
205 
206  this->RegisterService();
207  }
208 
209 
211  {
212  bool success = false;
213  const BaseData* input = this->GetInput();
214  if (input == nullptr)
215  {
216  mitkThrow() << "Cannot write data. Data pointer is nullptr.";
217  }
218 
219  const mitk::MAPRegistrationWrapper* wrapper = dynamic_cast<const mitk::MAPRegistrationWrapper*>(input);
220  if (wrapper == nullptr)
221  {
222  mitkThrow() << "Cannot write data. Data pointer is not a Registration wrapper.";
223  }
224 
225  std::ostream* writeStream = this->GetOutputStream();
226  std::string fileName = this->GetOutputLocation();
227  if (writeStream)
228  {
229  fileName = this->GetLocalFileName();
230  }
231 
232  // Switch the current locale to "C"
233  LocaleSwitch localeSwitch("C");
234 
235  try
236  {
237  success = DimHelper<3,3,WriteReg>::Execute(wrapper, fileName);
238  }
239  catch (const std::exception& e)
240  {
241  mitkThrow() << e.what();
242  }
243 
244  if (!success)
245  {
246  mitkThrow() << "Cannot write registration. Currently only registrations up to 4D are supported.";
247  }
248  }
249 
251  {
252  const mitk::MAPRegistrationWrapper* regWrapper = dynamic_cast<const mitk::MAPRegistrationWrapper*>(this->GetInput());
253 
254  if (regWrapper == nullptr)
255  {
257  }
258 
259  // Check if the registration dimension is supported
260  if (! DimHelper<3,3,CanWrite>::Execute(regWrapper))
261  {
263  };
264 
265  return IFileWriter::Supported;
266  }
267 
268  std::vector<BaseData::Pointer > MAPRegistrationWrapperIO::Read()
269  {
270  std::vector<BaseData::Pointer > result;
271 
272  LocaleSwitch("C");
273 
274  std::string fileName = this->GetLocalFileName();
275  if ( fileName.empty() )
276  {
277  mitkThrow() << "Cannot read file. Filename has not been set!";
278  }
279 
280  /* Remove the following kernel loader provider because in MITK no lazy file loading should be used
281  due to conflicts with session loading (end there usage of temporary directories)*/
282  map::io::RegistrationFileReader::LoaderStackType::unregisterProvider(map::io::LazyFileFieldKernelLoader<2,2>::getStaticProviderName());
283  map::io::RegistrationFileReader::LoaderStackType::unregisterProvider(map::io::LazyFileFieldKernelLoader<3,3>::getStaticProviderName());
284 
285  map::io::RegistrationFileReader::Pointer spReader = map::io::RegistrationFileReader::New();
286  spReader->setPreferLazyLoading(true);
287  map::core::RegistrationBase::Pointer spReg = spReader->read(fileName);
289  spRegWrapper->SetRegistration(spReg);
290 
291  result.push_back(spRegWrapper.GetPointer());
292  return result;
293  }
294 
296  {
298 
299  std::string fileName = this->GetLocalFileName();
300  std::ifstream in( fileName.c_str() );
301  if ( in.good() )
302  {
303  result = IFileReader::Supported;
304  }
305 
306  in.close();
307  return result;
308  }
309 
310  MAPRegistrationWrapperIO* MAPRegistrationWrapperIO::IOClone() const
311  {
312  return new MAPRegistrationWrapperIO(*this);
313  }
314 
315 }
#define MITK_INFO
Definition: mitkLogMacros.h:18
Base of all data objects.
Definition: mitkBaseData.h:37
std::vector< itk::SmartPointer< BaseData > > Read() override
Reads a path or stream and creates a list of BaseData objects.
STL namespace.
DataCollection - Class to facilitate loading/accessing structured data.
ConfidenceLevel GetWriterConfidenceLevel() const override
MAPRegistrationWrapper Wrapper class to allow the handling of MatchPoint registration objects as mitk...
void SetMimeType(const CustomMimeType &mimeType)
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.
::map::core::RegistrationBase * GetRegistration()
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()
void SetDescription(const std::string &description)
const BaseData * GetInput() const override
Get the input data set via SetInput().
void AddExtension(const std::string &extension)
ConfidenceLevel GetReaderConfidenceLevel() const override
LocaleSwitch(const std::string &newLocale)
void SetCategory(const std::string &category)
static bool in(Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4)
Definition: jsoncpp.cpp:244
std::ostream * GetOutputStream() const override
Get the output stream.
void SetMimeType(const CustomMimeType &mimeType)
std::string GetOutputLocation() const override
Get the current output location.
Abstract class for implementing a reader and writer.
void SetDescription(const std::string &description)
Sets a human readable description of this writer.
void Write() override
Write the base data to the specified location or output stream.