5a21f38dabe6265785bfa29aedec6784c60fd733
team1k
Python control library and server for the TEAM1k X-ray detector.
Communicates directly with the detector FPGA via UDP, replacing the previous k_test C++ program. Uses EPICS PV Access (PVA) for command/status and ZMQ for bulk data transfer.
Architecture
Client machine Detector machine
+--------------+ +-------------------------------+
| | PVA (commands/status) | team1k-server |
| Client |<---------------------->| Register I/O (UDP:42000) |
| | | PVA server |
| | ZMQ (frame data) | PVA streamer thread |
| |<---------------------->| Frame capture thread |
| | | ZMQ data transfer thread |
+--------------+ | |
| Acquisition subprocess |
| UDP data recv (UDP:41000) |
| Frame assembly |
| -> locking_shmring |
+-------------------------------+
Installation
pip install .
For HDF5 support (optional):
pip install ".[hdf5]"
Dependencies
locking_shmring— shared memory ring buffer (must be installed separately)p4p— EPICS PV Access for Pythonpyzmq— ZeroMQ for bulk data transfernumpy,pyserial
Running the server
team1k-server --detector-ip 10.0.0.32 --log-level INFO
All options:
--detector-ip Detector IP address (default: 10.0.0.32)
--register-port Detector register port (default: 42000)
--data-port Detector data port (default: 41000)
--pv-prefix PVA prefix (default: TEAM1K:)
--zmq-port ZMQ data transfer port (default: 42005)
--config Parameter file to apply on startup
--bellow-port Bellow stage serial port (default: /dev/CameraBellowStage)
--log-level DEBUG, INFO, WARNING, ERROR (default: INFO)
Client usage
Acquire frames
from team1k import Client, ExposureModes
client = Client(data_host="detector-machine")
# Configure
client.set_exposure_mode(ExposureModes.GLOBAL_SHUTTER_CDS)
client.set_integration_time(6.0) # ms
# One-shot: start DAQ, capture 100 frames, stop DAQ
frames = client.acquire_frames(100)
print(frames.shape) # (100, 1024, 1024)
print(frames.dtype) # uint16
client.close()
Manual DAQ control
client = Client(data_host="detector-machine")
client.start_daq()
# Grab frames from the running stream
batch1 = client.get_frames(50)
batch2 = client.get_frames(50)
client.stop_daq()
client.close()
Live image monitoring
client = Client()
def on_frame(image):
print(f"Frame received: {image.shape}")
client.monitor_image(on_frame)
# ... later
client.stop_monitor("IMAGE")
client.close()
Status
client = Client()
print(client.get_status())
print(client.is_acquiring())
print(client.get_frame_rate())
print(client.get_exposure_mode())
print(client.get_integration_time())
client.close()
Other commands
client.set_trigger_mode(TriggerModes.EXTERNAL)
client.set_adc_clock_freq(60.0) # MHz
client.set_adc_data_delay(0x1A7)
client.load_parameter_file("/path/to/params.txt")
client.set_test_mode(True) # FPGA test pattern
client.reset_connection()
# Peripherals
client.insert_detector()
client.retract_detector()
client.power_on()
client.power_off()
PV Access interface
All PVs are prefixed with TEAM1K: by default.
Status PVs (read-only)
| PV | Type | Description |
|---|---|---|
STATUS |
string[] | Server status |
ACQUIRING |
bool | DAQ running |
FRAME_RATE |
float | Current frame rate (Hz) |
FRAME_COUNT |
int | Total frames acquired |
EXPOSURE_MODE |
int | Current exposure mode (0-3) |
TRIGGER_MODE |
int | Current trigger mode |
INTEGRATION_TIME |
float | Integration time (ms) |
CAPTURE:STATUS |
string | IDLE / CAPTURING / READY / ERROR |
CAPTURE:PROGRESS |
int | Frames captured so far |
CAPTURE:TOTAL |
int | Frames requested |
IMAGE |
NTNDArray | Live image stream |
Command PVs (writable)
| PV | Type | Description |
|---|---|---|
CMD:EXPOSURE_MODE |
int | Set exposure mode |
CMD:TRIGGER_MODE |
int | Set trigger mode |
CMD:INTEGRATION_TIME |
float | Set integration time (ms) |
CMD:START_DAQ |
int | 1=start, 0=stop |
CMD:CAPTURE |
int | Capture N frames |
CMD:ADC_CLOCK_FREQ |
float | Set ADC clock (MHz) |
CMD:ADC_DATA_DELAY |
int | Set ADC data delay |
CMD:PARAMETER_FILE |
string | Apply parameter file |
CMD:RESET |
int | 1=reset connection |
CMD:TEST_MODE |
int | 1=enable FPGA test data |
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
parameter_file.py # Parameter file parser
acquisition/ # High-throughput data path
receiver.py # Acquisition subprocess (UDP -> shmring)
filewriter/ # On-demand frame capture
capture.py # FrameCapture + ZMQ DataTransferServer
pva/ # EPICS PV Access
interface.py # PVA server, command/status PVs
streamer.py # shmring -> NTNDArray live stream
peripherals/ # Hardware peripherals
bellow_stage.py # Camera bellow stage (serial)
power_supply.py # Power supply control
server.py # Main server entry point
Client.py # PVA + ZMQ client library
Description
Languages
Python
100%