Cheetah Operation for Integrators

The Cheetah Application

Cheetah is an application, that can be driven from a command-line, that searches beamformed data from the correlator–beamformer (CBF) and produces candidate detections of time-domain astrophysical sources. It is implemented in C++ and built on the PANDA C++ library, a generic framework for developing multi-architecture, single-process data-processing pipelines. In this page, we describe the basic operational model of cheetah when running as a standalone application from the command line. Details on how to execute cheetah using CSP and PSS LMCs will be provided elsewhere.

Cheetah supports searches for two broad categories of astrophysical time-domain sources:

  • Periodic sources — primarily pulsars, but also any regularly repeating radio signal.

  • Transient sources — non-repeating or aperiodically repeating radio sources. Examples include fast radio bursts (FRBs), rotating radio transients (RRATs), and giant pulses (GPs).

Each instance of Cheetah comprises a set of modules that can be individually enabled and configured as required, forming a pipeline specific to the source type under search.

Accordingly, Cheetah provides two main search pipelines:

  • Frequency-domain acceleration search (FDAS) — searches for (accelerated) periodic radio sources (pulsars). This search is performed on all ingested data after a scan has ended.

  • Single-pulse search (SPS) — searches for non-repeating or aperiodically repeating radio sources (e.g. FRBs, RRATs, GPs). This search is carried out in near real-time, during a scan, on ingested data.

Basic Operation

Cheetah is launched from the command line. A small number of command line arguments are used to configure cheetah at a high level, and the specific configurations for how the beamformed data should be handled, and the individual modules that will process it, are specified in a configuration file (nominally provided in XML format, described below).

The following command example shows how cheetah can be launched

cheetah_pipeline --config=</path/to/config/file> --pipeline=<required search pipeline> -s <data source> --log-level=<log level>

To see the list of command line options for cheetah, run

cheetah_pipeline -h

Configuring cheetah

Cheetah is composed of multiple modules, each of which can be independently configured, enabled, or disabled via a configuration file. Cheetah currently supports configuration files in XML format, with limited support for JSON. Work is underway to improve JSON support, to better align with the JSON-based configuration used elsewhere in the SKA. Cheetah can also be configured via command-line arguments, but due to the number of available options and possible combinations, this method risks being error-prone when running the pipeline manually. The current PSS.LMC manages Cheetah exclusively using configuration files in XML format.

The configuration file is defined and written to disk prior to the execution of Cheetah. Cheetah, when executed, reads the file, validates it, and assembles a pipeline accordingly. At the time of writing, the parameters specified in the configuration file are fixed for the lifetime of the cheetah pipeline and are not subject to changes, or available to be changed, whilst a pipeline is running.

An evolving spreadsheet showing cheetah configuration parameters and their definitions is located here.

The configuration file defines up to three beams, along with the individual modules required to search each beam. Module settings apply uniformly to all defined beams, as shown in the following example

<cheetah>
  <beams>
      <beam>
         <id>1</id>
         configuration options
      </beam>
      <beam>
          <id>2</id>
          configuration options
      </beam>
      <beam>
          <id>3</id>
          configuration options
      </beam>
  </beams>
  <module_a>configuration options</module_a>
  <module_b>configuration options</module_b>
  <module_c>configuration options</module_c>
</cheetah>

Data sources

The command line flag -s specifies the data source cheetah will use when launched. Cheetah is able to ingest data from network streams over UDP or from files (in sigproc filterbank format). To view which data sources are available, run

cheetah_pipeline --list-sources

The scope of this document is limited to sigproc and udp_low_lite as these are the only source formats currently integrated into operational and product test environments.

sigproc

SIGPROC is a widely used software package for pulsar data analysis and its filterbank file (normally stored with the file extension .fil) format is used for storing radio astronomy time-frequency data. A SIGPROC filterbank file consists of

  • A header - An ascii text block delimited by the character sets HEADER_START and HEADER_END. It consists of key-value pairs which describe the contents of the file and the observation (whether real or simulated) that produced them (e.g., source name, centre frequency, number of channels, channel bandwidth, time resolution, etc).

  • A data block - raw filterbank data stored as binary. The data are stored as 8-bit unsigned integers and represent power values for each frequency channel, sampled at uniform time intervals.

If the cheetah_pipeline argument,

cheetah_pipeline <other args> -s sigproc

is used, cheetah will read data from a sigproc file, the details of which (e.g, the path to the file) are specified in the configuration file. If this mode is used, cheetah will exit on completion of processing the file.

udp_low_lite

UDP_LOW_LITE is a network data format used by cheetah that is specific to SKA-LOW. Filterbank data is delivered to cheetah as a stream of UDP packets rather than a file on a disk (see CBF-PSS ICD). It provides the same time-frequency samples as SIGPROC data but is transmitted over a network for direct ingestion by the pipeline.

If the cheetah_pipeline argument

cheetah_pipeline <other args> -s udp_low_lite

