Fraxinus  2023.01.05-dev+develop.0da12
An IGT application
cxProbeImpl.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
12 #include "cxProbeImpl.h"
13 
14 #include <QStringList>
15 #include "cxVideoSource.h"
16 #include "cxLogger.h"
17 #include "cxProbeSector.h"
18 #include "cxProbeAdapterRTSource.h"
19 #include "cxTypeConversions.h"
20 #include "cxVector3D.h"
21 
22 #include "cxDataLocations.h"
24 
25 namespace cx
26 {
27 
28 ProbeImplPtr ProbeImpl::New(QString instrumentUid, QString scannerUid, ProbeXmlConfigParserPtr xml)
29 {
30  ProbeImpl* object = new ProbeImpl(instrumentUid, scannerUid);
31  ProbeImplPtr retval(object);
32  object->mSelf = retval;
33  retval->initProbeXmlConfigParser(xml);
34  retval->initConfigId();
35  return retval;
36 }
37 
38 bool ProbeImpl::isValid() const
39 {
40  return this->getProbeDefinition("active").getType() != ProbeDefinition::tNONE;
41 }
42 
44 {
45  QStringList retval;
46  for (std::map<QString, VideoSourcePtr>::iterator iter=mSource.begin(); iter!=mSource.end(); ++iter)
47  retval << iter->first;
48  return retval;
49 }
50 
52 {
53  if (mSource.empty())
54  return VideoSourcePtr();
55  if (uid=="active")
56  uid = mActiveUid;
57  if (mSource.count(uid))
58  return mSource.find(uid)->second;
59  return mSource.begin()->second;
60 }
61 
63 {
64  ProbeDefinition retval;
65 
66  if (uid=="active")
67  uid = mActiveUid;
68  if (mProbeDefinition.count(uid))
69  retval = mProbeDefinition.find(uid)->second;
70  else if (mProbeDefinition.count("default"))
71  retval = mProbeDefinition.find("default")->second;
72  else
73  retval = mProbeDefinition.begin()->second;
74 
75  // ensure uid is matching the requested uid even if not found.
76  retval.setUid(uid);
77  return retval;
78 }
79 
81 {
82  ProbeSectorPtr retval(new ProbeSector());
83  retval->setData(this->getProbeDefinition(uid));
84  return retval;
85 }
86 
87 void ProbeImpl::addXml(QDomNode& dataNode)
88 {
89  QDomDocument doc = dataNode.ownerDocument();
90  dataNode.toElement().setAttribute("config", mConfigurationId);
91 }
92 
93 void ProbeImpl::parseXml(QDomNode& dataNode)
94 {
95  if (dataNode.isNull())
96  return;
97  QString cfg = dataNode.toElement().attribute("config");
98  if (cfg.isEmpty())
99  return;
100  this->applyNewConfigurationWithId(cfg);
101 }
102 
103 QStringList ProbeImpl::getConfigIdList() const
104 {
105  if (!this->hasRtSource())
106  return QStringList();
107 
108  // Combine config lists from all RT sources
109  QStringList configIdList;
110  QStringList rtSourceList = mXml->getRtSourceList(this->getInstrumentScannerId(), this->getInstrumentId());
111  for (int i = 0; i < rtSourceList.size(); ++i)
112  configIdList << mXml->getConfigIdList(this->getInstrumentScannerId(), this->getInstrumentId(), rtSourceList[i]);
113 
114  return configIdList;
115 }
116 
117 QString ProbeImpl::getConfigName(QString configString)
118 {
119  ProbeXmlConfigParser::Configuration config = this->getConfiguration(configString);
120  return config.mName;
121 }
122 
123 QString ProbeImpl::getConfigId() const
124 {
125  if (this->getProbeDefinition().getUseDigitalVideo())
126  return "Digital";
127  return mConfigurationId;
128 }
129 
131 {
132  if (!this->hasRtSource())
133  return "";
134  QStringList retval;
135  retval << this->getInstrumentScannerId() << this->getInstrumentId() << this->getRtSourceName() << this->getConfigId();
136  return retval.join(":");
137 }
138 
140 {
141  this->setConfigId(uid);
142  this->applyConfig();
143  emit activeConfigChanged();
144 }
145 
146 void ProbeImpl::applyConfig()
147 {
148  this->updateProbeSector();
149  this->updateTemporalCalibration();
150  this->setSoundSpeedCompensationFactor(mSoundSpeedCompensationFactor);
151  emit sectorChanged();
152 }
153 
155 {
156  mOverrideTemporalCalibration = true;
157  mTemporalCalibration = val;
158  for (std::map<QString, ProbeDefinition>::iterator iter=mProbeDefinition.begin(); iter!=mProbeDefinition.end(); ++iter)
159  iter->second.setTemporalCalibration(mTemporalCalibration);
160 }
161 
163 {
164  if(similar(mSoundSpeedCompensationFactor, factor))
165  return;
166  mSoundSpeedCompensationFactor = factor;
167  for (std::map<QString, ProbeDefinition>::iterator iter=mProbeDefinition.begin(); iter!=mProbeDefinition.end(); ++iter)
168  iter->second.applySoundSpeedCompensationFactor(mSoundSpeedCompensationFactor);
169  emit sectorChanged();
170 }
171 
173 {
174  if (probeDefinition.getUid().isEmpty())
175  probeDefinition.setUid(mActiveUid);
176 
177  mProbeDefinition[probeDefinition.getUid()] = probeDefinition;
178  emit sectorChanged();
179 }
180 
182 {
183  CX_ASSERT(source); // not handled after refactoring - add clear method??
184  if (!source)
185  return;
186 
187  // uid already exist: check if base object is the same
188  if (mSource.count(source->getUid()))
189  {
190  VideoSourcePtr old = mSource.find(source->getUid())->second;
191 
192  ProbeAdapterRTSourcePtr oldAdapter;
193  oldAdapter = boost::dynamic_pointer_cast<ProbeAdapterRTSource>(old);
194  // check for identity, ignore if no change
195  if (oldAdapter && (source==oldAdapter->getBaseSource()))
196  return;
197  }
198 
199  // must have same uid as original: the uid identifies the video source
200  mSource[source->getUid()].reset(new ProbeAdapterRTSource(source->getUid(), mSelf.lock(), source));
201  emit sectorChanged();
202 
203  emit videoSourceAdded(mSource[source->getUid()]);
204 }
205 
207 {
208  if (!source)
209  return;
210  if (!mSource.count(source->getUid()))
211  return;
212 
213  mSource.erase(source->getUid());
214  mProbeDefinition.erase(source->getUid());
215  this->applyConfig();//May need to re-create config, as the old ProbeDefinition may be deleted
216 }
217 
218 void ProbeImpl::setActiveStream(QString uid)
219 {
220  if (uid.isEmpty())
221  return;
222  mActiveUid = uid;
223  emit sectorChanged();
224 }
225 
227 {
228  return mActiveUid;
229 }
230 
232 {
234 
235  int index = this->getConfigIdList().indexOf(config.mConfigId);
236  if (index<0)
237  return;
238  if (index!=0)
239  --index;
240 
241  mXml->removeConfig(config.mUsScanner, config.mUsProbe, config.mRtSource, config.mConfigId);
242  if (index < this->getConfigIdList().size())
243  this->applyNewConfigurationWithId(this->getConfigIdList()[index]);
244  emit sectorChanged();
245 }
246 
247 void ProbeImpl::saveCurrentConfig(QString uid, QString name)
248 {
250  config.mConfigId = uid;
251  config.mName = name;
252  config = createConfigurationFromProbeDefinition(config, this->getProbeDefinition("active"));
253 
254  mXml->saveCurrentConfig(config);
255  this->applyNewConfigurationWithId(uid);
256 }
257 
258 QString ProbeImpl::getRtSourceName(QString configurationId) const
259 {
260  QString configId = configurationId;
261  if (configId.isEmpty())
262  configId = mConfigurationId;
263 
264  return this->findRtSource(configId);
265 }
266 
267 QString ProbeImpl::findRtSource(QString configId) const
268 {
269  QStringList rtSourceList = mXml->getRtSourceList(this->getInstrumentScannerId(), this->getInstrumentId());
270 
271  //Use first RT source if no config id
272  if(configId.isEmpty() && !rtSourceList.empty())
273  return rtSourceList.at(0);
274 
275  QString retval;
276 
277  for (int i = 0; i < rtSourceList.size(); ++i)
278  {
279  QStringList configIdList;
280  configIdList << mXml->getConfigIdList(this->getInstrumentScannerId(), this->getInstrumentId(), rtSourceList[i]);
281  if(configIdList.contains(configId))
282  {
283  if(!retval.isEmpty())
284  reportWarning(QString("Config id is not unique: %1. Scanner %2, probe: %3. Occurring in RT source: %4 and %5").
285  arg(configId).arg(this->getInstrumentScannerId()).arg(this->getInstrumentId()).arg(rtSourceList[i]).arg(retval));
286  retval = rtSourceList[i];
287  }
288  }
289  return retval;
290 }
291 
292 ProbeImpl::ProbeImpl(QString instrumentUid, QString scannerUid) :
293  mInstrumentUid(instrumentUid),
294  mScannerUid(scannerUid),
295  mSoundSpeedCompensationFactor(1.0),
296  mOverrideTemporalCalibration(false),
297  mTemporalCalibration(0.0)
298 {
299  ProbeDefinition probeDefinition;
300  mProbeDefinition[probeDefinition.getUid()] = probeDefinition;
301  mActiveUid = probeDefinition.getUid();
302 }
303 
304 void ProbeImpl::initProbeXmlConfigParser(ProbeXmlConfigParserPtr xml = ProbeXmlConfigParserPtr())
305 {
306  if (!xml)
307  {
308  QString xmlFileName = cx::DataLocations::getRootConfigPath() + QString("/tool/ProbeCalibConfigs.xml");
309  mXml.reset(new ProbeXmlConfigParserImpl(xmlFileName));
310  } else
311  mXml = xml;
312 }
313 
314 void ProbeImpl::initConfigId()
315 {
316  QStringList configs = this->getConfigIdList();
317  if (!configs.isEmpty())
318  this->applyNewConfigurationWithId(configs[0]);
319  else
320  {
321  reportWarning(QString("Found no probe configuration for:\n"
322  "scanner=[%1] instrument=[%2].\n"
323  "Check that your %3 file contains entries\n"
324  "<USScanner> <Name>%1</Name> ... <USProbe> <Name>%2</Name>").arg(mScannerUid).arg(mInstrumentUid).arg(mXml->getFileName()));
325  }
326 }
327 
329 {
330  if (mConfig.mConfigId != this->getConfigId())
331  {
332  mConfig = this->getConfiguration(this->getConfigId());
333  }
334  return mConfig;
335 }
336 
338 {
339  if (mConfig.mConfigId != uid)
340  {
342  if(this->hasRtSource())
343  config = mXml->getConfiguration(mScannerUid, mInstrumentUid, this->getRtSourceName(uid), uid);
344  return config;
345  }
346  return mConfig;
347 }
348 
349 QString ProbeImpl::getInstrumentId() const
350 {
351  return mInstrumentUid;
352 }
353 
354 QString ProbeImpl::getInstrumentScannerId() const
355 {
356  return mScannerUid;
357 }
358 
359 bool ProbeImpl::hasRtSource() const
360 {
361  return !(this->getRtSourceName().isEmpty());
362 }
363 
364 void ProbeImpl::setConfigId(QString uid)
365 {
366  mConfigurationId = uid;
367 }
368 
369 void ProbeImpl::updateProbeSector()
370 {
371  if(this->isValidConfigId() && !this->getProbeDefinition().getUseDigitalVideo())
372  {
373  ProbeDefinition probeSector = this->createProbeSector();
374  this->setProbeDefinition(probeSector);
375  }
376 }
377 
378 bool ProbeImpl::isValidConfigId()
379 {
380  //May need to create ProbeXmlConfigParser::isValidConfig(...) also
381  return !this->getConfiguration().isEmpty();
382 }
383 
384 ProbeDefinition ProbeImpl::createProbeSector()
385 {
388  probeSector.setUid(mActiveUid);
389  return probeSector;
390 }
391 
392 void ProbeImpl::updateTemporalCalibration()
393 {
394  if (mOverrideTemporalCalibration)
395  this->setTemporalCalibration(mTemporalCalibration);
396 }
397 
398 
399 } //namespace cx
< a easy-to-work-with struct for a specific xml configuration
ProbeXmlConfigParser::Configuration getConfiguration()
virtual void saveCurrentConfig(QString uid, QString name)
save current config to disk under ids (uid,name).
virtual ProbeDefinition getProbeDefinition(QString uid="active") const
Return a ProbeDefinition for the given uid. Use &#39;active&#39; to get the default.
Definition: cxProbeImpl.cpp:62
#define CX_ASSERT(statement)
Definition: cxLogger.h:116
virtual void removeCurrentConfig()
remove the current config from disk
virtual void setActiveStream(QString uid)
virtual VideoSourcePtr getRTSource(QString uid="active") const
Return a VideoSource for the given uid. Use &#39;active&#39; to get the default stream.
Definition: cxProbeImpl.cpp:51
VideoSource that applies the parameters from a Probe to the VideoSource.
QString getRtSourceName(QString configurationId="") const
virtual QString getConfigName(QString uid)
QString getUid() const
virtual void setTemporalCalibration(double val)
virtual QString getActiveStream() const
virtual void parseXml(QDomNode &dataNode)
Definition: cxProbeImpl.cpp:93
virtual QString getConfigurationPath() const
virtual ProbeSectorPtr getSector(QString uid="active")
Definition: cxProbeImpl.cpp:80
virtual void removeRTSource(VideoSourcePtr source)
void videoSourceAdded(VideoSourcePtr source)
virtual void applyNewConfigurationWithId(QString uid)
void reportWarning(QString msg)
Definition: cxLogger.cpp:70
void setUid(QString uid)
Implementation of abstract interface ProbeXmlConfigParser Interface to ProbeCalibConfigs.xml.
boost::shared_ptr< class VideoSource > VideoSourcePtr
boost::shared_ptr< ProbeXmlConfigParser > ProbeXmlConfigParserPtr
void sectorChanged()
< Return a ProbeSectorPtr for the given uid. Use &#39;active&#39; to get the default.
virtual QString getConfigId() const
boost::shared_ptr< class ProbeSector > ProbeSectorPtr
Definition of characteristics for an Ultrasound Probe Sector.
void activeConfigChanged()
static QString getRootConfigPath()
return path to root config folder. May be replaced with getExistingConfigPath()
virtual void setSoundSpeedCompensationFactor(double val)
boost::shared_ptr< class ProbeImpl > ProbeImplPtr
virtual QStringList getAvailableVideoSources()
Return a list of all available video source. The default is one with uid==&#39;active&#39;.
Definition: cxProbeImpl.cpp:43
static ProbeImplPtr New(QString instrumentUid, QString scannerUid, ProbeXmlConfigParserPtr xml=ProbeXmlConfigParserPtr())
Definition: cxProbeImpl.cpp:28
QString mName
Name of config set.
virtual QStringList getConfigIdList() const
bool similar(const CameraInfo &lhs, const CameraInfo &rhs, double tol)
virtual bool isValid() const
Definition: cxProbeImpl.cpp:38
virtual void addXml(QDomNode &dataNode)
Definition: cxProbeImpl.cpp:87
Utility functions for drawing an US Probe sector.
Definition: cxProbeSector.h:38
virtual void setProbeDefinition(ProbeDefinition probeDefinition)
boost::shared_ptr< ProbeAdapterRTSource > ProbeAdapterRTSourcePtr
ProbeDefinition createProbeDefinitionFromConfiguration(ProbeXmlConfigParser::Configuration config)
ProbeXmlConfigParser::Configuration createConfigurationFromProbeDefinition(ProbeXmlConfigParser::Configuration basis, ProbeDefinition data)
virtual void setRTSource(VideoSourcePtr source)
Namespace for all CustusX production code.