INET Framework for OMNeT++/OMNEST
inet::physicallayer::DimensionalTransmitterBase Class Reference

#include <DimensionalTransmitterBase.h>

Inheritance diagram for inet::physicallayer::DimensionalTransmitterBase:
inet::IPrintableObject inet::physicallayer::ApskDimensionalTransmitter inet::physicallayer::DimensionalBackgroundNoise inet::physicallayer::Ieee80211DimensionalTransmitter inet::physicallayer::Ieee802154NarrowbandDimensionalTransmitter inet::physicallayer::NoiseDimensionalTransmitter

Classes

class  GainEntry
 

Public Member Functions

virtual std::ostream & printToStream (std::ostream &stream, int level, int evFlags=0) const override
 Prints this object to the provided output stream. More...
 
- Public Member Functions inherited from inet::IPrintableObject
virtual ~IPrintableObject ()
 
virtual std::string printToString () const
 
virtual std::string printToString (int level, int evFlags=0) const
 
virtual std::string getInfoStringRepresentation (int evFlags=0) const
 
virtual std::string getDetailStringRepresentation (int evFlags=0) const
 
virtual std::string getDebugStringRepresentation (int evFlags=0) const
 
virtual std::string getTraceStringRepresentation (int evFlags=0) const
 
virtual std::string getCompleteStringRepresentation (int evFlags=0) const
 

Protected Member Functions

virtual void initialize (int stage)
 
template<typename T >
std::vector< GainEntry< T > > parseGains (const char *text) const
 
virtual void parseTimeGains (const char *text)
 
virtual void parseFrequencyGains (const char *text)
 
template<typename T >
const Ptr< const IFunction< double, Domain< T > > > normalize (const Ptr< const IFunction< double, Domain< T >>> &function, const char *normalization) const
 
virtual Ptr< const IFunction< double, Domain< simsec, Hz > > > createGainFunction (const simtime_t startTime, const simtime_t endTime, Hz centerFrequency, Hz bandwidth) const
 
virtual Ptr< const IFunction< WpHz, Domain< simsec, Hz > > > createPowerFunction (const simtime_t startTime, const simtime_t endTime, Hz centerFrequency, Hz bandwidth, W power) const
 

Protected Attributes

const IInterpolator< simsec, double > * firstTimeInterpolator = nullptr
 
const IInterpolator< Hz, double > * firstFrequencyInterpolator = nullptr
 
std::vector< GainEntry< simsec > > timeGains
 
std::vector< GainEntry< Hz > > frequencyGains
 
const char * timeGainsNormalization = nullptr
 
const char * frequencyGainsNormalization = nullptr
 
int gainFunctionCacheLimit = -1
 
std::map< std::tuple< simtime_t, Hz, Hz >, Ptr< const IFunction< double, Domain< simsec, Hz > > > > gainFunctionCache
 

Additional Inherited Members

- Public Types inherited from inet::IPrintableObject
enum  PrintLevel {
  PRINT_LEVEL_TRACE, PRINT_LEVEL_DEBUG, PRINT_LEVEL_DETAIL, PRINT_LEVEL_INFO,
  PRINT_LEVEL_COMPLETE = INT_MIN
}
 
enum  PrintFlag { PRINT_FLAG_FORMATTED = (1 << 0), PRINT_FLAG_MULTILINE = (1 << 1) }
 

Member Function Documentation

◆ createGainFunction()

