Skip to content

Repository files navigation

SOUK Readout Tools

The SOUK Detector Readout System

Simons Observatory: UK (SOUK) uses Microwave Kinetic Inductance Detectors (MKIDs) to observe the cosmic microwave background across two telescopes. Each MKID is a superconducting resonator whose resonance frequency shifts in response to absorbed photons - the readout system's job is to continuously probe these resonances and record the detector responses.

The readout hardware is based on AMD/Xilinx RFSoC (Radio Frequency System-on-Chip) boards. Each board runs the souk-firmware dual-pipeline firmware providing two independent RF readout channels, each capable of driving and measuring up to 2048 tones simultaneously across a wide RF bandwidth. The full SOUK instrument uses 7 boards per telescope (28 RF networks in total), with all boards managed from a single host machine.

What This Package Does

souk_readout_tools is the Python control and data acquisition package for this system. It uses a client-server architecture with ReadoutClient and ReadoutServer classes:

  • The server runs on each RFSoC's ARM processor. It interfaces with the FPGA firmware through the souk_mkid_readout library and controls RF peripheral hardware (attenuators, amplifiers, etc.) via souk-peripherals-control. One server instance runs per pipeline (two per board), managing hardware state, configuration, and data tranmission.
  • The client runs on a remote machine and connects to an individual pipeline's server over TCP. It provides the high-level API for measurements, data acquisition, and basic analysis tools for inspecting data quality.
 Client Machine (OCS)               RFSoC Board                                            
┌─────────────────────┐            ┌──────────────────────────────────────────────────────┐
│  Python/IPython     │            │  ARM Processing System (PS)                          │
│                     │            │                                                      │
│                     │            │   ┌── Ubuntu 24.04 (CASPER image) ───────────────┐   │
│                     │            │   │                                              │   │
│    ReadoutClient A ─┼─── TCP ────┼───┼──  ReadoutServer 0 ────┐                     │   │
│                     │            │   │                        ├── souk_mkid_readout │   │
│    ReadoutClient B ─┼─── TCP ────┼───┼──  ReadoutServer 1 ────┘          │          │   │
│                     │            │   └───────────────────────────────────┼──────────┘   │
│    ReadoutClient C ─┼─           ├───────────────────────────────────────┼──────────────┤
│                     │            │  FPGA Programmable Logic (PL)         │              │
│    ...              │            │                                       │              │
│                     │            │   ┌── SOUK Firmware ──────────────────┴──────────┐   │
│    ReadoutClient N ─┼─           │   │                                              │   │
│                     │            │   │                   Pipeline 0     Pipeline 1  │   │
│                     │            │   └───────────────────────┼──────────────┼───────┘   │
│                     │            ├───────────────────────────┼──────────────┼───────────┤
│                     │            │  RF Data Converter        │              │           │
│                     │            │  (RFDC)                ┌──┴──┐        ┌──┴──┐        │
│                     │            │                      DAC0   ADC0    DAC1   ADC1      │
└─────────────────────┘            └────────────────────────┼─────┼────────┼─────┼────────┘
                                                           TX0   RX0      TX1   RX1         

Each ReadoutServer uses two TCP ports - a request port for JSON command/response control and a stream port for binary data transfer.

