Left: | ||
Right: |
OLD | NEW |
---|---|
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * Copyright (c) 2013 University of Washington | 3 * Copyright (c) 2013 University of Washington |
4 * Copyright (c) 2015 Bucknell University | |
4 * | 5 * |
5 * This program is free software; you can redistribute it and/or modify | 6 * This program is free software; you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 2 as | 7 * it under the terms of the GNU General Public License version 2 as |
7 * published by the Free Software Foundation; | 8 * published by the Free Software Foundation; |
8 * | 9 * |
9 * This program is distributed in the hope that it will be useful, | 10 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 13 * GNU General Public License for more details. |
13 * | 14 * |
14 * You should have received a copy of the GNU General Public License | 15 * You should have received a copy of the GNU General Public License |
15 * along with this program; if not, write to the Free Software | 16 * along with this program; if not, write to the Free Software |
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 * | 18 * |
18 * Author: Mitch Watrous (watrous@u.washington.edu) | 19 * Author: Mitch Watrous (watrous@u.washington.edu) |
20 * Modified by: Li Li (ll024@bucknell.edu) | |
19 */ | 21 */ |
20 | 22 |
21 #include <iostream> | 23 #include <iostream> |
22 #include <fstream> | 24 #include <fstream> |
23 #include <string> | 25 #include <string> |
24 #include <sstream> | 26 #include <sstream> |
25 | 27 |
26 #include "gnuplot-helper.h" | 28 #include "gnuplot-helper.h" |
27 #include "ns3/abort.h" | 29 #include "ns3/abort.h" |
28 #include "ns3/assert.h" | 30 #include "ns3/assert.h" |
29 #include "ns3/config.h" | 31 #include "ns3/config.h" |
30 #include "ns3/log.h" | 32 #include "ns3/log.h" |
31 #include "ns3/get-wildcard-matches.h" | 33 #include "ns3/get-wildcard-matches.h" |
32 | 34 |
33 namespace ns3 { | 35 namespace ns3 { |
34 | 36 |
35 NS_LOG_COMPONENT_DEFINE ("GnuplotHelper"); | 37 NS_LOG_COMPONENT_DEFINE ("GnuplotHelper"); |
36 | 38 |
37 GnuplotHelper::GnuplotHelper () | 39 GnuplotHelper::GnuplotHelper () |
38 : m_aggregator (0), | 40 : m_aggregator (0), |
39 m_plotProbeCount (0), | 41 m_plotProbeCount (0), |
40 m_outputFileNameWithoutExtension ("gnuplot-helper"), | 42 m_outputFileNameWithoutExtension ("gnuplot-helper"), |
41 m_title ("Gnuplot Helper Plot"), | 43 m_title ("Gnuplot Helper Plot"), |
42 m_xLegend ("X Values"), | 44 m_xLegend ("X Values"), |
43 m_yLegend ("Y Values"), | 45 m_yLegend ("Y Values"), |
44 m_terminalType ("png") | 46 m_terminalType ("png"), |
47 m_scalingFactor (1) | |
45 { | 48 { |
46 NS_LOG_FUNCTION (this); | 49 NS_LOG_FUNCTION (this); |
50 m_collectorFactory.SetTypeId ("ns3::EventDrivenCollector"); | |
47 | 51 |
48 // Note that this does not construct an aggregator. It will be | 52 // Note that this does not construct an aggregator. It will be |
49 // constructed later when needed. | 53 // constructed later when needed. |
50 } | 54 } |
51 | 55 |
52 GnuplotHelper::GnuplotHelper (const std::string &outputFileNameWithoutExtension, | 56 GnuplotHelper::GnuplotHelper (const std::string &outputFileNameWithoutExtension, |
53 const std::string &title, | 57 const std::string &title, |
54 const std::string &xLegend, | 58 const std::string &xLegend, |
55 const std::string &yLegend, | 59 const std::string &yLegend, |
56 const std::string &terminalType) | 60 const std::string &terminalType) |
57 : m_aggregator (0), | 61 : m_aggregator (0), |
58 m_plotProbeCount (0), | 62 m_plotProbeCount (0), |
59 m_outputFileNameWithoutExtension (outputFileNameWithoutExtension), | 63 m_outputFileNameWithoutExtension (outputFileNameWithoutExtension), |
60 m_title (title), | 64 m_title (title), |
61 m_xLegend (xLegend), | 65 m_xLegend (xLegend), |
62 m_yLegend (yLegend), | 66 m_yLegend (yLegend), |
63 m_terminalType (terminalType) | 67 m_terminalType (terminalType), |
68 m_scalingFactor (1) | |
64 { | 69 { |
65 NS_LOG_FUNCTION (this); | 70 NS_LOG_FUNCTION (this); |
71 m_collectorFactory.SetTypeId ("ns3::EventDrivenCollector"); | |
66 | 72 |
67 // Construct the aggregator. | 73 // Construct the aggregator. |
68 ConstructAggregator (); | 74 ConstructAggregator (); |
69 } | 75 } |
70 | 76 |
71 GnuplotHelper::~GnuplotHelper () | 77 GnuplotHelper::~GnuplotHelper () |
72 { | 78 { |
73 NS_LOG_FUNCTION (this); | 79 NS_LOG_FUNCTION (this); |
74 } | 80 } |
75 | 81 |
76 void | 82 void |
77 GnuplotHelper::ConfigurePlot (const std::string &outputFileNameWithoutExtension, | 83 GnuplotHelper::ConfigurePlot (const std::string &outputFileNameWithoutExtension, |
78 const std::string &title, | 84 const std::string &title, |
79 const std::string &xLegend, | 85 const std::string &xLegend, |
80 const std::string &yLegend, | 86 const std::string &yLegend, |
81 const std::string &terminalType) | 87 const std::string &terminalType) |
88 ······························ | |
82 { | 89 { |
83 NS_LOG_FUNCTION (this << outputFileNameWithoutExtension << title | 90 NS_LOG_FUNCTION (this << outputFileNameWithoutExtension << title |
84 << xLegend << yLegend << terminalType); | 91 << xLegend << yLegend << terminalType); |
85 | 92 |
86 // See if an aggregator has already been constructed. | 93 // See if an aggregator has already been constructed. |
87 if (m_aggregator != 0) | 94 if (m_aggregator != 0) |
88 { | 95 { |
89 NS_LOG_WARN ("An existing aggregator object " << m_aggregator << | 96 NS_LOG_WARN ("An existing aggregator object " << m_aggregator << |
90 " may be destroyed if no references remain."); | 97 " may be destroyed if no references remain."); |
91 } | 98 } |
92 | 99 |
93 // Store these so that they can be used to construct the aggregator. | 100 // Store these so that they can be used to construct the aggregator. |
94 m_outputFileNameWithoutExtension = outputFileNameWithoutExtension; | 101 m_outputFileNameWithoutExtension = outputFileNameWithoutExtension; |
95 m_title = title; | 102 m_title = title; |
96 m_xLegend = xLegend; | 103 m_xLegend = xLegend; |
97 m_yLegend = yLegend; | 104 m_yLegend = yLegend; |
98 m_terminalType = terminalType; | 105 m_terminalType = terminalType; |
99 | 106 |
100 // Construct the aggregator. | 107 // Construct the aggregator. |
101 ConstructAggregator (); | 108 ConstructAggregator (); |
102 } | 109 } |
103 | 110 |
111 void· | |
112 GnuplotHelper::SetTerminalType (const std::string &terminalType)· | |
113 { | |
114 m_terminalType = terminalType; | |
115 } | |
116 | |
117 void· | |
118 GnuplotHelper::SetScalingFactor (double scalingFactor) | |
119 { | |
120 m_scalingFactor = scalingFactor; | |
121 } | |
122 | |
123 void | |
124 GnuplotHelper::SetCollectorType (std::string collectorType, | |
125 std::string n0, const AttributeValue &v0, | |
126 std::string n1, const AttributeValue &v1, | |
127 std::string n2, const AttributeValue &v2, | |
128 std::string n3, const AttributeValue &v3, | |
129 std::string n4, const AttributeValue &v4, | |
130 std::string n5, const AttributeValue &v5, | |
131 std::string n6, const AttributeValue &v6, | |
132 std::string n7, const AttributeValue &v7) | |
133 { | |
134 ObjectFactory factory; | |
135 factory.SetTypeId (collectorType); | |
136 factory.Set (n0, v0); | |
137 factory.Set (n1, v1); | |
138 factory.Set (n2, v2); | |
139 factory.Set (n3, v3); | |
140 factory.Set (n4, v4); | |
141 factory.Set (n5, v5); | |
142 factory.Set (n6, v6); | |
143 factory.Set (n7, v7); | |
144 m_collectorFactory = factory; | |
145 } | |
146 | |
147 void | |
148 GnuplotHelper::SetKeyLocation(enum GnuplotAggregator::KeyLocation keyLocation) | |
149 { | |
150 m_keyLocation = keyLocation; | |
151 } | |
152 | |
104 void | 153 void |
105 GnuplotHelper::PlotProbe (const std::string &typeId, | 154 GnuplotHelper::PlotProbe (const std::string &typeId, |
106 const std::string &path, | 155 const std::string &path, |
107 const std::string &probeTraceSource, | 156 const std::string &probeTraceSource, |
108 const std::string &title, | 157 const std::string &title, |
109 enum GnuplotAggregator::KeyLocation keyLocation) | 158 enum GnuplotAggregator::KeyLocation keyLocation) |
110 { | 159 { |
111 NS_LOG_FUNCTION (this << typeId << path << probeTraceSource << title << keyLoc ation); | 160 NS_LOG_FUNCTION (this << typeId << path << probeTraceSource << title << keyLoc ation); |
112 | 161 |
113 // Get a pointer to the aggregator. | 162 if (!m_aggregator) |
114 Ptr<GnuplotAggregator> aggregator = GetAggregator (); | 163 { |
164 ConstructAggregator (); | |
165 } | |
115 | 166 |
116 // Add a subtitle to the title to show the trace source's path. | 167 // Add a subtitle to the title to show the trace source's path. |
117 aggregator->SetTitle ( m_title + " \\n\\nTrace Source Path: " + path); | 168 m_aggregator->SetTitle ( m_title + " \\n\\nTrace Source Path: " + path); |
118 | 169 |
119 // Set the default dataset plotting style for the values. | 170 // Set the default dataset plotting style for the values. |
120 aggregator->Set2dDatasetDefaultStyle (Gnuplot2dDataset::LINES_POINTS); | 171 m_aggregator->Set2dDatasetDefaultStyle (Gnuplot2dDataset::LINES_POINTS); |
121 | 172 |
122 // Set the location of the key in the plot. | 173 // Set the location of the key in the plot. |
123 aggregator->SetKeyLocation (keyLocation); | 174 m_aggregator->SetKeyLocation (keyLocation); |
124 | 175 |
125 std::string pathWithoutLastToken; | 176 std::string pathWithoutLastToken; |
126 std::string lastToken; | 177 std::string lastToken; |
127 | 178 |
128 // See if the path has any wildcards. | 179 // See if the path has any wildcards. |
129 bool pathHasNoWildcards = path.find ("*") == std::string::npos; | 180 bool pathHasNoWildcards = path.find ("*") == std::string::npos; |
130 | 181 |
131 // Remove the last token from the path; this should correspond to the· | 182 // Remove the last token from the path; this should correspond to the· |
132 // trace source attribute. | 183 // trace source attribute. |
133 size_t lastSlash = path.find_last_of ("/"); | 184 size_t lastSlash = path.find_last_of ("/"); |
(...skipping 21 matching lines...) Expand all Loading... | |
155 // This is used to make the probe's context be unique. | 206 // This is used to make the probe's context be unique. |
156 std::string matchIdentifier; | 207 std::string matchIdentifier; |
157 | 208 |
158 // Hook one or more probes and the aggregator together. | 209 // Hook one or more probes and the aggregator together. |
159 if (matchCount == 1 && pathHasNoWildcards) | 210 if (matchCount == 1 && pathHasNoWildcards) |
160 { | 211 { |
161 // Connect the probe to the aggregator only once because there | 212 // Connect the probe to the aggregator only once because there |
162 // is only one matching config path. There is no need to find | 213 // is only one matching config path. There is no need to find |
163 // the wildcard matches because the passed in path has none. | 214 // the wildcard matches because the passed in path has none. |
164 matchIdentifier = "0"; | 215 matchIdentifier = "0"; |
165 ConnectProbeToAggregator (typeId, | 216 CreateDataCollectionChain (typeId, |
166 matchIdentifier, | 217 matchIdentifier, |
167 path, | 218 path, |
168 probeTraceSource, | 219 probeTraceSource, |
169 title); | 220 title); |
170 } | 221 } |
171 else if (matchCount > 0) | 222 else if (matchCount > 0) |
172 { | 223 { |
173 // Handle all of the matches if there are more than one. | 224 // Handle all of the matches if there are more than one. |
174 for (uint32_t i = 0; i < matchCount; i++) | 225 for (uint32_t i = 0; i < matchCount; i++) |
175 { | 226 { |
176 // Set the match identifier. | 227 // Set the match identifier. |
177 std::ostringstream matchIdentifierStream; | 228 std::ostringstream matchIdentifierStream; |
178 matchIdentifierStream << i; | 229 matchIdentifierStream << i; |
179 matchIdentifier = matchIdentifierStream.str (); | 230 matchIdentifier = matchIdentifierStream.str (); |
180 | 231 |
181 // Construct the matched path and get the matches for each | 232 // Construct the matched path and get the matches for each |
182 // of the wildcards. | 233 // of the wildcards. |
183 std::string wildcardSeparator = " "; | 234 std::string wildcardSeparator = " "; |
184 std::string matchedPath = matches.GetMatchedPath (i) + lastToken; | 235 std::string matchedPath = matches.GetMatchedPath (i) + lastToken; |
185 std::string wildcardMatches = GetWildcardMatches (path, | 236 std::string wildcardMatches = GetWildcardMatches (path, |
186 matchedPath, | 237 matchedPath, |
187 wildcardSeparator); | 238 wildcardSeparator); |
188 | 239 |
189 // Connect the probe to the aggregator for this match. | 240 // Connect the probe to the aggregator for this match. |
190 ConnectProbeToAggregator (typeId, | 241 CreateDataCollectionChain (typeId, |
191 matchIdentifier, | 242 matchIdentifier, |
192 matchedPath, | 243 matchedPath, |
193 probeTraceSource, | 244 probeTraceSource, |
194 title + "-" + wildcardMatches); | 245 title + "-" + wildcardMatches); |
195 } | 246 } |
196 } | 247 } |
197 else | 248 else |
198 { | 249 { |
199 // There is a problem if there are no matching config paths. | 250 // There is a problem if there are no matching config paths. |
200 NS_FATAL_ERROR ("Lookup of " << path << " got no matches"); | 251 NS_FATAL_ERROR ("Lookup of " << path << " got no matches"); |
201 } | 252 } |
202 } | 253 } |
203 | 254 |
204 void | 255 void |
205 GnuplotHelper::AddProbe (const std::string &typeId, | 256 GnuplotHelper::AddProbe (const std::string &typeId, |
257 const std::string &path, | |
258 const std::string &probeTraceSource, | |
259 const std::string &dataSeriesName) | |
260 { | |
261 NS_LOG_FUNCTION (this << typeId << path << probeTraceSource << | |
262 dataSeriesName); | |
263 | |
264 if (!m_aggregator) | |
265 { | |
266 ConstructAggregator (); | |
267 } | |
268 | |
269 // Add a subtitle to the title to show the trace source's path. | |
270 m_aggregator->SetTitle ( m_title + " \\n\\nTrace Source Path: " + path); | |
271 | |
272 // Set the default dataset plotting style for the values. | |
273 m_aggregator->Set2dDatasetDefaultStyle (Gnuplot2dDataset::LINES_POINTS); | |
274 | |
275 // Set the location of the key in the plot. | |
276 m_aggregator->SetKeyLocation (m_keyLocation); | |
277 | |
278 std::string pathWithoutLastToken; | |
279 std::string lastToken; | |
280 | |
281 // See if the path has any wildcards. | |
282 bool pathHasNoWildcards = path.find ("*") == std::string::npos; | |
283 | |
284 // Remove the last token from the path; this should correspond to the· | |
285 // trace source attribute. | |
286 size_t lastSlash = path.find_last_of ("/"); | |
287 if (lastSlash == std::string::npos) | |
288 { | |
289 pathWithoutLastToken = path; | |
290 lastToken = ""; | |
291 } | |
292 else | |
293 { | |
294 // Chop off up to last token. | |
295 pathWithoutLastToken = path.substr (0, lastSlash); | |
296 | |
297 // Save the last token without the last slash. | |
298 lastToken = path.substr (lastSlash + 1, std::string::npos); | |
299 } | |
300 | |
301 // See if there are any matches for the probe's path with the last | |
302 // token removed; this corresponds to the traced object itself. | |
303 NS_LOG_DEBUG ("Searching config database for trace source " << path); | |
304 Config::MatchContainer matches = Config::LookupMatches (pathWithoutLastToken); | |
305 uint32_t matchCount = matches.GetN (); | |
306 NS_LOG_DEBUG ("Found " << matchCount << " matches for trace source " << path); | |
307 | |
308 // This is used to make the probe's context be unique. | |
309 std::string matchIdentifier; | |
310 | |
311 // Hook one or more probes and the aggregator together. | |
312 if (matchCount == 1 && pathHasNoWildcards) | |
313 { | |
314 // Connect the probe to the aggregator only once because there | |
315 // is only one matching config path. There is no need to find | |
316 // the wildcard matches because the passed in path has none. | |
317 matchIdentifier = "0"; | |
318 CreateDataCollectionChain (typeId, | |
319 matchIdentifier, | |
320 path, | |
321 probeTraceSource, | |
322 dataSeriesName); | |
323 //title); | |
324 } | |
325 else if (matchCount > 0) | |
326 { | |
327 // Handle all of the matches if there are more than one. | |
328 for (uint32_t i = 0; i < matchCount; i++) | |
329 { | |
330 // Set the match identifier. | |
331 std::ostringstream matchIdentifierStream; | |
332 matchIdentifierStream << i; | |
333 matchIdentifier = matchIdentifierStream.str (); | |
334 | |
335 // Construct the matched path and get the matches for each | |
336 // of the wildcards. | |
337 std::string wildcardSeparator = " "; | |
338 std::string matchedPath = matches.GetMatchedPath (i) + lastToken; | |
339 std::string wildcardMatches = GetWildcardMatches (path, | |
340 matchedPath, | |
341 wildcardSeparator); | |
342 | |
343 // Connect the probe to the aggregator for this match. | |
344 CreateDataCollectionChain (typeId, | |
345 matchIdentifier, | |
346 matchedPath, | |
347 probeTraceSource, | |
348 dataSeriesName + "-" + wildcardMatches); | |
349 } | |
350 } | |
351 else | |
352 { | |
353 // There is a problem if there are no matching config paths. | |
354 NS_FATAL_ERROR ("Lookup of " << path << " got no matches"); | |
355 } | |
356 | |
357 } | |
358 | |
359 void | |
360 GnuplotHelper::AddProbeToMap (const std::string &typeId, | |
206 const std::string &probeName, | 361 const std::string &probeName, |
207 const std::string &path) | 362 const std::string &path) |
208 { | 363 { |
209 NS_LOG_FUNCTION (this << typeId << probeName << path); | 364 NS_LOG_FUNCTION (this << typeId << probeName << path); |
210 | 365 |
211 // See if this probe had already been added. | 366 // See if this probe had already been added. |
212 if (m_probeMap.count (probeName) > 0) | 367 if (m_probeMap.count (probeName) > 0) |
213 { | 368 { |
214 NS_ABORT_MSG ("That probe has already been added"); | 369 NS_ABORT_MSG ("That probe has already been added"); |
215 } | 370 } |
(...skipping 14 matching lines...) Expand all Loading... | |
230 // Set the path. Note that no return value is checked here. | 385 // Set the path. Note that no return value is checked here. |
231 probe->ConnectByPath (path); | 386 probe->ConnectByPath (path); |
232 | 387 |
233 // Enable logging of data for the probe. | 388 // Enable logging of data for the probe. |
234 probe->Enable (); | 389 probe->Enable (); |
235 | 390 |
236 // Add this probe to the map so that its values can be used. | 391 // Add this probe to the map so that its values can be used. |
237 m_probeMap[probeName] = std::make_pair (probe, typeId); | 392 m_probeMap[probeName] = std::make_pair (probe, typeId); |
238 } | 393 } |
239 | 394 |
395 | |
240 void | 396 void |
241 GnuplotHelper::AddTimeSeriesAdaptor (const std::string &adaptorName) | 397 GnuplotHelper::AddCollector (const std::string &collectorName) |
242 { | 398 { |
243 NS_LOG_FUNCTION (this << adaptorName); | 399 NS_LOG_FUNCTION (this << collectorName); |
244 | 400 |
245 // See if this time series adaptor had already been added. | 401 Ptr<Collector> collector = DynamicCast<Collector> (m_collectorFactory.Create ( )); |
246 if (m_timeSeriesAdaptorMap.count (adaptorName) > 0) | 402 collector->Enable (); |
403 // See if this collector had already been added. | |
404 | |
405 if (m_collectorMap.count (collectorName) > 0) | |
247 { | 406 { |
248 NS_ABORT_MSG ("That time series adaptor has already been added"); | 407 NS_ABORT_MSG ("That Collector has already been added"); |
249 } | 408 } |
250 | 409 // Add this collector to the map so that it can be used. |
buherman
2015/06/29 08:53:53
A little bit too much indenting.
| |
251 // Create the time series adaptor. | 410 m_collectorMap[collectorName] = collector; |
252 Ptr<TimeSeriesAdaptor> timeSeriesAdaptor = CreateObject<TimeSeriesAdaptor> (); | |
253 | |
254 // Enable logging of data for the time series adaptor. | |
255 timeSeriesAdaptor->Enable (); | |
256 | |
257 // Add this time series adaptor to the map so that can be used. | |
258 m_timeSeriesAdaptorMap[adaptorName] = timeSeriesAdaptor; | |
259 } | 411 } |
260 | 412 |
261 Ptr<Probe> | 413 Ptr<Probe> |
262 GnuplotHelper::GetProbe (std::string probeName) const | 414 GnuplotHelper::GetProbe (std::string probeName) const |
263 { | 415 { |
264 // Look for the probe. | 416 // Look for the probe. |
265 std::map<std::string, std::pair <Ptr<Probe>, std::string> >::const_iterator ma pIterator = m_probeMap.find (probeName); | 417 std::map<std::string, std::pair <Ptr<Probe>, std::string> >::const_iterator ma pIterator = m_probeMap.find (probeName); |
266 | 418 |
267 // Return the probe if it has been added. | 419 // Return the probe if it has been added. |
268 if (mapIterator != m_probeMap.end ()) | 420 if (mapIterator != m_probeMap.end ()) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
300 // Set the aggregator's properties. | 452 // Set the aggregator's properties. |
301 m_aggregator->SetTerminal (m_terminalType); | 453 m_aggregator->SetTerminal (m_terminalType); |
302 m_aggregator->SetTitle (m_title); | 454 m_aggregator->SetTitle (m_title); |
303 m_aggregator->SetLegend (m_xLegend, m_yLegend); | 455 m_aggregator->SetLegend (m_xLegend, m_yLegend); |
304 | 456 |
305 // Enable logging of data for the aggregator. | 457 // Enable logging of data for the aggregator. |
306 m_aggregator->Enable (); | 458 m_aggregator->Enable (); |
307 } | 459 } |
308 | 460 |
309 void | 461 void |
310 GnuplotHelper::ConnectProbeToAggregator (const std::string &typeId, | 462 GnuplotHelper::CreateDataCollectionChain (const std::string &typeId, |
311 const std::string &matchIdentifier, | 463 const std::string &matchIdentifier, |
312 const std::string &path, | 464 const std::string &path, |
313 const std::string &probeTraceSource, | 465 const std::string &probeTraceSource, |
314 const std::string &title) | 466 const std::string &title) |
315 { | 467 { |
316 NS_LOG_FUNCTION (this << typeId << matchIdentifier << path << probeTraceSource | 468 NS_LOG_FUNCTION (this << typeId << matchIdentifier << path << probeTraceSource |
317 << title); | 469 << title); |
318 | 470 |
319 Ptr<GnuplotAggregator> aggregator = GetAggregator (); | 471 if (!m_aggregator) |
472 { | |
473 ConstructAggregator (); | |
474 } | |
320 | 475 |
321 // Increment the total number of plot probes that have been created. | 476 // Increment the total number of plot probes that have been created. |
322 m_plotProbeCount++; | 477 m_plotProbeCount++; |
323 | 478 |
324 // Create a unique name for this probe. | 479 // Create a unique name for this probe. |
325 std::ostringstream probeNameStream; | 480 std::ostringstream probeNameStream; |
326 probeNameStream << "PlotProbe-" << m_plotProbeCount; | 481 probeNameStream << "PlotProbe-" << m_plotProbeCount; |
327 std::string probeName = probeNameStream.str (); | 482 std::string probeName = probeNameStream.str (); |
328 | 483 |
329 // Create a unique dataset context string for this probe. | 484 // Create a unique dataset context string for this probe. |
330 std::string probeContext = probeName | 485 std::string probeContext = probeName |
331 + "/" + matchIdentifier + "/" + probeTraceSource; | 486 + "/" + matchIdentifier + "/" + probeTraceSource; |
332 | 487 |
333 // Add the probe to the map of probes, which will keep the probe in | 488 // Add the probe to the map of probes, which will keep the probe in |
334 // memory after this function ends. | 489 // memory after this function ends. |
335 AddProbe (typeId, probeName, path); | 490 AddProbeToMap (typeId, probeName, path); |
336 | 491 |
337 // Because the callbacks to the probes' trace sources don't use the | 492 // Add an Collector corresponding to the probe (this will also create |
338 // probe's context, a unique adaptor needs to be created for each | 493 // a ScalingCollector corresponding to this trace source) |
339 // probe context so that information is not lost. | 494 AddCollector (probeContext); |
340 AddTimeSeriesAdaptor (probeContext); | |
341 | 495 |
342 // Connect the probe to the adaptor. | 496 ConnectProbeToCollector(probeTraceSource, probeName, probeContext); |
497 | |
498 if (m_scalingFactor != 1.00) { | |
499 AddScalingCollector (probeContext); | |
500 } | |
501 | |
502 | |
503 ConnectCollectorToAggregator(probeContext); | |
504 // Add the dataset to the plot. | |
505 m_aggregator->Add2dDataset (probeContext, title); | |
506 } | |
507 | |
508 | |
509 void | |
510 GnuplotHelper::AddScalingCollector(const std::string &collectorName) | |
511 { | |
512 // Create the ScalingCollector | |
513 Ptr<ScalingCollector> scalingCollector = CreateObject<ScalingCollector> (); | |
514 | |
515 // Set the scaling factor of the ScalingFactor object | |
516 scalingCollector->SetAttribute ("ScalingFactor", DoubleValue (m_scalingFacto r)); | |
517 | |
518 // Enable logging of data for the ScalingCollector | |
519 scalingCollector->Enable(); | |
520 | |
521 // Add this collector to the map so that it can be used. | |
522 m_scalingCollectorMap[collectorName] = scalingCollector; | |
523 } | |
buherman
2015/06/29 08:53:53
Several lines above this are indented too long.
| |
524 | |
525 void | |
526 GnuplotHelper::ConnectProbeToCollector(const std::string probeTraceSource, | |
527 const std::string probeName,· | |
528 const std::string probeContext) | |
529 { | |
530 // Connect the probe to the collector. | |
343 if (m_probeMap[probeName].second == "ns3::DoubleProbe") | 531 if (m_probeMap[probeName].second == "ns3::DoubleProbe") |
344 { | 532 { |
345 m_probeMap[probeName].first->TraceConnectWithoutContext | 533 m_probeMap[probeName].first->TraceConnectWithoutContext |
346 (probeTraceSource, | 534 (probeTraceSource, |
347 MakeCallback (&TimeSeriesAdaptor::TraceSinkDouble, | 535 MakeCallback (&Collector::TraceSinkDouble, |
348 m_timeSeriesAdaptorMap[probeContext])); | 536 m_collectorMap[probeContext])); |
349 } | 537 } |
350 else if (m_probeMap[probeName].second == "ns3::BooleanProbe") | 538 else if (m_probeMap[probeName].second == "ns3::BooleanProbe") |
351 { | 539 { |
352 m_probeMap[probeName].first->TraceConnectWithoutContext | 540 m_probeMap[probeName].first->TraceConnectWithoutContext |
353 (probeTraceSource, | 541 (probeTraceSource, |
354 MakeCallback (&TimeSeriesAdaptor::TraceSinkBoolean, | 542 MakeCallback (&Collector::TraceSinkBoolean, |
355 m_timeSeriesAdaptorMap[probeContext])); | 543 m_collectorMap[probeContext])); |
356 } | 544 } |
357 else if (m_probeMap[probeName].second == "ns3::PacketProbe") | 545 else if (m_probeMap[probeName].second == "ns3::PacketProbe") |
358 { | 546 { |
359 m_probeMap[probeName].first->TraceConnectWithoutContext | 547 m_probeMap[probeName].first->TraceConnectWithoutContext |
360 (probeTraceSource, | 548 (probeTraceSource, |
361 MakeCallback (&TimeSeriesAdaptor::TraceSinkUinteger32, | 549 MakeCallback (&Collector::TraceSinkUinteger32, |
362 m_timeSeriesAdaptorMap[probeContext])); | 550 m_collectorMap[probeContext])); |
363 } | 551 } |
364 else if (m_probeMap[probeName].second == "ns3::ApplicationPacketProbe") | 552 else if (m_probeMap[probeName].second == "ns3::ApplicationPacketProbe") |
365 { | 553 { |
366 m_probeMap[probeName].first->TraceConnectWithoutContext | 554 m_probeMap[probeName].first->TraceConnectWithoutContext |
367 (probeTraceSource, | 555 (probeTraceSource, |
368 MakeCallback (&TimeSeriesAdaptor::TraceSinkUinteger32, | 556 MakeCallback (&Collector::TraceSinkUinteger32, |
369 m_timeSeriesAdaptorMap[probeContext])); | 557 m_collectorMap[probeContext])); |
370 } | 558 } |
371 else if (m_probeMap[probeName].second == "ns3::Ipv4PacketProbe") | 559 else if (m_probeMap[probeName].second == "ns3::Ipv4PacketProbe") |
372 { | 560 { |
373 m_probeMap[probeName].first->TraceConnectWithoutContext | 561 m_probeMap[probeName].first->TraceConnectWithoutContext |
374 (probeTraceSource, | 562 (probeTraceSource, |
375 MakeCallback (&TimeSeriesAdaptor::TraceSinkUinteger32, | 563 MakeCallback (&Collector::TraceSinkUinteger32, |
376 m_timeSeriesAdaptorMap[probeContext])); | 564 m_collectorMap[probeContext])); |
377 } | 565 } |
378 else if (m_probeMap[probeName].second == "ns3::Ipv6PacketProbe") | 566 else if (m_probeMap[probeName].second == "ns3::Ipv6PacketProbe") |
379 { | 567 { |
380 m_probeMap[probeName].first->TraceConnectWithoutContext | 568 m_probeMap[probeName].first->TraceConnectWithoutContext |
381 (probeTraceSource, | 569 (probeTraceSource, |
382 MakeCallback (&TimeSeriesAdaptor::TraceSinkUinteger32, | 570 MakeCallback (&Collector::TraceSinkUinteger32, |
383 m_timeSeriesAdaptorMap[probeContext])); | 571 m_collectorMap[probeContext])); |
384 } | 572 } |
385 else if (m_probeMap[probeName].second == "ns3::Uinteger8Probe") | 573 else if (m_probeMap[probeName].second == "ns3::Uinteger8Probe") |
386 { | 574 { |
387 m_probeMap[probeName].first->TraceConnectWithoutContext | 575 m_probeMap[probeName].first->TraceConnectWithoutContext |
388 (probeTraceSource, | 576 (probeTraceSource, |
389 MakeCallback (&TimeSeriesAdaptor::TraceSinkUinteger8, | 577 MakeCallback (&Collector::TraceSinkUinteger8, |
390 m_timeSeriesAdaptorMap[probeContext])); | 578 m_collectorMap[probeContext])); |
391 } | 579 } |
392 else if (m_probeMap[probeName].second == "ns3::Uinteger16Probe") | 580 else if (m_probeMap[probeName].second == "ns3::Uinteger16Probe") |
393 { | 581 { |
394 m_probeMap[probeName].first->TraceConnectWithoutContext | 582 m_probeMap[probeName].first->TraceConnectWithoutContext |
395 (probeTraceSource, | 583 (probeTraceSource, |
396 MakeCallback (&TimeSeriesAdaptor::TraceSinkUinteger16, | 584 MakeCallback (&Collector::TraceSinkUinteger16, |
397 m_timeSeriesAdaptorMap[probeContext])); | 585 m_collectorMap[probeContext])); |
398 } | 586 } |
399 else if (m_probeMap[probeName].second == "ns3::Uinteger32Probe") | 587 else if (m_probeMap[probeName].second == "ns3::Uinteger32Probe") |
400 { | 588 { |
401 m_probeMap[probeName].first->TraceConnectWithoutContext | 589 m_probeMap[probeName].first->TraceConnectWithoutContext |
402 (probeTraceSource, | 590 (probeTraceSource, |
403 MakeCallback (&TimeSeriesAdaptor::TraceSinkUinteger32, | 591 MakeCallback (&Collector::TraceSinkUinteger32, |
404 m_timeSeriesAdaptorMap[probeContext])); | 592 m_collectorMap[probeContext])); |
405 } | 593 } |
406 else if (m_probeMap[probeName].second == "ns3::TimeProbe") | 594 else if (m_probeMap[probeName].second == "ns3::TimeProbe") |
407 { | 595 { |
408 m_probeMap[probeName].first->TraceConnectWithoutContext | 596 m_probeMap[probeName].first->TraceConnectWithoutContext |
409 (probeTraceSource, | 597 (probeTraceSource, |
410 MakeCallback (&TimeSeriesAdaptor::TraceSinkDouble, | 598 MakeCallback (&Collector::TraceSinkTime, |
411 m_timeSeriesAdaptorMap[probeContext])); | 599 m_collectorMap[probeContext])); |
412 } | 600 } |
413 else | 601 else |
414 { | 602 { |
415 NS_FATAL_ERROR ("Unknown probe type " << m_probeMap[probeName].second << " ; need to add support in the helper for this"); | 603 NS_FATAL_ERROR ("Unknown probe type " << m_probeMap[probeName].second << " ; need to add support in the helper for this"); |
416 } | 604 } |
417 | 605 |
418 // Connect the adaptor to the aggregator. | 606 } |
419 std::string adaptorTraceSource = "Output"; | |
420 m_timeSeriesAdaptorMap[probeContext]->TraceConnect | |
421 (adaptorTraceSource, | |
422 probeContext, | |
423 MakeCallback (&GnuplotAggregator::Write2d, aggregator)); | |
424 | 607 |
425 // Add the dataset to the plot. | 608 void |
426 aggregator->Add2dDataset (probeContext, title); | 609 GnuplotHelper::ConnectCollectorToAggregator(const std::string probeContext) |
610 { | |
611 if (m_scalingFactor != 1.00) { | |
612 // if there is a ScalingCollector object, then connect· | |
613 // the collector to the ScalingCollector object and then | |
614 // the ScalingCollector object to the aggregator | |
buherman
2015/06/29 08:53:53
IMO, one of the use cases of ScalingCollector is t
| |
615 m_collectorMap[probeContext]->TraceConnectWithoutContext | |
616 ("Output", | |
617 MakeCallback(&ScalingCollector::TraceSinkDouble, | |
618 m_scalingCollectorMap[probeContext])); | |
619 | |
620 // Connect the ScalingCollector to the aggregator. | |
621 m_scalingCollectorMap[probeContext]->TraceConnect | |
622 ("Output", | |
623 probeContext, | |
624 MakeCallback (&GnuplotAggregator::Write2d, m_aggregator)); | |
625 } else { | |
626 // Otherwise connect the collector directly to the aggregator | |
627 m_collectorMap[probeContext]->TraceConnect | |
628 ("Output", | |
629 probeContext, | |
630 MakeCallback (&GnuplotAggregator::Write2d, m_aggregator)); | |
631 } | |
buherman
2015/06/29 08:53:53
The position of curly braces in the above block is
| |
427 } | 632 } |
428 | 633 |
429 } // namespace ns3 | 634 } // namespace ns3 |
430 | 635 |
OLD | NEW |