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);
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  ;
138  return tid;
139 }
140 
141 
142 
143 void
145 {
146  NS_LOG_FUNCTION (this << phy);
147 
148  Ptr<const SpectrumModel> rxSpectrumModel = phy->GetRxSpectrumModel ();
149 
150  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)");
151 
152  SpectrumModelUid_t rxSpectrumModelUid = rxSpectrumModel->GetUid ();
153 
154  // remove a previous entry of this phy if it exists
155  // we need to scan for all rxSpectrumModel values since we don't
156  // know which spectrum model the phy had when it was previously added
157  // (it's probably different than the current one)
158  for (RxSpectrumModelInfoMap_t::iterator rxInfoIterator = m_rxSpectrumModelInfoMap.begin ();
159  rxInfoIterator != m_rxSpectrumModelInfoMap.end ();
160  ++rxInfoIterator)
161  {
162  std::set<Ptr<SpectrumPhy> >::iterator phyIt = rxInfoIterator->second.m_rxPhySet.find (phy);
163  if (phyIt != rxInfoIterator->second.m_rxPhySet.end ())
164  {
165  rxInfoIterator->second.m_rxPhySet.erase (phyIt);
166  --m_numDevices;
167  break; // there should be at most one entry
168  }
169  }
170 
171  ++m_numDevices;
172 
173  RxSpectrumModelInfoMap_t::iterator rxInfoIterator = m_rxSpectrumModelInfoMap.find (rxSpectrumModelUid);
174 
175  if (rxInfoIterator == m_rxSpectrumModelInfoMap.end ())
176  {
177  // spectrum model unknown, add it to the list of RxSpectrumModels
178  std::pair<RxSpectrumModelInfoMap_t::iterator, bool> ret;
179  ret = m_rxSpectrumModelInfoMap.insert (std::make_pair (rxSpectrumModelUid, RxSpectrumModelInfo (rxSpectrumModel)));
180  NS_ASSERT (ret.second);
181  // also add the phy to the newly created set of SpectrumPhy for this RxSpectrumModel
182  std::pair<std::set<Ptr<SpectrumPhy> >::iterator, bool> ret2 = ret.first->second.m_rxPhySet.insert (phy);
183  NS_ASSERT (ret2.second);
184 
185  // and create the necessary converters for all the TX spectrum models that we know of
186  for (TxSpectrumModelInfoMap_t::iterator txInfoIterator = m_txSpectrumModelInfoMap.begin ();
187  txInfoIterator != m_txSpectrumModelInfoMap.end ();
188  ++txInfoIterator)
189  {
190  Ptr<const SpectrumModel> txSpectrumModel = txInfoIterator->second.m_txSpectrumModel;
191  SpectrumModelUid_t txSpectrumModelUid = txSpectrumModel->GetUid ();
192 
193  if (rxSpectrumModelUid != txSpectrumModelUid && !txSpectrumModel->IsOrthogonal (*rxSpectrumModel))
194  {
195  NS_LOG_LOGIC ("Creating converter between SpectrumModelUid " << txSpectrumModel->GetUid () << " and " << rxSpectrumModelUid);
196  SpectrumConverter converter (txSpectrumModel, rxSpectrumModel);
197  std::pair<SpectrumConverterMap_t::iterator, bool> ret2;
198  ret2 = txInfoIterator->second.m_spectrumConverterMap.insert (std::make_pair (rxSpectrumModelUid, converter));
199  NS_ASSERT (ret2.second);
200  }
201  }
202  }
203  else
204  {
205  // spectrum model is already known, just add the device to the corresponding list
206  std::pair<std::set<Ptr<SpectrumPhy> >::iterator, bool> ret2 = rxInfoIterator->second.m_rxPhySet.insert (phy);
207  NS_ASSERT (ret2.second);
208  }
209 
210 }
211 
212 
213 TxSpectrumModelInfoMap_t::const_iterator
215 {
216  NS_LOG_FUNCTION (this << txSpectrumModel);
217  SpectrumModelUid_t txSpectrumModelUid = txSpectrumModel->GetUid ();
218  TxSpectrumModelInfoMap_t::iterator txInfoIterator = m_txSpectrumModelInfoMap.find (txSpectrumModelUid);
219 
220  if (txInfoIterator == m_txSpectrumModelInfoMap.end ())
221  {
222  // first time we see this TX SpectrumModel
223  // we add it to the list
224  std::pair<TxSpectrumModelInfoMap_t::iterator, bool> ret;
225  ret = m_txSpectrumModelInfoMap.insert (std::make_pair (txSpectrumModelUid, TxSpectrumModelInfo (txSpectrumModel)));
226  NS_ASSERT (ret.second);
227  txInfoIterator = ret.first;
228 
229  // and we create the converters for all the RX SpectrumModels that we know of
230  for (RxSpectrumModelInfoMap_t::const_iterator rxInfoIterator = m_rxSpectrumModelInfoMap.begin ();
231  rxInfoIterator != m_rxSpectrumModelInfoMap.end ();
232  ++rxInfoIterator)
233  {
234  Ptr<const SpectrumModel> rxSpectrumModel = rxInfoIterator->second.m_rxSpectrumModel;
235  SpectrumModelUid_t rxSpectrumModelUid = rxSpectrumModel->GetUid ();
236 
237  if (rxSpectrumModelUid != txSpectrumModelUid && !txSpectrumModel->IsOrthogonal (*rxSpectrumModel))
238  {
239  NS_LOG_LOGIC ("Creating converter between SpectrumModelUid " << txSpectrumModelUid << " and " << rxSpectrumModelUid);
240 
241  SpectrumConverter converter (txSpectrumModel, rxSpectrumModel);
242  std::pair<SpectrumConverterMap_t::iterator, bool> ret2;
243  ret2 = txInfoIterator->second.m_spectrumConverterMap.insert (std::make_pair (rxSpectrumModelUid, converter));
244  NS_ASSERT (ret2.second);
245  }
246  }
247  }
248  else
249  {
250  NS_LOG_LOGIC ("SpectrumModelUid " << txSpectrumModelUid << " already present");
251  }
252  return txInfoIterator;
253 }
254 
255 
256 
257 void
259 {
260  NS_LOG_FUNCTION (this << txParams);
261 
262  NS_ASSERT (txParams->txPhy);
263  NS_ASSERT (txParams->psd);
264 
265 
266  Ptr<MobilityModel> txMobility = txParams->txPhy->GetMobility ();
267  SpectrumModelUid_t txSpectrumModelUid = txParams->psd->GetSpectrumModelUid ();
268  NS_LOG_LOGIC (" txSpectrumModelUid " << txSpectrumModelUid);
269 
270  //
271  TxSpectrumModelInfoMap_t::const_iterator txInfoIteratorerator = FindAndEventuallyAddTxSpectrumModel (txParams->psd->GetSpectrumModel ());
272  NS_ASSERT (txInfoIteratorerator != m_txSpectrumModelInfoMap.end ());
273 
274  NS_LOG_LOGIC ("converter map for TX SpectrumModel with Uid " << txInfoIteratorerator->first);
275  NS_LOG_LOGIC ("converter map size: " << txInfoIteratorerator->second.m_spectrumConverterMap.size ());
276  NS_LOG_LOGIC ("converter map first element: " << txInfoIteratorerator->second.m_spectrumConverterMap.begin ()->first);
277 
278  for (RxSpectrumModelInfoMap_t::const_iterator rxInfoIterator = m_rxSpectrumModelInfoMap.begin ();
279  rxInfoIterator != m_rxSpectrumModelInfoMap.end ();
280  ++rxInfoIterator)
281  {
282  SpectrumModelUid_t rxSpectrumModelUid = rxInfoIterator->second.m_rxSpectrumModel->GetUid ();
283  NS_LOG_LOGIC (" rxSpectrumModelUids " << rxSpectrumModelUid);
284 
285  Ptr <SpectrumValue> convertedTxPowerSpectrum;
286  if (txSpectrumModelUid == rxSpectrumModelUid)
287  {
288  NS_LOG_LOGIC ("no spectrum conversion needed");
289  convertedTxPowerSpectrum = txParams->psd;
290  }
291  else
292  {
293  NS_LOG_LOGIC (" converting txPowerSpectrum SpectrumModelUids" << txSpectrumModelUid << " --> " << rxSpectrumModelUid);
294  SpectrumConverterMap_t::const_iterator rxConverterIterator = txInfoIteratorerator->second.m_spectrumConverterMap.find (rxSpectrumModelUid);
295  if (rxConverterIterator == txInfoIteratorerator->second.m_spectrumConverterMap.end ())
296  {
297  // No converter means TX SpectrumModel is orthogonal to RX SpectrumModel
298  continue;
299  }
300  convertedTxPowerSpectrum = rxConverterIterator->second.Convert (txParams->psd);
301  }
302 
303 
304  for (std::set<Ptr<SpectrumPhy> >::const_iterator rxPhyIterator = rxInfoIterator->second.m_rxPhySet.begin ();
305  rxPhyIterator != rxInfoIterator->second.m_rxPhySet.end ();
306  ++rxPhyIterator)
307  {
308  NS_ASSERT_MSG ((*rxPhyIterator)->GetRxSpectrumModel ()->GetUid () == rxSpectrumModelUid,
309  "SpectrumModel change was not notified to MultiModelSpectrumChannel (i.e., AddRx should be called again after model is changed)");
310 
311  if ((*rxPhyIterator) != txParams->txPhy)
312  {
313  NS_LOG_LOGIC (" copying signal parameters " << txParams);
314  Ptr<SpectrumSignalParameters> rxParams = txParams->Copy ();
315  rxParams->psd = Copy<SpectrumValue> (convertedTxPowerSpectrum);
316  Time delay = MicroSeconds (0);
317 
318  Ptr<MobilityModel> receiverMobility = (*rxPhyIterator)->GetMobility ();
319 
320  if (txMobility && receiverMobility)
321  {
322  double pathLossDb = 0;
323  if (rxParams->txAntenna != 0)
324  {
325  Angles txAngles (receiverMobility->GetPosition (), txMobility->GetPosition ());
326  double txAntennaGain = rxParams->txAntenna->GetGainDb (txAngles);
327  NS_LOG_LOGIC ("txAntennaGain = " << txAntennaGain << " dB");
328  pathLossDb -= txAntennaGain;
329  }
330  Ptr<AntennaModel> rxAntenna = (*rxPhyIterator)->GetRxAntenna ();
331  if (rxAntenna != 0)
332  {
333  Angles rxAngles (txMobility->GetPosition (), receiverMobility->GetPosition ());
334  double rxAntennaGain = rxAntenna->GetGainDb (rxAngles);
335  NS_LOG_LOGIC ("rxAntennaGain = " << rxAntennaGain << " dB");
336  pathLossDb -= rxAntennaGain;
337  }
338  if (m_propagationLoss)
339  {
340  double propagationGainDb = m_propagationLoss->CalcRxPower (0, txMobility, receiverMobility);
341  NS_LOG_LOGIC ("propagationGainDb = " << propagationGainDb << " dB");
342  pathLossDb -= propagationGainDb;
343  }
344  NS_LOG_LOGIC ("total pathLoss = " << pathLossDb << " dB");
345  m_pathLossTrace (txParams->txPhy, *rxPhyIterator, pathLossDb);
346  if ( pathLossDb > m_maxLossDb)
347  {
348  // beyond range
349  continue;
350  }
351  double pathGainLinear = std::pow (10.0, (-pathLossDb) / 10.0);
352  *(rxParams->psd) *= pathGainLinear;
353 
355  {
356  rxParams->psd = m_spectrumPropagationLoss->CalcRxPowerSpectralDensity (rxParams->psd, txMobility, receiverMobility);
357  }
358 
359  if (m_propagationDelay)
360  {
361  delay = m_propagationDelay->GetDelay (txMobility, receiverMobility);
362  }
363  }
364 
365  Ptr<NetDevice> netDev = (*rxPhyIterator)->GetDevice ();
366  if (netDev)
367  {
368  // the receiver has a NetDevice, so we expect that it is attached to a Node
369  uint32_t dstNode = netDev->GetNode ()->GetId ();
371  rxParams, *rxPhyIterator);
372  }
373  else
374  {
375  // the receiver is not attached to a NetDevice, so we cannot assume that it is attached to a node
377  rxParams, *rxPhyIterator);
378  }
379  }
380  }
381 
382  }
383 
384 }
385 
386 void
388 {
389  NS_LOG_FUNCTION (this);
390  receiver->StartRx (params);
391 }
392 
393 
394 
395 uint32_t
397 {
398  return m_numDevices;
399 
400 }
401 
402 
405 {
406  NS_ASSERT (i < m_numDevices);
407  // this method implementation is computationally intensive. This
408  // method would be faster if we actually used a std::vector for
409  // storing devices, which we don't due to the need to have fast
410  // SpectrumModel conversions and to allow PHY devices to changea
411  // SpectrumModel at run time. Note that having this method slow is
412  // acceptable as it is not used much at run time (often not at all).
413  // On the other hand, having slow SpectrumModel conversion would be
414  // less acceptable.
415  uint32_t j = 0;
416  for (RxSpectrumModelInfoMap_t::const_iterator rxInfoIterator = m_rxSpectrumModelInfoMap.begin ();
417  rxInfoIterator != m_rxSpectrumModelInfoMap.end ();
418  ++rxInfoIterator)
419  {
420  for (std::set<Ptr<SpectrumPhy> >::const_iterator phyIt = rxInfoIterator->second.m_rxPhySet.begin ();
421  phyIt != rxInfoIterator->second.m_rxPhySet.end ();
422  ++phyIt)
423  {
424  if (j == i)
425  {
426  return (*phyIt)->GetDevice ();
427  }
428  j++;
429  }
430  }
431  NS_FATAL_ERROR ("m_numDevice > actual number of devices");
432  return 0;
433 }
434 
435 
436 
437 void
439 {
440  NS_LOG_FUNCTION (this << loss);
441  if (m_propagationLoss)
442  {
443  loss->SetNext (m_propagationLoss);
444  }
445  m_propagationLoss = loss;
446 }
447 
448 void
450 {
451  NS_LOG_FUNCTION (this << loss);
453  {
454  loss->SetNext (m_spectrumPropagationLoss);
455  }
457 }
458 
459 void
461 {
463  m_propagationDelay = delay;
464 }
465 
468 {
469  NS_LOG_FUNCTION (this);
471 }
472 
473 
474 } // namespace ns3
Ptr< SpectrumPropagationLossModel > m_spectrumPropagationLoss
Frequency-dependent propagation loss model to be used with this channel.
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:201
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
RxSpectrumModelInfoMap_t m_rxSpectrumModelInfoMap
Data structure holding, for each RX spectrum model, all the corresponding SpectrumPhy instances...
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...
uint32_t m_numDevices
Number of devices connected to the channel.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
virtual Ptr< SpectrumPropagationLossModel > GetSpectrumPropagationLossModel(void)
Get the frequency-dependent propagation loss model.
Ptr< PropagationDelayModel > m_propagationDelay
Propagation delay model to be used with this channel.
Ptr< PropagationLossModel > m_propagationLoss
Single-frequency propagation loss model to be used with this channel.
Class which implements a converter between SpectrumValue which are defined over different SpectrumMod...
tuple phy
Definition: third.py:86
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1375
virtual uint32_t GetNDevices(void) 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...
double CalcRxPower(double txPowerDbm, Ptr< MobilityModel > a, Ptr< MobilityModel > b) const
Returns the Rx Power taking into account all the PropagationLossModel(s) chained to the current one...
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.
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.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:90
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:1469
virtual void StartTx(Ptr< SpectrumSignalParameters > params)
Used by attached PHY instances to transmit signals on the channel.
virtual Ptr< NetDevice > GetDevice(uint32_t i) const
virtual void SetPropagationDelayModel(Ptr< PropagationDelayModel > delay)
Set the propagation delay model to be used.
TxSpectrumModelInfoMap_t m_txSpectrumModelInfoMap
Data structure holding, for each TX SpectrumModel, all the converters to any RX SpectrumModel, and all the corresponding SpectrumPhy instances.
Defines the interface for spectrum-aware channel implementations.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1009
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 'double' or 'float'...
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:914
std::map< SpectrumModelUid_t, TxSpectrumModelInfo > TxSpectrumModelInfoMap_t
Container: SpectrumModelUid_t, TxSpectrumModelInfo.
The Tx spectrum model information.