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 (std::string::const_iterator 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 (MetadataList::iterator 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 (MetadataList::iterator 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 (DataCalculatorList::iterator i = dc.DataCalculatorBegin(); i != dc.DataCalculatorEnd();
146  i++)
147  {
148  (*i)->Output(callback);
149  }
150 
151  scalarFile << std::endl << std::endl;
152  scalarFile.close();
153 
154  // end OmnetDataOutput::Output
155 }
156 
158  : m_scalar(scalar)
159 {
160  NS_LOG_FUNCTION(this << scalar);
161 }
162 
163 void
165  std::string name,
166  const StatisticalSummary* statSum)
167 {
168  NS_LOG_FUNCTION(this << context << name << statSum);
169 
170  if (context.empty())
171  {
172  context = ".";
173  }
174  if (name.empty())
175  {
176  name = "\"\"";
177  }
178  (*m_scalar) << "statistic " << context << " " << name << std::endl;
179  if (!isNaN(statSum->getCount()))
180  {
181  (*m_scalar) << "field count " << statSum->getCount() << std::endl;
182  }
183  if (!isNaN(statSum->getSum()))
184  {
185  (*m_scalar) << "field sum " << statSum->getSum() << std::endl;
186  }
187  if (!isNaN(statSum->getMean()))
188  {
189  (*m_scalar) << "field mean " << statSum->getMean() << std::endl;
190  }
191  if (!isNaN(statSum->getMin()))
192  {
193  (*m_scalar) << "field min " << statSum->getMin() << std::endl;
194  }
195  if (!isNaN(statSum->getMax()))
196  {
197  (*m_scalar) << "field max " << statSum->getMax() << std::endl;
198  }
199  if (!isNaN(statSum->getSqrSum()))
200  {
201  (*m_scalar) << "field sqrsum " << statSum->getSqrSum() << std::endl;
202  }
203  if (!isNaN(statSum->getStddev()))
204  {
205  (*m_scalar) << "field stddev " << statSum->getStddev() << std::endl;
206  }
207 }
208 
209 void
211  std::string name,
212  int val)
213 {
214  NS_LOG_FUNCTION(this << context << name << val);
215 
216  if (context.empty())
217  {
218  context = ".";
219  }
220  if (name.empty())
221  {
222  name = "\"\"";
223  }
224  (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
225  // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
226 }
227 
228 void
230  std::string name,
231  uint32_t val)
232 {
233  NS_LOG_FUNCTION(this << context << name << val);
234 
235  if (context.empty())
236  {
237  context = ".";
238  }
239  if (name.empty())
240  {
241  name = "\"\"";
242  }
243  (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
244  // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
245 }
246 
247 void
249  std::string name,
250  double val)
251 {
252  NS_LOG_FUNCTION(this << context << name << val);
253 
254  if (context.empty())
255  {
256  context = ".";
257  }
258  if (name.empty())
259  {
260  name = "\"\"";
261  }
262  (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
263  // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
264 }
265 
266 void
268  std::string name,
269  std::string val)
270 {
271  NS_LOG_FUNCTION(this << context << name << val);
272 
273  if (context.empty())
274  {
275  context = ".";
276  }
277  if (name.empty())
278  {
279  name = "\"\"";
280  }
281  (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
282  // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
283 }
284 
285 void
287  std::string name,
288  Time val)
289 {
290  NS_LOG_FUNCTION(this << context << name << val);
291 
292  if (context.empty())
293  {
294  context = ".";
295  }
296  if (name.empty())
297  {
298  name = "\"\"";
299  }
300  (*m_scalar) << "scalar " << context << " " << name << " " << val.GetTimeStep() << std::endl;
301  // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
302 }
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:444
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
#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)