Fraxinus  16.5.0-fx-rc6
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 #include "cxRecordSession.h"
33 
34 #include <QDomDocument>
35 #include <QDomElement>
36 #include "cxTypeConversions.h"
37 #include "cxLogger.h"
38 #include "cxTime.h"
39 #include "cxTool.h"
40 #include <QDateTime>
41 #include "cxTime.h"
42 #include "cxXMLNodeWrapper.h"
43 
44 namespace cx
45 {
46 
48 {
49 
50 }
51 
52 RecordSession::RecordSession(int id, QString category) :
53  mId(id),
54  mCategory(category)
55 {
56  mTimestamp = QDateTime::currentDateTime();
57 }
58 
59 
61 {}
62 
64 {
65  QDateTime time = QDateTime::currentDateTime();
66  mIntervals.push_back(IntervalType(time, time));
67 }
68 
70 {
71  if (mIntervals.empty())
72  return;
73  QDateTime time = QDateTime::currentDateTime();
74  mIntervals.back().second = time;
75 }
76 
78 {
79  if (mIntervals.empty())
80  return;
81  mIntervals.pop_back();
82 }
83 
84 QDateTime RecordSession::getTimestamp() const
85 {
86  return mTimestamp;
87 }
88 
90 {
91  QString format("hh:mm");
92  QString ts = this->getTimestamp().toString(format);
93 
94  return QString("%1 %2 %3")
95  .arg(mCategory)
96  .arg(mId)
97  .arg(ts);
98 }
99 
100 QString RecordSession::getUid() const
101 {
102  QString timestamp = this->getTimestamp().toString(timestampSecondsFormat());
103 
104  return QString("%1_%2")
105  .arg(mId, 2, 10, QChar('0'))
106  .arg(timestamp);
107 }
108 
110 {
111  QString timestamp = this->getTimestamp().toString(timestampSecondsFormat());
112  return QString("%1_%2_%3")
113  .arg(mCategory)
114  .arg(mId)
115  .arg(timestamp);
116 }
117 
118 void RecordSession::addXml(QDomNode& node)
119 {
120  XMLNodeAdder adder(node);
121  adder.node().toElement().setAttribute("uid", this->getUid());
122  adder.addTextToElement("category", mCategory);
123 
124  for (unsigned i=0; i<mIntervals.size(); ++i)
125  {
126  QDomElement interval = adder.addElement("interval");
127  interval.setAttribute("start", this->datetime2timestamp(mIntervals[i].first));
128  interval.setAttribute("stop", this->datetime2timestamp(mIntervals[i].second));
129  }
130 }
131 
132 void RecordSession::parseXml(QDomNode& node)
133 {
134  if (node.isNull())
135  {
136  reportWarning("RecordSession::parseXml() node is null");
137  return;
138  }
139 
140  if (this->isOldStyleXmlFormat(node))
141  {
142  this->parseXml_oldstyle(node);
143  return;
144  }
145 
146  XMLNodeParser parser(node);
147 
148  QDomElement base = node.toElement();
149 
150  this->setIdAndTimestampFromUid(base.attribute("uid"));
151  mCategory = parser.parseTextFromElement("category");
152 
153  std::vector<QDomElement> intervals = parser.getDuplicateElements("interval");
154  for (unsigned i=0; i<intervals.size(); ++i)
155  {
156  QDomElement source = intervals[i].toElement();
157  IntervalType interval;
158  bool ok;
159  interval.first = this->timestamp2datetime(source.attribute("start"));
160  interval.second = this->timestamp2datetime(source.attribute("stop"));
161  mIntervals.push_back(interval);
162  }
163 }
164 
165 QDateTime RecordSession::timestamp2datetime(QString in) const
166 {
167  return QDateTime::fromString(in, timestampMilliSecondsFormat());
168 }
169 
170 QString RecordSession::datetime2timestamp(QDateTime in) const
171 {
172  return in.toString(timestampMilliSecondsFormat());
173 }
174 
176 {
177  return node.firstChildElement("description").isElement();
178 }
179 
180 void RecordSession::parseXml_oldstyle(QDomNode& parentNode)
181 {
182  if (parentNode.isNull())
183  {
184  reportWarning("RecordSession::parseXml() parentnode is null");
185  return;
186  }
187 
188  QDomElement base = parentNode.toElement();
189 
190  QString uid = base.attribute("uid");
191 
192  bool ok;
193  double starttime = parentNode.namedItem("start").toElement().text().toDouble(&ok);
194  double stoptime = parentNode.namedItem("stop").toElement().text().toDouble(&ok);
195  QString description = parentNode.namedItem("description").toElement().text();
196 
197  mCategory = description.split("_"+uid).first();
198  this->setIdAndTimestampFromUid(uid);
199  mIntervals.push_back(std::make_pair(QDateTime::fromMSecsSinceEpoch(starttime),
200  QDateTime::fromMSecsSinceEpoch(stoptime)));
201 }
202 
204 {
205  mId = uid.split("_").first().toInt();
206  mTimestamp = QDateTime::fromString(uid.split("_").last(), timestampSecondsFormat());
207 }
208 
210 {
211  TimedTransformMap retval;
212 
213  if(tool && session)
214  {
215  for (unsigned i=0; i<session->mIntervals.size(); ++i)
216  {
217  TimedTransformMap values;
218  values = tool->getSessionHistory(session->mIntervals[i].first.toMSecsSinceEpoch(),
219  session->mIntervals[i].second.toMSecsSinceEpoch());
220  retval.insert(values.begin(), values.end());
221  }
222  }
223 
224  if(retval.empty() && session && verbose)
225  {
226  CX_LOG_ERROR() << QString("Could not find any tracking data for tool [%1] in session [%2]. ")
227  .arg(tool.get() ? tool->getName() : "NULL")
228  .arg(session.get() ? session->getHumanDescription() : "NULL");
229  }
230 
231  return retval;
232 }
233 
234 std::map<double, cx::ToolPositionMetadata> RecordSession::getToolHistory_metadata(ToolPtr tool, RecordSessionPtr session, bool verbose)
235 {
236  std::map<double, cx::ToolPositionMetadata> retval;
237 
238  if(tool && session)
239  {
240  for (unsigned i=0; i<session->mIntervals.size(); ++i)
241  {
242  double startTime = session->mIntervals[i].first.toMSecsSinceEpoch();
243  double stopTime = session->mIntervals[i].second.toMSecsSinceEpoch();
244  const std::map<double, cx::ToolPositionMetadata>& values = tool->getMetadataHistory();
245 
246  retval.insert(values.lower_bound(startTime),
247  values.upper_bound(stopTime));
248  }
249  }
250 
251  if(retval.empty() && session && verbose)
252  {
253  CX_LOG_ERROR() << QString("Could not find any tracking meta data for tool [%1] in session [%2]. ")
254  .arg(tool.get() ? tool->getName() : "NULL")
255  .arg(session.get() ? session->getHumanDescription() : "NULL");
256  }
257 
258  return retval;
259 }
260 
261 std::pair<QDateTime, QDateTime> RecordSession::getInterval(int i)
262 {
263  return mIntervals[i];
264 }
265 
267 {
268  return mIntervals.size();
269 }
270 
271 
272 }//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:43
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:39
static TimedTransformMap getToolHistory_prMt(ToolPtr tool, RecordSessionPtr session, bool verbose)
boost::shared_ptr< class RecordSession > RecordSessionPtr
void reportWarning(QString msg)
Definition: cxLogger.cpp:91
#define CX_LOG_ERROR
Definition: cxLogger.h:114
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
boost::shared_ptr< class Tool > ToolPtr