# 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 ```