Medical Imaging Interaction Toolkit  2018.4.99-1640525a
Medical Imaging Interaction Toolkit
mitkAbstractUltrasoundTrackerDevice.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 #include "mitkImageReadAccessor.h"
19 
20 // US Control Interfaces
24 
25 // Microservices
26 #include <usGetModuleContext.h>
27 #include <usModule.h>
28 #include <usModuleContext.h>
29 #include <usServiceProperties.h>
30 
31 #include <algorithm>
32 
33 // TempIncludes
34 #include <tinyxml.h>
35 
37  "org.mitk.modules.us.AbstractUltrasoundTrackerDevice";
40 
42  "org.mitk.services.AbstractUltrasoundTrackerDevice";
43 const std::string mitk::AbstractUltrasoundTrackerDevice::US_PROPKEY_DEVICENAME = US_INTERFACE_NAME + ".devicename";
44 const std::string mitk::AbstractUltrasoundTrackerDevice::US_PROPKEY_CLASS = US_INTERFACE_NAME + ".class";
45 const std::string mitk::AbstractUltrasoundTrackerDevice::US_PROPKEY_ID = US_INTERFACE_NAME + ".id";
46 //____
47 
49  NavigationDataSource::Pointer trackingDevice,
50  bool trackedUltrasoundActive)
51  : m_UltrasoundDevice(usDevice),
52  m_TrackingDeviceDataSource(trackingDevice),
53  m_SmoothingFilter(mitk::NavigationDataSmoothingFilter::New()),
54  m_DelayFilter(mitk::NavigationDataDelayFilter::New(0)),
55  m_DisplacementFilter(mitk::NavigationDataDisplacementFilter::New()),
56  m_LastFilterOfIGTPipeline(nullptr),
57  m_NumberOfSmoothingValues(0),
58  m_DelayCount(0),
59  m_IsTrackedUltrasoundActive(trackedUltrasoundActive)
60 {
61  m_DisplacementFilter->SetTransform6DOF(true);
62 
63  this->RebuildFilterPipeline();
64 
65  // create a new output (for the image data)
66  //___ mitk::Image::Pointer newOutput = mitk::Image::New();
67  //___ this->SetNthOutput(0, newOutput);
68 
69  // Combined Modality should not spawn an own acquire thread, because
70  // image acquiring is done by the included us device
71  //___ m_UltrasoundDevice->SetSpawnAcquireThread(false);
72 }
73 
75 {
76  return mitk::AffineTransform3D::New();
77 }
78 
80 {
81  if (m_UltrasoundDevice.IsNull() || m_TrackingDeviceDataSource.IsNull())
82  {
83  MITK_WARN << "Combined modality not correctly initialized, aborting!";
84  return;
85  }
86 
87  if (!m_UltrasoundDevice->GetIsActive())
88  {
89  MITK_WARN("mitkUSDevice")
90  << "Cannot freeze or unfreeze if device is not active.";
91  return;
92  }
93 
94  this->OnFreeze(freeze);
95 
96  if (freeze)
97  {
98  m_IsFreezed = true;
99  }
100  else
101  {
102  m_IsFreezed = false;
103  }
104 }
105 
107 {
108  return m_IsFreezed;
109 }
110 
112 {
113  if (m_ServiceRegistration != nullptr)
114  {
116  }
118 }
119 
121 {
123 }
124 
125 mitk::AffineTransform3D::Pointer mitk::AbstractUltrasoundTrackerDevice::GetCalibration(std::string depth)
126 {
127  return this->GetCalibration(depth, this->GetIdentifierForCurrentProbe());
128 }
129 
130 mitk::AffineTransform3D::Pointer mitk::AbstractUltrasoundTrackerDevice::GetCalibration(std::string depth,
131  std::string probe)
132 {
133  // make sure that there is no '/' which would cause problems for TinyXML
134  std::replace(probe.begin(), probe.end(), '/', '-');
135 
136  // create identifier for calibration from probe and depth
137  std::string calibrationKey = probe + mitk::AbstractUltrasoundTrackerDevice::ProbeAndDepthSeperator + depth;
138 
139  // find calibration for combination of probe identifier and depth
140  std::map<std::string, mitk::AffineTransform3D::Pointer>::iterator calibrationIterator =
141  m_Calibrations.find(calibrationKey);
142 
143  if (calibrationIterator == m_Calibrations.end())
144  {
145  return nullptr;
146  }
147 
148  return calibrationIterator->second;
149 }
150 
151 void mitk::AbstractUltrasoundTrackerDevice::SetCalibration(mitk::AffineTransform3D::Pointer calibration)
152 {
153  if (calibration.IsNull())
154  {
155  MITK_WARN << "Null pointer passed to SetCalibration of mitk::USDevice. Ignoring call.";
156  return;
157  }
158 
159  std::string calibrationKey = this->GetIdentifierForCurrentCalibration();
160  if (calibrationKey.empty())
161  {
162  MITK_WARN << "Could not get a key for the calibration -> Calibration cannot be set.";
163  return;
164  }
165 
166  m_Calibrations[calibrationKey] = calibration;
167 }
168 
170 {
172 }
173 
175 {
176  return this->RemoveCalibration(depth, this->GetIdentifierForCurrentProbe());
177 }
178 
179 bool mitk::AbstractUltrasoundTrackerDevice::RemoveCalibration(std::string depth, std::string probe)
180 {
181  // make sure that there is no '/' which would cause problems for TinyXML
182  std::replace(probe.begin(), probe.end(), '/', '-');
183 
184  // create identifier for calibration from probe and depth
185  std::string calibrationKey = probe + mitk::AbstractUltrasoundTrackerDevice::ProbeAndDepthSeperator + depth;
186 
187  return m_Calibrations.erase(calibrationKey) > 0;
188 }
189 
191 {
192  return DeviceClassIdentifier;
193 }
194 
196 {
197  if (m_UltrasoundDevice.IsNull())
198  {
199  MITK_ERROR("AbstractUltrasoundTrackerDevice")("USDevice") << "UltrasoundDevice must not be null.";
200  mitkThrow() << "UltrasoundDevice must not be null.";
201  }
202 
203  return m_UltrasoundDevice->GetUSImageSource();
204 }
205 
207 {
208  if (m_LastFilterOfIGTPipeline.IsNull())
209  {
210  this->RebuildFilterPipeline();
211  }
212  m_LastFilterOfIGTPipeline->SetToolMetaDataCollection(this->m_TrackingDeviceDataSource->GetToolMetaDataCollection());
214 }
215 
217 {
219 }
220 
222 {
223  return !m_Calibrations.empty();
224 }
225 
227 {
228  std::stringstream result;
229  result << "<calibrations>" << std::endl;
230  // For each calibration in the set
231  for (std::map<std::string, mitk::AffineTransform3D::Pointer>::iterator it = m_Calibrations.begin();
232  it != m_Calibrations.end();
233  it++)
234  {
235  mitk::AffineTransform3D::MatrixType matrix = it->second->GetMatrix();
236  mitk::AffineTransform3D::TranslationType translation = it->second->GetTranslation();
237  TiXmlElement elem(it->first);
238  // Serialize Matrix
239  elem.SetDoubleAttribute("M00", matrix[0][0]);
240  elem.SetDoubleAttribute("M01", matrix[0][1]);
241  elem.SetDoubleAttribute("M02", matrix[0][2]);
242  elem.SetDoubleAttribute("M10", matrix[1][0]);
243  elem.SetDoubleAttribute("M11", matrix[1][1]);
244  elem.SetDoubleAttribute("M12", matrix[1][2]);
245  elem.SetDoubleAttribute("M20", matrix[2][0]);
246  elem.SetDoubleAttribute("M21", matrix[2][1]);
247  elem.SetDoubleAttribute("M22", matrix[2][2]);
248  // Serialize Offset
249  elem.SetDoubleAttribute("T0", translation[0]);
250  elem.SetDoubleAttribute("T1", translation[1]);
251  elem.SetDoubleAttribute("T2", translation[2]);
252 
253  result << elem << std::endl;
254  }
255  result << "</calibrations>" << std::endl;
256 
257  return result.str();
258 }
259 
261  bool clearPreviousCalibrations)
262 {
263  // Sanitize Input
264  if (xmlString == "")
265  {
266  MITK_ERROR << "Empty string passed to Deserialize() method of CombinedModality. Aborting...";
267  mitkThrow() << "Empty string passed to Deserialize() method of CombinedModality. Aborting...";
268  return;
269  }
270  // Clear previous calibrations if necessary
271  if (clearPreviousCalibrations)
272  m_Calibrations.clear();
273 
274  // Parse Input
275  TiXmlDocument doc;
276  if (!doc.Parse(xmlString.c_str()))
277  {
278  MITK_ERROR << "Unable to deserialize calibrations in CombinedModality. Error was: " << doc.ErrorDesc();
279  mitkThrow() << "Unable to deserialize calibrations in CombinedModality. Error was: " << doc.ErrorDesc();
280  return;
281  }
282  TiXmlElement *root = doc.FirstChildElement();
283  if (root == nullptr)
284  {
285  MITK_ERROR << "Unable to deserialize calibrations in CombinedModality. String contained no root element.";
286  mitkThrow() << "Unable to deserialize calibrations in CombinedModality. String contained no root element.";
287  return;
288  }
289  // Read Calibrations
290  for (TiXmlElement *elem = root->FirstChildElement(); elem != nullptr; elem = elem->NextSiblingElement())
291  {
292  mitk::AffineTransform3D::MatrixType matrix;
293  mitk::AffineTransform3D::OffsetType translation;
294 
295  std::string calibName = elem->Value();
296 
297  // Deserialize Matrix
298  elem->QueryDoubleAttribute("M00", &matrix[0][0]);
299  elem->QueryDoubleAttribute("M01", &matrix[0][1]);
300  elem->QueryDoubleAttribute("M02", &matrix[0][2]);
301  elem->QueryDoubleAttribute("M10", &matrix[1][0]);
302  elem->QueryDoubleAttribute("M11", &matrix[1][1]);
303  elem->QueryDoubleAttribute("M12", &matrix[1][2]);
304  elem->QueryDoubleAttribute("M20", &matrix[2][0]);
305  elem->QueryDoubleAttribute("M21", &matrix[2][1]);
306  elem->QueryDoubleAttribute("M22", &matrix[2][2]);
307 
308  // Deserialize Offset
309  elem->QueryDoubleAttribute("T0", &translation[0]);
310  elem->QueryDoubleAttribute("T1", &translation[1]);
311  elem->QueryDoubleAttribute("T2", &translation[2]);
312 
313  mitk::AffineTransform3D::Pointer calibration = mitk::AffineTransform3D::New();
314  calibration->SetMatrix(matrix);
315  calibration->SetTranslation(translation);
316  m_Calibrations[calibName] = calibration;
317  }
318 }
319 
321 {
322  unsigned int oldNumber = m_NumberOfSmoothingValues;
323  m_NumberOfSmoothingValues = numberOfSmoothingValues;
324 
325  // if filter should be activated or deactivated
326  if ((oldNumber == 0 && numberOfSmoothingValues != 0) || (oldNumber != 0 && numberOfSmoothingValues == 0))
327  {
328  this->RebuildFilterPipeline();
329  }
330  m_SmoothingFilter->SetNumerOfValues(numberOfSmoothingValues);
331 }
332 
334 {
335  unsigned int oldCount = m_DelayCount;
336  m_DelayCount = delayCount;
337 
338  // if filter should be activated or deactivated
339  if ((oldCount == 0 && delayCount != 0) || (oldCount != 0 && delayCount == 0))
340  {
341  this->RebuildFilterPipeline();
342  }
343  m_DelayFilter->SetDelay(delayCount);
344 }
345 
347 
349 {
351  this->GetCurrentDepthValue();
352 }
353 
355 {
356  us::ServiceProperties usdeviceProperties = m_UltrasoundDevice->GetServiceProperties();
357 
358  us::ServiceProperties::const_iterator probeIt =
359  usdeviceProperties.find(mitk::USDevice::GetPropertyKeys().US_PROPKEY_PROBES_SELECTED);
360 
361  // get probe identifier from control interface for probes
363  if (probeIt != usdeviceProperties.end())
364  {
365  probeName = (probeIt->second).ToString();
366  }
367 
368  // make sure that there is no '/' which would cause problems for TinyXML
369  std::replace(probeName.begin(), probeName.end(), '/', '-');
370 
371  return probeName;
372 }
373 
375 {
376  us::ServiceProperties usdeviceProperties = m_UltrasoundDevice->GetServiceProperties();
377 
378  // get string for depth value from the micro service properties
379  std::string depth;
380  us::ServiceProperties::iterator depthIterator =
381  usdeviceProperties.find(mitk::USDevice::GetPropertyKeys().US_PROPKEY_BMODE_DEPTH);
382 
383  if (depthIterator != usdeviceProperties.end())
384  {
385  depth = depthIterator->second.ToString();
386  }
387  else
388  {
389  depth = "0";
390  }
391 
392  return depth;
393 }
394 
396 {
398 
400  {
401  m_SmoothingFilter->ConnectTo(m_LastFilterOfIGTPipeline.GetPointer());
403  }
404 
405  if (m_DelayCount > 0)
406  {
407  m_DelayFilter->ConnectTo(m_LastFilterOfIGTPipeline.GetPointer());
409  }
410 
411  if (m_IsTrackedUltrasoundActive)
412  {
413  m_DisplacementFilter->ConnectTo(m_LastFilterOfIGTPipeline.GetPointer());
415  }
416 }
417 
419 {
420  if (m_UltrasoundDevice->GetDeviceState() == USDevice::State_Activated)
421  {
422  m_UltrasoundDevice->Deactivate();
423  }
424  if (m_UltrasoundDevice->GetDeviceState() == USDevice::State_Connected)
425  {
426  m_UltrasoundDevice->Disconnect();
427  }
428 
429  if (m_ServiceRegistration != nullptr)
432 }
433 
435 {
436  // Get Context
437  us::ModuleContext *context = us::GetModuleContext();
438 
439  // Define ServiceProps
440  // us::ServiceProperties props;
441  mitk::UIDGenerator uidGen = mitk::UIDGenerator("org.mitk.services.AbstractUltrasoundTrackerDevice");
445 
446  m_ServiceRegistration = context->RegisterService(this, m_ServiceProperties);
447 }
448 
449 mitk::USAbstractControlInterface::Pointer mitk::AbstractUltrasoundTrackerDevice::GetControlInterfaceCustom()
450 {
451  if (m_UltrasoundDevice.IsNull())
452  {
453  MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null.";
454  mitkThrow() << "UltrasoundDevice must not be null.";
455  }
456 
457  return m_UltrasoundDevice->GetControlInterfaceCustom();
458 }
459 
461 {
462  if (m_UltrasoundDevice.IsNull())
463  {
464  MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null.";
465  mitkThrow() << "UltrasoundDevice must not be null.";
466  }
467 
468  return m_UltrasoundDevice->GetControlInterfaceBMode();
469 }
470 
472 {
473  if (m_UltrasoundDevice.IsNull())
474  {
475  MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null.";
476  mitkThrow() << "UltrasoundDevice must not be null.";
477  }
478 
479  return m_UltrasoundDevice->GetControlInterfaceProbes();
480 }
481 
483 {
484  if (m_UltrasoundDevice.IsNull())
485  {
486  MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null.";
487  mitkThrow() << "UltrasoundDevice must not be null.";
488  }
489 
490  return m_UltrasoundDevice->GetControlInterfaceDoppler();
491 }
std::string GetDeviceClass()
Returns the Class of the Device.
Generated unique IDs.
std::string SerializeCalibration()
Serializes all contained calibrations into an xml fragment.
#define MITK_ERROR
Definition: mitkLogMacros.h:20
NavigationDataDisplacementFilter adds an offset to navigation data objects.
virtual AffineTransform3D::Pointer GetUSPlaneTransform()
virtual void SetIsFreezed(bool freeze)
Can toggle if the combined modality is currently updated or freezed.
DataCollection - Class to facilitate loading/accessing structured data.
static mitk::USDevice::PropertyKeys GetPropertyKeys()
void SetCalibration(AffineTransform3D::Pointer calibration)
Sets a transformation as calibration data. Calibration data is set for the currently activated probe ...
itk::SmartPointer< mitk::NavigationDataDelayFilter > m_DelayFilter
bool RemoveCalibration()
Removes the calibration data of the currently active depth and probe.
void SetNumberOfSmoothingValues(unsigned int numberOfSmoothingValues)
void GenerateData() override
Grabs the next frame from the input. Must be implemented by the derived class. This method is called ...
itk::SmartPointer< mitk::NavigationDataSmoothingFilter > m_SmoothingFilter
#define MITK_WARN
Definition: mitkLogMacros.h:19
itk::SmartPointer< mitk::NavigationDataDisplacementFilter > m_DisplacementFilter
AbstractUltrasoundTrackerDevice(USDevice::Pointer usDevice, itk::SmartPointer< NavigationDataSource > trackingDevice, bool trackedUltrasoundActive)
std::map< std::string, AffineTransform3D::Pointer > m_Calibrations
#define mitkThrow()
This filter smoothes the navigation data by calculating the mean value of the last few input values a...
itk::SmartPointer< mitk::NavigationDataSource > GetNavigationDataSource()
virtual void OnFreeze(bool)
Called when mitk::AbstractUltrasoundTrackerDevice::SetIsFreezed() is called. Subclasses can overwrite...
virtual itk::SmartPointer< USControlInterfaceBMode > GetControlInterfaceBMode()
Wrapper for returning B mode control interface of the UltrasoundDevice.
void UnregisterOnService()
Remove this device from the micro service. This method is public for mitk::USCombinedModality, because this devices can be completly removed. This is not possible for API devices, which should be available while their sub module is loaded.
virtual itk::SmartPointer< USControlInterfaceDoppler > GetControlInterfaceDoppler()
Wrapper for returning doppler control interface of the UltrasoundDevice.
AffineTransform3D::Pointer GetCalibration()
Getter for calibration data of the currently active depth and probe.
US_UNORDERED_MAP_TYPE< std::string, Any > ServiceProperties
virtual itk::SmartPointer< USAbstractControlInterface > GetControlInterfaceCustom()
Wrapper for returning custom control interface of the UltrasoundDevice.
itk::SmartPointer< mitk::NavigationDataSource > m_LastFilterOfIGTPipeline
void DeserializeCalibration(const std::string &xmlString, bool clearPreviousCalibrations=true)
Deserializes a string provided by a prior call to Serialize(). If the bool flag is true...
static const char * replace[]
This is a dictionary to replace long names of classes, modules, etc. to shorter versions in the conso...
us::ServiceRegistration< Self > m_ServiceRegistration
The device&#39;s ServiceRegistration object that allows to modify it&#39;s Microservice registraton details...
USImageSource::Pointer GetUSImageSource()
Wrapper for returning USImageSource of the UltrasoundDevice.
itk::SmartPointer< NavigationDataSource > m_TrackingDeviceDataSource
virtual itk::SmartPointer< USControlInterfaceProbes > GetControlInterfaceProbes()
Wrapper for returning probes control interface of the UltrasoundDevice.
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.
us::ServiceProperties m_ServiceProperties
Properties of the device&#39;s Microservice.