Ptr< const IFunction< double, Domain< simsec, Hz > > > inet::physicallayer::DimensionalTransmitterBase::createGainFunction ( const simtime_t  startTime,
const simtime_t  endTime,
Hz  centerFrequency,
Hz  bandwidth 
) const
protectedvirtual
143 {
144  if (timeGains.size() == 0 && frequencyGains.size() == 0) {
145  double value = 1;
146  if (!strcmp("integral", timeGainsNormalization))
147  value /= (endTime - startTime).dbl();
148  if (!strcmp("integral", frequencyGainsNormalization))
149  value /= bandwidth.get();
150  return makeShared<Boxcar2DFunction<double, simsec, Hz>>(simsec(startTime), simsec(endTime), centerFrequency - bandwidth / 2, centerFrequency + bandwidth / 2, value);
151  }
152  else {
153  Ptr<const IFunction<double, Domain<simsec>>> timeGainFunction;
154  if (timeGains.size() != 0) {
155  auto centerTime = (startTime + endTime) / 2;
156  auto duration = endTime - startTime;
157  std::map<simsec, std::pair<double, const IInterpolator<simsec, double> *>> ts;
158  ts[getLowerBound<simsec>()] = { 0, firstTimeInterpolator };
159  ts[getUpperBound<simsec>()] = { 0, nullptr };
160  for (const auto& entry : timeGains) {
161  simsec time;
162  switch (entry.where) {
163  case 's': time = simsec(startTime); break;
164  case 'e': time = simsec(endTime); break;
165  case 'c': time = simsec(centerTime); break;
166  case ' ': time = simsec(0); break;
167  default: throw cRuntimeError("Unknown qualifier");
168  }
169  time += simsec(duration) * entry.length + entry.offset;
170  ts[time] = { entry.gain, entry.interpolator };
171  }
172  timeGainFunction = makeShared<Interpolated1DFunction<double, simsec>>(ts);
173  }
174  else
175  timeGainFunction = makeShared<Boxcar1DFunction<double, simsec>>(simsec(startTime), simsec(endTime), 1);
176  Ptr<const IFunction<double, Domain<Hz>>> frequencyGainFunction;
177  if (frequencyGains.size() != 0) {
178  auto startFrequency = centerFrequency - bandwidth / 2;
179  auto endFrequency = centerFrequency + bandwidth / 2;
180  std::map<Hz, std::pair<double, const IInterpolator<Hz, double> *>> fs;
181  fs[getLowerBound<Hz>()] = { 0, firstFrequencyInterpolator };
182  fs[getUpperBound<Hz>()] = { 0, nullptr };
183  for (const auto& entry : frequencyGains) {
184  Hz frequency;
185  switch (entry.where) {
186  case 's': frequency = startFrequency; break;
187  case 'e': frequency = endFrequency; break;
188  case 'c': frequency = centerFrequency; break;
189  case ' ': frequency = Hz(0); break;
190  default: throw cRuntimeError("Unknown qualifier");
191  }
192  frequency += bandwidth * entry.length + entry.offset;
193  ASSERT(!std::isnan(frequency.get()));
194  fs[frequency] = { entry.gain, entry.interpolator };
195  }
196  frequencyGainFunction = makeShared<Interpolated1DFunction<double, Hz>>(fs);
197  }
198  else
199  frequencyGainFunction = makeShared<Boxcar1DFunction<double, Hz>>(centerFrequency - bandwidth / 2, centerFrequency + bandwidth / 2, 1);
200  return makeShared<Combined2DFunction<double, simsec, Hz>>(normalize<simsec>(timeGainFunction, timeGainsNormalization), normalize<Hz>(frequencyGainFunction, frequencyGainsNormalization));
201  }
202 }

◆ createPowerFunction()

Ptr< const IFunction< WpHz, Domain< simsec, Hz > > > inet::physicallayer::DimensionalTransmitterBase::createPowerFunction ( const simtime_t  startTime,
const simtime_t  endTime,
Hz  centerFrequency,
Hz  bandwidth,
W  power 
) const
protectedvirtual
205 {
206  Ptr<const IFunction<WpHz, Domain<simsec, Hz>>> powerFunction;
207  if (gainFunctionCacheLimit == 0) {
208  if (timeGains.size() == 0 && frequencyGains.size() == 0)
209  powerFunction = makeShared<Boxcar2DFunction<WpHz, simsec, Hz>>(simsec(startTime), simsec(endTime), centerFrequency - bandwidth / 2, centerFrequency + bandwidth / 2, power / bandwidth);
210  else {
211  auto gainFunction = createGainFunction(startTime, endTime, centerFrequency, bandwidth);
212  powerFunction = makeShared<ConstantFunction<WpHz, Domain<simsec, Hz>>>(power / Hz(1))->multiply(gainFunction);
213  }
214  }
215  else {
216  Ptr<const IFunction<double, Domain<simsec, Hz>>> gainFunction;
217  std::tuple<simtime_t, Hz, Hz> key(endTime - startTime, centerFrequency, bandwidth);
218  auto it = gainFunctionCache.find(key);
219  if (it != gainFunctionCache.end())
220  gainFunction = it->second;
221  else {
222  gainFunction = createGainFunction(0, endTime - startTime, Hz(0), bandwidth);
223  gainFunctionCache[key] = gainFunction;
224  if ((int)gainFunctionCache.size() == gainFunctionCacheLimit)
225  gainFunctionCache.clear();
226  }
227  Point<simsec, Hz> shift(simsec(startTime), centerFrequency);
228  auto shiftedGainFunction = makeShared<DomainShiftedFunction<double, Domain<simsec, Hz>>>(gainFunction, shift);
229  powerFunction = makeShared<ConstantFunction<WpHz, Domain<simsec, Hz>>>(power / Hz(1))->multiply(shiftedGainFunction);
230  }
231  return makeFirstQuadrantLimitedFunction(powerFunction);
232 }

