MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
mitkNavigationDataReaderXML.cpp
Go to the documentation of this file.
1/*============================================================================
2
3The Medical Imaging Interaction Toolkit (MITK)
4
5Copyright (c) German Cancer Research Center (DKFZ)
6All rights reserved.
7
8Use of this source code is governed by a 3-clause BSD license that can be
9found in the LICENSE file.
10
11============================================================================*/
12
13// MITK
15#include <mitkIGTMimeTypes.h>
16#include <mitkLocaleSwitch.h>
17
18// Third Party
19#include <itksys/SystemTools.hxx>
20#include <fstream>
21#include <tinyxml2.h>
22
23namespace
24{
25 mitk::NavigationData::Pointer ReadNavigationData(const tinyxml2::XMLElement* ndElem)
26 {
27 if (nullptr == ndElem)
28 return nullptr;
29
31
32 ndElem->QueryDoubleAttribute("Time", &timeStamp);
33
34 if (-1 == timeStamp)
35 return nullptr;
36
38 position.Fill(0.0);
39
40 ndElem->QueryDoubleAttribute("X", &position[0]);
41 ndElem->QueryDoubleAttribute("Y", &position[1]);
42 ndElem->QueryDoubleAttribute("Z", &position[2]);
43
45
46 ndElem->QueryDoubleAttribute("QX", &orientation[0]);
47 ndElem->QueryDoubleAttribute("QY", &orientation[1]);
48 ndElem->QueryDoubleAttribute("QZ", &orientation[2]);
49 ndElem->QueryDoubleAttribute("QR", &orientation[3]);
50
52 matrix.SetIdentity();
53
54 ndElem->QueryDoubleAttribute("C00", &matrix[0][0]);
55 ndElem->QueryDoubleAttribute("C01", &matrix[0][1]);
56 ndElem->QueryDoubleAttribute("C02", &matrix[0][2]);
57 ndElem->QueryDoubleAttribute("C03", &matrix[0][3]);
58 ndElem->QueryDoubleAttribute("C04", &matrix[0][4]);
59 ndElem->QueryDoubleAttribute("C05", &matrix[0][5]);
60 ndElem->QueryDoubleAttribute("C10", &matrix[1][0]);
61 ndElem->QueryDoubleAttribute("C11", &matrix[1][1]);
62 ndElem->QueryDoubleAttribute("C12", &matrix[1][2]);
63 ndElem->QueryDoubleAttribute("C13", &matrix[1][3]);
64 ndElem->QueryDoubleAttribute("C14", &matrix[1][4]);
65 ndElem->QueryDoubleAttribute("C15", &matrix[1][5]);
66
67 int attrib = 0;
68 ndElem->QueryIntAttribute("Valid", &attrib);
69 bool isValid = 0 != attrib;
70
71 attrib = 0;
72 ndElem->QueryIntAttribute("hP", &attrib);
73 bool hasPosition = 0 != attrib;
74
75 attrib = 0;
76 ndElem->QueryIntAttribute("hO", &attrib);
77 bool hasOrientation = 0 != attrib;
78
79 auto navData = mitk::NavigationData::New();
80
81 navData->SetIGTTimeStamp(timeStamp);
82 navData->SetPosition(position);
83 navData->SetOrientation(orientation);
84 navData->SetCovErrorMatrix(matrix);
85 navData->SetDataValid(isValid);
86 navData->SetHasPosition(hasPosition);
87 navData->SetHasOrientation(hasOrientation);
88
89 return navData;
90 }
91}
92
94 : AbstractFileReader(IGTMimeTypes::NAVIGATIONDATASETXML_MIMETYPE(), "MITK NavigationData Reader (XML)")
95{
96 this->RegisterService();
97}
98
102
104 : AbstractFileReader(other)
105{
106}
107
112
113std::vector<itk::SmartPointer<mitk::BaseData>> mitk::NavigationDataReaderXML::DoRead()
114{
115 mitk::NavigationDataSet::Pointer dataset = nullptr == this->GetInputStream()
116 ? this->Read(this->GetInputLocation())
117 : this->Read(*this->GetInputStream());
118
119 std::vector<mitk::BaseData::Pointer> result;
120 result.emplace_back(dataset.GetPointer());
121
122 return result;
123}
124
125mitk::NavigationDataSet::Pointer mitk::NavigationDataReaderXML::Read(const std::string& fileName)
126{
127 std::ifstream stream(fileName);
128 stream.imbue(std::locale::classic());
129
130 return this->Read(stream);
131}
132
133mitk::NavigationDataSet::Pointer mitk::NavigationDataReaderXML::Read(std::istream& stream)
134{
135 std::string string(std::istreambuf_iterator<char>(stream), {});
136 tinyxml2::XMLDocument doc;
137
138 if (tinyxml2::XML_SUCCESS != doc.Parse(string.c_str()))
139 mitkThrowException(IGTIOException) << "Could not parse stream.";
140
141 const auto* rootElem = doc.RootElement();
142 decltype(rootElem) dataElem = nullptr;
143
144 if (nullptr == rootElem)
145 return nullptr;
146
147 int version = 0;
148 auto err = tinyxml2::XML_SUCCESS;
149
150 std::string rootElemVal = rootElem->Value();
151
152 if ("Version" == rootElemVal)
153 {
154 err = rootElem->QueryIntAttribute("Ver", &version);
155 dataElem = rootElem->NextSiblingElement("Data");
156 }
157 else if ("Data" == rootElemVal)
158 {
159 err = rootElem->QueryIntAttribute("version", &version);
160 dataElem = rootElem;
161 }
162
163 if (err != tinyxml2::XML_SUCCESS)
164 mitkThrowException(IGTIOException) << "Could not parse file format version.";
165
166 if (version != 1)
167 mitkThrowException(IGTIOException) << "File format version " << version << " is not supported.";
168
169 if (nullptr == dataElem)
170 mitkThrowException(IGTIOException) << "Data element not found.";
171
172 int toolCount = 0;
173
174 if (tinyxml2::XML_SUCCESS != dataElem->QueryIntAttribute("ToolCount", &toolCount))
175 mitkThrowException(IGTIOException) << "ToolCount attribute missing from Data element.";
176
177 if (0 >= toolCount)
178 mitkThrowException(IGTIOException) << "Invalid ToolCount: " << toolCount << ".";
179
180 auto navDataSet = NavigationDataSet::New(static_cast<unsigned int>(toolCount));
181 NavigationData::Pointer navData;
182
183 const auto* ndElem = dataElem->FirstChildElement();
184
185 if (nullptr != ndElem)
186 {
187 do
188 {
189 std::vector<NavigationData::Pointer> navDatas(toolCount);
190
191 for (decltype(toolCount) i = 0; i < toolCount; ++i)
192 {
193 navData = ReadNavigationData(ndElem);
194
195 if (navData.IsNull())
196 {
197 if (0 != i)
198 MITK_WARN("mitkNavigationDataReaderXML") << "Different number of NavigationData objects for different tools. Ignoring last ones.";
199
200 break;
201 }
202
203 navDatas[i] = navData;
204 ndElem = ndElem->NextSiblingElement();
205 }
206
207 if (navData.IsNotNull())
208 navDataSet->AddNavigationDatas(navDatas);
209
210 } while (nullptr != ndElem && navData.IsNotNull());
211 }
212
213 return navDataSet;
214}
mitk::NavigationDataReaderXML * Clone() const override
std::vector< itk::SmartPointer< BaseData > > DoRead() override
itk::Matrix< mitk::ScalarType, 6, 6 > CovarianceMatrixType
type that holds the error characterization of the position and orientation measurements
mitk::Quaternion OrientationType
Type that holds the orientation part of the tracking data.
double TimeStampType
type that holds the time at which the data was recorded in milliseconds
mitk::Point3D PositionType
Type that holds the position part of the tracking data.