Fraxinus  2023.01.05-dev+develop.0da12
An IGT application
cxToolFileParser.cpp
Go to the documentation of this file.
1 #include "cxToolFileParser.h"
2 
3 #include <QFile>
4 #include <QDir>
5 #include "cxLogger.h"
6 #include "cxFrame3D.h"
7 #include "cxTransformFile.h"
8 #include "cxEnumConversion.h"
9 
10 namespace cx {
11 
13 {
14  //vtkMatrix4x4Ptr M = vtkMatrix4x4Ptr::New();
15  //mCalibration.ExportTransform(*(M.GetPointer()));
16  //Transform3D sMt = Transform3D::fromVtkMatrix(M);
17  //return sMt;
18  return mCalibration;
19 }
20 
22 {
23  mCalibration = cal;
24  //mCalibration.ImportTransform(*cal.getVtkMatrix());
25 }
26 
28 {
29  QString filename = mCalibrationFilename;
30  // QFile calibrationFile;
31  if (!filename.isEmpty() && QFile::exists(filename))
32  {
33  //Calibration file exists, overwrite
34  // calibrationFile.setFileName(mCalibrationFilename);
35  }
36  else
37  {
38  //Make a new file, use rom file name as base name
39  filename = mSROMFilename.remove(".rom", Qt::CaseInsensitive);
40  filename.append(".cal");
41  // calibrationFile.setFileName(calibrationFileName);
42  }
43 
44  TransformFile file(filename);
45  file.write(this->getCalibrationAsSSC());
46  //
51  // Transform3D sMt = this->getCalibrationAsSSC();
52  //
53  // if (!calibrationFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
54  // {
55  // reportError("Could not open " + mUid + "s calibrationfile: " + calibrationFile.fileName());
56  // return;
57  // }
58  //
59  // QTextStream streamer(&calibrationFile);
60  // streamer << qstring_cast(sMt);
61  // streamer << endl;
62  //
63  // calibrationFile.close();
64 
65  report("Replaced calibration in " + filename);
66 }
67 
69 {
70  bool retval = true;
71  QString verificationError("Internal verification of tool " + mUid + " failed! REASON: ");
72  if (!mIsPointer && !mIsReference && !mIsProbe)
73  {
74  // reportError(verificationError+" Tag <tool>::<type> is invalid ["+qstring_cast(mType)+"]. Valid types: [pointer, usprobe, reference]");
76  verificationError
77  + " Tag <tool>::<type> is invalid, must be one one of pointer/probe/reference ");
78  retval = false;
79  }
80  if (mUid.isEmpty())
81  {
82  reportError(verificationError + " Tag <tool>::<uid> is empty. Give tool a unique id.");
83  retval = false;
84  }
85  if (mTrackerType == tsNONE)
86  {
88  verificationError + " Tag <sensor>::<type> is invalid ["
90  + "]. Valid types: [polaris, spectra, vicra, aurora, micron (NOT SUPPORTED YET)]");
91  retval = false;
92  }
93  if ((mTrackerType == tsAURORA) && (mPortNumber >= 4))
94  {
96  verificationError + " Tag <sensor>::<portnumber> is invalid ["
98  + "]. Valid numbers: [0, 1, 2, 3]");
99  retval = false;
100  }
101  if ((mTrackerType == tsAURORA) && (mChannelNumber >= 1))
102  {
103  reportError(
104  verificationError + " Tag <sensor>::<channelnumber> is invalid ["
105  + qstring_cast(mChannelNumber) + "]. Valid numbers: [0, 1]");
106  retval = false;
107  }
108  QDir dir;
109  if (!mSROMFilename.isEmpty() && !dir.exists(mSROMFilename))
110  {
111  reportError(
112  verificationError + " Tag <sensor>::<rom_file> is invalid [" + mSROMFilename
113  + "]. Valid path: relative path to existing rom file.");
114  retval = false;
115  }
116  if (!mCalibrationFilename.isEmpty() && !dir.exists(mCalibrationFilename))
117  {
118  reportError(
119  verificationError + " Tag <calibration>::<cal_file> is invalid ["
121  + "]. Valid path: relative path to existing calibration file.");
122  retval = false;
123  }
124  if (!mTransformSaveFileName.isEmpty() && !dir.exists(mTransformSaveFileName))
125  {
126  reportError(verificationError + " Logging folder is invalid. Contact programmer! :)");
127  retval = false;
128  }
129  if (!mLoggingFolderName.isEmpty() && !dir.exists(mLoggingFolderName))
130  {
131  reportError(verificationError + " Logging folder is invalid. Contact programmer! :)");
132  retval = false;
133  }
134 
135  return retval;
136 }
137 
138 ToolFileParser::ToolFileParser(QString absoluteToolFilePath, QString loggingFolder) :
139  mToolFilePath(absoluteToolFilePath), mLoggingFolder(loggingFolder), mToolTag("tool"), mToolTypeTag("type"),
140  mToolIdTag("id"), mToolNameTag("name"), mToolDescriptionTag("description"), mToolManufacturerTag("manufacturer"),
141  mToolClinicalAppTag("clinical_app"), mToolGeoFileTag("geo_file"), mToolPicFileTag("pic_file"),
142  mToolDocFileTag("doc_file"), mToolInstrumentTag("instrument"), mToolInstrumentTypeTag("type"),
144  mToolInstrumentScannerIdTag("scannerid"), mToolInstrumentDescriptionTag("description"),
145  mToolSensorTag("sensor"), mToolSensorTypeTag("type"), mToolSensorIdTag("id"),
146  mToolSensorNameTag("name"), mToolSensorWirelessTag("wireless"), mToolSensorDOFTag("DOF"),
147  mToolSensorPortnumberTag("portnumber"), mToolSensorChannelnumberTag("channelnumber"),
148  mToolSensorReferencePointTag("reference_point"), mToolSensorManufacturerTag("manufacturer"),
149  mToolSensorDescriptionTag("description"), mToolSensorRomFileTag("rom_file"), mToolCalibrationTag("calibration"),
150  mToolCalibrationFileTag("cal_file"),
151  mToolOpenigtlinkImageIdTag("openigtlinkimageid"), mToolOpenigtlinkTransformIdTag("openigtlinktransformid")
152 {
153 }
154 
156 {
157 }
158 
160 {
162 
163  QFile toolFile(mToolFilePath);
164  QString toolFolderAbsolutePath = QFileInfo(toolFile).dir().absolutePath() + "/";
165  QDomNode toolNode = this->getToolNode(mToolFilePath);
167  // ToolFileParser::ToolInternalStructure internalStructure;
168  if (toolNode.isNull())
169  {
170  report(
171  "Could not read the <tool> tag of file: " + mToolFilePath
172  + ", this is not a tool file, skipping.");
173  return retval;
174  }
175 
176  QDomElement toolTypeElement = toolNode.firstChildElement(mToolTypeTag);
177  QString toolTypeText = toolTypeElement.text();
178 
179  internalStructure->mIsReference = toolTypeText.contains("reference", Qt::CaseInsensitive);
180  internalStructure->mIsPointer = toolTypeText.contains("pointer", Qt::CaseInsensitive);
181  internalStructure->mIsProbe = toolTypeText.contains("usprobe", Qt::CaseInsensitive);
182 
183  // if (toolTypeText.contains("reference", Qt::CaseInsensitive))
184  // {
185  // internalStructure.mType = Tool::TOOL_REFERENCE;
186  // } else if (toolTypeText.contains("pointer", Qt::CaseInsensitive))
187  // {
188  // internalStructure.mType = Tool::TOOL_POINTER;
189  // } else if (toolTypeText.contains("usprobe", Qt::CaseInsensitive))
190  // {
191  // internalStructure.mType = Tool::TOOL_US_PROBE;
192  // } else
193  // {
194  // internalStructure.mType = Tool::TOOL_NONE;
195  // }
196 
197  QDomElement toolIdElement = toolNode.firstChildElement(mToolIdTag);
198  QString toolIdText = toolIdElement.text();
199  internalStructure->mUid = toolIdText;
200 
201  QDomElement toolNameElement = toolNode.firstChildElement(mToolNameTag);
202  QString toolNameText = toolNameElement.text();
203  internalStructure->mName = toolNameText;
204 
205  QDomElement toolClinicalAppElement = toolNode.firstChildElement(mToolClinicalAppTag);
206  QString toolClinicalAppText = toolClinicalAppElement.text();
207  QStringList applicationList = toolClinicalAppText.split(" ");
208  foreach(QString string, applicationList)
209  {
210  if (string.isEmpty())
211  continue;
212  string = string.toLower();
213  internalStructure->mClinicalApplications.push_back(string);
214  }
215 
216  QDomElement toolGeofileElement = toolNode.firstChildElement(mToolGeoFileTag);
217  QString toolGeofileText = toolGeofileElement.text();
218  if (!toolGeofileText.isEmpty())
219  toolGeofileText = toolFolderAbsolutePath + toolGeofileText;
220  internalStructure->mGraphicsFileName = toolGeofileText;
221 
222  QDomElement toolPicfileElement = toolNode.firstChildElement(mToolPicFileTag);
223  QString toolPicfileText = toolPicfileElement.text();
224  if (!toolPicfileText.isEmpty())
225  toolPicfileText = toolFolderAbsolutePath + toolPicfileText;
226  internalStructure->mPictureFileName = toolPicfileText;
227 
228  QDomElement toolImageIdfileElement = toolNode.firstChildElement(mToolOpenigtlinkImageIdTag);
229  QString toolImageIdfileText = toolImageIdfileElement.text();
230  internalStructure->mOpenigtlinkImageId = toolImageIdfileText;
231 
232  QDomElement toolTransformIdfileElement = toolNode.firstChildElement(mToolOpenigtlinkTransformIdTag);
233  QString toolTransformIdfileText = toolTransformIdfileElement.text();
234  internalStructure->mOpenigtlinkTransformId = toolTransformIdfileText;
235 
236  QDomElement toolInstrumentElement = toolNode.firstChildElement(mToolInstrumentTag);
237  if (toolInstrumentElement.isNull())
238  {
239  reportError(
240  "Could not find the <instrument> tag under the <tool> tag. Aborting this tool.");
241  return retval;
242  }
243  QDomElement toolInstrumentIdElement = toolInstrumentElement.firstChildElement(mToolInstrumentIdTag);
244  QString toolInstrumentIdText = toolInstrumentIdElement.text();
245  internalStructure->mInstrumentId = toolInstrumentIdText;
246 
247  QDomElement toolInstrumentScannerIdElement = toolInstrumentElement.firstChildElement(mToolInstrumentScannerIdTag);
248  QString toolInstrumentScannerIdText = toolInstrumentScannerIdElement.text();
249  internalStructure->mInstrumentScannerId = toolInstrumentScannerIdText;
250 
251  QDomElement toolSensorElement = toolNode.firstChildElement(mToolSensorTag);
252  if (toolSensorElement.isNull())
253  {
254  reportError("Could not find the <sensor> tag under the <tool> tag. Aborting this tool.");
255  return retval;
256  }
257  QDomElement toolSensorTypeElement = toolSensorElement.firstChildElement(mToolSensorTypeTag);
258  QString toolSensorTypeText = toolSensorTypeElement.text();
259  internalStructure->mTrackerType = string2enum<TRACKING_SYSTEM>(toolSensorTypeText);
260 
261  QDomElement toolSensorWirelessElement = toolSensorElement.firstChildElement(mToolSensorWirelessTag);
262  QString toolSensorWirelessText = toolSensorWirelessElement.text();
263  if (toolSensorWirelessText.contains("yes", Qt::CaseInsensitive))
264  internalStructure->mWireless = true;
265  else if (toolSensorWirelessText.contains("no", Qt::CaseInsensitive))
266  internalStructure->mWireless = false;
267 
268  QDomElement toolSensorDOFElement = toolSensorElement.firstChildElement(mToolSensorDOFTag);
269  QString toolSensorDOFText = toolSensorDOFElement.text();
270  if (toolSensorDOFText.contains("5", Qt::CaseInsensitive))
271  internalStructure->m5DOF = true;
272  else if (toolSensorDOFText.contains("6", Qt::CaseInsensitive))
273  internalStructure->m5DOF = false;
274 
275  QDomElement toolSensorPortnumberElement = toolSensorElement.firstChildElement(mToolSensorPortnumberTag);
276  QString toolSensorPortnumberText = toolSensorPortnumberElement.text();
277  internalStructure->mPortNumber = toolSensorPortnumberText.toUInt();
278 
279  QDomElement toolSensorChannelnumberElement = toolSensorElement.firstChildElement(mToolSensorChannelnumberTag);
280  QString toolSensorChannelnumberText = toolSensorChannelnumberElement.text();
281  internalStructure->mChannelNumber = toolSensorChannelnumberText.toUInt();
282 
283  QDomNodeList toolSensorReferencePointList = toolSensorElement.elementsByTagName(mToolSensorReferencePointTag);
284  for (int j = 0; j < toolSensorReferencePointList.count(); j++)
285  {
286  QDomNode node = toolSensorReferencePointList.item(j);
287  if (!node.hasAttributes())
288  {
289  reportWarning("Found reference point without id attribute. Skipping.");
290  continue;
291  }
292  QString id = node.toElement().attribute("id");
293  QString toolSensorReferencePointText = node.toElement().text();
294  Vector3D vector = Vector3D::fromString(toolSensorReferencePointText);
295  internalStructure->mReferencePoints[id] = vector;
296  }
297 
298  QDomElement toolSensorRomFileElement = toolSensorElement.firstChildElement(mToolSensorRomFileTag);
299  QString toolSensorRomFileText = toolSensorRomFileElement.text();
300  if (!toolSensorRomFileText.isEmpty())
301  toolSensorRomFileText = toolFolderAbsolutePath + toolSensorRomFileText;
302  internalStructure->mSROMFilename = toolSensorRomFileText;
303 
304  QDomElement toolCalibrationElement = toolNode.firstChildElement(mToolCalibrationTag);
305  if (toolCalibrationElement.isNull())
306  {
307  reportError(
308  "Could not find the <calibration> tag under the <tool> tag. Aborting this tool.");
309  return retval;
310  }
311  QDomElement toolCalibrationFileElement = toolCalibrationElement.firstChildElement(mToolCalibrationFileTag);
312  QString toolCalibrationFileText = toolCalibrationFileElement.text();
313  if (!toolCalibrationFileText.isEmpty())
314  toolCalibrationFileText = toolFolderAbsolutePath + toolCalibrationFileText;
315  internalStructure->mCalibrationFilename = toolCalibrationFileText;
316  internalStructure->mCalibration = this->readCalibrationFile(internalStructure->mCalibrationFilename);
317 
318  internalStructure->mTransformSaveFileName = mLoggingFolder;
319  internalStructure->mLoggingFolderName = mLoggingFolder;
320  retval = internalStructure;
321 
322  return retval;
323 }
324 
325 QDomNode ToolFileParser::getToolNode(QString toolAbsoluteFilePath)
326 {
327  QDomNode retval;
328  QFile toolFile(toolAbsoluteFilePath);
329  if (!mToolDoc.setContent(&toolFile))
330  {
331  reportError("Could not set the xml content of the tool file " + toolAbsoluteFilePath);
332  return retval;
333  }
334  //there can only be one tool defined in every tool.xml-file, that's why we say ...item(0)
335  retval = mToolDoc.elementsByTagName(mToolTag).item(0);
336  return retval;
337 }
338 
340 {
341  bool ok = true;
342  TransformFile file(absoluteFilePath);
343  Transform3D retval = file.read(&ok);
344 
345  if (ok)
346  {
347  retval = Frame3D::create(retval).transform(); // clean rotational parts, transform should now be pure rotation+translation
348  }
349 
350  return retval;
351 }
352 
353 /*
354 QString ToolFileParser::getTemplatesAbsoluteFilePath()
355 {
356  QString retval = DataLocations::getRootConfigPath() + "/tool/TEMPLATE_tool.xml";
357  return retval;
358 }
359 */
360 
361 }
QString qstring_cast(const T &val)
ToolFileParser(QString absoluteToolFilePath, QString loggingFolder="")
boost::shared_ptr< ToolInternalStructure > ToolInternalStructurePtr
void reportError(QString msg)
Definition: cxLogger.cpp:71
const QString mToolSensorRomFileTag
File format for storing a 4x4 matrix.The read/write methods emit error messages if you dont use the o...
const QString mToolSensorManufacturerTag
tsNONE
Not specified.
QString mLoggingFolder
absolutepath to the logging folder
const QString mToolCalibrationTag
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
Transform3D transform() const
Definition: cxFrame3D.cpp:140
QString mTransformSaveFileName
path to where transforms should be saved
const QString mToolGeoFileTag
const QString mToolSensorReferencePointTag
const QString mToolSensorDescriptionTag
const QString mToolSensorTag
const QString mToolSensorTypeTag
QString mSROMFilename
path to the tools SROM file
const QString mToolOpenigtlinkTransformIdTag
names of necessary tags in the tool file
void write(const Transform3D &transform)
Transform3D read(bool *ok=0)
const QString mToolDocFileTag
unsigned int mPortNumber
the port number the tool is connected to
QDomDocument mToolDoc
the tool xml document
const QString mToolNameTag
const QString mToolSensorChannelnumberTag
const QString mToolInstrumentNameTag
const QString mToolInstrumentManufacturerTag
const QString mToolInstrumentDescriptionTag
unsigned int mChannelNumber
the channel the tool is connected to
virtual ToolInternalStructurePtr getTool()
void reportWarning(QString msg)
Definition: cxLogger.cpp:70
const QString mToolInstrumentIdTag
QString mToolFilePath
absolutepath to the tool file
static Frame3D create(const Transform3D &transform)
Definition: cxFrame3D.cpp:128
Transform3D readCalibrationFile(QString absoluteFilePath)
const QString mToolSensorIdTag
const QString mToolPicFileTag
TRACKING_SYSTEM mTrackerType
what product the tool belongs to
const QString mToolInstrumentTag
const QString mToolInstrumentScannerIdTag
const QString mToolCalibrationFileTag
QString mCalibrationFilename
path to the tools calibration file
const QString mToolDescriptionTag
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:42
const QString mToolIdTag
tsAURORA
NDIs Aurora tracker.
const QString mToolSensorPortnumberTag
void report(QString msg)
Definition: cxLogger.cpp:69
const QString mToolSensorWirelessTag
QString mLoggingFolderName
path to where log should be saved
const QString mToolManufacturerTag
const QString mToolSensorNameTag
const QString mToolSensorDOFTag
const QString mToolClinicalAppTag
Transform3D mCalibration
transform read from mCalibrationFilename
const QString mToolInstrumentTypeTag
const QString mToolTypeTag
const QString mToolOpenigtlinkImageIdTag
QDomNode getToolNode(QString toolAbsoluteFilePath)
const QString mToolTag
Namespace for all CustusX production code.
void setCalibration(const Transform3D &cal)