API reference

This reference is generated from the source docstrings.

telsim

simms.telescope.generate_ms.nda(items)

Convert a list of items to a Dask array with appropriate dtype.

simms.telescope.generate_ms.remove_ms(ms)
Parameters:

ms (File | str)

simms.telescope.generate_ms.create_ms(ms, telescope_name, pointing_direction, dtime, ntimes, start_freq, dfreq, nchan, correlations, row_chunks, sefd, column, smooth=None, fit_order=None, start_time=None, start_ha=None, freq_range=None, sfile=None, tsys_over_eta=None, subarray_list=None, subarray_range=None, subarray_file=None, low_source_limit=None, high_source_limit=None, telescope_name_column='TELESCOPE_NAME')

Generate a CASA Measurement Set (MS) for a simulated observation.

Parameters:
  • ms (str) – Path to output Measurement Set directory (will be overwritten if it exists).

  • telescope_name (Union[str, File]) – Telescope or array definition (name or configuration file).

  • pointing_direction (str) – Target sky direction (e.g. ‘J2000 12:34:56.7 -45.23.10’).

  • dtime (int) – Integration time per visibility (seconds).

  • ntimes (int) – Number of time steps.

  • start_freq (Union[str, float]) – Starting frequency (string with units or raw Hz).

  • dfreq (Union[str, float]) – Channel frequency increment (string with units or raw Hz).

  • nchan (int) – Number of spectral channels.

  • correlations (str) – Correlation types (e.g. ‘XX’, ‘YY’, ‘RR’, ‘LL’).

  • row_chunks (int) – Dask chunk size along the row (time-baseline) dimension.

  • sefd (float) – System Equivalent Flux Density (Jy). If provided, noise is generated.

  • column (str) – Name of data column to populate (e.g. ‘DATA’ or ‘CORRECTED_DATA’).

  • smooth (str, optional) – SEFD frequency smoothing method (‘polyn’ or ‘spline’).

  • fit_order (int, optional) – Polynomial degree or spline smoothing parameter.

  • start_time (Union[str, List[str]], optional) – Observation start time (string or list for multi-part definitions).

  • start_ha (float, optional) – Starting hour angle (radians).

  • freq_range (str, optional) – Alternative frequency specification: [start, end, nchan].

  • sfile (File, optional) – Sensitivity file to override SEFD values.

  • tsys_over_eta (float, optional) – Tsys/eta value used when deriving SEFD if not explicitly given.

  • subarray_list (List[str], optional) – List of antenna names to include.

  • subarray_range (List[int], optional) – Index range of antennas to include.

  • subarray_file (File, optional) – File specifying subarray selection.

  • low_source_limit (Union[float, str], optional) – Elevation (deg) below which rows are flagged.

  • high_source_limit (Union[float, str], optional) – Elevation (deg) above which rows are flagged.

  • telescope_name_column (str)

Returns:

Writes the Measurement Set and its subtables to disk.

Return type:

None

simms.telescope.generate_ms.parse_frequency(value, option)

Parses a frequency value which may be a string with units or a float without units.

Parameters:
  • value (Union[str, float, int]) – The frequency value to parse.

  • option (str)

class simms.telescope.array_utilities.Array(layout, degrees=True, sefd=None, tsys_over_eta=None, sensitivity_file=None, subarray_list=None, subarray_range=None, subarray_file=None)

Bases: object

The Array class has functions for converting from one coordinate system to another.

Parameters:
set_itrf()
geodetic2global()

Convert the antenna positions from the geodetic (WGS84) frame to the global (ITRF/ECEF) frame

Return type:

An array of the antennas XYZ positions and an array of the array center in XYZ

global2geodetic(X, Y, Z)

Convert the antenna positions from the global (ITRF/ECEF) frame to the geodetic (WGS84) frame.

Parameters:
  • (X (float) – : global coordinates of the antennas.

  • Y (float) – : global coordinates of the antennas.

  • Z) (float) – : global coordinates of the antennas.

Returns:

(phi,lam,h) – : geodetic coordinates of the antennas.

Return type:

float

uvgen(pointing_direction, dtime, ntimes, start_freq, dfreq, nchan, start_time=None, start_ha=None)

Generate uvw coordimates

Parameters:
  • pointing_direction (List[str]) – : pointing direction.

  • dtime (int) – : integration time.

  • ntimes (int) – : number of times the sky should be snapped.

  • start_freq (Union[str,float]) – : starting freq of the observation.

  • dfreq (Union[str,float]) – : frequency interval.

  • nchan (int) – : number of channels.

  • start_time (Union[str, List[str]]) – : start time of the observation in UTC (YYYY-MM-DDTHH:MM:SS). Default is the current machine time.

  • start_ha (float) – : start hour angle in radians

Return type:

An array of the uvw time dependent positions, the time array and the frequency array

get_source_elevation(latitude, declination, hour_angles)

Track the source during the observation and get its elevation.

Parameters:
  • latitude (float) – : latitude of the observer in radians.

  • declination (float) – : declination of the source in radians.

  • hour_angles (array[float]) – : hour angles of the source in radians.

Returns:

source_elevations – : the elevations of the source in degrees.

Return type:

array[float]

simms.telescope.array_utilities.calculate_array_centre(ant_locations)

Calculate the geometric centre of an array given the antenna locations.

Parameters:

ant_locations (List[List[float]]) – A list of antenna locations, where each location is a list of [X, Y, Z] coordinates.

Returns:

The [X, Y, Z] coordinates of the geometric centre of the array.