is used, cheetah will read data from a network interface, the details of which (port, IP) are specified in the configuration file. If this mode is used, cheetah will not exit when the incoming stream terminates. It will remain active indefinitely, awaiting further data, until manually terminated (e.g, by CTRL+C or kill -15).

Configuring the data source

In the section of the configuration which described the beams, the user can set the source flags according to the expected data source.

<cheetah>
  <beams>
    <beam>
      <other_beam_config_options/>
      <source>
        <sigproc>
          <file>specify the sigproc file(s) to read as input data</file>
          <chunk_samples>the number of time samples in each chunk</chunk_samples>
          <default-nbits>specify the default number of bits to use when not specified in sigproc header</default-nbits>
        </sigproc>
        <udp_low_lite>
          <number_of_threads>the number of threads to run the engine</number_of_threads>
          <spectra_per_chunk>the number of time slices in each chunk (time_slices x no_of_channels = total data samples)</spectra_per_chunk>
          <max_buffers>the max number of udp packet buffers to use</max_buffers>
          <listen>
            <port>the port of the endpoint (default=34345)</port>
            <ip_address>the endpoint IP address (default=127.0.0.1)</ip_address>
          </listen>
        </udp_low_lite>
      </source>
      <id>1</id>
    </beam>
  </beams>
  <module_a>configuration options</module_a>
  <module_b>configuration options</module_b>
  <module_c>configuration options</module_c>
</cheetah>

When executed, cheetah will be configured to use only the data source specified on the command line, even if other data sources are included in the configuration file.

Pipelines

The command line flag --pipeline (or -p), specifies the search pipeline that the incoming data (described by the --source argument) will be passed through. To view which search pipelines are available, run

cheetah_pipeline --list-pipelines

The scope of this document is limited to Empty, Fdas and SinglePulse as these are the pipeline types that are currently integrated into operational and product test environments.

SinglePulse

This pipeline will ingest data from the data source and search it in real time for single pulses. Candidate pulses that are identified by the pipeline will be written to a location on disk as specified in the configuration file along with metadata that describe each pulse. In production we expect to stream candidate data directly over a network to SDP but this functionality is yet to be implemented.

The single pulse search pipeline will produce two types of data file representing the detected candidates.

  • Filterbank files (multiple per beam) - Slices of the input time-frequency series truncated around the detected candidate. The number of time samples around the candidate pulse is specified in the configuration file. The candidates are dispersed - that is, the frequency dependent effects of the interstellar medium (ISM) which causes lower frequencies to arrive later at the telescope than higher frequencies, is not removed before the candidate pulse is written to file. This means that candidates with a larger dispersion measure (DM), will produce larger filterbank files than those with a smaller DM. For efficiency, candidate filterbanks may include multiple distinct candidates, therefore there may be fewer individual filterbanks produced, than appear in the candidate metadata file (see below). The candidate filterbank files are named according to the timestamp of the first sample in the candidate file, and have the file extension .fil. Where no candidates are detected, no .fil files will be produced by the pipeline.

  • Candidate metadata file (one per beam) - This file describes relevant features of each detected candidate. It is an ascii plain-text file with N rows and M columns, where N is the number of detected candidates and M is the number of features. At the time of writing, 5 features are included in the candidate metadata file. The file is named according to the time of the first sample of the data being searched, and it has the extension .spccl. Where no candidates are detected, the file is still produced but will only contain the columns headers. These columns are (in order from l-r):

    • The time-of-arrival (timestamp) of the detected pulse (in modified Julian days (MJD)).

    • The DM of the detected pulse (in parsecs per cubic centimetre)

    • The width of the detected pulse (in ms)

    • The S/N (significance) of the detected pulse

    • The cluster to which the candidate belongs (clustering, in this context, means the grouping of unlabelled data points into “clusters” which represent candidates which are sufficiently similar to each other to have a high probability of originating from the same source).

Data is streamed out of the pipeline through output channels. Different parts of the pipeline will broadcast data to a named channel and this data will be fed to any exporter that is listening into that channel.

The locations on disk to where SPS candidates will be written is set in the configuration file. This is done in two steps. The first is to create the necessary data routing channels and to activate them, and the second is to associate the exporters from individual modules with those channels using sink_configs. An example is below in which the sps_events channel is created and activated, and is given two ids; one for the candidate metadata (spccl_files) and one for the candidate filterbanks (candidate_files). The sink_configs are then attached to these channels by means of the ids. We also configure the file extensions and the directories to which they are written. Note that the directory has to exist prior to the execution of cheetah. Cheetah will not create these directories.

