LinkMargin(name: str = 'Link margin', description: str = '', required_ebno_db: float | None = None, required_esno_db: float | None = None, required_cn_db: float | None = None, required_snr_db: float | None = None, noise_bandwidth: float | None = None, data_rate: float | None = None, symbol_rate: float | None = None, implementation_loss_db: float = 0.0, coding_gain_db: float = 0.0)
Bases: Component
Terminal analysis stage: compares the achieved link quality against a
required threshold and reports the margin.
Signal and noise pass through unchanged; the stage is annotated with
achieved_snr_db, achieved_ebno_db / achieved_esno_db,
required_db, margin_db and closes.
Provide the requirement as exactly one of required_ebno_db,
required_esno_db, required_cn_db or required_snr_db. When the
requirement is Eb/N0 or Es/N0, noise_bandwidth and data_rate
(or symbol_rate) are needed to convert the achieved C/N.
coding_gain_db is added to the achieved metric and
implementation_loss_db is subtracted from it before the margin is
taken.
Source code in linkbudget/margin.py
| def __init__(self, name: str = "Link margin", description: str = "",
required_ebno_db: float | None = None,
required_esno_db: float | None = None,
required_cn_db: float | None = None,
required_snr_db: float | None = None,
noise_bandwidth: float | None = None, data_rate: float | None = None,
symbol_rate: float | None = None, implementation_loss_db: float = 0.0,
coding_gain_db: float = 0.0) -> None:
requirements = {
"required_ebno_db": required_ebno_db,
"required_esno_db": required_esno_db,
"required_cn_db": required_cn_db,
"required_snr_db": required_snr_db,
}
given = [key for key, value in requirements.items() if value is not None]
if len(given) != 1:
raise ValueError(
"give exactly one of " + ", ".join(requirements) + f" (got {given})")
self.name = name
self.description = description
self.required_ebno_db = required_ebno_db
self.required_esno_db = required_esno_db
self.required_cn_db = required_cn_db
self.required_snr_db = required_snr_db
self.noise_bandwidth = noise_bandwidth
self.data_rate = data_rate
self.symbol_rate = symbol_rate
self.implementation_loss_db = implementation_loss_db
self.coding_gain_db = coding_gain_db
|
is_margin
class-attribute
instance-attribute
description
instance-attribute
description = description
required_ebno_db
instance-attribute
required_ebno_db = required_ebno_db
required_esno_db
instance-attribute
required_esno_db = required_esno_db
required_cn_db
instance-attribute
required_cn_db = required_cn_db
required_snr_db
instance-attribute
required_snr_db = required_snr_db
noise_bandwidth
instance-attribute
noise_bandwidth = noise_bandwidth
data_rate
instance-attribute
symbol_rate
instance-attribute
symbol_rate = symbol_rate
implementation_loss_db
instance-attribute
implementation_loss_db = implementation_loss_db
coding_gain_db
instance-attribute
coding_gain_db = coding_gain_db
propagate_signal
propagate_signal(signal_power: float, noise_power: float) -> StageData
Pass the power through unchanged; annotate the stage with the
achieved metric, the requirement and the resulting margin.
Source code in linkbudget/margin.py
| def propagate_signal(self, signal_power: float, noise_power: float) -> StageData:
"""Pass the power through unchanged; annotate the stage with the
achieved metric, the requirement and the resulting margin."""
if noise_power > 0.0:
achieved_snr = signal_power / noise_power
else:
achieved_snr = float("inf")
achieved_snr_db = convert.linear_to_db(achieved_snr)
cn0 = None
if self.noise_bandwidth:
cn0 = fom.cn0_from_snr(achieved_snr_db, self.noise_bandwidth)
achieved_ebno_db = fom.ebno_db(cn0, self.data_rate) if (
cn0 is not None and self.data_rate) else None
achieved_esno_db = fom.esno_db(cn0, self.symbol_rate) if (
cn0 is not None and self.symbol_rate) else None
metric, achieved_db, required_db = self._achieved_and_required(
achieved_snr_db, cn0)
margin_db = None
if achieved_db is not None:
margin_db = (achieved_db - required_db
+ self.coding_gain_db - self.implementation_loss_db)
return {"name": self.name,
"description": self.description,
"signal_power_in": signal_power,
"noise_power_in": noise_power,
"signal_power_out": signal_power,
"noise_power_out": noise_power,
"metric": metric,
"achieved_snr_db": achieved_snr_db,
"achieved_ebno_db": achieved_ebno_db,
"achieved_esno_db": achieved_esno_db,
"achieved_db": achieved_db,
"required_db": required_db,
"coding_gain_db": self.coding_gain_db,
"implementation_loss_db": self.implementation_loss_db,
"margin_db": margin_db,
"closes": bool(margin_db is not None and margin_db >= 0.0)}
|