rfgen.core.protocols and rfgen.core.pipeline¶
Scientific validation
The channel pipeline transformations and their immutable parameter record have been scientifically validated against published references. See the per-component reports:
Device fingerprint: validated with documented limitations.
TX power-amplifier nonlinearity (Rapp, Saleh): validated with documented limitations.
TX phase noise (Leeson): validated with documented limitations.
TX IQ imbalance, DAC quantization, CFO: validated.
AWGN channel propagation: validated.
RX mixer, IF filter, resampler: validated with documented limitations.
RX LNA noise, ADC quantization, AGC: validated with documented limitations.
RX phase noise and IQ imbalance: validated with documented limitations.
Each report covers construct validity, mathematical correctness against cited equations, empirical comparison to published reference numbers, literature grounding, experimental methodology, operating envelope, and documented limitations.
The rfgen.core.protocols module ships the channel-transformation contract: the BaseChannel ABC, the per-call ChannelContext and ChannelRxParams value types, and the SpectralEffect, Transformation, and Group enums. Concrete per-transformation ABCs and their built-in implementations live in sibling modules:
TorchSig, the external RFML benchmark library, appears only in the opt-in adapter path; see TorchSig Interop.
Module |
API page |
What it ships |
|---|---|---|
|
TX-side concretes (DAC, PA, TX phase noise, TX IQ-imbalance, CFO) |
|
|
AWGN and the Sionna-backed propagation skeletons |
|
|
The receiver stage core: the one implementation of each receiver stage (LO error, mixer, IF filter, resampler, SRO, LNA noise, ADC, RX phase noise, IQ imbalance, AGC) |
The per-device fingerprint store lives in rfgen.calibration.fingerprint; see the Device Fingerprint reference for FingerprintParams and DeviceRegistry.
This page documents the common surface. The per-transformation ABCs are
listed in the class index with cross-references to their owning module page.
The nine receiver ABCs are stage families rather than BaseChannel subclasses;
they are listed here for the slot map and documented on the receiver-stages page.
Pipeline model¶
The pipeline is a sequence of BaseChannel subclasses with one transformation per slot. Each concrete pins its slot via the Transformation class variable; the scene composer reads that variable to dispatch each emitter through the canonical pipeline order.
The 15 transformations split across a pre-sum and a post-sum boundary. TX stages run per emitter; propagation follows scene.channel_application (per path or, when supported, on the summed receiver buffer); the nine RX-capture and RX-hardware stages run post-sum per receiver.
The emitter plugin’s baseband modulation is outside this pipeline; it is the
emitter contract, not a channel transformation. In composed scenes, the scene
composer writes each placed component’s absolute realized_carrier_hz after
frequency placement. Each receiver carries center_freq_hz, bandwidth_hz,
sample_rate_hz, and noise_figure_db on its
ChannelRxParams instance.
Class index¶
Class |
Kind |
Group / Role |
|---|---|---|
abc |
Common ABC; every concrete transformation inherits from this |
|
datatype |
Per-call context passed to every |
|
datatype |
Active receiver RF and hardware parameters |
|
dataclass |
Validated, ordered chain of |
|
alias |
Alias of |
|
sentinel |
Pydantic model returned from |
|
TypedDict |
Schema for one entry of |
|
|
constant |
Canonical key tuple consumed from |
enum |
Declares whether a transformation preserves or updates spectral coordinates |
|
enum |
|
|
enum |
|
|
|
abc |
TX impairments: DAC quantization (lives in |
|
abc |
TX impairments: PA nonlinearity (lives in |
|
abc |
TX impairments: TX phase noise (lives in |
|
abc |
TX impairments: TX IQ imbalance (lives in |
|
abc |
TX impairments: CFO (lives in |
|
abc |
Channel propagation (lives in |
|
abc |
Receiver capture plane: LO frequency error (lives in |
|
abc |
Receiver capture plane: RX mixer (lives in |
|
abc |
Receiver capture plane: IF filter (lives in |
|
abc |
Receiver capture plane: resampler (lives in |
|
abc |
Receiver capture plane: LNA noise (lives in |
|
abc |
Receiver hardware plane: ADC quantization (lives in |
|
abc |
Receiver hardware plane: RX phase noise (lives in |
|
abc |
Receiver hardware plane: RX IQ imbalance (lives in |
|
abc |
Receiver hardware plane: AGC (lives in |
For per-class signatures of TX, propagation, and RX concretes, see the TX Impairments, Engine, and Receiver stages pages.
class rfgen.core.protocols.SpectralEffect¶
class SpectralEffect(StrEnum):
PRESERVES = "preserves"
UPDATES = "updates"
Classifies the intended relationship between the input and output spectral metadata of one BaseChannel call. Spectral metadata means the sample rate, occupied bandwidth, and realized carrier coordinates stored with a signal.
Member |
Declared transformation model |
|---|---|
|
The transformation describes its spectral coordinates as unchanged. This is the default on |
|
The transformation describes itself as changing spectral coordinates. |
The declaration communicates transformation taxonomy; it is not a runtime guarantee that coordinates were preserved or updated. Returned metadata is authoritative. The fixed-window renderer validates only that returned metadata is finite, has positive sample rate and bandwidth, and represents one interval within the capture. It does not assert output frequency or estimate spectral coordinates from I/Q samples.
class rfgen.core.enums.Group¶
class Group(IntEnum):
TX = 1 # per-emitter TX impairments
CHANNEL = 2 # per-(emitter, RX) pair propagation
Pipeline group tag. The leading digit of a Transformation integer is its group; the trailing digit is intra-group order. Group is distinct from Transformation: Group partitions the pre-sum chain; Transformation names individual operations within a group.
Both members are pre-sum. The receiver is not a pipeline group: its nine transformations run in exactly one place, the shared receiver frontend chain, so there is no partition left for a group to express. The integers 3 and 4 are retired rather than reused, because stored transformation-log entries carry them as pinned constants.
Transformation carries a .group property that returns the matching Group member for TX and CHANNEL transformations, and a .is_receiver predicate that is True for the nine receiver transformations. Reading .group on a receiver transformation raises ValidationError.
class rfgen.core.enums.Transformation¶
class Transformation(IntEnum):
# Group.TX (10s)
DAC = 11
PA = 12
TX_PHASE_NOISE = 13
TX_IQ_IMB = 14
CFO = 15
# Group.CHANNEL (20s)
PROPAGATION = 21
# Receiver, capture plane (30s)
RX_LO_FREQUENCY_ERROR = 30
RX_MIXER = 31
IF_FILTER = 32
RESAMPLER = 33
LNA_NOISE = 34
# Receiver, hardware plane (40s)
ADC = 41
RX_PHASE_NOISE = 42
RX_IQ_IMB = 43
AGC = 44
Integer tag pinned to every concrete channel implementation as a ClassVar[Transformation]. The integer value encodes ordering: value // 10 is the Group integer, value % 10 is the intra-group canonical order. The scene composer reads this tag to dispatch each emitter through the pipeline in monotonic order.
Notes¶
Multiple concrete implementations per transformation are allowed; only one transformation tag per class.
Do not define a new class with a Transformation value that does not appear in this enum. Renumbering existing members is a breaking change for the config validator.
class rfgen.core.protocols.ChannelContext¶
@dataclass(frozen=True, slots=True)
class ChannelContext:
"""Per-call context handed to every BaseChannel.apply() invocation."""
emitter_meta: SignalMetadata
rx_params: ChannelRxParams
scene_id: str
sample_idx: int
rng: torch.Generator
tx_pose: GeometryPose | None = None
geometry_asset_refs: tuple[GeometryAssetRef, ...] = ()
rt_solver_params: BaseModel | None = None
Kind. Frozen dataclass / value type.
Carries the per-transformation call context into BaseChannel.apply(). The scene driver constructs one ChannelContext per (emitter, RX, transformation) call; it is not shared across calls.
Fields¶
Field |
Type |
Description |
|---|---|---|
|
Ground-truth metadata for the emitter being transformed. TX-side transformations read |
|
|
The active receiver’s RF and hardware parameters. Carries |
|
|
str |
Stable scene identifier, used by transformations to derive deterministic per-scene seeds when needed. |
|
int |
Zero-based index of this sample within the current shard. Combined with |
|
|
The per-call RNG. All randomness inside |
|
GeometryPose | None |
Optional typed transmitter pose for Sionna propagation. |
|
|
Geometry assets active for this channel call. |
|
|
Optional solver configuration. |
Fingerprint fallback contract¶
When emitter_meta.extras does NOT contain the "fingerprint_params" slot, transformations that consume per-device priors MUST read defaults from FingerprintParams() (the device-fingerprint Pydantic model instantiated with declared default-prior values, which corresponds to the population-level prior mean). Such transformations MUST emit a transformation_log entry with fallback=True and fallback_reason="missing_fingerprint_params". Contract tests verify this fallback shape.
class rfgen.core.protocols.ChannelRxParams¶
@dataclass(frozen=True, slots=True)
class ChannelRxParams:
"""Active receiver RF and hardware parameters."""
center_freq_hz: float
bandwidth_hz: float
sample_rate_hz: float
noise_figure_db: float
rx_pose: GeometryPose | None = None
antenna_id: str | None = None
tag: str | None = None
Kind. Frozen dataclass / value type.
The per-receiver RF and hardware parameters passed through ChannelContext.rx_params. Built by the scene driver from the active ReceiverConfig for each receiver in the scene.
Fields¶
Field |
Type |
Required |
Default |
Description |
|---|---|---|---|---|
|
float |
yes |
– |
Receiver LO frequency in Hz. Used by |
|
float |
yes |
– |
Receiver analog capture bandwidth in Hz. Used by |
|
float |
yes |
– |
Receiver ADC sample rate in Hz. Target output rate for |
|
float |
yes |
– |
Receiver noise figure in dB. It is carried as receiver context; the shipped |
|
GeometryPose | None |
no |
|
Typed 3D receiver pose in scene-frame coordinates. It is optional for non-Sionna local transformations; every shipped Sionna backend requires it. The read-only |
|
str | None |
no |
|
Antenna-pattern identifier. Consumed by Sionna RT and PHY backends for AoA-dependent gain. |
|
str | None |
no |
|
Human-readable receiver label. The scene composer sets this to |
class rfgen.core.protocols.BaseChannel¶
class BaseChannel(ABC):
transformation: ClassVar[Transformation]
spectral_effect: ClassVar[SpectralEffect] = SpectralEffect.PRESERVES
@abstractmethod
def apply(self, signal: Signal, ctx: ChannelContext) -> Signal: ...
@abstractmethod
def schema(self) -> type[BaseModel]: ...
@classmethod
def schema_from_init(cls) -> type[BaseModel]: ...
Common ABC. Every concrete transformation inherits from a per-transformation ABC, which itself inherits from BaseChannel. BaseChannel is the type the scene composer dispatches against.
Class attributes¶
Attribute |
Type |
Description |
|---|---|---|
|
|
Identifies which of the 15 named transformations this implementation performs. The ABC enforces at class-definition time via |
|
Stored as |
Method: apply¶
@abstractmethod
def apply(self, signal: Signal, ctx: ChannelContext) -> Signal
Applies the transformation to signal and returns a new Signal with updated IQ and metadata. ctx carries the per-call context.
Parameters¶
Name |
Type |
Description |
|---|---|---|
|
Input IQ plus metadata; shape conventions follow the emitter contract |
|
|
Per-call context: |
Returns¶
A new Signal with the same IQ shape (unless the transformation changes sample rate) and metadata updated to reflect the applied operation.
Method: schema¶
@abstractmethod
def schema(self) -> type[BaseModel]
Returns the Pydantic model describing this transformation’s parameters. Subclasses with no parameters return EmptyParams; subclasses with keyword-only __init__ parameters MAY delegate to cls.schema_from_init().
Method: schema_from_init (classmethod, cached)¶
@classmethod
@functools.cache
def schema_from_init(cls) -> type[BaseModel]
Builds a Pydantic model from the subclass’s __init__ signature. Each keyword argument (excluding self and ctx) becomes a field with the parameter annotation forwarded as the field type and the parameter default forwarded as the field default; parameters without a default become required. Subclasses with no keyword arguments return EmptyParams.
The result is cached per-class via functools.cache, so repeated calls in hot loops are O(1) after the first invocation.
Extension contract¶
Every subclass of BaseChannel (whether via a per-transformation ABC or directly) MUST satisfy these invariants:
IQ shape.
apply()MUST return a Signal whoseiqhas shape(2, N)whereN == signal.iq.shape[-1], with the following exception:BaseResamplerimplementations MAY return a differentNequal toint(round(signal.iq.shape[-1] * ctx.rx_params.sample_rate_hz / signal.metadata.sample_rate_hz)). No other transformation may change the sample count.No in-place mutation.
apply()MUST NOT modifysignal.iqorsignal.metadatain place. Return a new Signal object; the input must be unchanged after the call.Metadata update.
apply()MUST return authoritative metadata and update every field its transformation affects. SpectralEffect communicates the transformation’s spectral model; it does not cause fixed-window rendering to enforce a frequency-preservation or frequency-update relationship. Fixed-window rendering validates only finite, positive, representable post-transform metadata. Implementations SHOULD append a TransformationLogEntry describing the realised parameters.Randomness source. All randomness MUST be drawn from
ctx.rng. Subclasses MUST NOT use module-level random state,random.random(), ortorch.rand()without a generator.transformationClassVar. Must equal theTransformationenum member identifying this slot. The ABC enforces this at class definition; missing or incorrectly-typed values raiseTypeError.No side effects.
apply()MUST NOT perform I/O, network calls, or mutations of shared state. State that persists across calls (e.g., per-device filter kernels) must be stored as instance attributes, not module globals.
Extension points¶
Method |
Status |
Notes |
|---|---|---|
|
Must override |
Core transformation logic; the primary abstract method |
|
Must override |
Return a Pydantic model for config validation; return |
|
Must set as ClassVar |
Set to the matching |
Notes¶
Do not inherit directly from BaseChannel to add a new transformation implementation. Inherit from the per-transformation ABC for the relevant slot, such as
BasePANonlinearityfor PA nonlinearity.Concrete-to-concrete inheritance is forbidden per project conventions.
class rfgen.core.protocols.EmptyParams¶
class EmptyParams(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid")
Sentinel Pydantic model returned from BaseChannel.schema() by transformations that take no parameters. The model has no fields, so EmptyParams.model_fields == {} and EmptyParams().model_dump() == {}.
class rfgen.core.protocols.TransformationLogEntry¶
class TransformationLogEntry(TypedDict):
name: str
group: int
transformation: int
params: dict[str, object]
applied_at_iso: str
fallback: bool
fallback_reason: str
TypedDict schema for one entry of SignalMetadata.transformation_log. Channel implementations append one TransformationLogEntry per applied transformation; audit and replay tooling consumes the log key-by-key.
Keys¶
Key |
Type |
Description |
|---|---|---|
|
str |
Human-readable transformation name (e.g. |
|
int |
Group integer (1…4). |
|
int |
Transformation integer. |
|
dict[str, object] |
Pydantic |
|
str |
Fixed ISO-8601 UTC provenance marker |
|
bool |
|
|
str |
Free-form reason string when |
ChannelChainConfig¶
ChannelChainConfig = ChannelConfig
Kind. Module-level alias (not a new class).
ChannelChainConfig is an alias of ChannelConfig, the Pydantic config model that already carries the chain field and its cross-entry invariants. The alias gives ChannelPipeline.from_config(ChannelChainConfig) a distinct name without duplicating the config model.
Construct via ChannelConfig directly:
from rfgen.config.channel import ChannelConfig
from rfgen.core.pipeline import ChannelChainConfig # same object
assert ChannelChainConfig is ChannelConfig # True
See ChannelConfig on the Config page for the full field list.
class rfgen.core.pipeline.ChannelPipeline¶
@dataclass(frozen=True, slots=True)
class ChannelPipeline:
chain: tuple[BaseChannel, ...] = ()
receiver_stages: tuple[BaseReceiverStage, ...] = ()
def __init__(
self,
transformations: Sequence[BaseChannel] = (),
receiver_stages: Sequence[BaseReceiverStage] = (),
) -> None: ...
@classmethod
def from_config(cls, config: ChannelChainConfig) -> ChannelPipeline: ...
Kind. Frozen dataclass. Lives in rfgen.core.pipeline, exported from rfgen.core.pipeline.__all__.
A validated, ordered chain of BaseChannel transformations, plus the receiver stages held beside it. The pipeline carries no DSP code: it holds the BaseChannel instances in canonical pipeline order, the receiver stages in configured order, and exposes the four partition properties consumed by the scene composer. Two mutation paths are blocked by the frozen-dataclass contract:
pipeline.chain[i] = otherraisesTypeError(tuple is immutable).pipeline.chain = (...)raisesdataclasses.FrozenInstanceError(frozen dataclass).
Attributes¶
Attribute |
Type |
Description |
|---|---|---|
|
|
Validated transformation chain, in canonical pipeline order. Read-only; set once at construction. |
|
|
Validated receiver-frontend stages, in configured order. Read-only; set once at construction. |
Constructor¶
ChannelPipeline(
transformations: Sequence[BaseChannel] = (),
receiver_stages: Sequence[BaseReceiverStage] = (),
)
Validates and freezes the transformation chain and the receiver stages.
Parameters¶
Name |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Ordered sequence of BaseChannel instances. An empty sequence is allowed; the scene composer documents which groups it requires. |
|
|
|
Ordered sequence of receiver-frontend stages, in canonical plane order. These are not chain entries: the composer runs them through the shared receiver frontend chain, in two segments. See Receiver stages. |
Raises¶
ChannelError when any of the following invariants is violated:
Invariant |
Trigger |
|---|---|
All entries are |
Any entry fails |
Group order is monotonic non-decreasing |
An entry’s |
Intra-group ordinals are monotonic non-decreasing |
Within the same Group, an entry’s |
At most one |
More than one propagation transformation appears in the chain |
No receiver transformation in the chain |
A chain entry pins a transformation for which |
All |
Any receiver entry fails |
The error message names the offending pair so the configuration author can correct the chain without reading the validator source.
ValidationError (not ChannelError) is raised when the receiver stages put a capture-plane stage after a hardware-plane one.
Partition properties¶
The two partition properties split chain by Group using the value // 10 rule. Their concatenation reconstructs list(chain):
tx_transforms + ([propagation] if propagation else []) == list(chain)
Property |
Type |
Description |
|---|---|---|
|
|
Entries whose |
|
|
The single |
Receiver entries are not chain entries. They are receiver-frontend stages held alongside the chain, and three attributes expose them:
Attribute |
Type |
Description |
|---|---|---|
|
|
Every configured receiver stage, in configured order. |
|
|
The subset whose family |
|
|
The subset whose family |
The plane is a stage-family ClassVar, not a configuration field, so no chain and no YAML file can move a stage to the other plane.
Dunder methods¶
Method |
Signature |
Behavior |
|---|---|---|
|
|
Returns |
|
|
Yields each |
|
|
Compares pipelines by |
|
|
Returns |
Method: from_config (classmethod)¶
@classmethod
def from_config(cls, config: ChannelChainConfig) -> ChannelPipeline
Builds a pipeline by resolving each chain entry through the plugin registry.
Each ChannelChainEntry in config.chain is resolved through an EntryPointRegistry over the rfgen.channels entry-point group. The discovered class is instantiated with the entry’s params mapping as keyword arguments. The resulting instances are then passed through the standard ChannelPipeline validator, so config-time and code-time construction enforce identical invariants.
Parameters¶
Name |
Type |
Description |
|---|---|---|
|
A validated |
Returns¶
A new ChannelPipeline whose chain contains one BaseChannel instance per non-receiver config.chain entry, and whose receiver_stages contains one BaseReceiverStage per receiver entry. Receiver entries resolve through the same registry and the same selector names; they land beside the chain rather than in it.
Raises¶
Exception |
Trigger |
|---|---|
|
Chain-level validation fails after plugin instantiation. |
|
An entry’s |
Validation invariants summary¶
Invariant |
Error type |
Error details |
|---|---|---|
All entries are |
|
Names the offending entry index and its actual type. |
Group order is monotonic non-decreasing |
|
Names the offending pair and their group labels. |
Intra-group ordinals are monotonic non-decreasing |
|
Names the offending pair, transformation names, and values. |
At most one |
|
Lists all |
Minimal example¶
from rfgen.core.pipeline import ChannelPipeline
from rfgen.hardware.tx import LinearDACQuantizer, LinearCFO
from rfgen.engine.propagation_generic import AWGNChannel
from rfgen.receiver.stages.frequency import MixerStage
from rfgen.receiver.stages.filtering import IFFilterStage
from rfgen.receiver.stages.conversion import ADCQuantizerStage
pipeline = ChannelPipeline(
transformations=[
LinearDACQuantizer(),
LinearCFO(f_offset_hz=100.0),
AWGNChannel(snr_db=20.0),
],
receiver_stages=[
MixerStage(),
IFFilterStage(),
ADCQuantizerStage(),
],
)
print(len(pipeline)) # 3, the chain only
print(pipeline.tx_transforms) # (LinearDACQuantizer, LinearCFO)
print(pipeline.propagation) # AWGNChannel instance
print(pipeline.receiver_stages) # (MixerStage, IFFilterStage, ADCQuantizerStage)
print(pipeline.capture_plane_stages) # (MixerStage, IFFilterStage)
print(pipeline.hardware_plane_stages) # (ADCQuantizerStage,)
print(repr(pipeline))
# ChannelPipeline(6 transformations: LinearDACQuantizer, LinearCFO, AWGNChannel, MixerStage, IFFilterStage, ADCQuantizerStage)
__len__ counts chain entries only; __repr__ counts both.
Passing a receiver stage in transformations raises: receiver entries belong in receiver_stages.
From config:
ChannelChainEntry.transformation is an int field backed by the
Transformation IntEnum, so a
dict passed to model_validate supplies the member or its ordinal, not the
member name. YAML channel-profile files name the member instead
(transformation: DAC); the profile loader resolves that name to the member
before validation.
from rfgen.core.pipeline import ChannelPipeline, ChannelChainConfig
from rfgen.core.enums import Transformation
from rfgen.config.channel import ChannelConfig
cfg = ChannelConfig.model_validate({
"chain": [
{"transformation": Transformation.DAC, "params": {}},
{"transformation": Transformation.PROPAGATION, "params": {"snr_db": 20.0}},
{"transformation": Transformation.ADC, "params": {}},
]
})
pipeline = ChannelPipeline.from_config(cfg)
# pipeline.chain -> (LinearDACQuantizer, AWGNChannel)
# pipeline.receiver_stages -> (ADCQuantizerStage,)
Per-transformation ABCs¶
The per-transformation ABCs live alongside their concretes in the implementation modules listed at the top of this page. Each ABC sets its transformation ClassVar to the matching Transformation member and leaves its transform method and schema abstract for concrete subclasses to override: apply for the BaseChannel families, apply_iq for the receiver stage families.
The TX-side ABCs and their concretes moved to their own package and page;
see Hardware for the five Group.TX families.
Channel propagation (rfgen.engine.propagation_generic, rfgen.engine.propagation_sionna, rfgen.engine.propagation_sionna_rt)¶
ABC |
|
Concretes shipped |
|---|---|---|
|
|
|
See Engine for per-class signatures.
Receiver capture and hardware planes (rfgen.receiver.stages)¶
ABC |
|
Plane |
Concretes shipped |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
These are receiver stages rather than BaseChannel implementations: each transforms interleaved IQ through apply_iq, and the shared rfgen.receiver.frontend.ReceiverFrontendChain owns the container. The ten registered selector names and the YAML configuration surface are unchanged. See Receiver stages for the per-class signatures.
TorchSig benchmark augmentation is outside ChannelPipeline; select the optional
classification adapter documented in TorchSig integration.
See Also¶
Concepts / Channels: mental model, boundaries, and data flow for the 4-group pipeline.
ChannelPipeline: validated chain container; constructor, partition properties, and
from_configfactory.Group: group membership enum.
Transformation: 15-member enum pinned on every concrete implementation. Fourteen transformations have dedicated ABCs; propagation uses
BaseChannelthroughBaseChannelPropagation.Reference / API / Enums: Group and Transformation entries.
Device Fingerprint:
FingerprintParamsandDeviceRegistryconsumed by TX-side and RX-hardware transformations.Engine: per-class signatures for
AWGNChanneland the Sionna-backed propagation concretes.Receiver stages: physical RX-capture and RX-hardware signatures.
Anchor aliases (cross-reference compatibility)¶
The anchors below preserve compatibility cross-reference targets. They resolve to the current per-transformation ABC index or its owning API page.
Group and Transformation define the current channel slots. The class index lists the per-transformation ABCs, five on the TX side and nine on the receiver; propagation is the remaining transformation slot.
Compatibility links for removed concrete names resolve to the current per-transformation contracts in TX Impairments, Engine, and Receiver stages. TorchSigImpairments is not a channel contract; use the optional classification augmentation boundary instead.
ChannelPipeline is a frozen dataclass in rfgen.core.pipeline with no ChainKind flag. ChannelChainConfig is an alias for ChannelConfig.
Compatibility names with the ...Channel suffix (SionnaUMaChannel, SionnaUMiChannel, SionnaRMaChannel, SionnaTDLChannel, SionnaCDLChannel, SionnaRTChannel) resolve to SionnaRT, SionnaUMa, SionnaUMi, SionnaRMa, SionnaTDL, and SionnaCDL. See Engine for the per-class signatures.