<cheetah>
  <beams>
    <beam>
      <active>true</active>
      <other_beam_configuration_options/>
      <sinks>
        <channels>
          <sps_events>
            <active>true</active>
            <sink>
              <id>spccl_files</id>
            </sink>
            <sink>
              <id>candidate_files</id>
            </sink>
          </sps_events>
        </channels>
        <sink_configs>
          <spccl_files>
            <extension>.spccl</extension>
            <dir>/path/to/sps/candidate/directory</dir>
            <id>spccl_files</id>
          </spccl_files>
          <spccl_sigproc_files>
            <dir>/path/to/sps/candidate/directory</dir>
            <extension>.fil</extension>
            <candidate_window>
              <ms_before>1000</ms_before>
              <ms_after>1000</ms_after>
            </candidate_window>
            <id>candidate_files</id>
          </spccl_sigproc_files>
        </sink_configs>
      </sinks>
    </beam>
  </beam>
  <module_a>configuration options</module_a>
  <module_b>configuration options</module_b>
  <module_c>configuration options</module_c>
</cheetah>

Below shows an example of the contents of a directory in which candidates from a single beam, searched by SPS, are written. There are nine filterbanks (fil), and one metadata file (spccl)

$ ls
2012_03_14_00:00:04.fil
2012_03_14_00:00:06.fil
2012_03_14_00:00:12.fil
2012_03_14_00:00:14.fil
2012_03_14_00:00:22.fil
2012_03_14_00:00:30.fil
2012_03_14_00:00:38.fil
2012_03_14_00:00:40.fil
2012_03_14_00:00:00.spccl
2012_03_14_00:00:46.fil

and the contents of the spccl file, which describes a total of 67 candidates, ordered by timestamps, the first 5 of which are listed below (note that the cluster id column does not appear in this example)

SPS candidate metadata

MJD(decimal days)           dm(dimensionless)          width(ms)             sigma
56000.0000623378                 550.4                 0.256                 6.17
56000.0000806282                2018.4                 8.192                 9.46
56000.00008064                  2024.8                 8.192                 7.88
56000.0000806756                2012                   8.192                 11.97
56000.000080723                 2002.4                 8.192                 13.45
...

Fdas

The frequency-domain acceleration search pipeline will ingest data from the data source and search it for pulsars. Candidate pulsars that are identified by the pipeline will be written to a location on disk as specified in the configuration file along with metadata that describe each candidate. In production we expect to stream candidate data directly over a network to SDP but this functionality is yet to be implemented. In this mode, the SPS pipeline will run alongside the FDAS pipeline and so the candidates described in the section above will be produced in addition to pulsar candidates.

The FDAS pipeline will produce two types of data file representing the detected candidates.

  • Candidate archive file (one per beam) - Candidate pulsar detections comprising folded and dedispersed individual archives (one for each detected candidate), separated by header data that describes the candidate. The number of phase bins, frequency channels and sub-integrations for the archives is specified in the configuration file. Phase bins define the resolution of the folded pulse profile, frequency channels correspond to the spectral channels across the observing band, and sub-integrations represent consecutive time segments into which the observation is divided. The candidate files are named according to the time at which the pipeline was executed, and have the file extension .ocld. Where no candidates are detected, no .ocld files will be produced by the pipeline.

  • Candidate metadata file (one per beam) - This file describes relevant features of each detected pulsar candidate. It is an ascii plain-text file with N rows and M columns, where N is the number of detected candidates and M is the number of features. At the time of writing, 6 features are included in the candidate metadata file. The file is named according to the time at which the pipeline was executed, and it has the extension .scl. Where no candidates are detected, the file is still produced but will only contain the columns headers. These columns are (in order from l-r):

    • The period of the detected pulsar (in ms),

    • The period-derivative - a measured of the extent to which the pulsar is accelerated by binary motion (dimensionless),

    • The DM of the detected pulsar (in parsecs per cubic centimetre),

    • The number of harmonics in the power spectrum that were summed to form the detection (dimensionless),

    • The width of the pulsar profile (in ms),

    • The S/N (significance) of the detected pulse.

To configure cheetah to export candidate data to a specific location on disk we follow the procedure described above for SPS. We define two new data export channels in the configuration file (in addition to those defined for SPS candidates above) and attach FDAS exporters to them as follows.

<channels>
  <search_events>
    <active>true</active>
      <sink>
        <id>scl_files</id>
      </sink>
  </search_events>
  <ocld>
    <active>true</active>
    <sink>
      <id>ocld_files</id>
    </sink>
  </ocld>
  <other_required_channels/>
</channels>
<sink_configs>
  <ocld_files>
    <extension>.ocld</extension>
    <dir>/path/to/fdas/candidate/directory</dir>
    <id>ocld_files</id>
  </ocld_files>
  <scl_files>
    <extension>.scl</extension>
    <dir>/path/to/fdas/candidate/directory</dir>
    <id>scl_files</id>
  </scl_files>
  <other_required_sink_configs/>
<sink_configs>

Note that, in the case of FDAS we create separate channels; one for the candidate metadata file called “search events”, and one for the folded archives called “ocld”. Note also, that SPS will also run alongside FDAS even if no channels/sinks are configured for SPS data products.

