Devices
Boot
The boot == DeviceProxy("LTS/Boot/1") device is responsible for (re)starting and initialising the other devices. Devices which are not reachable, for example because their docker container is explicitly stopped, are skipped during initialisation. This device provides the following commands:
- initialise_station()
Stop and start the other devices in the correct order, set their default values, and command them to initialise their hardware. This procedure runs asynchronously, causing this command to return immediately. Initialisation is aborted if an error is encountered.
- returns
None
The initialisation process can subsequently be followed through monitoring the following attributes:
- initialising_R
Whether the initialisation procedure is still ongoing.
- type
bool
- initialisation_progress_R
Percentage completeness of the initialisation procedure. Each succesfully configured device increments progress.
- type
int
- initialisation_status_R
A description of what the device is currently trying to do. If an error occurs, this will hint towards the cause.
- type
str
A useful pattern is thus to call initialise_station(), wait for initialising_R == False, and then check whether the initalisation was succesful, if initialisation_progress_R == 100. If a device fails to initialise, most likely the Logs will need to be consulted.
Docker
The docker == DeviceProxy("LTS/Docker/1") device controls the docker containers. It allows starting and stopping them, and querying whether they are running. Each container is represented by two attributes:
- <container>_R
Returns whether the container is running.
- type
bool
- <container>_RW
Set to
Trueto start the container, and toFalseto stop it.- type
bool
Warning
Do not stop the tango container, as doing so cripples the Tango infrastructure, leaving the station inoperable. It is also not wise to stop the device_docker container, as doing so would render this device unreachable.
RECV
The recv == DeviceProxy("LTS/RECV/1") device controls the RCUs, the LBA antennas, and HBA tiles. Central to its operation are the masks (see also Attribute masks):
- RCU_mask_RW
Controls which RCUs will actually be configured when attributes referring to RCUs are written.
- type
bool[N_RCUs]
- Ant_mask_RW
Controls which antennas will actually be configured when attributes referring to antennas are written.
- type
bool[N_RCUs][N_antennas_per_RCU]
Typically, N_RCUs == 32, and N_antennas_per_RCU == 3.
SDP
The sdp == DeviceProxy("LTS/SDP/1")` device controls the digital signal processing in SDP, performed by the firmware on the FPGAs on the Uniboards. Central to its operation is the mask (see also Attribute masks):
- TR_fpga_mask_RW
Controls which FPGAs will actually be configured when attributes referring to FPGAs are written.
- type
bool[N_fpgas]
Typically, N_fpgas == 16.
SST and XST
The sst == DeviceProxy("LTS/SST/1") and xst == DeviceProxy("LTS/XST/1") devices manages the SSTs (subband statistics) and XSTs (crosslet statistics), respectively. The statistics are emitted piece-wise through UDP packets by the FPGAs on the Uniboards in SDP. By default, each device configures the statistics to be streamed to itself (the device), from where the user can obtain them.
The statistics are exposed in two ways, as:
Attributes, representing the most recently received values,
TCP stream, to allow the capture and recording of the statistics over any period of time.
SST Statistics attributes
The SSTs represent the amplitude of the signal in each subband, for each antenna, as an integer value. They are exposed through the following attributes:
- sst_R
Amplitude of each subband, from each antenna.
- type
uint64[N_ant][N_subbands]
- sst_timestamp_R
Timestamp of the data, per antenna.
- type
uint64[N_ant]
- integration_interval_R
Timespan over which the SSTs were integrated, per antenna.
- type
float32[N_ant]
- subbands_calibrated_R
Whether the subband data was calibrated using the subband weights.
- type
bool[N_ant]
Typically, N_ant == 192, and N_subbands == 512.
XST Statistics attributes
The XSTs represent the cross-correlations between each pair of antennas, as complex values. The phases and amplitudes of the XSTs represent the phase and amplitude difference between the antennas, respectively. They are exposed as a matrix xst[a][b], of which only the triangle a<=b is filled, as the cross-correlation between antenna pairs (b,a) is equal to the complex conjugate of the cross-correlation of (a,b). The other triangle contains incidental values, but will be mostly 0.
Complex values which cannot be represented in Tango attributes. Instead, the XST matrix is exposed as both their carthesian and polar parts:
- xst_power_R, xst_phase_R
Amplitude and phase of the crosslet statistics.
- type
float32[N_ant][N_ant]
- xst_real_R, xst_imag_R
Real and imaginary parts of the crosslet statistics.
- type
float32[N_ant][N_ant]
- xst_timestamp_R
Timestamp of each block.
- type
int64[N_blocks]
- integration_interval_R
Timespan over which the XSTs were integrated, for each block.
- type
float32[N_blocks]
Typically, N_ant == 192, and N_blocks == 136.
The metadata refers to the blocks, which are emitted by the FPGAs to represent the XSTs between 12 x 12 consecutive antennas. The following code converts block numbers to the indices of the first antenna pair in a block:
from common.baselines import baseline_from_index
def first_antenna_pair(block_nr: int) -> int:
coarse_a, coarse_b = baseline_from_index(block_nr)
return (coarse_a * 12, coarse_b * 12)
Conversely, to calculate the block index for an antenna pair (a,b), use:
from common.baselines import baseline_index
def block_nr(a: int, b: int) -> int:
return baseline_index(a // 12, b // 12)
TCP stream
The TCP stream interface allows a user to subscribe to the statistics packet streams, combined into a single TCP stream. The statistics will be streamed until the user disconnects, or the device is turned off. Any number of subscribers is supported, as bandwidth allows. Simply connect to the following port:
Device |
TCP end point |
|---|---|
SST |
localhost:5101 |
XST |
localhost:5102 |
The easiest way to capture this stream is to use our statistics_writer, which will capture the statistics and store them in HDF5 file(s). The writer:
computes packet boundaries,
processes the data of each packet, and stores their values into the matrix relevant for the mode,
stores a matrix per timestamp,
stores packet header information per timestamp, as HDF5 attributes,
writes to a new file at a configurable interval.
To run the writer:
cd devices/statistics_writer
python3 statistics_writer.py --mode SST --host localhost
The correct port will automatically be chosen, depending on the given mode. See also statistics_writer.py -h for more information.
The writer can also parse a statistics stream stored in a file. This allows the stream to be captured and processed independently. Capturing the stream can for example be done using netcat:
nc localhost 5101 > SST-packets.bin