Referenced by inet::physicallayer::DimensionalBackgroundNoise::computeNoise(), inet::physicallayer::Ieee802154NarrowbandDimensionalTransmitter::createTransmission(), inet::physicallayer::ApskDimensionalTransmitter::createTransmission(), inet::physicallayer::Ieee80211DimensionalTransmitter::createTransmission(), and inet::physicallayer::NoiseDimensionalTransmitter::createTransmission().

◆ initialize()

void inet::physicallayer::DimensionalTransmitterBase::initialize ( int  stage)
protectedvirtual

◆ normalize()

template<typename T >
const Ptr< const IFunction< double, Domain< T > > > inet::physicallayer::DimensionalTransmitterBase::normalize ( const Ptr< const IFunction< double, Domain< T >>> &  function,
const char *  normalization 
) const
protected
119 {
120  if (!strcmp("", normalization))
121  return gainFunction;
122  else if (!strcmp("maximum", normalization)) {
123  auto max = gainFunction->getMax();
124  ASSERT(max != 0);
125  if (max == 1.0)
126  return gainFunction;
127  else
128  return gainFunction->divide(makeShared<ConstantFunction<double, Domain<T>>>(max));
129  }
130  else if (!strcmp("integral", normalization)) {
131  double integral = gainFunction->getIntegral();
132  ASSERT(integral != 0);
133  if (integral == 1.0)
134  return gainFunction;
135  else
136  return gainFunction->divide(makeShared<ConstantFunction<double, Domain<T>>>(integral));
137  }
138  else
139  throw cRuntimeError("Unknown normalization: '%s'", normalization);
140 }

◆ parseFrequencyGains()

void inet::physicallayer::DimensionalTransmitterBase::parseFrequencyGains ( const char *  text)
protectedvirtual
99 {
100  if (strcmp(text, "left s 0dB either e 0dB right")) {
101  firstFrequencyInterpolator = createInterpolator<Hz, double>(cStringTokenizer(text).nextToken());
102  frequencyGains = parseGains<Hz>(text);
103  }
104  else {
105  firstFrequencyInterpolator = nullptr;
106  frequencyGains.clear();
107  }
108 }

◆ parseGains()

template<typename T >
std::vector< DimensionalTransmitterBase::GainEntry< T > > inet::physicallayer::DimensionalTransmitterBase::parseGains ( const char *  text) const
protected
34 {
35  std::vector<GainEntry<T>> gains;
36  cStringTokenizer tokenizer(text);
37  tokenizer.nextToken();
38  while (tokenizer.hasMoreTokens()) {
39  char *token = const_cast<char *>(tokenizer.nextToken());
40  char where;
41  char *end;
42  if (*token == 's' || *token == 'c' || *token == 'e') {
43  where = *token;
44  end = token + 1;
45  }
46  else {
47  where = ' ';
48  end = token;
49  }
50  // TODO replace this BS with the expression evaluator when it supports simtime_t and bindings
51  // Allowed syntax:
52  // +-quantity
53  // s|c|e
54  // s|c|e+-quantity
55  // s|c|e+-b|d
56  // s|c|e+-b|d+-quantity
57  // s|c|e+-b|d*number
58  // s|c|e+-b|d*number+-quantity
59  double lengthMultiplier = 0;
60  if ((*(token + 1) == '+' || *(token + 1) == '-') &&
61  (*(token + 2) == 'b' || *(token + 2) == 'd'))
62  {
63  if (*(token + 3) == '*')
64  lengthMultiplier = strtod(token + 4, &end);
65  else {
66  lengthMultiplier = 1;
67  end += 2;
68  }
69  if (*(token + 1) == '-')
70  lengthMultiplier *= -1;
71  }
72  T offset = T(0);
73  if (end && strlen(end) != 0)
74  offset = T(cNEDValue::parseQuantity(end, (std::is_same<T, simsec>::value == true ? "s" : (std::is_same<T, Hz>::value == true ? "Hz" : ""))));
75  double gain = strtod(tokenizer.nextToken(), &end);
76  if (end && !strcmp(end, "dB"))
77  gain = dB2fraction(gain);
78  if (gain < 0)
79  throw cRuntimeError("Gain must be in the range [0, inf)");
80  auto interpolator = createInterpolator<T, double>(tokenizer.nextToken());
81  gains.push_back(GainEntry<T>(interpolator, where, lengthMultiplier, offset, gain));
82  }
83  return gains;
84 }

◆ parseTimeGains()

void inet::physicallayer::DimensionalTransmitterBase::parseTimeGains ( const char *  text)
protectedvirtual
87 {
88  if (strcmp(text, "left s 0dB either e 0dB right")) {
89  firstTimeInterpolator = createInterpolator<simsec, double>(cStringTokenizer(text).nextToken());
90  timeGains = parseGains<simsec>(text);
91  }
92  else {
93  firstTimeInterpolator = nullptr;
94  timeGains.clear();
95  }
96 }

