Programming References

Observation Class (JAX)

class tabascal.jax.observation.Observation(latitude: float, longitude: float, elevation: float, ra: float, dec: float, times: Array, freqs: Array, SEFD: Array, ENU_path=None, ENU_array=None, dish_d=13.965, random_seed=0, auto_corrs=False, n_int_samples=4, name='MeerKAT', max_chunk_MB: Optional[float] = None)

Construct an Observation object defining a radio interferometry observation.

Parameters

latitude: float

Latitude of the telescope.

longitude: float

Longitude of the telescope.

elevation: float

Elevation of the telescope.

ra: float

Right Ascension of the phase centre.

dec: float

Declination of the phase centre.

times: ndarray (n_time,)

Time centroids of each data point. This is the Greenwich Mean Sidereal Time (GMST).

freqs: ndarray (n_freq,)

Frequency centroids for each observation channel.

SEFD: ndarray (n_freq,)

System Equivalent Flux Density of the telescope over frequency.

ENU_path: str

Path to a txt file containing the ENU coordinates of each antenna.

ENU_array: ndarray (n_ant, 3)

ENU coordinates of each antenna.

dish_d: float

Diameter of each antenna dish.

random_seed: int

Random seed to use for random number generator.

auto_corrs: bool

Flag to include autocorrelations in simulation.

n_int_samples: int

Number of samples per time step which are then averaged. Must be large enough to capture time-smearing of RFI sources on longest baseline.

name: str

Name of the telescope.

Observation.addAstro(I: Array, ra: Array, dec: Array)

Add a set of astronomical sources to the observation.

Parameters

I: ndarray (n_src, n_freq)

Intensity of the sources in Jy.

ra: array (n_src,)

Right ascension of the sources in degrees.

dec: array (n_src,)

Declination of the sources in degrees.

Observation.addSatelliteRFI(Pv: Array, elevation: Array, inclination: Array, lon_asc_node: Array, periapsis: Array)

Add a satellite-based source of RFI to the observation.

Parameters

Pv: ndarray (n_src, n_freq)

Specific Emission Power in W/Hz

elevation: ndarray (n_src,)

Elevation/Altitude of the orbit in metres.

inclination: ndarray (n_src,)

Inclination angle of the orbit relative to the equatorial plane.

lon_asc_node: ndarray (n_src,)

Longitude of the ascending node of the orbit. This is the longitude of when the orbit crosses the equator from the south to the north.

periapsis: ndarray (n_src,)

Perisapsis of the orbit. This is the angular starting point of the orbit at t = 0.

Observation.addStationaryRFI(Pv: Array, latitude: Array, longitude: Array, elevation: Array)

Add a stationary source of RFI to the observation.

Parameters

Pv: ndarray (n_src, n_freq)

Specific Emission Power in W/Hz

latitude: ndarray (n_src,)

Geopgraphic latitude of the source in degrees.

longitude: ndarray (n_src,)

Geographic longitude of the source in degrees.

elevation: ndarray (n_src,)

Elevation/Altitude of the source above sea level in metres.

Observation.addGains(G0_mean: complex, G0_std: float, Gt_std_amp: float, Gt_std_phase: float, key=None)

Add complex antenna gains to the simulation. Gain amplitudes and phases are modelled as linear time-variates. Gains for all antennas at t = 0 are randomly sampled from a Gaussian described by the G0 parameters. The rate of change of both ampltudes and phases are sampled from a zero mean Gaussian with standard deviation as provided.

Parameters

G0_mean: complex

Mean of Gaussian at t = 0.

G0_std: float

Standard deviation of Gaussian at t = 0.

Gt_std_amp: float

Standard deviation of Gaussian describing the rate of change in the gain amplitudes in 1/seconds.

Gt_std_phase: float

Standard deviation of Gaussian describing the rate of change in the gain phases in rad/seconds.

key: jax.random.PRNGKey

Random number generator key.

Observation.calculate_vis()

Calculate the total gain amplified visibilities and average down to the originally defined sampling rate.

Observation.write_to_zarr(path: str = 'Observation', overwrite: bool = False)

Write the visibilities to disk using zarr format.

Observation.write_to_ms(path: str = 'Observation.ms', overwrite: bool = False)

Write the visibilities to disk using Measurement Set format.

Observation Class (Dask)

class tabascal.dask.observation.Observation(latitude: float, longitude: float, elevation: float, ra: float, dec: float, times: Array, freqs: Array, SEFD: Array, ENU_path: Optional[str] = None, ENU_array: Optional[Array] = None, dish_d: float = 13.965, random_seed: int = 0, auto_corrs: bool = False, n_int_samples: int = 4, name: str = 'MeerKAT', max_chunk_MB: float = 100.0)

