"""
The ska_oso_pdm._shared.spfrx module defines a Python representation of
SPFRx (Single-Pixel Feed receiver) configuration. SPFRx parameters apply
only to SKA-Mid targets.
"""
from typing import Annotated, Literal
from astropy import units
from pydantic import AfterValidator, Discriminator, Field
from ska_oso_pdm._shared import AstropyQuantity, PdmObject, TerseStrEnum, UnitHelpers
from ska_oso_pdm._shared.custom_types import Quantity
[docs]
class NoiseDiodeMode(TerseStrEnum):
"""
NoiseDiodeMode is an enumeration of SPFRx noise diode operating modes.
"""
PERIODIC = "periodic"
PSEUDO_RANDOM = "pseudo_random"
[docs]
class SPFRxNoiseDiodeDurationUnits(TerseStrEnum):
"""
Units for SPFRx noise diode durations (period, duty cycle, phase shift,
dwell).
"""
SECONDS = "s"
MILLISECONDS = "ms"
MICROSECONDS = "us"
NANOSECONDS = "ns"
[docs]
class SPFRxNoiseDiodeDurationQuantity(Quantity):
unit = units.Unit(SPFRxNoiseDiodeDurationUnits.MILLISECONDS)
def _constrain_non_negative(qty: units.Quantity) -> units.Quantity:
if qty.value < 0:
raise ValueError(f"Value must be >= 0, got {qty.value}")
return qty
SPFRxNoiseDiodeDurationQuantityType = Annotated[
AstropyQuantity,
SPFRxNoiseDiodeDurationQuantity,
AfterValidator(UnitHelpers.constrain_unit_to(SPFRxNoiseDiodeDurationUnits)),
AfterValidator(_constrain_non_negative),
]
[docs]
class PeriodicNoiseDiodeConfig(PdmObject):
"""
PeriodicNoiseDiodeConfig configures the SPFRx noise diode to fire on a
fixed period.
:param period: the noise diode period, must be >= 0
:param duty_cycle: the duration for which the noise diode should be on.
If duty_cycle > period, then the noise diode will be on 100% of the
time. Must be >= 0
:param phase_shift: the phase shift of the periodic signal, must be >= 0
"""
mode: Literal[NoiseDiodeMode.PERIODIC] = NoiseDiodeMode.PERIODIC
period: SPFRxNoiseDiodeDurationQuantityType = units.Quantity(
value=0, unit=SPFRxNoiseDiodeDurationUnits.MILLISECONDS
)
duty_cycle: SPFRxNoiseDiodeDurationQuantityType = units.Quantity(
value=0, unit=SPFRxNoiseDiodeDurationUnits.MILLISECONDS
)
phase_shift: SPFRxNoiseDiodeDurationQuantityType = units.Quantity(
value=0, unit=SPFRxNoiseDiodeDurationUnits.MILLISECONDS
)
[docs]
class PseudoRandomNoiseDiodeConfig(PdmObject):
"""
PseudoRandomNoiseDiodeConfig configures the SPFRx noise diode to fire
according to a pseudo-random binary sequence.
:param binary_polynomial: defines which bits of the shift register are fed
back to generate the next bit sequence, must be >= 0
:param seed: initial state of the shift register in the PRBS generator,
must be >= 0
:param dwell: time interval between transitions to the next bit, must be >= 0
"""
mode: Literal[NoiseDiodeMode.PSEUDO_RANDOM] = NoiseDiodeMode.PSEUDO_RANDOM
binary_polynomial: int = Field(ge=0)
seed: int = Field(ge=0)
dwell: SPFRxNoiseDiodeDurationQuantityType = units.Quantity(
value=0, unit=SPFRxNoiseDiodeDurationUnits.MILLISECONDS
)
NoiseDiodeConfigUnion = Annotated[
PeriodicNoiseDiodeConfig | PseudoRandomNoiseDiodeConfig,
Discriminator("mode"),
]
[docs]
class TargetSPFRxConfiguration(PdmObject):
"""
TargetSPFRxConfiguration holds dish-level SPFRx (Single-Pixel Feed
Receiver) settings carried on the target configuration for SKA-Mid.
:param attenuation_1_x: optional attenuation for receptor 1, X polarisation, dB,
0.0-31.75
:param attenuation_1_y: optional attenuation for receptor 1, Y polarisation, dB,
0.0-31.75
:param attenuation_2_x: optional attenuation for receptor 2, X polarisation, dB,
0.0-31.75
:param attenuation_2_y: optional attenuation for receptor 2, Y polarisation, dB,
0.0-31.75
:param noise_diode: optional noise diode configuration
"""
attenuation_1_x: float | None = Field(default=None, ge=0.0, le=31.75)
attenuation_1_y: float | None = Field(default=None, ge=0.0, le=31.75)
attenuation_2_x: float | None = Field(default=None, ge=0.0, le=31.75)
attenuation_2_y: float | None = Field(default=None, ge=0.0, le=31.75)
noise_diode: NoiseDiodeConfigUnion | None = None