◆ printToStream()

Member Data Documentation

◆ firstFrequencyInterpolator

const IInterpolator<Hz, double>* inet::physicallayer::DimensionalTransmitterBase::firstFrequencyInterpolator = nullptr
protected

◆ firstTimeInterpolator

const IInterpolator<simsec, double>* inet::physicallayer::DimensionalTransmitterBase::firstTimeInterpolator = nullptr
protected

◆ frequencyGains

std::vector<GainEntry<Hz> > inet::physicallayer::DimensionalTransmitterBase::frequencyGains
protected

◆ frequencyGainsNormalization

const char* inet::physicallayer::DimensionalTransmitterBase::frequencyGainsNormalization = nullptr
protected

◆ gainFunctionCache

std::map<std::tuple<simtime_t, Hz, Hz>, Ptr<const IFunction<double, Domain<simsec, Hz> > > > inet::physicallayer::DimensionalTransmitterBase::gainFunctionCache
mutableprotected

◆ gainFunctionCacheLimit

int inet::physicallayer::DimensionalTransmitterBase::gainFunctionCacheLimit = -1
protected

◆ timeGains

std::vector<GainEntry<simsec> > inet::physicallayer::DimensionalTransmitterBase::timeGains
protected

◆ timeGainsNormalization

const char* inet::physicallayer::DimensionalTransmitterBase::timeGainsNormalization = nullptr
protected

The documentation for this class was generated from the following files:
inet::physicallayer::DimensionalTransmitterBase::createGainFunction
virtual Ptr< const IFunction< double, Domain< simsec, Hz > > > createGainFunction(const simtime_t startTime, const simtime_t endTime, Hz centerFrequency, Hz bandwidth) const
Definition: DimensionalTransmitterBase.cc:142
inet::units::units::T
compose< Wb, pow< m, -2 > > T
Definition: Units.h:951
inet::units::values::simsec
value< simtime_t, units::s > simsec
Definition: Units.h:1236
inet::units::units::Hz
pow< s, -1 > Hz
Definition: Units.h:935
inet::physicallayer::DimensionalTransmitterBase::gainFunctionCache
std::map< std::tuple< simtime_t, Hz, Hz >, Ptr< const IFunction< double, Domain< simsec, Hz > > > > gainFunctionCache
Definition: DimensionalTransmitterBase.h:47
inet::math::Point
N-dimensional point.
Definition: Point.h:93
inet::physicallayer::DimensionalTransmitterBase::parseFrequencyGains
virtual void parseFrequencyGains(const char *text)
Definition: DimensionalTransmitterBase.cc:98
inet::physicallayer::DimensionalTransmitterBase::gainFunctionCacheLimit
int gainFunctionCacheLimit
Definition: DimensionalTransmitterBase.h:46
inet::math::ConstantFunction
Definition: PrimitiveFunctions.h:19
inet::math::dB2fraction
double dB2fraction(double dB)
Converts a dB value to fraction.
Definition: INETMath.h:153
inet::physicallayer::DimensionalTransmitterBase::timeGains
std::vector< GainEntry< simsec > > timeGains
Definition: DimensionalTransmitterBase.h:41
inet::physicallayer::DimensionalTransmitterBase::parseTimeGains
virtual void parseTimeGains(const char *text)
Definition: DimensionalTransmitterBase.cc:86
inet::math::makeFirstQuadrantLimitedFunction
Ptr< const DomainLimitedFunction< R, D > > makeFirstQuadrantLimitedFunction(const Ptr< const IFunction< R, D >> &f)
Definition: CompoundFunctions.h:71
inet::INITSTAGE_LOCAL
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
inet::sctp::max
double max(const double a, const double b)
Returns the maximum of a and b.
Definition: SctpAssociation.h:266
inet::physicallayer::DimensionalTransmitterBase::timeGainsNormalization
const char * timeGainsNormalization
Definition: DimensionalTransmitterBase.h:43
inet::math::Domain
This class represents the domain of a mathematical function.
Definition: Domain.h:24
inet::physicallayer::DimensionalTransmitterBase::frequencyGains
std::vector< GainEntry< Hz > > frequencyGains
Definition: DimensionalTransmitterBase.h:42
inet::physicallayer::DimensionalTransmitterBase::firstFrequencyInterpolator
const IInterpolator< Hz, double > * firstFrequencyInterpolator
Definition: DimensionalTransmitterBase.h:40
inet::physicallayer::DimensionalTransmitterBase::firstTimeInterpolator
const IInterpolator< simsec, double > * firstTimeInterpolator
Definition: DimensionalTransmitterBase.h:39
inet::physicallayer::DimensionalTransmitterBase::frequencyGainsNormalization
const char * frequencyGainsNormalization
Definition: DimensionalTransmitterBase.h:44