Loading...
Searching...
No Matches
satellite-stats-antenna-gain-helper.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2018 CNES
4 *
5 * 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 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * 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 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Mathias Ettinger <mettinger@toulouse.viveris.com>
19 */
20
22
23#include "ns3/boolean.h"
24#include "ns3/callback.h"
25#include "ns3/data-collection-object.h"
26#include "ns3/distribution-collector.h"
27#include "ns3/enum.h"
28#include "ns3/log.h"
29#include "ns3/magister-gnuplot-aggregator.h"
30#include "ns3/multi-file-aggregator.h"
31#include "ns3/node-container.h"
32#include "ns3/nstime.h"
33#include "ns3/probe.h"
34#include "ns3/satellite-handover-module.h"
35#include "ns3/satellite-helper.h"
36#include "ns3/satellite-topology.h"
37#include "ns3/scalar-collector.h"
38#include "ns3/singleton.h"
39#include "ns3/string.h"
40#include "ns3/unit-conversion-collector.h"
41
42#include <sstream>
43#include <string>
44
45NS_LOG_COMPONENT_DEFINE("SatStatsAntennaGainHelper");
46
47namespace ns3
48{
49
50NS_OBJECT_ENSURE_REGISTERED(SatStatsAntennaGainHelper);
51
53 : SatStatsHelper(satHelper),
54 m_averagingMode(false)
55{
56 NS_LOG_FUNCTION(this << satHelper);
57}
58
63
64TypeId
66{
67 static TypeId tid =
68 TypeId("ns3::SatStatsAntennaGainHelper")
69 .SetParent<SatStatsHelper>()
70 .AddAttribute("AveragingMode",
71 "If true, all samples will be averaged before passed to aggregator. "
72 "Only affects histogram, PDF, and CDF output types.",
73 BooleanValue(false),
76 MakeBooleanChecker());
77 return tid;
78}
79
80void
82{
83 NS_LOG_FUNCTION(this << averagingMode);
84 m_averagingMode = averagingMode;
85}
86
87bool
89{
90 NS_LOG_FUNCTION(this);
91 return m_averagingMode;
92}
93
94void
95SatStatsAntennaGainHelper::AntennaGainCallback(std::string identifier, double gain)
96{
97 std::stringstream ss(identifier);
98 uint32_t identifierNum;
99 if (!(ss >> identifierNum))
100 {
101 NS_FATAL_ERROR("Cannot convert '" << identifier << "' to number");
102 }
103 Ptr<DataCollectionObject> collector = m_terminalCollectors.Get(identifierNum);
104 NS_ASSERT_MSG(collector != nullptr,
105 "Unable to find collector with identifier " << identifierNum);
106
107 switch (GetOutputType())
108 {
111 Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
112 NS_ASSERT(c != nullptr);
113 c->TraceSinkDouble(0.0, gain);
114 break;
115 }
116
119 Ptr<UnitConversionCollector> c = collector->GetObject<UnitConversionCollector>();
120 NS_ASSERT(c != nullptr);
121 c->TraceSinkDouble(0.0, gain);
122 break;
123 }
124
131 if (m_averagingMode)
132 {
133 Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
134 NS_ASSERT(c != nullptr);
135 c->TraceSinkDouble(0.0, gain);
136 }
137 else
138 {
139 Ptr<DistributionCollector> c = collector->GetObject<DistributionCollector>();
140 NS_ASSERT(c != nullptr);
141 c->TraceSinkDouble(0.0, gain);
142 }
143 break;
144
145 default:
146 NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
147 << " is not a valid output type for this statistics.");
148 break;
149 }
150}
151
152void
154{
155 NS_LOG_FUNCTION(this);
156
157 switch (GetOutputType())
158 {
160 NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
161 << " is not a valid output type for this statistics.");
162 break;
163
165 // Setup aggregator.
166 m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
167 "OutputFileName",
168 StringValue(GetOutputFileName()),
169 "MultiFileMode",
170 BooleanValue(false),
171 "EnableContextPrinting",
172 BooleanValue(true),
173 "GeneralHeading",
174 StringValue(GetIdentifierHeading("gain_db")));
175
176 // Setup collectors.
177 m_terminalCollectors.SetType("ns3::ScalarCollector");
178 m_terminalCollectors.SetAttribute("InputDataType",
179 EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
180 m_terminalCollectors.SetAttribute(
181 "OutputType",
182 EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
184 m_terminalCollectors.ConnectToAggregator("Output",
186 &MultiFileAggregator::Write1d);
187 break;
188 }
189
191 // Setup aggregator.
192 m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
193 "OutputFileName",
194 StringValue(GetOutputFileName()),
195 "GeneralHeading",
196 StringValue(GetTimeHeading("gain_db")));
197
198 // Setup collectors.
199 m_terminalCollectors.SetType("ns3::UnitConversionCollector");
200 m_terminalCollectors.SetAttribute("ConversionType",
201 EnumValue(UnitConversionCollector::TRANSPARENT));
203 m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
205 &MultiFileAggregator::Write2d);
206 break;
207 }
208
212 if (m_averagingMode)
213 {
214 // Setup aggregator.
215 m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
216 "OutputFileName",
217 StringValue(GetOutputFileName()),
218 "MultiFileMode",
219 BooleanValue(false),
220 "EnableContextPrinting",
221 BooleanValue(false),
222 "GeneralHeading",
223 StringValue(GetDistributionHeading("gain_db")));
224 Ptr<MultiFileAggregator> fileAggregator =
225 m_aggregator->GetObject<MultiFileAggregator>();
226 NS_ASSERT(fileAggregator != nullptr);
227
228 // Setup the final-level collector.
229 m_averagingCollector = CreateObject<DistributionCollector>();
230 DistributionCollector::OutputType_t outputType =
231 DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
233 {
234 outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
235 }
237 {
238 outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
239 }
240 m_averagingCollector->SetOutputType(outputType);
241 m_averagingCollector->SetName("0");
242 m_averagingCollector->TraceConnect(
243 "Output",
244 "0",
245 MakeCallback(&MultiFileAggregator::Write2d, fileAggregator));
246 m_averagingCollector->TraceConnect(
247 "OutputString",
248 "0",
249 MakeCallback(&MultiFileAggregator::AddContextHeading, fileAggregator));
250 m_averagingCollector->TraceConnect(
251 "Warning",
252 "0",
253 MakeCallback(&MultiFileAggregator::EnableContextWarning, fileAggregator));
254
255 // Setup collectors.
256 m_terminalCollectors.SetType("ns3::ScalarCollector");
257 m_terminalCollectors.SetAttribute("InputDataType",
258 EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
259 m_terminalCollectors.SetAttribute(
260 "OutputType",
261 EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
263 Callback<void, double> callback =
264 MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
265 for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
266 it != m_terminalCollectors.End();
267 ++it)
268 {
269 it->second->TraceConnectWithoutContext("Output", callback);
270 }
271 }
272 else
273 {
274 // Setup aggregator.
275 m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
276 "OutputFileName",
277 StringValue(GetOutputFileName()),
278 "GeneralHeading",
279 StringValue(GetDistributionHeading("gain_db")));
280
281 // Setup collectors.
282 m_terminalCollectors.SetType("ns3::DistributionCollector");
283 DistributionCollector::OutputType_t outputType =
284 DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
286 {
287 outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
288 }
290 {
291 outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
292 }
293 m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
295 m_terminalCollectors.ConnectToAggregator("Output",
297 &MultiFileAggregator::Write2d);
298 m_terminalCollectors.ConnectToAggregator("OutputString",
300 &MultiFileAggregator::AddContextHeading);
301 m_terminalCollectors.ConnectToAggregator("Warning",
303 &MultiFileAggregator::EnableContextWarning);
304 }
305
306 break;
307 }
308
311 NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
312 << " is not a valid output type for this statistics.");
313 break;
314
316 // Setup aggregator.
317 m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
318 "OutputPath",
319 StringValue(GetOutputPath()),
320 "OutputFileName",
321 StringValue(GetName()));
322 Ptr<MagisterGnuplotAggregator> plotAggregator =
323 m_aggregator->GetObject<MagisterGnuplotAggregator>();
324 NS_ASSERT(plotAggregator != nullptr);
325 // plot->SetTitle ("");
326 plotAggregator->SetLegend("Time (in seconds)", "Antenna Gain (in dB)");
327 plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
328
329 // Setup collectors.
330 m_terminalCollectors.SetType("ns3::UnitConversionCollector");
331 m_terminalCollectors.SetAttribute("ConversionType",
332 EnumValue(UnitConversionCollector::TRANSPARENT));
334 for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
335 it != m_terminalCollectors.End();
336 ++it)
337 {
338 const std::string context = it->second->GetName();
339 plotAggregator->Add2dDataset(context, context);
340 }
341 m_terminalCollectors.ConnectToAggregator("OutputTimeValue",
343 &MagisterGnuplotAggregator::Write2d);
344 break;
345 }
346
350 if (m_averagingMode)
351 {
352 // Setup aggregator.
353 m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
354 "OutputPath",
355 StringValue(GetOutputPath()),
356 "OutputFileName",
357 StringValue(GetName()));
358 Ptr<MagisterGnuplotAggregator> plotAggregator =
359 m_aggregator->GetObject<MagisterGnuplotAggregator>();
360 NS_ASSERT(plotAggregator != nullptr);
361 // plot->SetTitle ("");
362 plotAggregator->SetLegend("Antenna gain (in dB)", "Frequency");
363 plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
364 plotAggregator->Add2dDataset(GetName(), GetName());
366
367 // Setup the final-level collector.
368 m_averagingCollector = CreateObject<DistributionCollector>();
369 DistributionCollector::OutputType_t outputType =
370 DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
372 {
373 outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
374 }
376 {
377 outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
378 }
379 m_averagingCollector->SetOutputType(outputType);
380 m_averagingCollector->SetName("0");
381 m_averagingCollector->TraceConnect(
382 "Output",
383 GetName(),
384 MakeCallback(&MagisterGnuplotAggregator::Write2d, plotAggregator));
386
387 // Setup collectors.
388 m_terminalCollectors.SetType("ns3::ScalarCollector");
389 m_terminalCollectors.SetAttribute("InputDataType",
390 EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
391 m_terminalCollectors.SetAttribute(
392 "OutputType",
393 EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE));
395 Callback<void, double> callback =
396 MakeCallback(&DistributionCollector::TraceSinkDouble1, m_averagingCollector);
397 for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
398 it != m_terminalCollectors.End();
399 ++it)
400 {
401 it->second->TraceConnectWithoutContext("Output", callback);
402 }
403 }
404 else
405 {
406 // Setup aggregator.
407 m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
408 "OutputPath",
409 StringValue(GetOutputPath()),
410 "OutputFileName",
411 StringValue(GetName()));
412 Ptr<MagisterGnuplotAggregator> plotAggregator =
413 m_aggregator->GetObject<MagisterGnuplotAggregator>();
414 NS_ASSERT(plotAggregator != nullptr);
415 // plot->SetTitle ("");
416 plotAggregator->SetLegend("Antenna gain (in dB)", "Frequency");
417 plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
418
419 // Setup collectors.
420 m_terminalCollectors.SetType("ns3::DistributionCollector");
421 DistributionCollector::OutputType_t outputType =
422 DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
424 {
425 outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
426 }
428 {
429 outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
430 }
431 m_terminalCollectors.SetAttribute("OutputType", EnumValue(outputType));
433 for (CollectorMap::Iterator it = m_terminalCollectors.Begin();
434 it != m_terminalCollectors.End();
435 ++it)
436 {
437 const std::string context = it->second->GetName();
438 plotAggregator->Add2dDataset(context, context);
439 }
440 m_terminalCollectors.ConnectToAggregator("Output",
442 &MagisterGnuplotAggregator::Write2d);
443 }
444
445 break;
446 }
447
448 default:
449 NS_FATAL_ERROR("SatStatsDelayHelper - Invalid output type");
450 break;
451 }
452
453 // Setup probes and connect them to the collectors.
455}
456
457void
459{
460 NS_LOG_FUNCTION(this);
461
462 Callback<void, std::string, double> callback =
464
465 NodeContainer utUsers = Singleton<SatTopology>::Get()->GetUtNodes();
466 for (NodeContainer::Iterator it = utUsers.Begin(); it != utUsers.End(); ++it)
467 {
468 Ptr<SatHandoverModule> hoModule = (*it)->GetObject<SatHandoverModule>();
469 if (!hoModule)
470 {
471 NS_LOG_INFO("UT " << *it << " does not check for antenna gain, bailing out.");
472 }
473 else
474 {
475 std::ostringstream oss;
476 oss << GetIdentifierForUt(*it);
477
478 if (hoModule->TraceConnect("AntennaGainTrace", oss.str(), callback))
479 {
480 NS_LOG_INFO(this << " successfully connected with UT " << *it);
481 }
482 else
483 {
484 NS_LOG_WARN(this << " unable to connect to UT " << *it);
485 }
486 }
487 }
488}
489
490} // namespace ns3
Base class for antenna gain statistics helpers.
void AntennaGainCallback(std::string identifier, double gain)
Receive inputs from trace sources.
SatStatsAntennaGainHelper(Ptr< const SatHelper > satHelper)
void InstallProbes()
Set up several probes or other means of listeners and connect them to the collectors.
static TypeId GetTypeId()
inherited from ObjectBase base class
CollectorMap m_terminalCollectors
Maintains a list of collectors created by this helper.
Ptr< DataCollectionObject > m_aggregator
The aggregator created by this helper.
Ptr< DistributionCollector > m_averagingCollector
The final collector utilized in averaged output (histogram, PDF, and CDF).
void DoInstall()
Install the probes, collectors, and aggregators necessary to produce the statistics output.
static std::string GetOutputTypeName(OutputType_t outputType)
SatStatsHelper(Ptr< const SatHelper > satHelper)
Creates a new helper instance.
virtual std::string GetIdentifierHeading(std::string dataLabel) const
virtual std::string GetOutputPath() const
Ptr< DataCollectionObject > CreateAggregator(std::string aggregatorTypeId, std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue())
Create the aggregator according to the output type.
virtual std::string GetOutputFileName() const
Compute the path and file name where statistics output should be written to.
uint32_t CreateCollectorPerIdentifier(CollectorMap &collectorMap) const
Create one collector instance for each identifier in the simulation.
OutputType_t GetOutputType() const
uint32_t GetIdentifierForUt(Ptr< Node > utNode) const
std::string GetName() const
virtual std::string GetTimeHeading(std::string dataLabel) const
virtual std::string GetDistributionHeading(std::string dataLabel) const
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.