Source code for ska_mid_cbf_fhs_common.helpers.power_calculations

"""Helper function(s) for power/gain calculations."""

from mpmath import mp

from ska_mid_cbf_fhs_common.helpers.math import FHS_MPMATH_PRECISION, FloatLike, MPFloat


[docs] def calculate_gain_multiplier(p_max: FloatLike, measured_power: FloatLike, headroom: FloatLike) -> MPFloat: """ Calculate the gain multiplier required to apply to the signal to achieve the optimal output power adhering to the provided headroom. Args: p_max (:obj:`FloatLike`): Maximum signal power, in decibels (dB). measured_power (:obj:`FloatLike`): Average power measurement (is this in volts?). Must be within the interval (0, 1]. headroom (:obj:`FloatLike`): Requested RFI headroom, in decibels (dB). Returns: :obj:`MPFloat`: The gain multiplier to apply to the signal. """ if measured_power <= 0 or measured_power > 1: raise ValueError(f"The measured power must be within the interval (0, 1]. Got: {measured_power}") mp.dps = FHS_MPMATH_PRECISION p_max = MPFloat(p_max) measured_power = MPFloat(measured_power) headroom = MPFloat(headroom) p_measured = mp.fmul(10, mp.log10(measured_power)) # Measured power, in dB gain = mp.fsub(mp.fsub(p_max, p_measured), headroom) # Required gain, in dB return mp.power(10, mp.fdiv(gain, 20)) # Gain multiplier to apply to the signal
[docs] def calculate_output_power(measured_power: FloatLike, multiplier: FloatLike) -> MPFloat: """ Calculate the power achieved after applying the specified gain multiplier. Args: measured_power (:obj:`FloatLike`): Average power measurement (is this in volts?). Must be within the interval (0, 1]. multiplier (:obj:`FloatLike`): Gain multiplier to apply to the measured power. Returns: :obj:`MPFloat`: The calculated output power. """ if measured_power <= 0 or measured_power > 1: raise ValueError(f"The measured power must be within the interval (0, 1]. Got: {measured_power}") if multiplier <= 0: raise ValueError(f"The multiplier must be positive. Got: {multiplier}") mp.dps = FHS_MPMATH_PRECISION measured_power = MPFloat(measured_power) multiplier = MPFloat(multiplier) return mp.fmul(mp.power(multiplier, 2), measured_power)
[docs] def calculate_expected_power(p_max: FloatLike, headroom: FloatLike) -> MPFloat: """ Calculate the expected optimal output power adhering to the provided headroom. Args: p_max (:obj:`FloatLike`): Maximum signal power, in decibels (dB). headroom (:obj:`FloatLike`): Requested RFI headroom, in decibels (dB). Returns: :obj:`MPFloat`: The expected optimal output power. """ mp.dps = FHS_MPMATH_PRECISION p_max = MPFloat(p_max) headroom = MPFloat(headroom) return mp.power(10, mp.fdiv(mp.fsub(p_max, headroom), 10))