Below is an example of the contents of a directory in which candidates from a single beam, searched by FDAS, are written.

$ ls
2025_09_11_10:18:09.ocld
2025_09_11_10:17:50.scl

and the contents of the scl file, which describes a total of 10 candidates, are listed below

p(ms)   p_dot(dimensionless)    dm      harmonic        width(ms)       sigma
18.51789845     0       90.59999847     1       18.51789845     12.94970608
13.88878313     0       98              4       3.472195783     8.159461975
166.6783334     0       99.59999847     9       18.51981483     15.8805275
185.1279007     0       99.59999847     9       20.56976674     15.86526489
12.34554952     0       99.90000153     4       3.08638738      11.99324417
43.20892652     0       100.3000031     7       6.172703788     11.14119911
18.51789845     0       100.5999985     2       9.258949227     20.93026733
64.80817383     0       100.5999985     6       10.8013623      11.78199291
185.1279007     0       109.5999985     9       20.56976674     11.38225937
166.6783334     0       109.5999985     9       18.51981483     11.34067822

Log levels

Cheetah writes logs to STDOUT and STDERR. Informational messages and routine diagnostics are written to STDOUT, while warnings and errors are sent to STDERR. These output streams can be captured or redirected by the environment in which cheetah is running. There are 5 message categories produced by cheetah. These are

  • LOG - High-level events which detail the normal operation of the pipeline. This is equivalent to INFO in other standard logging libraries.

  • DEBUG - Low level events for tracing internal logic and providing diagnostics

  • WARN - An unexpected event has occurred but processing continues

  • ERROR - A significant event has occurred which may have corrupted normal operation of one or more components. Processing may continue if an exception is not raised

  • CONTROL - High level events relevant only to the PSS control system (PSS.LMC).

Cheetah log messages do not follow any standard logging formats like those implemented by python’s logging package, or C++’s sdplog. At the time of writing, Cheetah logs follow the format

[log-level][thread ID][File path and line number][Unix epoch]Message content

Worked examples

Here we present two examples of configurations and cheetah launch commands. Each pipeline dumps candidate data to disk and reads input data from sigproc files.

Executing scans using CSP.LMC LOW

This guide explains how to install a minikube environment into which the CSP.LMC LOW can be deployed and used to configure and manage a (set of) PSS scan(s). In this guide, CSP.LMC LOW and cheetah are installed on the same server. Everything below has been tested/previously run using Ubuntu 22.04.4 LTS.

Installing minikube

First, if not already downloaded to the server, clone the SKA minikube repository.

git clone –recursive https://gitlab.com/ska-telescope/sdi/ska-cicd-deploy-minikube.git

