A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
omnet-data-output.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008 Drexel University
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Joe Kopena (tjkopena@cs.drexel.edu)
18 */
19
20#include "omnet-data-output.h"
21
22#include "data-calculator.h"
23#include "data-collector.h"
24
25#include "ns3/log.h"
26#include "ns3/nstime.h"
27
28#include <cstdlib>
29#include <fstream>
30
31using namespace ns3;
32
33NS_LOG_COMPONENT_DEFINE("OmnetDataOutput");
34
35//--------------------------------------------------------------
36//----------------------------------------------
38{
39 NS_LOG_FUNCTION(this);
40
41 m_filePrefix = "data";
42}
43
45{
46 NS_LOG_FUNCTION(this);
47}
48
49/* static */
52{
53 static TypeId tid = TypeId("ns3::OmnetDataOutput")
55 .SetGroupName("Stats")
56 .AddConstructor<OmnetDataOutput>();
57 return tid;
58}
59
60void
62{
63 NS_LOG_FUNCTION(this);
64
66 // end OmnetDataOutput::DoDispose
67}
68
69//----------------------------------------------
70
71inline bool
72isNumeric(const std::string& s)
73{
74 bool decimalPtSeen = false;
75 bool exponentSeen = false;
76 char last = '\0';
77
78 for (auto it = s.begin(); it != s.end(); it++)
79 {
80 if ((*it == '.' && decimalPtSeen) || (*it == 'e' && exponentSeen) ||
81 (*it == '-' && it != s.begin() && last != 'e'))
82 {
83 return false;
84 }
85 else if (*it == '.')
86 {
87 decimalPtSeen = true;
88 }
89 else if (*it == 'e')
90 {
91 exponentSeen = true;
92 decimalPtSeen = false;
93 }
94
95 last = *it;
96 }
97 return true;
98}
99
100void
102{
103 NS_LOG_FUNCTION(this << &dc);
104
105 std::ofstream scalarFile;
106 std::string fn = m_filePrefix + "-" + dc.GetRunLabel() + ".sca";
107 scalarFile.open(fn, std::ios_base::out);
108
109 /// \todo add timestamp to the runlevel
110 scalarFile << "run " << dc.GetRunLabel() << std::endl;
111 scalarFile << "attr experiment \"" << dc.GetExperimentLabel() << "\"" << std::endl;
112 scalarFile << "attr strategy \"" << dc.GetStrategyLabel() << "\"" << std::endl;
113 scalarFile << "attr measurement \"" << dc.GetInputLabel() << "\"" << std::endl;
114 scalarFile << "attr description \"" << dc.GetDescription() << "\"" << std::endl;
115
116 for (auto i = dc.MetadataBegin(); i != dc.MetadataEnd(); i++)
117 {
118 std::pair<std::string, std::string> blob = (*i);
119 scalarFile << "attr \"" << blob.first << "\" \"" << blob.second << "\"" << std::endl;
120 }
121
122 scalarFile << std::endl;
123 if (isNumeric(dc.GetInputLabel()))
124 {
125 scalarFile << "scalar . measurement \"" << dc.GetInputLabel() << "\"" << std::endl;
126 }
127 for (auto i = dc.MetadataBegin(); i != dc.MetadataEnd(); i++)
128 {
129 std::pair<std::string, std::string> blob = (*i);
130 if (isNumeric(blob.second))
131 {
132 scalarFile << "scalar . \"" << blob.first << "\" \"" << blob.second << "\""
133 << std::endl;
134 }
135 }
136 OmnetOutputCallback callback(&scalarFile);
137
138 for (auto i = dc.DataCalculatorBegin(); i != dc.DataCalculatorEnd(); i++)
139 {
140 (*i)->Output(callback);
141 }
142
143 scalarFile << std::endl << std::endl;
144 scalarFile.close();
145
146 // end OmnetDataOutput::Output
147}
148
150 : m_scalar(scalar)
151{
152 NS_LOG_FUNCTION(this << scalar);
153}
154
155void
157 std::string name,
158 const StatisticalSummary* statSum)
159{
160 NS_LOG_FUNCTION(this << context << name << statSum);
161
162 if (context.empty())
163 {
164 context = ".";
165 }
166 if (name.empty())
167 {
168 name = "\"\"";
169 }
170 (*m_scalar) << "statistic " << context << " " << name << std::endl;
171 if (!isNaN(statSum->getCount()))
172 {
173 (*m_scalar) << "field count " << statSum->getCount() << std::endl;
174 }
175 if (!isNaN(statSum->getSum()))
176 {
177 (*m_scalar) << "field sum " << statSum->getSum() << std::endl;
178 }
179 if (!isNaN(statSum->getMean()))
180 {
181 (*m_scalar) << "field mean " << statSum->getMean() << std::endl;
182 }
183 if (!isNaN(statSum->getMin()))
184 {
185 (*m_scalar) << "field min " << statSum->getMin() << std::endl;
186 }
187 if (!isNaN(statSum->getMax()))
188 {
189 (*m_scalar) << "field max " << statSum->getMax() << std::endl;
190 }
191 if (!isNaN(statSum->getSqrSum()))
192 {
193 (*m_scalar) << "field sqrsum " << statSum->getSqrSum() << std::endl;
194 }
195 if (!isNaN(statSum->getStddev()))
196 {
197 (*m_scalar) << "field stddev " << statSum->getStddev() << std::endl;
198 }
199}
200
201void
203 std::string name,
204 int val)
205{
206 NS_LOG_FUNCTION(this << context << name << val);
207
208 if (context.empty())
209 {
210 context = ".";
211 }
212 if (name.empty())
213 {
214 name = "\"\"";
215 }
216 (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
217 // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
218}
219
220void
222 std::string name,
223 uint32_t val)
224{
225 NS_LOG_FUNCTION(this << context << name << val);
226
227 if (context.empty())
228 {
229 context = ".";
230 }
231 if (name.empty())
232 {
233 name = "\"\"";
234 }
235 (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
236 // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
237}
238
239void
241 std::string name,
242 double val)
243{
244 NS_LOG_FUNCTION(this << context << name << val);
245
246 if (context.empty())
247 {
248 context = ".";
249 }
250 if (name.empty())
251 {
252 name = "\"\"";
253 }
254 (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
255 // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
256}
257
258void
260 std::string name,
261 std::string val)
262{
263 NS_LOG_FUNCTION(this << context << name << val);
264
265 if (context.empty())
266 {
267 context = ".";
268 }
269 if (name.empty())
270 {
271 name = "\"\"";
272 }
273 (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
274 // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
275}
276
277void
279 std::string name,
280 Time val)
281{
282 NS_LOG_FUNCTION(this << context << name << val);
283
284 if (context.empty())
285 {
286 context = ".";
287 }
288 if (name.empty())
289 {
290 name = "\"\"";
291 }
292 (*m_scalar) << "scalar " << context << " " << name << " " << val.GetTimeStep() << std::endl;
293 // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
294}
Collects data.
std::string GetExperimentLabel() const
Return the experiment label.
DataCalculatorList::iterator DataCalculatorBegin()
Returns an iterator to the beginning of the DataCalculator list.
DataCalculatorList::iterator DataCalculatorEnd()
Returns an iterator to the past-the-end of the DataCalculator list.
std::string GetDescription() const
Return the description label.
MetadataList::iterator MetadataBegin()
Returns an iterator to the beginning of the metadata list.
MetadataList::iterator MetadataEnd()
Returns an iterator to the past-the-end of the metadata list.
std::string GetStrategyLabel() const
Return the strategy label.
std::string GetRunLabel() const
Return the runID label.
std::string GetInputLabel() const
Return the input label.
Abstract Data Output Interface class s.
void DoDispose() override
Destructor implementation.
std::string m_filePrefix
File prefix for the DataOutputInterface.
Class to generate OMNeT output.
OmnetOutputCallback(std::ostream *scalar)
Constructor.
void OutputSingleton(std::string context, std::string name, int val) override
Generates a single data output.
void OutputStatistic(std::string context, std::string name, const StatisticalSummary *statSum) override
Generates data statistics.
Outputs data in a format compatible with OMNeT library and framework.
void DoDispose() override
Destructor implementation.
void Output(DataCollector &dc) override
Outputs information from the provided DataCollector.
static TypeId GetTypeId()
Register this type.
Abstract class for calculating statistical data.
virtual double getMax() const =0
Returns the maximum of the values.
virtual double getMean() const =0
Returns the mean of the (weighted) observations.
virtual double getStddev() const =0
Returns the standard deviation of the (weighted) observations.
virtual long getCount() const =0
Returns the number of observations.
virtual double getMin() const =0
Returns the minimum of the values.
virtual double getSum() const =0
virtual double getSqrSum() const =0
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetTimeStep() const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:445
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool isNaN(double x)
true if x is NaN
bool isNumeric(const std::string &s)