Construct an Observation object defining a radio interferometry observation.

Parameters

latitude: float

Latitude of the telescope.

longitude: float

Longitude of the telescope.

elevation: float

Elevation of the telescope.

ra: float

Right Ascension of the phase centre.

dec: float

Declination of the phase centre.

times: ndarray (n_time,)

Time centroids of each data point.

freqs: ndarray (n_freq,)

Frequency centroids for each observation channel.

SEFD: ndarray (n_freq,)

System Equivalent Flux Density of the telescope over frequency.

ENU_path: str

Path to a txt file containing the ENU coordinates of each antenna.

ENU_array: ndarray (n_ant, 3)

ENU coordinates of each antenna.

dish_d: float

Diameter of each antenna dish.

random_seed: int

Random seed to use for random number generator.

auto_corrs: bool

Flag to include autocorrelations in simulation.

n_int_samples: int

Number of samples per time step which are then averaged. Must be large enough to capture time-smearing of RFI sources on longest baseline.

name: str

Name of the telescope.

Observation.addAstro(I: Array, ra: Array, dec: Array)

Add a set of astronomical sources to the observation.

Parameters

I: ndarray (n_src, n_time_fine, n_freq) or

Intensity of the sources in Jy. If I.ndim==2, then this is assumed to the spectrogram (n_time, n_freq) of a single source. If I.ndim==1, then this is assumed to be the spectral profile of a single source.

ra: array (n_src,)

Right ascension of the sources in degrees.

dec: array (n_src,)

Declination of the sources in degrees.

Observation.addSatelliteRFI(Pv: Array, elevation: Array, inclination: Array, lon_asc_node: Array, periapsis: Array)

Add a satellite-based source of RFI to the observation.

Parameters

Pv: ndarray (n_src, n_time_fine, n_freq)

Specific Emission Power in W/Hz. If Pv.ndim==1, it is assumed to be of shape (n_freq,) and is the spectrum of a single RFI source. If Pv.ndim==2, it is assumed to be of shape (n_time_fine, n_freq) and is the spectrogram of a single RFI source.

elevation: ndarray (n_src,)

Elevation/Altitude of the orbit in metres.

inclination: ndarray (n_src,)

Inclination angle of the orbit relative to the equatorial plane.

lon_asc_node: ndarray (n_src,)

Longitude of the ascending node of the orbit. This is the longitude of when the orbit crosses the equator from the south to the north.

periapsis: ndarray (n_src,)

Perisapsis of the orbit. This is the angular starting point of the orbit at t = 0.

Observation.addStationaryRFI(Pv: Array, latitude: Array, longitude: Array, elevation: Array)

Add a stationary source of RFI to the observation.

Parameters

Pv: ndarray (n_src, n_time_fine, n_freq)

Specific Emission Power in W/Hz. If Pv.ndim==1, it is assumed to be of shape (n_freq,) and is the spectrum of a single RFI source. If Pv.ndim==2, it is assumed to be of shape (n_time_fine, n_freq) and is the spectrogram of a single RFI source.

latitude: ndarray (n_src,)

Geopgraphic latitude of the source in degrees.

longitude: ndarray (n_src,)

Geographic longitude of the source in degrees.

elevation: ndarray (n_src,)

Elevation/Altitude of the source above sea level in metres.

Observation.addGains(G0_mean: float, G0_std: float, Gt_std_amp: float, Gt_std_phase: float, random_seed=None)

Add complex antenna gains to the simulation. Gain amplitudes and phases are modelled as linear time-variates. Gains for all antennas at t = 0 are randomly sampled from a Gaussian described by the G0 parameters. The rate of change of both ampltudes and phases are sampled from a zero mean Gaussian with standard deviation as provided.

Parameters

G0_mean: float

Mean of Gaussian at t = 0.

G0_std: float

Standard deviation of Gaussian at t = 0.

Gt_std_amp: float

Standard deviation of Gaussian describing the rate of change in the gain amplitudes in 1/seconds.

Gt_std_phase: float

Standard deviation of Gaussian describing the rate of change in the gain phases in rad/seconds.

random_seed: int, optional

Random number generator key.

Observation.calculate_vis(random_seed=None)

Calculate the total gain amplified visibilities, average down to the originally defined sampling rate and add noise.

Observation.write_to_zarr(path: str = 'Observation', overwrite: bool = False)

Write the visibilities to disk using zarr format.

Observation.write_to_ms(path: str = 'Observation.ms', overwrite: bool = False, ds: Optional[Dataset] = None)

