Files
team1k/README.md
2026-03-05 13:19:12 -06:00

260 lines
7.4 KiB
Markdown

# 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
```bash
pip install .
```
For notebook progress bars (optional):
```bash
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:
```yaml
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
```bash
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
```python
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
```python
# 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
```python
# 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
```python
# 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
```