Medical Imaging Interaction Toolkit  2018.4.99-a3d2e8fb
Medical Imaging Interaction Toolkit
mitkUSDevicePersistence.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 //Microservices
16 #include <usServiceReference.h>
17 #include <usModuleContext.h>
18 #include <usGetModuleContext.h>
19 #include <usModuleContext.h>
20 
21 #include <iostream>
22 
23 mitk::USDevicePersistence::USDevicePersistence() : m_devices("MITK US", "Device Settings")
24 {
25 }
26 
28 {
29  us::ModuleContext* thisContext = us::GetModuleContext();
30 
31  std::vector<us::ServiceReference<USDevice> > services = thisContext->GetServiceReferences<USDevice>();
32  MITK_INFO << "Trying to save " << services.size() << " US devices.";
33  int numberOfSavedDevices = 0;
34  for (std::vector<us::ServiceReference<USDevice> >::iterator it = services.begin(); it != services.end(); ++it)
35  {
36  mitk::USDevice::Pointer currentDevice = thisContext->GetService(*it);
37  //check if it is a USVideoDevice
38  if (currentDevice->GetDeviceClass() == "org.mitk.modules.us.USVideoDevice")
39  {
40  mitk::USVideoDevice::Pointer currentVideoDevice = dynamic_cast<mitk::USVideoDevice*>(currentDevice.GetPointer());
41  QString identifier = "device" + QString::number(numberOfSavedDevices);
42  m_devices.setValue(identifier, USVideoDeviceToString(currentVideoDevice));
43  numberOfSavedDevices++;
44  }
45 
46  else
47  {
48  MITK_WARN << "Saving of US devices of the type " << currentDevice->GetDeviceClass() << " is not supported at the moment. Skipping device.";
49  }
50  }
51  m_devices.setValue("numberOfSavedDevices", numberOfSavedDevices);
52  MITK_INFO << "Successfully saved " << numberOfSavedDevices << " US devices.";
53 }
54 
55 std::vector<mitk::USDevice::Pointer> mitk::USDevicePersistence::RestoreLastDevices()
56 {
57  std::vector<mitk::USDevice::Pointer> devices;
58 
59  int numberOfSavedDevices = m_devices.value("numberOfSavedDevices").toInt();
60 
61  for (int i = 0; i < numberOfSavedDevices; i++)
62  {
63  // Try each device. If an exception occurs: Ignore device and notify user
64  try
65  {
66  QString currentString = m_devices.value("device" + QString::number(i)).toString();
67  mitk::USDevice::Pointer currentDevice = dynamic_cast<mitk::USDevice*>(StringToUSVideoDevice(currentString).GetPointer());
68  //currentDevice->Initialize();
69  devices.push_back(currentDevice.GetPointer());
70  }
71  catch (...)
72  {
73  MITK_ERROR << "Error occured while loading a USVideoDevice from persistence. Device assumed corrupt, will be deleted.";
74  //QMessageBox::warning(nullptr, "Could not load device" ,"A stored ultrasound device is corrupted and could not be loaded. The device will be deleted.");
75  }
76  }
77 
78  MITK_INFO << "Restoring " << numberOfSavedDevices << " US devices.";
79 
80  return devices;
81 }
82 
84 {
85  QString manufacturer = d->GetManufacturer().c_str();
86  QString model = d->GetName().c_str();
87  QString comment = d->GetComment().c_str();
88  int source = d->GetDeviceID();
89  std::string file = d->GetFilePath();
90  if (!d->GetIsSourceFile()) file = "none"; //if GetIsSourceFile is true, the device plays back a file
91 
92  mitk::USImageVideoSource::Pointer imageSource = dynamic_cast<mitk::USImageVideoSource*>(d->GetUSImageSource().GetPointer());
93  if (!imageSource)
94  {
95  MITK_ERROR << "There is no USImageVideoSource at the current device.";
96  mitkThrow() << "There is no USImageVideoSource at the current device.";
97  }
98 
99  int greyscale = imageSource->GetIsGreyscale();
100  int resOverride = imageSource->GetResolutionOverride();
101  int resWidth = imageSource->GetResolutionOverrideWidth();
102  int resHight = imageSource->GetResolutionOverrideHeight();
103 
104  QString probes = ""; //ACV$100%1%1%0$120%2%2%0$140%2%2%5!BDW$90%1%1%2$100%1%1%8!CSV$50%1%2%3$60%2%2%5
105 
106  char probesSeperator = '!';
107  std::vector<mitk::USProbe::Pointer> allProbesOfDevice = d->GetAllProbes();
108  if (allProbesOfDevice.size() > 0)
109  {
110  for (std::vector<mitk::USProbe::Pointer>::iterator it = allProbesOfDevice.begin(); it != allProbesOfDevice.end(); it++)
111  {
112  if (it == allProbesOfDevice.begin())
113  { // if it is the first element there is no need for the probes seperator
114  probes = probes + USProbeToString(*it);
115  }
116  else
117  {
118  probes = probes + probesSeperator + USProbeToString(*it);
119  }
120  }
121  }
122 
123  char seperator = '|';
124 
125  QString returnValue = manufacturer + seperator
126  + model + seperator
127  + comment + seperator
128  + QString::number(source) + seperator
129  + file.c_str() + seperator
130  + QString::number(greyscale) + seperator
131  + QString::number(resOverride) + seperator
132  + QString::number(resWidth) + seperator
133  + QString::number(resHight) + seperator
134  + probes
135  ;
136 
137  MITK_INFO << "Output String: " << returnValue.toStdString();
138  return returnValue;
139 }
140 
141 QString mitk::USDevicePersistence::USProbeToString(mitk::USProbe::Pointer p)
142 {
143  QString probe = QString::fromStdString(p->GetName());
144  QString croppingSeparator = QString(",");
145  probe = probe + croppingSeparator + QString::number(p->GetProbeCropping().top)
146  + croppingSeparator + QString::number(p->GetProbeCropping().right)
147  + croppingSeparator + QString::number(p->GetProbeCropping().bottom)
148  + croppingSeparator + QString::number(p->GetProbeCropping().left)
149  + croppingSeparator;
150 
151  char depthSeperator = '$';
152  char spacingSeperator = '%';
153  std::map<int, mitk::Vector3D> depthsAndSpacing = p->GetDepthsAndSpacing();
154  if (depthsAndSpacing.size() > 0)
155  {
156  for (std::map<int, mitk::Vector3D>::iterator it = depthsAndSpacing.begin(); it != depthsAndSpacing.end(); it++){
157  probe = probe + depthSeperator + QString::number(it->first) + spacingSeperator + QString::number(it->second[0])
158  + spacingSeperator + QString::number(it->second[1]) + spacingSeperator + QString::number(it->second[2]);
159  }
160  }
161  return probe;
162 }
163 
165 {
166  MITK_INFO << "Input String: " << s.toStdString();
167  std::vector<std::string> data;
168  std::string seperators = "|";
169  std::string text = s.toStdString();
170  split(text, seperators, data);
171  if (data.size() != 10)
172  {
173  MITK_ERROR << "Cannot parse US device! (Size: " << data.size() << ")";
174  return mitk::USVideoDevice::New("INVALID", "INVALID", "INVALID");
175  }
176 
177  std::string manufacturer = data.at(0);
178  std::string model = data.at(1);
179  std::string comment = data.at(2);
180  int source = (QString(data.at(3).c_str())).toInt();
181  std::string file = data.at(4);
182  bool greyscale = (QString(data.at(5).c_str())).toInt();
183  bool resOverride = (QString(data.at(6).c_str())).toInt();
184  int resWidth = (QString(data.at(7).c_str())).toInt();
185  int resHight = (QString(data.at(8).c_str())).toInt();
186 
187  // Create Device
188  mitk::USVideoDevice::Pointer returnValue;
189  if (file == "none")
190  {
191  returnValue = mitk::USVideoDevice::New(source, manufacturer, model);
192  returnValue->SetComment(comment);
193  }
194  else
195  {
196  returnValue = mitk::USVideoDevice::New(file, manufacturer, model);
197  returnValue->SetComment(comment);
198  }
199 
200  mitk::USImageVideoSource::Pointer imageSource =
201  dynamic_cast<mitk::USImageVideoSource*>(returnValue->GetUSImageSource().GetPointer());
202  if (!imageSource)
203  {
204  MITK_ERROR << "There is no USImageVideoSource at the current device.";
205  mitkThrow() << "There is no USImageVideoSource at the current device.";
206  }
207 
208  // Set Video Options
209  imageSource->SetColorOutput(!greyscale);
210 
211  // If Resolution override is activated, apply it
212  if (resOverride)
213  {
214  imageSource->OverrideResolution(resWidth, resHight);
215  imageSource->SetResolutionOverride(true);
216  }
217 
218  std::string probes = data.at(9);
219  std::string probesSeperator = "!";
220  std::vector<std::string> probesVector;
221  split(probes, probesSeperator, probesVector);
222  for (std::vector<std::string>::iterator it = probesVector.begin(); it != probesVector.end(); it++)
223  {
224  mitk::USProbe::Pointer probe = StringToUSProbe(*it);
225  returnValue->AddNewProbe(probe);
226  }
227 
228  return returnValue;
229 }
230 
231 mitk::USProbe::Pointer mitk::USDevicePersistence::StringToUSProbe(std::string s)
232 {
233  mitk::USProbe::Pointer probe = mitk::USProbe::New();
234  std::string croppingSeparator = ",";
235  std::string spacingSeperator = "%";
236  std::string depthSeperator = "$";
237  std::vector<std::string> probeCropping;
238  split(s, croppingSeparator, probeCropping);
239 
240  std::vector<std::string> depthsWithSpacings;
241  split(s, depthSeperator, depthsWithSpacings);
242 
243  //The first entry of the probeCropping vector is the name of the ultrasound probe:
244  std::string probeName = probeCropping.at(0);
245  probe->SetName(probeName);
246  //The entries 1, 2, 3 and 4 of the probeCropping vector are the cropping top,
247  // right, bottom and left:
248  if( probeCropping.size() >= 6 )
249  {
250  QString top = QString::fromStdString(probeCropping.at(1));
251  QString right = QString::fromStdString(probeCropping.at(2));
252  QString bottom = QString::fromStdString(probeCropping.at(3));
253  QString left = QString::fromStdString(probeCropping.at(4));
254  probe->SetProbeCropping(top.toUInt(), bottom.toUInt(), left.toUInt(), right.toUInt());
255  }
256 
257  for (std::vector<std::string>::iterator it = depthsWithSpacings.begin(); it != depthsWithSpacings.end(); it++)
258  {
259  //The first element is the name of the probe and the cropping entries.
260  //other elements are the scanning depths of the probe and the spacing
261  if (it != depthsWithSpacings.begin())
262  {
263  std::vector<std::string> spacings;
264  split(*it, spacingSeperator, spacings);
265  mitk::Vector3D spacing;
266  double x;
267  double y;
268  double z;
269  int depth;
270  try
271  {
272  x = spacingToDouble(spacings.at(1));
273  y = spacingToDouble(spacings.at(2));
274  z = spacingToDouble(spacings.at(3));
275  }
276  catch (const mitk::Exception& e)
277  {
278  MITK_ERROR << e.GetDescription() << "Spacing of " << probe->GetName() << " at depth " << spacings.at(0) << " will be set to default value 1,1,0.";
279  x = 1;
280  y = 1;
281  z = 1;
282  }
283  spacing[0] = x;
284  spacing[1] = y;
285  spacing[2] = z;
286 
287  try
288  {
289  depth = depthToInt(spacings.at(0));
290  }
291  catch (const mitk::Exception& e)
292  {
293  MITK_ERROR << probe->GetName() << ": " << e.GetDescription();
294  continue;
295  }
296  probe->SetDepthAndSpacing(depth, spacing);
297  }
298  }
299  return probe;
300 }
301 
302 void mitk::USDevicePersistence::split(std::string& text, std::string& separators, std::vector<std::string>& words)
303 {
304  int n = text.length();
305  int start, stop;
306 
307  start = text.find_first_not_of(separators);
308  while ((start >= 0) && (start < n))
309  {
310  stop = text.find_first_of(separators, start);
311  if ((stop < 0) || (stop > n)) stop = n;
312  words.push_back(text.substr(start, stop - start));
313  start = text.find_first_not_of(separators, stop + 1);
314  }
315 }
316 
318 {
319  std::istringstream i(s);
320  double x;
321  if (!(i >> x))
322  {
323  //something went wrong because the string contains characters which can not be convertet into double
324  mitkThrow() << "An error occured while trying to recover the spacing.";
325  }
326  return x;
327 }
328 
330 {
331  std::istringstream i(s);
332  int x;
333  if (!(i >> x))
334  {
335  //something went wrong because the string contains characters which can not be convertet into int
336  mitkThrow() << "An error occured while trying to recover the scanning depth. " << s << " is not a valid scanning depth. ";
337  }
338  return x;
339 }
mitk::USProbe::Pointer StringToUSProbe(std::string s)
QString USVideoDeviceToString(mitk::USVideoDevice::Pointer d)
A device holds information about it&#39;s model, make and the connected probes. It is the common super cl...
Definition: mitkUSDevice.h:73
std::vector< mitk::USDevice::Pointer > RestoreLastDevices()
#define MITK_INFO
Definition: mitkLogMacros.h:18
#define MITK_ERROR
Definition: mitkLogMacros.h:20
static Pointer New()
Method for creation through the object factory.
This class can be pointed to a video file or a videodevice and delivers USImages. ...
QString USProbeToString(mitk::USProbe::Pointer p)
void split(std::string &text, std::string &separators, std::vector< std::string > &words)
#define MITK_WARN
Definition: mitkLogMacros.h:19
An object of this class represents an exception of MITK. Please don&#39;t instantiate exceptions manually...
Definition: mitkException.h:45
#define mitkThrow()
mitk::USVideoDevice::Pointer StringToUSVideoDevice(QString s)
static Pointer New()
double spacingToDouble(std::string s)
A mitk::USVideoDevice is the common class for video only devices. They capture video input either fro...
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.