Accessing the Tango interface
In the SKA system, SDP is controlled via tango devices, the controller, and various subarray devices. The device commands and state transitions are described in their own documentation pages:
Most of the commands running on the subarray device require a “configuration string”. The schemas for such strings is described in the Schemas library.
By default, the ska-sdp chart does not deploy the ITango shell pod from the
ska-tango-base chart. Make sure you install/upgrade the chart to have ITango enabled.
(See instructions at Installing SDP with other complementary interfaces.)
Start an ITango session with:
$ kubectl exec -it ska-tango-base-itango-console -n <namespace> -- itango3
List the Tango devices that are currently in the Tango DB:
In [1]: lsdev
Device Alias Server Class
---------------------------------------- ------------------------- ------------------------- --------------------
sys/access_control/1 TangoAccessControl/1 TangoAccessControl
sys/database/2 DataBaseds/2 DataBase
sys/rest/0 TangoRestServer/rest TangoRestServer
sys/tg_test/1 TangoTest/test TangoTest
test-sdp/control/0 SDPController/0 SDPController
test-sdp/queueconnector/01 SDPQueueConnector/01 SDPQueueConnector
test-sdp/subarray/01 SDPSubarray/01 SDPSubarray
Next, connect to the subarray device, turn it On, and check its obsState.
In [2]: d = DeviceProxy('test-sdp/subarray/01')
In [3]: d.state()
Out[3]: tango._tango.DevState.OFF
In [4]: d.On()
In [5]: d.state()
Out[5]: tango._tango.DevState.ON
In [6]: d.obsState
Out[6]: <obsState.EMPTY: 0>
Note: if you are trying to execute a command that is not allowed in a given obsState, the subarray will report a tango error and stays in the obsState where it originally was at the time of command execution.
To start processing on SDP, you will need a configuration string, which provides the set up, the request for resources, and the request of what processing script to run. You can find an example string in the Tango Jupyter notebook (the configuration string can be found here, we recommend that you copy it from the display-version of the notebook and not the raw file).
Save the copied configuration string (which is provided as JSON in the example notebook) as a python string. Make sure you update the execution block and processing block IDs (if you run this multiple times, you will need to increment the number at the end):
import json
EXECUTION_BLOCK_ID = f"eb-test-20221012-00001"
PROCESSING_BLOCK_ID_REALTIME = f"pb-testrealtime-20221012-00001"
PROCESSING_BLOCK_ID_BATCH = f"pb-testbatch-20221012-00001"
config = json.dumps(<copied-json-string>)
Below, we provide the steps from assigning resources to the processing, through configure and scan, to releasing the resources and ending the process.
Once the AssignResources command is executed, you will see two processing blocks deployed
in the <processing-namespace>. First the realtime script will run.
In [8]: d.AssignResources(config)
In [9]: d.obsState
Out[9]: <obsState.IDLE: 0>
In [10]: d.Configure('{"interface": "https://schema.skao.int/ska-sdp-configure/2.0", "scan_type": "target:a"}')
In [11]: d.obsState
Out[11]: <obsState.READY: 2>
In the READY observing state, SDP processing pipelines are fully deployed and ready to start recording data. The data may already be flowing through the system with scan ID 0, which indicates the data are not part of a scan and are used for initial calibration and quality assessment.
The Scan command starts a scan. It requires a scan ID and optionally accepts a start time in ISO 8601 format with UTC timezone. If the start time is not provided, the scan starts immediately.
In [12]: d.Scan('{"interface": "https://schema.skao.int/ska-sdp-scan/2.0", "scan_id": 1}')
In [13]: d.obsState
Out[13]: <obsState.SCANNING: 3>
To schedule a scan with a specific start time:
d.Scan('{"interface": "https://schema.skao.int/ska-sdp-scan/2.0", "scan_id": 2, "start_time": "2026-05-14T12:34:56.789Z"}')
When start_time is specified, SDP will only start recording at the specified start time.
In [14]: d.EndScan()
In [15]: d.obsState
Out[15]: <obsState.READY: 2>
The EndScan command transitions the subarray back to READY state. Data continues to flow through the system with scan ID 0, which indicates the data are not part of a scan.
In [16]: d.End()
In [17]: d.obsState
Out[17]: <obsState.IDLE: 0>
Executing d.End() will trigger the batch processing block (a dask cluster),
which will automatically terminate once it’s finished the processing assigned to it.
To finish up, run:
In [18]: d.ReleaseResources('{ "interface": "https://schema.skao.int/ska-sdp-releaseres/2.0", '
'"resources": {"receptors": ["SKA001", "SKA002", "SKA003", "SKA004"]}}')
In [19]: d.obsState
Out[19]: <obsState.EMPTY: 0>
In [20]: d.Off()
In [21]: d.state()
Out[21]: tango._tango.DevState.OFF
ReleaseResources takes the list of resources (“receptors”) to be released. If you
want to release all of them at once, you may use d.ReleaseAllResources().
If at any time the obsState becomes FAULT, there has been an error somewhere in the steps.
Restart the subarray by running the d.Restart() command, which will take it back to
the EMPTY ObsState. The Off() command can also be used. Then start again.
Information and meanings on the commands and attributes provided by Tango can be found in the LMC Documentation.