CustusX  20.03-rc1
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(
140  "type"), mToolIdTag("id"), mToolNameTag("name"), mToolDescriptionTag("description"), mToolManufacturerTag(
141  "manufacturer"), mToolClinicalAppTag("clinical_app"), mToolGeoFileTag("geo_file"), mToolPicFileTag(
142  "pic_file"), mToolDocFileTag("doc_file"), mToolInstrumentTag("instrument"), mToolInstrumentTypeTag(
144  "manufacturer"), mToolInstrumentScannerIdTag("scannerid"), mToolInstrumentDescriptionTag(
145  "description"), mToolSensorTag("sensor"), mToolSensorTypeTag("type"), mToolSensorIdTag(
146  "id"), mToolSensorNameTag("name"), mToolSensorWirelessTag("wireless"), mToolSensorDOFTag(
148  "channelnumber"), mToolSensorReferencePointTag("reference_point"), mToolSensorManufacturerTag(
149  "manufacturer"), mToolSensorDescriptionTag("description"), mToolSensorRomFileTag(
150  "rom_file"), mToolCalibrationTag("calibration"), mToolCalibrationFileTag("cal_file")
151 {
152 }
153 
155 {
156 }
157 
159 {
161 
162  QFile toolFile(mToolFilePath);
163  QString toolFolderAbsolutePath = QFileInfo(toolFile).dir().absolutePath() + "/";
164  QDomNode toolNode = this->getToolNode(mToolFilePath);
166 // ToolFileParser::ToolInternalStructure internalStructure;
167  if (toolNode.isNull())
168  {
169  report(
170  "Could not read the <tool> tag of file: " + mToolFilePath
171  + ", this is not a tool file, skipping.");
172  return retval;
173  }
174 
175  QDomElement toolTypeElement = toolNode.firstChildElement(mToolTypeTag);
176  QString toolTypeText = toolTypeElement.text();
177 
178  internalStructure->mIsReference = toolTypeText.contains("reference", Qt::CaseInsensitive);
179  internalStructure->mIsPointer = toolTypeText.contains("pointer", Qt::CaseInsensitive);
180  internalStructure->mIsProbe = toolTypeText.contains("usprobe", Qt::CaseInsensitive);
181 
182 // if (toolTypeText.contains("reference", Qt::CaseInsensitive))
183 // {
184 // internalStructure.mType = Tool::TOOL_REFERENCE;
185 // } else if (toolTypeText.contains("pointer", Qt::CaseInsensitive))
186 // {
187 // internalStructure.mType = Tool::TOOL_POINTER;
188 // } else if (toolTypeText.contains("usprobe", Qt::CaseInsensitive))
189 // {
190 // internalStructure.mType = Tool::TOOL_US_PROBE;
191 // } else
192 // {
193 // internalStructure.mType = Tool::TOOL_NONE;
194 // }
195 
196  QDomElement toolIdElement = toolNode.firstChildElement(mToolIdTag);
197  QString toolIdText = toolIdElement.text();
198  internalStructure->mUid = toolIdText;
199 
200  QDomElement toolNameElement = toolNode.firstChildElement(mToolNameTag);
201  QString toolNameText = toolNameElement.text();
202  internalStructure->mName = toolNameText;
203 
204  QDomElement toolClinicalAppElement = toolNode.firstChildElement(mToolClinicalAppTag);
205  QString toolClinicalAppText = toolClinicalAppElement.text();
206  QStringList applicationList = toolClinicalAppText.split(" ");
207  foreach(QString string, applicationList)
208  {
209  if (string.isEmpty())
210  continue;
211  string = string.toLower();
212  internalStructure->mClinicalApplications.push_back(string);
213  }
214 
215  QDomElement toolGeofileElement = toolNode.firstChildElement(mToolGeoFileTag);
216  QString toolGeofileText = toolGeofileElement.text();
217  if (!toolGeofileText.isEmpty())
218  toolGeofileText = toolFolderAbsolutePath + toolGeofileText;
219  internalStructure->mGraphicsFileName = toolGeofileText;
220 
221  QDomElement toolPicfileElement = toolNode.firstChildElement(mToolPicFileTag);
222  QString toolPicfileText = toolPicfileElement.text();
223  if (!toolPicfileText.isEmpty())
224  toolPicfileText = toolFolderAbsolutePath + toolPicfileText;
225  internalStructure->mPictureFileName = toolPicfileText;
226 
227  QDomElement toolInstrumentElement = toolNode.firstChildElement(mToolInstrumentTag);
228  if (toolInstrumentElement.isNull())
229  {
230  reportError(
231  "Could not find the <instrument> tag under the <tool> tag. Aborting this tool.");
232  return retval;
233  }
234  QDomElement toolInstrumentIdElement = toolInstrumentElement.firstChildElement(mToolInstrumentIdTag);
235  QString toolInstrumentIdText = toolInstrumentIdElement.text();
236  internalStructure->mInstrumentId = toolInstrumentIdText;
237 
238  QDomElement toolInstrumentScannerIdElement = toolInstrumentElement.firstChildElement(mToolInstrumentScannerIdTag);
239  QString toolInstrumentScannerIdText = toolInstrumentScannerIdElement.text();
240  internalStructure->mInstrumentScannerId = toolInstrumentScannerIdText;
241 
242  QDomElement toolSensorElement = toolNode.firstChildElement(mToolSensorTag);
243  if (toolSensorElement.isNull())
244  {
245  reportError("Could not find the <sensor> tag under the <tool> tag. Aborting this tool.");
246  return retval;
247  }
248  QDomElement toolSensorTypeElement = toolSensorElement.firstChildElement(mToolSensorTypeTag);
249  QString toolSensorTypeText = toolSensorTypeElement.text();
250  internalStructure->mTrackerType = string2enum<TRACKING_SYSTEM>(toolSensorTypeText);
251 
252  QDomElement toolSensorWirelessElement = toolSensorElement.firstChildElement(mToolSensorWirelessTag);
253  QString toolSensorWirelessText = toolSensorWirelessElement.text();
254  if (toolSensorWirelessText.contains("yes", Qt::CaseInsensitive))
255  internalStructure->mWireless = true;
256  else if (toolSensorWirelessText.contains("no", Qt::CaseInsensitive))
257  internalStructure->mWireless = false;
258 
259  QDomElement toolSensorDOFElement = toolSensorElement.firstChildElement(mToolSensorDOFTag);
260  QString toolSensorDOFText = toolSensorDOFElement.text();
261  if (toolSensorDOFText.contains("5", Qt::CaseInsensitive))
262  internalStructure->m5DOF = true;
263  else if (toolSensorDOFText.contains("6", Qt::CaseInsensitive))
264  internalStructure->m5DOF = false;
265 
266  QDomElement toolSensorPortnumberElement = toolSensorElement.firstChildElement(mToolSensorPortnumberTag);
267  QString toolSensorPortnumberText = toolSensorPortnumberElement.text();
268  internalStructure->mPortNumber = toolSensorPortnumberText.toUInt();
269 
270  QDomElement toolSensorChannelnumberElement = toolSensorElement.firstChildElement(mToolSensorChannelnumberTag);
271  QString toolSensorChannelnumberText = toolSensorChannelnumberElement.text();
272  internalStructure->mChannelNumber = toolSensorChannelnumberText.toUInt();
273 
274  QDomNodeList toolSensorReferencePointList = toolSensorElement.elementsByTagName(mToolSensorReferencePointTag);
275  for (int j = 0; j < toolSensorReferencePointList.count(); j++)
276  {
277  QDomNode node = toolSensorReferencePointList.item(j);
278  if (!node.hasAttributes())
279  {
280  reportWarning("Found reference point without id attribute. Skipping.");
281  continue;
282  }
283  bool ok;
284  int id = node.toElement().attribute("id").toInt(&ok);
285  if (!ok)
286  {
287  reportWarning("Attribute id of a reference point was not an int. Skipping.");
288  continue;
289  }
290  QString toolSensorReferencePointText = node.toElement().text();
291  Vector3D vector = Vector3D::fromString(toolSensorReferencePointText);
292  internalStructure->mReferencePoints[id] = vector;
293  }
294 
295  QDomElement toolSensorRomFileElement = toolSensorElement.firstChildElement(mToolSensorRomFileTag);
296  QString toolSensorRomFileText = toolSensorRomFileElement.text();
297  if (!toolSensorRomFileText.isEmpty())
298  toolSensorRomFileText = toolFolderAbsolutePath + toolSensorRomFileText;
299  internalStructure->mSROMFilename = toolSensorRomFileText;
300 
301  QDomElement toolCalibrationElement = toolNode.firstChildElement(mToolCalibrationTag);
302  if (toolCalibrationElement.isNull())
303  {
304  reportError(
305  "Could not find the <calibration> tag under the <tool> tag. Aborting this tool.");
306  return retval;
307  }
308  QDomElement toolCalibrationFileElement = toolCalibrationElement.firstChildElement(mToolCalibrationFileTag);
309  QString toolCalibrationFileText = toolCalibrationFileElement.text();
310  if (!toolCalibrationFileText.isEmpty())
311  toolCalibrationFileText = toolFolderAbsolutePath + toolCalibrationFileText;
312  internalStructure->mCalibrationFilename = toolCalibrationFileText;
313  internalStructure->mCalibration = this->readCalibrationFile(internalStructure->mCalibrationFilename);
314 
315  internalStructure->mTransformSaveFileName = mLoggingFolder;
316  internalStructure->mLoggingFolderName = mLoggingFolder;
317  retval = internalStructure;
318 
319  return retval;
320 }
321 
322 QDomNode ToolFileParser::getToolNode(QString toolAbsoluteFilePath)
323 {
324  QDomNode retval;
325  QFile toolFile(toolAbsoluteFilePath);
326  if (!mToolDoc.setContent(&toolFile))
327  {
328  reportError("Could not set the xml content of the tool file " + toolAbsoluteFilePath);
329  return retval;
330  }
331  //there can only be one tool defined in every tool.xml-file, that's why we say ...item(0)
332  retval = mToolDoc.elementsByTagName(mToolTag).item(0);
333  return retval;
334 }
335 
337 {
338  bool ok = true;
339  TransformFile file(absoluteFilePath);
340  Transform3D retval = file.read(&ok);
341 
342  if (ok)
343  {
344  retval = Frame3D::create(retval).transform(); // clean rotational parts, transform should now be pure rotation+translation
345  }
346 
347  return retval;
348 }
349 
350 /*
351 QString ToolFileParser::getTemplatesAbsoluteFilePath()
352 {
353  QString retval = DataLocations::getRootConfigPath() + "/tool/TEMPLATE_tool.xml";
354  return retval;
355 }
356 */
357 
358 }
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
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
names of necessary tags in the tool file
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
QDomNode getToolNode(QString toolAbsoluteFilePath)
const QString mToolTag
Namespace for all CustusX production code.
void setCalibration(const Transform3D &cal)