Return type:

List[float]

simms.telescope.array_utilities.write_centre_to_array_config(array_config_path, centre)

Write the calculated centre to the array configuration YAML file.

Parameters:
  • array_config_path (File) – Path to the array configuration YAML file.

  • centre (List[float]) – The [X, Y, Z] coordinates of the geometric centre to write.

Return type:

None

skysim

class simms.skymodel.ascii_skies.SkymodelParameter(info: Optional[str] = None, writable: bool = False, dtype: str = 'str', implicit: Any = None, tags: List[str] = <factory>, required: Optional[bool] = False, choices: Optional[List[Any]] = (), element_choices: Optional[List[Any]] = None, default: Any = '<UNSET DEFAULT VALUE>', aliases: Optional[List[str]] = (), mkdir: bool = False, path_policies: scabha.cargo.PathPolicies = <factory>, remove_if_exists: Optional[bool] = None, access_parent_dir: Optional[bool] = None, write_parent_dir: Optional[bool] = None, must_exist: Optional[bool] = None, skip_freshness_checks: Optional[bool] = None, nom_de_guerre: Optional[str] = None, policies: scabha.cargo.ParameterPolicies = <factory>, category: Optional[scabha.cargo.ParameterCategory] = None, metavar: Optional[str] = None, abbreviation: Optional[str] = None, metadata: Dict[str, Any] = <factory>, suppress_cli_default: bool = False, units: Optional[str] = None, alias: Optional[str] = None, ptype: Optional[str] = 'number', frame: Optional[str] = None, join: Optional[List[str]] = None)

Bases: Parameter

Parameters:
  • info (str | None)

  • writable (bool)

  • dtype (str)

  • implicit (Any)

  • tags (List[str])

  • required (bool | None)

  • choices (List[Any] | None)

  • element_choices (List[Any] | None)

  • default (Any)

  • aliases (List[str] | None)

  • mkdir (bool)

  • path_policies (PathPolicies)

  • remove_if_exists (bool | None)

  • access_parent_dir (bool | None)

  • write_parent_dir (bool | None)

  • must_exist (bool | None)

  • skip_freshness_checks (bool | None)

  • nom_de_guerre (str | None)

  • policies (ParameterPolicies)

  • category (ParameterCategory | None)

  • metavar (str | None)

  • abbreviation (str | None)

  • metadata (Dict[str, Any])

  • suppress_cli_default (bool)

  • units (str | None)

  • alias (str | None)

  • ptype (str | None)

  • frame (str | None)

  • join (List[str] | None)

info: str | None = None
units: str | None = None
alias: str | None = None
ptype: str | None = 'number'
frame: str | None = None
required: bool | None = False
join: List[str] | None = None
set_value(value)

Set and convert the parameter value to the appropriate type and units.

Parameters:

value (str or float or int) – Value to set. Can be a plain number or a string with units.

Returns:

The converted value is stored in self.value.

Return type:

None

Raises:
  • KeyError – If the parameter type is unknown.

  • ValueError – If the value cannot be parsed or converted to the target units.

class simms.skymodel.ascii_skies.ASCIISourceSchema(info: str, parameters: Dict[str, simms.skymodel.ascii_skies.SkymodelParameter])

Bases: object

Parameters:
info: str
parameters: Dict[str, SkymodelParameter]
class simms.skymodel.ascii_skies.ASCIISource(schema: simms.skymodel.ascii_skies.ASCIISourceSchema)

Bases: object

Parameters:

schema (ASCIISourceSchema)

schema: ASCIISourceSchema
set_source_param(field, value)

Set a parameter value for the source.

Parameters:
  • field (str) – Name of the source parameter (e.g., ‘ra’, ‘dec’, ‘flux’, ‘name’).

  • value (str or float or int) – Value to assign. Converted to the appropriate type and units.

Return type:

None

Raises:
  • AttributeError – If field is not a valid parameter in the schema.

  • ValueError – If the value cannot be converted to the required type/units.

Notes

This method updates the instance in place.

alias_to_field_mapper()
field_to_alias_mapper()
finalise()

Validate set fields and derive source type flags.

Notes

  • Ensures the source satisfies the minimal point-source requirements.

  • Sets boolean flags: is_point, is_polarised, is_line, is_continuum, is_transient, and is_exoplanet_transient.

  • Computes and sets fields that are defined as a join of other fields.

Raises:

ASCIISourceError – If the source does not satisfy minimal point-source requirements.

value_or_default(field)

Return the value of a field or its default.

Parameters:

field (str) – Source field name (e.g., ‘ra’, ‘dec’, ‘stokes_i’).

Returns:

The value set from the ASCII file, or the schema default if unset.

Return type:

int or float or str

get_brightness_matrix(chan_freqs, ncorr, unique_times=None, time_index_mapper=None, full_stokes=True, linear_basis=True)

Generate the brightness matrix across frequency (and time if transient).

Parameters:
  • chan_freqs (numpy.ndarray) – 1D array of channel frequencies in Hz.

  • ncorr (int) – Number of correlations (e.g., 4 for full Stokes).

  • unique_times (numpy.ndarray, optional) – 1D array of unique time samples (seconds) for transient sources.

  • time_index_mapper (numpy.ndarray, optional) – Mapping indices from unique time samples to the output time axis.

  • full_stokes (bool, default True) – If True, compute all Stokes parameters; otherwise Stokes I only.

  • linear_basis (bool, default True) – If True, use linear polarization basis (XX, XY, YX, YY). If False, use circular basis (RR, RL, LR, LL).

