CustusX  15.8
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxCyclicActionLogger.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 
33 #include "cxCyclicActionLogger.h"
34 #include <numeric>
35 #include <sstream>
36 #include <QStringList>
37 #include "cxTypeConversions.h"
38 #include <cmath>
39 #include "cxLogger.h"
40 
41 namespace cx
42 {
43 
45 {
46  mRenderClock.start();
47  mIntervalClock.start();
48  this->reset();
49 }
50 
52 {
53  mName = name;
54  mRenderClock.start();
55  mIntervalClock.start();
56  this->reset();
57 }
58 
59 void CyclicActionLogger::reset(int interval)
60 {
61  mIntervalClock.restart();
62  mInterval = interval;
63  mTiming.clear();
64 }
65 
67 {
68  this->time("outside");
69 }
70 
71 void CyclicActionLogger::time(QString id)
72 {
73  std::vector<Entry>::iterator iter;
74  for (iter=mTiming.begin(); iter!=mTiming.end(); ++iter)
75  {
76  if (iter->id!=id)
77  continue;
78  iter->time.push_back(mRenderClock.restart());
79  return;
80  }
81 
82  Entry newEntry;
83  newEntry.id = id;
84  newEntry.time.push_back(mRenderClock.restart());
85  mTiming.push_back(newEntry);
86 }
87 
91 {
92  if (!mIntervalClock.elapsed())
93  return -1;
94  double numberOfRenderings = mTiming.empty() ? 0 : mTiming.front().time.size();
95  double fps = 1000.0 * numberOfRenderings / mIntervalClock.elapsed();
96  return floor(fps+0.5); // round
97 }
98 
100 {
101  return mIntervalClock.elapsed() > mInterval;
102 }
103 
105 {
106  return this->dumpStatisticsSmall();
107 // std::stringstream ss;
108 // ss << "=== " << mName << " statistics ===" << std::endl;
109 // ss << "Interval \t= " << mInterval << " ms" << std::endl;
110 // ss << "Elapsed \t= " << mIntervalClock.elapsed() << " ms" << std::endl;
111 // ss << "FPS \t= " << this->getFPS() << " frames/s" << std::endl;
112 //
113 //
114 // if (mRenderTime.empty() || mOffRenderTime.empty())
115 // return qstring_cast(ss.str());
116 //
117 // double maxRenderTime = *std::max_element(mRenderTime.begin(), mRenderTime.end());
118 // double maxOffRenderTime = *std::max_element(mOffRenderTime.begin(), mOffRenderTime.end());
119 //
120 // double meanRenderTime = std::accumulate(mRenderTime.begin(), mRenderTime.end(), 0)/mRenderTime.size();
121 // double meanOffRenderTime = std::accumulate(mOffRenderTime.begin(), mOffRenderTime.end(), 0)/mOffRenderTime.size();
122 // double meanTotalTime = meanRenderTime + meanOffRenderTime;
123 //
124 // ss << "Mean time:\t= " << meanTotalTime << " ms/frame" << std::endl;
125 // ss << std::endl;
126 // ss << "Mean times: \t"<< "render: " << meanRenderTime << "\tother: " << meanOffRenderTime << std::endl;
127 // ss << "Max times: \t" << "render: " << maxRenderTime << "\tother: " << maxOffRenderTime << std::endl;
128 // ss << std::endl;
129 //
130 // ss << "Render Times: " << mRenderTime.size() << std::endl;
131 // for (unsigned i = 0; i < mRenderTime.size(); ++i)
132 // ss << mRenderTime[i] << " ";
133 // ss << std::endl;
134 //
135 // ss << "Off Render Times: " << mOffRenderTime.size() << std::endl;
136 // for (unsigned i = 0; i < mOffRenderTime.size(); ++i)
137 // ss << mOffRenderTime[i] << " ";
138 // ss << std::endl;
139 //
140 // ss << "================================" << std::endl;
141 // ss << std::endl;
142 // return qstring_cast(ss.str());
143 }
144 
146 {
147  std::stringstream ss;
148  ss << mName << ":\t";
149  ss << "Elapsed=" << mIntervalClock.elapsed() << " ms";
150  ss << "\tFPS=" << this->getFPS() << " fps";
151 
152  if (mTiming.empty())
153  return qstring_cast(ss.str());
154 
155  QStringList meanTimes;
156  QStringList maxTimes;
157  QStringList ids;
158  double totalTime=0;
159 
160  std::vector<Entry>::iterator entry;
161  for (entry=mTiming.begin(); entry!=mTiming.end(); ++entry)
162  {
163  double maxTime = this->getMaxTime(entry->time);
164  double meanTime = this->getMeanTime(entry->time);
165  totalTime += meanTime;
166 
167  meanTimes << qstring_cast(int(meanTime));
168  maxTimes << qstring_cast(int(maxTime));
169  ids << entry->id;
170  }
171 
172  ss << QString("\t(total=%1)").arg(ids.join("+"));
173  ss << QString("\tMean:(%2=%3) ms/frame").arg(totalTime).arg(meanTimes.join("+"));
174  ss << QString("\tMax:(%1)").arg(maxTimes.join("+"));
175 
176  return qstring_cast(ss.str());
177 }
178 
179 double CyclicActionLogger::getMeanTime(std::vector<double> &time)
180 {
181  return std::accumulate(time.begin(), time.end(), 0)/time.size();
182 }
183 
184 double CyclicActionLogger::getMaxTime(std::vector<double> &time)
185 {
186  return *std::max_element(time.begin(), time.end());
187 }
188 
190 {
191  std::vector<Entry>::iterator entry = getTimingVectorIterator(id);
192  if(entry == mTiming.end())
193  {
194  reportWarning("CyclicActionLogger::getTime() unknown id: " + id);
195  return 0;
196  }
197  return getMeanTime(entry->time);
198 }
199 
200 std::vector<CyclicActionLogger::Entry>::iterator CyclicActionLogger::getTimingVectorIterator(QString id)
201 {
202  std::vector<Entry>::iterator entry;
203  for (entry=mTiming.begin(); entry!=mTiming.end(); ++entry)
204  {
205  if(entry->id == id)
206  break;
207  }
208  return entry;
209 }
210 
212 {
213  double totalTime = 0;
214  std::vector<Entry>::iterator entry;
215  for (entry=mTiming.begin(); entry!=mTiming.end(); ++entry)
216  {
217  if(entry->id != "outside")
218  {
219  double meanTime = this->getMeanTime(entry->time);
220  totalTime += meanTime;
221  }
222  }
223  return totalTime;
224 }
225 
226 } // namespace cx
QString qstring_cast(const T &val)
void reset(int interval=1000)
void begin()
start timing for this cycle
void reportWarning(QString msg)
Definition: cxLogger.cpp:91
int getTotalLoggedTime()
Total time contained in entered id's (id outside is not counted)
void time(QString id)
store time from begin or last time()