2026-03-06 01:28:58 -06:00
2026-03-05 13:19:12 -06:00
2026-03-05 13:19:12 -06:00
2026-03-06 01:28:58 -06:00
2026-03-05 13:19:12 -06:00

team1k

Python control library and server for the TEAM1k X-ray detector.

Communicates directly with the detector FPGA via UDP. Uses EPICS PV Access (PVA) for the image stream and basic controls (areaDetector-style), and a TCP protocol for the Python client.

Architecture

Client machine                          Detector machine
+--------------+                        +-------------------------------+
|              |   TCP (control+data)   |  team1k-server                |
|  Client      |<--------------------->|    Register I/O (UDP:42000)   |
|  (Python)    |                        |    TCP client server          |
|              |                        |    Buffered frame capture     |
+--------------+                        |    PVA server (areaDetector)  |
                                        |    PVA streamer (IMAGE)       |
EPICS clients                           |    Power supply monitoring    |
+--------------+                        |    Auto-reconnect             |
|  pvget/CSS/  |   PVA (IMAGE stream)  |                               |
|  other tools |<--------------------->|  Acquisition subprocess       |
+--------------+                        |    UDP data recv (UDP:41000)  |
                                        |    Frame assembly             |
                                        |    -> locking_shmring         |
                                        +-------------------------------+

Installation

pip install .

For notebook progress bars (optional):

pip install ".[client]"

Dependencies

  • locking_shmring — shared memory ring buffer (must be installed separately)
  • p4p — EPICS PV Access for Python
  • pyyaml — YAML config parsing
  • pyvisa, pyvisa-py — power supply control
  • numpy, pyserial

Configuration

Create a YAML config file:

detector:
  ip: "10.0.0.32"
  register_port: 42000
  data_port: 41000
  auto_reconnect: true
  reconnect_interval: 5.0

adc:
  clock_frequency_mhz: 50
  data_delay: 0x180
  order_7to0: 0x89abcdef
  order_15to8: 0x01234567

digital_signals:
  order_7to0: 0x24FFFFFF
  order_15to8: 0xF5F310FF
  polarity: 0x0014

defaults:
  exposure_mode: 3
  trigger_mode: external
  trigger_polarity: rising
  integration_time_ms: 4.0

server:
  pv_prefix: "TEAM1K:"
  client_port: 42010

peripherals:
  bellow_port: "/dev/CameraBellowStage"

  detector_power:
    port: "/dev/DetectorPowerSupply"
    voltage_step: 0.2
    channels:
      1: { voltage: 5.0, current: 2.0, ovp: 6.0 }
      2: { voltage: 3.3, current: 1.0, ovp: 4.0 }

  tec:
    port: "/dev/TECsPowerSupply"
    voltage_step: 0.2
    channels:
      1: { voltage: 12.0, current: 3.0, ovp: 14.0 }

Running the server

team1k-server --config config.yaml --log-level INFO

Options:

--config          YAML config file path
--detector-ip     Override detector IP address
--pv-prefix       Override PVA prefix
--client-port     Override TCP client port
--log-level       DEBUG, INFO, WARNING, ERROR (default: INFO)

The server starts DAQ automatically after initialization (continuous mode). The PVA IMAGE stream is always live.

Client usage

The Python client connects via TCP. No EPICS/p4p installation needed.

Basic usage

from team1k import Client

client = Client("detector-machine")

# Configure
client.exposure_mode = 3       # GlobalCDS
client.trigger_mode = 1        # External
client.integration_time = 4.0  # ms

# Status
print(client.state)            # "Acquiring"
print(client.frame_rate)       # 500.0

# Capture frames (shows progress bar)
frames = client.capture(100)
print(frames.shape)  # (100, 1024, 1024)
print(frames.dtype)  # uint16

client.close()

Capture modes

# Fixed number of frames
frames = client.capture(num_frames=100)

# Capture for a duration
frames = client.capture(duration=5.0)

# Open-ended capture (start/stop)
stream = client.start_capture()
# ... do something ...
frames = stream.stop()

# Disable progress bar
frames = client.capture(100, progress=False)

Peripherals

# Bellow stage
client.insert_detector()
client.retract_detector()

# Detector power
client.power_on()
client.power_off()
print(client.power_status)  # {1: {"voltage": 5.01, "current": 1.2}, ...}

# TEC
client.tec_on()
client.tec_off()
print(client.tec_status)

Advanced

# Direct register access
value = client.read_register(22)
client.write_register(22, 3)

# Reconnect after power cycle
client.power_on()
client.reconnect()

# Full status
print(client.status())

# Context manager
with Client("detector-machine") as c:
    frames = c.capture(100)

PV Access interface

All PVs are prefixed with TEAM1K: by default. Follows areaDetector conventions with RW + _RBV readback pattern.

Acquisition PVs

PV Type RW Description
Acquire / _RBV bool RW Start/stop DAQ
AcquireTime / _RBV float RW Integration time (seconds)
ExposureMode / _RBV enum RW Rolling/Rolling with Pause/Global/Global with CDS
TriggerMode / _RBV enum RW Internal/External
ArrayCounter_RBV int RO Total frames acquired
FrameRate_RBV float RO Current frame rate (Hz)
DetectorState_RBV enum RO Disconnected/Initializing/Idle/Acquiring/Error
MaxSizeX_RBV / MaxSizeY_RBV int RO 1024, 1024
IMAGE NTNDArray RO Live image stream

Peripheral PVs

PV Type RW Description
Bellow:Insert bool RW Write true to insert
Bellow:Retract bool RW Write true to retract
Bellow:Position_RBV int RO Current position
Power:Enable / _RBV bool RW Detector power on/off
Power:ChN:Voltage_RBV float RO Channel N voltage
Power:ChN:Current_RBV float RO Channel N current
TEC:Enable / _RBV bool RW TEC power on/off
TEC:ChN:Voltage_RBV float RO Channel N voltage
TEC:ChN:Current_RBV float RO Channel N current

Package structure

src/team1k/
    detector/           # Direct UDP communication with detector FPGA
        udp_transport.py    # Low-level UDP socket
        registers.py        # Register read/write protocol
        data_port.py        # Data port + loopback registration
        chip_config.py      # Chip constants (1024x1024, packet layout)
        commands.py         # Detector commands (exposure, trigger, etc.)
        adc.py              # Si570 I2C clock programming
    acquisition/        # High-throughput data path
        receiver.py         # Acquisition subprocess (UDP -> shmring)
    pva/                # EPICS PV Access (areaDetector-style)
        interface.py        # PVA server, RW PVs with _RBV readbacks
        streamer.py         # shmring -> NTNDArray live stream
    peripherals/        # Hardware peripherals
        power_base.py       # VISA power supply base class
        power_supply.py     # Detector power supply
        tec.py              # TEC controller
        bellow_stage.py     # Camera bellow stage (serial)
    config.py           # YAML configuration loader
    state.py            # DetectorState enum
    server.py           # Main server entry point
    tcp_server.py       # TCP client handler
    tcp_protocol.py     # Shared TCP message framing
    capture.py          # Buffered frame capture (shmring -> TCP)
    client.py           # Pure-TCP client library
Description
No description provided
Readme 156 KiB
Languages
Python 100%