A Discrete-Event Network Simulator
API
multi-model-spectrum-channel.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 CTTC
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: Nicola Baldo <nbaldo@cttc.es>
19  */
20 
21 #include <ns3/object.h>
22 #include <ns3/simulator.h>
23 #include <ns3/log.h>
24 #include <ns3/packet.h>
25 #include <ns3/packet-burst.h>
26 #include <ns3/net-device.h>
27 #include <ns3/node.h>
28 #include <ns3/double.h>
29 #include <ns3/mobility-model.h>
30 #include <ns3/spectrum-phy.h>
31 #include <ns3/spectrum-converter.h>
32 #include <ns3/spectrum-propagation-loss-model.h>
33 #include <ns3/propagation-loss-model.h>
34 #include <ns3/propagation-delay-model.h>
35 #include <ns3/antenna-model.h>
36 #include <ns3/angles.h>
37 #include <iostream>
38 #include <utility>
40 
41 
42 namespace ns3 {
43 
44 NS_LOG_COMPONENT_DEFINE ("MultiModelSpectrumChannel");
45 
46 NS_OBJECT_ENSURE_REGISTERED (MultiModelSpectrumChannel);
47 
48 
55 std::ostream& operator<< (std::ostream& lhs, TxSpectrumModelInfoMap_t& rhs)
56 {
57  for (TxSpectrumModelInfoMap_t::iterator it = rhs.begin ();
58  it != rhs.end ();
59  ++it)
60  {
61  SpectrumConverterMap_t::iterator jt;
62  for (jt = it->second.m_spectrumConverterMap.begin ();
63  jt != it->second.m_spectrumConverterMap.end ();
64  ++jt)
65  {
66  lhs << "(" << it->first << "," << jt->first << ") ";
67  }
68  }
69  return lhs;
70 }
71 
73  : m_txSpectrumModel (txSpectrumModel)
74 {
75 }
76 
77 
79  : m_rxSpectrumModel (rxSpectrumModel)
80 {
81 }
82 
83 
85 {
86  NS_LOG_FUNCTION (this);
87 }
88 
89 void
91 {
92  NS_LOG_FUNCTION (this);
93  m_propagationDelay = 0;
94  m_propagationLoss = 0;
95  m_spectrumPropagationLoss = 0;
96  m_txSpectrumModelInfoMap.clear ();
97  m_rxSpectrumModelInfoMap.clear ();
99 }
100 
101 TypeId
103 {
104  static TypeId tid = TypeId ("ns3::MultiModelSpectrumChannel")
106  .SetGroupName ("Spectrum")
107  .AddConstructor<MultiModelSpectrumChannel> ()
108  .AddAttribute ("MaxLossDb",
109  "If a single-frequency PropagationLossModel is used, "
110  "this value represents the maximum loss in dB for which "
111  "transmissions will be passed to the receiving PHY. "
112  "Signals for which the PropagationLossModel returns "
113  "a loss bigger than this value will not be propagated "
114  "to the receiver. This parameter is to be used to reduce "
115  "the computational load by not propagating signals that "
116  "are far beyond the interference range. Note that the "
117  "default value corresponds to considering all signals "
118  "for reception. Tune this value with care. ",
119  DoubleValue (1.0e9),
121  MakeDoubleChecker<double> ())
122  .AddTraceSource ("PathLoss",
123  "This trace is fired whenever a new path loss value "
124  "is calculated. The first and second parameters "
125  "to the trace are pointers respectively to the "
126  "TX and RX SpectrumPhy instances, whereas the "
127  "third parameters is the loss value in dB. "
128  "Note that the loss value reported by this trace is "
129  "the single-frequency loss value obtained by evaluating "
130  "only the TX and RX AntennaModels and the "
131  "PropagationLossModel. In particular, note that "
132  "SpectrumPropagationLossModel (even if present) "
133  "is never used to evaluate the loss value "
134  "reported in this trace. ",
136  "ns3::SpectrumChannel::LossTracedCallback")
137  .AddTraceSource ("TxSigParams",
138  "This trace is fired whenever a signal is transmitted. "
139  "The sole parameter is a pointer to a copy of the "
140  "SpectrumSignalParameters provided by the transmitter.",
142  "ns3::MultiModelSpectrumChannel::SignalParametersTracedCallback")
143  ;
144  return tid;
145 }
146 
147 
148 
149 void
151 {
152  NS_LOG_FUNCTION (this << phy);
153 
154  Ptr<const SpectrumModel> rxSpectrumModel = phy->GetRxSpectrumModel ();
155 
156  NS_ASSERT_MSG ((0 != rxSpectrumModel), "phy->GetRxSpectrumModel () returned 0. Please check that the RxSpectrumModel is already set for the phy before calling MultiModelSpectrumChannel::AddRx (phy)");
157 
158  SpectrumModelUid_t rxSpectrumModelUid = rxSpectrumModel->GetUid ();
159 
160  // remove a previous entry of this phy if it exists
161  // we need to scan for all rxSpectrumModel values since we don't
162  // know which spectrum model the phy had when it was previously added
163  // (it's probably different than the current one)
164  for (RxSpectrumModelInfoMap_t::iterator rxInfoIterator = m_rxSpectrumModelInfoMap.begin ();
165  rxInfoIterator != m_rxSpectrumModelInfoMap.end ();
166  ++rxInfoIterator)
167  {
168  std::set<Ptr<SpectrumPhy> >::iterator phyIt = rxInfoIterator->second.m_rxPhySet.find (phy);
169  if (phyIt != rxInfoIterator->second.m_rxPhySet.end ())
170  {
171  rxInfoIterator->second.m_rxPhySet.erase (phyIt);
172  --m_numDevices;
173  break; // there should be at most one entry
174  }
175  }
176 
177  ++m_numDevices;
178 
179  RxSpectrumModelInfoMap_t::iterator rxInfoIterator = m_rxSpectrumModelInfoMap.find (rxSpectrumModelUid);
180 
181  if (rxInfoIterator == m_rxSpectrumModelInfoMap.end ())
182  {
183  // spectrum model unknown, add it to the list of RxSpectrumModels
184  std::pair<RxSpectrumModelInfoMap_t::iterator, bool> ret;
185  ret = m_rxSpectrumModelInfoMap.insert (std::make_pair (rxSpectrumModelUid, RxSpectrumModelInfo (rxSpectrumModel)));
186  NS_ASSERT (ret.second);
187  // also add the phy to the newly created set of SpectrumPhy for this RxSpectrumModel
188  std::pair<std::set<Ptr<SpectrumPhy> >::iterator, bool> ret2 = ret.first->second.m_rxPhySet.insert (phy);
189  NS_ASSERT (ret2.second);
190 
191  // and create the necessary converters for all the TX spectrum models that we know of
192  for (TxSpectrumModelInfoMap_t::iterator txInfoIterator = m_txSpectrumModelInfoMap.begin ();
193  txInfoIterator != m_txSpectrumModelInfoMap.end ();
194  ++txInfoIterator)
195  {
196  Ptr<const SpectrumModel> txSpectrumModel = txInfoIterator->second.m_txSpectrumModel;
197  SpectrumModelUid_t txSpectrumModelUid = txSpectrumModel->GetUid ();
198 
199  if (rxSpectrumModelUid != txSpectrumModelUid && !txSpectrumModel->IsOrthogonal (*rxSpectrumModel))
200  {
201  NS_LOG_LOGIC ("Creating converter between SpectrumModelUid " << txSpectrumModel->GetUid () << " and " << rxSpectrumModelUid);
202  SpectrumConverter converter (txSpectrumModel, rxSpectrumModel);
203  std::pair<SpectrumConverterMap_t::iterator, bool> ret2;
204  ret2 = txInfoIterator->second.m_spectrumConverterMap.insert (std::make_pair (rxSpectrumModelUid, converter));
205  NS_ASSERT (ret2.second);
206  }
207  }
208  }
209  else
210  {
211  // spectrum model is already known, just add the device to the corresponding list
212  std::pair<std::set<Ptr<SpectrumPhy> >::iterator, bool> ret2 = rxInfoIterator->second.m_rxPhySet.insert (phy);
213  NS_ASSERT (ret2.second);
214  }
215 
216 }
217 
218 
219 TxSpectrumModelInfoMap_t::const_iterator
221 {
222  NS_LOG_FUNCTION (this << txSpectrumModel);
223  SpectrumModelUid_t txSpectrumModelUid = txSpectrumModel->GetUid ();
224  TxSpectrumModelInfoMap_t::iterator txInfoIterator = m_txSpectrumModelInfoMap.find (txSpectrumModelUid);
225 
226  if (txInfoIterator == m_txSpectrumModelInfoMap.end ())
227  {
228  // first time we see this TX SpectrumModel
229  // we add it to the list
230  std::pair<TxSpectrumModelInfoMap_t::iterator, bool> ret;
231  ret = m_txSpectrumModelInfoMap.insert (std::make_pair (txSpectrumModelUid, TxSpectrumModelInfo (txSpectrumModel)));
232  NS_ASSERT (ret.second);
233  txInfoIterator = ret.first;
234 
235  // and we create the converters for all the RX SpectrumModels that we know of
236  for (RxSpectrumModelInfoMap_t::const_iterator rxInfoIterator = m_rxSpectrumModelInfoMap.begin ();
237  rxInfoIterator != m_rxSpectrumModelInfoMap.end ();
238  ++rxInfoIterator)
239  {
240  Ptr<const SpectrumModel> rxSpectrumModel = rxInfoIterator->second.m_rxSpectrumModel;
241  SpectrumModelUid_t rxSpectrumModelUid = rxSpectrumModel->GetUid ();
242 
243  if (rxSpectrumModelUid != txSpectrumModelUid && !txSpectrumModel->IsOrthogonal (*rxSpectrumModel))
244  {
245  NS_LOG_LOGIC ("Creating converter between SpectrumModelUid " << txSpectrumModelUid << " and " << rxSpectrumModelUid);
246 
247  SpectrumConverter converter (txSpectrumModel, rxSpectrumModel);
248  std::pair<SpectrumConverterMap_t::iterator, bool> ret2;
249  ret2 = txInfoIterator->second.m_spectrumConverterMap.insert (std::make_pair (rxSpectrumModelUid, converter));
250  NS_ASSERT (ret2.second);
251  }
252  }
253  }
254  else
255  {
256  NS_LOG_LOGIC ("SpectrumModelUid " << txSpectrumModelUid << " already present");
257  }
258  return txInfoIterator;
259 }
260 
261 
262 
263 void
265 {
266  NS_LOG_FUNCTION (this << txParams);
267 
268  NS_ASSERT (txParams->txPhy);
269  NS_ASSERT (txParams->psd);
270  Ptr<SpectrumSignalParameters> txParamsTrace = txParams->Copy (); // copy it since traced value cannot be const (because of potential underlying DynamicCasts)
271  m_txSigParamsTrace (txParamsTrace);
272 
273  Ptr<MobilityModel> txMobility = txParams->txPhy->GetMobility ();
274  SpectrumModelUid_t txSpectrumModelUid = txParams->psd->GetSpectrumModelUid ();
275  NS_LOG_LOGIC (" txSpectrumModelUid " << txSpectrumModelUid);
276 
277  //
278  TxSpectrumModelInfoMap_t::const_iterator txInfoIteratorerator = FindAndEventuallyAddTxSpectrumModel (txParams->psd->GetSpectrumModel ());
279  NS_ASSERT (txInfoIteratorerator != m_txSpectrumModelInfoMap.end ());
280 
281  NS_LOG_LOGIC ("converter map for TX SpectrumModel with Uid " << txInfoIteratorerator->first);
282  NS_LOG_LOGIC ("converter map size: " << txInfoIteratorerator->second.m_spectrumConverterMap.size ());
283  NS_LOG_LOGIC ("converter map first element: " << txInfoIteratorerator->second.m_spectrumConverterMap.begin ()->first);
284 
285  for (RxSpectrumModelInfoMap_t::const_iterator rxInfoIterator = m_rxSpectrumModelInfoMap.begin ();
286  rxInfoIterator != m_rxSpectrumModelInfoMap.end ();
287  ++rxInfoIterator)
288  {
289  SpectrumModelUid_t rxSpectrumModelUid = rxInfoIterator->second.m_rxSpectrumModel->GetUid ();
290  NS_LOG_LOGIC (" rxSpectrumModelUids " << rxSpectrumModelUid);
291 
292  Ptr <SpectrumValue> convertedTxPowerSpectrum;
293  if (txSpectrumModelUid == rxSpectrumModelUid)
294  {
295  NS_LOG_LOGIC ("no spectrum conversion needed");
296  convertedTxPowerSpectrum = txParams->psd;
297  }
298  else
299  {
300  NS_LOG_LOGIC (" converting txPowerSpectrum SpectrumModelUids" << txSpectrumModelUid << " --> " << rxSpectrumModelUid);
301  SpectrumConverterMap_t::const_iterator rxConverterIterator = txInfoIteratorerator->second.m_spectrumConverterMap.find (rxSpectrumModelUid);
302  if (rxConverterIterator == txInfoIteratorerator->second.m_spectrumConverterMap.end ())
303  {
304  // No converter means TX SpectrumModel is orthogonal to RX SpectrumModel
305  continue;
306  }
307  convertedTxPowerSpectrum = rxConverterIterator->second.Convert (txParams->psd);
308  }
309 
310 
311  for (std::set<Ptr<SpectrumPhy> >::const_iterator rxPhyIterator = rxInfoIterator->second.m_rxPhySet.begin ();
312  rxPhyIterator != rxInfoIterator->second.m_rxPhySet.end ();
313  ++rxPhyIterator)
314  {
315  NS_ASSERT_MSG ((*rxPhyIterator)->GetRxSpectrumModel ()->GetUid () == rxSpectrumModelUid,
316  "SpectrumModel change was not notified to MultiModelSpectrumChannel (i.e., AddRx should be called again after model is changed)");
317 
318  if ((*rxPhyIterator) != txParams->txPhy)
319  {
320  NS_LOG_LOGIC (" copying signal parameters " << txParams);
321  Ptr<SpectrumSignalParameters> rxParams = txParams->Copy ();
322  rxParams->psd = Copy<SpectrumValue> (convertedTxPowerSpectrum);
323  Time delay = MicroSeconds (0);
324 
325  Ptr<MobilityModel> receiverMobility = (*rxPhyIterator)->GetMobility ();
326 
327  if (txMobility && receiverMobility)
328  {
329  double pathLossDb = 0;
330  if (rxParams->txAntenna != 0)
331  {
332  Angles txAngles (receiverMobility->GetPosition (), txMobility->GetPosition ());
333  double txAntennaGain = rxParams->txAntenna->GetGainDb (txAngles);
334  NS_LOG_LOGIC ("txAntennaGain = " << txAntennaGain << " dB");
335  pathLossDb -= txAntennaGain;
336  }
337  Ptr<AntennaModel> rxAntenna = (*rxPhyIterator)->GetRxAntenna ();
338  if (rxAntenna != 0)
339  {
340  Angles rxAngles (txMobility->GetPosition (), receiverMobility->GetPosition ());
341  double rxAntennaGain = rxAntenna->GetGainDb (rxAngles);
342  NS_LOG_LOGIC ("rxAntennaGain = " << rxAntennaGain << " dB");
343  pathLossDb -= rxAntennaGain;
344  }
345  if (m_propagationLoss)
346  {
347  double propagationGainDb = m_propagationLoss->CalcRxPower (0, txMobility, receiverMobility);
348  NS_LOG_LOGIC ("propagationGainDb = " << propagationGainDb << " dB");
349  pathLossDb -= propagationGainDb;
350  }
351  NS_LOG_LOGIC ("total pathLoss = " << pathLossDb << " dB");
352  m_pathLossTrace (txParams->txPhy, *rxPhyIterator, pathLossDb);
353  if ( pathLossDb > m_maxLossDb)
354  {
355  // beyond range
356  continue;
357  }
358  double pathGainLinear = std::pow (10.0, (-pathLossDb) / 10.0);
359  *(rxParams->psd) *= pathGainLinear;
360 
361  if (m_spectrumPropagationLoss)
362  {
363  rxParams->psd = m_spectrumPropagationLoss->CalcRxPowerSpectralDensity (rxParams->psd, txMobility, receiverMobility);
364  }
365 
366  if (m_propagationDelay)
367  {
368  delay = m_propagationDelay->GetDelay (txMobility, receiverMobility);
369  }
370  }
371 
372  Ptr<NetDevice> netDev = (*rxPhyIterator)->GetDevice ();
373  if (netDev)
374  {
375  // the receiver has a NetDevice, so we expect that it is attached to a Node
376  uint32_t dstNode = netDev->GetNode ()->GetId ();
378  rxParams, *rxPhyIterator);
379  }
380  else
381  {
382  // the receiver is not attached to a NetDevice, so we cannot assume that it is attached to a node
384  rxParams, *rxPhyIterator);
385  }
386  }
387  }
388 
389  }
390 
391 }
392 
393 void
395 {
396  NS_LOG_FUNCTION (this);
397  receiver->StartRx (params);
398 }
399 
400 std::size_t
402 {
403  return m_numDevices;
404 }
405 
408 {
409  NS_ASSERT (i < m_numDevices);
410  // this method implementation is computationally intensive. This
411  // method would be faster if we actually used a std::vector for
412  // storing devices, which we don't due to the need to have fast
413  // SpectrumModel conversions and to allow PHY devices to changea
414  // SpectrumModel at run time. Note that having this method slow is
415  // acceptable as it is not used much at run time (often not at all).
416  // On the other hand, having slow SpectrumModel conversion would be
417  // less acceptable.
418  std::size_t j = 0;
419  for (RxSpectrumModelInfoMap_t::const_iterator rxInfoIterator = m_rxSpectrumModelInfoMap.begin ();
420  rxInfoIterator != m_rxSpectrumModelInfoMap.end ();
421  ++rxInfoIterator)
422  {
423  for (std::set<Ptr<SpectrumPhy> >::const_iterator phyIt = rxInfoIterator->second.m_rxPhySet.begin ();
424  phyIt != rxInfoIterator->second.m_rxPhySet.end ();
425  ++phyIt)
426  {
427  if (j == i)
428  {
429  return (*phyIt)->GetDevice ();
430  }
431  j++;
432  }
433  }
434  NS_FATAL_ERROR ("m_numDevice > actual number of devices");
435  return 0;
436 }
437 
438 
439 
440 void
442 {
443  NS_LOG_FUNCTION (this << loss);
444  if (m_propagationLoss)
445  {
446  loss->SetNext (m_propagationLoss);
447  }
448  m_propagationLoss = loss;
449 }
450 
451 void
453 {
454  NS_LOG_FUNCTION (this << loss);
455  if (m_spectrumPropagationLoss)
456  {
457  loss->SetNext (m_spectrumPropagationLoss);
458  }
459  m_spectrumPropagationLoss = loss;
460 }
461 
462 void
464 {
465  NS_ASSERT (m_propagationDelay == 0);
466  m_propagationDelay = delay;
467 }
468 
471 {
472  NS_LOG_FUNCTION (this);
473  return m_spectrumPropagationLoss;
474 }
475 
476 
477 } // namespace ns3
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
uint32_t SpectrumModelUid_t
Uid for SpectrumModels.
The Rx spectrum model information.
virtual void StartRx(Ptr< SpectrumSignalParameters > params)=0
Notify the SpectrumPhy instance of an incoming signal.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
void SetNext(Ptr< PropagationLossModel > next)
Enables a chain of loss models to act on the signal.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
virtual void AddPropagationLossModel(Ptr< PropagationLossModel > loss)
Add the single-frequency propagation loss model to be used.
Vector GetPosition(void) const
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
virtual Ptr< const SpectrumModel > GetRxSpectrumModel() const =0
This SpectrumChannel implementation can handle the presence of SpectrumPhy instances which can use di...
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
phy
Definition: third.py:86
virtual Ptr< SpectrumPropagationLossModel > GetSpectrumPropagationLossModel(void)
Get the frequency-dependent propagation loss model.
NS_ASSERT_MSG(false,"Ipv4AddressGenerator::MaskToIndex(): Impossible")
Class which implements a converter between SpectrumValue which are defined over different SpectrumMod...
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1381
virtual Ptr< NetDevice > GetDevice(std::size_t i) const
SpectrumModelUid_t GetUid() const
static TypeId GetTypeId(void)
Get the type ID.
virtual void AddRx(Ptr< SpectrumPhy > phy)
Add a SpectrumPhy to a channel, so it can receive packets.
TxSpectrumModelInfoMap_t::const_iterator FindAndEventuallyAddTxSpectrumModel(Ptr< const SpectrumModel > txSpectrumModel)
This method checks if m_rxSpectrumModelInfoMap contains an entry for the given TX SpectrumModel...
TracedCallback< Ptr< SpectrumSignalParameters > > m_txSigParamsTrace
Traced callback for SpectrumSignalParameters in StartTx requests.
bool IsOrthogonal(const SpectrumModel &other) const
Check if another SpectrumModels has bands orthogonal to our bands.
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual std::size_t GetNDevices(void) const
RxSpectrumModelInfo(Ptr< const SpectrumModel > rxSpectrumModel)
Constructor.
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
void DoDispose()
Destructor implementation.
virtual void AddSpectrumPropagationLossModel(Ptr< SpectrumPropagationLossModel > loss)
Add the frequency-dependent propagation loss model to be used.
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: double.h:42
TracedCallback< Ptr< SpectrumPhy >, Ptr< SpectrumPhy >, double > m_pathLossTrace
static void ScheduleWithContext(uint32_t context, Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event with the given context.
Definition: simulator.h:1475
virtual void StartTx(Ptr< SpectrumSignalParameters > params)
Used by attached PHY instances to transmit signals on the channel.
virtual void SetPropagationDelayModel(Ptr< PropagationDelayModel > delay)
Set the propagation delay model to be used.
Defines the interface for spectrum-aware channel implementations.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1023
struct holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:71
TxSpectrumModelInfo(Ptr< const SpectrumModel > txSpectrumModel)
Constructor.
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
a unique identifier for an interface.
Definition: type-id.h:58
virtual void StartRx(Ptr< SpectrumSignalParameters > params, Ptr< SpectrumPhy > receiver)
Used internally to reschedule transmission after the propagation delay.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
std::map< SpectrumModelUid_t, TxSpectrumModelInfo > TxSpectrumModelInfoMap_t
Container: SpectrumModelUid_t, TxSpectrumModelInfo.
The Tx spectrum model information.