Write the visibilities to disk using Measurement Set format.

Coordinates

tabascal.jax.coordinates.radec_to_lmn(ra: Array, dec: Array, phase_centre: Array) Array

Convert right-ascension and declination positions of a set of sources to direction cosines.

Parameters

randarray (n_src,)

Right-ascension in degrees.

decndarray (n_src,)

Declination in degrees.

phase_centrendarray (2,)

The ra and dec coordinates of the phase centre in degrees.

Returns

lmnndarray (n_src, 3)

The direction cosines, (l,m,n), coordinates of each source.

tabascal.jax.coordinates.radec_to_XYZ(ra: Array, dec: Array) Array

Convert Right ascension and Declination to unit vector in ECI coordinates.

Parameters

randarray (n_src,)

Right-ascension in degrees.

decndarray (n_src,)

Declination in degrees.

Returns

xyz: ndarray (n_src, 3) or (3,)

The ECI coordinate unit vector of each source.

tabascal.jax.coordinates.ENU_to_GEO(geo_ref: Array, enu: Array) Array

Convert a set of points in ENU co-ordinates to geographic coordinates i.e. (latitude, longitude, elevation).

Parameters

geo_ref: ndarray (3,)

The latitude, longitude and elevation, (lat,lon,elevation), of the reference position i.e. ENU = (0,0,0).

enu: ndarray (n_ants, 3)

The ENU coordinates of each antenna. (East, North, Up).

Returns

geo_ants: ndarray (n_ant, 3)

The geographic coordinates, (lat,lon,elevation), of each antenna.

tabascal.jax.coordinates.GEO_to_XYZ(geo: Array, times: Array) Array

Convert geographic coordinates to an Earth Centred Inertial (ECI) coordinate frame. This is different to ECEF as ECI remains fixed with the celestial sphere whereas ECEF coordinates rotate w.r.t. the celestial sphere. (0,0,0) is the Earth’s centre of mass, +z points to the North Pole and +x is in the plane of the Equator passing through the Meridian at t = 0 and +y is also in the plane of the Equator and passes through 90 degrees East at t = 0. ECEF and ECI are aligned when t % T_s = 0.

Parameters

geo: ndarray (n_time, 3)

The geographic coordinates, (lat,lon,elevation), at each point in time.

times: ndarray (n_time,)

The time of each position in seconds.

Returns

xyz: ndarray (n_time, 3)

The ECI coordinates at each time, (lat,lon,elevation), of each antenna.

tabascal.jax.coordinates.ENU_to_ITRF(enu: Array, lat: float, lon: float) Array

Calculate ITRF coordinates from ENU coordinates of antennas given the latitude and longitude of the antenna array centre.

Paramters

enu: ndarray (n_ant, 3)

The East, North, Up coordinates of each antenna.

lat: float

The latitude of the observer/telescope.

lon: float

The longitude of the observer/telescope.

Returns

itrf: jnp.array (n_ant, 3)

The ITRF coordinates of the antennas.

tabascal.jax.coordinates.ENU_to_UVW(enu: Array, latitude: float, longitude: float, ra: float, dec: float, times: Array) Array

Convert antenna coordinates in the ENU frame to the UVW coordinates, where w points at the phase centre defined by (ra,dec), at specific times for a telescope at a specifc latitude and longitude.

Parameters

enu: ndarray (n_ant, 3)

The East, North, Up coordindates of each antenna relative to the position defined by the latitude and longitude.

latitude: float

Latitude of the telescope.

longitude: float

Longitude of the telescope.

ra: float

Right Ascension of the phase centre.

dec: float

Declination of the phase centre.

times: ndarray (n_time,)

Times, in seconds, at which to calculate the UVW coordinates.

Returns

uvw: ndarray (n_time, n_ant, 3)

UVW coordinates, in metres, of the individual antennas at each time.

tabascal.jax.coordinates.Rotx(theta: float) Array

Define a rotation matrix about the ‘x-axis’ by an angle theta, in degrees.

Parameters

theta: float

Rotation angle in degrees.

Returns

R: ndarray (3, 3)

Rotation matrix.

tabascal.jax.coordinates.Rotz(theta: float) Array

Define a rotation matrix about the ‘z-axis’ by an angle theta, in degrees.

Parameters

theta: float

Rotation angle in degrees.

Returns

R: ndarray (3, 3)

Rotation matrix.

tabascal.jax.coordinates.orbit(times: Array, elevation: float, inclination: float, lon_asc_node: float, periapsis: float) Array

Calculate orbital path of a satellite in perfect circular orbit.

