Instrument Calibration

The signal path lengths and sensitivity differ per antenna, due to factors including:

  • Wear and tear of the antennas and cables,

  • Differences in cable length between antenna and RCU,

  • Differences in signal path lengths within the processing equipment.

The signals thus need to adjusted with respect to each other in order to align their phases and amplitudes. These per-antenna calibration values are split into the following parts to apply them:

  • recv.RCU_attenuator_dB_RW: Coarse attenuation of each antenna input in the RCU, in dB,

  • sdp.FPGA_signal_input_samples_delay_RW: Coarse delay added to each antenna input in the SDP, in samples,

  • sdp.FPGA_subband_weights_RW: Fine attenuation & delay of each antenna input in the SDP, as a complex multiplication factor per antenna per subband.

These signal differences are frequency dependent. To address this, we maintain different models for signals around the reference frequencies of 50 MHz (LBA), and 150, 200, and 250 MHz (HBA). The calibration subsystem uses the antennafield.Frequency_Band_RW attribute to determine the current reference frequency for each antenna:

Antenna type

Frequency band

antennafield.Frequency_Band_RW

Clock

recv.RCU_band_select_RW

Reference frequency

LBA

10 - 90 MHz

LBA_10_90 / LBA_10_70

(any)

1

50 MHz

LBA

30 - 90 MHz

LBA_30_90 / LBA_30_70

(any)

2

50 MHz

HBA

110 - 190 MHz

HBA_110_190

200 MHz

2

150 MHz

HBA

170 - 230 MHz

HBA_170_230

160 MHz

1

200 MHz

HBA

210 - 240 MHz

HBA_210_250

200 MHz

4

250 MHz

Mathematical Background

We equalise the signals of the different antennas to compensate for the delay and attenuation effects, in two steps: coarse and fine. The following table describes what is corrected for where:

Effect

Granuality

Compensation

How

Delay

Coarse

sdp.FPGA_signal_input_samples_delay_RW

Delaying using a ring buffer

Delay

Fine

sdp.FPGA_subband_weights_RW

Phase shifts

Attenuation

Coarse

recv.RCU_attenuator_dB_RW

Dampening whole dBs

Attenuation

Fine

sdp.FPGA_subband_weights_RW

Amplitude scaling

The coarse delay compensation is done in SDP, by delaying all inputs to line up with the latest arriving one. The FPGAs do this through a sample shift, in which the samples from each input is delayed a fixed number of samples. At the 200 MHz clock, samples are 5 ns. The sample shift aligns the inputs with a remaining difference of +/- 2.5 ns.

This remainder is corrected for in the fine delay compensation, by shifting the phases of each input backwards. A phase shift is frequency dependent (-2pi * frequency * delay), and is thus applied at the higher frequency resolution after creating subbands. The FPGA_subband_weights_RW in SDP allows us to configure a complex correction factor for each subband from each input. A phase shift phi is converted into a complex factor through cos(phi) + i * sin(phi).

Note

The delay compensation shifts all antenna signals by a fixed amount: the number of samples to delay to line up with the longest cable. Yet we mark those signals as “now” in SDP. This introduces a temporal shift of the order of 200ns. This is deemed acceptable, as after the station FFT (that creates the subbands), we have 5.12ms samples, which is an order of magnitude higher time scale.

The coarse loss compensation is done in RECV on the RCU, which can attenuate each input an integer number of decibels. We attenuate each signal to line up with the weakest. The remaining attenuation is +/- 0.5 dB.

The remainder is corrected for in the fine loss compensation, by applying an amplitude scaling factor (10^(-dB/10)) as part of the complex FPGA_subband_weights_RW (see above). This scaling factor is the same for all subbands.

Configuration

The following properties describe the AntennaField for calibration purposes:

Antenna_Cables:

Encodes which cable type is attached to each antenna in the field, as described in dict common.cables.cable_types.

type:

str[N_antennas]

Field_Attenuation:

Attenuation to apply to all the antennas, on top of the cable model, to align this antennafield with other fields.

type:

float64

Coarse Corrections

Both the coarse attenuation and delay corrections are caused by the difference in cable lengths: longer cables result in more delay, and more loss of signal. We maintain a cable model in the dict common.cables.cable_types, which describes the delay introduced by each cable, as well as the loss at each of our modelled frequencies.

The coarse corrections are the rounded versions of these differences. The rounding errors, as well as the subtle differences between the individual cables of the same type are compensated for in the fine corrections below. The AntennaField exposes the following attributes to inspect the configuration and the computed calibration values:

Antenna_Cables_R:

The type of cable connected to each antenna.

type:

str[N_antennas]

Antenna_Loss_R:

