1.1 --- a/examples/stats/README Wed Nov 11 11:57:14 2009 +0100
1.2 +++ b/examples/stats/README Wed Nov 11 12:44:09 2009 +0100
1.3 @@ -14,3 +14,23 @@
1.4 available online on the ns-3 wiki at:
1.5
1.6 http://www.nsnam.org/wiki/index.php/Statistical_Framework_for_Network_Simulation
1.7 +
1.8 +*** Using ns-3 with the OMNeT++ analysis tool ***
1.9 +
1.10 +The stat framework can write out the result in a format that is compatible with the
1.11 +output format of OMNeT++ 4 Discrete Event Simulator Framework.
1.12 +Use the wifi-example-omnet.sh script to generate the results in OMNeT++ format.
1.13 +
1.14 +If you want to analyse the results with OMNeT++'s result analyser tool:
1.15 +a) Download OMNeT++ 4 and install it. Start the IDE. (www.omnetpp.org)
1.16 +b) If you do not want to install the whole simulator framework, there is a seperate
1.17 + package which contains only the analysis tool from the OMNeT++ package.
1.18 + You can download it from http://omnetpp.org/download/release/omnetpp-scave.tgz
1.19 +
1.20 +Once you are running the OMNeT++ IDE or the separate analysis tool (SCAVE)
1.21 +- Choose File|Import...|Existing Projects into Workspace, then click [Next]
1.22 +- Select root directory. (choose the examples/stats directory) and click [Finish]
1.23 +
1.24 +Double click the wifi-example-omnet.anf in the opened project and select
1.25 +the Chart page to see the created chart. Experiment with the analysis tool and read its
1.26 +documentation: http://omnetpp.org/doc/omnetpp40/userguide/ch09.html
2.1 --- a/examples/stats/wifi-example-sim.cc Wed Nov 11 11:57:14 2009 +0100
2.2 +++ b/examples/stats/wifi-example-sim.cc Wed Nov 11 12:44:09 2009 +0100
2.3 @@ -200,6 +200,7 @@
2.4 Ptr<CounterCalculator<uint32_t> > totalTx =
2.5 CreateObject<CounterCalculator<uint32_t> >();
2.6 totalTx->SetKey("wifi-tx-frames");
2.7 + totalTx->SetContext("node[0]");
2.8 Config::Connect("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
2.9 MakeBoundCallback(&TxCallback, totalTx));
2.10 data.AddDataCalculator(totalTx);
2.11 @@ -211,6 +212,7 @@
2.12 Ptr<PacketCounterCalculator> totalRx =
2.13 CreateObject<PacketCounterCalculator>();
2.14 totalRx->SetKey("wifi-rx-frames");
2.15 + totalRx->SetContext("node[1]");
2.16 Config::Connect("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
2.17 MakeCallback(&PacketCounterCalculator::PacketUpdate,
2.18 totalRx));
2.19 @@ -225,6 +227,7 @@
2.20 Ptr<PacketCounterCalculator> appTx =
2.21 CreateObject<PacketCounterCalculator>();
2.22 appTx->SetKey("sender-tx-packets");
2.23 + appTx->SetContext("node[0]");
2.24 Config::Connect("/NodeList/0/ApplicationList/*/$Sender/Tx",
2.25 MakeCallback(&PacketCounterCalculator::PacketUpdate,
2.26 appTx));
2.27 @@ -237,6 +240,7 @@
2.28 Ptr<CounterCalculator<> > appRx =
2.29 CreateObject<CounterCalculator<> >();
2.30 appRx->SetKey("receiver-rx-packets");
2.31 + appRx->SetContext("node[1]");
2.32 receiver->SetCounter(appRx);
2.33 data.AddDataCalculator(appRx);
2.34
2.35 @@ -263,6 +267,7 @@
2.36 Ptr<PacketSizeMinMaxAvgTotalCalculator> appTxPkts =
2.37 CreateObject<PacketSizeMinMaxAvgTotalCalculator>();
2.38 appTxPkts->SetKey("tx-pkt-size");
2.39 + appTxPkts->SetContext("node[0]");
2.40 Config::Connect("/NodeList/0/ApplicationList/*/$Sender/Tx",
2.41 MakeCallback
2.42 (&PacketSizeMinMaxAvgTotalCalculator::PacketUpdate,
2.43 @@ -277,6 +282,7 @@
2.44 Ptr<TimeMinMaxAvgTotalCalculator> delayStat =
2.45 CreateObject<TimeMinMaxAvgTotalCalculator>();
2.46 delayStat->SetKey("delay");
2.47 + delayStat->SetContext(".");
2.48 receiver->SetDelayTracker(delayStat);
2.49 data.AddDataCalculator(delayStat);
2.50
3.1 --- a/src/contrib/stats/basic-data-calculators.h Wed Nov 11 11:57:14 2009 +0100
3.2 +++ b/src/contrib/stats/basic-data-calculators.h Wed Nov 11 12:44:09 2009 +0100
3.3 @@ -29,7 +29,8 @@
3.4 //------------------------------------------------------------
3.5 //--------------------------------------------
3.6 template <typename T = uint32_t>
3.7 - class MinMaxAvgTotalCalculator : public DataCalculator {
3.8 + class MinMaxAvgTotalCalculator : public DataCalculator,
3.9 + public StatisticalSummary {
3.10 public:
3.11 MinMaxAvgTotalCalculator();
3.12 virtual ~MinMaxAvgTotalCalculator();
3.13 @@ -38,6 +39,15 @@
3.14
3.15 virtual void Output(DataOutputCallback &callback) const;
3.16
3.17 + long getCount() const { return m_count; }
3.18 + double getSum() const { return m_total; }
3.19 + double getMin() const { return m_min; }
3.20 + double getMax() const { return m_max; }
3.21 + double getMean() const { return m_total / (double)m_count; }
3.22 + double getStddev() const { return NaN; } // unsupported
3.23 + double getVariance() const { return NaN; } // unsupported
3.24 + double getSqrSum() const { return NaN; } // unsupported
3.25 +
3.26 protected:
3.27 virtual void DoDispose(void);
3.28
3.29 @@ -86,23 +96,15 @@
3.30 }
3.31 // end MinMaxAvgTotalCalculator::Update
3.32 }
3.33 +
3.34 template <typename T>
3.35 void
3.36 MinMaxAvgTotalCalculator<T>::Output(DataOutputCallback &callback) const
3.37 {
3.38 - callback.OutputSingleton(m_key, "count", m_count);
3.39 - if (m_count > 0) {
3.40 - callback.OutputSingleton(m_key, "total", m_total);
3.41 - callback.OutputSingleton(m_key, "average", m_total/m_count);
3.42 - callback.OutputSingleton(m_key, "max", m_max);
3.43 - callback.OutputSingleton(m_key, "min", m_min);
3.44 - }
3.45 - // end MinMaxAvgTotalCalculator::Output
3.46 + callback.OutputStatistic(m_context, m_key, this);
3.47 }
3.48
3.49
3.50 -
3.51 -
3.52 //------------------------------------------------------------
3.53 //--------------------------------------------
3.54 template <typename T = uint32_t>
3.55 @@ -178,7 +180,7 @@
3.56 void
3.57 CounterCalculator<T>::Output(DataOutputCallback &callback) const
3.58 {
3.59 - callback.OutputSingleton(m_key, "count", m_count);
3.60 + callback.OutputSingleton(m_context, m_key, m_count);
3.61 // end CounterCalculator::Output
3.62 }
3.63
4.1 --- a/src/contrib/stats/data-calculator.cc Wed Nov 11 11:57:14 2009 +0100
4.2 +++ b/src/contrib/stats/data-calculator.cc Wed Nov 11 12:44:09 2009 +0100
4.3 @@ -27,6 +27,8 @@
4.4
4.5 NS_LOG_COMPONENT_DEFINE("DataCalculator");
4.6
4.7 +static double zero = 0;
4.8 +const double ns3::NaN = zero / zero;
4.9
4.10 //--------------------------------------------------------------
4.11 //----------------------------------------------
4.12 @@ -70,6 +72,20 @@
4.13
4.14 //----------------------------------------------
4.15 void
4.16 +DataCalculator::SetContext(const std::string context)
4.17 +{
4.18 + m_context = context;
4.19 + // end DataCalculator::SetContext
4.20 +}
4.21 +
4.22 +std::string
4.23 +DataCalculator::GetContext() const
4.24 +{
4.25 + return m_context;
4.26 + // end DataCalculator::GetContext
4.27 +}
4.28 +//----------------------------------------------
4.29 +void
4.30 DataCalculator::Enable()
4.31 {
4.32 m_enabled = true;
5.1 --- a/src/contrib/stats/data-calculator.h Wed Nov 11 11:57:14 2009 +0100
5.2 +++ b/src/contrib/stats/data-calculator.h Wed Nov 11 12:44:09 2009 +0100
5.3 @@ -26,9 +26,56 @@
5.4 #include "ns3/simulator.h"
5.5
5.6 namespace ns3 {
5.7 + extern const double NaN;
5.8 + inline bool isNaN(double x) { return x != x; }
5.9
5.10 class DataOutputCallback;
5.11
5.12 + class StatisticalSummary {
5.13 + public:
5.14 + /**
5.15 + * Returns the number of the observations.
5.16 + */
5.17 + virtual long getCount() const = 0;
5.18 +
5.19 + /**
5.20 + * Returns the sum of the values.
5.21 + * @see getWeightedSum()
5.22 + */
5.23 + virtual double getSum() const = 0;
5.24 +
5.25 + /**
5.26 + * Returns the sum of the squared values.
5.27 + * @see getWeightedSqrSum()
5.28 + */
5.29 + virtual double getSqrSum() const = 0;
5.30 +
5.31 + /**
5.32 + * Returns the minimum of the values.
5.33 + */
5.34 + virtual double getMin() const = 0;
5.35 +
5.36 + /**
5.37 + * Returns the maximum of the values.
5.38 + */
5.39 + virtual double getMax() const = 0;
5.40 +
5.41 + /**
5.42 + * Returns the mean of the (weighted) observations.
5.43 + */
5.44 + virtual double getMean() const = 0;
5.45 +
5.46 + /**
5.47 + * Returns the standard deviation of the (weighted) observations.
5.48 + */
5.49 + virtual double getStddev() const = 0;
5.50 +
5.51 + /**
5.52 + * Returns the variance of the (weighted) observations.
5.53 + */
5.54 + virtual double getVariance() const = 0;
5.55 + };
5.56 +
5.57 //------------------------------------------------------------
5.58 //--------------------------------------------
5.59 class DataCalculator : public Object {
5.60 @@ -43,6 +90,9 @@
5.61 void SetKey(const std::string key);
5.62 std::string GetKey() const;
5.63
5.64 + void SetContext(const std::string context);
5.65 + std::string GetContext() const;
5.66 +
5.67 virtual void Start(const Time& startTime);
5.68 virtual void Stop(const Time& stopTime);
5.69
5.70 @@ -52,6 +102,7 @@
5.71 bool m_enabled; // Descendant classes *must* check & respect m_enabled!
5.72
5.73 std::string m_key;
5.74 + std::string m_context;
5.75
5.76 virtual void DoDispose(void);
5.77
6.1 --- a/src/contrib/stats/data-output-interface.h Wed Nov 11 11:57:14 2009 +0100
6.2 +++ b/src/contrib/stats/data-output-interface.h Wed Nov 11 12:44:09 2009 +0100
6.3 @@ -23,6 +23,7 @@
6.4
6.5 #include "ns3/object.h"
6.6 #include "ns3/nstime.h"
6.7 +#include "ns3/data-calculator.h"
6.8
6.9 namespace ns3 {
6.10
6.11 @@ -52,6 +53,10 @@
6.12 public:
6.13 virtual ~DataOutputCallback() {}
6.14
6.15 + virtual void OutputStatistic(std::string key,
6.16 + std::string variable,
6.17 + const StatisticalSummary *statSum) = 0;
6.18 +
6.19 virtual void OutputSingleton(std::string key,
6.20 std::string variable,
6.21 int val) = 0;
7.1 --- a/src/contrib/stats/omnet-data-output.cc Wed Nov 11 11:57:14 2009 +0100
7.2 +++ b/src/contrib/stats/omnet-data-output.cc Wed Nov 11 12:44:09 2009 +0100
7.3 @@ -19,6 +19,7 @@
7.4 */
7.5
7.6 #include <fstream>
7.7 +#include <cstdlib>
7.8
7.9 #include "ns3/log.h"
7.10 #include "ns3/nstime.h"
7.11 @@ -54,26 +55,31 @@
7.12 }
7.13
7.14 //----------------------------------------------
7.15 +
7.16 +inline bool isNumeric(const std::string& s) {
7.17 + char *endp;
7.18 + strtod(s.c_str(), &endp);
7.19 + return endp == s.c_str() + s.size();
7.20 +}
7.21 +
7.22 void
7.23 OmnetDataOutput::Output(DataCollector &dc)
7.24 {
7.25
7.26 std::ofstream scalarFile;
7.27 - std::string fn = m_filePrefix + ".sca";
7.28 - scalarFile.open(fn.c_str(), std::ios_base::app);
7.29 + std::string fn = m_filePrefix +"-"+dc.GetRunLabel()+ ".sca";
7.30 + scalarFile.open(fn.c_str(), std::ios_base::out);
7.31
7.32 - scalarFile << std::endl;
7.33 + // TODO add timestamp to the runlevel
7.34 scalarFile << "run " << dc.GetRunLabel() << std::endl;
7.35 - scalarFile << std::endl;
7.36 scalarFile << "attr experiment \"" << dc.GetExperimentLabel()
7.37 << "\"" << std::endl;
7.38 scalarFile << "attr strategy \"" << dc.GetStrategyLabel()
7.39 << "\"" << std::endl;
7.40 - scalarFile << "attr input \"" << dc.GetInputLabel()
7.41 + scalarFile << "attr measurement \"" << dc.GetInputLabel()
7.42 << "\"" << std::endl;
7.43 scalarFile << "attr description \"" << dc.GetDescription()
7.44 << "\"" << std::endl;
7.45 - scalarFile << std::endl;
7.46
7.47 for (MetadataList::iterator i = dc.MetadataBegin();
7.48 i != dc.MetadataEnd(); i++) {
7.49 @@ -83,7 +89,18 @@
7.50 }
7.51
7.52 scalarFile << std::endl;
7.53 -
7.54 + if (isNumeric(dc.GetInputLabel())) {
7.55 + scalarFile << "scalar . measurement \"" << dc.GetInputLabel()
7.56 + << "\"" << std::endl;
7.57 + }
7.58 + for (MetadataList::iterator i = dc.MetadataBegin();
7.59 + i != dc.MetadataEnd(); i++) {
7.60 + std::pair<std::string, std::string> blob = (*i);
7.61 + if (isNumeric(blob.second)) {
7.62 + scalarFile << "scalar . \"" << blob.first << "\" \"" << blob.second << "\""
7.63 + << std::endl;
7.64 + }
7.65 + }
7.66 OmnetOutputCallback callback(&scalarFile);
7.67
7.68 for (DataCalculatorList::iterator i = dc.DataCalculatorBegin();
7.69 @@ -97,6 +114,7 @@
7.70 // end OmnetDataOutput::Output
7.71 }
7.72
7.73 +
7.74 OmnetDataOutput::OmnetOutputCallback::OmnetOutputCallback
7.75 (std::ostream *scalar) :
7.76 m_scalar(scalar)
7.77 @@ -104,42 +122,92 @@
7.78 }
7.79
7.80 void
7.81 -OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string key,
7.82 - std::string variable,
7.83 +OmnetDataOutput::OmnetOutputCallback::OutputStatistic(std::string context,
7.84 + std::string name,
7.85 + const StatisticalSummary *statSum)
7.86 +{
7.87 + if (context == "")
7.88 + context = ".";
7.89 + if (name == "")
7.90 + name = "\"\"";
7.91 + (*m_scalar) << "statistic " << context << " " << name << std::endl;
7.92 + if (!isNaN(statSum->getCount()))
7.93 + (*m_scalar) << "field count " << statSum->getCount() << std::endl;
7.94 + if (!isNaN(statSum->getSum()))
7.95 + (*m_scalar) << "field sum " << statSum->getSum() << std::endl;
7.96 + if (!isNaN(statSum->getMean()))
7.97 + (*m_scalar) << "field mean " << statSum->getMean() << std::endl;
7.98 + if (!isNaN(statSum->getMin()))
7.99 + (*m_scalar) << "field min " << statSum->getMin() << std::endl;
7.100 + if (!isNaN(statSum->getMax()))
7.101 + (*m_scalar) << "field max " << statSum->getMax() << std::endl;
7.102 + if (!isNaN(statSum->getSqrSum()))
7.103 + (*m_scalar) << "field sqrsum " << statSum->getSqrSum() << std::endl;
7.104 + if (!isNaN(statSum->getStddev()))
7.105 + (*m_scalar) << "field stddev " << statSum->getStddev() << std::endl;
7.106 +}
7.107 +
7.108 +void
7.109 +OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string context,
7.110 + std::string name,
7.111 int val)
7.112 {
7.113 - (*m_scalar) << "scalar " << key << " " << variable << " " << val << std::endl;
7.114 + if (context == "")
7.115 + context = ".";
7.116 + if (name == "")
7.117 + name = "\"\"";
7.118 + (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
7.119 // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
7.120 }
7.121 +
7.122 void
7.123 -OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string key,
7.124 - std::string variable,
7.125 +OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string context,
7.126 + std::string name,
7.127 uint32_t val)
7.128 {
7.129 - (*m_scalar) << "scalar " << key << " " << variable << " " << val << std::endl;
7.130 + if (context == "")
7.131 + context = ".";
7.132 + if (name == "")
7.133 + name = "\"\"";
7.134 + (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
7.135 // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
7.136 }
7.137 +
7.138 void
7.139 -OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string key,
7.140 - std::string variable,
7.141 +OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string context,
7.142 + std::string name,
7.143 double val)
7.144 {
7.145 - (*m_scalar) << "scalar " << key << " " << variable << " " << val << std::endl;
7.146 + if (context == "")
7.147 + context = ".";
7.148 + if (name == "")
7.149 + name = "\"\"";
7.150 + (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
7.151 // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
7.152 }
7.153 +
7.154 void
7.155 -OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string key,
7.156 - std::string variable,
7.157 +OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string context,
7.158 + std::string name,
7.159 std::string val)
7.160 {
7.161 - (*m_scalar) << "scalar " << key << " " << variable << " " << val << std::endl;
7.162 + if (context == "")
7.163 + context = ".";
7.164 + if (name == "")
7.165 + name = "\"\"";
7.166 + (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
7.167 // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
7.168 }
7.169 +
7.170 void
7.171 -OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string key,
7.172 - std::string variable,
7.173 +OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string context,
7.174 + std::string name,
7.175 Time val)
7.176 {
7.177 - (*m_scalar) << "scalar " << key << " " << variable << " " << val << std::endl;
7.178 + if (context == "")
7.179 + context = ".";
7.180 + if (name == "")
7.181 + name = "\"\"";
7.182 + (*m_scalar) << "scalar " << context << " " << name << " " << val.GetTimeStep() << std::endl;
7.183 // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
7.184 }
8.1 --- a/src/contrib/stats/omnet-data-output.h Wed Nov 11 11:57:14 2009 +0100
8.2 +++ b/src/contrib/stats/omnet-data-output.h Wed Nov 11 12:44:09 2009 +0100
8.3 @@ -45,24 +45,28 @@
8.4 public:
8.5 OmnetOutputCallback(std::ostream *scalar);
8.6
8.7 - void OutputSingleton(std::string key,
8.8 - std::string variable,
8.9 + void OutputStatistic(std::string context,
8.10 + std::string name,
8.11 + const StatisticalSummary *statSum);
8.12 +
8.13 + void OutputSingleton(std::string context,
8.14 + std::string name,
8.15 int val);
8.16
8.17 - void OutputSingleton(std::string key,
8.18 - std::string variable,
8.19 + void OutputSingleton(std::string context,
8.20 + std::string name,
8.21 uint32_t val);
8.22
8.23 - void OutputSingleton(std::string key,
8.24 - std::string variable,
8.25 + void OutputSingleton(std::string context,
8.26 + std::string name,
8.27 double val);
8.28
8.29 - void OutputSingleton(std::string key,
8.30 - std::string variable,
8.31 + void OutputSingleton(std::string context,
8.32 + std::string name,
8.33 std::string val);
8.34
8.35 - void OutputSingleton(std::string key,
8.36 - std::string variable,
8.37 + void OutputSingleton(std::string context,
8.38 + std::string name,
8.39 Time val);
8.40
8.41 private:
9.1 --- a/src/contrib/stats/sqlite-data-output.cc Wed Nov 11 11:57:14 2009 +0100
9.2 +++ b/src/contrib/stats/sqlite-data-output.cc Wed Nov 11 12:44:09 2009 +0100
9.3 @@ -154,6 +154,25 @@
9.4 }
9.5
9.6 void
9.7 +SqliteDataOutput::SqliteOutputCallback::OutputStatistic(std::string key,
9.8 + std::string variable,
9.9 + const StatisticalSummary *statSum)
9.10 +{
9.11 + OutputSingleton(key,variable+"-count", (double)statSum->getCount());
9.12 + if (!isNaN(statSum->getSum()))
9.13 + OutputSingleton(key,variable+"-total", statSum->getSum());
9.14 + if (!isNaN(statSum->getMax()))
9.15 + OutputSingleton(key,variable+"-max", statSum->getMax());
9.16 + if (!isNaN(statSum->getMin()))
9.17 + OutputSingleton(key,variable+"-min", statSum->getMin());
9.18 + if (!isNaN(statSum->getSqrSum()))
9.19 + OutputSingleton(key,variable+"-sqrsum", statSum->getSqrSum());
9.20 + if (!isNaN(statSum->getStddev()))
9.21 + OutputSingleton(key,variable+"-stddev", statSum->getStddev());
9.22 +}
9.23 +
9.24 +
9.25 +void
9.26 SqliteDataOutput::SqliteOutputCallback::OutputSingleton(std::string key,
9.27 std::string variable,
9.28 int val)
10.1 --- a/src/contrib/stats/sqlite-data-output.h Wed Nov 11 11:57:14 2009 +0100
10.2 +++ b/src/contrib/stats/sqlite-data-output.h Wed Nov 11 12:44:09 2009 +0100
10.3 @@ -48,6 +48,10 @@
10.4 public:
10.5 SqliteOutputCallback(Ptr<SqliteDataOutput> owner, std::string run);
10.6
10.7 + void OutputStatistic(std::string key,
10.8 + std::string variable,
10.9 + const StatisticalSummary *statSum);
10.10 +
10.11 void OutputSingleton(std::string key,
10.12 std::string variable,
10.13 int val);
11.1 --- a/src/contrib/stats/time-data-calculators.cc Wed Nov 11 11:57:14 2009 +0100
11.2 +++ b/src/contrib/stats/time-data-calculators.cc Wed Nov 11 12:44:09 2009 +0100
11.3 @@ -70,12 +70,12 @@
11.4 void
11.5 TimeMinMaxAvgTotalCalculator::Output(DataOutputCallback &callback) const
11.6 {
11.7 - callback.OutputSingleton(m_key, "count", m_count);
11.8 + callback.OutputSingleton(m_context, m_key + "-count", m_count);
11.9 if (m_count > 0) {
11.10 - callback.OutputSingleton(m_key, "total", m_total);
11.11 - callback.OutputSingleton(m_key, "average", m_total/Scalar(m_count));
11.12 - callback.OutputSingleton(m_key, "max", m_max);
11.13 - callback.OutputSingleton(m_key, "min", m_min);
11.14 + callback.OutputSingleton(m_context, m_key + "-total", m_total);
11.15 + callback.OutputSingleton(m_context, m_key + "-average", m_total/Scalar(m_count));
11.16 + callback.OutputSingleton(m_context, m_key + "-max", m_max);
11.17 + callback.OutputSingleton(m_context, m_key + "-min", m_min);
11.18 }
11.19 // end TimeMinMaxAvgTotalCalculator::Output
11.20 }