Parameters

times: ndarray (n_time,)

Times at which to evaluate the positions.

elevation: float

Elevation/Altitude of the orbit in metres.

inclination: float

Inclination angle of the orbit relative to the equatorial plane.

lon_asc_node: float

Longitude of the ascending node of the orbit. This is the longitude of when the orbit crosses the equator from the south to the north.

periapsis: float

Perisapsis of the orbit. This is the angular starting point of the orbit at t = 0.

Returns

positions: ndarray (n_time, 3)

The position vector of the orbiting object at each specified time.

tabascal.jax.coordinates.orbit_velocity(times: Array, elevation: float, inclination: float, lon_asc_node: float, periapsis: float) Array

Calculate the velocity of a circular orbit at specific times.

Parameters

times: ndarray (n_time,)

Times at which to evaluate the rotation matrices.

elevation: float

Elevation/Altitude of the orbit in metres.

inclination: float

Inclination angle of the orbit relative to the equatorial plane.

lon_asc_node: float

Longitude of the ascending node of the orbit. This is the longitude of when the orbit crosses the equator from the south to the north.

periapsis: float

Perisapsis of the orbit. This is the angular starting point of the orbit at t = 0.

Returns

velocity: ndarray (n_time, 3)

The velocity vector at the specified times.

tabascal.jax.coordinates.RIC_dev(times: Array, true_orbit_params: Array, estimated_orbit_params: Array) Array

Calculate the Radial (R), In-track (I) and Cross-track (C) deviations between two circular orbits given their orbit parameters at many time steps.

Parameters

times: array (n_time,)

Times at which to evaluate the RIC deviations.

true_orb_params: ndarray (4,)

Orbit parameters (elevation, inclination, lon_asc_node, periapsis) of the object of most interest. The more accurate measurement when comparing the same object.

est_orb_params: array (elevation, inclination, lon_asc_node, periapsis)

Estimated orbit parameters.

Returns

RIC: ndarray (n_time, 3)

Radial, In-track and Cross-track coordinates, in metres, of the orbiting body relative to the orbit defined by ‘true_orbit_params’.

tabascal.jax.coordinates.orbit_fisher(times: Array, orbit_params: Array, RIC_std: Array) Array

Calculate the inverse covariance (Fisher) matrix in orbital elements induced by errors in the RIC frame of an orbiting object. This is essentially linear uncertainty propagation assuming Gaussian errors.

Parameters

times: ndarray (n_time,)

Times at which the RIC covariance/standard deviations is defined.

orbit_params: ndarray (4,)

Orbit parameters (elevation, inclination, lon_asc_node, periapsis) for the orbit defining the origin of the RIC frame.

RIC_std: ndarray (3,)

The standard deviation in the Radial, In-track and Cross-track directions.

Returns

fisher: ndarray (4, 4)

The inverse covariance (Fisher) matrix for the orbit parameters induced by the orbit uncertainties in the RIC frame.

Interferometry

tabascal.jax.interferometry.rfi_vis(app_amplitude, c_distances, freqs, a1, a2)

Calculate visibilities from distances to rfi sources.

Parameters

app_amplitude: array_like (n_src, n_time, n_ant, n_freq)

Apparent amplitude at the antennas.

c_distances: array_like (n_src, n_time, n_ant)

The phase corrected distances between the rfi sources and the antennas in metres.

freqs: array_like (n_freq,)

Frequencies in Hz.

a1: array_like (n_bl,)

Antenna 1 indexes, between 0 and n_ant-1.

a2: array_like (n_bl,)

Antenna 2 indexes, between 0 and n_ant-1.

Returns

vis: array_like (n_time, n_bl, n_freq)

The visibilities.

tabascal.jax.interferometry.astro_vis(sources, uvw, lmn, freqs)

Calculate visibilities from a set of point sources using DFT.

Parameters

sources: array_like (n_src, n_time, n_freq)

Array of point source intensities in Jy.

uvw: array_like (ntime, n_bl, 3)

(u,v,w) coordinates of each baseline.

lmn: array_like (n_src, 3)

(l,m,n) coordinate of each source.

freqs: array_like (n_freq,)

Frequencies in Hz.

Returns

vis: array_like (n_time, n_bl, n_freq)

Visibilities of the given set of sources and baselines.

tabascal.jax.interferometry.ants_to_bl(G, a1, a2)

Calculate the complex gains for each baseline given the per antenna gains.

Parameters

G: array_like (n_time, n_ant, n_freq)

Complex gains at each antenna over time.

a1: array_like (n_bl,)

Antenna 1 indexes, between 0 and n_ant-1.