This tool will install all required dependencies (helm, minikube, kubectl etc) and launch the minikube cluster. As part of its workflow, it runs some commands with sudo priveleges. For this reason, passwordless sudo access must be enabled for whichever user is performing the installation (See https://serverfault.com/questions/160581/how-to-setup-passwordless-sudo-on-linux for guidance). Once this is enabled, navigate to the repository directory and launch a minikube cluster as follows.

cd ska-cicd-deploy-minikube

make all DRIVER=docker MEM=16384 CPUS=16

This will take approximately 5 minutes to complete. Once this has finished, you can check that the cluster is running using kubectl.

kubectl get pods --all-namespaces

which will show something like

NAMESPACE            NAME                                                          READY   STATUS      RESTARTS       AGE
extdns               extdns-coredns-7b44849645-tjzvb                               1/1     Running     0              21m
ingress-nginx        ingress-nginx-admission-create-zm68c                          0/1     Completed   0              27d
ingress-nginx        ingress-nginx-admission-patch-c79z5                           0/1     Completed   0              27d
ingress-nginx        ingress-nginx-controller-67c5cb88f-bltks                      1/1     Running     11 (23m ago)   27d
kube-system          coredns-674b8bbfcf-7h98x                                      1/1     Running     11 (23m ago)   27d
kube-system          etcd-minikube                                                 1/1     Running     3 (23m ago)    27d
kube-system          kube-apiserver-minikube                                       1/1     Running     4 (23m ago)    27d
kube-system          kube-controller-manager-minikube                              1/1     Running     3 (23m ago)    27d
kube-system          kube-proxy-rgdpq                                              1/1     Running     3 (23m ago)    27d
kube-system          kube-scheduler-minikube                                       1/1     Running     3 (23m ago)    27d
kube-system          metrics-server-7fbb699795-h6kdb                               1/1     Running     11 (23m ago)   27d
kube-system          storage-provisioner                                           1/1     Running     17 (22m ago)   27d
kyverno              kyverno-admission-controller-bfb99d565-sgwrz                  1/1     Running     13 (23m ago)   27d
kyverno              kyverno-background-controller-5fcc4b78fb-8f4v4                1/1     Running     12 (23m ago)   27d

To tear everything down again (should you need to) run

make minikube-clean

This will delete the whole cluster - including any components that are deployed into it - so should be used with care.

Installing CSP.LMC LOW

The CSP.LMC LOW expects certain default prerequisites.

  • sshd is installed and running on the server (check with systemctl status ssh)

  • there exists a user on the system called cheetah with a standard home area (i.e, /home/cheetah). This user also has the password cheetah.

  • cheetah is installed into that user’s home area and the executable is in the following location - /home/cheetah/cheetah/install/bin/cheetah_pipeline. The executable can be softlinked to this location if required.

If the following conditions are fulfilled, clone and navigate to the CSP.LMC LOW repository (note: For the 2025 Pawsey tests, use branch at4-2014-test-pull-branch-of-pss-lmc if udp_low_lite is required as the data source - see below).

git clone --recursive https://gitlab.com/ska-telescope/ska-csp-lmc-low.git

cd ska-csp-lmc-low

The CSP.LMC is able to communicate with and control various different “cheetahs” - such a cheetah simulators, containerised cheetahs or bare metal cheetahs. Going forward this guide will focus on bare metal cheetah. The first step is to locate the correct helm chart for controlling a bare metal cheetah and edit it to contain the IP address of the host on which cheetah is installed (this can be localhost or a remote server). Open the “real cheetah” helm chart

vi charts/low-csp-umbrella/values-real-cheetah.yaml

and add the IP address of the host on which cheetah is installed (obtainable with ip addr show) to the ska-pss-lmc section in the field nodeIP.

If streaming data into cheetah from another node (or the same node onto which cheetah is installed) fill in the pipelineIPs and nodeStartPort with the address and port cheetah just listen to for a CBF stream.

ska-pss-lmc:
  enabled: true
  telescope: SKA-low
  #ska_pss_lmc:
  #  image:
  #    registry: registry.gitlab.com/ska-telescope/ska-pss-lmc
  #    image: ska-pss-lmc
  #    tag: 0.3.0-rc.1-dev.cd778462a

  numSubarrays: 4
  nodes:
    - nodeIP: "172.16.1.11" # cheetah processing node address
      pipelineIPs:     # data node IP addresses (the same as ctrl in test environment)
        - "172.16.1.11" # IP from which cheetah will listen for incoming stream data.
  nodeStartPort: 2100

The next step is to build the CSP.LMC LOW docker image. Firstly run

eval $(minikube docker-env).

this changes the current shell’s Docker environment variables so that the local docker CLI no longer talks to the host machine’s Docker daemon — it talks to the Docker daemon running inside the Minikube VM. Next we build the CSP.LMC LOW

make oci-build

This will take about 5 minutes. To verify that the image is available and deployable, run

docker image ls

which should print something that includes:

ska-csp-lmc-low                                                                   1.1.0-dirty                    b296a15aa435   4 weeks ago     1.47GB

The next step is to deploy the image into the minikube cluster. From the repository root directory, run

make VALUES_FILE=charts/low-csp-umbrella/values-real-cheetah.yaml k8s-install-chart

(Note: If, in a development branch, you see an error such as “Error: the lock file (Chart.lock) is out of sync with the dependencies file (Chart.yaml).”, remove or rename ./charts/low-csp-umbrella/Chart.lock and rerun the above command.)

Once this completes (or in a separate terminal whilst it’s deploying, you can see the deployment in the low-csp namespace

kubectl get pods -n low-csp

which should show something like

NAME                                    READY   STATUS      RESTARTS   AGE
cheetah-deployment-0                    1/1     Running     0          2m29s
databaseds-ds-tango-databaseds-0        1/1     Running     0          2m23s
databaseds-tangodb-tango-databaseds-0   1/1     Running     0          2m29s
ds-allocator-default-0                  1/1     Running     0          2m10s
ds-cheetahctrl-test-001-0               1/1     Running     0          2m10s
ds-controller-default-0                 1/1     Running     0          2m8s
ds-cspcontroller-test-controller-0      1/1     Running     0          107s
ds-cspsubarray-test-subarray1-0         1/1     Running     0          2m1s
ds-cspsubarray-test-subarray2-0         1/1     Running     0          2m
ds-cspsubarray-test-subarray3-0         1/1     Running     0          2m
ds-cspsubarray-test-subarray4-0         1/1     Running     0          2m2s
ds-fspcapability-test-0-0               1/1     Running     0          91s
ds-psscontroller-test-0-0               1/1     Running     0          2m7s
ds-psssubarray-test-01-0                1/1     Running     0          2m10s
ds-psssubarray-test-02-0                1/1     Running     0          2m7s
ds-psssubarray-test-03-0                1/1     Running     0          2m10s
ds-psssubarray-test-04-0                1/1     Running     0          2m6s
ds-pst-resourcemanager-test-0-0         1/1     Running     0          92s
ds-pstcapability-test-0-0               1/1     Running     0          91s
ds-resourcemanager-test-0-0             1/1     Running     0          2m10s
ds-ska-pst-lmc-beam-test-01-0           1/1     Running     0          2m10s
ds-ska-pst-lmc-beam-test-02-0           1/1     Running     0          2m10s
ds-subarray-1-0                         1/1     Running     0          2m10s
ds-subarray-2-0                         1/1     Running     0          2m7s
ds-subarray-3-0                         1/1     Running     0          2m8s
ds-subarray-4-0                         1/1     Running     0          2m8s
ds-tangotest-test-0                     1/1     Running     0          2m9s
ska-pst-init-paths-zs5gt                0/2     Completed   0          2m29s
ska-tango-base-itango-console           1/1     Running     0          2m29s

Executing a scan

The following assumes that a Single Pulse search is to be configured using data from UDP stream. In other words, the command that PSS.LMC will execute under the hood is

/home/cheetah/cheetah/install/bin/cheetah_pipeline --config=<config> -p SinglePulse s udp_low --log-level=debug

All commands in the guide that follows are executed in an iTango console. However, it’s possible (and probably more efficient) to do with with Taranta dashboard. In the example below we will not send any data to cheetah. This means that although we configure a single pulse search pipeline, cheetah will not receive any data to pass to it. Cheetah will simply start, wait for data, and then we will terminate it.

First connect to the itango console pod, setting the entrypoint as itango3 - this will bring up an iTango console into which we can type commands to prepare and manage a PSS scan.

kubectl exec -it ska-tango-base-itango-console -n low-csp -- itango3


Defaulted container "itango" out of: itango, check-dependencies-0 (init)
ITango 9.5 -- An interactive Tango client.

Running on top of Python 3.10.12, IPython 8.5 and PyTango 9.5

help      -> ITango's help system.
object?   -> Details about 'object'. ?object also works, ?? prints more.

IPython profile: tango

hint: Try typing: mydev = Device("<tab>

In [1]:

The first step is to create device proxies to all tango devices we wish to interact with. Creating a device proxy means instantiating a local software object that represents a remote Tango device. Through this proxy, commands can be sent and attributes read or written as if the device were local.

We will create proxies to the following devices.

  • The CSP controller (csp)

  • A CSP subarray controller (csp_subarray)

  • A PSS subarray controller (pss_subarray)

  • A cheetah (node) controller (cheetah)

  • A CBF controller (cbf)

In [1]: csp = tango.DeviceProxy("low-csp/control/0")

In [2]: csp_subarray = tango.DeviceProxy("low-csp/subarray/01")

In [3]: pss_subarray = tango.DeviceProxy("low-pss/subarray/01")

In [4]: cheetah = tango.DeviceProxy("low-pss/cheetah/001")

In [5]: cbf = tango.DeviceProxy("low-cbf/subarray/01")

Now check the adminMode on the CSP controller (should be ONLINE)

In [6]: csp.AdminMode
Out[6]: <adminMode.ONLINE: 0>

The same adminMode should be reported by all other devices. If it is in OFFLINE mode, we can set it to ONLINE as below. One of the consequences of this is that the PSS node controller(s) will log in to the cheetah application server over ssh.

In [7]: csp.AdminMode = 0

In [8]: csp.AdminMode
Out[8]: <adminMode.ONLINE: 0>

Next we can check the ObsState of the CSP subarray controller, which should be empty.

In [9]: csp_subarray.ObsState
Out[9]: <obsState.EMPTY: 0>

The same should be true of all other devices (except cheetah which starts in IDLE). Now we are in a position to assign resource to our subarray. The following is an example AssignResources payload

{
  "interface": "https://schema.skao.int/ska-low-csp-assignresources/5.0",
  "transaction_id": "txn-....-00001",
  "common": {
    "subarray_id": 1
  },
  "lowcbf": {},
  "pss": {
    "beams_id": [
      1,
      2,
      3
    ]
  }
}

which we will flatten (easier for iTango), assign to a variable and pass to AssignResources

In [13]: resources = '{"interface":"https://schema.skao.int/ska-low-csp-assignresources/5.0","transaction_id":"txn-....-00001","commo
  ...: n":{"subarray_id":1},"lowcbf":{},"pss":{"beams_id":[1,2,3]}}'

In [14]: csp_subarray.AssignResources(resources)

Now we use the PSS subarray to see the resources we’ve assigned. Note above, we assigned 3 beam (each on the same IP with consecutive ports) into one subarray (1 cheetah)

In [15]: pss_subarray.AssignedCheetahs
Out[15]: '{"cheetahs": [{"cheetah_fqdn": "low-pss/cheetah/001", "beams": [{"beam_id": 1, "ip_addr": "172.16.1.11", "port": "2100"}, {"beam_id": 2, "ip_addr": "172.16.1.11", "port": "2101"}, {"beam_id": 3, "ip_addr": "172.16.1.11", "port": "2102"}]}]}'

We should also have transitioned to an IDLE state

In [16]: csp_subarray.ObsState
Out[16]: <obsState.IDLE: 2>

Now we are in a position to configure the scan we wish to carry out. An example scan configuration payload can be found in LMC scan configuration payload example. We will flatten this configuration command, assign to a variable and pass to Configure

In [17]: configure_payload = '{"interface":"https://schema.skao.int/ska-low-csp-configure/6.0","transaction_id":"txn-....-00001","sub
  ...: array":{"subarray_name":"science period 23"},"common":{"config_id":"sbi-mvp01-20200325-00001-science_A","subarray_id":1,"eb_
  ...: id":"eb-x449-20231105-34696"},"lowcbf":{"stations":{"stns":[[18,1],[34,1],[21,1],[42,1],[54,1],[72,1]],"stn_beams":[{"beam_i
  ...: d":1,"freq_ids":[64],"delay_poly":"ska_low/tm_leaf_node/csp_subarray01/DelayModel"}]},"vis":{"fsp":{"firmware":"vis:0.0.6-de
  ...: v.636d2e14:gitlab","fsp_ids":[1]},"stn_beams":[{"stn_beam_id":1,"host":[[0,"192.168.2.2"]],"mac":[[0,"0c-42-a1-9c-a2-1b"]],"
  ...: port":[[0,20000,1]],"integration_ms":849}]},"search_beams":{"firmware":"pss","beams":[{"pss_beam_id":1,"stn_beam_id":1,"stn_
  ...: weights":[0.9,1.0,1.0,1.0,0.9,1.0],"delay_poly":"tango://delays.skao.int/low/stn-beam/1","jones":"tango://jones.skao.int/low
  ...: /stn-beam/1"}]}},"pss":{"beam":[{"beam_id":1,"reference_frame":"ICRS","ra":82.75,"dec":21,"centre_frequency":1400,"beam_dela
  ...: y_centre":0,"dest_host":"192.168.178.25","dest_port":9021},{"beam_id":2,"reference_frame":"ICRS","ra":84.25,"dec":21.5,"cent
  ...: re_frequency":1400,"beam_delay_centre":0,"dest_host":"192.168.178.26","dest_port":9021}],"ddtr":{"dedispersion_samples":1310
  ...: 72,"cpu":{"active":false},"fpga":{"active":false},"gpu_bruteforce":{"active":false,"copy_dmtrials_to_host":true},"klotski":{
  ...: "active":true},"klotski_bruteforce":{"active":false},"dedispersion":[{"start":0,"end":100,"step":0.1},{"start":100,"end":300
  ...: ,"step":0.2},{"start":300,"end":700,"step":0.4},{"start":700,"end":1500,"step":0.8},{"start":1500,"end":3100,"step":1.6}]},"
  ...: config_id":1,"spdt":{"cpu":{"active":false,"samples_per_iteration":1,"number_of_widths":1},"threshold":6,"klotski":{"active":
  ...: true,"pulse_widths":"1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,15000"},"klotski_bruteforce":{"active":false,"pulse_wi
  ...: dths":"1,2,4,8,16,32,64,128"}},"transaction_id":"txn-....-00001","cheetah":[{"cheetah_id":1,"beams":[{"beam":{"active":true,
  ...: "sinks":{"channels":{"sps_events":{"active":true,"sink":[{"sink_id":"spccl_files"},{"sink_id":"candidate_files"}]}},"sink_co
  ...: nfigs":{"spccl_files":{"extension":".spccl","dir":"/tmp/beam1","sink_id":"spccl_files"},"spccl_sigproc_files":{"spectra_per_
  ...: file":0,"dir":"/tmp/beam1","extension":".fil","candidate_window":{"ms_before":500,"ms_after":1000},"sink_id":"candidate_file
  ...: s"}}},"source":{"sigproc":{"file":"filterbank1.fil","chunk_samples":1024,"default-nbits":8,"active":true},"udp_low":{"number
  ...: _of_threads":2,"spectra_per_chunk":2048,"number_of_channels":7776,"max_buffers":1,"active":false}},"beam_id":1}},{"beam":{"a
  ...: ctive":false,"sinks":{"channels":{"sps_events":{"active":true,"sink":[{"sink_id":"spccl_files"},{"sink_id":"candidate_files"
  ...: }]}},"sink_configs":{"spccl_files":{"extension":".spccl","dir":"/tmp/beam2","sink_id":"spccl_files"},"spccl_sigproc_files":{
  ...: "spectra_per_file":0,"dir":"/tmp/beam2","extension":".fil","candidate_window":{"ms_before":500,"ms_after":1000},"sink_id":"c
  ...: andidate_files"}}},"source":{"sigproc":{"file":"filterbank2.fil","chunk_samples":1024,"default-nbits":8,"active":true},"udp_
  ...: low":{"number_of_threads":2,"spectra_per_chunk":2048,"number_of_channels":7776,"max_buffers":1,"active":false}},"beam_id":2}
  ...: },{"beam":{"active":false,"sinks":{"channels":{"sps_events":{"active":true,"sink":[{"sink_id":"spccl_files"},{"sink_id":"can
  ...: didate_files"}]}},"sink_configs":{"spccl_files":{"extension":".spccl","dir":"/tmp/beam3","sink_id":"spccl_files"},"spccl_sig
  ...: proc_files":{"spectra_per_file":0,"dir":"/tmp/beam3","extension":".fil","candidate_window":{"ms_before":500,"ms_after":1000}
  ...: ,"sink_id":"candidate_files"}}},"source":{"sigproc":{"file":"filterbank3.fil","chunk_samples":1024,"default-nbits":8,"active
  ...: ":true},"udp_low":{"number_of_threads":2,"spectra_per_chunk":2048,"number_of_channels":7776,"max_buffers":1,"active":false}}
  ...: ,"beam_id":3}}]}]}}'