Returns:

Brightness matrix with shape (ncorr, ntime, nfreq) for transient sources or (ncorr, nfreq) for non-transient sources.

Return type:

numpy.ndarray

Raises:

ValueError – If required spectral or transient fields are missing or invalid.

Notes

  • Spectrum is modeled as a Gaussian line or a polynomial continuum, depending on which fields are present.

  • For transient sources, a logistic lightcurve is applied. The lightcurve only scales the spectrum, so it is applied as a separable factor here.

continuum_coefficients()

Continuum polynomial coefficients, highest unset orders dropped.

Returns:

[cont_coeff_1, cont_coeff_2, cont_coeff_3] truncated after the last coefficient the source actually sets. An empty list means the source has no continuum spectrum.

Return type:

list of float

get_lightcurve(unique_times)

Evaluate the transient lightcurve on a time axis.

Parameters:

unique_times (numpy.ndarray) – Sorted unique time stamps spanning the whole observation. Transient parameters are defined relative to unique_times[0], so this must not be a per-block subset of the observation’s times.

Returns:

Fractional intensity of shape (unique_times.size,).

Return type:

numpy.ndarray

class simms.skymodel.ascii_skies.ASCIISkymodel(skymodel_file, delimiter=None, source_schema_file=None, sources=None)

Bases: object

A sky model built from an ASCII column file.

Parameters:
  • skymodel_file (str or scabha.basetypes.File) – Path to the sky model file.

  • delimiter (str, optional) – Column delimiter used in the file. If None, split on whitespace.

  • source_schema_file (str or scabha.basetypes.File, optional) – Path to the YAML source schema. Defaults to DEFAULT_SOURCE_SCHEMA.

  • sources (list of ASCIISource, optional) – Populated after parsing.

Raises:

ASCIISkymodelError – If the file cannot be read or validated.

skymodel_file: str | File
delimiter: str = None
source_schema_file: str | File = None
sources: List[ASCIISource] = None
property has_transient

Visibility prediction from FITS sky models.

Conventions

Everything here predicts the same quantity, verified in tests/predict_fits_tests.py against a brute-force transcription of the RIME:

V(u, v, w, nu) = sum_pix S_pix * exp(2j*pi * (u*l + v*m + w*(n - 1)) * nu / c)

where (l, m) are the direction cosines of a pixel relative to the MS phase centre, n = sqrt(1 - l**2 - m**2), and there is no 1/n factor because the image is in Jy/pixel rather than surface brightness.