a2: array_like (n_bl,)

Antenna 2 indexes, between 0 and n_ant-1.

Returns

G_bl: array_like (n_time, n_bl, n_freq)

Complex gains on each baseline over time.

tabascal.jax.interferometry.airy_beam(theta: Array, freqs: Array, dish_d: float)

Calculate the primary beam voltage at a given angular distance from the pointing direction. The beam intensity model is the Airy disk as defined by the dish diameter. This is the same a the CASA default.

Parameters

theta: (n_src, n_time, n_ant)

The angular separation between the pointing direction and the source.

freqs: (n_freq,)

The frequencies at which to calculate the beam in Hz.

dish_d: float

The diameter of the dish in meters.

Returns

E: ndarray (n_src, n_time, n_ant, n_freq)

The beam voltage at each frequency.

tabascal.jax.interferometry.Pv_to_Sv(Pv: Array, d: Array) Array

Convert emission power to received intensity in Jy. Assumes constant power across the bandwidth. Calculated from

\[Jy = \]

rac{P G_a}{FSPL Delta u A_e}

=

rac{P G_a lambda^2 4pi}{(4pi d)^2 Delta u lambda^2}

=

rac{P G_a}{4pi d^2 Delta u}

Pv: ndarray (n_src, n_time, n_freq)

Specific emission power in W/Hz.

d: ndarray (n_src, n_time, n_ant)

Distances from source to receiving antennas in m.

Sv: ndarray (n_src, n_time, n_ant, n_freq)

Spectral flux density at the receiving antennas in Jy.

tabascal.jax.interferometry.SEFD_to_noise_std(SEFD: Array, chan_width: Array, int_time: Array)

Calculate the standard deviation of the complex noise in a visibility given the system equivalent flux density, the channel width and integration time.

Parameters

SEFD: ndarray (n_freq, )

System equivalent flux density in Jy.

chan_width: ndarray (n_time, n_ant, n_freq)

Channel width in Hz.

int_time: float

Integration time in seconds.

Returns

noise_std: ndarray (n_time, n_ant, n_freq)

Standard deviation of the complex noise in a visibility.

tabascal.jax.interferometry.int_sample_times(times: Array, n_int_samples: int = 1)

Calculate the times at which to sample the visibilities given the time centroids. This shoudl produce n_int_samples times per integration time that are evenly spaced around the time centroid.

Parameters

times: ndarray (n_time, )

The time centroids at which to sample the visibilities.

n_int_samples: int

The number of samples to take per integration time.

Returns

times_fine: ndarray (n_time * n_int_samples, )

The times at which to sample the visibilities.

tabascal.jax.interferometry.generate_gains(G0_mean: complex, G0_std: float, Gt_std_amp: float, Gt_std_phase: float, times: Array, n_ant: int, n_freq: int, key: Array)

Generate complex antenna gains. Gain amplitudes and phases are modelled as linear time-variates. Gains for all antennas at t = 0 are randomly sampled from a Gaussian described by the G0 parameters. The rate of change of both ampltudes and phases are sampled from a zero mean Gaussian with standard deviation as provided.

Parameters

G0_mean: complex

Mean of Gaussian at t = 0.

G0_std: float

Standard deviation of Gaussian at t = 0.

Gt_std_amp: float

Standard deviation of Gaussian describing the rate of change in the gain amplitudes in 1/seconds.

Gt_std_phase: float

Standard deviation of Gaussian describing the rate of change in the gain phases in rad/seconds.

key: jax.random.PRNGKey

Random number generator key.

tabascal.jax.interferometry.apply_gains(vis_ast: Array, vis_rfi: Array, gains: Array, a1: Array, a2: Array)

Apply antenna gains to visibilities.

Parameters

vis_ast: ndarray (n_time, n_bl, n_freq)

The astronomical visibilities.

vis_rfi: ndarray (n_time, n_bl, n_freq)

The RFI visibilities.

gains: ndarray (n_time, n_ant, n_freq)

The antenna gains.

a1: ndarray (n_bl,)

The first antenna index for each baseline.

a2: ndarray (n_bl,)

The second antenna index for each baseline.

Returns

vis_obs: ndarray (n_time, n_bl, n_freq)

The visibilities with gains applied.

tabascal.jax.interferometry.time_avg(vis: Array, n_int_samples: int = 1)

Average visibilities in time.

Parameters

vis: ndarray (n_time_fine, n_bl, n_freq)

The visibilities to average in time.

n_int_samples: int

The number of samples to take per integration time.

Returns

vis_avg: ndarray (n_time, n_bl, n_freq)

The averaged visibilities.