In [18]: csp_subarray.Configure(configure_payload)
Out[18]: [array([2], dtype=int32), ['1761300307.3304389_149744188458775_Configure']]

Note that any candidate destinations specified in this configuration, need to exist on the filesystem or cheetah will not succesfully start. Candidate destinations here are /tmp/beam1/, /tmp/beam2, /tmp/beam3.

We can check that the configuration was accepted as follows

In [19]: csp_subarray.LongRunningCommandResult
Out[19]:
('1761300307.3304389_149744188458775_Configure',
 '[0, "Task configure completed with result OK"]')

We can also check that the configuration file (config.xml) was written to cheetah’s home area. If using the development branch, note that the config files contains the sources udp_low and udp_low_lite, even though only udp_low was specified in the config above.

Now all devices should have transitioned to ObSstate=READY

In [20]: csp_subarray.ObsState
Out[20]: <obsState.READY: 4>

Before we scan we need to update the cheetah command to our requirements. We can check the currently configured data source and pipeline choice as follows.

In [21]: cheetah.cheetahDataSource
Out[21]: 'udp_low'

In [22]: cheetah.cheetahType
Out[22]: 'Empty'

For this example we’ll change the pipeline choice from Empty to SinglePulse

In [23]: cheetah.cheetahType = 'SinglePulse'