The loss introduced by each cable, according to the cable model, in dB, for the currently selected frequency.

type:

float64[N_antennas]

Antenna_Delay_R:

The delay introduced by each cable, according to the cable model, in seconds.

type:

float64[N_antennas]

Calibration_SDP_Signal_Input_Samples_Delay_R:

The delay which is to be applied to both polarisations of each antenna, in samples.

type:

uint32[N_antennas]

Calibration_RCU_Attenuation_dB_R:

The attenuation to apply to each antenna, in (integer) dB.

type:

uint32[N_antennas]

Fine Corrections

The fine attenuation and delay corrections are caused by both known and unknown differences between the antennas. The known differences are the remainders from the cable model, left after the coarse corrections have been applied. The fine corrections are applied in SDP as subband weights, which are complex multiplication factors for each subband for each input.

The AntennaField exposes the known corrections as:

Calibration_SDP_Fine_Calibration_Default_R:

Computed fine calibration values, as a tuple (delay, phase_offset, amplitude_scaling).

type:

float64[N_antennas * N_pol][3]

Calibration_SDP_Subband_Weights_Default_R:

Computed fine calibration values as subband weights (complex values).

type:

float64[N_antennas * N_pol][N_subbands * VALUES_PER_COMPLEX]

To also cover the unknown differences between the antennas, the correct subband weights are actually measured and stored in calibration tables. These values then cover both the known and the unknown corrections. The AntennaField exposes the actual subband weights it will apply through:

Calibration_SDP_Subband_Weights_R:

Fine calibration values as subband weights (complex values).

type:

float64[N_antennas * N_pol][N_subbands * VALUES_PER_COMPLEX]

The individual calibration tables for each frequency are provided through:

Calibration_SDP_Subband_Weights_50MHz_R:

Fine calibration values as subband weights, for 50MHz input signals.

Calibration_SDP_Subband_Weights_150MHz_R:

Fine calibration values as subband weights, for 150MHz input signals.

Calibration_SDP_Subband_Weights_200MHz_R:

Fine calibration values as subband weights, for 200MHz input signals.

Calibration_SDP_Subband_Weights_250MHz_R:

Fine calibration values as subband weights, for 250MHz input signals.

type:

float64[N_antennas * N_pol][N_subbands * VALUES_PER_COMPLEX]

Managing Calibration Tables

The calibration tables for SDP are stored in the HDF5 file format, described at XXX, and easily read and written in Python by using the common.calibration_table.CalibrationTable class in this package, or with the more generic h5py Python package. Each file is typically named CalTable-CS001-HBA0-150MHz.h5, and is thus specific for an antenna field and the frequency band used to determine it. Each file contains the subband weights, as well as metadata on how and when they were determined.

The AntennaField device reads these files from disk, maintained in a dedicated Docker volume. New files can be downloaded from a central location on demand, providing the follow functionality:

Calibration_Table_Base_URL:

Property which contains the root URL for the calibration tables. The remote location of a calibration table is f.e. {Calibration_Table_Base_URL}/CS001/CalTable-CS001-HBA0-150MHz.h5.

download_calibration_tables():

Command to download and apply the latest calibration tables, caching them in the Docker volume.

calibrate():

Command to apply the calibration tables present in the Docker volume.

Applying Calibration Values

The following commands in AntennaField upload new calibration values to the signal chain in RECV and SDP:

calibrate_recv():

Configure recv.RCU_attenuator_dB_RW for the antennas in the field.

calibrate_sdp():

Configure sdp.FPGA_signal_input_samples_delay_RW and sdp.FPGA_subband_weights_RW for the antennas in the field.

Since both calibrations depend on the frequency of the signals, the above commands are automatically called when the attribute antennafield.Frequency_Band_RW is written.

Celestial & Geodetic Calibration

The TileBeam and DigitalBeam devices use python-casacore to compute the direction of a given pointing with respect to our antennas and reference positions. Casacore in turn uses measures tables for the precise measurements of celestial positions, geodetical information, and time calibrations (f.e. leap seconds). These tables need to be installed and periodically updated to maintain the pointing accuracy:

measures_directory_R:

Directory of the active set of measures tables. The directory name includes the timestamp denoting their age.

type:

str

measures_directories_available_R:

List of installed sets of measures tables.

type:

str[64]

download_measures():

Download (but do not activate) the latest measures tables from ftp://ftp.astron.nl/outgoing/Measures/WSRT_Measures.ztar. Returns the directory name in which the measures were installed.

returns:

str

use_measures(dir):

Activate the measures tables in the provided directory. This necessitates turning off and restarting the TileBeam device, so the command will always appear to fail. Turn the device back and the selected measures tables will be active.

returns:

(does not return)