Source code for edges.analysis.loss

"""Functions defining expected losses from the instruments."""

import warnings
from pathlib import Path

import attrs
import numpy as np
import numpy.typing as npt
from astropy import units as un

from ..cal import loss
from ..cal import sparams as sp
from ..config import config


[docs] def low2_balun_connector_loss( ants11: sp.ReflectionCoefficient | str | Path, use_approx_eps0: bool = True, connector: sp.CoaxialCable = sp.KNOWN_CABLES["SC3792 Connector"], balun: sp.CoaxialCable = sp.KNOWN_CABLES["lowband-balun-tube"], ) -> npt.NDArray: """Obtain the balun and connector loss for the low-2 instrument on-site at MRO. Parameters ---------- freq An array of frequencies at which to calculate the balun+connector loss. ants11 The antenna S11, either as a numpy array, a path to a file containing the S11, or a S11Model instance. use_approx_eps0 : bool, optional Whether to approximate the vacuum electric permittivity as 8.854e-12 F/m instead of the ~10-digit accuracy it has from astropy. This is mainly for backward compatibility with previous results. Default is True. connector The connector to use. Default is the SC3792 connector. balun The balun to use. Default is the lowband-balun-tube. Returns ------- loss : np.ndarray The balun+connector loss as a function of frequency (same length as `freq`). """ if use_approx_eps0: connector = attrs.evolve(connector, eps0=8.854e-12 * un.F / un.m) balun = attrs.evolve(balun, eps0=8.854e-12 * un.F / un.m) # Get the antenna s11 if isinstance(ants11, str | Path): ants11 = sp.ReflectionCoefficient.from_file(ants11) mdl = loss.get_cable_loss_model([connector, balun]) return mdl(ants11)
def _get_loss(fname: str | Path, freq: np.ndarray, n_terms: int) -> np.ndarray: gr = np.genfromtxt(fname) fr = gr[:, 0] dr = gr[:, 1] par = np.polyfit(fr, dr, n_terms) model = np.polyval(par, freq) return 1 - model def _get_loss_from_datafile( filename: str | Path, freq: np.ndarray, instrument: str | None, configuration: str, loss_type: str, n_terms: int, ) -> np.ndarray: if str(filename).startswith(":"): if instrument is None: raise ValueError( f"For non-absolute path {filename}, you must provide 'band'." ) if str(filename) == ":": # Use the built-in loss files if configuration: loss_type += f"_{configuration}" filename = ( Path(__file__).parent / "data" / "loss" / instrument / f"{loss_type}.txt" ) if not filename.exists(): warnings.warn( f"Ground loss file {filename} does not exist. Returning ones.", stacklevel=2, ) return np.ones(freq.shape) else: # Find the file in the standard directory structure filename = config.antenna / instrument / "loss" / str(filename)[1:] else: filename = Path(filename) return _get_loss(str(filename), freq, n_terms)
[docs] def ground_loss( freq: np.ndarray, filename: str | Path, instrument: str | None = None, configuration: str = "", ) -> np.ndarray: """ Calculate ground loss of a particular antenna at given frequencies. Parameters ---------- filename : path File in which value of the ground loss for this instrument are tabulated. freq : array-like Frequency in MHz. For mid-band (low-band), between 50 and 150 (120) MHz. instrument : str, optional The instrument to find the ground loss for. Only required if `filename` doesn't exist and isn't an absolute path (in which case the standard directory structure will be searched using ``band``). configuration : str, optional The configuration of the instrument. A string, such as "45deg", which defines the orientation or other configuration parameters of the instrument, which may affect the ground loss. """ return _get_loss_from_datafile( filename, freq=freq, instrument=instrument, configuration=configuration, loss_type="ground", n_terms=8, )
[docs] def antenna_loss( freq: np.ndarray, filename: str | Path, instrument: str | None = None, configuration: str = "", ): """ Calculate antenna loss of a particular antenna at given frequencies. Parameters ---------- filename : path File in which value of the antenna loss for this instrument are tabulated. freq : array-like Frequency in MHz. For mid-band (low-band), between 50 and 150 (120) MHz. instrument The instrument to find the antenna loss for. Only required if `filename` starts with the magic ':' (in which case the standard directory structure will be searched using ``band``). configuration : str, optional The configuration of the instrument. A string, such as "45deg", which defines the orientation or other configuration parameters of the instrument, which may affect the antenna loss. """ return _get_loss_from_datafile( filename, freq=freq, instrument=instrument, configuration=configuration, loss_type="ground", n_terms=11, )