Capabilities

  • Tone control - set frequencies, amplitudes, and phases for up to 2048 readout tones per pipeline with full TX/RX power calibration through the entire signal chain (DSP → DAC → RF frontend → cryostat → detector). Tone updates happen on millisecond timescales, enabling fast resonator tracking.
  • Blind tone management - add fixed off-resonance monitor tones for gain/phase tracking, with config-based and interactive helpers, sweep inclusion, calibrated power support, and retune-safe tone metadata.
  • Data acquisition - discrete samples, continuous streaming, triggered streaming, and single tone snapshots (1024 sample bursts at the pre-accumulator rate). All data includes PTP telescope timestamps from the firmware for precise time synchronisation.
  • G3 stream output - record continuous streams to so3g/spt3g .g3 files (Observation, Wiring, Scan frames with G3SuperTimestream payloads) for downstream OCS / SO data pipelines.
  • Mock server mode - ReadoutClient(mock=True) emulates the readout server in-process (synthetic resonator catalogue, sweeps, snapshots, streams) for OCS / controller integration testing without RFSoC hardware.
  • Frequency sweeping - wideband survey sweeps across the full RF band and targeted sweeps around individual resonances
  • Resonance finding - automated peak detection across multiple data formats (magnitude, phase, group delay, |dS21/df|, etc), plus an interactive PyQt5 GUI
  • Resonance fitting - linear and Duffing-capable complex S21 fitting (fit_resonance, batch_fit, fit_sweep_stack) with extracted physical parameters (fr, Qi, Qc, phi, etc.), optional uncertainty weighting, and process-parallel fitting support. batch_fit consumes server sweep dictionaries and preserves tone metadata; fit_sweep_stack consumes already-windowed arrays and fits rows independently.
  • Retuning - sweep-and-retune workflows to track drifting resonances using max-derivative or min-magnitude methods
  • Fast frequency modulation - dither each tone over a few probe points (2-3) every accumulation and stream the samples tagged per point, for real-time IQ → frequency/dissipation conversion (live per-resonator dφ/df rather than a stale start-of-obs calibration) and inflection-point resonator tracking. Toggle on/off at any time and update centres/offsets live with no dropped frames; the souk_readout_tools.modulation toolkit demodulates in the de-embedded/phase-centred basis (params_from_sweepgroup_cyclesdemodulate). See Fast Frequency Modulation.
  • Power management - automatic TX/RX level optimisation with saturation detection, dynamic range management, and calibrated power control in dBm at any reference plane in the signal chain
  • ADC calibration freeze - freeze the RFSoC's internal ADC calibration during observations to eliminate drift noise, with periodic defrost for recalibration
  • Clock source control - select internal (12.8 MHz) or external (10 MHz) PL reference clock with PLL lock status monitoring
  • PTP/NTP timing status - packaged ptp4l, chrony, and timing-monitor service templates, plus get_info("timing") for checking GM lock, PHC/NTP source health, and firmware sync readiness
  • Timed sync & multi-board alignment (v7.10) - TT-targeted firmware syncs so independent boards align timestamps and accumulations to the same epoch, with on-board 1-PPS generation from the TSU strobe path. See TSU Strobe and Timed Sync.
  • Dual-pipeline support - two independent pipelines per board with three-level initialisation (program FPGA → shared resources → per-pipeline resources) to prevent cross-pipeline disruption
  • VACC multitone (v7.9+) - multiple tones per FFT bin with automatic LO index management and sparse tone index handling
  • Parameter-series measurements - repeat any measurement across an external parameter (attenuation, temperature, bias, time, ...) with run directories, resume, retries, and live summaries; power sweeps are the worked example. See Parameter-Series Measurements.
  • Configuration sync - YAML-based config with push_config()/pull_config() for client-server synchronisation, including automatic calibration file transfer
  • Server infrastructure - async TCP server with systemd daemon support, multi-client streaming, and remote status monitoring
  • Analysis utilities - built-in tools for parsing raw data, plotting in various formats, fitting resonance and noise models, and extracting detector parameters.

Quick Start (Client)

Most users only need the client. The server should already be running on the RFSoC.

Clone the repository and initialise submodules:

git clone https://github.com/sr-cdf/souk_readout_tools
cd souk_readout_tools
git submodule init && git submodule update

Create a python virtual environment and install:

python3 -m venv client_venv
source ./client_venv/bin/activate
pip install .

On Windows, use python -m venv and .\client_venv\Scripts\Activate.ps1 instead.

No RFSoC hardware? Pass mock=True to run against a built-in in-process mock server — no config or address needed — to explore the API or develop analysis code without a board:

from souk_readout_tools.client.readout_client import ReadoutClient

client = ReadoutClient(mock=True)
client.ensure_ready()
freqs = [0.800e9, 1.500e9]
client.set_tone_frequencies(freqs)
client.set_tone_phases(client.generate_newman_phases(freqs))  # Newman phases minimise the multi-tone crest factor
data = client.parse_samples(client.get_samples(500), num_tones=2)

Otherwise, connect to a real running server and pull its config:

from souk_readout_tools.client.readout_client import ReadoutClient

client = ReadoutClient(address='10.11.11.11', request_port=10000)
client.pull_config(save_as='my_config.yaml')

Or create a config from the bundled template:

from souk_readout_tools.config_utils import copy_template_config
copy_template_config('my_config.yaml', pipeline_id=0)

Then connect, initialise, set tones, and acquire data:

client = ReadoutClient(config_file='my_config.yaml')
client.ensure_ready()

