A Discrete-Event Network Simulator
API
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 
31 using namespace ns3;
32 
33 NS_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 */
50 TypeId
52 {
53  static TypeId tid = TypeId("ns3::OmnetDataOutput")
55  .SetGroupName("Stats")
56  .AddConstructor<OmnetDataOutput>();
57  return tid;
58 }
59 
60 void
62 {
63  NS_LOG_FUNCTION(this);
64 
66  // end OmnetDataOutput::DoDispose
67 }
68 
69 //----------------------------------------------
70 
71 inline bool
72 isNumeric(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))
81  {
82  return false;
83  }
84  else if (*it == '.')
85  {
86  decimalPtSeen = true;
87  }
88  else if ((*it == 'e') && exponentSeen)
89  {
90  return false;
91  }
92  else if (*it == 'e')
93  {
94  exponentSeen = true;
95  decimalPtSeen = false;
96  }
97  else if (*it == '-' && it != s.begin() && last != 'e')
98  {
99  return false;
100  }
101 
102  last = *it;
103  }
104  return true;
105 }
106 
107 void
109 {
110  NS_LOG_FUNCTION(this << &dc);
111 
112  std::ofstream scalarFile;
113  std::string fn = m_filePrefix + "-" + dc.GetRunLabel() + ".sca";
114  scalarFile.open(fn, std::ios_base::out);
115 
117  scalarFile << "run " << dc.GetRunLabel() << std::endl;
118  scalarFile << "attr experiment \"" << dc.GetExperimentLabel() << "\"" << std::endl;
119  scalarFile << "attr strategy \"" << dc.GetStrategyLabel() << "\"" << std::endl;
120  scalarFile << "attr measurement \"" << dc.GetInputLabel() << "\"" << std::endl;
121  scalarFile << "attr description \"" << dc.GetDescription() << "\"" << std::endl;
122 
123  for (auto i = dc.MetadataBegin(); i != dc.MetadataEnd(); i++)
124  {
125  std::pair<std::string, std::string> blob = (*i);
126  scalarFile << "attr \"" << blob.first << "\" \"" << blob.second << "\"" << std::endl;
127  }
128 
129  scalarFile << std::endl;
130  if (isNumeric(dc.GetInputLabel()))
131  {
132  scalarFile << "scalar . measurement \"" << dc.GetInputLabel() << "\"" << std::endl;
133  }
134  for (auto i = dc.MetadataBegin(); i != dc.MetadataEnd(); i++)
135  {
136  std::pair<std::string, std::string> blob = (*i);
137  if (isNumeric(blob.second))
138  {
139  scalarFile << "scalar . \"" << blob.first << "\" \"" << blob.second << "\""
140  << std::endl;
141  }
142  }
143  OmnetOutputCallback callback(&scalarFile);
144 
145  for (auto i = dc.DataCalculatorBegin(); i != dc.DataCalculatorEnd(); i++)
146  {
147  (*i)->Output(callback);
148  }
149 
150  scalarFile << std::endl << std::endl;
151  scalarFile.close();
152 
153  // end OmnetDataOutput::Output
154 }
155 
157  : m_scalar(scalar)
158 {
159  NS_LOG_FUNCTION(this << scalar);
160 }
161 
162 void
164  std::string name,
165  const StatisticalSummary* statSum)
166 {
167  NS_LOG_FUNCTION(this << context << name << statSum);
168 
169  if (context.empty())
170  {
171  context = ".";
172  }
173  if (name.empty())
174  {
175  name = "\"\"";
176  }
177  (*m_scalar) << "statistic " << context << " " << name << std::endl;
178  if (!isNaN(statSum->getCount()))
179  {
180  (*m_scalar) << "field count " << statSum->getCount() << std::endl;
181  }
182  if (!isNaN(statSum->getSum()))
183  {
184  (*m_scalar) << "field sum " << statSum->getSum() << std::endl;
185  }
186  if (!isNaN(statSum->getMean()))
187  {
188  (*m_scalar) << "field mean " << statSum->getMean() << std::endl;
189  }
190  if (!isNaN(statSum->getMin()))
191  {
192  (*m_scalar) << "field min " << statSum->getMin() << std::endl;
193  }
194  if (!isNaN(statSum->getMax()))
195  {
196  (*m_scalar) << "field max " << statSum->getMax() << std::endl;
197  }
198  if (!isNaN(statSum->getSqrSum()))
199  {
200  (*m_scalar) << "field sqrsum " << statSum->getSqrSum() << std::endl;
201  }
202  if (!isNaN(statSum->getStddev()))
203  {
204  (*m_scalar) << "field stddev " << statSum->getStddev() << std::endl;
205  }
206 }
207 
208 void
210  std::string name,
211  int val)
212 {
213  NS_LOG_FUNCTION(this << context << name << val);
214 
215  if (context.empty())
216  {
217  context = ".";
218  }
219  if (name.empty())
220  {
221  name = "\"\"";
222  }
223  (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
224  // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
225 }
226 
227 void
229  std::string name,
230  uint32_t val)
231 {
232  NS_LOG_FUNCTION(this << context << name << val);
233 
234  if (context.empty())
235  {
236  context = ".";
237  }
238  if (name.empty())
239  {
240  name = "\"\"";
241  }
242  (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
243  // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
244 }
245 
246 void
248  std::string name,
249  double val)
250 {
251  NS_LOG_FUNCTION(this << context << name << val);
252 
253  if (context.empty())
254  {
255  context = ".";
256  }
257  if (name.empty())
258  {
259  name = "\"\"";
260  }
261  (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
262  // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
263 }
264 
265 void
267  std::string name,
268  std::string val)
269 {
270  NS_LOG_FUNCTION(this << context << name << val);
271 
272  if (context.empty())
273  {
274  context = ".";
275  }
276  if (name.empty())
277  {
278  name = "\"\"";
279  }
280  (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
281  // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
282 }
283 
284 void
286  std::string name,
287  Time val)
288 {
289  NS_LOG_FUNCTION(this << context << name << val);
290 
291  if (context.empty())
292  {
293  context = ".";
294  }
295  if (name.empty())
296  {
297  name = "\"\"";
298  }
299  (*m_scalar) << "scalar " << context << " " << name << " " << val.GetTimeStep() << std::endl;
300  // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
301 }
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:931
#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)