In [24]: cheetah.cheetahType
Out[24]: 'SinglePulse'

Now we are in a position to execute our scan. Following is an example scan payload.

{
  "interface": "https://schema.skao.int/ska-low-csp-scan/3.2",
  "common": {
    "subarray_id": 1
  },
  "lowcbf": {
    "scan_id": 987654321
  },
  "pss": {
    "scan_id": 1
  }
}

which we will flatten, assign to a variable and pass to Scan

In [25]: scan_payload = '{"interface":"https://schema.skao.int/ska-low-csp-scan/3.2","common":{"subarray_id":1},"lowcbf":{"scan_id":9
  ...: 87654321},"pss":{"scan_id":1}}'

In [26]: csp_subarray.scan(scan_payload)
Out[26]: [array([2], dtype=int32), ['1761301248.420311_118237901111260_Scan']]

At this point cheetah is running and you can send it data. Use the cheetah device controller to see the last log line produced by cheetah

In [27]: cheetah.CheetahLogLine
Out[27]: '[control][tid=124748471017536][/home/cheetah/pss-builder/ska-pss-cheetah/checkout/cheetah/../cheetah/pipelines/search_pipeline/detail/CheetahConfig.cpp:274][1761301248]Cheetah pipeline configured\r\n'

We should also be able to see cheetah running in top and also in cheetah’s home area, the file cheetah.log will contain captured console output from cheetah. All devices should be in ObsState=SCANNING at this point

In [28]: csp_subarray.ObsState
Out[28]: <obsState.SCANNING: 5>

Now after some time (e.g, after the data stream has stopped) we can end the scan.

In [29]: csp_subarray.endscan()
Out[29]: [array([2], dtype=int32), ['1761301654.807784_249518913442014_EndScan']]

At this point cheetah will be terminated and ObsState will return to READY for all devices. We can now reconfigure for another scan (note: the config.xml file in cheetah’s home area will need to be removed manually or the next configuration will just be appended to it and ignored) or we can end the SB here and deconfigure as follows.

In [30]: csp_subarray.End()
Out[30]: [array([2], dtype=int32), ['1761301841.760148_16636500370877_End']]

In [31]: csp_subarray.ObsState
Out[31]: <obsState.IDLE: 2>

Now we are in IDLE we can release the allocated resources back to the array.

In [32]: csp_subarray.ReleaseAllResources()
Out[32]:
[array([2], dtype=int32), ['1761301905.2586143_12272711285685_ReleaseAllResources']]

In [33]: csp_subarray.ObsState
Out[33]: <obsState.EMPTY: 0>

Then if required, we can set the adminMode back to OFFLINE using the csp controller

csp.adminMode=1