ducc0.wgridder.dirty2vis reproduces this exactly when called with divide_by_n=False and the pixel-to-direction-cosine mapping l = -(i - npix//2) * pixsize_x, m = -(j - npix//2) * pixsize_y. It therefore requires a regular (l, m) grid, which only an orthographic (SIN) projection whose tangent point coincides with the phase centre provides. Any other projection, or a tangent point away from the phase centre, is reprojected onto such a grid first.

The DFT backend needs no regular grid and is exact for every projection, so sparse component-like images are predicted without resampling.

class simms.skymodel.fits_skies.FitsGrid(delta_l, delta_m, ref_l, ref_m, l_ref, m_ref, deviation_pixels)

Bases: object

Mapping from image pixel indices to direction cosines, for dirty2vis.

l = l_ref + delta_l * (i - ref_l) and likewise for m.

Parameters:
delta_l: float
delta_m: float
ref_l: float
ref_m: float
l_ref: float
m_ref: float
deviation_pixels: float
property is_regular: bool
ducc_kwargs(npix_l, npix_m)

Arguments placing this grid in the frame dirty2vis assumes.

Parameters:
Return type:

dict

pixel_lmn(i_pix, j_pix)

Direction cosines (l, m, n - 1) of pixels on this regular grid.

Parameters:
  • i_pix (ndarray)

  • j_pix (ndarray)

Return type:

ndarray

class simms.skymodel.fits_skies.PreparedFitsSky(chan_freqs, spectrum, backend, ncorr, polarisation, linear_basis, ncomp, npix_l, npix_m, planes=None, stokes_names=None, grid=None, tol=1e-07, lmn=None, bmat=None, uniform_freqs=True)

Bases: object

A FITS sky model reduced to what a prediction backend needs.

Parameters:
  • chan_freqs (ndarray)

  • spectrum (FitsSpectrum)

  • backend (str)

  • ncorr (int)

  • polarisation (bool)

  • linear_basis (bool)

  • ncomp (int)

  • npix_l (int)

  • npix_m (int)

  • planes (ndarray | None)

  • stokes_names (List[str] | None)

  • grid (FitsGrid | None)

  • tol (float)

  • lmn (ndarray | None)

  • bmat (ndarray | None)

  • uniform_freqs (bool)

chan_freqs: ndarray
spectrum: FitsSpectrum
backend: str
ncorr: int
polarisation: bool
linear_basis: bool
ncomp: int
npix_l: int
npix_m: int
planes: ndarray | None = None
stokes_names: List[str] | None = None
grid: FitsGrid | None = None
tol: float = 1e-07
lmn: ndarray | None = None
bmat: ndarray | None = None
uniform_freqs: bool = True
property nspec: int
property flat_spectrum: bool

True when one image serves every channel, so the gridder runs once.

select_channels(chan_ids)

Restrict the model to a subset of channels, for channel-chunked prediction.

The reference image and the spectral coefficients are channel-independent, so only the channel grid moves for FLAT and POLY; a CUBE also slices its per-channel planes, and the DFT brightness matrix its channel axis.

Parameters:

chan_ids (ndarray)

Return type:

PreparedFitsSky

simms.skymodel.fits_skies.pixel_lm(cel, ra0, dec0, i_pix, j_pix)

Direction cosines of image pixels relative to the phase centre.

Exact for every projection: the pixel centres are pushed through the WCS and then converted with the same radec2lm the ASCII path uses.

Parameters:
  • cel (astropy.wcs.WCS) – Celestial sub-WCS of the image.

  • ra0 (float) – Phase centre (radians).

  • dec0 (float) – Phase centre (radians).

  • i_pix (array_like) – 0-based pixel indices along the longitude and latitude axes.

  • j_pix (array_like) – 0-based pixel indices along the longitude and latitude axes.

Returns:

(l, m), each of shape i_pix.shape.

Return type:

tuple of numpy.ndarray

simms.skymodel.fits_skies.lm_to_radec(el, em, ra0, dec0)

Inverse of simms.utilities.radec2lm(), in radians.

Parameters:
  • el (ndarray)

  • em (ndarray)

  • ra0 (float)

  • dec0 (float)

simms.skymodel.fits_skies.fit_lm_grid(cel, ra0, dec0, npix_l, npix_m, samples=9)

Fit l and m as linear functions of pixel index, and measure the misfit.

The misfit is zero for a SIN projection tangent at the phase centre and grows with field size for any other projection, so it is the criterion for whether the gridder may be used at all.

Parameters:
Return type:

FitsGrid

simms.skymodel.fits_skies.attach_image_beam(prepared, provider, is_altaz, ra0, dec0, lon, lat, t_start, duration, pa_step, mid_freq, phase_ra0=None, phase_dec0=None)

Multiply the apparent sky by a parallactic-angle-averaged power beam (in place).

Approximate: one representative antenna beam, averaged over parallactic angle, is applied to every Stokes plane (or DFT component). This ignores per-baseline beams, heterogeneity and cross-hand leakage – correct only for a homogeneous array. The beam is applied per channel where the model has a real channel axis (DFT components, a spectral CUBE), otherwise at the band mid-frequency (single FLAT/POLY plane).

ra0/dec0 are the beam (antenna pointing) centre; phase_ra0/phase_dec0 are the phase centre the image l/m are referenced to, so the beam is sampled at each pixel’s offset from where the dish points.

Parameters:
Return type:

PreparedFitsSky

class simms.skymodel.fits_skies.SinResampler(coords, jacobian, shape, grid, order=3)

Bases: object

A fixed mapping from a SIN target grid onto an arbitrary source image.

Built once so that flux maps and spectral coefficient maps are resampled onto exactly the same target pixels, differing only in whether the Jacobian is applied.

Parameters:
coords: ndarray
jacobian: ndarray
shape: tuple
grid: FitsGrid
order: int = 3
simms.skymodel.fits_skies.sin_resampler(cel, ra0, dec0, cell, npix_l, npix_m, order=3)

Build a resampler onto a SIN grid tangent at the phase centre.

Flux is conserved exactly (to interpolation accuracy) without any solid-angle bookkeeping: Jy/pixel is a density with respect to pixel index, so scaling the interpolated value by the Jacobian determinant of the target-to-source pixel map accounts for the change of pixel area.

Parameters:
  • cel (astropy.wcs.WCS) – Celestial sub-WCS of the source image.

  • ra0 (float) – Phase centre (radians).

  • dec0 (float) – Phase centre (radians).

  • cell (float) – Pixel size of the target grid, in radians.

  • npix_l (int) – Shape of the source image.

  • npix_m (int) – Shape of the source image.

  • order (int, optional) – Spline order for scipy.ndimage.map_coordinates(). Default 3.

Return type:

SinResampler

simms.skymodel.fits_skies.reproject_to_sin(planes, cel, ra0, dec0, cell, order=3)

Resample flux planes onto a SIN grid tangent at the phase centre.

Parameters:
simms.skymodel.fits_skies.stokes_to_correlations(get, ncorr, polarisation, linear_basis)

Combine Stokes quantities into correlations.

get(name) returns the I, Q, U or V quantity, or 0 when the model does not carry it. The combination is linear, so it may be applied either to image planes or, equivalently, to the visibilities they predict.

Parameters:
Return type:

list

simms.skymodel.fits_skies.choose_backend(ncomp, npix_l, npix_m, nrow, nchan, nplanes)

Pick the cheaper of the two exact backends.

The DFT costs one phasor per component, row and channel. The gridder costs an image FFT per plane and channel, plus a degridding term proportional to rows. Break-even is therefore a few hundred components, not a fraction of the image: a “sparse” CLEAN model with thousands of components still wants the gridder.

Parameters:
Return type:

str

simms.skymodel.fits_skies.prepare_fits_sky(input_fitsimages, ra0, dec0, chan_freqs, ms_delta_nu, ncorr, nrow, linear_basis=True, polarisation=True, tol=1e-07, backend='auto', spectrum='auto', spi_maps=None, ref_freq=None, spectrum_order=2, spectrum_tol=0.001, interpolation='linear', stack_axis='STOKES', reproject_order=3)

Read one or more FITS images into a form a prediction backend can consume.

Parameters:
  • input_fitsimages (File or list of File) – A single FITS image, or an ordered list of per-Stokes images.

  • ra0 (float) – MS phase centre (radians).

  • dec0 (float) – MS phase centre (radians).

  • chan_freqs (numpy.ndarray) – MS channel centres (Hz).

  • ms_delta_nu (float) – MS channel width (Hz).

  • ncorr (int) – Number of correlations to predict (2 or 4).

  • nrow (int) – Total rows in the MS. Used only by the backend cost model.

  • linear_basis (bool, optional) – Linear (XX/XY/YX/YY) or circular (RR/RL/LR/LL) correlations.

  • polarisation (bool, optional) – Predict every correlation. Forced off when the model carries only Stokes I.

  • tol (float, optional) – Pixels below this brightness (Jy) are dropped from the component list.

  • backend ({"auto", "dft", "fft"}, optional) – Prediction backend. “auto” uses choose_backend().

  • spectrum ({"auto", "flat", "poly", "cube"}, optional) – How the model varies with frequency. “auto” takes a single plane as flat, and for a cube fits a log-polynomial, falling back to the cube when the fit residual exceeds spectrum_tol.

  • spi_maps (list of File, optional) – Spectral-index (and higher-order) coefficient maps, ordered c1, c2, … When given, the spectrum is analytic and nothing is fitted.

  • ref_freq (float, optional) – Reference frequency of the analytic spectrum (Hz). Defaults to the MS band centre.

  • spectrum_order (int, optional) – Order of the fitted log-polynomial. 1 is a plain spectral index. Default 2.

  • spectrum_tol (float, optional) – Largest fractional flux residual for which a fitted log-polynomial is accepted under spectrum=”auto”.

  • interpolation (str, optional) – Spectral interpolation method when the FITS and MS channel grids differ and the cube is kept.

  • stack_axis (str, optional) – Axis along which a list of FITS images is stacked.

  • reproject_order (int, optional) – Spline order used when reprojecting a non-SIN image.

Return type:

PreparedFitsSky

Raises:

FITSSkymodelError – If the MS band lies outside the FITS band, or an unsupported Stokes axis or backend is requested.

simms.skymodel.fits_skies.predict_fits_channel_block(prepared, uvw, chan_ids, out_dtype=None, epsilon=1e-07, do_wgridding=True, nthreads=1)

Predict one (row, channel) block, restricting the model to chan_ids.

Parameters:
Return type:

ndarray

simms.skymodel.fits_skies.predict_fits_block(prepared, uvw, noise_vis=None, out_dtype=None, epsilon=1e-07, do_wgridding=True, nthreads=1)

Predict visibilities for one block of rows.

Parameters:
  • prepared (PreparedFitsSky) – Sky model from prepare_fits_sky().

  • uvw (numpy.ndarray) – UVW coordinates of shape (nrow, 3), in metres.

  • noise_vis (float, optional) – RMS noise per visibility (Jy).

  • out_dtype (numpy.dtype, optional) – Complex dtype to cast to. Named out_dtype because da.blockwise consumes any dtype kwarg itself and never forwards it.

  • epsilon (float, optional) – Gridder accuracy.

  • do_wgridding (bool, optional) – Apply the w term with w-gridding.

  • nthreads (int, optional) – Threads for the gridder. Default 1; dask supplies row parallelism.

Returns:

Visibilities of shape (nrow, nchan, ncorr).

Return type:

numpy.ndarray

class simms.skymodel.source_factory.SourceType(name: str, required: List[str] = <factory>, inherit: Any = None, surplus: List[str] = <factory>)

Bases: object

Parameters:
name: str
required: List[str]
inherit: Any = None
surplus: List[str]
is_valid(fields, raise_exception=False, none_or_all=False)
Parameters:
class simms.skymodel.source_factory.StokesData(data, linear_basis=True)

Bases: object

Container for source/image Stokes intensity data.

Parameters:
  • data (list of int or numpy.ndarray) – Stokes parameter data ordered as I, Q, U, V (or IVQU when not linear).

  • linear_basis (bool, optional) – If True, the Stokes parameters are interpreted in a linear basis (I, Q, U, V). If False, they are interpreted in a circular basis (I, V, Q, U). Default is True.

data: List[int] | ndarray
linear_basis: bool | None = True
set_spectrum(freqs, specfunc, full_pol=True, **kwargs)

Add a spectral axis to the Stokes data.

Parameters:
  • freqs (numpy.ndarray) – Frequency array.

  • specfunc (Callable) – Callable with signature f(freqs, flux, **kwargs) returning the spectral profile.

  • full_pol (bool, optional) – If True, compute spectra for all four Stokes parameters. If False, only Stokes I is used. Default is True.

  • **kwargs – Additional keyword arguments forwarded to specfunc.

Return type:

None

get_brightness_matrix(ncorr)

Build the brightness (coherency) matrix.

Parameters:

ncorr (int) – Number of output correlations (2 or 4).

Returns:

Brightness matrix with the same shape as self.data except that the Stokes axis is replaced by a correlation axis of length ncorr. For ncorr == 2 the dtype is float; for ncorr == 4 the dtype is complex.

Return type:

numpy.ndarray

property I
property Q
property U
property V
property is_polarised
simms.skymodel.source_factory.contspec(freqs, flux, coeff, nu_ref)

Continuum (power-law) spectral profile.

Parameters:
  • freqs (numpy.ndarray) – Frequency array.

  • flux (float) – Reference flux density at nu_ref.

  • coeff (float or array-like) – Power-law coefficient(s). If array-like with length > 1, treated as polynomial coefficients of log-log curvature (via numpy.polynomial), so that the exponent varies with frequency as c1 + c2*ln(nu/nu_ref) + c3*ln(nu/nu_ref)**2 + .... If length == 1 or float, treated as a constant spectral index.

  • nu_ref (float) – Reference frequency.

Returns:

Spectral profile evaluated at freqs.

Return type:

numpy.ndarray

simms.skymodel.source_factory.gauss_1d(xaxis, peak, width, x0)

Single Gaussian spectral line profile.

Parameters:
  • xaxis (numpy.ndarray) – Grid along the spectral axis.

  • peak (float) – Gaussian peak amplitude.

  • width (float) – Full width at half maximum (FWHM) in the same units as xaxis.

  • x0 (float) – Centre position of the Gaussian.

Returns:

Profile evaluated at xaxis.

Return type:

numpy.ndarray

simms.skymodel.source_factory.exoplanet_transient_logistic(times, transient_start, transient_absorb, transient_ingress, transient_period)

Logistic transit lightcurve for an exoplanet-like transient.

Parameters:
  • times (numpy.ndarray) – Time samples at which to evaluate the lightcurve, in seconds relative to the start of the observation.

  • transient_start (int) – Time at which the transit begins (seconds).

  • transient_absorb (float) – Maximum fractional flux decrease during transit (e.g., 0.01 = 1% dip).

  • transient_ingress (int) – Duration of ingress/egress (seconds).

  • transient_period (int) – Total duration of the transit event, including ingress and egress (seconds).

Returns:

Normalized intensity time series of shape times.shape.

Return type:

numpy.ndarray

Primary beams

Primary-beam models for skysim.

The cosine-taper (“JimBeam”) voltage model in this module is re-implemented from katbeam (https://github.com/ska-sa/katbeam), Copyright (c) 2020, National Research Foundation (SARAO), released under the BSD 3-Clause License, originally authored by Mattieu de Villiers. We vendor the maths and the bundled L/UHF coefficient tables (simms/skymodel/beam_data/) rather than depend on the package so that we can (a) drop an unmaintained dependency and (b) load arbitrary coefficient CSVs – e.g. the MeerKAT-Extension MKAT-EA-* tables – which upstream katbeam cannot.

A cosine aperture taper (Essential Radio Astronomy, Condon & Ransom, 2016) models the co-polarised primary beam. It is parameterised, per frequency and per feed (H/V), by a pointing offset (“squint”, l0/m0) and a full-width-half-maximum in each of the two feed axes. HH/VV are voltage patterns: they peak at 1 on axis and equal sqrt(0.5) at the half-power point, so |HH|**2 is the power beam and Stokes I is 0.5*(|HH|**2 + |VV|**2).

simms.skymodel.beams.local_sidereal_time(times, lon)

Mean local sidereal time (radians) for MS TIME seconds at longitude lon (rad).

Used to form the local hour angle LST - RA that sets the sky orientation (parallactic angle, elevation) at the site. This is a distinct quantity from the Greenwich hour angle that simms.telescope.array_utilities.Array.uvgen() uses for the UVW rotation of its ECEF baselines – the two differ by the array longitude and both are correct in their own frame.

Parameters:
  • times (ndarray)

  • lon (float)

Return type:

ndarray

simms.skymodel.beams.parallactic_angle(times, ra0, dec0, lon, lat)

Parallactic angle (radians) at the field centre for each timestamp.

Parameters:
  • times (numpy.ndarray) – MS TIME values in seconds, shape (ntime,).

  • ra0 (float) – Field-centre right ascension and declination (radians).

  • dec0 (float) – Field-centre right ascension and declination (radians).

  • lon (float) – Array-reference geodetic longitude and latitude (radians).

  • lat (float) – Array-reference geodetic longitude and latitude (radians).

Returns:

Parallactic angle per timestamp, shape (ntime,). This is the position angle of the zenith at the field centre; alt-az feeds rotate the beam on the sky by this angle.

Return type:

numpy.ndarray

simms.skymodel.beams.cosine_taper(r)

Cosine-taper voltage pattern cos(pi*rr)/(1 - 4*rr**2) with rr = r*R_FWHM.

r is normalised so the half-power point is at r = 0.5. The rr = 0.5 singularity of 1 - 4*rr**2 is removable (limit pi/4) and handled here.

Parameters:

r (ndarray)

Return type:

ndarray

class simms.skymodel.beams.CosineTaperBeam(freqs_mhz, squint_deg, fwhm_deg, name='')

Bases: object

Frequency-interpolated cosine-taper voltage beam for the H and V feeds.

Parameters:
  • freqs_mhz (numpy.ndarray) – Tabulated frequencies (MHz), shape (nfreq,).

  • squint_deg (numpy.ndarray) – Per-feed pointing offsets in degrees, shape (4, nfreq) ordered Hx, Hy, Vx, Vy.

  • fwhm_deg (numpy.ndarray) – Per-feed FWHMs in degrees, same shape/ordering as squint_deg.

  • name (str, optional) – Label for diagnostics.

classmethod from_csv(path, name='')

Load a katbeam-format coefficient CSV.

The file has two header rows (column names, then units) followed by rows of freq[MHz], Hx, Hy, Vx, Vy squint[arcmin], Hx, Hy, Vx, Vy fwhm[arcmin].

Parameters:

name (str)

Return type:

CosineTaperBeam

classmethod from_builtin(name)

Load one of the bundled models in BUILTIN_BEAMS.

Parameters:

name (str)

Return type:

CosineTaperBeam

classmethod load(spec)

Load by built-in name if known, otherwise treat spec as a CSV path.

Parameters:

spec (str)

Return type:

CosineTaperBeam

voltages(x_deg, y_deg, freqs_mhz)

Voltage patterns for both feeds.

Parameters:
  • x_deg (numpy.ndarray) – Feed-frame coordinates in degrees (x toward +AZ, y toward +EL), shape (nsrc,).

  • y_deg (numpy.ndarray) – Feed-frame coordinates in degrees (x toward +AZ, y toward +EL), shape (nsrc,).

  • freqs_mhz (numpy.ndarray) – Frequencies in MHz, shape (nchan,).

Returns:

Real voltage patterns of shape (nsrc, nchan, 2); the last axis is feed 0 = H/X, 1 = V/Y.

Return type:

numpy.ndarray

class simms.skymodel.beams.BeamProvider

Bases: object

Evaluate a per-feed voltage beam, de-rotating the sky into the feed frame.

Subclasses implement _eval() in the feed frame. The base handles the parallactic-angle rotation so a source at sky direction cosines (l, m) is evaluated at the feed-frame coordinates R(-chi) . (l, m).

jones(ell, emm, freqs, chi)

2x2 voltage Jones per parallactic-angle sample.

Same inputs as voltage(); returns (ntime, nsrc, nchan, 2, 2) complex.

Return type:

ndarray

voltage(ell, emm, freqs, chi)

Voltage beam for each parallactic angle.

Parameters:
  • ell (numpy.ndarray) – Sky-frame direction cosines (l, m), shape (nsrc,).

  • emm (numpy.ndarray) – Sky-frame direction cosines (l, m), shape (nsrc,).

  • freqs (numpy.ndarray) – Frequencies in Hz, shape (nchan,).

  • chi (numpy.ndarray) – Parallactic angle per sample (radians), shape (ntime,). Pass zeros for a non-rotating (e.g. equatorial-mount) beam.

Returns:

Complex voltages of shape (ntime, nsrc, nchan, 2).

Return type:

numpy.ndarray

class simms.skymodel.beams.UnityBeamProvider

Bases: BeamProvider

A flat, unity beam (no attenuation). Used for antennas with no configured beam.

class simms.skymodel.beams.JimBeamProvider(beam)

Bases: BeamProvider

Analytic cosine-taper (“JimBeam”) voltage provider wrapping CosineTaperBeam.

Parameters:

beam (CosineTaperBeam)

class simms.skymodel.beams.FitsBeamProvider(l_grid, m_grid, freqs_hz, values, name='')

Bases: BeamProvider

Per-feed voltage beam interpolated from a gridded FITS cube (measured/eidos beams).

The cube is a regular grid of complex per-feed voltages over (l, m) direction cosines and frequency; it is defined in the feed frame (as holography/eidos beams are), so the BeamProvider base rotates the sky (l, m) into that frame by -chi before this interpolates. Bilinear in (l, m), linear in frequency, zero outside the grid.

Use from_fits() for the on-disk layout, or from_arrays() to build one directly (e.g. in tests).

Parameters:

name (str)

classmethod from_arrays(l_grid, m_grid, freqs_hz, values, name='')

Build from explicit grids and a (nl, nm, nfreq, K) cube (K=2 [HH,VV] or 4 [HH,HV,VH,VV]).

Parameters:

name (str)

Return type:

FitsBeamProvider

classmethod from_fits(path, name='')

Load a per-feed voltage beam cube.

The primary HDU leading axis holds the feed voltages as real/imag pairs: 4 planes [HH, VV]×(real, imag) for a diagonal beam, or 8 planes [HH, HV, VH, VV]×(real, imag) for a full 2x2 Jones (leakage). A linear WCS gives the L/M axes in degrees (SIN direction cosines scaled to degrees, l_deg = 180/pi * l) and the FREQ axis in Hz.

Parameters:

name (str)

Return type:

FitsBeamProvider

simms.skymodel.beams.load_beam_config(path)

Load a beam-config YAML mapping each TELESCOPE_NAME to a provider spec.

Return type:

dict

simms.skymodel.beams.resolve_antenna_beams(telescope_names, mount, beam_config, beam_band='L')

Map antennas to beam types and build one provider per type.

Parameters:
  • telescope_names (sequence of str) – Per-antenna ANTENNA.TELESCOPE_NAME values, length nant.

  • mount (sequence of str) – Per-antenna ANTENNA.MOUNT values, length nant.

  • beam_config (dict or None) – Mapping of telescope_name -> provider spec (see load_beam_config()).

  • beam_band (str) – Default band for JimBeam entries that omit an explicit model.

Returns:

  • ant_type (numpy.ndarray) – Per-antenna type index, shape (nant,).

  • providers (list of BeamProvider) – One provider per type, indexed by ant_type.

  • type_is_altaz (numpy.ndarray) – Whether each type’s mount rotates the beam (ALT-AZ), shape (ntype,).

simms.skymodel.beams.pa_sample_grid(t_start, duration, ra0, dec0, lon, lat, pa_step_deg)

A parallactic-angle sample grid spanning the observation, uniform in time.

The grid is uniform in time (so a row is indexed by its timestamp, monotonically and without arctan2 wrap issues) and sized by the maximum PA rate over the span so a fast (near-zenith) transit is resolved to pa_step_deg, up to MAX_PA_SAMPLES samples.

Returns:

  • tgrid (numpy.ndarray) – Sample times (MS seconds), shape (n_pa,).

  • chi_grid (numpy.ndarray) – Unwrapped parallactic angle at each sample (radians), shape (n_pa,).

simms.skymodel.beams.build_beam_grid(providers, type_is_altaz, ell, emm, freqs, chi_grid, max_gib=4.0)

Sample every type’s voltage beam on the PA grid.

Returns an array of shape (ntype, n_pa, nsrc, nchan, 2). Stored as complex64 (halving this large array vs complex128); a beam voltage is O(1), so single precision is ample and visibilities still accumulate in double. Alt-az types use chi_grid; others are evaluated at zero parallactic angle (no rotation). Raises MemoryError if the grid would exceed max_gib (see _check_beam_grid_footprint()).

simms.skymodel.beams.corr_basis_transform(is_circular)

2x2 transform folded into the beam Jones so V lands in the MS correlation basis.

Identity for a linear-correlation MS; the constant linear->circular feed matrix for a circular one (the feeds are physically linear, so circular correlations are a fixed rotation of the linear ones).

Parameters:

is_circular (bool)

Return type:

ndarray

simms.skymodel.beams.build_beam_grid_jones(providers, type_is_altaz, ell, emm, freqs, chi_grid, basis_transform, max_gib=4.0)

Sample every type’s 2x2 voltage Jones on the PA grid, folding the basis transform.

Returns (ntype, n_pa, nsrc, nchan, 2, 2) complex64 holding E' = S . E, so the kernel’s V = E'_p B_feed E'_q^H = S (E_p B E_q^H) S^H lands in the MS correlation basis (B_feed is the linear-feed coherency). Alt-az types use chi_grid. Raises MemoryError if the grid would exceed max_gib (see _check_beam_grid_footprint()).

simms.skymodel.beams.image_power_beam(provider, is_altaz, ell, emm, freqs, chi_grid)

Parallactic-angle-averaged power beam <0.5(|g^X|^2 + |g^V|^2)> at each point.

For the FITS-image path, which grids one apparent sky for all baselines and times: there is no per-baseline beam, so the beam is averaged over the observation’s parallactic-angle range (a single sample when is_altaz is False). Loops over frequency and PA to keep the working set at O(npts) for large images.

Parameters:
  • provider (BeamProvider) – A single representative antenna beam.

  • is_altaz (bool) – Whether to average over chi_grid (True) or evaluate once at chi = 0.

  • ell (numpy.ndarray) – Direction cosines of the points (pixels/components), shape (npts,).

  • emm (numpy.ndarray) – Direction cosines of the points (pixels/components), shape (npts,).

  • freqs (numpy.ndarray) – Frequencies (Hz), shape (nchan,).

  • chi_grid (numpy.ndarray) – Parallactic-angle samples (radians).

Returns:

Real power beam of shape (npts, nchan) in [0, ~1].

Return type:

numpy.ndarray

simms.skymodel.beams.corr_feed_maps(ncorr)

Feed indices for each correlation in the linear basis.

Returns (corr_feed_p, corr_feed_q) giving, per correlation, the feed (0=H/X, 1=V/Y) of the first and second antenna. 4-corr is [XX, XY, YX, YY]; 2-corr is [XX, YY]. Circular basis is unsupported by the diagonal per-feed model.

simms.skymodel.beams.array_lonlat(positions)

Geodetic (lon, lat) in radians from the mean of ITRF/ECEF antenna positions.

simms.skymodel.beams.read_pointing_centre(ms, fallback_ra0, fallback_dec0)

Antenna pointing centre (radians) from POINTING.DIRECTION.

This is where the dishes point, and hence where the primary beam is centred – distinct from FIELD.PHASE_DIR (the correlator phase centre, a freely-shiftable quantity). Reads the poly order-0 term of the first row’s direction and falls back to the given phase centre, with a warning, when the MS has no usable POINTING table.

The direction is interpreted as a fixed sky position, which requires an equatorial measure frame. J2000/ICRS (and an absent keyword, as older simms MSs may have) take the fast path silently; another equatorial frame is accepted with a warning; a horizontal frame (AZEL etc.) raises NotImplementedError, since it maps to a time-dependent sky direction that a single beam centre cannot represent.

simms.skymodel.beams.reproject_lm(ell, emm, from_ra0, from_dec0, to_ra0, to_dec0)

Re-reference direction cosines from one tangent centre to another (a no-op if they match).

Source (l, m) prepared for the phase centre are re-expressed relative to the beam (pointing) centre, so the beam is sampled at each source’s offset from where the dish points.

simms.skymodel.beams.resolve_beam(spec, band='L')

Build a beam provider from a spec: a .fits cube, a CSV/built-in JimBeam, or a band.

Parameters:

band (str)

Return type:

BeamProvider

simms.skymodel.beams.averaged_power_beam(provider, ell, emm, freqs, chi_grid)

Frequency- and parallactic-angle-averaged Stokes-I power beam A(l, m), shape (npts,).

Averages image_power_beam() (already PA-averaged) over frequency. Used for the image-/component-domain apply/correct, which is a direct multiply/divide by one map.

simms.skymodel.beams.write_beam_fits(beam, l_grid, m_grid, freqs_hz, path)

Write a cosine-taper beam to a 4-plane FITS cube that FitsBeamProvider.from_fits() reads.

Samples beam on the (l_grid, m_grid) direction-cosine grid at freqs_hz and stores [HH, VV] feed voltages as real/imag planes: (4, nfreq, nm, nl), with a linear WCS giving L/M in degrees and FREQ in Hz.

Parameters:

beam (CosineTaperBeam)