Fraxinus  2023.01.05-dev+develop.0da12
An IGT application
cxRecordSession.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 #include "cxRecordSession.h"
12 
13 #include <QDomDocument>
14 #include <QDomElement>
15 #include "cxTypeConversions.h"
16 #include "cxLogger.h"
17 #include "cxTime.h"
18 #include "cxTool.h"
19 #include <QDateTime>
20 #include "cxTime.h"
21 #include "cxXMLNodeWrapper.h"
22 
23 namespace cx
24 {
25 
27 {
28 
29 }
30 
31 RecordSession::RecordSession(int id, QString category) :
32  mId(id),
33  mCategory(category)
34 {
35  mTimestamp = QDateTime::currentDateTime();
36 }
37 
38 
40 {}
41 
43 {
44  QDateTime time = QDateTime::currentDateTime();
45  mIntervals.push_back(IntervalType(time, time));
46 }
47 
49 {
50  if (mIntervals.empty())
51  return;
52  QDateTime time = QDateTime::currentDateTime();
53  mIntervals.back().second = time;
54 }
55 
57 {
58  if (mIntervals.empty())
59  return;
60  mIntervals.pop_back();
61 }
62 
63 QDateTime RecordSession::getTimestamp() const
64 {
65  return mTimestamp;
66 }
67 
69 {
70  QString format("hh:mm");
71  QString ts = this->getTimestamp().toString(format);
72 
73  return QString("%1 %2 %3")
74  .arg(mCategory)
75  .arg(mId)
76  .arg(ts);
77 }
78 
79 QString RecordSession::getUid() const
80 {
81  QString timestamp = this->getTimestamp().toString(timestampSecondsFormat());
82 
83  return QString("%1_%2")
84  .arg(mId, 2, 10, QChar('0'))
85  .arg(timestamp);
86 }
87 
89 {
90  QString timestamp = this->getTimestamp().toString(timestampSecondsFormat());
91  return QString("%1_%2_%3")
92  .arg(mCategory)
93  .arg(mId)
94  .arg(timestamp);
95 }
96 
97 void RecordSession::addXml(QDomNode& node)
98 {
99  XMLNodeAdder adder(node);
100  adder.node().toElement().setAttribute("uid", this->getUid());
101  adder.addTextToElement("category", mCategory);
102 
103  for (unsigned i=0; i<mIntervals.size(); ++i)
104  {
105  QDomElement interval = adder.addElement("interval");
106  interval.setAttribute("start", this->datetime2timestamp(mIntervals[i].first));
107  interval.setAttribute("stop", this->datetime2timestamp(mIntervals[i].second));
108  }
109 }
110 
111 void RecordSession::parseXml(QDomNode& node)
112 {
113  if (node.isNull())
114  {
115  reportWarning("RecordSession::parseXml() node is null");
116  return;
117  }
118 
119  if (this->isOldStyleXmlFormat(node))
120  {
121  this->parseXml_oldstyle(node);
122  return;
123  }
124 
125  XMLNodeParser parser(node);
126 
127  QDomElement base = node.toElement();
128 
129  this->setIdAndTimestampFromUid(base.attribute("uid"));
130  mCategory = parser.parseTextFromElement("category");
131 
132  std::vector<QDomElement> intervals = parser.getDuplicateElements("interval");
133  for (unsigned i=0; i<intervals.size(); ++i)
134  {
135  QDomElement source = intervals[i].toElement();
136  IntervalType interval;
137  bool ok;
138  interval.first = this->timestamp2datetime(source.attribute("start"));
139  interval.second = this->timestamp2datetime(source.attribute("stop"));
140  mIntervals.push_back(interval);
141  }
142 }
143 
144 QDateTime RecordSession::timestamp2datetime(QString in) const
145 {
146  return QDateTime::fromString(in, timestampMilliSecondsFormat());
147 }
148 
149 QString RecordSession::datetime2timestamp(QDateTime in) const
150 {
151  return in.toString(timestampMilliSecondsFormat());
152 }
153 
155 {
156  return node.firstChildElement("description").isElement();
157 }
158 
159 void RecordSession::parseXml_oldstyle(QDomNode& parentNode)
160 {
161  if (parentNode.isNull())
162  {
163  reportWarning("RecordSession::parseXml() parentnode is null");
164  return;
165  }
166 
167  QDomElement base = parentNode.toElement();
168 
169  QString uid = base.attribute("uid");
170 
171  bool ok;
172  double starttime = parentNode.namedItem("start").toElement().text().toDouble(&ok);
173  double stoptime = parentNode.namedItem("stop").toElement().text().toDouble(&ok);
174  QString description = parentNode.namedItem("description").toElement().text();
175 
176  mCategory = description.split("_"+uid).first();
177  this->setIdAndTimestampFromUid(uid);
178  mIntervals.push_back(std::make_pair(QDateTime::fromMSecsSinceEpoch(starttime),
179  QDateTime::fromMSecsSinceEpoch(stoptime)));
180 }
181 
183 {
184  mId = uid.split("_").first().toInt();
185  mTimestamp = QDateTime::fromString(uid.split("_").last(), timestampSecondsFormat());
186 }
187 
189 {
190  TimedTransformMap retval;
191 
192  if(tool && session)
193  {
194  for (unsigned i=0; i<session->mIntervals.size(); ++i)
195  {
196  TimedTransformMap values;
197  values = tool->getSessionHistory(session->mIntervals[i].first.toMSecsSinceEpoch(),
198  session->mIntervals[i].second.toMSecsSinceEpoch());
199  retval.insert(values.begin(), values.end());
200  }
201  }
202 
203  if(retval.empty() && session && verbose)
204  {
205  CX_LOG_ERROR() << QString("Could not find any tracking data for tool [%1] in session [%2]. ")
206  .arg(tool.get() ? tool->getName() : "NULL")
207  .arg(session.get() ? session->getHumanDescription() : "NULL");
208  }
209 
210  return retval;
211 }
212 
213 std::map<double, cx::ToolPositionMetadata> RecordSession::getToolHistory_metadata(ToolPtr tool, RecordSessionPtr session, bool verbose)
214 {
215  std::map<double, cx::ToolPositionMetadata> retval;
216 
217  if(tool && session)
218  {
219  for (unsigned i=0; i<session->mIntervals.size(); ++i)
220  {
221  double startTime = session->mIntervals[i].first.toMSecsSinceEpoch();
222  double stopTime = session->mIntervals[i].second.toMSecsSinceEpoch();
223  const std::map<double, cx::ToolPositionMetadata>& values = tool->getMetadataHistory();
224 
225  retval.insert(values.lower_bound(startTime),
226  values.upper_bound(stopTime));
227  }
228  }
229 
230  if(retval.empty() && session && verbose)
231  {
232  CX_LOG_ERROR() << QString("Could not find any tracking meta data for tool [%1] in session [%2]. ")
233  .arg(tool.get() ? tool->getName() : "NULL")
234  .arg(session.get() ? session->getHumanDescription() : "NULL");
235  }
236 
237  return retval;
238 }
239 
240 std::pair<QDateTime, QDateTime> RecordSession::getInterval(int i)
241 {
242  return mIntervals[i];
243 }
244 
246 {
247  return mIntervals.size();
248 }
249 
250 
251 }//namespace cx
static std::map< double, ToolPositionMetadata > getToolHistory_metadata(ToolPtr tool, RecordSessionPtr session, bool verbose)
QString getUid() const
std::pair< QDateTime, QDateTime > IntervalType
QDomElement addElement(QString name)
unsigned getIntervalCount() const
QString timestampMilliSecondsFormat()
Definition: cxTime.cpp:22
std::vector< QDomElement > getDuplicateElements(QString name)
QDateTime timestamp2datetime(QString in) const
void addXml(QDomNode &node)
void setIdAndTimestampFromUid(QString uid)
std::vector< IntervalType > mIntervals
QString timestampSecondsFormat()
Definition: cxTime.cpp:18
static TimedTransformMap getToolHistory_prMt(ToolPtr tool, RecordSessionPtr session, bool verbose)
boost::shared_ptr< class RecordSession > RecordSessionPtr
void reportWarning(QString msg)
Definition: cxLogger.cpp:70
#define CX_LOG_ERROR
Definition: cxLogger.h:99
std::pair< QDateTime, QDateTime > getInterval(int i)
QDomElement addTextToElement(QString name, QString text)
QString getHumanDescription() const
description useful for display in gui.
bool isOldStyleXmlFormat(QDomNode &node)
QString getDescription() const
another legacy uid, used for folder creation etc
QString parseTextFromElement(QString name)
QDateTime getTimestamp() const
void parseXml_oldstyle(QDomNode &parentNode)
QString datetime2timestamp(QDateTime in) const
void parseXml(QDomNode &node)
std::map< double, Transform3D > TimedTransformMap
Namespace for all CustusX production code.
boost::shared_ptr< class Tool > ToolPtr