MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
mitkAbstractUltrasoundTrackerDevice.cpp
Go to the documentation of this file.
1/*============================================================================
2
3The Medical Imaging Interaction Toolkit (MITK)
4
5Copyright (c) German Cancer Research Center (DKFZ)
6All rights reserved.
7
8Use of this source code is governed by a 3-clause BSD license that can be
9found in the LICENSE file.
10
11============================================================================*/
12
14#include "mitkImageReadAccessor.h"
19#include <mitkUIDGenerator.h>
20
21// US Control Interfaces
25
26// Microservices
27#include <usGetModuleContext.h>
28#include <usModule.h>
29#include <usModuleContext.h>
30#include <usServiceProperties.h>
31
32#include <algorithm>
33
34// TempIncludes
35#include <tinyxml2.h>
36
38 "org.mitk.modules.us.AbstractUltrasoundTrackerDevice";
41
43 "org.mitk.services.AbstractUltrasoundTrackerDevice";
44const std::string mitk::AbstractUltrasoundTrackerDevice::US_PROPKEY_DEVICENAME = US_INTERFACE_NAME + ".devicename";
45const std::string mitk::AbstractUltrasoundTrackerDevice::US_PROPKEY_CLASS = US_INTERFACE_NAME + ".class";
46const std::string mitk::AbstractUltrasoundTrackerDevice::US_PROPKEY_ID = US_INTERFACE_NAME + ".id";
47//____
48
50 NavigationDataSource::Pointer trackingDevice,
51 bool trackedUltrasoundActive)
52 : m_UltrasoundDevice(usDevice),
53 m_TrackingDeviceDataSource(trackingDevice),
54 m_SmoothingFilter(mitk::NavigationDataSmoothingFilter::New()),
55 m_DelayFilter(mitk::NavigationDataDelayFilter::New(0)),
56 m_DisplacementFilter(mitk::NavigationDataDisplacementFilter::New()),
57 m_LastFilterOfIGTPipeline(nullptr),
58 m_NumberOfSmoothingValues(0),
59 m_DelayCount(0),
60 m_IsTrackedUltrasoundActive(trackedUltrasoundActive)
61{
62 m_DisplacementFilter->SetTransform6DOF(true);
63
65
66 // create a new output (for the image data)
67 //___ mitk::Image::Pointer newOutput = mitk::Image::New();
68 //___ this->SetNthOutput(0, newOutput);
69
70 // Combined Modality should not spawn an own acquire thread, because
71 // image acquiring is done by the included us device
72 //___ m_UltrasoundDevice->SetSpawnAcquireThread(false);
73}
74
76{
77 return mitk::AffineTransform3D::New();
78}
79
81{
82 if (m_UltrasoundDevice.IsNull() || m_TrackingDeviceDataSource.IsNull())
83 {
84 MITK_WARN << "Combined modality not correctly initialized, aborting!";
85 return;
86 }
87
88 if (!m_UltrasoundDevice->GetIsActive())
89 {
90 MITK_WARN("mitkUSDevice")
91 << "Cannot freeze or unfreeze if device is not active.";
92 return;
93 }
94
95 this->OnFreeze(freeze);
96
97 if (freeze)
98 {
99 m_IsFreezed = true;
100 }
101 else
102 {
103 m_IsFreezed = false;
104 }
105}
106
108{
109 return m_IsFreezed;
110}
111
113{
114 if (m_ServiceRegistration != nullptr)
115 {
116 m_ServiceRegistration.Unregister();
117 }
118 m_ServiceRegistration = 0;
119}
120
122{
123 return this->GetCalibration(this->GetCurrentDepthValue(), this->GetIdentifierForCurrentProbe());
124}
125
126mitk::AffineTransform3D::Pointer mitk::AbstractUltrasoundTrackerDevice::GetCalibration(std::string depth)
127{
128 return this->GetCalibration(depth, this->GetIdentifierForCurrentProbe());
129}
130
131mitk::AffineTransform3D::Pointer mitk::AbstractUltrasoundTrackerDevice::GetCalibration(std::string depth,
132 std::string probe)
133{
134 // make sure that there is no '/' which would cause problems for TinyXML
135 std::replace(probe.begin(), probe.end(), '/', '-');
136
137 // create identifier for calibration from probe and depth
138 std::string calibrationKey = probe + mitk::AbstractUltrasoundTrackerDevice::ProbeAndDepthSeperator + depth;
139
140 // find calibration for combination of probe identifier and depth
141 std::map<std::string, mitk::AffineTransform3D::Pointer>::iterator calibrationIterator =
142 m_Calibrations.find(calibrationKey);
143
144 if (calibrationIterator == m_Calibrations.end())
145 {
146 return nullptr;
147 }
148
149 return calibrationIterator->second;
150}
151
152void mitk::AbstractUltrasoundTrackerDevice::SetCalibration(mitk::AffineTransform3D::Pointer calibration)
153{
154 if (calibration.IsNull())
155 {
156 MITK_WARN << "Null pointer passed to SetCalibration of mitk::USDevice. Ignoring call.";
157 return;
158 }
159
160 std::string calibrationKey = this->GetIdentifierForCurrentCalibration();
161 if (calibrationKey.empty())
162 {
163 MITK_WARN << "Could not get a key for the calibration -> Calibration cannot be set.";
164 return;
165 }
166
167 m_Calibrations[calibrationKey] = calibration;
168}
169
171{
172 return this->RemoveCalibration(this->GetCurrentDepthValue(), this->GetIdentifierForCurrentProbe());
173}
174
176{
177 return this->RemoveCalibration(depth, this->GetIdentifierForCurrentProbe());
178}
179
180bool mitk::AbstractUltrasoundTrackerDevice::RemoveCalibration(std::string depth, std::string probe)
181{
182 // make sure that there is no '/' which would cause problems for TinyXML
183 std::replace(probe.begin(), probe.end(), '/', '-');
184
185 // create identifier for calibration from probe and depth
186 std::string calibrationKey = probe + mitk::AbstractUltrasoundTrackerDevice::ProbeAndDepthSeperator + depth;
187
188 return m_Calibrations.erase(calibrationKey) > 0;
189}
190
192{
193 return DeviceClassIdentifier;
194}
195
197{
198 if (m_UltrasoundDevice.IsNull())
199 {
200 MITK_ERROR("AbstractUltrasoundTrackerDevice")("USDevice") << "UltrasoundDevice must not be null.";
201 mitkThrow() << "UltrasoundDevice must not be null.";
202 }
203
204 return m_UltrasoundDevice->GetUSImageSource();
205}
206
208{
209 if (m_LastFilterOfIGTPipeline.IsNull())
210 {
211 this->RebuildFilterPipeline();
212 }
213 m_LastFilterOfIGTPipeline->SetToolMetaDataCollection(this->m_TrackingDeviceDataSource->GetToolMetaDataCollection());
214 return m_LastFilterOfIGTPipeline;
215}
216
218{
219 return m_Calibrations.find(this->GetIdentifierForCurrentCalibration()) != m_Calibrations.end();
220}
221
223{
224 return !m_Calibrations.empty();
225}
226
228{
229 tinyxml2::XMLDocument doc;
230 auto* calibrations = doc.NewElement("calibrations");
231 doc.InsertEndChild(calibrations);
232
233 // For each calibration in the set
234 for (std::map<std::string, mitk::AffineTransform3D::Pointer>::iterator it = m_Calibrations.begin();
235 it != m_Calibrations.end();
236 it++)
237 {
238 mitk::AffineTransform3D::MatrixType matrix = it->second->GetMatrix();
239 mitk::AffineTransform3D::TranslationType translation = it->second->GetTranslation();
240 auto *elem = doc.NewElement(it->first.c_str());
241 // Serialize Matrix
242 elem->SetAttribute("M00", matrix[0][0]);
243 elem->SetAttribute("M01", matrix[0][1]);
244 elem->SetAttribute("M02", matrix[0][2]);
245 elem->SetAttribute("M10", matrix[1][0]);
246 elem->SetAttribute("M11", matrix[1][1]);
247 elem->SetAttribute("M12", matrix[1][2]);
248 elem->SetAttribute("M20", matrix[2][0]);
249 elem->SetAttribute("M21", matrix[2][1]);
250 elem->SetAttribute("M22", matrix[2][2]);
251 // Serialize Offset
252 elem->SetAttribute("T0", translation[0]);
253 elem->SetAttribute("T1", translation[1]);
254 elem->SetAttribute("T2", translation[2]);
255
256 calibrations->InsertEndChild(elem);
257 }
258
259 tinyxml2::XMLPrinter printer;
260 doc.Print(&printer);
261
262 return printer.CStr();
263}
264
266 bool clearPreviousCalibrations)
267{
268 // Sanitize Input
269 if (xmlString == "")
270 {
271 MITK_ERROR << "Empty string passed to Deserialize() method of CombinedModality. Aborting...";
272 mitkThrow() << "Empty string passed to Deserialize() method of CombinedModality. Aborting...";
273 return;
274 }
275 // Clear previous calibrations if necessary
276 if (clearPreviousCalibrations)
277 m_Calibrations.clear();
278
279 // Parse Input
280 tinyxml2::XMLDocument doc;
281 if (tinyxml2::XML_SUCCESS != doc.Parse(xmlString.c_str()))
282 {
283 MITK_ERROR << "Unable to deserialize calibrations in CombinedModality. Error was: " << doc.ErrorStr();
284 mitkThrow() << "Unable to deserialize calibrations in CombinedModality. Error was: " << doc.ErrorStr();
285 return;
286 }
287 auto *root = doc.FirstChildElement();
288 if (root == nullptr)
289 {
290 MITK_ERROR << "Unable to deserialize calibrations in CombinedModality. String contained no root element.";
291 mitkThrow() << "Unable to deserialize calibrations in CombinedModality. String contained no root element.";
292 return;
293 }
294 // Read Calibrations
295 for (auto *elem = root->FirstChildElement(); elem != nullptr; elem = elem->NextSiblingElement())
296 {
297 mitk::AffineTransform3D::MatrixType matrix;
298 mitk::AffineTransform3D::OffsetType translation;
299
300 std::string calibName = elem->Value();
301
302 // Deserialize Matrix
303 elem->QueryDoubleAttribute("M00", &matrix[0][0]);
304 elem->QueryDoubleAttribute("M01", &matrix[0][1]);
305 elem->QueryDoubleAttribute("M02", &matrix[0][2]);
306 elem->QueryDoubleAttribute("M10", &matrix[1][0]);
307 elem->QueryDoubleAttribute("M11", &matrix[1][1]);
308 elem->QueryDoubleAttribute("M12", &matrix[1][2]);
309 elem->QueryDoubleAttribute("M20", &matrix[2][0]);
310 elem->QueryDoubleAttribute("M21", &matrix[2][1]);
311 elem->QueryDoubleAttribute("M22", &matrix[2][2]);
312
313 // Deserialize Offset
314 elem->QueryDoubleAttribute("T0", &translation[0]);
315 elem->QueryDoubleAttribute("T1", &translation[1]);
316 elem->QueryDoubleAttribute("T2", &translation[2]);
317
318 mitk::AffineTransform3D::Pointer calibration = mitk::AffineTransform3D::New();
319 calibration->SetMatrix(matrix);
320 calibration->SetTranslation(translation);
321 m_Calibrations[calibName] = calibration;
322 }
323}
324
326{
327 unsigned int oldNumber = m_NumberOfSmoothingValues;
328 m_NumberOfSmoothingValues = numberOfSmoothingValues;
329
330 // if filter should be activated or deactivated
331 if ((oldNumber == 0 && numberOfSmoothingValues != 0) || (oldNumber != 0 && numberOfSmoothingValues == 0))
332 {
333 this->RebuildFilterPipeline();
334 }
335 m_SmoothingFilter->SetNumerOfValues(numberOfSmoothingValues);
336}
337
339{
340 unsigned int oldCount = m_DelayCount;
341 m_DelayCount = delayCount;
342
343 // if filter should be activated or deactivated
344 if ((oldCount == 0 && delayCount != 0) || (oldCount != 0 && delayCount == 0))
345 {
346 this->RebuildFilterPipeline();
347 }
348 m_DelayFilter->SetDelay(delayCount);
349}
350
352
354{
355 return this->GetIdentifierForCurrentProbe() + mitk::AbstractUltrasoundTrackerDevice::ProbeAndDepthSeperator +
356 this->GetCurrentDepthValue();
357}
358
360{
361 us::ServiceProperties usdeviceProperties = m_UltrasoundDevice->GetServiceProperties();
362
363 us::ServiceProperties::const_iterator probeIt =
364 usdeviceProperties.find(mitk::USDevice::GetPropertyKeys().US_PROPKEY_PROBES_SELECTED);
365
366 // get probe identifier from control interface for probes
368 if (probeIt != usdeviceProperties.end())
369 {
370 probeName = (probeIt->second).ToString();
371 }
372
373 // make sure that there is no '/' which would cause problems for TinyXML
374 std::replace(probeName.begin(), probeName.end(), '/', '-');
375
376 return probeName;
377}
378
380{
381 us::ServiceProperties usdeviceProperties = m_UltrasoundDevice->GetServiceProperties();
382
383 // get string for depth value from the micro service properties
384 std::string depth;
385 us::ServiceProperties::iterator depthIterator =
386 usdeviceProperties.find(mitk::USDevice::GetPropertyKeys().US_PROPKEY_BMODE_DEPTH);
387
388 if (depthIterator != usdeviceProperties.end())
389 {
390 depth = depthIterator->second.ToString();
391 }
392 else
393 {
394 depth = "0";
395 }
396
397 return depth;
398}
399
401{
402 m_LastFilterOfIGTPipeline = m_TrackingDeviceDataSource;
403
404 if (m_NumberOfSmoothingValues > 0)
405 {
406 m_SmoothingFilter->ConnectTo(m_LastFilterOfIGTPipeline.GetPointer());
407 m_LastFilterOfIGTPipeline = m_SmoothingFilter;
408 }
409
410 if (m_DelayCount > 0)
411 {
412 m_DelayFilter->ConnectTo(m_LastFilterOfIGTPipeline.GetPointer());
413 m_LastFilterOfIGTPipeline = m_DelayFilter;
414 }
415
416 if (m_IsTrackedUltrasoundActive)
417 {
418 m_DisplacementFilter->ConnectTo(m_LastFilterOfIGTPipeline.GetPointer());
419 m_LastFilterOfIGTPipeline = m_DisplacementFilter;
420 }
421}
422
424{
425 if (m_UltrasoundDevice->GetDeviceState() == USDevice::State_Activated)
426 {
427 m_UltrasoundDevice->Deactivate();
428 }
429 if (m_UltrasoundDevice->GetDeviceState() == USDevice::State_Connected)
430 {
431 m_UltrasoundDevice->Disconnect();
432 }
433
434 if (m_ServiceRegistration != nullptr)
435 m_ServiceRegistration.Unregister();
436 m_ServiceRegistration = 0;
437}
438
440{
441 // Get Context
442 us::ModuleContext *context = us::GetModuleContext();
443
444 // Define ServiceProps
445 // us::ServiceProperties props;
446 mitk::UIDGenerator uidGen = mitk::UIDGenerator("org.mitk.services.AbstractUltrasoundTrackerDevice");
447 m_ServiceProperties[US_PROPKEY_ID] = uidGen.GetUID();
448 m_ServiceProperties[US_PROPKEY_DEVICENAME] = m_UltrasoundDevice->GetName();
449 m_ServiceProperties[US_PROPKEY_CLASS] = mitk::AbstractUltrasoundTrackerDevice::DeviceClassIdentifier;
450
451 m_ServiceRegistration = context->RegisterService(this, m_ServiceProperties);
452}
453
455{
456 if (m_UltrasoundDevice.IsNull())
457 {
458 MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null.";
459 mitkThrow() << "UltrasoundDevice must not be null.";
460 }
461
462 return m_UltrasoundDevice->GetControlInterfaceCustom();
463}
464
466{
467 if (m_UltrasoundDevice.IsNull())
468 {
469 MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null.";
470 mitkThrow() << "UltrasoundDevice must not be null.";
471 }
472
473 return m_UltrasoundDevice->GetControlInterfaceBMode();
474}
475
477{
478 if (m_UltrasoundDevice.IsNull())
479 {
480 MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null.";
481 mitkThrow() << "UltrasoundDevice must not be null.";
482 }
483
484 return m_UltrasoundDevice->GetControlInterfaceProbes();
485}
486
488{
489 if (m_UltrasoundDevice.IsNull())
490 {
491 MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null.";
492 mitkThrow() << "UltrasoundDevice must not be null.";
493 }
494
495 return m_UltrasoundDevice->GetControlInterfaceDoppler();
496}
itk::SmartPointer< mitk::NavigationDataSource > GetNavigationDataSource()
itk::SmartPointer< mitk::NavigationDataDisplacementFilter > m_DisplacementFilter
USImageSource::Pointer GetUSImageSource()
Wrapper for returning USImageSource of the UltrasoundDevice.
virtual itk::SmartPointer< USAbstractControlInterface > GetControlInterfaceCustom()
Wrapper for returning custom control interface of the UltrasoundDevice.
virtual void SetIsFreezed(bool freeze)
Can toggle if the combined modality is currently updated or freezed.
void UnregisterOnService()
Remove this device from the micro service. This method is public for mitk::USCombinedModality,...
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,...
void GenerateData() override
Grabs the next frame from the input. Must be implemented by the derived class. This method is called ...
virtual AffineTransform3D::Pointer GetUSPlaneTransform()
void SetCalibration(AffineTransform3D::Pointer calibration)
Sets a transformation as calibration data. Calibration data is set for the currently activated probe ...
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.
AbstractUltrasoundTrackerDevice(USDevice::Pointer usDevice, itk::SmartPointer< NavigationDataSource > trackingDevice, bool trackedUltrasoundActive)
std::string GetDeviceClass()
Returns the Class of the Device.
void SetNumberOfSmoothingValues(unsigned int numberOfSmoothingValues)
virtual itk::SmartPointer< USControlInterfaceBMode > GetControlInterfaceBMode()
Wrapper for returning B mode control interface of the UltrasoundDevice.
virtual itk::SmartPointer< USControlInterfaceProbes > GetControlInterfaceProbes()
Wrapper for returning probes control interface of the UltrasoundDevice.
std::string SerializeCalibration()
Serializes all contained calibrations into an xml fragment.
bool RemoveCalibration()
Removes the calibration data of the currently active depth and probe.
NavigationDataDisplacementFilter adds an offset to navigation data objects.
This filter smoothes the navigation data by calculating the mean value of the last few input values a...
static mitk::USDevice::PropertyKeys GetPropertyKeys()
IGT Exceptions.