Skip to content

RF Chain

RF chain models for transmit power, losses, noise temperature, and cascaded stage analysis.

The simple RFChainModel is documented in Core Models. This page covers the cascaded multi-stage chain.

RF Stage

RFStage dataclass

RFStage(name, gain_db, nf_db, iip3_dbm=None)

A single RF stage (LNA, filter, mixer, PA, etc.).

Parameters:

Name Type Description Default
name str

Human-readable stage identifier (e.g., "LNA", "BPF", "PA").

required
gain_db float

Stage gain in dB. Use negative values for lossy elements (filters, cables).

required
nf_db float

Noise figure in dB. For a passive loss of L dB, NF = L dB.

required
iip3_dbm float | None

Input-referred third-order intercept point in dBm. None means the stage is assumed linear (e.g., passive filter).

None

Cascaded RF Chain

CascadedRFChain

CascadedRFChain(stages, tx_power_w=1.0)

Multi-stage RF chain with Friis noise cascade and IIP3 cascade.

Supports both TX and RX chain analysis. For a receive chain the key output is cascaded noise temperature; for a transmit chain the key output is total gain/loss from PA to antenna feed.

Parameters:

Name Type Description Default
stages list of RFStage

Ordered list of stages from input to output.

required
tx_power_w float

Transmit power at PA output in watts (default 1.0).

1.0

Examples:

>>> chain = CascadedRFChain([
...     RFStage("LNA", gain_db=20.0, nf_db=1.5),
...     RFStage("BPF", gain_db=-2.0, nf_db=2.0),
... ])
>>> chain.cascaded_nf_db()
1.52
Source code in src/opensatcom/rf/cascade.py
def __init__(self, stages: list[RFStage], tx_power_w: float = 1.0) -> None:
    if not stages:
        raise ValueError("CascadedRFChain requires at least one stage")
    self._stages = list(stages)
    self._tx_power_w = tx_power_w

total_gain_db

total_gain_db()

Total cascaded gain in dB (sum of all stage gains).

Returns:

Type Description
float

Total gain in dB.

Source code in src/opensatcom/rf/cascade.py
def total_gain_db(self) -> float:
    """Total cascaded gain in dB (sum of all stage gains).

    Returns
    -------
    float
        Total gain in dB.
    """
    return sum(s.gain_db for s in self._stages)

total_gain_lin

total_gain_lin()

Total cascaded gain as a linear ratio.

Returns:

Type Description
float

Total gain as a linear power ratio.

Source code in src/opensatcom/rf/cascade.py
def total_gain_lin(self) -> float:
    """Total cascaded gain as a linear ratio.

    Returns
    -------
    float
        Total gain as a linear power ratio.
    """
    return db10_to_lin(self.total_gain_db())

cascaded_nf_db

cascaded_nf_db()

Cascaded noise figure in dB using Friis formula.

F_total = F_1 + (F_2 - 1)/G_1 + (F_3 - 1)/(G_1 * G_2) + ...

Returns:

Type Description
float

Cascaded noise figure in dB.

Source code in src/opensatcom/rf/cascade.py
def cascaded_nf_db(self) -> float:
    """Cascaded noise figure in dB using Friis formula.

    F_total = F_1 + (F_2 - 1)/G_1 + (F_3 - 1)/(G_1 * G_2) + ...

    Returns
    -------
    float
        Cascaded noise figure in dB.
    """
    return lin_to_db10(self._cascaded_nf_lin())

cascaded_noise_temp_k

cascaded_noise_temp_k()

Equivalent input noise temperature from cascaded NF.

T_e = T_ref * (F - 1) where T_ref = 290 K.

Returns:

Type Description
float

Equivalent noise temperature in Kelvin.

Source code in src/opensatcom/rf/cascade.py
def cascaded_noise_temp_k(self) -> float:
    """Equivalent input noise temperature from cascaded NF.

    T_e = T_ref * (F - 1)  where T_ref = 290 K.

    Returns
    -------
    float
        Equivalent noise temperature in Kelvin.
    """
    return T_REF_K * (self._cascaded_nf_lin() - 1.0)

cascaded_iip3_dbm

cascaded_iip3_dbm()

Cascaded input-referred IIP3 in dBm.

1/IIP3_total = 1/IIP3_1 + G_1/IIP3_2 + G_1*G_2/IIP3_3 + ...

Returns:

Type Description
float or None

Cascaded IIP3 in dBm, or None if no stage has IIP3 defined.

Source code in src/opensatcom/rf/cascade.py
def cascaded_iip3_dbm(self) -> float | None:
    """Cascaded input-referred IIP3 in dBm.

    1/IIP3_total = 1/IIP3_1 + G_1/IIP3_2 + G_1*G_2/IIP3_3 + ...

    Returns
    -------
    float or None
        Cascaded IIP3 in dBm, or None if no stage has IIP3 defined.
    """
    # Collect stages with IIP3
    has_iip3 = any(s.iip3_dbm is not None for s in self._stages)
    if not has_iip3:
        return None

    inv_iip3_total = 0.0
    cumulative_gain = 1.0
    for i, stage in enumerate(self._stages):
        if stage.iip3_dbm is not None:
            iip3_lin = db10_to_lin(stage.iip3_dbm / 10.0 * 10.0)  # dBm to mW
            inv_iip3_total += cumulative_gain / iip3_lin
        cumulative_gain *= db10_to_lin(stage.gain_db)

    if inv_iip3_total == 0.0:
        return None
    return lin_to_db10(1.0 / inv_iip3_total)

tx_losses_db

tx_losses_db()

Total TX loss (negative of total gain when gain < 0).

For a TX chain where stages represent post-PA losses (feed, cable, filter), this returns the magnitude of loss in dB (positive number).

Returns:

Type Description
float

Total TX-path loss in dB (positive number, 0.0 if net gain).

Source code in src/opensatcom/rf/cascade.py
def tx_losses_db(self) -> float:
    """Total TX loss (negative of total gain when gain < 0).

    For a TX chain where stages represent post-PA losses (feed, cable,
    filter), this returns the magnitude of loss in dB (positive number).

    Returns
    -------
    float
        Total TX-path loss in dB (positive number, 0.0 if net gain).
    """
    total = self.total_gain_db()
    return -total if total < 0 else 0.0

to_simple_rf_chain

to_simple_rf_chain()

Convert to the simple RFChainModel for backward compatibility.

Maps cascaded noise temp to rx_noise_temp_k and cascaded losses to tx_losses_db.

Returns:

Type Description
RFChainModel

Simplified RF chain model.

Source code in src/opensatcom/rf/cascade.py
def to_simple_rf_chain(self) -> RFChainModel:
    """Convert to the simple RFChainModel for backward compatibility.

    Maps cascaded noise temp to ``rx_noise_temp_k`` and cascaded
    losses to ``tx_losses_db``.

    Returns
    -------
    RFChainModel
        Simplified RF chain model.
    """
    return RFChainModel(
        tx_power_w=self._tx_power_w,
        tx_losses_db=self.tx_losses_db(),
        rx_noise_temp_k=self.cascaded_noise_temp_k(),
    )