freqs = [0.800e9, 1.500e9]
client.set_tone_frequencies(freqs)                            # frequencies in Hz
client.set_tone_powers([-90, -95], reference_plane='detector') # powers in dBm
client.set_tone_phases(client.generate_newman_phases(freqs))  # Newman phases minimise the multi-tone crest factor

raw = client.get_samples(500)
data = client.parse_samples(raw, num_tones=2)

# Plot the timestream
from souk_readout_tools.plotting import plot_timestream
plot_timestream(data)

For full installation details (including server setup, SD card imaging, and daemon configuration), see the Installation Guide. For RFSoC timing setup, see Timing and PTP.

CLI Tools

Client (installed on your machine):

Command Description
souk-connection-test Test connectivity to the readout server (-C config.yaml or -a address)
souk-wideband_sweep Perform a wideband frequency sweep
souk-mkid-finder-app Launch the interactive MKID resonance finder GUI
souk-batch-snapshots Acquire pre-accumulator snapshots across tones
souk-find-resonances Find resonances from sweep data

Server (installed on the RFSoC):

Command Description
souk-readout-server Start the readout server (optional config path, -p for pipeline)
souk-enable-daemon Enable the server as a systemd service (-p 0 1 for both pipelines)
souk-enable-daemons Enable both pipeline systemd services
souk-disable-daemon Disable the server systemd service(s)
souk-disable-daemons Disable both pipeline systemd services
souk-restart-daemon Restart the server systemd service(s) without reinstalling them
souk-restart-daemons Restart both pipeline systemd services without reinstalling them
souk-enable-timing Install and restart the packaged ptp4l, chrony PHC, and timing-monitor setup
souk-timing-monitor Run the PTP/NTP timing monitor daemon
souk-test-timing-monitor Query or stream status from /run/timing-monitor.sock
souk-find-attenuators Discover RUDAT and SOUK mixerless-module attenuators (--status for live values)
souk-find-bypass-amps Discover SOUK mixerless-module bypass amplifiers (--status for bypass state)
souk-find-lnas Discover populated LNA bias monitors (--status for voltage/current readings)
souk-rf-peripherals-status Combined attenuator, bypass-amplifier, and LNA status report

Documentation

Document Description
Installation Guide Full client and server installation, SD card setup, daemon configuration
Getting Started Configuration, usage guide, and worked examples for all features
Fast Frequency Modulation Real-time IQ → frequency/dissipation conversion and resonator tracking via per-tone probe-point modulation
Calibration Power calibration model and RF signal-chain configuration
Tone Power Notes Dynamic-range, VACC, crest-factor, and blind-tone power guidance
Resonator Noise Workflow Drive-power tuning, blackbody-load directory layout, and on/off-resonance noise captures
Parameter-Series Measurements Repeating any measurement across an external parameter (attenuation, temperature, time, ...) with run directories, resume, and live summaries
RF Peripherals RF attenuator, bypass amplifier, and discovery tooling
LNA Bias Cryostat LNA bias control, soft-off, and status monitoring
Dual Pipeline Dual-pipeline setup, initialisation model, and multi-server operation
Clock Source PL reference clock selection (internal/external) and PLL status
Timing and PTP ptp4l, chrony, timing-monitor setup, standalone monitoring, and firmware-sync readiness
Timing Site Checklist Site commissioning checks for PTP GM, chrony, monitor state, and holdover behaviour
TSU Strobe and Timed Sync 1-PPS TSU strobe, firmware timed-sync bring-up for multi-board timestamp alignment, and test scripts
v7.9 Multitone Notes VACC multitone design notes and constraints
Changelog Version history, feature list, and roadmap

Configuration

YAML-based configuration with five sections: rfsoc_host, firmware, rf_frontend, cryostat, and detector. A template config with all parameters and defaults is bundled with the package. Config files live wherever you choose on the client side - keep them with your measurement data.

The standard workflow is: create or pull a config, edit hardware-/firmware-specific settings, connect with it, and use push_config() / pull_config() to synchronise with the server. Calibration files referenced in the config are transferred automatically.

See Getting Started - Configuration for details.

Requirements

  • Client: Python >= 3.10. Tested on Linux (Python 3.10, 3.12) and Windows (Python 3.12). Dependencies: numpy, scipy, matplotlib, pyyaml, ipython, pyqt5.
  • Server: Python >= 3.10 on the Xilinx/RFSoC CASPER Linux image. Requires souk_mkid_readout from the souk-firmware repository.

About

Tools for working with the SOUK MKID Readout System

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages