PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusSetUsParameterCommand.cxx
Go to the documentation of this file.
1 /*=Plus=header=begin======================================================
2 Program: Plus
3 Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved.
4 See License.txt for details.
5 =========================================================Plus=header=end*/
6 
7 #include "PlusConfigure.h"
9 
10 #include "vtkPlusDataCollector.h"
11 #include "vtkObjectFactory.h"
12 #include "vtkPlusChannel.h"
15 #include "vtkPlusUsDevice.h"
16 
17 #include <vtkVariant.h>
18 #include <vtkSmartPointer.h>
19 
20 #include <limits>
21 #include <iterator>
22 #include <string>
23 
24 namespace
25 {
26  static const std::string SET_US_PARAMETER_CMD = "SetUsParameter";
27 }
28 
30 
31 //----------------------------------------------------------------------------
33 {
34  this->UsDeviceId = "";
35  this->RequestedParameterChanges.clear();
36 }
37 
38 //----------------------------------------------------------------------------
40 {
41  this->RequestedParameterChanges.clear();
42 }
43 
44 //----------------------------------------------------------------------------
46 {
47  SetName(SET_US_PARAMETER_CMD);
48 }
49 
50 //----------------------------------------------------------------------------
51 void vtkPlusSetUsParameterCommand::PrintSelf(ostream& os, vtkIndent indent)
52 {
53  this->Superclass::PrintSelf(os, indent);
54 }
55 
56 //----------------------------------------------------------------------------
57 void vtkPlusSetUsParameterCommand::GetCommandNames(std::list<std::string>& cmdNames)
58 {
59  cmdNames.clear();
60  cmdNames.push_back(SET_US_PARAMETER_CMD);
61 }
62 
63 //----------------------------------------------------------------------------
64 std::string vtkPlusSetUsParameterCommand::GetDescription(const std::string& commandName)
65 {
66  std::string desc;
67  if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, SET_US_PARAMETER_CMD))
68  {
69  desc += SET_US_PARAMETER_CMD;
70  //TODO:
71  desc += ": Set depth image parameter. Attributes: UsDeviceId: ID of the ultrasound device.";
72  }
73 
74  return desc;
75 }
76 
77 //----------------------------------------------------------------------------
79 {
80  this->RequestedParameterChanges.clear();
82  {
83  return PLUS_FAIL;
84  }
85 
86  this->SetUsDeviceId(aConfig->GetAttribute("UsDeviceId"));
87 
88  // Parse nested elements and store requested parameter changes
89  for (int elemIndex = 0; elemIndex < aConfig->GetNumberOfNestedElements(); ++elemIndex)
90  {
91  vtkXMLDataElement* currentElem = aConfig->GetNestedElement(elemIndex);
92  if (igsioCommon::IsEqualInsensitive(currentElem->GetName(), "Parameter"))
93  {
94  const char* parameterName = currentElem->GetAttribute("Name");
95  const char* parameterValue = currentElem->GetAttribute("Value");
96  if (!parameterName || !parameterValue)
97  {
98  LOG_ERROR("Unable to find required Name or Value attribute in " << (currentElem->GetName() ? currentElem->GetName() : "(undefined)") << " element in SetUsParameter command");
99  continue;
100  }
101 
102  this->RequestedParameterChanges[parameterName] = parameterValue;
103  }
104  }
105 
106  return PLUS_SUCCESS;
107 }
108 
109 //----------------------------------------------------------------------------
111 {
113  {
114  return PLUS_FAIL;
115  }
116 
117  XML_WRITE_STRING_ATTRIBUTE_IF_NOT_EMPTY(UsDeviceId, aConfig);
118 
119  // Write parameters as nested elements
120  std::map<std::string, std::string>::iterator paramIt;
121  for (paramIt = this->RequestedParameterChanges.begin(); paramIt != this->RequestedParameterChanges.end(); ++paramIt)
122  {
123  vtkSmartPointer<vtkXMLDataElement> paramElem = vtkSmartPointer<vtkXMLDataElement>::New();
124  paramElem->SetName("Parameter");
125  paramElem->SetAttribute("Name", paramIt->first.c_str());
126  paramElem->SetAttribute("Value", paramIt->second.c_str());
127  aConfig->AddNestedElement(paramElem);
128  }
129 
130  return PLUS_SUCCESS;
131 }
132 
133 //----------------------------------------------------------------------------
135 {
136  LOG_DEBUG("vtkPlusSetUsParameterCommand::Execute: " << (!this->Name.empty() ? this->Name : "(undefined)")
137  << ", device: " << (this->UsDeviceId.empty() ? "(undefined)" : this->UsDeviceId));
138 
139  if (this->Name.empty())
140  {
141  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", "No command name specified.");
142  return PLUS_FAIL;
143  }
144  else if (!igsioCommon::IsEqualInsensitive(this->Name, SET_US_PARAMETER_CMD))
145  {
146  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", "Unknown command name: " + this->Name + ".");
147  return PLUS_FAIL;
148  }
149 
150  vtkPlusUsDevice* usDevice = GetUsDevice();
151  if (usDevice == NULL)
152  {
153  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", std::string("Device ")
154  + (this->UsDeviceId.empty() ? "(undefined)" : this->UsDeviceId) + std::string(" is not found."));
155  return PLUS_FAIL;
156  }
157 
158  std::string usDeviceId = (usDevice->GetDeviceId().empty() ? "(unknown)" : usDevice->GetDeviceId());
159  vtkPlusUsImagingParameters* imagingParameters = usDevice->GetImagingParameters();
160  std::string resultString = "<CommandReply>";
161  std::string error = "";
162  std::map < std::string, std::pair<IANA_ENCODING_TYPE, std::string> > metaData;
163  PlusStatus status = PLUS_SUCCESS;
164 
165  std::map<std::string, std::string>::iterator paramIt;
166  for (paramIt = this->RequestedParameterChanges.begin(); paramIt != this->RequestedParameterChanges.end(); ++paramIt)
167  {
168  std::string parameterName = paramIt->first;
169  std::string value = paramIt->second;
170  resultString += "<Parameter Name=\"" + parameterName + "\"";
171 
172  if (parameterName == vtkPlusUsImagingParameters::KEY_TGC)
173  {
174  std::stringstream ss;
175  ss.str(value);
176  std::vector<double> numbers((std::istream_iterator<double>(ss)), std::istream_iterator<double>());
177  if (numbers.size() != 3)
178  {
179  error += "Failed to parse " + parameterName + ".";
180  resultString += " Success=\"false\"/>";
181  metaData[parameterName] = std::make_pair(IANA_TYPE_US_ASCII, "FAIL");
182  status = PLUS_FAIL;
183  continue;
184  }
185  imagingParameters->SetTimeGainCompensation(numbers);
186  }
187  else if (parameterName == vtkPlusUsImagingParameters::KEY_IMAGESIZE)
188  {
189  std::stringstream ss;
190  ss.str(value);
191  std::vector<int> numbers((std::istream_iterator<int>(ss)), std::istream_iterator<int>());
192  if (numbers.size() != 3)
193  {
194  error += "Failed to parse " + parameterName + ". ";
195  resultString += " Success=\"false\"/>";
196  metaData[parameterName] = std::make_pair(IANA_TYPE_US_ASCII, "FAIL");
197  status = PLUS_FAIL;
198  continue;
199  }
200  imagingParameters->SetImageSize(numbers[0], numbers[1], numbers[2]);
201  }
202  else if (parameterName == vtkPlusUsImagingParameters::KEY_FREQUENCY
203  || parameterName == vtkPlusUsImagingParameters::KEY_DEPTH
205  || parameterName == vtkPlusUsImagingParameters::KEY_SECTOR
206  || parameterName == vtkPlusUsImagingParameters::KEY_GAIN
208  || parameterName == vtkPlusUsImagingParameters::KEY_CONTRAST
209  || parameterName == vtkPlusUsImagingParameters::KEY_POWER
210  || parameterName == vtkPlusUsImagingParameters::KEY_DYNRANGE
211  || parameterName == vtkPlusUsImagingParameters::KEY_ZOOM
213  || parameterName == vtkPlusUsImagingParameters::KEY_VOLTAGE)
214  {
215  // double type parameter
216  bool valid = false;
217  double parameterValue = vtkVariant(value).ToDouble(&valid);
218  if (!valid)
219  {
220  error += "Failed to parse " + parameterName + ". ";
221  resultString += " Success=\"false\"/>";
222  metaData[parameterName] = std::make_pair(IANA_TYPE_US_ASCII, "FAIL");
223  status = PLUS_FAIL;
224  continue;
225  }
226  imagingParameters->SetValue<double>(parameterName, parameterValue);
227  }
228  else
229  {
230  error += "Invalid parameter " + parameterName + ". ";
231  resultString += " Success=\"false\"/>";
232  metaData[parameterName] = std::make_pair(IANA_TYPE_US_ASCII, "FAIL");
233  status = PLUS_FAIL;
234  continue;
235  }
236 
237  if (usDevice->SetNewImagingParameters(*imagingParameters) == PLUS_FAIL)
238  {
239  error += "Failed to set " + parameterName + ". ";
240  resultString += " Success=\"false\"/>";
241  metaData[parameterName] = std::make_pair(IANA_TYPE_US_ASCII, "FAIL");
242  status = PLUS_FAIL;
243  continue;
244  }
245 
246  resultString += " Success=\"true\"/>";
247  metaData[parameterName] = std::make_pair(IANA_TYPE_US_ASCII, "SUCCESS");
248  } // For each parameter
249  resultString += "</CommandReply>";
250 
251  if (status != PLUS_SUCCESS)
252  {
253  LOG_WARNING("Failed to set US parameter, result string was: " << resultString);
254  }
255 
256  vtkSmartPointer<vtkPlusCommandRTSCommandResponse> commandResponse = vtkSmartPointer<vtkPlusCommandRTSCommandResponse>::New();
257  commandResponse->UseDefaultFormatOff();
258  commandResponse->SetClientId(this->ClientId);
259  commandResponse->SetOriginalId(this->Id);
260  commandResponse->SetDeviceName(this->DeviceName);
261  commandResponse->SetCommandName(this->GetName());
262  commandResponse->SetStatus(status);
263  commandResponse->SetRespondWithCommandMessage(this->RespondWithCommandMessage);
264  commandResponse->SetErrorString(error);
265  commandResponse->SetResultString(resultString);
266  commandResponse->SetParameters(metaData);
267  this->CommandResponseQueue.push_back(commandResponse);
268 
269  return status;
270 }
271 
272 //----------------------------------------------------------------------------
274 {
275  vtkPlusDataCollector* dataCollector = GetDataCollector();
276  if (dataCollector == NULL)
277  {
278  LOG_ERROR("Data collector is invalid");
279  return NULL;
280  }
281  vtkPlusUsDevice* usDevice = NULL;
282  if (!this->UsDeviceId.empty())
283  {
284  // Ultrasound device ID is specified
285  vtkPlusDevice* device = NULL;
286  if (dataCollector->GetDevice(device, this->UsDeviceId) != PLUS_SUCCESS)
287  {
288  LOG_ERROR("No ultrasound device has been found by the name " << this->UsDeviceId);
289  return NULL;
290  }
291  // device found
292  usDevice = dynamic_cast<vtkPlusUsDevice*>(device);
293  if (usDevice == NULL)
294  {
295  // wrong type
296  LOG_ERROR("The specified device " << this->UsDeviceId << " is not UsDevice");
297  return NULL;
298  }
299  }
300  else
301  {
302  // No ultrasound device id is specified, auto-detect the first one and use that
303  for (DeviceCollectionConstIterator it = dataCollector->GetDeviceConstIteratorBegin(); it != dataCollector->GetDeviceConstIteratorEnd(); ++it)
304  {
305  usDevice = dynamic_cast<vtkPlusUsDevice*>(*it);
306  if (usDevice != NULL)
307  {
308  // found an ultrasound device
309  break;
310  }
311  }
312  if (usDevice == NULL)
313  {
314  LOG_ERROR("No UsDevice has been found");
315  return NULL;
316  }
317  }
318  return usDevice;
319 }
virtual vtkPlusUsImagingParameters * GetImagingParameters()
virtual void PrintSelf(ostream &os, vtkIndent indent)
Abstract interface for tracker and video devices.
Definition: vtkPlusDevice.h:60
std::vector< vtkPlusDevice * >::const_iterator DeviceCollectionConstIterator
Definition: vtkPlusDevice.h:48
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *aConfig)
virtual void PrintSelf(ostream &os, vtkIndent indent)
This class is used to store a configuration of the imaging parameters of an ultrasound video device....
PlusStatus GetDevice(vtkPlusDevice *&aDevice, const std::string &aDeviceId) const
std::string Name
igsioStatus PlusStatus
Definition: PlusCommon.h:40
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *aConfig)
virtual std::string GetDeviceId() const
virtual void GetCommandNames(std::list< std::string > &cmdNames)
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *aConfig)
virtual PlusStatus SetNewImagingParameters(const vtkPlusUsImagingParameters &newImagingParameters)
#define PLUS_FAIL
Definition: PlusCommon.h:43
PlusStatus SetTimeGainCompensation(const std::vector< double > &tgc)
DeviceCollectionConstIterator GetDeviceConstIteratorBegin() const
DeviceCollectionConstIterator GetDeviceConstIteratorEnd() const
Manages devices that record image or positional data.
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
bool RespondWithCommandMessage
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *aConfig)
virtual std::string GetDescription(const std::string &commandName)
PlusStatus SetImageSize(const FrameSizeType &imageSize)
void QueueCommandResponse(PlusStatus status, const std::string &message, const std::string &error="", const igtl::MessageBase::MetaDataMap *metaData=nullptr)
virtual vtkPlusDataCollector * GetDataCollector()
std::string DeviceName
const char const char * value
Definition: phidget22.h:5111
PlusStatus SetValue(const std::string &paramName, T aValue)
PlusCommandResponseList CommandResponseQueue
vtkStandardNewMacro(vtkPlusSetUsParameterCommand)
Abstract interface for ultrasound video devices.
std::map< std::string, std::string > RequestedParameterChanges
This command requests ultrasound parameter change in the client.