这是本节的多页打印视图。
点击此处打印.
返回本页常规视图.
欢迎使用Quatm
欢迎来到 Quatm 用户指南!无论你是刚开始搭建实验控制系统,还是希望从 LabView、Matlab 迁移到开源方案,这里都能帮你快速上手。
什么是 Quatm?
Quatm 是一个专为量子物理实验设计的开源控制框架。它把设备驱动、时序管理、数据采集和分析这些常见需求整合在一起,让你只需关注实验本身,而不是底层的软件细节。了解更多 →
Quatm 不提供:
- 硬件:Quatm 是纯软件框架,实验所需的仪器设备需要你自行采购和维护。
- 实验方案:Quatm 提供控制的工具,具体的实验逻辑和物理方案由你定义。
Quatm 提供:
- 完整的控制架构:设备驱动、时序控制、参数管理和数据分析,开箱即用。
- 灵活的部署方式:单机运行、控制端—客户端分离,随需选择。
- 活跃的社区支持:持续迭代、问题追踪和用户交流。
Quatm 适合我吗?
如果你的实验涉及超冷原子、离子阱、量子光学、量子化学等领域,需要精确控制多个仪器设备和全自动化实验测量,Quatm 会是理想的选择。
特别适合以下场景:
- 🧪 长期使用 LabView 或 Matlab,想迁移到开源、可定制的方案
- 🔌 多种厂商硬件混杂,需要一个统一的控制层
- 🚀 希望将实验流程自动化,解放科研精力
💡 提示:如果你已经在使用全套 Artiq 生态,其原生支持已非常完善,Quatm 可能不是最佳选择。
系统架构
Quatm 采用分布式微服务架构,每个组件(硬件驱动、分析例程、GUI 面板)作为独立操作系统进程运行,通过 ZeroMQ 消息进行通信:
┌─────────────────────────────────────────────────────┐
│ GUI 层 │
│ 实验浏览器 │ 参数编辑器 │ 图像监视器 │ 数据分析管理 │
└──────────────┬──────────────────────────────────────┘
│ ZMQ PUB/SUB + RPC
┌──────────────┼──────────────────────────────────────┐
│ 通信层 (quatm.servers) │
│ DataClient │ ImageClient │ CommandClient │ Properties │
└──────────────┬──────────────────────────────────────┘
│
┌──────────────┼──────────────────────────────────────┐
│ 实验层 │ 分析层 │
│ Experiment 基类 │ 吸收成像 │ 高斯拟合 │
│ realtime() 时序控制 │ 亮斑检测 │ 图像切片 │
│ 参数扫描与队列管理 │ 数据平均 │ 拟合加速 │
└──────────────┬──────────────────────────────────────┘
│
┌──────────────┴──────────────────────────────────────┐
│ 驱动层 │
│ FPGA │ Andor │ BlackFly │ Rigol │ Valon │ Thorlabs │
│ DDS │ Toptica │ PI Stage │ 监控设备 (温度/磁场/真空) │
└─────────────────────────────────────────────────────┘
各层职责
| 层级 | 模块 | 职责 |
|---|
| GUI 层 | quatm.GUI | Qt 图形界面,实验管理、设备控制、数据可视化 |
| 通信层 | quatm.servers | ZMQ 发布/订阅消息、RPC 远程调用、分布式属性同步 |
| 实验层 | quatm.experiment | 声明式实验时序、参数扫描、设备属性管理 |
| 分析层 | quatm.analysis | 实时图像处理、曲线拟合、离子检测(Cython 加速) |
| 物理层 | quatm.physics | 光偶极阱建模、Stark 位移、散射率、Feshbach 共振 |
| 驱动层 | quatm.drivers | 统一硬件抽象,支持 300+ 种实验室仪器 |
| 监控层 | quatm.monitor | 温度、磁场、真空等环境参数持续监测 |
这种架构确保:故障隔离(一个组件崩溃不影响全局)、并行处理(图像分析与实验时序同时运行)、网络透明(组件可分布在不同机器)。
文档导航
系统学习 Quatm 的最佳路径:
| 章节 | 你将学到 |
|---|
| 快速开始 | 安装 Python 环境,配置 device_db.py 接入设备,编写并运行第一个实验 |
| 实验编辑指南 | Experiment 基类的完整生命周期,NumberValue/BoolValue/StringCombo 参数类型,delay() 和 realtime 时序控制 |
| 设备与驱动 | TTLOut/DAC/genericAttr 三种属性模式,校准文件使用,自定义驱动开发 |
| 数据与分析 | DataClient/ImageClient 通信,HDF5 存储结构,图像分析、离子检测等内置模块 |
| 通信层 | ZMQ 发布/订阅通信、DataClient/ImageClient/CommandClient、分布式属性系统 |
| GUI 组件 | 实验浏览器、参数编辑器、序列编辑器、图像监视器的使用与定制 |
| 物理模型库 | 原子数据库、光偶极阱建模、Stark 位移与散射率计算 |
| 监控设备 | 温度控制器、高斯计、波长计、真空规等环境监测设备 |
| 部署指南 | 单机、客户端—控制端分离、多控制端集群的部署架构 |
| 最佳实践 | 单一职责、Mixin 复用、设备状态检查、异常安全关闭 |
| 应用案例 | MOT 装载优化、吸收成像、Rabi 振荡等完整案例 |
| 代码贡献 | 提交 Issue、发起 Pull Request、代码审查流程 |
🚀 建议路径:快速开始 → 实验编辑指南 → 设备与驱动 → 应用案例。其余章节可按需查阅。
1 - 快速开始
从零开始搭建 Quatm 实验控制环境,只需几分钟即可运行第一个实验。
欢迎!下面几步就能让 Quatm 在你的机器上跑起来。
完成本指南后,你将能够:
- ✅ 在本地安装并验证 Quatm 环境
- ✅ 理解 device_db.py 的设备配置方式
- ✅ 编写一个带有参数面板的完整实验脚本
- ✅ 在模拟模式下运行和调试实验
环境要求
- Python:3.9 及以上版本
- 操作系统:Windows 7 以上、Linux(内核版本 5.10.261 及以上)、macOS 10.12 及以上
- 硬件:模拟模式无需硬件;实际实验需要支持 TTL/DAC 的控制器,实时控制需要 FPGA 模块(如 ADwin、Red Pitaya、NI-FPGA 等)
安装
git clone https://github.com/quatm/quatm.git
cd quatm
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
验证
from quatm.experiment import Experiment
class HelloQuatm(Experiment):
def build(self):
print("Quatm 就绪!")
def run(self):
print("Hello, Quatm!")
HelloQuatm().run()
下一步
1.1 - 编写第一个实验
从零开始编写你的第一个 Quatm 实验脚本,学习实验类的基本结构和运行方式。
实验的基本结构
每个 Quatm 实验都是一个继承自 Experiment 的 Python 类。只需定义 build() 和 run() 两个核心方法:
from quatm.experiment import Experiment, NumberValue
from quatm.experiment.experiment import delay
class MyFirstExperiment(Experiment):
def build(self):
# 声明设备
self.setattr_device("fpga")
# 声明参数
self.setattr_argument(
"target_voltage",
NumberValue("target_voltage", ndecimals=2, step=0.01, value=4.00)
)
def run(self):
# 设置 DAC 通道输出并等待后切换
self.my_dac = 1.0
delay(0.5)
self.my_dac = self.target_voltage
build() — 声明阶段
build() 在实验加载时执行一次,用于声明实验中使用的设备和参数。
设备声明模式
# DAQ/控制器设备(type: local)
self.setattr_device("fpga")
# 属性设备(type: attr),直接作为实验属性使用
self.setattr_device("cooling_ttl")
# 通用属性设备(type: generic_attr)
self.setattr_device("Li_frequency")
参数类型
| 类型 | 类 | 使用场景 |
|---|
| 数值 | NumberValue | 电压、频率、时间等连续量 |
| 布尔 | BoolValue | 开关、使能等二值选项 |
| 选项 | StringCombo | 模式选择、扫描类型等固定选项 |
self.setattr_argument("b_field", NumberValue("b_field", ndecimals=1, step=0.5, value=5.0))
self.setattr_argument("cooling", BoolValue("cooling", True))
self.setattr_argument("scan", StringCombo("scan", ["完整扫描", "快速扫描"]))
run() — 执行阶段
run() 是实验的主体逻辑,每次运行按钮点击时执行。
设备控制
def run(self):
# 模拟量输出
self.trap_dac = 3.5 # 设置 DAC 输出
# TTL 数字输出
self.aom_ttl = True # 打开 AOM
delay(0.1)
self.aom_ttl = False # 关闭 AOM
数据采集
def run(self):
self.camera.expose(0.1)
img = self.camera.last_image
# 发送到数据管理器
self._dataq.send({"atom_count": analyze(img)})
运行实验
将 .py 文件放入 experiments/ 目录,启动 Quatm 浏览器:
python -m quatm.GUI.browser
1.2 - 常见问题
Quatm 安装和使用中的常见问题及解决方案。
Windows 系统
pyzmq 安装失败
安装 Microsoft C++ Build Tools 后重试。
FPGA 控制器驱动
需安装厂商提供的 SDK,FPGA 需要按照实际需求定义和烧录timetable。模拟模式下无需实际硬件。
Linux 系统
Qt 图形库依赖
sudo apt install libxcb-cursor0 libxcb-xinerama0 libegl1-mesa
相机权限
Andor / BlackFly 需配置 udev 规则。
Windows Subsystem for Linux (WSL)
WSL 用户请确保在 Linux 文件系统挂载上运行,避免在 Windows 文件系统上操作导致意外错误。
1.3 - 配置仪器设备
通过 device_db.py 将实验仪器接入 Quatm 框架。
Quatm 通过 configuration/device_db.py 管理所有实验仪器。该文件定义一个名为 device_db 的字典,每个键对应一个可在实验中使用的设备名称。
设备类型
device_db 支持三种设备类型:
| type | 说明 | 使用场景 |
|---|
local | 驱动类实例 | FPGA 控制器、相机等需要完整驱动对象的设备 |
attr | 属性映射 | 将驱动的某个通道映射为实验属性(如 DAC、TTL) |
generic_attr | 通用属性 | 调用驱动的任意函数,实现灵活的功能映射 |
配置示例
device_db = {
# 驱动设备:加载完整的驱动实例
"fpga": {
"type": "local",
"module": "quatm.drivers.fpga.client",
"class": "fpgaClient",
"arguments": {},
},
# 属性设备:TTL 通道映射
"cooling_aom": {
"type": "attr",
"module": "quatm.experiment.attributes",
"class": "TTLOut",
"arguments": {"channel": 5, "logic": "a"},
},
# 属性设备:DAC 通道映射
"trap_coil_x": {
"type": "attr",
"module": "quatm.experiment.attributes",
"class": "DAC",
"arguments": {"channel": 2},
},
}
属性设备参数
TTLOut — 数字输出
| 参数 | 说明 |
|---|
channel | FPGA 控制器 TTL 通道编号 |
logic | "l" 为正逻辑,"a" 为反逻辑 |
DAC — 模拟输出
| 参数 | 说明 |
|---|
channel | FPGA 控制器 DAC 通道编号 |
gaugefile | 校准文件路径(可选) |
通用属性配置
对于需要灵活映射的驱动功能,使用 genericAttr:
"Li_frequency": {
"type": "generic_attr",
"module": "quatm.experiment.attributes",
"class": "genericAttr",
"driver": "lithium_dds_0",
"function": "set_frequency",
"arguments": {
"function_kwargs": {"channel": [0]},
"minval": 40, "maxval": 90,
"multiplier": 1E6, "display_unit": "MHz",
},
}
校准文件
对于非线性响应的设备,可使用两列空格分隔的文本文件进行校准:
2.2 4.0
2.0 3.8
1.8 3.6
1.6 3.34
在 DAC 配置中通过 gauge 参数引用:
"rf_power": {
"type": "attr",
"module": "quatm.experiment.attributes",
"class": "DAC",
"arguments": {"channel": 3, "gauge": "configuration/gauge-rf-power.txt"},
}
自定义驱动接入
编写自定义驱动类后,在 device_db 中以 type: "local" 注册:
"my_laser": {
"type": "local",
"module": "my_lab.my_laser_driver",
"class": "MyLaserDriver",
"arguments": {"port": "/dev/ttyUSB0"},
}
然后在实验中通过 self.setattr_device("my_laser") 使用。
2 - 实验编辑指南
深入了解 Quatm 实验框架的核心 API,掌握从基础实验到高级控制的完整编写方法。
Experiment 基类
所有 Quatm 实验都继承自 Experiment 基类。该基类提供了完整的实验生命周期管理和设备控制接口。
核心方法
| 方法 | 调用时机 | 用途 |
|---|
build() | 实验加载时执行一次 | 声明设备、定义参数 |
run() | 每次点击运行按钮 | 实验主逻辑 |
start_measurement() | 每次测量开始前 | 初始化操作(仅一次) |
start_sequence() | 每次扫描序列开始前 | 序列级初始化 |
end_sequence() | 每次扫描序列结束后 | 序列级清理 |
end_measurement() | 测量结束后 | 最后的清理操作 |
声明设备
使用 setattr_device() 将 device_db 中配置的设备引入实验:
def build(self):
self.setattr_device("fpga") # FPGA 控制器
self.setattr_device("camera") # 科学相机
self.setattr_device("valon_5009") # 频率合成器
设备名称必须与 configuration/device_db.py 中的键完全一致。
声明参数
使用 setattr_argument() 创建可在 GUI 中调整的实验参数:
from quatm.experiment import Experiment, NumberValue
from quatm.experiment.experiment import BoolValue, StringCombo
def build(self):
# 数值参数
self.setattr_argument(
"exposure_time",
NumberValue("exposure_time", ndecimals=2, step=0.01, value=1.0)
)
# 布尔开关
self.setattr_argument("enable_cooling", BoolValue("enable_cooling", True))
# 字符串选项
self.setattr_argument("scan_type", StringCombo("scan_type", ["频率", "功率"]))
设备属性类型
设备接入后,根据 device_db 中的配置类型,呈现为不同的属性:
| 类型 | 对应类 | 用途 |
|---|
attr | DAC / TTLOut | 直接映射到硬件通道 |
generic_attr | genericAttr | 调用驱动上的任意函数 |
local | 驱动类实例 | 完整驱动对象 |
实验生命周期
每个实验按以下层次结构执行:
测量 (measurement)
└─ 序列 (sequence / repetition)
└─ 运行 (run)
- run:单次实验执行,每次调用
run() 方法 - sequence:一组使用不同参数值的 run 集合(参数扫描)
- measurement:一个或多个 sequence 的完整测量
时序控制
delay() 函数
delay(seconds) 在非实时模式下暂停指定秒数,在实时模式下仅递增内部计时器:
def run(self):
self.cooling_laser.on()
delay(0.1) # 等待 100 毫秒
self.camera.expose(1.0)
实验控制设备
使用 realtime 上下文管理器实现精确的硬件时序:
def run(self):
with realtime(repetitions=3):
self.ttl_channel = True
delay(0.001)
self.ttl_channel = False
数据管理
发送实验数据
通过 DataClient 将数据推送到数据管理器:
def run(self):
result = measure_atoms()
self._dataq.send({
"atom_count": result,
"temperature": T
})
数据以 HDF5 格式自动保存,支持 InfluxDB 远程推送。
前馈控制
Feed_forward 类允许根据历史数据动态调整实验参数:
from quatm.experiment.feedforward import Feed_forward
def build(self):
self.ff = Feed_forward(self)
self.ff.set_refresh_time(refresh_time=1)
def run(self):
# 根据历史斜率自动调整
self.ff.set_yslope(self.measured_slope)
模拟模式
在无实际硬件时,可通过 simulation_class_decorator 装饰器启用模拟:
from quatm.experiment.simulation_decorator import simulation_class_decorator
@simulation_class_decorator
class TestExperiment(Experiment):
def build(self):
self.setattr_device("fpga")
模拟模式下所有设备操作被拦截并记录,不会产生实际硬件输出。
3 - 设备与驱动
Quatm 原生支持 50+ 品牌、100+ 种实验仪器——涵盖科学相机、信号源、激光器、运动平台、DAQ 与环境监测。
Quatm 通过 configuration/device_db.py 统一管理所有仪器设备,支持三种接入模式。
设备接入模式
| type | 行为 | 适用场景 |
|---|
local | 实例化驱动类,作为完整对象使用 | FPGA 控制器、相机等需要方法调用的设备 |
attr | 将通道映射为 Python 属性 | DAC 输出、TTL 数字信号 |
generic_attr | 调用驱动的任意函数 | DDS 频率设置等灵活映射 |
驱动分类
Quatm 内置 50+ 品牌 的实验仪器驱动,分为以下 7 个类别:
| 类别 | 品牌数 | 典型设备 |
|---|
| 📷 科学相机 | 15 | Andor EMCCD/sCMOS、FLIR Blackfly、Basler、Hamamatsu ORCA、Thorlabs TSI |
| 📡 信号源与射频 | 8 | Valon 5009、DDS AD9959、Agilent 33500、Rigol DG1020Z |
| 🔬 激光器与光学 | 9 | Cobolt、Toptica iBeam、Sirah Matisse、M² Solstis、HighFinesse 波长计 |
| 🎯 运动与定位 | 8 | PI 纳米台、Attocube、Newport Picomotor、Thorlabs APT |
| 🔌 DAQ 与电源 | 9 | NI DAQ/SWITCH/Digital、Rigol DP1116A、EA PS2000B、Keithley 2110、示波器 |
| 🌡️ 环境监测 | 9 | Lakeshore 218、Cryocon、Pfeiffer TPG2xx、Leybold ITR、液氦液位计 |
| ⚡ 实验控制 | 3 | ADwin FPGA、NI-FPGA、Red Pitaya、Conrad 继电器板 |
属性设备详解
TTLOut — 数字输出
映射硬件控制器的 TTL 通道为实验属性,支持正/反逻辑:
"cooling_aom": {
"type": "attr",
"module": "quatm.experiment.attributes",
"class": "TTLOut",
"arguments": {"channel": 5, "logic": "a"},
}
实验中直接赋值:self.cooling_aom = True
DAC — 模拟输出
映射硬件控制器的 DAC 通道,支持校准曲线:
"trap_x": {
"type": "attr",
"module": "quatm.experiment.attributes",
"class": "DAC",
"arguments": {"channel": 2, "gauge": "gauge-trap-x.txt"},
}
校准文件
非线性设备使用两列文本文件校准。第一列为期望物理量,第二列为实际 DAC 值,系统自动线性插值。
自定义驱动
"my_laser": {
"type": "local",
"module": "my_lab.laser_driver",
"class": "LaserController",
"arguments": {"port": "/dev/ttyUSB0"},
}
通信协议
| 协议 | 典型设备 |
|---|
| VISA / SCPI | 信号发生器、万用表、示波器、电源 |
| 串口 (RS232/RS485) | 激光器、真空计、位移台、温控器 |
| Modbus RTU | Omron/Lumel 温控器 |
| TCP/IP (Telnet/JSON) | M² 激光器、Attocube 控制器 |
| 原生 SDK DLL | Andor、Basler、Hamamatsu 等相机 |
| NI-DAQmx | NI 数据采集卡 |
| USB HID | ANC350 纳米定位器 |
| SPI | AD9959 DDS |
3.1 - 科学相机
Andor、Basler、Hamamatsu、FLIR 等 15 品牌科学相机与图像采集驱动。
概述
Quatm 为全球 15 个主流科学相机品牌提供统一的 ICamera 接口封装,覆盖 EMCCD、sCMOS、高速 CMOS 和工业相机。
Andor 系列:iXon EMCCD / Zyla sCMOS / Shamrock 光谱仪
概述
Quatm 提供两套 Andor 相机驱动,通过原生 SDK 实现高性能成像控制:
| 驱动类 | SDK | 适用型号 | 接口 |
|---|
AndorSDK2Camera | atmcd32d.dll (SDK2) | iXon EMCCD, Luca, Clara | PCIe / USB |
AndorSDK3Camera | atcore.dll (SDK3) | Zyla, Neo, Marana (sCMOS) | USB3 / CameraLink |
ShamrockSpectrograph | ShamrockCIF.dll | SR-303i, SR-500i 等光谱仪 | USB |
所有类继承自 io.camera 接口,支持 ROI、binning、曝光控制和帧缓冲管理。
Andor SDK2 (EMCCD) AndorSDK2Camera
⚙️
iXon EMCCD
Andor SDK2 系列
| 通信 | DLL (atm32cd32) |
| 读出模式 | EM/传统 |
| ADC 频率 | 1/5/10 MHz |
| 像素深度 | 16-bit |
| 制冷 | TEC(≤ -100°C) |
适用于极低光信号场景(单原子/离子荧光),通过电子倍增(EM Gain)实现单光子级灵敏度。
驱动模块:AndorSDK2Camera
初始化
from quatm.drivers.andor.AndorSDK2 import AndorSDK2Camera
# 连接第一台相机
cam = AndorSDK2Camera(cam_id=0)
# 配置采集参数
cam.setup_acquisition(
exposure=0.1, # 曝光时间 (s)
em_gain=200, # EM 增益 (0-1000)
readout_rate="5MHz",# 读出速率
pre_amp_gain=2, # 前置放大增益
hsspeed=0, # 水平转移速率
temperature=-70, # 目标温度 (°C)
)
# 采集单帧
cam.start_acquisition(nframes=1)
image = cam.read_multiple_images(nframes=1)
关键参数
| 参数 | 说明 | 典型范围 |
|---|
exposure | 单帧曝光时长 | 0.001 – 3600 s |
em_gain | 电子倍增增益 | 0 – 1000(线性或真实增益模式) |
readout_rate | ADC 读出频率 | 1MHz / 5MHz / 10MHz |
temperature | 传感器目标温度 | -60 至 -100°C(取决于冷却器) |
pre_amp_gain | 前置放大器增益 | 1× – 4× |
Andor SDK3 (sCMOS) AndorSDK3Camera
⚙️
Zyla / Neo sCMOS
Andor SDK3 系列
| 通信 | DLL (atcore) |
| 传感器 | sCMOS |
| 接口 | USB3 / CameraLink |
| 像素深度 | 12/16-bit |
| 帧率 | 最高 100 fps(全分辨率) |
适用于快速序列成像和需要大视场的场景。基于 GenAPI 属性模型配置曝光、ROI 和触发。
驱动模块:AndorSDK3Camera
初始化
from quatm.drivers.andor.AndorSDK3 import AndorSDK3Camera
cam = AndorSDK3Camera(cam_id=0)
cam.setup_acquisition(
exposure=0.05,
pixel_format="Mono16",
trigger_mode="Internal",
)
Andor Shamrock 光谱仪 ShamrockSpectrograph
控制光栅选择、中心波长和狭缝宽度:
from quatm.drivers.andor.Shamrock import ShamrockSpectrograph
spec = ShamrockSpectrograph(idx=0)
spec.set_wavelength(780.24) # 中心波长 (nm)
spec.set_grating(2) # 选择光栅
spec.set_slit_width(50, port=1) # 入口狭缝 (µm)
设备配置
"emccd": {
"type": "local",
"module": "drivers.andor.AndorSDK2",
"class": "AndorSDK2Camera",
"arguments": {"cam_id": 0},
}
校准提示
EMCCD 增益需针对定量荧光测量进行校准。过高增益会引入时钟感应电荷(CIC)噪声和非线性。建议使用荧光珠或标准光源建立增益-信号关系曲线。
FLIR / Teledyne / Blackfly S / Grasshopper3
概述
Quatm 通过 TeledyneSpinnakerCamera 类封装 Spinnaker SDK,支持所有兼容 GenICam/GenAPI 的 FLIR/Teledyne USB3/GigE 相机。
⚙️
Blackfly S / Grasshopper3
FLIR Spinnaker 系列
| 通信 | Spinnaker SDK |
| 接口 | USB3 / GigE |
| 像素格式 | Mono8/16, Bayer |
| 触发 | 硬件/软件 |
| 帧率 | 取决于型号 |
用于实验室通用成像:MOT 监测、对准光束成像、设备状态监控。
驱动模块:TeledyneSpinnakerCamera
初始化
from quatm.drivers.teledyne.spinnaker import TeledyneSpinnakerCamera
# 列出所有可用相机
cam_list = TeledyneSpinnakerCamera.list_cameras()
# 连接指定相机(序列号或索引)
cam = TeledyneSpinnakerCamera(cam_id="serial_xxx")
# 或使用索引
cam = TeledyneSpinnakerCamera(cam_id=0)
# 配置并开始采集
cam.setup_acquisition(
exposure=0.02, # 20 ms 曝光
pixel_format="Mono8",
width=1920, height=1200,
offset_x=0, offset_y=0,
)
关键方法
| 方法 | 说明 |
|---|
list_cameras() | 枚举系统中所有 Spinnaker 相机 |
setup_acquisition(**kwargs) | 配置 ROI、曝光、像素格式等 |
start_acquisition(nframes) | 开始采集指定帧数 |
read_multiple_images(nframes) | 读取已采集图像 |
get_device_info() | 获取相机序列号、型号、固件版本 |
常用属性操作
通过 GenAPI 节点名称直接读写相机参数:
# 设置增益
cam.set_attribute("Gain", 10.0)
# 启用自动曝光
cam.set_attribute("ExposureAuto", "Continuous")
# 获取传感器温度
temp = cam.get_attribute("DeviceTemperature")
设备配置
"monitor_cam": {
"type": "local",
"module": "drivers.teledyne.spinnaker",
"class": "TeledyneSpinnakerCamera",
"arguments": {"cam_id": 0},
}
多相机同步
Spinnaker SDK 支持多相机硬件触发同步。设置 TriggerMode = On 和 TriggerSource = Line0 即可通过外部 TTL 信号实现纳秒级同步曝光。stop(): Stop capturing images.
quatm.drivers.blackfly.bfly.Camserver(name, serial)
class quatm.drivers.blackfly.bfly.Camserver(object):
def __init__(self, name, serial):
pass
def generateImageIndex(self):
pass
def run(self):
pass
def sendimage(self, im):
pass
def updateBusInfo(self):
pass
generateImageIndex(): In the current measurement, count the images. If the next run has started (either task, repetition or run changes), reset the counter (imgindex).
run(): Run loop running forever. Sends images from the camera to the imagestream and initiates reconfiguration of the camera in case properties have changed.
sendimage(im): Send Blackfly camera image via the imagestream. The image is converted to numpy array, additional information like binning, timestamp, etc., is added to a dictionary and both are sent to the imagestream.
- Args:
im - Blackfly image object. - Returns:
None
updateBusInfo(): Detect cameras on the bus and update info in properties if new camera has been found.
quatm.drivers.blackfly.bfly.pc2
class quatm.drivers.blackfly.bfly.pc2(object):
pass
- Dummy class in case driver is not installed.
Function:
Thorlabs TSI / uc480 科学相机
TLCamera ThorlabsTLCamera
⚙️
TSI 系列
Thorlabs 科学相机
| 通信 | TLCamera SDK |
| 接口 | USB3 |
| 传感器 | sCMOS / CCD |
| 支持 | ROI, binning |
适用于 SDK 级控制的高帧率科学成像。
驱动模块:ThorlabsTLCamera
from quatm.drivers.thorlabs.TLCamera import ThorlabsTLCamera
cam = ThorlabsTLCamera(serial="12345678")
cam.setup_acquisition(exposure=0.01, width=1024, height=768)
概述
Quatm 为全球 15 个主流科学相机品牌提供统一的 io.camera 接口封装,覆盖 EMCCD、sCMOS、高速 CMOS 和工业相机。所有驱动通过原生 SDK 实现高性能采集。
Andor 系列:EMCCD / sCMOS / 光谱仪
概述
Quatm 提供两套 Andor 相机驱动,通过原生 SDK 实现高性能成像控制:
| 驱动类 | SDK | 适用型号 | 接口 |
|---|
AndorSDK2Camera | atmcd32d.dll (SDK2) | iXon EMCCD, Luca, Clara | PCIe / USB |
AndorSDK3Camera | atcore.dll (SDK3) | Zyla, Neo, Marana (sCMOS) | USB3 / CameraLink |
ShamrockSpectrograph | ShamrockCIF.dll | SR-303i, SR-500i 等光谱仪 | USB |
所有类继承自 io.camera 接口,支持 ROI、binning、曝光控制和帧缓冲管理。
Andor SDK2 (EMCCD) AndorSDK2Camera
⚙️
iXon EMCCD
Andor SDK2 系列
| 通信 | DLL (atm32cd32) |
| 读出模式 | EM/传统 |
| ADC 频率 | 1/5/10 MHz |
| 像素深度 | 16-bit |
| 制冷 | TEC(≤ -100°C) |
适用于极低光信号场景(单原子/离子荧光),通过电子倍增(EM Gain)实现单光子级灵敏度。
驱动模块:AndorSDK2Camera
初始化
from quatm.drivers.andor.AndorSDK2 import AndorSDK2Camera
# 连接第一台相机
cam = AndorSDK2Camera(cam_id=0)
# 配置采集参数
cam.setup_acquisition(
exposure=0.1, # 曝光时间 (s)
em_gain=200, # EM 增益 (0-1000)
readout_rate="5MHz",# 读出速率
pre_amp_gain=2, # 前置放大增益
hsspeed=0, # 水平转移速率
temperature=-70, # 目标温度 (°C)
)
# 采集单帧
cam.start_acquisition(nframes=1)
image = cam.read_multiple_images(nframes=1)
关键参数
| 参数 | 说明 | 典型范围 |
|---|
exposure | 单帧曝光时长 | 0.001 – 3600 s |
em_gain | 电子倍增增益 | 0 – 1000(线性或真实增益模式) |
readout_rate | ADC 读出频率 | 1MHz / 5MHz / 10MHz |
temperature | 传感器目标温度 | -60 至 -100°C(取决于冷却器) |
pre_amp_gain | 前置放大器增益 | 1× – 4× |
Andor SDK3 (sCMOS) AndorSDK3Camera
⚙️
Zyla / Neo sCMOS
Andor SDK3 系列
| 通信 | DLL (atcore) |
| 传感器 | sCMOS |
| 接口 | USB3 / CameraLink |
| 像素深度 | 12/16-bit |
| 帧率 | 最高 100 fps(全分辨率) |
适用于快速序列成像和需要大视场的场景。基于 GenAPI 属性模型配置曝光、ROI 和触发。
驱动模块:AndorSDK3Camera
初始化
from quatm.drivers.andor.AndorSDK3 import AndorSDK3Camera
cam = AndorSDK3Camera(cam_id=0)
cam.setup_acquisition(
exposure=0.05,
pixel_format="Mono16",
trigger_mode="Internal",
)
Andor Shamrock 光谱仪 ShamrockSpectrograph
控制光栅选择、中心波长和狭缝宽度:
from quatm.drivers.andor.Shamrock import ShamrockSpectrograph
spec = ShamrockSpectrograph(idx=0)
spec.set_wavelength(780.24) # 中心波长 (nm)
spec.set_grating(2) # 选择光栅
spec.set_slit_width(50, port=1) # 入口狭缝 (µm)
设备配置
"emccd": {
"type": "local",
"module": "drivers.andor.AndorSDK2",
"class": "AndorSDK2Camera",
"arguments": {"cam_id": 0},
}
校准提示
EMCCD 增益需针对定量荧光测量进行校准。过高增益会引入时钟感应电荷(CIC)噪声和非线性。建议使用荧光珠或标准光源建立增益-信号关系曲线。
FLIR / Teledyne Spinnaker 系列
概述
Quatm 通过 TeledyneSpinnakerCamera 类封装 Spinnaker SDK,支持所有兼容 GenICam/GenAPI 的 FLIR/Teledyne USB3/GigE 相机。
⚙️
Blackfly S / Grasshopper3
FLIR Spinnaker 系列
| 通信 | Spinnaker SDK |
| 接口 | USB3 / GigE |
| 像素格式 | Mono8/16, Bayer |
| 触发 | 硬件/软件 |
| 帧率 | 取决于型号 |
用于实验室通用成像:MOT 监测、对准光束成像、设备状态监控。
驱动模块:TeledyneSpinnakerCamera
初始化
from quatm.drivers.teledyne.spinnaker import TeledyneSpinnakerCamera
# 列出所有可用相机
cam_list = TeledyneSpinnakerCamera.list_cameras()
# 连接指定相机(序列号或索引)
cam = TeledyneSpinnakerCamera(cam_id="serial_xxx")
# 或使用索引
cam = TeledyneSpinnakerCamera(cam_id=0)
# 配置并开始采集
cam.setup_acquisition(
exposure=0.02, # 20 ms 曝光
pixel_format="Mono8",
width=1920, height=1200,
offset_x=0, offset_y=0,
)
关键方法
| 方法 | 说明 |
|---|
list_cameras() | 枚举系统中所有 Spinnaker 相机 |
setup_acquisition(**kwargs) | 配置 ROI、曝光、像素格式等 |
start_acquisition(nframes) | 开始采集指定帧数 |
read_multiple_images(nframes) | 读取已采集图像 |
get_device_info() | 获取相机序列号、型号、固件版本 |
常用属性操作
通过 GenAPI 节点名称直接读写相机参数:
# 设置增益
cam.set_attribute("Gain", 10.0)
# 启用自动曝光
cam.set_attribute("ExposureAuto", "Continuous")
# 获取传感器温度
temp = cam.get_attribute("DeviceTemperature")
设备配置
"monitor_cam": {
"type": "local",
"module": "drivers.teledyne.spinnaker",
"class": "TeledyneSpinnakerCamera",
"arguments": {"cam_id": 0},
}
多相机同步
Spinnaker SDK 支持多相机硬件触发同步。设置 TriggerMode = On 和 TriggerSource = Line0 即可通过外部 TTL 信号实现纳秒级同步曝光。stop(): Stop capturing images.
quatm.drivers.blackfly.bfly.Camserver(name, serial)
class quatm.drivers.blackfly.bfly.Camserver(object):
def __init__(self, name, serial):
pass
def generateImageIndex(self):
pass
def run(self):
pass
def sendimage(self, im):
pass
def updateBusInfo(self):
pass
generateImageIndex(): In the current measurement, count the images. If the next run has started (either task, repetition or run changes), reset the counter (imgindex).
run(): Run loop running forever. Sends images from the camera to the imagestream and initiates reconfiguration of the camera in case properties have changed.
sendimage(im): Send Blackfly camera image via the imagestream. The image is converted to numpy array, additional information like binning, timestamp, etc., is added to a dictionary and both are sent to the imagestream.
- Args:
im - Blackfly image object. - Returns:
None
updateBusInfo(): Detect cameras on the bus and update info in properties if new camera has been found.
quatm.drivers.blackfly.bfly.pc2
class quatm.drivers.blackfly.bfly.pc2(object):
pass
- Dummy class in case driver is not installed.
Function:
Thorlabs TSI / uc480
Thorlabs 科学相机
Quatm 支持多类 Thorlabs 设备,包含位移台、光学测量仪器与相机。
TLCamera 科学相机 ThorlabsTLCamera
⚙️
TSI 系列
Thorlabs 科学相机
| 通信 | TLCamera SDK |
| 接口 | USB3 |
| 传感器 | sCMOS / CCD |
| 支持 | ROI, binning |
适用于需要 SDK 级别控制的高帧率科学成像。
驱动模块:ThorlabsTLCamera
from quatm.drivers.thorlabs.TLCamera import ThorlabsTLCamera
cam = ThorlabsTLCamera(serial="12345678")
---
## Basler — Pylon SDK 系列
⚙️
Basler ace / dart
Pylon SDK 系列
| 通信 |
Pylon SDK (GenICam) |
| 接口 |
USB3 / GigE |
| 传感器 |
CMOS |
| 像素格式 |
Mono8/16, Bayer |
| 功能 |
ROI, Binning, 硬件触发 |
工业级 CMOS 相机,适合 MOT 荧光监测、对准光束成像等常规实验室成像任务。
驱动模块:BaslerPylonCamera
```python
from quatm.drivers.Basler.pylon import BaslerPylonCamera
# 枚举全部相机
cams = BaslerPylonCamera.list_cameras()
cam = BaslerPylonCamera(cam_id=cams[0])
cam.setup_acquisition(exposure=0.02)
cam.start_acquisition(nframes=1)
Hamamatsu ORCA 系列 sCMOS
⚙️
ORCA-Fusion / ORCA-Flash4.0
Hamamatsu DCAM
| 通信 | DCAM SDK (DLL) |
| 传感器 | sCMOS |
| 像素 | 2048×2048 (Fusion) |
| 帧率 | 最高 100 fps |
| 读出噪声 | < 1.6 e⁻ |
超低噪声 sCMOS,适用于单原子/单离子荧光定量成像。
驱动模块:DCAMCamera
from quatm.drivers.DCAM.DCAM import DCAMCamera
cam = DCAMCamera(idx=0)
cam.setup_acquisition(exposure=0.1, pixel_format="Mono16")
Photometrics Prime / Evolve 系列
⚙️
Prime BSI / Evolve EMCCD
Photometrics PVCAM
| 通信 | PVCAM SDK (DLL) |
| 传感器 | 背照式 sCMOS / EMCCD |
| 接口 | PCIe / USB3 |
| 像素深度 | 16-bit |
背照式 sCMOS 提供高量子效率;EMCCD 型号支持单光子灵敏度。
驱动模块:PVCAMCamera
from quatm.drivers.Photometrics.pvcam import PVCAMCamera
cam = PVCAMCamera(cam_name="Prime_BSI_95B")
cam.setup_acquisition(exposure=0.05)
Princeton Instruments PIXIS / ProEM
⚙️
PIXIS / ProEM / IsoPlane
Princeton PICam
| 通信 | PICam SDK (DLL) |
| 传感器 | CCD / EMCCD |
| 制冷 | 液氮 / TEC |
| 接口 | PCIe / USB |
光谱学级 CCD/EMCCD,常与 Acton/IsoPlane 光谱仪配合使用。
驱动模块:PicamCamera
from quatm.drivers.PrincetonInstruments.picam import PicamCamera
cam = PicamCamera(cam_id=0)
cam.setup_acquisition(exposure=1.0) # 长曝光光谱采集
PCO edge / dimax 高速相机
⚙️
edge / dimax / pco.panda
PCO SC2
| 通信 | SC2 SDK (DLL) |
| 接口 | CameraLink HS / USB3 / GigE |
| 帧率 | 最高数千 fps |
| 传感器 | sCMOS / 高速 CMOS |
适合快速动力学过程:MOT 装载动态、离子晶体重排实时观测。
驱动模块:PCOSC2Camera
from quatm.drivers.PCO.SC2 import PCOSC2Camera
cam = PCOSC2Camera(interface="USB 3.0")
cam.setup_acquisition(exposure=0.001) # 1 ms 高速采集
Allied Vision Alvium / Mako
⚙️
Alvium / Mako / Bonito
Allied Vision Vimba X
| 通信 | VimbaX SDK (GenICam) |
| 接口 | USB3 / GigE / CameraLink |
| 传感器 | CMOS |
紧凑型工业相机,适合空间受限的光路集成。
驱动模块:AlliedVisionVimbaXCamera
from quatm.drivers.AlliedVision.VimbaX import AlliedVisionVimbaXCamera
cam = AlliedVisionVimbaXCamera(cam_id=0)
IDS uEye+ / Ensenso
⚙️
uEye+ / Ensenso 3D
IDS peak
| 通信 | IDS peak SDK |
| 接口 | USB3 / GigE |
| 传感器 | CMOS |
通用 USB/GigE 相机,包括 Ensenso 3D 立体相机。
驱动模块:GenericIDSPeakCamera
from quatm.drivers.IDS.peak import GenericIDSPeakCamera
cam = GenericIDSPeakCamera(cam_id=0)
通用配置范式
所有相机通过 device_db.py 以 type: "local" 注册:
"imaging_cam": {
"type": "local",
"module": "drivers.Basler.pylon",
"class": "BaslerPylonCamera",
"arguments": {"cam_id": 0},
}
帧采集卡
对于 Camera Link 接口的相机,Quatm 还内置 NI IMAQ、BitFlow 和 Silicon Software 帧采集卡驱动,用法与相机驱动一致——所有采集卡同样继承 io.camera 接口。3.2 - 信号源与射频
Valon 5009、DDS AD9959、Agilent、Rigol 等频率合成器与射频仪器驱动。
概述
Quatm 支持从通用函数发生器到矢量网络分析仪的多种射频仪器,涵盖频率合成、任意波形和 S 参数测量。
Valon 5009 双通道微波频率合成器
概述
Valon 5009 是一款双通道频率合成器(23.5 MHz – 6 GHz),通过串口控制。Quatm 通过 valon 封装,支持独立设置两路输出频率和功率。
⚙️
Valon 5009
Dual RF Synthesizer
| 通信 | 串口 (RS232) |
| 频率范围 | 23.5 MHz – 6 GHz |
| 通道数 | 2 |
| 输出功率 | -30 ~ +10 dBm |
| 频率分辨率 | 0.1 Hz |
广泛应用于离子阱实验中驱动微波跃迁(如 Ba⁺ 9.9 GHz 超精细跃迁)或作为 AOM 驱动源。
驱动模块:valon
初始化
from quatm.drivers.valon.valon_quatm import valon
# 连接 Valon(默认 /dev/ttyUSB0)
valon = valon(port="/dev/ttyUSB0")
# 设置通道 1 频率为 500 MHz
valon.set_frequency(freq=500e6, source=1)
# 设置通道 2 频率为 9.925 GHz(需外部倍频)
valon.set_frequency(freq=9.925e9, source=2)
# 发送原始指令
valon.sendRaw("LOCK 1 ON\r\n")
关键方法
| 方法 | 说明 |
|---|
set_frequency(freq, source) | 设置通道 1 或 2 输出频率 (Hz) |
sendCommand(source, command, value) | 发送格式化 SCPI 命令 |
sendRaw(cmd) | 发送原始字符串命令 |
串口通信
Valon 驱动底层通过 VSerialPort(serial.Serial 子类)通信,典型参数:
# 串口参数(驱动默认)
port = "/dev/ttyUSB0"
baudrate = 115200
timeout = 0.1
使用 Valon 5009 驱动 9.925 GHz 超精细跃迁,扫描频率测量 Rabi 振荡。
关键参数
| 起始频率 | 9.924 GHz |
| 终止频率 | 9.926 GHz |
| 步进 | 10 kHz |
| 每点重复 | 100 次 |
# 实验片段:频率扫描
import numpy as np
frequencies = np.arange(9.924e9, 9.926e9, 10e3)
for f in frequencies:
valon.set_frequency(freq=f, source=2)
# ... 执行探测序列 ...
参考:参见离子阱实验 → 量子态检测
频率精度
Valon 5009 内部参考频率稳定性有限。对于高精度光谱或量子操控实验,建议:
- 外接 10 MHz 铷钟参考信号
- 或使用 HighFinesse 波长计 / 频谱分析仪实时监测输出频率
class quatm.drivers.valon.valon_prog.Valon_Standalone(name='Valon')
Bases: object
Standalone driver for the Valon frequency generator. Commands can be sent via the Commandhub and are processed in parallel to the experiment, thereby the experiment is not delayed by the Valon.
function quatm.drivers.valon.valon_prog.run()
DDS AD9959 四通道直接数字合成
概述
AD9959 驱动封装 AD9959 评估板,通过 SPI 总线控制 4 个独立 DDS 通道,实现精密频率、幅度和相位控制。
⚙️
AD9959 评估板
4 通道 DDS
| 通信 | SPI |
| 通道数 | 4 |
| 频率分辨率 | 32-bit (0.12 Hz @ 500 MHz 时钟) |
| 相位分辨率 | 14-bit |
| 幅度控制 | 10-bit DAC |
广泛应用于冷原子/离子实验中的 AOM 驱动、边带生成和相干操控。
驱动模块:AD9959
初始化
from quatm.drivers.dds import AD9959
dds = AD9959()
# 配置通道 0 — 冷却光 AOM
dds.set_frequency(0, 80e6) # 80 MHz
dds.set_amplitude(0, 0.5) # 50% 幅度
dds.set_phase(0, 0) # 0° 相位
# 配置通道 1 — 再泵浦光 AOM(+0.1 MHz 差频)
dds.set_frequency(1, 80.1e6)
dds.set_amplitude(1, 0.3)
关键方法
| 方法 | 说明 |
|---|
set_frequency(ch, freq_hz) | 设置通道频率 (Hz) |
set_amplitude(ch, amp) | 设置通道幅度 (0–1 分数) |
set_phase(ch, phase_deg) | 设置通道相位 (°) |
update_all() | 一次性更新所有通道 |
同步更新
AD9959 支持同步更新模式:先对 4 个通道分别调用 set_* 方法(缓冲区),再调用 update_all() 统一写入硬件。这确保了多通道之间的相位一致性,对边带冷却等需要精确相位关系的实验至关重要。设备配置
"aom_dds": {
"type": "local",
"module": "drivers.DDS",
"class": "AD9959",
}
dds.set_amplitude(1, 0.5)
## 典型应用
| 应用 | 配置 |
|------|------|
| AOM 驱动 | 单通道固定频率 |
| 拉曼跃迁 | 双通道差频锁定 |
| 阱驱动 | 多通道相位控制 |
| 边带冷却 | 频率调制 |
## 替代驱动
还提供基于串口(AT 命令)接口的 AD9959 板替代驱动:
```python
from quatm.drivers.dds.alibaba import AD9959Board
Rigol DG1020Z 双通道函数发生器
DG1020Z
⚙️
DG1020Z
Rigol 函数发生器
| 通信 | VISA (USB/LAN) |
| 通道数 | 2 |
| 频率范围 | 1 µHz – 25 MHz |
| 幅度 | 1 mVpp – 10 Vpp |
| 采样率 | 200 MSa/s |
用于生成 AOM/EOM 驱动信号、调制波形和自定义任意波形。
驱动模块:RigolDG1020Z
from quatm.drivers.AWG.specific import RigolDG1020Z
fg = RigolDG1020Z(addr="USB0::...")
fg.set_frequency(80e6)
fg.set_amplitude(1.0) # 1.0 Vpp
fg.enable_output(channel=1, enable=True)
fg.set_function(channel=1, function="SIN")
=== Agilent 信号源扩展内容 ===
DDS AD9959
概述
AD9959 驱动封装 AD9959 评估板,通过 SPI 总线控制 4 个独立 DDS 通道,实现精密频率、幅度和相位控制。
⚙️
AD9959 评估板
4 通道 DDS
| 通信 | SPI |
| 通道数 | 4 |
| 频率分辨率 | 32-bit (0.12 Hz @ 500 MHz 时钟) |
| 相位分辨率 | 14-bit |
| 幅度控制 | 10-bit DAC |
广泛应用于冷原子/离子实验中的 AOM 驱动、边带生成和相干操控。
驱动模块:AD9959
初始化
dds = AD9959()
# 配置通道 0 — 冷却光 AOM
dds.set_frequency(0, 80e6) # 80 MHz
dds.set_amplitude(0, 0.5) # 50% 幅度
dds.set_phase(0, 0) # 0° 相位
# 配置通道 1 — 再泵浦光 AOM(+0.1 MHz 差频)
dds.set_frequency(1, 80.1e6)
dds.set_amplitude(1, 0.3)
关键方法
| 方法 | 说明 |
|---|
set_frequency(ch, freq_hz) | 设置通道频率 (Hz) |
set_amplitude(ch, amp) | 设置通道幅度 (0–1 分数) |
set_phase(ch, phase_deg) | 设置通道相位 (°) |
update_all() | 一次性更新所有通道 |
同步更新
AD9959 支持同步更新模式:先对 4 个通道分别调用 set_* 方法(缓冲区),再调用 update_all() 统一写入硬件。这确保了多通道之间的相位一致性,对边带冷却等需要精确相位关系的实验至关重要。设备配置
"aom_dds": {
"type": "local",
"module": "drivers.DDS",
"class": "AD9959",
}
dds.set_amplitude(1, 0.5)
## 典型应用
| 应用 | 配置 |
|------|------|
| AOM 驱动 | 单通道固定频率 |
| 拉曼跃迁 | 双通道差频锁定 |
| 阱驱动 | 多通道相位控制 |
| 边带冷却 | 频率调制 |
## 替代驱动
还提供基于串口(AT 命令)接口的 AD9959 板替代驱动:
```python
Rigol DG1020Z
DG1020Z 双通道函数/任意波形发生器
⚙️
DG1020Z
Rigol 函数发生器
| 通信 | VISA (USB/LAN) |
| 通道数 | 2 |
| 频率范围 | 1 µHz – 25 MHz |
| 幅度 | 1 mVpp – 10 Vpp |
| 采样率 | 200 MSa/s |
用于生成 AOM/EOM 驱动信号、调制波形和自定义任意波形。
驱动模块:RigolDG1020Z
from quatm.drivers.awg.specific import RigolDG1020Z
fg = RigolDG1020Z(addr="USB0::0x1AB1::0x0642::DG1ZA123456789::INSTR")
fg.set_frequency(80e6) # 80 MHz
fg.set_amplitude(1.0) # 1.0 Vpp
fg.enable_output(channel=1, enable=True)
fg.set_function(channel=1, function="SIN")
DP1116A 可编程直流电源
⚙️
DP1116A
Rigol 直流电源
| 通信 | VISA |
| 输出 | 16V/10A 或 32V/5A |
| 通道数 | 1 |
| 分辨率 | 1 mV / 1 mA |
用于线圈电流控制、激光二极管驱动和电路板供电。
驱动模块:DP1116A
from quatm.drivers.rigol.power_supply import DP1116A
ps = DP1116A(addr="USB0::0x1AB1::0x0E11::DP1A123456789::INSTR")
ps.set_voltage(12.0) # 12V
dc.set_current(0.5) # 500 mA 限流
ps.enable_output(True)
示波器
Rigol DS 系列示波器兼容 Tektronix SCPI 指令集,通过 ITektronixScope 驱动控制:
from quatm.drivers.tektronix.base import ITektronixScope
scope = ITektronixScope(addr="USB0::0x1AB1::0x04CE::DS123456789::INSTR", nchannels=4)
scope.set_timebase(scale=1e-6) # 1 µs/div
scope.set_vertical(channel=1, scale=0.5) # 0.5 V/div
waveform = scope.acquire(channel=1)
关键方法(信号发生器)
Agilent / Keysight 33500 系列任意波形发生器
⚙️
33500B / 33220A / 33250A
Agilent/Keysight
| 通信 | VISA (USB/LAN/GPIB) |
| 通道数 | 1–2 |
| 频率 | 最高 120 MHz (33500B) |
| 分辨率 | 14-bit |
| 采样率 | 250 MSa/s |
| 波形 | 正弦/方波/锯齿/脉冲/噪声/ARB |
实验室标准信号源,用于 AOM 驱动、调制信号和参考时钟生成。
驱动模块:Agilent33500 / Agilent33220A
from quatm.drivers.awg.specific import Agilent33500
awg = Agilent33500(addr="USB0::0x0957::0x2C07::MY52801234::INSTR")
# 配置 80 MHz 正弦波
awg.set_function(channel=1, function="SIN")
awg.set_frequency(80e6)
awg.set_amplitude(1.0) # 1 Vpp
awg.enable_output(channel=1, enable=True)
# 脉冲串模式 — 生成 N 个周期后自动关闭
awg.enable_burst(channel=1, ncycles=100)
支持型号
| 驱动类 | 适用型号 |
|---|
Agilent33500 | 33500B、33510B、33520B、33522B |
Agilent33220A | 33220A、33250A |
RigolDG1000 | DG1022、DG1032 |
RigolDG1020Z | DG1022Z、DG1032Z |
Instek AFG2000 / AFG2225 双通道
⚙️
AFG-2225 / AFG-2100
Instek
| 通信 | VISA |
| 通道数 | 1 (AFG2000) / 2 (AFG2225) |
| 频率 | 最高 25 MHz |
| 采样率 | 200 MSa/s |
性价比高的双通道任意波形发生器。
驱动模块:InstekAFG2225 / InstekAFG2000
from quatm.drivers.awg.specific import InstekAFG2225
awg = InstekAFG2225(addr="USB0::...")
awg.set_frequency(10e6)
awg.set_amplitude(2.0)
awg.enable_output(channel=1, enable=True)
awg.enable_output(channel=2, enable=True)
Tektronix AFG1000 任意波形发生器
⚙️
AFG1022 / AFG1062
Tektronix
| 通信 | VISA |
| 通道数 | 2 |
| 频率 | 最高 60 MHz (AFG1062) |
| 采样率 | 300 MSa/s |
| 任意波形 | 64 MB 存储 |
双通道高性能 AWG,支持大容量自定义波形。
驱动模块:TektronixAFG1000
from quatm.drivers.awg.specific import TektronixAFG1000
awg = TektronixAFG1000(addr="USB0::...")
awg.set_function(channel=1, function="ARB")
# 加载自定义波形...
Tektronix DPO/MSO 系列示波器
⚙️
DPO2000 / MSO4000 系列
Tektronix 示波器
| 通信 | VISA |
| 带宽 | 100 MHz – 1 GHz |
| 通道数 | 2–4 |
| 采样率 | 最高 5 GS/s |
通过 SCPI 自动化波形采集和参数测量。常用于实验调试和脉冲序列验证。
驱动模块:ITektronixScope
from quatm.drivers.tektronix.base import ITektronixScope
scope = ITektronixScope(
addr="USB0::0x0699::0x0401::C012345::INSTR",
nchannels=4
)
# 配置触发
scope.set_trigger(source=1, level=0.5, slope="POS")
scope.set_timebase(scale=1e-6) # 1 µs/div
scope.set_vertical(channel=1, scale=0.1) # 0.1 V/div
# 采集波形
waveform = scope.acquire(channel=1)
Agilent E5071C 矢量网络分析仪
⚙️
E5071C
Agilent VNA
| 通信 | VISA |
| 频率 | 9 kHz – 20 GHz |
| 端口 | 2–4 |
| 功能 | S 参数、阻抗、史密斯圆图 |
用于 RF 器件特性表征——滤波器、放大器、天线和传输线的 S 参数测量。
驱动模块:AgilentE5071C
from quatm.drivers.Agilent.vna import AgilentE5071C
vna = AgilentE5071C(addr="TCPIP::192.168.1.100::INSTR")
vna.set_frequency_range(start=1e6, stop=1e9, points=1001)
vna.set_if_bandwidth(100) # 100 Hz IFBW
vna.set_averaging(count=10)
# 读取 S21 参数
freq, s21 = vna.read_S_parameters(parameter="S21")
PicoVNA 便携式矢量网络分析仪
⚙️
PicoVNA
Pico Technology
| 通信 | TCP/SCPI (端口 5025) |
| 频率 | 300 kHz – 8.5 GHz |
| 端口 | 2 |
| 动态范围 | 100 dB
|
紧凑型 USB 控制 VNA,适合实验室桌面 RF 调试。
驱动模块:PicoVNA
from quatm.drivers.PicoTech.vna_scpi import PicoVNA
vna = PicoVNA(addr="localhost") # 或 IP 地址
vna.set_frequency_range(start=10e6, stop=500e6)
s_params = vna.read_S_parameters(parameter="S21")
通用 SCPI 设备配置
"function_gen": {
"type": "local",
"module": "drivers.awg.specific",
"class": "Agilent33500",
"arguments": {"addr": "USB0::..."},
}
3.3 - 激光器与光学
Cobolt、Toptica、Sirah Matisse、M² Solstis、HighFinesse 波长计等激光器与光学测量驱动。
概述
Quatm 支持半导体激光器、泵浦激光器、可调谐环形激光器及光学测量仪器。激光器类设备通过串口控制;SCPI 仪器继承标准接口。
概述
Quatm 支持半导体激光器、泵浦激光器、可调谐环形激光器及光学测量仪器。激光器类设备通过串口和SCPI协议通信。
Hubner Cobolt MLD / DPL 单频激光器
⚙️
Cobolt 06-01 系列
Hubner Cobolt
| 通信 | 串口 (115200 baud) |
| 波长 | 405/445/488/515/532/561/594/633/660/780/1064 nm |
| 功率 | 25–300 mW |
| 调制 | 模拟 + 数字 TTL (高达 5 MHz) |
紧凑型 DPSS/半导体激光器,适合离子/原子冷却光、再泵浦光和荧光激发。
驱动模块:Cobolt
from quatm.drivers.Hubner.Cobolt import Cobolt
laser = Cobolt(conn="/dev/ttyUSB0")
# 开启激光
laser.set_autostart(True)
laser.set_power(50e-3) # 50 mW
# 数字调制(TTL)
laser.set_digital_modulation(True)
laser.set_modulation_power(100e-3) # 调制时的高功率
# 读取运行参数
hours = laser.get_operating_hours()
temp = laser.get_base_temperature()
Toptica iBeam 智能半导体激光器
⚙️
iBeam 系列
Toptica
| 通信 | 串口 (115200 baud) |
| 波长 | 375–1550 nm |
带内置控制器的智能激光头,支持自动电流/功率校准和状态诊断。
驱动模块:TopticaIBeam
from quatm.drivers.Toptica.ibeam import TopticaIBeam
laser = TopticaIBeam(conn="/dev/ttyUSB0")
laser.set_power(channel=0, power=10e-3)
laser.enable(channel=0, enable=True)
Laser Quantum Finesse 泵浦激光器
⚙️
Finesse
Laser Quantum
| 通信 | 串口 (19200 baud) |
| 功率 | 4–16 W (532 nm) |
| 噪声 | < 0.1% RMS |
| 应用 | 钛宝石/染料激光器泵浦 |
超低噪声连续波 DPSS 激光器,用于泵浦 Sirah Matisse 等可调谐环形激光器。
驱动模块:Finesse
from quatm.drivers.LaserQuantum.base import Finesse
pump = Finesse(conn="/dev/ttyUSB0")
pump.set_power(10.0) # 10 W
pump.enable(True)
actual_power = pump.get_power()
Lighthouse Photonics Sprout G
⚙️
Sprout G
Lighthouse Photonics
| 通信 | 串口 (19200 baud) |
| 波长 | 532 nm |
| 功率 | 6–18 W |
| 噪声 | < 0.2% RMS |
高功率 532 nm 固态泵浦激光器,适用于钛宝石激光器和光偶极阱。
驱动模块:SproutG
from quatm.drivers.LighthousePhotonics.base import SproutG
sprout = SproutG(conn="/dev/ttyUSB0")
sprout.set_power(15.0)
sprout.enable(True)
Sirah Matisse 可调谐环形激光器
⚙️
Matisse
Sirah Lasertechnik
| 通信 | VISA 或 TCP/IP |
| 波长范围 | 可见光–近红外 (取决于染料/钛宝石) |
| 线宽 | < 50 kHz (锁定) |
| 调谐元件 | 双折射滤波器 + 薄/厚标准具 + 压电 |
精密可调谐环形激光器系统。
MatisseTuner 协调激光器与 HighFinesse 波长计,实现自动波长调谐和扫描拼接。
驱动模块:SirahMatisse / MatisseTuner
from quatm.drivers.Sirah.Matisse import SirahMatisse
matisse = SirahMatisse(addr="TCPIP::192.168.1.10::INSTR")
# 设置波长
matisse.set_birefringent_filter(wavelength=780.24) # nm
matisse.set_thin_etalon(wavelength=780.24)
matisse.set_thick_etalon(wavelength=780.24)
# 压电扫描
matisse.set_piezo_voltage(50.0) # 0–100 V
# 自动调谐(需配合波长计)
from quatm.drivers.Sirah.tuner import MatisseTuner
tuner = MatisseTuner(laser=matisse, wavemeter=wlm)
tuner.tune_to(wavelength=780.24) # 自动搜索并锁定
tuner.scan(start=780.20, stop=780.30, speed=0.01) # nm/s
M² Solstis 窄线宽可调谐激光器
⚙️
Solstis
M² Lasers
| 通信 | TCP/IP JSON + WebSocket |
| 波长范围 | 700–1000 nm (钛宝石) |
| 线宽 | < 50 kHz |
| 功能 | 标准具锁定、腔参考锁定、波长计反馈 |
全数字可调谐激光系统,通过 TCP/IP JSON 接口完全远程控制。支持 WebSocket 实时状态流。
驱动模块:Solstis (ICE Bloc)
from quatm.drivers.M2.solstis import Solstis
solstis = Solstis(addr="192.168.1.20", port=8080)
# 波长调谐
solstis.set_wavelength(780.24)
# 标准具锁定
solstis.lock_etalon()
# 太赫兹扫描(与 EMM 模块配合)
solstis.set_terahertz_scan(start_freq=0, stop_freq=100e9)
光功率计 & 波长计
Thorlabs PM100/PM400 光功率计
Thorlabs 光功率计详情见本页下方。
Ophir Vega 激光功率/能量计
⚙️
Vega
Ophir
| 通信 | 串口 |
| 探头 | 热电堆/光电二极管/热释电 |
| 功率 | µW – kW |
| 能量 | µJ – J |
多功能激光测量仪,支持连续波功率和脉冲能量测量。
驱动模块:VegaPowerMeter
from quatm.drivers.Ophir.base import VegaPowerMeter
pm = VegaPowerMeter(conn="/dev/ttyUSB0")
power = pm.get_power()
HighFinesse WS6/WS7 精密波长计
⚙️
WS6 / WS7
HighFinesse
| 通信 | 原生 wlmData.dll |
| 精度 | 2–200 MHz (取决于型号) |
| 通道数 | 1–8 |
| 测量速率 | 最高 500 Hz |
| 波长范围 | 350–1120 nm |
用于精密激光频率测量和反馈控制的 Fizeau 干涉仪波长计。多通道型号可同时监测多台激光器频率。
驱动模块:WLM
from quatm.drivers.HighFinesse.wlm import WLM
wlm = WLM(version=7, dll_path="C:\\wlm\\wlmData.dll")
# 读取通道 1 当前频率
freq = wlm.get_frequency(channel=1) # THz
wavelength = wlm.get_wavelength(channel=1) # nm
# 曝光控制(自动适应光强)
wlm.set_exposure(channel=1, mode="auto")
Matisse 自动调谐
HighFinesse 波长计 + Sirah Matisse 的组合是 Quatm 中典型的激光频率反馈控制系统。MatisseTuner 驱动协调两者,实现闭环自动调谐和宽范围无跳模扫描。
Thorlabs 光功率计
光功率计 GenericPM
⚙️
PM100 / PM400 系列
Thorlabs 功率计
| 通信 | VISA (USB) |
| 支持探头 | 光电二极管/热电堆/热释电 |
| 波长范围 | 取决于探头 |
| 功率范围 | nW – W 级 |
通过 SCPI 命令与 Thorlabs 功率计表头通信,支持多种探头类型。
驱动模块:GenericPM
from quatm.drivers.thorlabs.misc import GenericPM
pm = GenericPM(addr="USB0::0x1313::0x8078::P1234567::INSTR")
# 设置工作波长(用于探头校准)
pm.set_wavelength(780.0) # 780 nm
# 读取功率
power = pm.get_power() # 返回当前功率 (W)
TLCamera 科学相机 ThorlabsTLCamera
Thorlabs 光功率计 PM100 / PM400
⚙️
PM100 / PM400 系列
Thorlabs 功率计
| 通信 | VISA (USB) |
| 支持探头 | 光电二极管/热电堆/热释电 |
| 波长范围 | 取决于探头 |
| 功率范围 | nW – W 级 |
通过 SCPI 命令与 Thorlabs 功率计表头通信,支持多种探头类型。
驱动模块:GenericPM
from quatm.drivers.Thorlabs.misc import GenericPM
pm = GenericPM(addr="USB0::0x1313::0x8078::P1234567::INSTR")
pm.set_wavelength(780.0) # 780 nm 校准
power = pm.get_power() # 当前功率 (W)
3.4 - 运动与定位
PI 纳米定位台、Attocube、Newport Picomotor、Thorlabs APT 等精密运动与定位驱动。
概述
Quatm 支持从压电纳米定位到步进电机长行程的多种运动平台,统一 IMultiaxisStage 接口。
Physik Instrumente (PI) 压电纳米定位
概述
GenericPIController 封装 PI 通用控制器串口通信,通过 ASCII 命令集控制多种 PI 压电定位平台。
⚙️
PI 压电控制器
E-xxx 系列
| 通信 | 串口 (RS232) |
| 协议 | PI ASCII 命令集 |
| 轴数 | 取决于控制器型号 |
| 精度 | 亚纳米级 |
典型应用包括高 NA 物镜精密对焦、光纤耦合自动对准、干涉仪光路调节和光偶极阱束腰位置控制。
驱动模块:GenericPIController
初始化
from quatm.drivers.PhysikInstrumente.base import GenericPIController
# 串口连接
stage = GenericPIController(conn="/dev/ttyUSB0")
# 归零
stage.home(axis=0)
# 绝对定位(µm)
stage.move_to(axis=0, position=50.0)
# 相对移动
stage.move_by(axis=1, delta=10.0)
# 查询当前位置
pos = stage.get_position(axis=0)
关键方法
| 方法 | 说明 |
|---|
home(axis) | 指定轴归零 |
move_to(axis, position) | 绝对定位 (µm) |
move_by(axis, delta) | 相对移动 (µm) |
get_position(axis) | 查询当前位置 |
stop(axis) | 紧急停止 |
设备配置
"objective_z": {
"type": "local",
"module": "drivers.PhysikInstrumente.base",
"class": "GenericPIController",
"arguments": {"conn": "/dev/ttyUSB0"},
}
## 使用示例
```python
# 在 Experiment 类中
self.pi_stage = self.get_device("pi_stage")
# 移动到指定位置 (μm)
self.pi_stage.move_absolute(x=50.0, y=25.0, z=10.0)
# 相对移动
self.pi_stage.move_relative(dx=1.0, dy=0.0, dz=0.0)
注意:压电平移台有行程限制,超出范围会触发硬件保护。使用前请查阅设备手册确认最大行程。
Thorlabs APT/Kinesis 位移台
KDC101 / K10CR1 系列
⚙️
KDC101 / K10CR1 / 滤光轮
Thorlabs APT/Kinesis
| 通信 | 串口 (FTDI) |
| 协议 | APT (二进制) |
| 适用设备 | 直流伺服电机、步进电机、滤光轮、快门 |
统一封装 Thorlabs APT 协议设备。
驱动模块:BasicKinesisDevice
from quatm.drivers.Thorlabs.kinesis import BasicKinesisDevice
stage = BasicKinesisDevice(conn="27200001")
stage.home()
stage.move_to(position=25.0) # mm
Elliptec 压电谐振电机
⚙️
ELLx 系列
Thorlabs Elliptec
| 通信 | 串口 (9600 baud) |
| 行程 | 取决于滑块 |
| 精度 | µm 级 |
紧凑型压电谐振电机,适合空间受限的光学调整架。
驱动模块:ElliptecMotor
from quatm.drivers.Thorlabs.elliptec import ElliptecMotor
motor = ElliptecMotor(conn="/dev/ttyUSB0", addrs=[0])
motor.move_to(axis=0, position=10.0)
电动滤光轮 FW102/FW212
from quatm.drivers.Thorlabs.serial import FW
fw = FW(conn="/dev/ttyUSB0")
fw.set_position(position=2) # 切换到第 2 个滤光片位置
Physik Instrumente (PI)
概述
GenericPIController 封装 PI 通用控制器串口通信,通过 ASCII 命令集控制多种 PI 压电定位平台。
⚙️
PI 压电控制器
E-xxx 系列
| 通信 | 串口 (RS232) |
| 协议 | PI ASCII 命令集 |
| 轴数 | 取决于控制器型号 |
| 精度 | 亚纳米级 |
典型应用包括高 NA 物镜精密对焦、光纤耦合自动对准、干涉仪光路调节和光偶极阱束腰位置控制。
驱动模块:GenericPIController
初始化
from quatm.drivers.PhysikInstrumente.base import GenericPIController
# 串口连接
stage = GenericPIController(conn="/dev/ttyUSB0")
# 归零
stage.home(axis=0)
# 绝对定位(µm)
stage.move_to(axis=0, position=50.0)
# 相对移动
stage.move_by(axis=1, delta=10.0)
# 查询当前位置
pos = stage.get_position(axis=0)
关键方法
| 方法 | 说明 |
|---|
home(axis) | 指定轴归零 |
move_to(axis, position) | 绝对定位 (µm) |
move_by(axis, delta) | 相对移动 (µm) |
get_position(axis) | 查询当前位置 |
stop(axis) | 紧急停止 |
设备配置
"objective_z": {
"type": "local",
"module": "drivers.PhysikInstrumente.base",
"class": "GenericPIController",
"arguments": {"conn": "/dev/ttyUSB0"},
}
## 使用示例
```python
# 在 Experiment 类中
self.pi_stage = self.get_device("pi_stage")
# 移动到指定位置 (μm)
self.pi_stage.move_absolute(x=50.0, y=25.0, z=10.0)
# 相对移动
self.pi_stage.move_relative(dx=1.0, dy=0.0, dz=0.0)
注意:压电平移台有行程限制,超出范围会触发硬件保护。使用前请查阅设备手册确认最大行程。
Thorlabs 位移台与电机
Quatm 支持多类 Thorlabs 设备,包含位移台、光学测量仪器与相机。
APT/Kinesis 位移台 BasicKinesisDevice
⚙️
KDC101 / K10CR1 / 滤光轮
Thorlabs APT/Kinesis
| 通信 | 串口 (FTDI) |
| 协议 | APT (二进制) |
| 适用设备 | 直流伺服电机、步进电机、滤光轮、快门 |
统一封装 Thorlabs APT 协议设备,通过串口(FTDI 芯片)通信。
驱动模块:BasicKinesisDevice
from quatm.drivers.thorlabs.kinesis import BasicKinesisDevice
# 连接指定序列号的设备
stage = BasicKinesisDevice(conn="27200001") # 序列号
# 归零
stage.home()
# 绝对定位(mm)
stage.move_to(position=25.0)
# 读取当前位置
pos = stage.get_position()
Elliptec 压电谐振电机 ElliptecMotor
⚙️
ELLx 系列
Thorlabs Elliptec
| 通信 | 串口 (9600 baud) |
| 行程 | 取决于滑块长度 |
| 精度 | µm 级 |
| 真空兼容 | 可选 |
紧凑型压电谐振电机,适合空间受限的光学调整架。
驱动模块:ElliptecMotor
from quatm.drivers.thorlabs.elliptec import ElliptecMotor
motor = ElliptecMotor(conn="/dev/ttyUSB0", addrs=[0])
motor.move_to(axis=0, position=10.0) # mm
电动滤光轮
from quatm.drivers.thorlabs.serial import FW
fw = FW(conn="/dev/ttyUSB0") # FW102 / FW212
fw.set_position(position=2) # 切换到第 2 个滤光片位置
KDC101 电机平移台
通过 .NET SDK 控制 Thorlabs KDC101/T-Cube 系列电机平移台。
from quatm.drivers.thorlabs.kdc101 import KDC101
stage = KDC101("26001234") # 序列号
stage.home() # 回零
stage.move_absolute(10.0) # 移动到 10.0 mm
pos = stage.get_position() # 读取当前位置
| 功能 | 说明 |
|---|
| 回零 | 自动寻找限位开关 |
| 绝对移动 | 移动到指定位置 (mm) |
| 相对移动 | 相对当前位置移动 |
| 位置读取 | 实时读取当前位置 |
##概述
Quatm 支持从压电纳米定位到步进电机长行程的多种运动平台。所有平台继承 io.stage 接口,提供统一的 move_to / get_position / home API。
Attocube ANC300 / ANC350 纳米定位
⚙️
ANC300
Attocube
| 通信 | TCP/IP (端口 7230) |
| 轴数 | 最多 7 轴 |
| 行程 | mm 级 |
| 精度 | nm 级 |
| 适用 | 低温 / 真空 |
模块化纳米定位控制器,通过 TCP/IP 远程控制。广泛用于低温恒温器内物镜和样品的精确定位。
驱动模块:ANC300
from quatm.drivers.Attocube.anc300 import ANC300
anc = ANC300(conn=("192.168.1.30", 7230))
# 归零
anc.home(axis=0)
# 纳米级步进
anc.move_by(axis=0, delta=0.1) # 100 nm
# 连续扫描模式
anc.set_continuous_mode(axis=1, enable=True)
anc.set_continuous_speed(axis=1, speed=100.0) # nm/s
⚙️
ANC350
Attocube (USB)
| 通信 | USB HID (PyUSB) |
| 轴数 | 最多 3 轴 |
| 控制 | USB 直接连接 |
USB 版本,适合桌面应用。
驱动模块:ANC350
from quatm.drivers.Attocube.anc350 import ANC350
anc = ANC350(conn=0) # 第一台 USB 设备
anc.move_to(axis=0, position=50.0)
Newport Picomotor 8742 4 轴控制器
⚙️
Picomotor 8742
Newport
| 通信 | USB (PyUSB) 或 TCP/IP Telnet (端口 23) |
| 轴数 | 4 |
| 步长 | < 30 nm |
| 真空兼容 | 可选 |
压电惯性电机控制器,支持 USB 直连或网络控制。真空兼容型号可直接用于真空腔内的光学元件调整。
驱动模块:Picomotor8742
from quatm.drivers.Newport.picomotor import Picomotor8742
# USB 连接
pico = Picomotor8742(conn=0)
# 或 TCP/IP
pico = Picomotor8742(conn="192.168.1.40", multiaddr=(0, 1))
pico.move_to(axis=0, position=5.0) # mm
pico.home(axis=0)
SmarAct MCS2 / SCU3D 高精度定位
⚙️
MCS2
SmarAct
| 通信 | 原生 MCS2 SDK |
| 轴数 | 最多 18 轴 |
| 精度 | nm 级 |
| 速度 | 最高 20 mm/s |
| 真空/低温 | 可选模块 |
模块化高精度定位系统,支持多轴协调运动和复杂轨迹。
驱动模块:MCS2
from quatm.drivers.SmarAct.MCS2 import MCS2
mcs = MCS2(locator="usb:sn:12345678")
mcs.move_to(axis=0, position=10.0) # mm
mcs.get_position(axis=0)
⚙️
SCU3D
SmarAct 3 轴
一体化 3 轴控制器,适合紧凑空间。
驱动模块:SCU3D
from quatm.drivers.SmarAct.scu3d import SCU3D
scu = SCU3D(idx=0)
scu.move_to(axis=1, position=25.0)
Standa 8SMC 步进电机控制器
⚙️
8SMC4 / 8SMC5
Standa
| 通信 | 串口 (115200 baud) |
| 轴数 | 1–4 |
| 步进分辨率 | 取决于电机/丝杠 |
| 应用 | 长行程位移台、旋转台 |
经济型步进电机控制器,适合光学平台上的长行程粗定位。
驱动模块:Standa8SMC
from quatm.drivers.standa.base import Standa8SMC
stage = Standa8SMC(conn="/dev/ttyUSB0")
stage.move_to(position=50.0) # mm
stage.home()
⚙️
Performax
Arcus Technology
| 通信 | USB (DLL) 或 RS485 串口 |
| 轴数 | 最多 4 轴 |
| 功能 | 加减速曲线、限位检测 |
高性能步进电机控制器,提供平滑的 S 曲线加减速。
驱动模块:GenericPerformaxStage
from quatm.drivers.arcus.performax import GenericPerformaxStage
stage = GenericPerformaxStage(idx=0, conn="USB")
stage.move_to(axis=0, position=100.0)
stage.set_acceleration(axis=0, accel=50.0) # mm/s²
Trinamic TMCM-1110 一体化步进电机
⚙️
TMCM-1110
Trinamic
| 通信 | 串口 (9600 baud, TMCL 协议) |
| 功能 | StallGuard 失速检测、CoolStep 节能 |
一体化步进电机模块,内置控制器和驱动器。适合简单旋转/平移任务和光路快门。
驱动模块:TMCM1110
from quatm.drivers.trinamic.base import TMCM1110
motor = TMCM1110(conn="/dev/ttyUSB0")
motor.move_to(position=180.0) # 旋转 (°)
motor.set_velocity(500.0) # °/s
Thorlabs Elliptec 压电谐振电机
Thorlabs 位移台详情见本页下方。
通用运动平台配置
"objective_z": {
"type": "local",
"module": "drivers.Attocube.anc300",
"class": "ANC300",
"arguments": {"conn": ("192.168.1.30", 7230)},
}
多轴协调
所有 io.multiaxisstage 驱动支持独立的轴向映射。通过 muxaxis 工具可将物理轴组合为逻辑坐标系,实现倾斜校正、坐标变换等高级功能。3.5 - DAQ 与电源
NI DAQ、Rigol/EA 电源、Keithley/Voltcraft 万用表、示波器等数据采集与电学测量驱动。
概述
数据采集和电源设备是实验自动化的基础设施。Quatm 提供统一的 NI-DAQmx 封装和 SCPI/Modbus 仪器驱动。
Rigol DP1116A 可编程直流电源
⚙️
DP1116A
Rigol 直流电源
| 通信 | VISA |
| 输出 | 16V/10A 或 32V/5A |
| 通道数 | 1 |
| 分辨率 | 1 mV / 1 mA |
用于线圈电流控制、激光二极管驱动和电路板供电。
驱动模块:DP1116A
from quatm.drivers.rigol.power_supply import DP1116A
ps = DP1116A(addr="USB0::0x1AB1::0x0E11::DP1A123456789::INSTR")
ps.set_voltage(12.0) # 12V
dc.set_current(0.5) # 500 mA 限流
ps.enable_output(True)
Rigol DP932 可编程直流电源
用于为各种实验室设备提供可编程直流电源。
from quatm.drivers.rigol.dp932 import RigolDP932
psu = RigolDP932("USB0::...")
psu.set_voltage(1, 5.0) # 通道 1: 5.0 V
psu.set_current(1, 1.0) # 通道 1: 1.0 A 限流
psu.output_on(1)
NI-SWITCH 矩阵/多路复用开关
⚙️
PXI-25xx / SCXI-11xx 系列
NI-SWITCH
| 通信 | NI-SWITCH API |
| 拓扑 | 矩阵/多路复用/通用 |
| 通道 | 取决于模块 |
| 切换速度 | ms 级 |
| 最大电压 | 300 V (取决于模块) |
NI 开关模块通过
niswitch Python API 控制。适用于实验中的信号路由切换、校准多路复用和线圈极性翻转。
驱动模块:ni_switch
from quatm.drivers.NI.ni_switch import NISwitch
sw = NISwitch(resource_name="PXI1Slot2")
sw.connect(channel1="ch0", channel2="com0")
sw.disconnect(channel1="ch0", channel2="com0")
all_relays = sw.get_relay_count()
NI-Digital 数字波形发生器/分析仪
⚙️
PXIe-657x / PXIe-655x 系列
NI-Digital
| 通信 | NI-Digital Pattern API |
| 通道 | 32–128 |
| 速率 | 最高 200 MHz |
| 电压 | 1.2–5.5 V (可编程) |
| 功能 | Pattern 生成/采集、PMU 参数测量 |
NI 数字波形仪器通过
nidigital Python API 控制。生成和采集高速数字波形,适用于自定义 TTL 时序协议和芯片级数字测试。
驱动模块:ni_digital
from quatm.drivers.NI.ni_digital import NIDigital
dig = NIDigital(resource_name="PXI1Slot3")
dig.configure_voltage_levels(voltage=3.3)
pattern = [0b10101010] * 100 # 100 周期数字波形
dig.burst_pattern(pattern, frequency=10e6)
NI-DAQmx 多功能数据采集卡
⚙️
PCIe-63xx / USB-63xx / PXI 系列
NI DAQ
| 通信 | NI-DAQmx |
| 模拟输入 | 16-bit, 最高 2 MS/s |
| 模拟输出 | 16-bit |
| 数字 I/O | TTL, 最高 10 MHz |
| 计数器 | 2–4 通道 |
通用多功能数据采集卡,用于模拟信号记录、时序数字 I/O 和光子计数。
驱动模块:NIDAQ
from quatm.drivers.NI.daq import NIDAQ
daq = NIDAQ(
dev_name="Dev1",
rate=100_000, # 100 kS/s
buffer_size=10_000,
)
# 模拟输入(连续采集)
daq.configure_ai(channels=["ai0", "ai1"], voltage_range=(-10, 10))
daq.start_ai()
data = daq.read_ai(samples=1000)
# 模拟输出
daq.configure_ao(channels=["ao0"], voltage_range=(0, 5))
daq.write_ao(channel="ao0", voltage=3.3)
# 数字 I/O
daq.configure_di(lines=["port0/line0"])
daq.configure_do(lines=["port0/line1"])
daq.write_do(line="port0/line1", value=True)
# 计数器(光子计数 / 频率测量)
daq.configure_counter(
counter="ctr0",
mode="edge_count",
source="PFI0",
)
counts = daq.read_counter("ctr0")
Conrad 继电器板控制器
⚙️
Relay Board
Conrad
| 通信 | 串口 (19200 baud, 二进制协议) |
| 通道 | 每板 8 继电器,支持菊花链 |
| 触点 | AC/DC 切换 |
经济型多通道继电器控制器,适合粗粒度开关控制:磁阱线圈极性切换、设备供电开关、激光快门控制。
驱动模块:RelayBoard
from quatm.drivers.Conrad.base import RelayBoard
# 单板
rb = RelayBoard(conn="/dev/ttyUSB0", start_addr=0)
rb.set_relay(relay=0, state=True) # 闭合第 1 个继电器
rb.set_relay(relay=3, state=False) # 断开第 4 个继电器
# 字节写入(同时控制 8 路)
rb.write_byte(0b10101010)
Elektro Automatik PS2000B 高功率电源
⚙️
PS2000B 系列
Elektro Automatik
| 通信 | 串口 (115200 baud) |
| 功率 | 640 W – 15 kW (取决于型号) |
| 电压 | 最高 1500 V |
| 电流 | 最高 510 A |
| 功能 | 恒压/恒流/恒功率模式 |
高功率可编程直流电源,用于磁阱线圈大电流驱动和 Feshbach 共振磁场线圈供电。
驱动模块:PS2000B
from quatm.drivers.ElektroAutomatik.base import PS2000B
ps = PS2000B(conn="/dev/ttyUSB0", remote_mode=True)
# 恒流模式 — 磁场线圈
ps.set_current(50.0) # 50 A
ps.set_voltage_limit(20.0) # 20 V 限压
ps.enable_output(True)
# 读取实际值
actual_v = ps.get_voltage()
actual_i = ps.get_current()
Keithley 2110 台式数字万用表
⚙️
2110
Keithley
| 通信 | VISA (USB/LAN) |
| 功能 | DCV/ACV/DCI/ACI/电阻/电容/频率/温度 |
| 精度 | 5½ 位 |
| 采样率 | 最高 50 kS/s |
精密台式万用表,用于电学特性表征和传感器校准。
驱动模块:Keithley2110
from quatm.drivers.Keithley.multimeter import Keithley2110
dmm = Keithley2110(addr="USB0::0x05E6::0x2110::1234567::INSTR")
# DC 电压测量
voltage = dmm.measure_voltage(range="10V")
# 4 线电阻测量
resistance = dmm.measure_resistance_4wire(range="100Ω")
# 温度(热电偶)
temp = dmm.measure_temperature(tc_type="K")
Voltcraft VC7055 双通道台式万用表
⚙️
VC7055
Voltcraft
| 通信 | 串口 (115200 baud, SCPI) |
| 通道数 | 2 |
| 功能 | DCV/ACV/DCI/ACI/电阻/频率/电容 |
| 蓝牙 | 可选 (VC7055BT) |
双通道台式万用表,内置蓝牙的 BT 型号支持无线数据采集。
驱动模块:VC7055
from quatm.drivers.Voltcraft.multimeter import VC7055
dmm = VC7055(addr="/dev/ttyUSB0")
# 双通道同时测量
v1 = dmm.measure_voltage(channel=1)
v2 = dmm.measure_voltage(channel=2)
设备配置
"daq": {
"type": "local",
"module": "drivers.NI.daq",
"class": "NIDAQ",
"arguments": {"dev_name": "Dev1", "rate": 100_000},
},
"coil_ps": {
"type": "local",
"module": "drivers.ElektroAutomatik.base",
"class": "PS2000B",
"arguments": {"conn": "/dev/ttyUSB0", "remote_mode": True},
},
"dmm": {
"type": "local",
"module": "drivers.Keithley.multimeter",
"class": "Keithley2110",
"arguments": {"addr": "USB0::..."},
},
3.6 - 环境监测
Lakeshore、Cryocon、Pfeiffer、Leybold 等温度、真空、低温监测驱动。
概述
实验室环境监测是量子实验稳定性的基础。Quatm 内置温度、真空和低温液位监测驱动,支持实时数据记录和异常告警。
Lakeshore 218 温度监测器
⚙️
218
Lakeshore
| 通信 | 串口 (9600 baud, 7E1) |
| 通道数 | 8 |
| 传感器 | 二极管 (Si/GaAs)、铂电阻 (Pt100/1000)、Cernox、RuO₂ |
| 温度 | 1.4 K – 1500 K (取决于传感器) |
低温物理实验标准温度监测器。8 通道独立配置,支持二极管、电阻温度计和 Cernox 薄膜电阻。
驱动模块:Lakeshore218
from quatm.drivers.Lakeshore.base import Lakeshore218
ls = Lakeshore218(conn="/dev/ttyUSB0")
# 配置通道 1 为硅二极管
ls.set_sensor_type(channel=1, sensor_type="DT-670")
# 读取温度
temp = ls.get_temperature(channel=1) # Kelvin
all_temps = ls.get_all_temperatures() # 全部 8 通道
# 读取传感器原始值(电压/电阻)
raw = ls.get_reading(channel=1)
Cryocon 12C / 14C / 18C 温度控制器
⚙️
12C / 14C / 18C
Cryocon
| 通信 | 串口 (9600 baud) |
| 通道数 | 2–4 (取决于型号) |
| 支持传感器 | 二极管/Pt/Cernox |
带 PID 加热输出的低温温度控制器,用于精密温度稳定。
驱动模块:Cryocon1x
from quatm.drivers.Cryocon.base import Cryocon1x
cryo = Cryocon1x(conn="/dev/ttyUSB0", nchannels=4)
# 读取通道 1 温度
temp = cryo.get_temperature(channel=1)
# PID 设定点
cryo.set_setpoint(channel=1, temperature=4.2) # 4.2 K
cryo.set_heater_range(channel=1, range="low")
cryo.enable_heater(channel=1, enable=True)
Lumel RE72 · Omron E5_C 温控器
⚙️
RE72 / E5_C
Lumel / Omron
| 通信 | RS485 Modbus RTU |
| 功能 | PID 自整定、斜坡/保持程序 |
| 应用 | 光学平台温度稳定、激光晶体温控 |
工业级 PID 温度控制器,通过 Modbus RTU 协议通信。常用于激光器晶体温度控制和光学平台环境温控。
驱动模块:LumelRE72Controller / OmronE5xCController
from quatm.drivers.Lumel.base import LumelRE72Controller
from quatm.drivers.Omron.base import OmronE5xCController
# Lumel RE72
lumel = LumelRE72Controller(conn="/dev/ttyUSB1", daddr=1)
temp = lumel.get_temperature()
lumel.set_setpoint(25.0)
# Omron E5_C
omron = OmronE5xCController(conn="/dev/ttyUSB1", daddr=2)
omron.set_setpoint(30.0)
omron.enable_heater(True)
Pfeiffer TPG2xx 高真空计
⚙️
TPG2xx 系列
Pfeiffer Vacuum
| 通信 | 串口 (9600 baud) |
| 通道数 | 2 |
| 支持规管 | Pirani / Cold Cathode / 复合规 |
| 量程 | 大气压 – 10⁻¹⁰ mbar |
紧凑型双通道真空计控制器,同时支持粗真空(Pirani)和超高真空(冷阴极)规管。
驱动模块:TPG2xx
from quatm.drivers.Pfeiffer.base import TPG2xx
tpg = TPG2xx(conn="/dev/ttyUSB0")
# 读取两路压力
p1 = tpg.get_pressure(channel=1) # mbar
p2 = tpg.get_pressure(channel=2)
# 规管类型识别
gauge_type = tpg.get_gauge_type(channel=1)
Leybold ITR 宽量程真空计
⚙️
ITR 系列
Leybold
| 通信 | 串口 (9600 baud, 二进制协议) |
| 量程 | 大气压 – 5×10⁻¹⁰ mbar |
| 输出 | 持续压力数据流 |
宽量程皮拉尼/冷阴极复合真空计,主动推送压力数据。
驱动模块:GenericITR
from quatm.drivers.Leybold.base import GenericITR
itr = GenericITR(conn="/dev/ttyUSB0")
pressure = itr.get_pressure() # mbar
Agilent XGS-600 多通道真空控制器
⚙️
XGS-600
Agilent
| 通信 | 串口 (RS485) |
| 通道数 | 最多 6 路规管 |
| 规管类型 | Hot Filament / Cold Cathode / Pirani / Convection |
大型真空系统的多规管控制器,通过 RS485 串联地址访问。
驱动模块:XGS600
from quatm.drivers.Agilent.pressure import XGS600
xgs = XGS600(conn="/dev/ttyUSB0", addr=1)
# 读取所有通道压力
pressures = xgs.get_all_pressures()
p1 = xgs.get_pressure(channel=1)
低温液位监测
Cryomagnetics LM500 液氦/液氮液位计
⚙️
LM500 / LM510
Cryomagnetics
| 通信 | 串口 (9600 baud) |
| 功能 | He/N₂ 液位、温度、样品室温度 |
| 通道 | 1–2 液位 + 4 温度 |
超导磁体杜瓦液位监测标准设备。同时监测液氦/液氮液位和样品室温度。
驱动模块:LM500
from quatm.drivers.Cryomagnetics.base import LM500
lm = LM500(conn="/dev/ttyUSB0")
helium_level = lm.get_helium_level() # %
nitrogen_level = lm.get_nitrogen_level() # %
sample_temp = lm.get_temperature()
American Magnetics 1700 液位监测器
⚙️
1700
American Magnetics
| 通信 | 串口或 TCP/IP (端口 7180) |
| 功能 | He / N₂ 液位、继电器控制 |
支持串口和网络双接口的液位监测器。
驱动模块:AM1700
from quatm.drivers.AmericanMagnetics.base import AM1700
am = AM1700(conn="192.168.1.50") # TCP/IP
# 或串口: am = AM1700(conn="/dev/ttyUSB0")
level = am.get_helium_level()
通用环境监测配置
"chamber_pressure": {
"type": "local",
"module": "drivers.Pfeiffer.base",
"class": "TPG2xx",
"arguments": {"conn": "/dev/ttyUSB0"},
},
"cryo_temp": {
"type": "local",
"module": "drivers.Lakeshore.base",
"class": "Lakeshore218",
"arguments": {"conn": "/dev/ttyUSB1"},
},
自动化监控
结合 Quatm 的 DataStreamMonitor 和 UpdatingPlot 组件,可实时可视化真空、温度和液位数据,并设置阈值告警自动暂停实验。3.7 - 实验控制与其他
ADwin、NI-FPGA、Red Pitaya 等 FPGA 控制器与辅助设备驱动,覆盖从纳秒级实时时序到通用开关逻辑的全谱实验控制需求。
概述
FPGA 控制器和辅助设备是实验自动化的重要组成——从纳秒级实时时序到继电器开关,Quatm 提供统一的控制接口。目前已支持 ADwin、NI-FPGA、Red Pitaya 等多个品牌。
ADwin
概述
ADwin 是 Jaeger Computergesteuerte Messtechnik 公司的实时控制器系列,基于 FPGA/DSP 架构,独立于 PC 操作系统执行实时任务。
⚙️
ADwin
Gold II / Pro II
| 通信 | PCI / USB |
| 处理器 | DSP + FPGA |
| 时序精度 | 纳秒级 |
| 模拟输入 | 16-bit |
| 数字 I/O | TTL (5V) |
| 内存 | 32 MB DRAM |
运行 ADbasic 编译的实时进程,与 Quatm 通过共享内存或寄存器读写通信。典型应用包括激光冷却时序、MOT 磁场开关和光子计数采集。
驱动模块:ADwin
工作原理
PC (Quatm) ADwin (实时)
┌──────────┐ PCI/USB ┌──────────────┐
│ experiment│ ←──────────→ │ ADbasic 进程 │
│ .py │ Par/Data │ 纳秒时序 + 采集 │
└──────────┘ └──────────────┘
Quatm 实验脚本通过 ADwin 驱动读写参数和数据数组,与 ADwin 上运行的 ADbasic 进程交互。时序关键部分在 ADwin 硬件上执行,Python 侧负责参数设置和结果读取。
初始化
from quatm.drivers.adwin import ADwin
# 连接 ADwin(PCI 总线)
adw = ADwin(device_number=1)
# 加载并启动 ADbasic 进程
adw.load_process("experiment_sequence.TB1")
adw.start_process()
# 设置实验参数
adw.set_par(1, 100_000) # Par_1 = 100 µs 冷却时间
adw.set_par(2, 50) # Par_2 = 50 次循环
adw.set_par(3, 10_000) # Par_3 = 10 ms 探测时间
# 启动一次实验序列(ADbasic 中通过事件触发)
adw.trigger()
# 读取采集数据
photons = adw.get_data(1, data_length=1000) # 从 Data_1 读取光子计数
关键方法
| 方法 | 说明 |
|---|
load_process(binary_path) | 加载 ADbasic 编译的二进制进程 |
start_process() | 启动已加载的进程 |
stop_process() | 停止运行中的进程 |
set_par(index, value) | 写入整型参数(1–80) |
set_fpar(index, value) | 写入浮点参数(1–80) |
get_par(index) | 读取整型参数 |
get_data(index, data_length) | 读取数据数组(1–200) |
set_data(index, values) | 写入数据数组 |
trigger() | 发送软件触发事件 |
典型 ADbasic 进程结构
' ADbasic 代码片段 — 实验时序
Init:
Par_1 = 100000 ' 冷却时间 (µs)
Par_2 = 50 ' 循环次数
Event:
For i = 1 To Par_2
P2_DAC(1, 5000) ' 设置 AOM 功率
P2_DAC(2, 800) ' 设置磁场
' ... 等待、采集、切换 ...
Next i
设备配置
"adwin": {
"type": "local",
"module": "quatm.drivers.adwin",
"class": "ADwin",
"arguments": {"device_number": 1},
}
开发调试
开发阶段可使用 ADwinDummy 模拟器(无硬件)测试实验逻辑。模拟器提供相同的 API 接口但不执行实际硬件操作,适合在办公电脑上开发和验证实验脚本。Exception:
quatm.drivers.adwin.client module
Class:
quatm.drivers.adwin.units module
NI-FPGA LabVIEW FPGA 模块化仪器
⚙️
PXIe-78xxR / PCIe-78xxR 系列
NI-FPGA
| 通信 | NI-FPGA Interface Python API |
| FPGA | Xilinx Kintex/Virtex |
| 数字 I/O | 最高 1 Gb/s |
| 模拟 I/O | 最高 3.2 GS/s |
| 编程 | LabVIEW FPGA + Python 运行时控制 |
通过
nifpga Python API 在运行时控制 LabVIEW FPGA 位流。适合需要极高吞吐量和确定性时序的自定义数字信号处理。
驱动模块:ni_fpga
from quatm.drivers.NI.ni_fpga import NIFPGA
fpga = NIFPGA(resource_name="RIO0", bitfile="custom_logic.lvbitx")
fpga.run()
fpga.write_control("pulse_width", 100) # ns
fpga.write_control("trigger_delay", 50)
fpga.read_indicator("photon_count")
与 ADwin 的对比
| 特性 | ADwin | NI-FPGA |
|---|
| 编程语言 | ADbasic (类 BASIC) | LabVIEW FPGA (图形化) |
| Python 控制 | 参数/数据数组读写 | 控件/指示器读写 |
| 适用场景 | 纳秒时序、光子计数 | 高速 DSP、自定义协议 |
| 硬件生态 | 独立控制器 | NI PXI 平台集成 |
Conrad 继电器板
⚙️
Relay Board
Conrad
| 通信 | 串口 (19200 baud) |
| 通道 | 8 继电器/板 |
| 支持 | 菊花链扩展 |
经济型多通道继电器控制器,适合磁阱线圈极性切换、设备供电开关和激光快门控制。
驱动模块:RelayBoard
from quatm.drivers.Conrad.base import RelayBoard
rb = RelayBoard(conn="/dev/ttyUSB0", start_addr=0)
rb.set_relay(relay=0, state=True)
rb.set_relay(relay=3, state=False)
rb.write_byte(0b10101010)
开发调试
开发阶段可使用 ADwinDummy 模拟器测试实验逻辑,无需连接实际硬件。4 - 数据与分析
Quatm 数据管理架构、实时监控、图像处理与分析工具的完整文档。
quatm.analysis package
Submodules
quatm.analysis.bright_spots 模块
检测图像中的亮斑(如离子)。使用 skimage.features.blob_dog 进行亮斑检测。
输入:
输出:
- 图像流:
np.array:包含亮斑位置掩码dict:检测到的亮斑数量 N_bright
- Datastream:
bloblist: the locations of the bright spotsdict: N_bright the number of bright spots detected
Properties:
imagestreams ([str]): Input streamsmax_sigma (float): Parameter from blob_dogthreshold (float): Parameter from blob_dog
Hint:
将输出流用作图像监视器中的掩码。
class quatm.analysis.bright_spots.BrightSpots(name)
Bases: object
run()
quatm.analysis.bright_spots.main_run(name)
quatm.analysis.crashit module
模拟分析程序崩溃场景以测试容错。
quatm.analysis.gaussfit module
对数据集执行一维高斯拟合。
Fit function:
[ f(x) = \frac{A_0}{\sqrt{2\pi}\sigma} e^{\frac{-(x-\mu)^2}{2\sigma^2}} + C ]
Output:
输出为包含拟合结果字典和拟合曲线二维数组的数据流。
Fit parameter nomenclature:
A0: ( A_0 )sigma: ( \sigma )pos: ( \mu )offset: ( C )height: ( \frac{A_0}{\sqrt{2\pi}\sigma} )
In older versions some of the parameters were named differently:
area: ( A_0 )height: ( A_0 )
Format of the input datastream:
The fit can handle two types of data:
- 1D
numpy.array (data.ndim == 1): the y-values are taken from the data, and the x values are a linear spaced index from 0 to ny. - 2D
numpy.array:
Properties controlling the program:
datastreams: list of input datastreams
class quatm.analysis.gaussfit.Gaussfit(name)
Bases: object
run()
quatm.analysis.gaussfit.main_run(name)
quatm.analysis.imagedivider module
Handle absorption imaging data. According to Beer’s Law, light travelling through an atomic cloud is attenuated by:
[ I = I_0 e^{-n(x,y)\sigma} ]
where ( I_0 ) is the intensity before the cloud (Imaging beam without atoms) and ( I ) is the attenuated intensity (Image with atoms), ( \sigma ) is the absorption cross section, and ( n(x,y) ) is the column density of the atoms. Transforming this equation allows us to determine the column density of the atoms from the import two images.
[ n(x,y) = \frac{ln(I_0/I)}{\sigma} ]
where ( \sigma ) is given by:
[ N_{atoms} = \frac{ln(I_0/I)}{\frac{\sigma_0}{1+(2\Delta/\Gamma)^2}} ]
where effscale rescales the value from atoms per ( m^2 ) to atoms per pixel.
[ \sigma_0 = \frac{\hbar\omega\Gamma}{2 I_{sat}/C_2} ]
where ( \omega ) is the angular frequency of the laser, ( \Gamma ) is the linewidth of the transition in angular frequencies, ( I_{sat} ) is the saturation intensity in SI units, and ( C_2 ) is the Clebsh-Gordon coefficient for the dipole transition.
Properties:
imagestreams: input datastreamsimageWithAtoms: index of the image containing the image data with atoms (0 being the first image in each run)imageWithoutAtoms: the image containing the image without atomsabsorptionCrossection: defaults to ( \sigma_0 )detuning_rad: detuning of the imaging laser from resonancelinewidth_rad: linewidth of the transition
class quatm.analysis.imagedivider.ImageSlice(name)
Bases: object
C_2 = 0.6666666666666666gamma = 36897377.3978814h_bar = 1.0545716346179718e-34isat = 25.4omega = 2807325165778985.0
run()
sig0 = 1.4335384024006802e-13
quatm.analysis.imagedivider.main_run(name)
quatm.analysis.imageselector module
使用 imgindex 从流中每次选取单张图像。
Input:
Output:
- Imagestream: the selected image
Properties:
imagestreams: ([str]) input image streamsSelectedImage: (int) the number of the image to be selected counting from 0.
class quatm.analysis.imageselector.ImageSlice(name)
Bases: object
run()
quatm.analysis.imageselector.main_run(name)
quatm.analysis.imageslice module
从图像流中创建线性轨迹和子区域。
![Imageslice]
Input:
Output:
colsum_ (datastream): summation in the direction of columns (use only row that lie within the region of interest. (gray area))rowsum_ (datastream): summation along rowscolsumcut_, rowsumcut_: use only data within the region of interestcolint, rowint, colintcut, rowintcut: Perform numeric integration (which means the sum is multiplied by the metric pixel size)- (imagestream): send the image within the ROI
Properties:
cutimg: (bool) send the image inside the ROIcolsum: send the column sumrowsum: send the sum over the rowscolsumcut, rowsumcut: (bool) send the corresponding data restricted to the region of interestcolint, rowint, colintcut, rowintcut: similar to the sum version but taking into account the scale. Therefore these versions can be treated as integrals
class quatm.analysis.imageslice.ImageSlice(name)
Bases: object
run()
quatm.analysis.imageslice.main_run(name)
4.1 - 2D 高斯拟合
astropy 实时二维高斯拟合——检测 ROI,输出参数和轮廓线。
概述
TwoDGaussFit 对图像流执行实时二维高斯拟合(Gaussian2D + Const2D),输出中心坐标、宽度和振幅。
from quatm.analysis.TwoDGaussFit import TwoDGaussFit
fitter = TwoDGaussFit(props=props, image_stream="andor")
fitter.run()
# 输出: x0, y0, sigma_x, sigma_y, amplitude, offset
4.2 - 1D 高斯拟合
Cython 加速一维高斯拟合——输出位置、宽度、幅度和 3D 峰值密度。
概述
Gaussfit 对一维数据流执行 Cython 优化高斯拟合。输出 A0、sigma、pos、offset、waist 和三维峰值密度。
from quatm.analysis.gaussfit import Gaussfit
gf = Gaussfit(props=props, data_stream="pmt")
gf.run()
# 输出: pos, sigma, A0, offset, waist, peak_density_3D
4.3 - 表格组件
table_parameterItem 和 table_parameter 类扩展了 pyqtgraph 参数树的功能,使其能够以表格形式显示和编辑 NumPy 记录数组。通过注册自定义参数类型,这些类可以轻松地集成到现有的 pyqtgraph 应用程序中,提供灵活且强大的数据编辑功能。
概述
这个代码定义了一个用于编辑 NumPy 记录数组的自定义参数类型 table_parameter,并在 PyQt 环境中实现了一个表格小部件,用于显示和编辑记录数组的数据。
table_parameterItem 类
table_parameterItem 继承自 pTypes.WidgetParameterItem,是一个用于编辑 NumPy 记录数组的表格小部件。
主要方法
__init__(self, param, depth):
makeWidget(self):
- 创建一个表格小部件 (
QTableWidget)。 - 获取初始值,并根据值的结构设置表格的行列数和标题。
- 连接信号和槽,以便在表格内容更改时触发相应的操作。
value(self):
- 获取表格当前的值,并返回一个 NumPy 记录数组。
- 尝试从表格中读取数据并填充到 NumPy 数组中,如果失败则返回初始值。
setValue(self, arr):
- 设置表格的值。
- 根据提供的 NumPy 数组填充表格的每个单元格。
valueChanged(self, param, val, force=False):
- 当参数值更改时调用,更新表格的显示内容。
- 断开信号连接,更新表格值后重新连接信号,确保信号处理不会重复触发。
table_parameter 类
table_parameter 继承自 Parameter,用于管理和存储表格参数项的值。
主要方法
registerParameterType 函数
使用 registerParameterType 函数将自定义参数类型 table_parameter 注册到参数树中,使其可以在参数树中使用。
使用场景
- 该代码主要用于需要在图形用户界面中编辑和显示 NumPy 记录数组的场景。
- 适用于科学计算、数据分析等需要处理大量数据的应用程序。
- 提供了一种灵活的方式在 Qt 应用程序中集成和使用表格参数项。
4.4 - 数据管理分析模块
这段代码实现了一个复杂的图形用户界面应用,用于科学实验数据的管理、分析和可视化。
主要功能和组件介绍
1. 数据存储管理 (H5StorageDataMgr)
- 数据存储:通过HDF5文件格式保存和加载实验数据。
- 数据订阅:管理数据流和图像流的订阅,确保在实验过程中捕获和存储所有相关数据。
- 定时保存:定期自动保存数据,以防数据丢失。
- 数据清理:在需要时清理当前加载的数据。
2. 图形用户界面 (H5StorageGui)
- 标签页管理:包含选择数据、绘制数据和事件数据三个主要标签页,每个标签页对应不同的功能模块。
- 数据选择和加载:允许用户选择数据文件和加载特定实验数据进行分析。
- 保存和加载按钮:提供保存当前数据和从文件加载数据的功能。
3. 数据绘图 (H5DataPlotter)
- 数据可视化:使用pyqtgraph和matplotlib库将实验数据绘制成图表,支持多种图形格式(如折线图、散点图等)。
- 坐标轴选择:允许用户选择和配置x轴和y轴的数据源和显示方式。
- 定期更新:定期检查并更新绘图数据,以确保图表反映最新的实验数据。
- 数据导出:将绘制的图表导出为PDF或PNG格式文件。
4. 事件数据处理 (EventPlotter)
- 事件分析:处理和绘制事件数据,例如离子存活率或损失率的概率或频率。
- 自定义事件函数:用户可以选择和配置不同的事件函数来分析数据。
- 保存事件数据:将事件分析结果保存为CSV或pickle文件,方便后续数据处理和分析。
交互功能和用户体验
- 交互式控件:使用Qt提供交互式控件,如按钮、复选框、组合框和文本输入框,使用户能够方便地进行数据选择、配置和操作。
- 动态更新:用户界面和绘图能够实时更新,确保用户始终看到最新的实验数据。
- 多样化导出选项:支持将图表导出为不同格式,便于用户在报告和演示中使用。
辅助功能
- 错误和信息处理:通过日志和弹窗显示错误信息和操作反馈,帮助用户及时了解系统状态和操作结果。
- 数据过滤和处理:支持数据过滤和自定义处理函数,提供灵活的数据分析手段。
这个应用程序特别适合用于需要频繁收集、分析和可视化实验数据的科研环境。通过集成多种数据处理和绘图功能,它能够显著提高实验数据管理和分析的效率。
导入模块
代码导入了必要的模块和库,用于数据处理、图形绘制、图形用户界面(GUI)开发等。主要模块包括:
- NumPy 和 SciPy:用于科学计算和数据处理。
- matplotlib 和 pyqtgraph:用于图形绘制。
- Qt:用于构建图形用户界面。
- pandas:用于数据处理和分析。
全局变量和常量定义
定义了一些物理常数,例如m_Li(锂原子质量)、m_Ba(钡原子质量)和kB(玻尔兹曼常数),这些常量用于后续的计算和拟合。
H5StorageGui 类
这是主界面类,继承自 BWidget。它包含了三个主要组件:
- H5StorageDataMgr:用于数据管理和存储。
- H5DataPlotter:用于数据的绘制和展示。
- EventPlotter:用于处理和绘制事件数据。
__init__ 方法
- 初始化三个主要组件并将它们添加到标签页中。
- 设置保存、加载和清除按钮,并配置定时器以定期保存数据。
H5StorageDataMgr 类
该类用于管理HDF5数据存储和加载。主要功能包括:
- 选择数据存储目录。
- 管理数据订阅。
- 存储和加载数据文件。
- 定期保存和更新数据。
__init__ 方法
- 初始化数据管理器,设置数据存储路径和文件名。
- 添加数据订阅编辑器,用于管理数据流和图像流。
- 配置定时器以定期更新数据。
数据存储和加载
savetoFile 方法:将当前数据保存到HDF5文件中。loadFromFile 方法:从HDF5文件中加载数据。clear 方法:清除当前数据。
H5DataPlotter 类
用于绘制和展示数据。主要功能包括:
- 设置坐标轴选择器。
- 管理不同数据源。
- 定期检查和更新数据。
- 导出图形到PDF或PNG格式。
__init__ 方法
- 初始化绘图窗口和数据选择器。
- 设置坐标轴选择器和导出按钮。
- 配置定时器以定期检查数据更新。
数据更新和绘制
checkForNewData 方法:定期检查是否有新数据,并更新绘图。updateDatasources 方法:更新数据源列表。update 方法:更新坐标轴选择器和绘图数据。gen_export_plot 方法:生成用于导出的图形。exportpng 和 exportpdf 方法:导出图形到PNG和PDF格式。
EventPlotter 类
继承自 H5DataPlotter,用于处理和绘制事件数据。主要功能包括:
- 设置和管理事件数据的坐标轴选择器。
- 处理事件数据的计算和拟合。
- 导出事件数据的图形。
__init__ 方法
- 初始化事件绘图窗口和数据选择器。
- 配置定时器以定期检查事件数据更新。
数据更新和绘制
updateData 方法:更新事件数据。get_event_data 方法:获取和处理事件数据。addFitting 和 addBinning 方法:添加数据拟合和分箱处理。save_events 方法:保存事件数据。
继承自 YAxisWidget,用于事件数据的Y轴管理。主要功能包括:
updateData 方法
- 更新Y轴数据和事件函数参数。
- 处理和应用数据过滤器。
用于设置事件函数和参数。主要功能包括:
主要功能总结
- 数据管理:通过
H5StorageDataMgr 类实现,支持数据的存储、加载和定期保存。 - 数据绘制:通过
H5DataPlotter 类和 EventPlotter 类实现,支持数据和事件数据的绘制、更新和导出。 - 图形用户界面:通过 Qt 构建,支持用户交互、数据选择和配置。
4.5 - 数据流订阅管理
这段代码实现了能够动态订阅、显示和更新数据流的数据可视化界面。
PlotDataEditor 类
PlotDataEditor 类是一个管理数据或图像流订阅的小部件。它包含以下关键部分:
- 初始化方法:接收属性对象和数据字典,设置布局,创建一个下拉菜单用于选择数据流。
- 更新数据流列表:清空并重新填充下拉菜单中的数据流。
- 更新数据通道:根据用户选择更新数据通道。
ScrollPlot 类继承自 pg.PlotItem,用于显示滚动数据图表。它的主要功能包括:
- 初始化方法:设置图表属性,初始化数据缓冲区,创建数据流客户端和属性对象。
- 初始化数据缓冲区:创建一个用于存储数据的数组。
- 数据馈送方法:将新数据块添加到数据数组中。
- 更新图表:根据数据数组更新图表显示。
- 设置新数据:从数据流接收新数据,并调用数据馈送和图表更新方法。
- 数据选择对话框:弹出一个对话框供用户选择数据流。
- 订阅窗口:管理数据流订阅的对话框。
- 配置窗口:弹出一个对话框供用户配置图表属性。
ScrollWindow 类继承自 BMainWindow,是应用程序的主窗口。它包含以下关键部分:
- 初始化方法:创建主窗口和图形窗口,初始化多个
ScrollPlot 实例,并添加到窗口中。 - 初始化图表:循环创建并添加
ScrollPlot 实例。 - 数据馈送方法:将新数据块添加到数据数组中。
- 更新图表:根据数据数组更新所有图表的显示。
- 更新方法:定期调用数据馈送和图表更新方法。
main 函数
main 函数是程序的入口点,执行以下步骤:
- 创建一个
QApplication 实例。 - 创建并显示
ScrollWindow 实例。 - 启动应用程序事件循环。
主要功能和工作流程
- 数据订阅和显示:
PlotDataEditor 管理数据流订阅,ScrollPlot 显示订阅的数据,并定期更新图表。 - 用户交互:用户可以通过图形界面选择和配置数据流,更新图表显示。
- 定期更新:通过定时器定期检查和更新数据,实现滚动显示效果。
4.6 - 数据流订阅管理
SubscriptionEditor 类提供了一个直观的界面,用户可以方便地管理数据和图像流的订阅。通过灵活的属性管理和用户交互,确保用户能够轻松地添加、删除和更新订阅,从而适应不断变化的需求和数据源。
概述
这个代码定义了一个订阅编辑器 SubscriptionEditor 类,主要用于管理程序对数据流或图像流的订阅。在 PyQt 环境中,通过一个简单的图形用户界面,用户可以查看和修改当前的订阅列表。
SubscriptionEditor 类
SubscriptionEditor 类继承自 QWidget,用于管理数据或图像流的订阅。
主要方法和属性
使用场景
- 该代码主要用于需要管理数据或图像流订阅的应用程序。
- 适用于需要动态调整订阅数据源的场景,例如科学计算、数据采集和监控等应用。
- 提供了一种用户友好的方式,通过图形界面查看和修改订阅列表。
4.7 - 图表动态显示器
这个脚本可以用于需要实时监控和展示数据流的应用程序,例如科学实验、工业监控和实时数据分析等。用户可以通过 GUI 配置数据流的订阅和绘图属性,实时查看和分析数据变化。
概述
这个脚本使用 Qt 和 pyqtgraph 库创建了一个实时更新的绘图工具。工具订阅数据流并动态更新图表显示。核心组件包括 UpdatingPlot 类和 LivePlot 类。
主要组件
UpdatingPlot 类
UpdatingPlot 类继承自 pg.PlotItem,用于创建能够订阅数据流并实时更新的图表。
主要方法和属性
初始化方法 __init__:
- 初始化数据客户端和属性客户端。
- 设置绘图区域的上下文菜单,添加订阅和配置选项。
- 启动定时器,每隔 10 毫秒调用
setnewData 方法更新数据。
setnewData 方法:
- 检查数据流中是否有新数据。
- 处理新数据并更新曲线显示。
subscribe_window 方法:
- 创建并显示一个对话框,允许用户配置数据流订阅。
- 更新订阅配置。
updateConfiguration 方法:
- 更新数据流订阅。
- 清除旧的绘图,并为每个数据流创建新的曲线。
configureWindow 方法:
- 创建并显示一个对话框,允许用户配置绘图属性。
- 更新绘图配置。
LivePlot 类
LivePlot 类继承自 QtWidgets.QWidget,用于创建包含 UpdatingPlot 图表的窗口。
主要方法和属性
初始化方法 __init__:
- 初始化窗口布局,添加
UpdatingPlot 图表。 - 设置窗口大小提示和显示配置。
sizeHint 方法:
setSizeHint 方法:
使用场景
这个脚本可以用于需要实时监控和展示数据流的应用程序,例如科学实验、工业监控和实时数据分析等。用户可以通过 GUI 配置数据流的订阅和绘图属性,实时查看和分析数据变化。
示例
下面是一个示例,展示如何使用 UpdatingPlot 和 LivePlot 类:
def main(name):
app = QtGui.QApplication([])
camWin = LivePlot(name)
camWin.show()
sys.exit(app.exec())
if __name__ == '__main__':
main('dummyname')
在这个示例中,main 函数创建一个 LivePlot 窗口并启动应用程序事件循环。运行此代码将显示一个包含实时更新图表的窗口。
关键功能
- 实时数据更新:使用定时器定期检查数据流中的新数据并更新图表显示。
- 动态配置:通过 GUI 配置数据流订阅和绘图属性,支持用户自定义设置。
- 可扩展性:基于 Qt 和 pyqtgraph 构建,易于扩展和集成其他功能。
4.8 - 图形ROI管理器
这个类适用于需要在图形界面中显示和管理多个兴趣区域的应用程序,特别是那些需要通过中心属性类来通信和管理属性的场景。例如,科学实验中的图像处理和分析,实时监控中的区域选择和管理等。
概述
这个脚本定义了一个名为 zmq_ROI 的类,它继承自 pyqtgraph.ROI,并通过 Quatm 的中心属性类 Properties 来通信其属性。该类主要用于在图形界面中显示和管理一个兴趣区域(ROI),并实时更新其属性。
主要组件
zmq_ROI 类
zmq_ROI 类继承自 pg.ROI,用于创建一个可以通过属性类 Properties 来管理和通信其属性的兴趣区域。
属性和方法
使用场景
这个类适用于需要在图形界面中显示和管理多个兴趣区域的应用程序,特别是那些需要通过中心属性类来通信和管理属性的场景。例如,科学实验中的图像处理和分析,实时监控中的区域选择和管理等。
示例
下面是一个使用 zmq_ROI 类的示例:
import pyqtgraph as pg
from PyQt6.QtWidgets import QApplication
import sys
def main():
app = QApplication(sys.argv)
win = pg.GraphicsLayoutWidget(show=True)
view = win.addViewBox()
view.setAspectLocked(True)
img = pg.ImageItem()
view.addItem(img)
# 创建并添加 zmq_ROI 实例
roi = zmq_ROI('exampleROI', pos=[50, 50], size=[100, 100])
view.addItem(roi)
# 显示窗口
win.show()
sys.exit(app.exec())
if __name__ == '__main__':
main()
在这个示例中,main 函数创建一个包含图像和兴趣区域(ROI)的窗口。运行此代码将显示一个窗口,其中包含一个可拖动和调整大小的 ROI。
关键功能
- 属性通信:通过
Properties 类管理和通信 ROI 的属性,使得多个 ROI 可以共享和实时更新其属性。 - 定时更新:通过定时器定期检查和更新 ROI 的位置和大小。
- 图形界面集成:集成到
pyqtgraph 中,提供强大的图形界面支持。
4.9 - 偏斜高斯拟合
Cython 偏态正态拟合——额外输出偏度和众数。
概述
GaussfitSkewed 使用偏态正态分布对一维数据进行 Cython 优化拟合,输出偏度参数 a 和众数 mode。
from quatm.analysis.gaussfit_skewed import GaussfitSkewed
gs = GaussfitSkewed(props=props, data_stream="tof")
gs.run()
# 输出: pos, sigma, A0, offset, a (偏度), mode (众数)
4.10 - 属性编辑器
这个代码实现了一个属性编辑器 GUI,用于管理和编辑属性树。
ScalableGroup 类
ScalableGroup 类是一个自定义的参数组,用于自动生成两个子参数,这两个子参数始终互为倒数。
初始化方法
__init__ 方法:- 初始化参数组,并设置组类型、添加文本和添加列表。
- 调用基类
GroupParameter 的初始化方法。
添加新参数方法
addNew 方法:- 根据参数类型(字符串、浮点数或整数)添加新的子参数。
- 设置新子参数的初始值和属性。
TreeEdit 类
TreeEdit 类用于从 Properties 类中提取信息并根据树视图进行格式化。
初始化方法
__init__ 方法:- 初始化类实例,设置父类和子树路径。
- 从属性对象中提取条目,并创建参数组。
- 连接参数组的状态变化信号到
change 方法。
解析字典方法
_parsedict 方法:- 将字典格式化为可以在树视图中查看的格式。
- 根据不同的数据类型(整数、布尔、字符串、浮点数、列表、字典)创建相应的参数条目。
更改参数方法
change 方法:- 处理树视图中的任何更改。
- 根据参数类型和变化的数据更新属性对象。
更新方法
_update 和 _update_whole_tree 方法:- 更新树视图中选定条目或整个树视图。
- 根据属性对象中的数据重新生成参数条目。
PropEdit 类
PropEdit 类是属性编辑器的主要 GUI 窗口,用于管理属性树。
初始化方法
__init__ 方法:- 初始化类实例,设置子树路径。
- 创建布局和参数树视图。
- 添加更新、删除、保存和加载按钮,并连接相应的槽函数。
更新、保存、加载和删除方法
update 方法:save 方法:load 方法:delete 方法:
PropSelector 类
PropSelector 类是属性选择器 GUI,用于从属性树中选择和管理键列表。
初始化方法
__init__ 方法:- 初始化类实例,设置子树路径。
- 创建布局和参数树视图。
- 添加选择和删除按钮,并连接相应的槽函数。
选择和删除方法
select 方法:updateKeys 方法:delete_marked 方法:
主函数
main 方法:- 创建应用程序实例,设置窗口图标,创建并显示主窗口。
- 进入应用程序事件循环。
代码逻辑
- 导入所需模块:导入标准库、第三方库和项目特定模块。
- 定义 ScalableGroup 类:自定义参数组,用于自动生成子参数。
- 定义 TreeEdit 类:从
Properties 类中提取信息并根据树视图进行格式化。 - 定义 PropEdit 类:属性编辑器的主要 GUI 窗口。
- 定义 PropSelector 类:属性选择器 GUI,用于选择和管理键列表。
- 定义主函数:创建并启动应用程序。
- 运行主程序:检查是否在交互模式下运行,如果不是,则运行主程序。
运行流程概述
- 启动应用程序:创建
QApplication 实例,并设置窗口图标。 - 创建 PropEdit 实例:初始化属性编辑器,并显示主窗口。
- 管理属性树:通过参数树视图和按钮与属性对象交互,更新、保存、加载和删除属性条目。
- 进入事件循环:应用程序进入事件循环,等待用户交互。
4.11 - 属性更新管理器
该代码实现了一个用于检查属性更新的 GUI 应用程序。通过 PropertiesChecker 类,用户可以定期检查属性是否更新,并在属性未更新时发出警报,使用了 Qt 的多种控件和信号槽机制来实现用户交互和数据更新。
PropertiesChecker 类
PropertiesChecker 类用于检查属性是否定期更新,并在属性未更新时发出警报。以下是该类的详细分析:
初始化方法
__init__ 方法:- 初始化类实例,并设置初始状态或配置。
- 创建两个
Properties 对象,用于检查属性的更新。 - 初始化一个
QSoundEffect 对象,用于播放警报声音。 - 调用
run 方法开始检查属性更新。
警报窗口方法
open_alert_window 方法:- 创建并显示一个警报对话框,当属性未更新时调用。
- 播放警报声音。
属性检查方法
run 方法:- 使用一个无限循环定期检查属性是否更新。
- 每隔一段时间设置和检查属性值。
- 如果属性值未更新,则打印错误信息并显示警报窗口;否则,打印属性仍在更新的信息。
主函数
main 方法:- 创建应用程序实例,设置窗口图标,创建并显示主窗口。
- 进入应用程序事件循环。
代码逻辑
- 导入所需模块:导入标准库、第三方库和项目特定模块。
- 定义 PropertiesChecker 类:包含初始化方法、警报窗口方法和属性检查方法。
- 定义主函数:创建并启动应用程序。
- 运行主程序:检查是否在交互模式下运行,如果不是,则运行主程序。
运行流程概述
- 启动应用程序:创建
QApplication 实例,并设置窗口图标。 - 创建 PropertiesChecker 实例:初始化属性检查器,并开始检查属性更新。
- 检查属性更新:在
run 方法中,定期设置和检查属性值,并在属性未更新时发出警报。 - 显示警报窗口:当属性未更新时,显示警报对话框并播放警报声音。
- 进入事件循环:应用程序进入事件循环,等待用户交互。
4.12 - 数据流图片流监视器
该代码使用 Qt 库构建了一个 GUI 应用,用于显示和编辑数据流、图像数据和相机属性。代码主要定义了一些自定义窗口小部件(widgets),包括参数显示框、图像数据框和相机属性框,并实现了上下文菜单、订阅管理和数据选择对话框等功能。
概要
该应用用于显示和编辑数据流、图像及相机属性,包含参数显示框、图像数据框和相机属性框等组件。
主要类和功能
ParameterBox
该类继承自 BFrame,用于显示单个参数。它包括以下功能:
- 初始化:设置框架样式、获取属性和数据流名称,并初始化显示标签。
- 数据更新:使用定时器定期从数据流中获取新数据,并更新显示值。
- 上下文菜单:右键单击时显示上下文菜单,包括订阅管理和数据选择功能。
- 订阅管理:打开订阅管理窗口以编辑订阅。
- 数据选择:打开数据选择对话框以选择要显示的数据。
ImageDataBox
该类继承自 BFrame,用于显示图像数据。它包括以下功能:
- 初始化:设置框架样式、获取属性,并初始化显示框。
- 上下文菜单:右键单击时显示上下文菜单,包括订阅管理功能。
- 订阅管理:打开订阅管理窗口以编辑订阅。
- 数据更新:通过设置新数据的方法更新显示框内容。
CamPropsBox
该类继承自 ImageDataBox,用于显示相机属性。它包括以下功能:
- 初始化:获取相机名称和属性子树,并设置定时器定期更新数据。
- 上下文菜单:右键单击时显示上下文菜单,包括属性和相机选择功能。
- 属性窗口:打开属性选择窗口以编辑相机属性。
- 相机选择窗口:打开相机选择窗口以选择要显示的相机。
- 数据更新:根据当前相机和配置获取并显示相机属性。
DataBox
这是一个简单的用于显示标签和值的框,继承自 QWidget。它主要包括:
- 初始化:设置布局,添加标签和值的显示。
- 大小提示:返回组件的建议大小。
详细描述
ParameterBox 类
__init__ 方法:
- 初始化框架样式和宽度。
- 获取参数属性和数据流名称。
- 初始化显示标签和值标签,并设置布局。
- 设置上下文菜单策略和定时器。
setNewData 方法:
openMenu 方法:
dataSelectDialog 方法:
subscribe_window 方法:
updateSubscription 方法:
updateDataLists 方法:
ImageDataBox 类
__init__ 方法:
- 初始化框架样式和宽度。
- 获取属性并初始化显示框。
- 设置上下文菜单策略。
openMenu 方法:
subscribe_window 方法:
dataSelectDialog 方法:
setNewData 方法:
CamPropsBox 类
__init__ 方法:
openMenu 方法:
props_window 方法:
cams_window 方法:
setNewData 方法:
DataBox 类
运行流程
- 创建
ParameterBox、ImageDataBox 和 CamPropsBox 的实例。 - 定时器触发,调用
setNewData 方法从数据流中获取新数据并更新显示。 - 用户右键单击组件,显示上下文菜单。
- 用户选择订阅管理或数据选择选项,打开相应的对话框。
- 用户在对话框中编辑订阅或选择数据,更新组件显示。
4.13 - 数据流图片流监视器
该代码实现了一个基于 Qt 的应用程序,用于订阅和显示数据流或图像流。应用程序提供了一个可滚动的绘图窗口,用户可以通过多种交互方式来管理数据源和配置绘图属性。
功能介绍
该代码实现了一个基于 Qt 的应用程序,用于订阅和显示数据流或图像流。应用程序提供了一个可滚动的绘图窗口,用户可以通过多种交互方式来管理数据源和配置绘图属性。
代码结构
- 导入必要的模块和库
- 定义
PlotDataEditor 类 - 定义
ScrollPlot 类 - 定义
ScrollWindow 类 - 定义脚本入口
类:PlotDataEditor
功能介绍
PlotDataEditor 类是一个小部件,用于管理程序对数据流或图像流的订阅。
方法
__init__:初始化 PlotDataEditor 对象,设置布局和控件,更新可用流的列表。- 参数:
props (属性对象)、data (初始数据字典)、category (流的类别)、parent (父对象)、preselect (预选择的流名称)。
update_streamlist:更新流选择框中的可用流列表。updateDatachannel:更新选定的数据通道,并在父对象中设置相关属性。
功能介绍
ScrollPlot 类是一个绘图部件,用于订阅数据流并实时更新显示。
方法
__init__:初始化 ScrollPlot 对象,设置属性,订阅数据流,并配置绘图选项。- 参数:
name (绘图的名称)、parent (父对象)。
initDataBuffer:初始化数据缓冲区,用于存储接收的数据。feedData:将新数据块添加到数据缓冲区,并计算运行平均值(如果启用)。clearPlot:清除绘图中的数据。updatePlot:更新绘图,显示新的数据点和运行平均值。updatePlotContent:更新绘图内容,删除当前内容以便显示新的数据。updateTitle:更新绘图的标题。updateSubscription:更新数据流的订阅,切换到新的数据流。updateDataLists:更新数据列表和相关属性。setnewData:接收新数据并更新绘图。setScatterplot:设置散点图的绘图选项。deletePlot:删除绘图并从属性中移除相关配置。dataSelectDialog:打开数据选择对话框,用于选择新的数据源。subscribe_window:打开订阅窗口,用于管理数据流的订阅。configureWindow:打开配置窗口,用于修改绘图属性。running_mean:静态方法,计算运行平均值。
功能介绍
ScrollWindow 类是主窗口类,包含多个滚动绘图,用于显示和管理数据流。
方法
__init__:初始化 ScrollWindow 对象,设置窗口和工具栏,并恢复之前保存的绘图。- 参数:
name (窗口的名称)、parent (父对象)、n_plots (初始绘图数量)。
init_toolbar:初始化工具栏,添加操作按钮。updateAllSubscriptions:更新所有绘图的订阅。restorePlots:恢复之前保存的绘图。addPlot:添加新绘图到窗口中。
脚本入口
功能介绍
脚本入口用于创建应用程序实例,显示主窗口并启动应用事件循环。
主要步骤
- 创建
QApplication 实例。 - 创建
ScrollWindow 实例。 - 显示主窗口。
- 启动应用事件循环。
总结
该代码实现了一个完整的应用程序,用于管理和显示数据流。通过定义多个类和方法,用户可以方便地订阅数据流、配置绘图属性以及实时更新绘图。
4.14 - 数据实时监视器
该模块是一个用于在科学实验中实时绘制和分析数据的控件。该控件集成了 pyqtgraph 库,用于高效地绘制和更新图表。
方法:__init__
功能:初始化 DataPlotterWidget 对象,设置属性和布局,启动定时器用于实时数据更新。
参数:
axis_name:轴名称prop_root:属性根路径datastream_names:数据流名称列表n_yaxis:Y轴数量parent:父对象
主要步骤:
- 初始化属性和数据管理器 (
DataSummary)。 - 创建并设置网格布局 (
QGridLayout)。 - 调用
buildPlotWidget 方法创建绘图小部件。 - 调用
buildDataSelector 方法创建数据选择器。 - 启动定时器,每20毫秒调用
checkForNewData 方法检查新数据。
功能:创建并设置绘图窗口和右键菜单。
主要步骤:
- 创建
pyqtgraph 图形布局窗口 (GraphicsLayoutWidget)。 - 在窗口中添加绘图项 (
PlotItem)。 - 添加右键菜单选项,通过
QAction 类实现。
方法:buildDataSelector
功能:创建并设置数据选择器界面。
主要步骤:
- 创建数据选择器 (
DataSelectorItem)。 - 创建 X轴选择器 (
XAxisWidget) 和多个 Y轴选择器 (YAxisWidgetHelper)。 - 设置网格布局 (
QGridLayout) 来管理数据选择器控件的排列和显示。 - 隐藏配置界面,默认不显示。
方法:toggleConfig
功能:切换配置界面的显示和隐藏状态。
主要步骤:
- 根据
configVisible 变量的值显示或隐藏配置界面。 - 更新
configVisible 变量的值。
方法:setDataSource
功能:设置或更改数据源。
参数:text - 数据源名称。
方法:checkForNewData
功能:检查是否有新数据,并更新图表。
主要步骤:
- 调用
recvData 方法从数据源接收数据。 - 如果有新数据,更新
lastUpdate 时间戳。 - 调用
updateDatasources 和 update 方法更新数据源和图表。
方法:updateDatasources
功能:检查并更新数据源列表。
主要步骤:
- 创建一个新的数据源列表
sourcelist。 - 如果数据源列表有变化,更新数据选择器中的数据源列表。
方法:update
功能:更新数据选择器中的可选数据字段,并更新图表。
主要步骤:
- 从当前数据集中选择所有代表浮点数或整数的键。
- 更新数据选择器中的可选键列表。
- 调用
_updatePlotData 方法更新图表。
方法:_updatePlotData
功能:更新图表数据。
主要步骤:
- 获取当前选中的 X轴字段。
- 调用每个 Y轴选择器的
updateData 方法更新数据。
方法:exportpdf
功能:导出图表为 PDF 文件。
主要步骤:
- 创建一个
matplotlib 图表对象。 - 调用每个 Y轴选择器的
plotmpl 方法将数据绘制到图表上。 - 保存图表为 PDF 文件并使用查看器打开。
方法:clear
功能:清除数据。
主要步骤:
- 调用数据管理器的
clear 方法清除数据。 - 移除所有图表项。
方法:plotData
功能:在图表中绘制数据。
参数:
主要步骤:
- 创建一个
pg.PlotDataItem 对象并设置绘图样式。 - 将数据添加到图表项中并绘制。
方法:__init__
功能:初始化 YAxisWidgetHelper 对象,设置属性和布局。
参数:
label:标签plotter:数据绘图器对象props:属性对象plotitem:绘图项对象parent:父对象
主要步骤:
- 初始化 Y轴选择器,创建并设置布局和过滤器组合框。
- 创建并配置绘图项。
方法:updateYscale
功能:更新 Y轴缩放比例。
参数:text - 缩放比例文本。
功能:创建上下文菜单。
参数:position - 菜单位置。
主要步骤:
- 创建菜单项用于添加过滤、分箱和拟合。
- 显示菜单并处理用户选择。
方法:_initPlot
功能:初始化绘图项。
主要步骤:
- 创建并配置
pg.PlotDataItem 对象。 - 添加到绘图项中。
功能:配置绘图样式。
主要步骤:
- 设置绘图项的绘图样式。
- 如果有后续数据处理步骤,递归调用其配置方法。
方法:addBinning
功能:添加分箱处理步骤。
主要步骤:
- 如果当前没有后续处理步骤,创建
BinningWidget 并添加到布局中。 - 更新数据。
方法:addFitting
功能:添加拟合处理步骤。
主要步骤:
- 如果当前没有后续处理步骤,创建
FittingWidget 并添加到布局中。 - 更新数据。
方法:reevaluateData
功能:重新评估数据。
主要步骤:
- 获取当前 X轴字段。
- 调用
updateData 方法更新数据。
方法:updateData
功能:更新数据。
参数:xtext - X轴字段。
主要步骤:
- 获取当前 Y轴字段。
- 从数据源获取数据并应用过滤器。
- 更新图表中的数据。
方法:plotmpl
功能:在 matplotlib 图表中绘制数据。
参数:
主要步骤:
- 将数据绘制到
matplotlib 图表轴中。 - 如果有后续数据处理步骤,递归调用其绘图方法。
4.15 - 图像查看器
该代码实现了一个基于 Qt 的图像查看器应用,名为 ImageWindow。这个应用包含一个中心图像显示区域和两个用于显示线图的侧边栏。用户可以通过该应用实时查看和分析图像数据,并调整图像的显示参数。
功能介绍
该代码实现了一个基于 Qt 的图像查看器应用,名为 ImageWindow。这个应用包含一个中心图像显示区域和两个用于显示线图的侧边栏。用户可以通过该应用实时查看和分析图像数据,并调整图像的显示参数。
代码结构
- 导入必要的模块和库
- 定义
ImageWindow 类 - 定义主函数
main - 定义脚本入口
类:ImageWindow
简短功能介绍
ImageWindow 类是一个主窗口,包含一个图像显示区域和两个用于显示线图的侧边栏。此外,它还提供了一些工具栏和面板,用于调整图像显示参数和查看图像信息。
方法:__init__
功能:初始化 ImageWindow 对象,并设置窗口名称和父对象。
参数:
name:窗口名称。parent:父对象(可选)。
主要步骤:
- 调用父类
BMainWindow 的构造函数。 - 初始化属性字段。
- 调用
initUI 方法初始化用户界面。
方法:initUI
功能:初始化用户界面,包括状态栏、图像显示区域和停靠窗口。
主要步骤:
- 显示状态栏信息。
- 创建图像显示区域并设置为中心部件。
- 创建停靠窗口(Dock Widgets)。
功能:创建用于显示线图、直方图和图像信息的停靠窗口。
主要步骤:
- 创建顶部的线图停靠窗口并添加到主窗口。
- 创建右侧的线图停靠窗口并添加到主窗口。
- 创建左侧的直方图停靠窗口并添加到主窗口。
- 创建顶部的图像信息停靠窗口并添加到主窗口。
方法:update_min_max
功能:更新图像显示的最小和最大亮度值。
主要步骤:
- 获取直方图的最小和最大亮度值。
- 更新属性中的最小和最大亮度值。
方法:get_tick_position
功能:获取直方图梯度的刻度位置。
主要步骤:
- 获取直方图梯度的所有刻度位置。
- 计算并返回归一化的刻度位置。
方法:closeEvent
功能:在窗口关闭事件中保存当前图像的显示范围和刻度位置。
主要步骤:
- 获取图像显示的 x 和 y 范围。
- 保存显示范围和刻度位置到属性中。
- 调用父类的关闭事件处理方法。
主函数:main
功能:创建并显示 ImageWindow 实例。
参数:
主要步骤:
- 创建
QApplication 实例。 - 创建
ImageWindow 实例并设置窗口图标。 - 显示窗口。
- 启动应用事件循环。
脚本入口
功能:解析命令行参数并调用 main 函数。
主要步骤:
- 检查是否以交互模式运行。
- 解析命令行参数获取程序实例名称。
- 调用
main 函数。
4.16 - 图像监视器
该代码实现了一个基于 Qt 的图像监控器应用,名为 ImageDisplay。这个应用能够接收并实时显示图像数据,并提供多种工具来调整和保存图像。用户可以通过该应用监控图像流,应用滤波器,调整显示参数,并保存当前图像。
功能介绍
该代码实现了一个名为ImageDisplay的图像监控器应用,。这个应用能够接收并实时显示图像数据,并提供多种工具来调整和保存图像。用户可以通过该应用监控图像流,应用滤波器,调整显示参数,并保存当前图像。
代码结构
- 导入必要的模块和库
- 定义
ImageDisplay 类 - 定义主函数
main - 定义脚本入口
类:ImageDisplay
简短功能介绍
ImageDisplay 类是一个自更新的图像显示窗口,能够实时接收和显示图像数据,并提供多种工具和设置来调整图像显示效果。
方法:__init__
功能:初始化 ImageDisplay 对象,并设置窗口名称和父对象。
参数:
name:窗口名称。parent:父对象(可选)。
主要步骤:
- 初始化属性字段。
- 创建并设置图像显示区域。
- 订阅图像流和掩码流。
- 设置图像显示和掩码显示的初始数据。
- 创建图像显示窗口和控件布局。
- 启动定时器以定期更新图像。
方法:sizeHint
功能:返回窗口的推荐大小。
返回值:QtCore.QSize(800, 700)
方法:noise_filter
功能:应用噪声滤波器处理图像。
参数:
主要步骤:
- 将图像数据转换为绝对值。
- 应用双边滤波器和中值滤波器进行去噪处理。
- 返回处理后的图像。
方法:spot_detector
功能:检测图像中的亮点。
参数:
主要步骤:
- 将图像二值化,阈值为
_spot_level。
方法:update_image
功能:定期更新图像显示。
主要步骤:
- 检查是否有新图像数据。
- 接收并处理新图像数据。
- 更新图像显示。
- 更新图像掩码。
方法:update_mask
功能:更新图像掩码。
主要步骤:
- 检查是否有新掩码数据。
- 接收并处理新掩码数据。
- 更新掩码显示。
方法:saveCurrentImage
功能:保存当前显示的图像为 PNG 文件。
主要步骤:
- 构建文件路径,包含当前时间戳。
- 保存图像数据到文件。
方法:subscribe_window
功能:打开订阅窗口,用于选择图像流。
主要步骤:
- 打开订阅窗口。
- 更新图像流订阅。
方法:subscribe_mask
功能:打开订阅窗口,用于选择掩码流。
主要步骤:
- 打开订阅窗口。
- 更新掩码流订阅。
方法:_subscribe_win
功能:创建并显示订阅窗口。
参数:
主要步骤:
- 创建对话框。
- 添加订阅编辑器到对话框。
- 显示对话框。
功能:打开配置窗口,用于调整图像显示参数。
主要步骤:
- 创建对话框。
- 添加属性编辑器到对话框。
- 显示对话框。
主函数:main
功能:创建并显示 ImageDisplay 实例。
参数:
主要步骤:
- 创建
QApplication 实例。 - 创建
ImageDisplay 实例并设置窗口图标。 - 显示窗口。
- 启动应用事件循环。
脚本入口
功能:解析命令行参数并调用 main 函数。
主要步骤:
- 检查是否以交互模式运行。
- 解析命令行参数获取程序实例名称。
- 调用
main 函数。
4.17 - 吸收成像 (imagedivider)
Beer-Lambert 柱密度计算——有原子/无原子/背景三帧成像。
概述
ImageDivider 根据 Beer-Lambert 定律处理吸收成像数据,利用有原子图像(with-atoms)、无原子图像(without-atoms)和背景图像(background)计算二维原子柱密度。
from quatm.analysis.imagedivider import ImageDivider
div = ImageDivider(props=props, image_stream="absorption")
div.run()
# 输出: 柱密度图像 (atoms/m²)
4.18 - 离子检测系列
BrightSpots / IonState / SingleIonPresent——离子存在性与量子态判别。
模块概览
| 类 | 方法 | 用途 |
|---|
BrightSpots (ion_blob) | cv2.connectedComponents | 阈值+连通分量分析 |
BrightSpots (bright_spots) | skimage.blob_dog | DoG 斑点检测 |
SingleIonPresent | 多标准综合 | 计数+位置+宽度+偏度 |
IonState | 四图序列 | 离子态分类(存活/热/搁置/丢失) |
IonState 判别流程
图像 1 (无离子) → 图像 2 (有离子) → 图像 3 (存活?) → 图像 4 (搁置?)
↓
存活 / 热离子 / 搁置 / 丢失 / 无离子
from quatm.analysis.ion_state import IonState
detector = IonState(props=props)
detector.run()
# 输出: state = "survived" | "hot" | "shelved" | "lost" | "no_ion"
4.19 - 图像处理工具
热像素过滤/检测、图像旋转、切片、选择器和背景减法。
模块列表
| 模块 | 类 | 功能 |
|---|
hot_pixel_filter | HotFilter | 邻域比较→热像素均值替换 |
hot_pixel_finder | HotFilter | 检测异常像素坐标 |
rotate_image | ImageRotate | imutils 旋转+坐标补偿 |
imageslice | ImageSlice | ROI 行/列求和与积分 |
imageselector | ImageSlice | 多图中按 index 选择 |
substract_image | ImageSubstract | 背景图像减法 |
from quatm.analysis.hot_pixel_filter import HotFilter
filter = HotFilter(props=props, image_stream="andor")
filter.run()
5 - GUI 组件
Quatm 基于 Qt 的图形界面——12 个核心组件,覆盖实验浏览、参数编辑、任务调度、数据可视化和设备监控。
Quatm 提供了完整的可视化图形界面。以下是所有 GUI 组件的详细文档。
组件索引
| 组件 | 文档 | 简介 |
|---|
| 🔍 实验浏览器 | → | 主窗口——多文档界面、文件树、队列和代码编辑 |
| ⚙️ 实验管理器 | → | 核心执行引擎——测量→序列→单次运行的生命周期管理 |
| 📋 实验队列 | → | 任务队列表格——优先级排序、状态跟踪、暂停/终止/重启 |
| 📝 准备台 | → | 参数暂存、复制、循环构建后推入队列 |
| 🔁 循环器 | → | 条件循环——根据测量结果自动切换实验组 |
| 🪟 实验窗口 | → | 单实验控制——动态参数界面 + 代码编辑 |
| 🎛️ 参数系统 | → | FloatBox/BoolBox/ComboBox——参数 GUI 控件体系 |
| 🌲 属性编辑器 | → | 基于 pyqtgraph ParameterTree 的键值浏览 |
| 📈 实时绘图 | → | 实时一维数据流——多曲线、缩放、订阅管理 |
| 💡 LED指示灯 | → | 红/绿 LED 状态灯——径向渐变动画 |
| 🧱 GUI基础类 | → | BWidget/BMainWindow/BFrame,窗口持久化 |
| 📷 图像监视器 | → | 实时科学图像显示——ROI、滤波、子类定制 |
| 📊 分析管理器 | → | 分析进程的启动/停止/状态监控 |
| 📡 数据流监视器 | → | 多类型数据流——曲线/图像/消息三合一监视 |
| ✏️ 序列编辑器 | → | QScintilla 代码编辑 + 时序图可视化 |
| ⚡ 进程管理器 | → | 五类后台进程(Server/Driver/GUI/Viewer/Monitor) |
| 🔌 设备管理器 | → | PyVISA 设备发现与驱动绑定 |
| 💾 数据存储 | → | HDF5 存储/加载 + 定时自动保存 |
| ⏱️ 自动保存 | → | 定时保存时间表编辑器 |
| 📈 实时滚动图 | → | 实时滚动折线/散点图——运行平均 + 多曲线 |
| 📐 数据模型 | → | DictSyncModel——字典/列表到 Qt 表格映射 |
| 🔧 实验辅助 | → | ODT 对准 + 电场补偿 + 压电镜 + Verdi 对准 |
| 🎚️ 参数框 | → | 紧凑型标签-数值实时参数显示 |
| 🗂️ 可折叠组件 | → | 手风琴式可折叠面板对话框 |
| 🧩 实验参数面板 | → | 实验参数控制面板 |
| 🔌 DAC 控制器 | → | FPGA DAC 手动设置工具 |
| 🧵 后台工作线程 | → | QRunnable 后台工作线程——信号驱动 |
| ⏱️ 时序浏览器 | → | 实验时序可视化(DAC+TTL 图表) |
| 📊 滚动波形窗口 | → | 多通道实时滚动波形显示 |
| 📡 订阅编辑器 | → | 数据/图像流订阅管理 |
| 📋 表格参数 | → | 实验参数树表格编辑节点 |
| 🎯 远程 ROI | → | 可远程同步的 ROI 组件 |
| 🖼️ 图像查看器 | → | 科学图像查看器(线剖面+LUT) |
| 🔔 属性检查器 | → | 属性健康轮询+异常告警 |
| 📐 辅助绘图工具 | → | 通用测量数据绘图(多Y轴+滤波+拟合) |
架构总览
┌─────────────────────────────────────────────────────────┐
│ Browser (主窗口) │
├──────────────┬──────────────────┬───────────────────────┤
│ FileSelector │ ExperimentWindow│ CodeEditor │
│ (实验目录树) │ (参数界面+提交) │ (代码编辑) │
├──────────────┴──────────────────┴───────────────────────┤
│ ExperimentQ ← PrepStation ← Looper │
│ (任务队列) (准备台) (条件循环) │
├─────────────────────────────────────────────────────────┤
│ ExperimentManager (执行引擎) │
└─────────────────────────────────────────────────────────┘
启动 GUI
python -m quatm.GUI.browser
参数编辑器
quatm.GUI.parameterbox 和 quatm.GUI.property_editor — 可视化调整实验参数:
- 自动根据
NumberValue / BoolValue / StringCombo 生成对应控件 - 支持参数分组(
group 参数) - 扫描标签页支持设置参数扫描范围
序列编辑器
quatm.GUI.editor_sequencer — 可视化编排实验时序:
- 拖拽式 TTL 脉冲和模拟输出编辑
- 支持并行和串行任务
- 微秒级定时精度
图像监视器
quatm.GUI.image_monitor.ImageMonitor — 实时显示科学图像:
数据流监视器
quatm.GUI.streammonitor — 实时数据流可视化:
- 动态绘图 (
updating_plot) - 表格参数显示 (
table_parameter) - 数据订阅管理 (
subscription_editor)
辅助工具
| 工具 | 文件 | 功能 |
|---|
| 实验助手 | experiment_helper.py | 多功能实验助手面板 |
| ODT 对准 | odt_alignment_helper.py | 光偶极阱对准辅助 |
| 电场补偿 | comp_helper.py | 杂散场补偿辅助 |
| 自动保存 | auto_save_editor.py | 实验数据自动保存配置 |
| H5 存储 | h5storage.py | HDF5 文件浏览与管理 |
启动 GUI
python -m quatm.GUI.browser
5.1 - 实验浏览器 (Browser)
Quatm 主窗口——实验浏览、文件选择、队列管理和多窗口工作区。
概述
Browser 是 Quatm 的主应用程序窗口,基于 QMainWindow + QMdiArea 多文档界面架构。它将文件浏览、实验队列、任务管理和代码编辑整合在统一工作区中。
架构
┌─────────────┬──────────────────────────────────┐
│ FileSelector │ QMdiArea (子窗口区) │
│ (实验目录树) │ ┌──────────┬─────────────────┐ │
│ │ │Experiment │ CodeEditor │ │
├─────────────┤ │Window │ (实验代码编辑) │ │
│ ExperimentQ │ └──────────┴─────────────────┘ │
│ (任务队列) │ │
├─────────────┤ │
│ PrepStation │ │
│ (准备台) │ │
├─────────────┤ │
│ Looper │ │
│ (循环器) │ │
└─────────────┴──────────────────────────────────┘
核心组件
| 组件 | 类 | 描述 |
|---|
| 实验目录 | FileSelector | experiments/ 目录树,双击打开实验文件 |
| 任务队列 | ExperimentQ | 表格化任务列表,支持暂停/终止/删除 |
| 任务执行 | ExperimentManager | 从队列取出任务并调度执行 |
| 准备台 | PrepStation | 编辑和预览实验参数后推入队列 |
| 循环器 | Looper | 根据测量结果条件循环运行 |
| 代码编辑 | CodeEditor | 基于 QScintilla 的 Python 代码编辑器 |
启动
from quatm.GUI.browser import Browser
browser = Browser()
browser.show()
或从命令行:
python -m quatm.GUI.browser
窗口持久化
Browser 继承 QMainWindow,通过 QSettings 自动保存和恢复:
- 主窗口几何位置和大小
- 已打开的
ExperimentWindow 子窗口及其文件路径
5.2 - 实验管理器 (ExperimentManager)
核心实验执行引擎——管理测量→序列→单次运行的生命周期。
概述
ExperimentManager 是 Quatm 的核心执行引擎,负责从 ExperimentQ 队列中取出任务并按测量 → 序列 → 单次运行的层级结构调度执行。
执行流程
queue_fn (持续轮询)
└─→ start_measurement
└─→ _sequence_run (循环扫描/序列)
└─→ _runloop (单次实验运行)
└─→ end_measurement
关键方法
| 方法 | 说明 |
|---|
queue_fn() | 持续轮询 ExperimentQ,取出就绪任务 |
start_measurement(task) | 初始化测量上下文 |
_sequence_run(task) | 处理扫描参数循环 |
_runloop(task) | 执行单次实验运行 |
end_measurement(task) | 结束测量,保存数据 |
线程模型
from quatm.GUI.experiment_manager import ExperimentManager
manager = ExperimentManager(browser)
# 内部使用 browser_workers.Worker 线程池
# 任务在独立线程中执行,不阻塞 GUI
5.3 - 实验队列 (ExperimentQ)
任务队列表格——维护实验任务的优先级排序、状态跟踪和生命周期管理。
概述
ExperimentQ 是 QGroupBox 内嵌的表格部件,通过 ScheduleModel 管理实验任务的优先级排序和状态显示。
任务状态
| 状态 | 含义 |
|---|
queued | 等待执行 |
running | 正在执行 |
paused | 已暂停 |
finished | 执行完成 |
error | 执行出错 |
操作
| 按钮 | 功能 |
|---|
| ⏸ Pause | 暂停队列自动执行 |
| ⏹ Stop | 终止当前任务 |
| 🔄 Restart | 重新运行已完成/出错的任务 |
| 🗑 Delete | 从队列中移除任务 |
数据模型
# expDict 结构
expDict = {
task_id: {
"name": "Rabi 扫描",
"status": "queued",
"priority": 1,
"repeat": 10,
...
}
}
任务按 priority(越小越优先)→ task_id(FIFO)排序。
5.4 - 准备台 (PrepStation)
实验参数暂存与编辑区——在推入队列前预览、复制和微调任务。
概述
PrepStation 是 QGroupBox 内的表格部件,通过 PrepModel 暂存实验任务。在推入 ExperimentQ 之前,可以在此处预览参数、复制任务和构建实验循环。
功能
| 操作 | 说明 |
|---|
| 📋 暂存 | 从 ExperimentWindow 提交任务到此待编辑 |
| 📝 复制 | 复制任务生成变体(如改变扫描参数) |
| 🔁 构建循环 | 将多个任务组合为 Looper 循环组 |
| 💾 保存/加载 | 将参数集保存为 JSON 文件 |
| ➡️ 推入队列 | 确认后推入 ExperimentQ 排队执行 |
数据模型
PrepModel 继承 DictSyncModel,自动同步表格编辑到内部字典。表格列包括任务名、参数、重复次数和状态。
5.5 - 循环器 (Looper)
条件循环执行器——根据测量结果自动决定是否重复或切换实验。
概述
Looper 是 QGroupBox 内的条件循环控制面板。它管理实验任务组,根据每次运行的测量结果自动判断是否继续循环或切换下一组任务。
核心逻辑
开始循环
└─→ 运行当前组任务
└─→ 读取测量结果
├─ 满足条件 → 继续循环当前组
└─ 不满足 → 切换到下一组
组件
| 组件 | 说明 |
|---|
groupDict | 循环组字典,每组合多个任务 |
DataManager | 管理测量结果数据 |
LoopManager | 控制循环逻辑和条件判断 |
AutoSaveEditor | 自动 HDF5 保存计划配置 |
LedIndicator | 循环运行状态指示灯 |
用法
# 在 PrepStation 中构建循环组后推入 Looper
looper.add_group("优化组", tasks=[task1, task2])
looper.add_group("测量组", tasks=[task3])
looper.set_condition("优化组.信号 > 阈值 → 切换到测量组")
looper.start()
5.6 - 实验窗口 (ExperimentWindow)
单实验控制窗口——动态构建参数界面并管理提交、扫描和参数持久化。
概述
ExperimentWindow 是每个实验文件的控制面板。它通过 importlib 动态加载实验模块,自动解析 NumberValue / BoolValue / StringCombo 参数并生成对应的控件界面。
功能
| 功能 | 说明 |
|---|
| 🔍 动态加载 | importlib 导入实验模块,反射获取参数定义 |
| 🎛️ 参数界面 | 自动生成 FloatBox / BoolBox / ComboBox 控件 |
| 📤 提交队列 | 将当前参数集提交到 ExperimentQ |
| 🔁 扫描参数 | 设置参数扫描范围和步进 |
| 💾 保存/加载 | JSON 格式的参数集读写 |
| ✏️ 代码编辑 | 内嵌 CodeEditor 查看和修改实验代码 |
参数解析
class MyExperiment(Experiment):
cooling_time = NumberValue(100, unit='µs', minval=1, maxval=10000)
readout_mode = BoolValue(False)
qubit_select = StringCombo(['q0', 'q1', 'q2'])
这些定义自动生成带标签、单位和范围的控件。
5.7 - 参数系统
FloatBox/BoolBox/ComboBox——实验中参数参数的 GUI 控件体系。
概述
Quatm 提供了一套完整的参数 GUI 控件,将实验参数定义自动映射为可视化控件。所有控件继承 BasicManager 基类,通过 Properties 与实验运行时双向同步。
控件类体系
BasicManager (QFrame)
├── FloatManager → FloatBox (QDoubleSpinBox)
├── BoolManager → BoolBox (QCheckBox)
└── ComboManager → ComboBox (QComboBox)
FloatBox — 数值参数
from quatm.GUI.arg_boxes import FloatBox
box = FloatBox(
props=props,
value=NumberValue(100, unit='µs', minval=1, maxval=10000),
parent=parent,
display_multiplier=1,
step=10,
ndecimals=1,
)
| 参数 | 说明 |
|---|
value | NumberValue 实例,含默认值、单位、范围 |
display_multiplier | 显示倍率(如 µs→ms 转换) |
step | 步进值 |
ndecimals | 小数位数 |
BoolBox — 布尔开关
from quatm.GUI.arg_boxes import BoolBox
box = BoolBox(props=props, value=BoolValue(False), parent=parent)
ComboBox — 下拉选择
from quatm.GUI.arg_boxes import ComboBox
box = ComboBox(
props=props,
value=StringCombo(['q0', 'q1', 'q2']),
parent=parent,
)
数据流
用户调整控件 → Properties 更新 → 实验脚本读取 self.param
实验脚本写入 self.param → Properties 通知 → GUI 控件刷新
5.8 - 属性编辑器 (PropertyEditor)
基于 pyqtgraph ParameterTree 的属性查看与编辑工具。
概述
PropEdit 是基于 pyqtgraph.parametertree.ParameterTree 的属性编辑器。它将 Properties 中的键值数据可视化为可展开的树状视图,支持动态类型识别和搜索过滤。
组件
| 组件 | 类 | 说明 |
|---|
| 属性编辑器 | PropEdit | BWidget + ParameterTree,支持搜索和刷新 |
| 属性选择器 | PropSelector | QComboBox,下拉列出属性键 |
| 树生成器 | TreeEdit | 将 Properties 字典转换为 Parameter 节点 |
| 可扩展组 | ScalableGroup | pyqtgraph GroupParameter 子类,支持动态添加子参数 |
用法
from quatm.GUI.property_editor import PropEdit
editor = PropEdit(name="设备状态", parent=parent, props=props)
# 自动生成树状视图,双击节点编辑值
特性
- 动态类型:自动识别 int/float/str/bool 并匹配对应控件
- 搜索过滤:内置搜索框快速定位参数
- 实时同步:修改自动写回
Properties
5.9 - 实时绘图 (UpdatingPlot)
基于 pyqtgraph 的实时一维数据流可视化。
概述
UpdatingPlot 继承 pyqtgraph.PlotItem,通过 DataClient 订阅数据流实现实时绘图。每 10ms 检查新数据,自动添加/移除曲线。
数据流
数据源 → ZeroMQ PUB → DataClient 订阅
↓
UpdatingPlot (10ms 轮询)
↓
pyqtgraph 渲染
用法
from quatm.GUI.updating_plot import UpdatingPlot
plot = UpdatingPlot(name="PMT 信号")
# 右键菜单 → 订阅编辑器 → 选择数据流
交互功能
| 功能 | 说明 |
|---|
| 📊 多曲线 | 自动管理多条数据曲线 |
| 🔍 缩放平移 | pyqtgraph 内置交互 |
| 📡 订阅管理 | SubscriptionEditor 选择数据源 |
| ⚙️ 属性配置 | PropEdit 调整显示参数 |
5.10 - LED 指示灯 (LedIndicator)
红/绿双色 LED 状态指示灯——带径向渐变和颜色切换动画。
概述
LedIndicator 继承 QAbstractButton,渲染一个带径向渐变效果的圆形 LED 灯。支持绿色/红色切换,常用于显示设备连接状态、实验运行状态等。
颜色模式
| 方法 | 颜色 | 说明 |
|---|
set_green() | 🟢 | 通常表示正常/就绪 |
set_red() | 🔴 | 通常表示错误/警告 |
视觉效果
- 径向渐变:中心高亮 → 边缘暗色,模拟真实 LED 发光
- 开关状态:On 时亮色,Off 时暗色(模拟熄灭状态)
用法
from quatm.GUI.qled import LedIndicator
led = LedIndicator(parent=parent)
led.set_green() # 设备就绪
led.set_red() # 设备异常
5.11 - GUI 基础类 (quatmQt)
BWidget、BMainWindow、BFrame——带几何持久化和属性通信的 Qt 基类。
概述
quatmQt.py 定义了所有 Quatm GUI 组件的基类,提供窗口几何持久化和 Properties 通信总线。
类层次
QWidget → BWidget
QFrame → BFrame
QMainWindow → BMainWindow
from quatm.GUI.quatmQt import BWidget
widget = BWidget(name="my_widget", parent=None)
| 特性 | 说明 |
|---|
| 几何持久化 | 通过 QSettings 自动保存/恢复位置和大小 |
| 属性通信 | 每个实例自动关联 Properties 实例 |
| 命名空间 | name 参数用于 QSettings 键和日志标识 |
BMainWindow — 主窗口基类
from quatm.GUI.quatmQt import BMainWindow
window = BMainWindow(name="MainWindow", parent=None)
window.setWindowTitle("Quatm")
除 BWidget 的全部特性外,还管理窗口标题和菜单栏。
CustomCompleter
from quatm.GUI.quatmQt import CustomCompleter
completer = CustomCompleter(items, parent)
completer.setFilterMode("contains") # 或 "begins"
带 contains / begins 匹配模式的下拉自动补全组件,用于搜索框和命令输入。
5.12 - 图像监视器 (ImageMonitor)
实时科学图像显示与分析——支持 ROI、滤波和子类定制。
概述
ImageMonitor 用于实时显示科学相机采集的图像数据。支持 ROI 区域选择、图像滤波和自定义显示逻辑。
功能
| 功能 | 说明 |
|---|
| 📷 实时显示 | 高速刷新科学图像 |
| 🔲 ROI 选择 | 矩形/自由形状感兴趣区域 |
| 🎚️ 滤波 | 高斯、中值等图像预处理 |
| 🧬 可扩展 | 子类化 ImageMonitor 定制显示逻辑 |
子类化示例
class FluorescenceMonitor(ImageMonitor):
def process_image(self, image):
# 自定义处理逻辑
return image - background
参见 数据与分析 中的图像查看器和监视器文档。
5.13 - 分析管理器 (AnalysisManager)
树形视图面板——管理分析进程的启动、停止与状态监控。
概述
TreeViewWidget 是管理分析进程的树形视图面板。它显示所有注册的分析模块,支持启动/停止单个进程、批量终止游离进程,以及实时状态监控。
功能
| 操作 | 说明 |
|---|
| ▶️ 启动 | 选中分析模块并启动对应进程 |
| ⏹ 停止 | 终止运行中的分析进程 |
| 🔄 状态刷新 | 实时更新各进程运行状态 |
| 🧹 清理 | 终止所有失去响应的游离进程 |
用法
from quatm.GUI.analysismanager import TreeViewWidget
mgr = TreeViewWidget(parent=parent)
mgr.addItem("ROI 分析", "roi_analysis")
mgr.startProcess("roi_analysis")
5.14 - 数据流监视器 (StreamMonitor)
多类型实时数据流监视——支持曲线、图像和文本消息三合一。
概述
StreamMonitor 通过 DataClient 订阅 ZeroMQ 数据流,实时显示三种类型的数据:一维数值曲线、二维科学图像和文本日志消息。
功能模式
| 模式 | 说明 |
|---|
| 📈 曲线 | 实时滚动的数值曲线(如 PMT 信号、温度) |
| 🖼️ 图像 | 二维科学图像流(如相机快照) |
| 📝 消息 | 文本日志或状态消息流 |
用法
from quatm.GUI.streammonitor import StreamMonitor
monitor = StreamMonitor(props=props, parent=parent)
# 右键 → 订阅编辑器 → 选择数据流
5.15 - 序列编辑器 (EditorSequencer)
代码编辑器 + 时序可视化——QScintilla 编辑 + 多通道状态图渲染。
概述
ExperimentSequencer 将 Python 实验代码与可视化时序图关联。CodeEditor 基于 QScintilla 提供语法高亮和自动补全;ExperimentSequencer.plotSequence() 将代码解析为 TTL/模拟通道的时序状态图。
组件
| 组件 | 说明 |
|---|
CodeEditor | QScintilla Python 编辑器,语法高亮 |
ExperimentParser | 解析实验代码提取时序指令 |
ExperimentSequencer | 渲染多通道状态图 |
用法
from quatm.GUI.editor_sequencer import ExperimentSequencer
seq = ExperimentSequencer(parent=parent)
seq.setCode(code_str)
seq.plotSequence() # 渲染时序图
5.16 - 进程管理器 (ProcessManager)
分布式进程面板——管理 Server/Driver/GUI/Viewer/Monitor 五类后台进程。
概述
ProcessManager 管理 Quatm 分布式架构中的所有后台进程。进程分为五类:Server(通信)、Driver(设备驱动)、GUI(图形界面)、Viewer(数据查看)和 Monitor(环境监控)。
进程类别
| 类别 | 说明 | 典型进程 |
|---|
| Server | ZeroMQ 通信服务 | CommandHub, DataHub |
| Driver | 设备驱动进程 | Andor, ADwin, Valon |
| GUI | 图形界面进程 | Browser, PrepStation |
| Viewer | 数据查看进程 | UpdatingPlot, StreamMonitor |
| Monitor | 环境监控进程 | 温度、真空监测 |
用法
from quatm.GUI.processmanager import ProcessManager
pm = ProcessManager(parent=parent)
pm.startProcess("Andor", "Driver")
pm.stopProcess("Andor")
5.17 - 设备管理器 (DeviceManager)
PyVISA 设备发现与驱动绑定——扫描、查询、选择 VISA 仪器。
概述
VISADeviceLister 通过 PyVISA 扫描系统中所有 VISA 仪器,支持设备识别查询和驱动文件绑定。它生成 DeviceInfo 对象,供 device_db.py 配置使用。
工作流
1. refresh_devices() → 扫描 VISA 总线
2. query_device_info() → 获取 *IDN? 标识
3. select_driver_file() → 绑定驱动类
4. add_device_to_selected() → 添加到 device_db
用法
from quatm.GUI.device_manager import VISADeviceLister
dl = VISADeviceLister(parent=parent)
dl.refresh_devices()
# 列表中显示所有 USB/GPIB/LAN VISA 设备
5.18 - 数据存储 (H5Storage)
HDF5 数据存储/加载/定时保存——含数据选择与绘图一体化面板。
概述
H5StorageGui 提供 HDF5 文件的读写、定时自动保存和数据可视化。支持多标签页数据浏览、binning 处理和 inline 绘图。
功能
| 功能 | 说明 |
|---|
| 💾 保存 | 实验数据写入 HDF5 文件 |
| 📂 加载 | 从 HDF5 文件恢复实验数据 |
| ⏱️ 定时保存 | 按时间表自动执行保存 |
| 📊 绘图 | 内嵌 BinningWidget 数据可视化 |
| 🧹 清空 | 清除已保存数据 |
用法
from quatm.GUI.h5storage import H5StorageGui
storage = H5StorageGui(props=props, parent=parent)
storage.savetoFile("data.h5")
storage.loadFromFile("data.h5")
5.19 - 实时滚动图 (LivePlot)
实时滚动折线/散点图——数据流订阅、运行平均与多曲线。
概述
ScrollPlot 提供基于 pyqtgraph 的实时滚动图表。支持折线图和散点图模式、运行平均滤波和多曲线叠加。
功能
| 功能 | 说明 |
|---|
| 📈 滚动显示 | 最新数据自动滚动到视野内 |
| 📊 散点图 | setScatterplot() 切换模式 |
| 🔢 运行平均 | running_mean 参数平滑数据 |
| 📡 订阅 | 通过 DataClient 订阅数据流 |
| 🎨 多曲线 | 同时显示多条数据曲线 |
用法
from quatm.GUI.live_plot import ScrollPlot
plot = ScrollPlot(name="实时信号", parent=parent)
plot.subscribe_window() # 选择数据源
plot.feedData(new_data)
5.20 - 自动保存编辑器 (AutoSaveEditor)
定时保存时间表编辑器——配置 HDF5 自动保存的频率和触发条件。
概述
AutoSaveEditor 是一个弹窗编辑器,用于配置实验数据的定时自动保存计划。设置保存间隔、触发条件和目标路径。
配置项
| 参数 | 说明 |
|---|
| 保存间隔 | 定时保存的时间间隔 |
| 触发条件 | 按时间或事件触发 |
| 目标路径 | HDF5 文件存储位置 |
用法
from quatm.GUI.auto_save_editor import AutoSaveEditor
editor = AutoSaveEditor(props=props, parent=parent)
editor.load_AutoSaveEditor_props()
editor.update_ticked([dt1, dt2, dt3])
5.21 - 实验辅助工具
ODT 对准、电场补偿、Verdi 对准——实验自动化校准与优化工具集。
概述
Quatm 将日常实验校准任务封装为 GUI 辅助工具,实现一键运行和自动优化。
ODT 对准辅助 — OdtAlignmentHelper
通过 AC 斯塔克位移信号自动优化光偶极阱的激光对准。
from quatm.GUI.odt_alignment_helper import OdtAlignmentHelper
helper = OdtAlignmentHelper(props=props, parent=parent)
helper.run_all() # 执行完整对准流程
杂散场补偿 — CompensationHelper
通过迭代测量各轴补偿电压,自动最小化杂散电场/磁场。
| 组件 | 说明 |
|---|
PlotWidget | 三轴补偿信号的实时绘图 |
ControlWidget | 补偿参数的手动微调面板 |
from quatm.GUI.comp_helper import CompensationHelper
comp = CompensationHelper(props=props, parent=parent)
Verdi 对准辅助 — VerdiAlignmentHelper
通过压电镜控制与 AC 斯塔克信号优化 Verdi 泵浦激光对准。
from quatm.GUI.verdi_alignment_helper import VerdiAlignmentHelper
verdi = VerdiAlignmentHelper(props=props, parent=parent)
压电镜控制 — PiezoMirrorControl
简单四方向面板,通过按钮或键盘(WASD)控制压电反射镜。
from quatm.GUI.piezo_mirror_controler import PiezoMirrorControl
mirror = PiezoMirrorControl(props=props, parent=parent)
# WASD 或点击方向键控制
多功能助手 — LittleHelper
聚合以上所有辅助工具的标签页主窗口。
python -m quatm.GUI.little_helper
5.22 - 数据模型 (Models)
DictSyncModel/ListSyncModel——将 Python 字典/列表自动映射为 Qt 表格。
概述
models.py 提供将 Python 数据结构映射为 Qt 表格模型的基类。ExperimentQ、PrepStation 和 Looper 的表格界面均基于此构建。
核心类
| 类 | 说明 |
|---|
_SyncSubstruct | 字典操作辅助,支持 append/insert/pop 回调 |
DictSyncModel | 字典→表格映射基类,支持排序、编辑、删除 |
ListSyncModel | 列表→表格映射基类 |
ScheduleModel | ExperimentQ 的排序模型(优先级+任务号) |
用法
from quatm.GUI.models import DictSyncModel
model = DictSyncModel(
headers=["名称", "值", "单位"],
dataNames=["name", "value", "unit"],
init={"name": "param1", "value": 100, "unit": "µs"}
)
5.23 - 可折叠组件 (Expandables)
CollapsibleDialog——可折叠/展开的手风琴式树形对话框。
概述
CollapsibleDialog 提供手风琴式可折叠面板对话框。每个面板包含一个展开/折叠按钮和自定义内容区域,适合配置界面和高级参数设置。
核心类
| 类 | 说明 |
|---|
SectionExpandButton | 三角形箭头按钮,点击展开/折叠 |
CollapsibleDialog | 树形对话框容器,add_section() 添加面板 |
用法
from quatm.GUI.theexpandables import CollapsibleDialog
dialog = CollapsibleDialog(title="高级设置", parent=parent)
dialog.add_section("相机设置", QLabel("曝光时间"))
dialog.add_section("触发设置", QLabel("触发源"))
5.24 - 参数框 (ParameterBox)
紧凑型实时参数显示——标签-数值对面板,订阅数据流自动刷新。
概述
ParameterBox 以紧凑的标签-数值对形式显示实时数据流中的单个参数。自动订阅数据流并更新显示,适合仪表盘式监控面板。
用法
from quatm.GUI.parameterbox import ParameterBox
box = ParameterBox(prop_key="pmt_signal", parent=parent)
box.subscribe_window() # 选择数据源
# 实时显示 PMT 信号值
5.25 - 实验参数面板 (SimpleDefaults)
DefaultExp + 参数管理器基类——从设备数据库自动构建实验属性 UI。
概述
simple_defaults.py 是 Quatm 参数 UI 的底层框架。DefaultExp 从 device_db.py 加载所有设备属性并按 group 键自动分组,BasicManager 系列类提供 Float/Int/Bool/String/Frequency 等多种参数输入控件。
类体系
DefaultExp (Experiment)
└── 自动加载 device_db 属性 → 分组
BasicManager (QFrame)
├── IntManager → QSpinBox
│ ├── FloatManager → QDoubleSpinBox
│ └── FrequencyManager → 频率输入
├── BoolManager → QCheckBox
└── ComboManager → QComboBox
DefaultExp
from quatm.GUI.simple_defaults import DefaultExp
exp = DefaultExp(props=props)
# 自动生成 group 分组:{"激光器": [param1, param2], "探测": [param3]}
BasicManager
所有参数控件的基类,自动从 Properties 同步值:
from quatm.GUI.simple_defaults import FloatManager
mgr = FloatManager(
props=props, parent=parent,
name="cooling_time",
unit="µs", minval=1, maxval=10000,
step=10, ndecimals=1, default_value=100,
)
| 参数 | 说明 |
|---|
name | 参数名,对应 Properties 键 |
unit | 显示单位(后缀) |
minval/maxval | 值范围 |
display_multiplier | 显示倍率 |
ndecimals | 小数位数 |
5.26 - ADwin DAC 控制 (SimpleAdwin)
ADwin 16 路 DAC 通道手动电压设置工具。
概述
DACvalues 和 DACsingle 提供 ADwin 系统 16 个 DAC 通道的手动电压设置界面,用于调试和校准时的独立通道控制。
组件
| 组件 | 说明 |
|---|
DACvalues | 16 通道批量电压设置面板 |
DACsingle | 单通道精细调节控件 |
用法
from quatm.GUI.simple_Adwin import DACvalues
dac = DACvalues(adwin_device=adw, parent=parent)
dac.set_channel(0, 5.0) # 通道 0 输出 5V
5.27 - 后台工作线程 (Workers)
Worker/WorkerSignals——通用 QRunnable 后台线程封装。
概述
browser_workers.py 和 helper_workers.py 提供基于 QRunnable 的通用后台工作线程封装,通过信号机制传递 finished/error/result/progress 状态。
信号
| 信号 | 说明 |
|---|
finished | 任务完成 |
error(tuple) | 异常信息 |
result(object) | 返回结果 |
progress(int) | 进度百分比 |
terminate | 请求终止(helper_workers 扩展) |
publish | 数据发布(helper_workers 扩展) |
用法
from quatm.GUI.browser_workers import Worker
worker = Worker(fn=my_long_task)
worker.signals.finished.connect(on_done)
worker.signals.error.connect(on_error)
QThreadPool.globalInstance().start(worker)
5.28 - 实验时间线 (Timeline)
ADwin 实验时序可视化——DAC 和 TTL 通道随时间变化的图表查看器。
概述
Timeline 加载 ADwin 记录的实验数据,将多通道 DAC 电压和 TTL 状态渲染为时间序列图表,方便调试和验证实验时序逻辑。
用法
from quatm.GUI.experiment_timeline import Timeline
tl = Timeline(data_file="experiment_trace.h5")
tl.show()
# 查看 DAC 通道 1-4 和 TTL 通道 1-8 的时序
5.29 - 滚动波形窗口 (ScrollWindow)
多通道实时滚动波形显示窗口,支持数据流订阅与动态更新。
概述
ScrollWindow 是 BMainWindow 子类的多通道实时波形显示器。内嵌 ScrollPlot 绘图组件和 PlotDataEditor 数据配置面板。
组件
| 组件 | 说明 |
|---|
ScrollWindow | 主窗口,管理多通道布局 |
ScrollPlot | pyqtgraph 实时滚动波形图 |
PlotDataEditor | 数据源选择和显示参数配置 |
用法
from quatm.GUI.scrollwindow import ScrollWindow
win = ScrollWindow(name="PMT 监测", parent=parent)
win.subscribe_channels(["ch1", "ch2"])
5.30 - 订阅编辑器 (SubscriptionEditor)
管理数据/图像流的订阅列表——添加、删除和浏览已订阅的数据源。
概述
SubscriptionEditor 提供一个对话框界面,列出所有可用的数据流和图像流,支持添加/删除订阅,是 UpdatingPlot、LivePlot 和 StreamMonitor 的数据源选择组件。
用法
from quatm.GUI.subscription_editor import SubscriptionEditor
editor = SubscriptionEditor(props=props, parent=parent)
editor.add_subscription("pmt_signal")
5.31 - 表格参数 (TableParameter)
基于 QTableWidget 的 numpy 结构化数组编辑器——用于 pyqtgraph 参数树。
概述
table_parameter 提供 pyqtgraph ParameterTree 的表格编辑节点。允许在参数树中直接编辑 numpy 结构化数组(如校准表、扫描序列)。
用法
from quatm.GUI.table_parameter import table_parameter
import numpy as np
dt = np.dtype([('freq', float), ('amp', float)])
param = table_parameter(name="扫描表", value=np.zeros(10, dtype=dt))
5.32 - 远程 ROI (zmq_ROI)
通过 Properties 发布位置/大小的可远程同步 ROI 组件。
概述
zmq_ROI 继承 pyqtgraph.ROI,将其位置和大小属性通过 ZeroMQ Properties 发布到网络,允许远程客户端同步查看和调整 ROI 区域。
用法
from quatm.GUI.zmq_ROI import zmq_ROI
roi = zmq_ROI(name="分析区域", props=props, parent=view)
# 拖动 ROI → Properties 自动更新 → 远程同步
5.33 - 图像查看器 (ImageWindow)
带侧边线剖面和直方图 LUT 的科学图像查看器主窗口。
概述
ImageWindow 是 BMainWindow 子类的科学图像查看器。支持多 dock 布局:侧边线剖面(x/y 方向强度分布)、直方图 LUT 调节和 ROI 分析。
功能
| 功能 | 说明 |
|---|
| 🖼️ 图像显示 | 高动态范围科学图像渲染 |
| 📏 线剖面 | 水平和垂直方向的强度剖面 |
| 🎨 LUT | 直方图调节伪彩色映射 |
| 🧩 多 dock | 灵活的子窗口布局 |
用法
from quatm.GUI.image_group import ImageWindow
win = ImageWindow(name="吸收成像", parent=parent)
win.set_image(absorption_image)
5.34 - 属性检查器 (PropertiesChecker)
轮询检测 Properties 系统状态——异常时弹窗+声音告警。
概述
PropertiesChecker 定时轮询 Quatm 的 Properties 通信总线,检测关键属性的健康状态。当检测到异常(如设备断连、数据超时)时弹出告警窗口并播放声音提示。
用法
from quatm.GUI.properties_checker import PropertiesChecker
checker = PropertiesChecker(props=props, interval_ms=5000)
checker.start_monitoring()
5.35 - 辅助绘图 (HelperPlotter)
通用测量数据绘图组件——多 Y 轴、滤波、拟合。
概述
DataPlotterWidget 从 DataSummary 获取测量数据并自动渲染图表。支持多 Y 轴叠加、数据滤波和曲线拟合。
功能
| 功能 | 说明 |
|---|
| 📊 自动绘图 | 从 DataSummary 提取测量数据 |
| 📈 多 Y 轴 | 不同量纲的数据叠加显示 |
| 🔢 滤波 | 运行平均、中值滤波 |
| 📐 拟合 | 线性/指数/高斯曲线拟合 |
用法
from quatm.GUI.helper_plotter import DataPlotterWidget
plotter = DataPlotterWidget(data_summary=summary, parent=parent)
plotter.plot_all()
6 - 通信层
Quatm 分布式通信与数据管理系统 — 基于 ZeroMQ 的进程间通信框架
概述
通信层是 Quatm 框架的通信骨干。所有进程间通信(设备驱动、分析脚本、GUI 面板之间的数据交互)都通过 ZeroMQ 的 发布/订阅(PUB/SUB) 模式进行,命令与控制则通过 RPC 实现。这确保了:
- 故障隔离:某个相机驱动崩溃不会导致整个实验中断
- 并行处理:图像处理与实验时序可同时运行
- 网络透明:各组件可以运行在不同的机器上
实验脚本
│
▼
[with realtime():] ──→ FPGA ──→ DAC/TTL 输出
│
▼
分析脚本 ◄── 图像/数据流 (ZMQ PUB/SUB)
│
▼
结果发布 ──→ DataManager ──→ HDF5 存储
客户端类型
quatm.servers 提供了四种标准客户端,用于处理不同类型的进程间通信:
| 客户端 | 用途 | 适用场景 |
|---|
CommandClient | 控制驱动和进程 | 向设备发送指令、启停驱动 |
DataClient | 传输小数据 | 1D 曲线、标量值、元数据 |
ImageClient | 传输大数据块 | 相机图像(2D 数组) |
MessageClient | 日志消息传递 | 错误、警告、信息、调试消息 |
基础客户端 — GenericClient
所有客户端的基类,封装了 ZMQ 连接和数据收发逻辑。
from quatm.servers.clients import GenericClient
client = GenericClient("my_channel")
client.subscribe("data_stream_name")
# 发送数据
client.send({"temperature": 25.0, "timestamp": 12345})
# 接收数据
if client.has_new_data():
data = client.recv()
| 方法 | 说明 |
|---|
subscribe(name) | 订阅指定的数据流 |
unsubscribe(name) | 取消订阅 |
send(data) | 发送数据 |
recv() | 接收数据 |
has_new_data() | 检查是否有新数据到达 |
数据客户端 — DataClient
专为小数据集设计的客户端,数据以 JSON 格式序列化,支持 NumPy 数组附件。
from quatm.servers.clients import DataClient
data_client = DataClient("analysis_result")
data_client.send({
"fit_params": {"A0": 1.5, "sigma": 0.3, "pos": 10.2},
"fit_curve": numpy_array
})
图像客户端 — ImageClient
优化用于传输相机图像等大型 2D 数据块。
from quatm.servers.clients import ImageClient
img_client = ImageClient("camera_output")
img_client.send(image_array) # 发送 NumPy 图像数组
命令客户端 — CommandClient
用于向驱动程序发送控制命令,使用独立通道以确保命令不被数据流阻塞。
消息客户端 — MessageClient
标准化的消息传递接口,所有消息带有时间戳和来源信息。
from quatm.servers import send_error, send_warning, send_info, send_debug
send_info("实验开始执行")
send_warning("激光功率偏低,请检查")
send_error("相机连接失败")
分布式属性系统
Quatm 通过分布式属性树管理所有运行时配置参数,支持跨进程实时同步。
配置层级
| 层级 | 说明 | 示例 |
|---|
| Configuration | 深层、基础系统属性 | 运行哪些硬件、可用驱动列表 |
| Properties | 对象特定参数 | ROI 位置、校准值、拟合参数 |
| Preferences | 不影响数据的次要选择 | 鼠标指针形状、窗口位置 |
PropertyAttribute
将分布式属性映射为 Python 属性,读写操作自动同步到属性树。
from quatm.servers.properties import PropertyAttribute, Properties
class MyComponent:
# 声明分布式属性,默认值为 42.0
_my_param = PropertyAttribute('/MyComponent/param', 42.0)
def __init__(self):
self._props = Properties('MyComponent')
def do_something(self):
# 读取属性值
x = self._my_param.value
# 写入属性值,自动同步到分布式树
self._my_param.value = 99.0
Properties
管理组件内部属性的同步副本,通过后台守护线程使用 ZMQ PUB/SUB 连接到中央属性中心。
from quatm.servers.properties import Properties
props = Properties('MyProcess')
props.set('/path/to/property', value)
current_value = props.get('/path/to/property')
配置读取器
读取静态配置文件 configuration/configfile.json,提供系统级别的运行时配置。
from quatm.servers.configreader import ConfigReader
reader = ConfigReader()
config = reader.getConfiguration()
常用路径常量
quatm.servers 导出以下路径常量,方便定位工作目录:
| 常量 | 说明 |
|---|
workpath | 工作根目录 |
driverpath | 驱动文件目录 |
iconpath | 图标资源目录 |
datapath | 数据存储目录 |
experiment_path | 实验脚本目录 |
configpath | 配置文件目录 |
6.1 - ZMQ 客户端 (clients)
DataClient/ImageClient/CommandClient——ZeroMQ 发布/订阅通信。
概述
clients.py 提供 Quatm 的核心 ZMQ 通信基础设施。各级客户端通过 PUB/SUB 模式收发数据、图像和命令。
客户端类
| 类 | 数据类型 | 用途 |
|---|
GenericClient | — | 基类,socket 管理 + JSON 序列化 |
DataClient | dict + numpy array | 一维数据流发送/接收 |
ImageClient | numpy image | 二维图像流传输 |
CommandClient | string | 设备驱动命令发送 |
用法
from quatm.servers.clients import DataClient
dc = DataClient(props=props)
dc.send({"pmt": 1234}, arr=numpy_array)
data = dc.recv(timeout=1000) # ms
6.2 - 属性树 (Properties)
分布式分层属性树——类 Unix 路径语法,ZMQ 实时同步。
概述
Properties 是 Quatm 的核心状态管理系统。它是一个分层键值树,通过 ZMQ REP/XPUB 在进程间实时同步变更。
类
| 类 | 说明 |
|---|
Properties | 线程化属性树服务,ZMQ 发布/订阅同步 |
PropertyAttribute | 描述符式树节点访问器 |
用法
from quatm.servers.properties import Properties
props = Properties()
props["laser/power"] = 50e-3 # 设置
power = props["laser/power"] # 读取
props.subscribe("laser/*") # 监听子树
# 远程访问(另一进程)
value = props["camera/exposure"] # 自动 ZMQ 同步
6.3 - 数据管理 (DataSummary)
多流数据聚合——按实验运行对齐,超时补齐后 HDF5 存储。
概述
DataSummary 聚合多个 ZMQ 数据流,按实验运行自动对齐时间轴,补齐缺失数据,并以 HDF5 格式保存结构化数据集。
from quatm.servers.datamgr import DataSummary
summary = DataSummary(props=props, streams=["pmt", "temperature"])
summary.start()
# 每次实验结束后自动保存: experiment_001.h5
6.4 - 消息系统 (MessageClient)
标准化日志消息——info/warning/error/debug 四级,时间戳+源标识。
概述
MessageClient 提供跨进程的标准化日志消息系统,支持四级日志级别。
全局函数
| 函数 | 级别 |
|---|
send_info(msg) | ℹ️ 信息 |
send_warning(msg) | ⚠️ 警告 |
send_error(msg) | ❌ 错误 |
send_debug(msg) | 🐛 调试 |
from quatm.servers.messageclient import send_error, send_info
send_info("实验启动完成")
send_error("相机连接超时")
6.5 - 配置与属性持久化
configreader + propertylogger——JSON 配置文件读取与属性树磁盘持久化。
模块
| 模块 | 功能 |
|---|
configreader.ConfigReader | 读取 configfile.json 配置 |
configreader.Properties() | 读取 properties.json 启动属性 |
propertylogger.run_propertylogger() | 定期将属性树写入磁盘 JSON |
datalogger.DataStreamLogger | 监控活跃数据流并记录时间戳 |
imagelogger.ImageStreamLogger | 监控活跃图像流并记录时间戳 |
from quatm.servers.configreader import ConfigReader
cfg = ConfigReader()
work_path = cfg.get("workpath")
device_db = cfg.get("device_db")
6.6 - 外围服务模块
CameraHub、InfluxDB、Mattermost、Bokeh、ZMQ 代理等外围服务。
服务列表
| 模块 | 功能 |
|---|
camerahub.CameraHub | FLIR Spinnaker 相机发现/启动/配置 |
influxdb.influxdb | InfluxDB 时间序列数据写入与查询 |
mattermost.post_to_mattermost() | Mattermost 频道消息/文件发送 |
image_network_server | Bokeh Web 实时图像浏览器 |
xsub_xpub.run_server() | ZMQ XSUB/XPUB 代理服务 |
experiment_status | 实验状态监控→Mattermost 通知 |
from quatm.servers.influxdb import influxdb
db = influxdb(host="localhost", database="quatm")
db.write("temperature", {"lab_temp": 22.5})
7 - 部署指南
在实际实验环境中部署和运行 Quatm 框架的指南。
部署架构
Quatm 的通信基于 ZeroMQ,支持灵活的网络拓扑:
┌──────────────────┐ ZeroMQ ┌──────────────────┐
│ 控制端 (实验室) │ ◄──────────────────► │ 客户端 (办公) │
│ • 设备驱动 │ │ • GUI 浏览器 │
│ • 实验引擎 │ │ • 参数编辑器 │
│ • 数据采集 │ │ • 数据监视器 │
└──────────────────┘ └──────────────────┘
核心服务
| 服务 | 模块 | 功能 |
|---|
| 数据管理 | datamgr.DataSummary | 接收、存储实验数据为 HDF5 |
| 数据记录 | datalogger | 实时数据流记录 |
| 图像记录 | imagelogger | 图像数据存储 |
| 属性管理 | properties.Properties | 分布式属性同步 |
| 配置读取 | configreader | 路径和配置管理 |
| 消息转发 | xsub_xpub | ZeroMQ 消息代理 |
单机部署
所有组件在同一台计算机上运行:
git clone https://github.com/quatm/quatm.git
cd quatm
pip install -r requirements.txt
# 编辑 configuration/device_db.py
python -m quatm.GUI.browser
分离部署
控制端运行实验引擎,客户端远程连接:
# 控制端(实验室计算机)
python -m quatm.servers.experiment_server --port 7777
# 客户端(办公计算机)
python -m quatm.GUI.browser --connect 192.168.1.100:7777
系统服务(Linux)
[Unit]
Description=Quatm Experiment Server
After=network.target
[Service]
Type=simple
User=labuser
WorkingDirectory=/home/labuser/quatm
ExecStart=/home/labuser/.venv/bin/python -m quatm.servers.experiment_server
Restart=always
[Install]
WantedBy=multi-user.target
数据存储
- 本地:HDF5 格式,保存在
Data/年-月-日/ 目录 - 远程:支持 InfluxDB 推送(配置
properties.json)
8 - 实验框架
Quatm 实验调度、任务管理、序列编辑与运行监控的核心组件文档。
quatm.experiment 包
该包提供对实验的完整控制。用户可以编写简单或高级的实验脚本并执行。
教程
快速开始
要定义一个实验,需要创建一个继承自 Experiment 的类,并至少定义 build 和 run 两个方法。在 build 阶段,会创建一个实验窗口用于进一步配置。run 阶段在点击窗口中的"运行"按钮时执行,可多次执行以实现重复测量或参数扫描。
简单示例:
class my_experiment(Experiment):
def build(): # this function is executed once when the file is loaded.
# you want to use the dac MyDAC you configured in device.db
self.setattr_device("Mydac") # -0.1600
# define additional variables
self.setattr_argument("targetvoltage", NumberValue(ndecimals=2, step=0.01, value=4.00))
def run(): # this function is executed for each run of the experiment
self.Mydac = 1 # set the dac to 1V
delay(1) # delay 1 second
self.Mydac = self.targetvoltage # set the DAC to a user-defined target voltage
在此示例中,声明需要使用 Mydac DAC。Mydac 必须是 device_db 中的有效条目。所有 setattr_... 函数应放在 build 阶段。
额外定义的变量是 targetvoltage。setattr_argument 用于在实验窗口中创建可通过 GUI 设置或扫描的字段,默认值为 4,步长为 0.01。
在 run() 阶段,输出设为 1V,等待一秒后设为用户定义的值。build 阶段定义的属性可通过 self 前缀在 run 阶段访问。
基本配置
配置文件 device_db.py 位于 configuration 目录中,定义了一个名为 device_db 的字典。每个键对应一个可在实验中使用的设备。以下示例配置了一个 TTL 通道和一个 DAC 通道。
示例:
device_db = {
"controller": {
"type": "local",
"module": "quatm.drivers.fpga.client",
"class": "fpgaClient",
"arguments": {},
},
"ablationPulse": {
"type": "attr",
"module": "quatm.experiment.ttl",
"class": "TTLOut",
"arguments": {"channel": 0},
},
"trapX2": {
"type": "attr",
"module": "quatm.experiment.dac",
"class": "DAC",
"arguments": {"channel": 2},
}
}
配置文件中定义了两类设备。第一类是 FPGA 控制器的 local 驱动。module 指向驱动类所在的 Python 模块,class 指定要实例化的类,arguments 为传递给构造函数的参数。
第二类将一个 TTL 通道映射为实验属性。使用 TTL 或 DAC 属性设备前,必须先定义对应的控制器驱动。
第三类定义了一个 DAC 通道。DAC 通道可指定额外的参数(如校准文件)。
接入自定义驱动
假设你编写了 evalcontrol 驱动模块,包含 AD9959 类。该类接受 bus_number 和 port_numbers 参数,提供 set_frequency 方法设置 DDS 频率。DDS 多通道需指定目标通道。
我们希望通过 Li_frequency 属性访问 DDS 的通道 0,并将软件限制在 40-90 MHz 以保护硬件。对应的 device_db 配置如下:
自定义驱动配置示例:
device_db = {
...
"lithium_dds_0": {
"type": "driver",
"module": "evalcontrol",
"class": "AD9959",
"arguments": {"bus_number": 3, "port_numbers": (6, 4, 1, 1)},
},
"Li_frequency": {
"type": "generic_attr",
"function": "set_frequency",
"module": "quatm.experiment.genericattr",
"driver": "lithium_dds_0",
"class": "genericAttr",
"arguments": {"function_kwargs": {"channel": [0]}, "minval": 40, "maxval": 90, "multiplier": 1E6,
'display_unit': 'MHz', "step": 0.1},
},
...
}
第一条配置生成驱动类的实例。之后可通过 generic_attr 定义多个参数,每个参数调用驱动类中的不同函数。function 指定要调用的函数名,function_kwargs 传递额外参数。minval/maxval 提供软件限制,multiplier 控制显示单位。编写实验脚本时应使用 SI 单位,GUI 通过 display_unit 和 multiplier 显示。step 控制 GUI 步长。
配置完成后,在实验中这样使用:
class my_experiment(Experiment):
def build():
self.setattr_device("Li_frequency")
self.setattr_device("lithium_dds_0") # you need this entry to create the driver class instance
def run():
self.Li_frequency = 66E6 # set the DDS to 66MHz
delay(1) # delay 1 second
self.Li_frequency = 50E6 # set DDS to 50MHz
使用校准文件
Quatm DAC 通道支持校准文件。例如,当电压控制衰减器的响应为非线性时,可使用校准文件将期望的 RF 功率映射为实际 DAC 值。校准文件为两列空格分隔的文本文件(可用 numpy.loadtxt 读取)。
一个典型的校准文件内容如下:
2.2 4
2 3.8
1.8 3.6
1.6 3.34
1.4 3.12
1.2 2.90
1.0 2.68
0.8 2.48
0.6 2.26
第一列为 DAC 值,第二列为 RF 功率。两列关系应严格单调。建议使用 SI 基本单位(如 1.12E-7 W 而非 11.2 µW)。
使用时在 DAC 配置中通过 gauge 参数指定校准文件路径(相对于项目根目录)。
一般情况下 device_db.py 的内容结构如下:
device_db = {
...
"rf": {
"type": "attr",
"module": "quatm.experiment.dac",
"class": "DAC",
"arguments": {"channel": 9, "minval": 0.1, "maxval":
8.1 - 数据类控件
该代码实现了三个自定义的GUI控件类,用于处理实验中的浮点数、布尔值和组合框参数。代码使用了quatm.GUI.simple_defaults模块中的FloatManager、BoolManager和ComboManager作为基类,并扩展了它们的功能。主要类包括:FloatBox、BoolBox和ComboBox。
类和方法
FloatBox 类
FloatBox 继承自 FloatManager,用于处理实验中的浮点数参数。
方法:
__init__(self, props, value, parent=None, **kwargs):初始化浮点数控件。
props:属性对象,用于存储和管理配置数据。value:初始值。parent:父窗口。**kwargs:其他关键字参数,包括参数名称等。- 调用父类的初始化方法,并传递参数名称。
updateValue(self, value):更新实验中的对应参数。
value:新的浮点数值。- 更新控件的值,并在属性对象中设置对应的参数值和最后设置的参数信息。
BoolBox 类
BoolBox 继承自 BoolManager,用于处理实验中的布尔值参数。
方法:
ComboBox 类
ComboBox 继承自 ComboManager,用于处理实验中的组合框参数。
方法:
updateValue(self, value):更新实验中的对应参数。value:新的组合框值。- 将值转换为字符串列表中的对应值。
- 更新控件的值,并在属性对象中设置对应的参数值和最后设置的参数信息。
类的详细说明
FloatBox 类
FloatBox类用于处理实验中的浮点数参数。它继承自FloatManager,并扩展了其功能,以便在属性对象中设置参数值。
class FloatBox(FloatManager):
''' Box for handling the attribute argument
Args:
argument:(NumberValue)
points to the argument in the experiment
unit:(str)
unit string
display_multiplier:(float)
multiplication factor for the unit
'''
def __init__(self, props, value, parent=None, **kwargs):
super().__init__(props, parent, parName=kwargs['name'], **kwargs)
def updateValue(self, value):
'''Update the corresponding argument in Experiment
Args:
value:(type needs to correspont the to the argument type it represents
'''
self.value = value*self.display_multiplier
if self._props:
self._props.set(self.parName, value*self.display_multiplier)
self._props.set('last_set', self.parName+': '+str(value))
BoolBox 类
BoolBox类用于处理实验中的布尔值参数。它继承自BoolManager,并扩展了其功能,以便在属性对象中设置参数值。
class BoolBox(BoolManager):
''' GUI for boolean values
KWArgs:
parName:(str)
name of the parameter
value:(BoolValue)
reference to the argument class
'''
def updateValue(self, value):
'''Update the corresponding argument in Experiment
Args:
value:(type needs to correspont the to the argument type it represents
'''
self.value = bool(value)
if self._props:
self._props.set(self.parName, bool(value))
self._props.set('last_set', self.parName+': '+str(value))
def updateCheckbox(self):
''' updates the spin box if properties have changed '''
val=self.value #the values in properties are in SI units. Non SI only on disp
if val != self.isChecked():
self.setChecked(val)
ComboBox 类
ComboBox类用于处理实验中的组合框参数。它继承自ComboManager,并扩展了其功能,以便在属性对象中设置参数值。
class ComboBox(ComboManager):
''' GUI for boolean values
KWArgs:
parName:(str)
name of the parameter
argument:(BoolValue)
reference to the argument class
'''
def updateValue(self, value):
'''Update the corresponding argument in Experiment
Args:
value:(type needs to correspont the to the argument type it represents
'''
value = self.stringlist[value]
self.value = value
if self._props:
self._props.set(self.parName, value)
self._props.set('last_set', self.parName+': '+str(value))
总结
该代码实现了三个自定义的GUI控件类:FloatBox、BoolBox和ComboBox,用于处理实验中的不同类型的参数。这些类继承自相应的管理类,并扩展了它们的功能,以便在属性对象中设置和更新参数值。
8.2 - 实验窗口控件类
该代码定义了几个自定义的GUI控件类,包括基础窗口小部件、框架、主窗口以及带有自动完成功能的组合框和自定义的文本编辑控件。这些控件通过继承Qt的基本控件类,并添加了一些自定义的功能来实现。
类和方法
BWidget 继承自 QWidget,实现了一个基础窗口小部件类,包含移动和调整大小事件的日志记录功能。
方法:
__init__(self, name='Noname', parent=None):初始化窗口小部件。
name:窗口小部件名称,默认为’Noname’。parent:父窗口。- 初始化属性对象并恢复窗口几何设置。
closeEvent(self, event):处理窗口关闭事件。
event:关闭事件。- 保存窗口几何设置并调用父类的关闭事件处理方法。
BFrame 类
BFrame 继承自 QFrame,实现了一个基础框架类,包含移动和调整大小事件的日志记录功能。
方法:
__init__(self, name='Noname', parent=None):初始化框架。
name:框架名称,默认为’Noname’。parent:父窗口。- 初始化属性对象并恢复框架几何设置。
closeEvent(self, event):处理框架关闭事件。
event:关闭事件。- 保存框架几何设置并调用父类的关闭事件处理方法。
BMainWindow 类
BMainWindow 继承自 QMainWindow,实现了一个基础主窗口类,包含移动和调整大小事件的日志记录功能。
方法:
__init__(self, name='Noname', parent=None):初始化主窗口。
name:主窗口名称,默认为’Noname’。parent:父窗口。- 初始化属性对象并恢复主窗口几何设置。
closeEvent(self, event):处理主窗口关闭事件。
event:关闭事件。- 保存主窗口几何设置并调用父类的关闭事件处理方法。
CustomCompleter 类
CustomCompleter 继承自 QCompleter,实现了一个自定义的自动完成器。
方法:
__init__(self, items, parent=None, match_flag='contains'):初始化自动完成器。
items:自动完成项。parent:父窗口。match_flag:匹配标志,默认为’contains’。- 设置完成模式为弹出完成。
pathFromIndex(self, index):根据索引返回路径。
SearchComboBox 类
SearchComboBox 继承自 QComboBox,实现了一个带有自动完成功能的组合框。
方法:
__init__(self, parent=None, match_flag='contains'):初始化组合框。
parent:父窗口。match_flag:匹配标志,默认为’contains’。- 设置可编辑性和自动完成器。
add_if_new(self, text):如果文本不存在,则添加并返回索引。
text:文本。- 如果文本不存在于组合框中,则添加并返回其索引。
find_or_add(self, text):如果文本存在则设置当前项,如果不存在则添加并设置当前项。
SearchLineEdit 类
SearchLineEdit 继承自 QLineEdit,实现了一个自定义的文本编辑控件,用于SearchComboBox。
方法:
__init__(self, parent=None):初始化文本编辑控件。
keyPressEvent(self, event):处理按键事件。
focusInEvent(self, event):处理获得焦点事件。
focusOutEvent(self, event):处理失去焦点事件。
类的详细说明
BWidget类是一个基础窗口小部件类,包含移动和调整大小事件的日志记录功能。
class BWidget(QWidget):
""" base class of quatm Widgets
includes logging of move and resize events"""
def __init__(self,name='Noname',parent=None):
super().__init__(parent)
self._props=Properties(name)
self._name = name
settings=QtCore.QSettings("quatm", self._name)
try:
self.restoreGeometry(settings.value("geometry"))
except:
print('geometry not found')
def closeEvent(self,event):
settings=QtCore.QSettings("quatm", self._name)
settings.setValue("geometry", self.saveGeometry())
super().closeEvent(event)
BFrame 类
BFrame类是一个基础框架类,包含移动和调整大小事件的日志记录功能。
class BFrame(QFrame):
""" base class of quatm Widgets
includes logging of move and resize events"""
def __init__(self,name='Noname',parent=None):
super().__init__(parent)
self._props=Properties(name)
self._name = name
settings=QtCore.QSettings("quatm", self._name)
try:
self.restoreGeometry(settings.value("geometry"))
except:
print('geometry not found')
def closeEvent(self,event):
settings=QtCore.QSettings("quatm", self._name)
settings.setValue("geometry", self.saveGeometry())
super().closeEvent(event)
BMainWindow 类
BMainWindow类是一个基础主窗口类,包含移动和调整大小事件的日志记录功能。
class BMainWindow(QMainWindow):
def __init__(self,name='Noname',parent=None):
super().__init__(parent)
self._props=Properties(name)
self._name = name
settings=QtCore.QSettings("quatm", self._name)
try:
self.restoreGeometry(settings.value("geometry"))
except:
print('geometry not found')
self.setWindowTitle(name)
def closeEvent(self,event):
settings=QtCore.QSettings("quatm", self._name)
settings.setValue("geometry", self.saveGeometry())
super().closeEvent(event)
CustomCompleter 类
CustomCompleter类是一个自定义的自动完成器,用于实现不同的匹配方式。
class CustomCompleter(QCompleter):
def __init__(self, items, parent=None, match_flag='contains'):
super(CustomCompleter, self).__init__(items, parent)
self.setCompletionMode(QCompleter.CompletionMode.PopupCompletion)
self.match_flag = match_flag
def pathFromIndex(self, index):
path = index.data()
if self.match_flag == 'contains' and self.completionPrefix() in path:
return path
elif self.match_flag == 'begins' and path.startswith(self.completionPrefix()):
return path
return ''
SearchComboBox 类
SearchComboBox类是一个带有自动完成功能的组合框,允许用户搜索和选择项。
class SearchComboBox(QComboBox):
"""
QComboBox with the autocompleter QCompleter enabled.
This adds an editable QLineEdit which allows the contents of the combobox to be searched.
Filtered list appears as a popup below the search box.
The full list can be accessed by click the drop-down arrow.
match_flag: can be either 'contains' or 'begins to get the matchFlag to MatchContains or MatchStartsWith.
Has a custom QLineEdit called SearchLineEdit.
"""
def __init__(self, parent=None, match_flag='contains'):
super().__init__(parent)
self.setLineEdit(SearchLineEdit(self))
self.setEditable(True)
self.setInsertPolicy(QComboBox.InsertPolicy.NoInsert)
self.completer = CustomCompleter(self.model(), self, match_flag)
self.setCompleter(self.completer)
self.setDuplicatesEnabled(False)
def add_if_new(self, text):
"""if it's in the box, add it. return the index of the item"""
idx = self.findText(text)
if
idx < 0: # findText returns -1 if the item isn't in the combobox
self.addItem(text)
idx = self.findText(text)
return idx
def find_or_add(self, text):
"""if it's in the box, set it, if not, add and set it"""
idx = self.add_if_new(text)
self.setCurrentIndex(idx)
SearchLineEdit 类
SearchLineEdit类是SearchComboBox的自定义文本编辑控件,处理特殊的按键事件和焦点事件。
class SearchLineEdit(QLineEdit):
"""
Custom QLineEdit for the SearchComboBox class.
On focus in (e.g. when clicked on for the first time) the full text is selected.
On focus out or pressing enter, the current text is stored. When pressing escape, the stored text is applied.
On escape, reverts the
"""
def __init__(self, parent=None):
super().__init__(parent)
self.parent = parent
def keyPressEvent(self, event: QKeyEvent):
if event.key() == Qt.Key.Key_Escape:
self.setText(self.lastText)
elif event.key() == Qt.Key.Key_Enter:
self.lastText = self.text()
else:
super().keyPressEvent(event)
def focusInEvent(self, event):
super().focusInEvent(event)
QTimer.singleShot(0, self.selectAll) # ensures other events are processed first. Prevents UI locking up.
def focusOutEvent(self, event):
super().focusInEvent(event)
self.lastText = self.text()
总结
该代码实现了几个自定义的GUI控件类,包括基础窗口小部件、框架、主窗口以及带有自动完成功能的组合框和自定义的文本编辑控件。这些控件通过继承Qt的基本控件类,并添加了一些自定义的功能来实现。
8.3 - 实验序列编辑器
该代码实现了一个图形用户界面(GUI)应用程序,用于编辑和可视化实验序列。应用程序使用了Qt库来创建界面,Qsci库提供代码编辑器,pyqtgraph库用于绘图。代码主要包括三个类:CodeEditor、ExperimentSequencer 和 ExperimentParser,以及一个主窗口类 CodeEditorParser。
类和方法
CodeEditor 类
CodeEditor 继承自 QsciScintilla,实现了一个简单的代码编辑器,具有语法高亮和自动补全功能。
方法:
__init__(self, parent=None, filename=None):初始化编辑器,设置字体、缩进、自动补全和行号。
parent:父窗口filename:要加载的文件名- 设置最小尺寸为800x600
- 设置编辑器字体为
Courier New,字号12,固定间距 - 设置缩进宽度为4,不使用制表符缩进,启用自动缩进
- 启用自动补全,触发阈值为3个字符
- 设置边距宽度以显示行号
- 如果提供了文件名,则加载文件内容到编辑器中
saveFile(self):保存当前文本到文件。
- 如果提供了文件名,则将编辑器中的文本写入文件
- 如果保存成功,打印"file saved successfully"
- 如果保存失败,打印错误信息
- 如果文件名无效,打印"filename is invalid, failed to save file"
ExperimentSequencer 类
ExperimentSequencer 继承自 QtWidgets.QWidget,用于可视化实验序列。
方法:
__init__(self, parent=None, filename=None):初始化窗口,订阅属性并创建绘图窗口。
parent:父窗口filename:文件名(未使用)- 订阅
Properties的Sequencer属性 - 创建
GraphicsLayoutWidget并设置背景为白色 - 将绘图窗口添加到网格布局中
plotSequence(self, sequence):绘制实验序列,输入格式由 ExperimentParser 定义。
sequence:包含实验序列的字典,键为通道名,值为包含时间和状态的子字典- 重置绘图窗口
- 矢量化布尔值到整数的转换
- 找到全局最小和最大时间
- 处理开始和结束时未定义的值
- 准备颜色
- 为每个通道创建线图,根据通道名选择颜色
- 将所有图的X轴链接到第一个图
ExperimentParser 类
ExperimentParser 用于解析实验代码,模拟实验运行并输出包含通道、时间和通道状态的表。
方法:
__init__(self, filename=None):初始化解析器,构建实验。
filename:文件名- 调用
buildExperiment方法构建实验
buildExperiment(self):构建实验,使其在 self.filename 中可访问。
simulateExperiment(self):模拟实验运行,返回指令堆栈,并按通道组织为字典。
- 运行实验,获取模拟的命令堆栈
- 将命令堆栈转移到字典中,键为通道名,值为包含时间和状态的子字典
CodeEditorParser 类
CodeEditorParser 继承自 QtWidgets.QMainWindow,将代码编辑器、解析器和实验代码的可视化结合在一起。
方法:
__init__(self, parent=None, filename=None):初始化主窗口,创建停靠窗口和按钮。
parent:父窗口filename:文件名- 设置窗口标题为“Experiment Editor”
- 设置窗口几何尺寸为1280x800
- 创建停靠窗口和按钮
- 初始化时模拟实验序列并绘制
addButtons(self):添加保存和模拟按钮。
- 创建保存和模拟按钮
- 将按钮添加到布局中
- 连接按钮点击事件到相应的方法
createDocks(self):创建停靠区,包含左侧的 CodeEditor 和右侧的 ExperimentSequencer。
- 创建
CodeEditor实例并添加到左侧停靠区 - 创建
ExperimentSequencer实例并添加到右侧停靠区
simulateExperiment(self):模拟当前版本的实验,将指令堆栈传递给 ExperimentSequencer 进行可视化。
- 保存文件,重建实验并模拟运行
- 将模拟的指令堆栈传递给
ExperimentSequencer进行绘制
main() 函数
- 创建
QApplication 实例。 - 创建
CodeEditorParser 实例并显示。 - 启动应用程序的主循环。
def main():
app = QtWidgets.QApplication(sys.argv)
Win = CodeEditorParser(filename=sys.argv[1])
Win.show()
sys.exit(app.exec())
代码执行
代码通过命令行执行,接收一个文件名作为参数:
python script.py your_experiment_file.py
总结
该代码实现了一个集成代码编辑、实验序列解析和可视化的GUI工具。通过Qt提供的窗口和控件,用户可以方便地编辑实验代码,并实时查看实验序列的变化。
8.4 - 多线程任务管理器
该代码实现了一个实验管理器 (ExperimentManager) 类,用于管理和运行实验队列中的任务。该管理器在一个工作线程中不断检查队列中的实验任务,并根据任务的优先级和状态来决定执行哪些实验。实验任务由测量、序列(或扫描)和运行组成,在执行实验时会调用相关的开始和结束函数来控制实验的流程。
以下是该代码的详细中文文档说明:
代码概述
该代码实现了一个实验管理器 (ExperimentManager) 类,用于管理和运行实验队列中的任务。该管理器在一个工作线程中不断检查队列中的实验任务,并根据任务的优先级和状态来决定执行哪些实验。实验任务由测量、序列(或扫描)和运行组成,在执行实验时会调用相关的开始和结束函数来控制实验的流程。
依赖库
numpy:用于数值计算和数组操作。time:用于时间操作和延时。Qt.QtCore:用于信号槽机制和日期时间操作。quatm.GUI.browser_workers:包含 Worker 类,用于多线程处理。quatm.servers:包含发送信息和错误的函数。
类 ExperimentManager
该类包含了管理实验任务队列的功能,包括运行实验、暂停实验、终止实验等。
初始化方法 __init__(self, browser=None)
初始化实验管理器,设置浏览器、属性、队列、线程池等,并启动实验队列。
参数:
运行实验方法 run(self, taskNr, progress_callback=None)
处理实验任务的运行逻辑。
参数:
taskNr:任务编号。progress_callback:进度回调函数。
内部方法 _sequence_run(self)
初始化运行循环并开始实验。
内部方法 _runloop(self)
运行实验(或实验扫描),在每次运行前检查实验是否暂停或终止。
暂停方法 pause(self)
暂停或继续实验。
启动队列方法 start_queue(self)
在实验线程中启动实验队列工作器。
队列函数 queue_fn(self, progress_callback=None)
实验队列持续检查实验字典中的新任务,如果字典为空或有实验在运行,则不做任何操作。
检查到期方法 due_check(taskDict)
检查任务是否到期。
参数:
返回:
更新表格方法 update_table(self)
通知 GUI 更新表格显示。
终止实验方法 terminate_experiment(self)
优雅地终止实验,允许当前运行完成。
开始测量方法 start_measurement(self)
设置参数并调用实验的 start_measurement 函数。
开始序列方法 start_sequence(self)
调用实验的 start_sequence 函数。
结束序列方法 end_sequence(self)
调用实验的 end_sequence 函数。
结束测量方法 end_measurement(self)
运行 end_measurement 函数,并清理表格。
设置字典方法 set_dict(self, name, value)
设置实验参数。
参数:
设置运行编号方法 set_run_nr(self, value)
设置实验运行编号并更新表格。
参数:
设置重复编号方法 set_rep_nr(self, value)
设置实验重复编号并更新表格。
参数:
代码详细说明
初始化 ExperimentManager
在初始化方法中,实验管理器会从浏览器对象中获取属性和队列,并启动实验队列工作器。实验队列工作器会在一个单独的线程中运行,不断检查实验队列中的任务。
运行实验 run
在运行实验方法中,实验管理器会检查任务是否存在,并获取任务的详细信息,包括实验名、参数、扫描参数、扫描值等。然后调用相关的开始和结束方法来控制实验的流程。
队列函数 queue_fn
队列函数会持续检查实验字典中的新任务,并根据任务的优先级和状态来决定执行哪些实验。如果任务到期,则运行任务,否则继续检查下一个任务。
暂停和终止实验
实验管理器提供了暂停和终止实验的方法。暂停方法会切换实验的暂停状态,并更新队列显示。终止方法会优雅地终止实验,允许当前运行完成。
其他辅助方法
实验管理器还提供了一些辅助方法,用于设置实验参数、更新表格显示等。
代码示例
以下是一个简单的使用示例:
from PyQt6.QtWidgets import QApplication
import sys
from quatm.servers import Properties
from quatm.GUI.browser import Browser
from quatm.GUI.experiment_manager import ExperimentManager
app = QApplication(sys.argv)
browser = Browser()
experiment_manager = ExperimentManager(browser)
# 添加实验任务到队列
experiment_manager.queue.add_task(task_dict)
# 开始运行实验
experiment_manager.run(taskNr)
sys.exit(app.exec())
8.5 - 实验序列编辑器
该代码实现了一个实验浏览器(Browser)应用程序,提供了图形用户界面来管理和运行各种实验。通过使用Qt库构建界面,代码实现了实验文件选择、实验队列管理、参数设置和实验执行等功能。
代码概述
该代码实现了一个实验浏览器(Browser)应用程序,提供了图形用户界面来管理和运行各种实验。通过使用Qt库构建界面,代码实现了实验文件选择、实验队列管理、参数设置和实验执行等功能。
依赖库
os、importlib.util、inspect、traceback、numpy、json、datetime:标准库,用于文件操作、模块加载、错误处理、数值计算和日期时间处理。Qt.QtCore 和 Qt.QtWidgets:用于构建GUI应用程序。quatm.servers 和 quatm.GUI:自定义库,用于属性管理和GUI组件。
类和方法
Browser 类
Browser 继承自 QMainWindow,实现了实验浏览器的主界面。
信号:
方法:
__init__(self):初始化浏览器,设置属性、任务队列和其他组件,并恢复窗口几何设置。closeEvent(self, event):处理窗口关闭事件,调用父类的关闭事件处理方法。init_ui(self):初始化用户界面,设置状态栏和中央窗口区域,并创建停靠窗口。create_dock_widgets(self):创建停靠窗口,包含文件选择器、实验队列、准备站和循环器。open_experiment(self, filepath, startup=False):打开一个新的实验窗口,如果实验已经打开,则不执行任何操作。update_exp_window_task(self):更新所有实验窗口中的任务号。
ExperimentSubWindow 类
ExperimentSubWindow 继承自 QMdiSubWindow,实现了实验窗口的容器。
方法:
__init__(self, name, props, parent=None):初始化子窗口,设置窗口标题和属性。store_geometry(self):存储窗口几何设置。
ExperimentWindow 类
ExperimentWindow 继承自 QWidget,实现了单个实验的控制,包括参数设置和任务提交。
方法:
__init__(self, filepath, props, parent=None, browser=None):初始化实验窗口,加载实验文件并构建用户界面。init_ui(self):初始化用户界面,创建控件和布局。save_params(self, backup=False):保存实验参数到JSON文件。load_params(self):从JSON文件加载实验参数。get_files(self):打开文件选择对话框,获取文件路径。update_task_qsb(self):更新任务号选择框。submit_to_queue(self):提交实验到实验队列。submit_next(self):提交实验到实验队列,并设置最高优先级。submit_to_prepper(self):提交实验到准备站。setup_scan(self):设置扫描序列。setup_task_dict(self):创建任务字典,存储实验参数。build_argument_dict(self):创建实验参数字典。edit_sequence(self):打开序列编辑器窗口。closeEvent(self, event):处理窗口关闭事件,移除打开的窗口。gui_columns(self):返回GUI列数。arguments(self):返回实验参数。argument_names(self):返回实验参数名称列表。argument_dicts(self):返回实验参数字典列表。store_geometry(self):存储窗口几何设置。
SequenceEditor 类
SequenceEditor 继承自 QDialog,实现了序列编辑器窗口。
方法:
__init__(self, experimentWindow, parent=None):初始化序列编辑器窗口,设置窗口标题和图标,并创建控件和布局。update_parameter(self, parname, n):根据参数名称更新参数的范围和步长。update_list_generator(self):更新列表生成器。update_values(self):更新序列编辑器中的值。
QDock 类
QDock 继承自 QDockWidget,实现了包含实验队列、准备站和循环器的停靠窗口。
方法:
__init__(self, parent=None):初始化停靠窗口,设置布局和子控件。
FileSelector 类
FileSelector 继承自 QWidget,实现了实验文件选择器。
方法:
__init__(self, browser, parent=None):初始化文件选择器,设置属性和布局,并创建文件树视图。file_model(self, directory):创建文件模型,用于显示目录中的文件和文件夹。set_column_widths(self):设置文件树视图的列宽。go_up(self):导航到上一级目录。create_context_menu(self, position):创建上下文菜单,提供编辑和组合编辑选项。open_editor(self, filename):打开代码编辑器。open_file(self):打开文件或目录。
辅助函数
filepath_split(filepath)
拆分文件路径,返回路径、扩展名、名称和文件名。
def filepath_split(filepath):
"""
takes /dir/name.ext
returns path, ext, name, filename
= /dir/name, ext, name, name.ext
"""
path, ext = os.path.splitext(filepath) # /dir/name, ext
name = os.path.basename(path) # name
filename = os.path.basename(filepath) # name.ext
return path, ext, name, filename
主函数
初始化应用程序并启动主窗口。
def main():
qApp = QApplication(sys.argv)
Win = Browser()
qApp.setWindowIcon(QIcon(iconpath + '/browser.png'))
Win.show()
sys._excepthook = sys.excepthook
sys.excepthook = exception_hook
sys.exit(qApp.exec())
def exception_hook(exctype, value, traceback):
send_error('[Browser] ' + str([exctype, value, traceback]))
sys._excepthook(exctype, value, traceback)
sys.exit(1)
# Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
send_info('[Browser] Quatm Browser starts')
if (sys.flags.interactive != 1) or not hasattr(Qt, 'PYQT_VERSION'):
main()
总结
该代码实现了一个实验浏览器应用程序,通过图形用户界面管理和运行各种实验。它提供了实验文件选择、实验队列管理、参数设置和实验执行等功能,并使用Qt库构建用户界面。
8.6 - 实验队列管理器
该代码实现了一个实验队列管理器,通过图形用户界面(GUI)来显示和控制实验任务队列。使用Qt库来构建界面,其中包含按钮和表格,用于管理实验任务。代码主要包括一个类:ExperimentQ。
类和方法
ExperimentQ 类
ExperimentQ 继承自 QGroupBox,实现了一个实验队列管理器,显示和控制实验任务队列。
方法:
__init__(self, browser, parent=None, title="Experiment Queue"):初始化实验队列管理器。
browser:浏览器对象,用于访问属性和实验管理器parent:父窗口title:组框标题,默认为"Experiment Queue"- 创建按钮和表格,并设置布局
- 初始化属性
- 设置锁定标志为
False
create_buttons(self):创建并配置控制按钮。
- 创建暂停按钮、终止按钮、终止所有按钮和重启按钮
- 设置按钮图标、提示信息和点击事件处理函数
init_table_actions(self):初始化表格操作。
- 创建删除、终止、终止所有、休眠和暂停操作
- 设置操作的快捷键和上下文
- 将操作添加到表格
init_table(self):初始化表格。
- 创建
QTableView 并设置选择行为、选择模式和上下文菜单策略 - 隐藏垂直表头并设置其调整模式为内容适应
- 初始化
expDict 为一个空字典 - 创建
ScheduleModel 并将其设置为表格模型 - 设置水平表头的调整模式
set_model(self, model):设置表格的新模型。
delete_clicked(self):从队列中删除任务,或者如果任务正在运行则优雅地终止。
- 获取选中的行,并获取对应的任务编号
- 如果任务状态为“Running”或“Scanning”,则标记任务为终止
- 否则,从模型中删除任务
- 设置当前索引为选中的行
terminate_clicked(self):优雅地终止选中的任务(允许完成运行)。
- 获取选中的行,并获取对应的任务编号
- 标记任务为终止,状态设置为“Termination Pending”
- 如果没有选中任务,且模型中有任务,则终止第一个任务
terminate_all(self):终止所有任务。
- 遍历所有任务,标记为终止,状态设置为“Termination Pending”
set_sleeping(self):将选中的任务设置为“Sleeping”状态,或者取消“Sleeping”状态。
- 获取选中的行,并获取对应的任务编号
- 如果任务状态为“Sleeping”,则设置为“Queued”,否则设置为“Sleeping”
pause(self):暂停当前运行的实验。
- 调用浏览器的实验管理器的暂停方法
- 根据实验管理器的暂停状态,切换暂停按钮的图标
update_item(self, k, v):更新表格中的项目。
k:键(任务编号)v:值(任务信息)- 将任务信息更新到模型中,并解锁
delete_item(self, k):删除表格中的项目。
restart(self):用于测试按钮的功能。
代码执行
该代码通过创建 ExperimentQ 对象,并将其嵌入到主窗口中来执行。主窗口中会包含实验队列的表格和控制按钮,用户可以通过这些按钮来控制实验任务的状态。
# 示例代码,展示如何创建并显示 ExperimentQ 对象
if __name__ == "__main__":
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow
app = QApplication(sys.argv)
mainWindow = QMainWindow()
browser = ... # 创建或获取浏览器对象
experimentQueue = ExperimentQ(browser)
mainWindow.setCentralWidget(experimentQueue)
mainWindow.show()
sys.exit(app.exec())
8.7 - 多线程任务管理器
该代码实现了一个多线程工作者类(Worker)和信号类(WorkerSignals),用于在应用程序中处理多线程任务。Worker类继承自QRunnable,WorkerSignals类继承自QObject,定义了一组可用的信号,以便在工作线程中传递信息。
代码概述
该代码实现了一个多线程工作者类(Worker)和信号类(WorkerSignals),用于在应用程序中处理多线程任务。Worker类继承自QRunnable,WorkerSignals类继承自QObject,定义了一组可用的信号,以便在工作线程中传递信息。
依赖库
sys:用于获取异常信息。traceback:用于格式化异常跟踪信息。Qt.QtCore:提供Qt核心功能,包括信号和槽机制、可运行对象等。
类和方法
WorkerSignals 类
WorkerSignals 继承自 QObject,定义了一组可用的信号,以便在工作线程中传递信息。
信号:
finished:没有数据,表示任务完成。error:传递一个包含异常类型、异常值和格式化异常跟踪信息的元组。result:传递处理函数返回的结果数据。progress:传递一个整数,表示进度百分比。update_ui:用于更新用户界面。tableUpdate:用于更新表格。addItem:传递一个整数和一个QVariant,用于添加项目。deleteItem:传递一个整数,用于删除项目。taskStart:表示任务开始。taskDone:表示任务完成。
class WorkerSignals(QObject):
'''
Defines the signals available from a running worker thread.
Supported signals are:
finished
No data
error
`tuple` (exctype, value, traceback.format_exc() )
result
`object` data returned from processing, anything
progress
`int` indicating % progress
'''
finished = pyqtSignal()
error = pyqtSignal(tuple)
result = pyqtSignal(object)
progress = pyqtSignal(int)
update_ui = pyqtSignal()
tableUpdate = pyqtSignal()
addItem = pyqtSignal(int, QtCore.QVariant)
deleteItem = pyqtSignal(int)
taskStart = pyqtSignal()
taskDone = pyqtSignal()
Worker 类
Worker 继承自 QRunnable,实现了一个工作线程,用于处理耗时的任务。
方法:
class Worker(QRunnable):
'''
Worker thread
Inherits from QRunnable to handle worker thread setup, signals and wrap-up.
:param callback: The function callback to run on this worker thread. Supplied args and
kwargs will be passed through to the runner.
:type callback: function
:param args: Arguments to pass to the callback function
:param kwargs: Keywords to pass to the callback function
'''
def __init__(self, fn, *args, **kwargs):
super(Worker, self).__init__()
# Store constructor arguments (re-used for processing)
self.fn = fn
self.args = args
self.kwargs = kwargs
self.signals = WorkerSignals()
# Add the callback to our kwargs
self.kwargs['progress_callback'] = self.signals.progress
@pyqtSlot()
def run(self):
"""
Initialise the runner function with passed args, kwargs.
"""
# Retrieve args/kwargs here; and fire processing using them
try:
result = self.fn(*self.args, **self.kwargs)
except:
traceback.print_exc()
exctype, value = sys.exc_info()[:2]
self.signals.error.emit((exctype, value, traceback.format_exc()))
finally:
self.signals.finished.emit() # Done
总结
该代码定义了一个用于多线程任务处理的工作者类(Worker)和信号类(WorkerSignals)。Worker类继承自QRunnable,可以在工作线程中运行传入的函数,并通过信号机制传递任务的进度、结果或错误信息。WorkerSignals类定义了一组信号,以便在工作线程和主线程之间进行通信。
8.8 - 自动保存编辑器
该代码实现了一个自动保存编辑器,通过图形用户界面(GUI)来管理和设置定期自动保存的时间。使用Qt库来构建界面,包括日期时间编辑控件和复选框。主要类包括:AutoSaveEditor 和 DateTimeWidget。
类和方法
AutoSaveEditor 类
AutoSaveEditor 继承自 BWidget,实现了一个自动保存时间的编辑器。
信号:
subscriptionsChanged:订阅改变信号。propertiesChanged:属性改变信号。
方法:
__init__(self, props, max_items, name='regular_auto_save_times', parent=None):初始化自动保存编辑器。
props:属性对象,用于存储和管理配置数据。max_items:最大项目数量。name:属性名称,默认为’regular_auto_save_times’。parent:父窗口。- 设置布局,并加载和初始化日期时间控件。
load_AutoSaveEditor_props(props, prop_name, max_items):加载自动保存编辑器属性。
props:属性对象。prop_name:属性名称。max_items:最大项目数量。- 返回日期时间和勾选状态。
update_props(props, prop_name, datetimes, ticked):更新属性。
props:属性对象。prop_name:属性名称。datetimes:日期时间数组。ticked:勾选状态数组。
update_datetime(self, idx, datetime_save):更新日期时间。
idx:索引。datetime_save:新的日期时间。
update_ticked(self, idx, ticked):更新勾选状态。
accept(self):接受并保存更改。
DateTimeWidget 继承自 QFrame,实现了一个日期时间选择控件。
方法:
__init__(self, idx, parent, datetime_save=datetime.datetime.now(), ticked=False):初始化日期时间控件。
idx:索引。parent:父组件。datetime_save:初始日期时间,默认为当前时间。ticked:初始勾选状态,默认为False。- 设置布局,创建并初始化日期时间编辑控件和复选框。
datetime_changed(self):日期时间改变事件处理。
ticked_changed(self):勾选状态改变事件处理。
主函数
代码通过创建 QApplication 实例和 AutoSaveEditor 窗口来执行,并启动应用程序的主循环。
if __name__ == '__main__':
import sys
props = Properties('Tests/AutoSaveEditor')
pp = AutoSaveEditor(props, max_items=20)
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QApplication.instance().exec_()
代码执行
该代码通过命令行执行,创建一个AutoSaveEditor对象,并显示自动保存编辑器窗口。
类的详细说明
AutoSaveEditor 类
AutoSaveEditor类用于管理和设置定期自动保存的时间。它提供了一个图形用户界面,允许用户添加、编辑和删除自动保存的时间点。
方法:
__init__(self, props, max_items, name='regular_auto_save_times', parent=None):
load_AutoSaveEditor_props(props, prop_name, max_items):
- 静态方法,用于从属性对象中加载日期时间和勾选状态,并返回它们。
update_props(props, prop_name, datetimes, ticked):
- 静态方法,用于更新属性对象中的日期时间和勾选状态。
update_datetime(self, idx, datetime_save):
update_ticked(self, idx, ticked):
accept(self):
- 接受并保存更改,更新属性并通知父组件,然后关闭窗口。
DateTimeWidget类用于显示和编辑单个日期时间和勾选状态。
方法:
__init__(self, idx, parent, datetime_save=datetime.datetime.now(), ticked=False):
- 初始化方法,设置布局,创建并初始化日期时间编辑控件和复选框。
datetime_changed(self):
ticked_changed(self):
8.9 - 实验时间线查看器
该代码实现了一个实验时间线查看器,通过图形用户界面(GUI)来显示和控制实验时间序列。使用Qt库来构建界面,其中包含按钮、文本框和绘图区域。代码主要包括三个类:Timeline、TimelinePlotter 和 SelectorWidget。
类和方法
Timeline 类
Timeline 继承自 QMainWindow,实现了一个实验时间线查看器。
方法:
__init__(self, *args, **kwargs):初始化时间线查看器。
- 设置窗口标题为"Timeline Viewer"。
- 加载JSON文件中的实验序列。
- 创建主窗口组件,包括文件加载区、绘图区和选择区。
- 设置中央窗口部件。
plot_experimental_sequence(self, time_dict, init_vals=None):绘制实验时间序列。
- 重置绘图区域。
- 深拷贝时间序列字典。
- 找到最大时间
tmax。 - 为每个时间序列添加一个点,确保每个序列都在
tmax结束。 - 准备颜色。
- 为每个选中的输出绘制折线图,并根据条件选择不同的颜色和填充方式。
load_file(self, filename):加载实验序列文件。
- 读取JSON文件并解析实验序列。
- 获取输出名称集合。
- 构建时间序列字典。
- 逆向设备数据库转换时间序列字典。
- 更新选择器组件中的名称。
decode_ttl_bitmask(self, bitmask, command):解码TTL位掩码。
- 将位掩码转换为二进制字符串。
- 找到二进制字符串中的所有1的位置。
- 根据命令生成TTL字典。
get_set_of_used_outputs(self, sequence):获取使用的输出集合。
construct_time_sequences(self, sequence, set_of_output_names):构建时间序列字典。
reverse_device_db_transformation(self, time_sequence_dict, device_db_path=workpath+'/configuration/'):逆向设备数据库转换时间序列字典。
- 加载设备数据库。
- 构建逆向映射字典。
- 根据逆向映射字典转换时间序列字典中的名称和值。
TimelinePlotter 类
TimelinePlotter 继承自 GraphicsLayoutWidget,用于可视化实验序列。
方法:
__init__(self, sequence):初始化绘图组件。
SelectorWidget 继承自 QFrame,用于选择要显示的实验序列。
方法:
__init__(self, parent=None, clear_name_dict=None):初始化选择器组件。
get_names(self, clear_name_dict):获取并显示名称。
- 获取清晰名称字典的键并排序。
- 如果名称未变化,则直接返回。
- 否则,更新滚动区域中的复选框。
select_all(self):全选复选框。
deselect_all(self):取消全选复选框。
主函数
代码通过创建 QApplication 实例和 Timeline 窗口来执行,并启动应用程序的主循环。
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Timeline()
window.setWindowIcon(QtGui.QIcon(workpath + '/quatm/icons/time_line.png'))
window.setWindowTitle('Timeline Viewer')
window.show()
sys.exit(app.exec())
代码执行
该代码通过命令行执行,创建一个Timeline对象,并显示实验时间线查看器窗口。
8.10 - 多线程处理框架
该代码实现了一个基于 Qt 的多线程处理框架。主要包含两个类:WorkerSignals 和 Worker。WorkerSignals 类定义了线程工作时使用的各种信号,而 Worker 类继承自 QRunnable,用于处理多线程任务的设置、执行和信号传递。
功能介绍
该代码实现了一个基于 Qt 的多线程处理框架。主要包含两个类:WorkerSignals 和 Worker。WorkerSignals 类定义了线程工作时使用的各种信号,而 Worker 类继承自 QRunnable,用于处理多线程任务的设置、执行和信号传递。
代码结构
- 导入必要的模块和库
- 定义类
WorkerSignals - 定义类
Worker
类:WorkerSignals
简短功能介绍
WorkerSignals 类定义了可从正在运行的工作线程发出的信号。这些信号用于指示线程的各种状态和进度,包括完成、错误、结果和进度更新。
属性
finished:无数据的信号,指示线程已完成。error:包含异常类型、值和追溯信息的元组信号。result:处理结果数据的信号。progress:指示进度的整数信号。terminate:终止信号。start:启动信号。publish:发布信号。runDone:运行完成信号。logging:日志信号,包含日志信息字符串。clear:清除信号。
类:Worker
简短功能介绍
Worker 类继承自 QRunnable,用于处理工作线程的设置、信号和结束。它允许在独立线程中运行指定的函数,并通过信号机制与主线程通信。
方法:__init__
功能:初始化 Worker 对象,存储传递的函数及其参数,并设置信号。
参数:
fn:要在工作线程中运行的函数。args:传递给函数的参数。kwargs:传递给函数的关键字参数。
主要步骤:
- 调用父类
QRunnable 的构造函数。 - 存储传递的函数及其参数。
- 初始化
WorkerSignals 对象。 - 将进度回调添加到关键字参数中。
方法:run
功能:初始化传递的函数并执行它,处理可能的异常,并通过信号机制传递结果。
主要步骤:
- 尝试运行传递的函数,并捕获其结果。
- 如果发生异常,捕获异常信息并发出
error 信号。 - 如果函数运行成功,发出
result 信号传递结果。 - 最后,无论是否发生异常,发出
finished 信号指示完成。
8.11 - 实验任务循环管理器
该代码定义了几个自定义的GUI控件类,包括基础窗口小部件、框架、主窗口以及带有自动完成功能的组合框和自定义的文本编辑控件。这些控件通过继承Qt的基本控件类,并添加了一些自定义的功能来实现。
代码结构
- 导入必要的模块和库
- 定义主要的
Looper 类 - 定义
LoopItem 类及其子类(TaskItem, ListItem, ConditionalItem 等) - 定义辅助类(
DataManager, LoopManager, LoopGroup 等) - 实现 GUI 部件和功能
类:Looper
简短功能介绍
Looper 类是整个循环控制的核心。它负责管理任务组、定时器、按钮和循环的启动与终止。
方法
__init__:初始化 Looper 对象,设置属性和布局,创建按钮和标签页。add_tab:添加新的任务组标签页。delete_tab:删除指定的任务组标签页。create_buttons:创建控制按钮。save_loop:保存当前循环配置。load_loop:加载之前保存的循环配置。terminate_by_time:根据时间自动终止循环。
类:LoopItem
简短功能介绍
LoopItem 类是所有循环项的基类,提供了基本的属性和方法。它被 TaskItem, ListItem, ConditionalItem 等类继承,并扩展其功能。
子类:TaskItem
- 功能:表示单个任务项,执行特定的任务并跟踪运行次数。
- 方法:
__init__:初始化任务项,设置任务信息和UI组件。run:执行任务,并将任务添加到任务队列。end_run:更新任务状态和运行次数。task_start:任务开始时的操作。task_end:任务结束时的操作。update_task:更新任务信息。max_check:检查是否达到最大运行次数。
子类:ListItem
- 功能:表示一个任务列表,按顺序执行列表中的任务。
- 方法:
__init__:初始化任务列表项,设置任务列表信息和UI组件。run:执行当前任务,并更新任务索引。end_run:更新任务列表状态和运行次数。edit_list:编辑任务列表。update_task_labels:更新任务标签。
子类:ConditionalItem
- 功能:表示条件项,根据条件的结果执行不同的任务。
- 方法:
__init__:初始化条件项,设置条件信息和UI组件。run:评估条件并选择下一步操作。update_boxes:更新条件的UI组件。
类:DataManager
简短功能介绍
DataManager 类管理数据订阅和更新,处理数据的接收和存储。
方法
__init__:初始化数据管理器,设置属性和数据客户端。set_new_data:处理新的数据,更新数据字典。edit_subscriptions:编辑数据订阅。
类:LoopManager
简短功能介绍
LoopManager 类负责管理循环的执行,处理循环任务的启动、终止和控制。
方法
__init__:初始化循环管理器,设置属性和线程池。loop_fn:循环执行函数,处理循环任务。run_loop:启动循环任务。terminate:终止循环任务。task_start:任务开始时的操作。task_end:任务结束时的操作。
类:LoopGroup
简短功能介绍
LoopGroup 类表示一个任务组,包含多个任务项和一个组项。
方法
__init__:初始化任务组,设置属性和布局。create_buttons:创建任务组的控制按钮。delete_group:删除任务组。update_loop_group_file:更新任务组配置文件。
类:Baustelle
简短功能介绍
Baustelle 类是任务组的编辑器,提供添加、删除和编辑任务项的功能。
方法
__init__:初始化编辑器,设置属性和布局。add_task_item:添加新的任务项。add_list_item:添加新的任务列表项。add_conditional:添加新的条件项。add_group_item:添加新的组项。update_idx:更新任务项的索引。
类:LoopSubMgr
简短功能介绍
LoopSubMgr 类是一个GUI,用于编辑数据流的订阅。
方法
__init__:初始化订阅管理器,设置属性和布局。update_subscriptions:更新数据流的订阅。
类:ListEdit
简短功能介绍
ListEdit 类是一个对话框,用于编辑 ListItem 的任务列表。
方法
__init__:初始化对话框,设置属性和布局。closeEvent:在对话框关闭时更新任务列表。
类:PrepBox 和 ListBox
简短功能介绍
PrepBox 和 ListBox 类分别用于显示和管理预备任务列表和当前任务列表。
方法
init_ui:初始化UI组件。set_model:设置数据模型。push_selection:将选中的任务添加到任务列表。unpack_selection:解包选中的任务并添加到任务列表。move_up:在任务列表中上移任务。move_down:在任务列表中下移任务。delete_clicked:删除选中的任务。
类:VLine
简短功能介绍
VLine 类用于在UI中创建分隔线。
简短功能介绍
LoopTabWidget 和 EditableTabBar 类自定义了标签页控件,允许编辑标签页名称和管理标签页。
方法
addTab:添加新的标签页。setIconOn:设置标签页的图标为启用状态。setIconOff:设置标签页的图标为禁用状态。setTabText:设置标签页的文本。editTab:编辑标签页名称。
辅助函数
功能
get_experiment:获取实验对象。edit_key_in_place:编辑字典中的键。find_or_add:在组合框中查找或添加项目。parse_text:解析文本,转换为特定格式。
8.12 - 实验任务预备队列管理器
该代码定义了几个自定义的GUI控件类,包括基础窗口小部件、框架、主窗口以及带有自动完成功能的组合框和自定义的文本编辑控件。这些控件通过继承Qt的基本控件类,并添加了一些自定义的功能来实现。
概要
该代码定义了用于管理和展示队列(Queue)和准备站(PrepStation)表格的模型。模型指定了表格数据的形式(如字典或列表),以及如何展示和操作这些数据,包括如何获取、设置和删除数据,以及如何排序数据。模型可以直接从数据集中读取数据,并在数据集发生更改时自动更新表格。
主要类和功能
_SyncSubstruct
此类定义了用于操作表格数据字典的方法。方法包括添加、插入、弹出、设置、删除和获取字典项。这个类主要是为了便于在模型中更新数据字典,并在数据更新时调用回调函数来通知模型。
DictSyncModel
这是一个基类,用于将字典(backing_store)转换为表格。模型可以读取和编辑字典中的数据,并根据需要更新表格显示。其主要功能包括:
- 初始化模型,设置表头、数据名称和初始数据。
- 获取行数和列数。
- 获取和设置单元格数据。
- 获取表头数据。
- 插入和删除字典项。
- 排序和转换数据。
关键方法
rowCount: 返回字典中的条目数。columnCount: 返回列的数量,即表头的数量。data: 根据索引和角色获取数据。setData: 设置单元格数据,并根据需要进行类型转换。headerData: 获取表头数据。__setitem__: 插入或更新字典项,并更新表格显示。__delitem__: 删除字典项,并更新表格显示。__getitem__: 获取字典项。sort_key: 定义排序键(由子类实现)。convert: 将字典键转换为列数据(由子类实现)。flags: 定义单元格的属性(由子类实现)。
ScheduleModel
这是用于管理实验队列的表格模型。数据结构是一个字典,每个字典代表一个实验任务。任务按优先级和任务编号排序。
关键方法
sort_key: 返回用于排序的键,首先按优先级排序,然后按任务编号排序。convert: 将字典键转换为列数据,特别是将日期时间字符串转换为 QDateTime 对象。flags: 定义可编辑和不可编辑的列。
ListSyncModel
类似于 DictSyncModel,但处理的是列表而不是字典。主要用于管理需要按顺序排列的数据集合。
关键方法
rowCount: 返回列表的长度。columnCount: 返回列的数量。data: 根据索引和角色获取数据。setData: 设置单元格数据,并根据需要进行类型转换。headerData: 获取表头数据。__delitem__: 删除列表项,并更新表格显示。__getitem__: 获取列表项。sort_key: 定义排序键(由子类实现)。convert: 将列表项转换为列数据(由子类实现)。flags: 定义单元格的属性(由子类实现)。
PrepModel
这是用于准备站的表格模型,使用列表来管理任务,因为准备站中的任务不需要唯一的 ID,可以自由更改顺序。
关键方法
convert: 将列表项转换为列数据,特别是将日期时间字符串转换为 QDateTime 对象。flags: 定义可编辑和不可编辑的列。
功能特点
- 数据同步:模型可以同步更新数据字典或列表,并通知表格更新显示。
- 数据排序:模型可以根据指定的键对数据进行排序。
- 数据转换:模型可以根据列索引转换数据类型,如将日期时间字符串转换为
QDateTime 对象。 - 数据编辑:模型支持在表格中编辑数据,并将更改反映到原始数据集合中。
- 表格属性:模型可以定义哪些列是可编辑的,哪些是只读的。
运行流程
- 创建模型实例,传入初始数据。
- 模型通过
rowCount 和 columnCount 方法告知表格数据的大小。 - 表格通过
data 方法获取单元格数据并显示。 - 当用户编辑表格时,模型通过
setData 方法更新数据集合。 - 模型通过发射信号通知表格数据已更改,表格自动更新显示。
8.13 - 实验运行调度管理器
Prepper 类是 Quatm 实验调度与运行系统的核心组件,负责管理实验队列、线程调度和状态跟踪。
概述
Prepper 类(位于 quatm.gui.prepper 模块)是实验调度和运行系统的核心,提供以下核心能力:
- 任务队列管理:维护待执行的实验任务列表
- 线程调度:基于线程池的单线程调度策略,避免并发冲突
- 状态跟踪:通过
expDict 追踪每个实验的配置和运行状态 - 定时轮询:周期性检查任务状态并更新 UI
核心架构
graph TD
A[实验任务入队] --> B[queue 任务队列]
B --> C[threadpool 线程池]
C --> D[执行实验]
D --> E[expDict 状态更新]
E --> F[timer 定时刷新 UI]
F --> G[browser 界面展示]API 参考
构造函数
from quatm.gui.prepper import Prepper
prepper = Prepper(browser=None)
| 参数 | 类型 | 必填 | 说明 |
|---|
browser | object | 否 | 浏览器/UI 对象,用于界面交互和状态展示 |
成员变量
| 变量 | 类型 | 说明 |
|---|
browser | object | 关联的 UI 浏览器对象 |
queue | Queue | 实验任务队列(FIFO) |
expDict | dict | 实验配置与状态字典 |
threadpool | ThreadPoolExecutor | 线程池(max_workers=1) |
timer | QTimer | UI 定时刷新器 |
使用示例
基础用法
from quatm.gui.prepper import Prepper
from quatm.experiments import RabiExperiment
# 1. 初始化调度器
prepper = Prepper(browser=my_browser)
# 2. 创建实验并加入队列
exp = RabiExperiment(
qubit="q0",
durations=[10, 20, 50, 100], # ns
amplitudes=[0.1, 0.2, 0.3, 0.4]
)
prepper.queue.put(exp)
# 3. 启动调度(从队列中取出并执行)
prepper.start()
批量实验调度
# 批量提交多个实验
experiments = [
RabiExperiment(qubit="q0", durations=range(10, 100, 10)),
RamseyExperiment(qubit="q0", delays=range(0, 1000, 50)),
T1Experiment(qubit="q0", wait_times=range(1, 100, 5)),
]
for exp in experiments:
prepper.queue.put(exp)
# 调度器会按 FIFO 顺序逐个执行
prepper.start()
线程模型
Prepper 使用 max_workers=1 的线程池设计,原因如下:
- 硬件安全:避免多个实验同时操作同一 FPGA 控制器,防止寄存器冲突
- 状态一致性:确保
expDict 在单线程下读写安全,无需加锁 - 可预测性:实验按入队顺序严格串行执行,结果可复现
from concurrent.futures import ThreadPoolExecutor
# Prepper 内部等价于:
self.threadpool = ThreadPoolExecutor(max_workers=1)
错误处理
调度器内置了异常捕获机制,通过 traceback 模块记录详细的堆栈信息:
import traceback
def _run_experiment(self, exp):
try:
result = exp.run()
self.expDict[exp.id] = {"status": "done", "result": result}
except Exception as e:
self.expDict[exp.id] = {
"status": "error",
"error": str(e),
"traceback": traceback.format_exc()
}
实验失败不会中断调度器——错误被记录在 expDict 中,后续任务继续执行。
扩展指南
添加调度策略
如需支持优先级调度或依赖调度,可以扩展 Prepper 类:
class PriorityPrepper(Prepper):
"""支持优先级调度的实验管理器"""
def __init__(self, browser=None):
super().__init__(browser)
from queue import PriorityQueue
self.queue = PriorityQueue()
def submit(self, exp, priority=0):
"""提交实验并指定优先级(数值越小优先级越高)"""
self.queue.put((priority, exp))
添加实验类型
通过实现统一的实验接口,Prepper 可以支持任意实验类型:
class BaseExperiment:
"""所有实验的基类"""
def run(self):
raise NotImplementedError
@property
def id(self):
return id(self)
# Prepper 通过鸭子类型支持任何实现了 run() 方法的对象
常见问题
Q: 为什么线程池大小固定为 1?
A: 量子物理实验中,多个实验同时操作同一硬件可能导致不可预料的结果。单线程模型保证了时序确定性。
Q: 如何查看当前队列中的任务?
A: 通过 prepper.queue.qsize() 获取待执行任务数,通过 prepper.expDict 查看各实验状态。
Q: 实验执行中可以暂停吗?
A: 任何进程或者子进程都可以在实验执行过程中随时暂停、编辑、删除和添加。
8.14 - 实验预处理
该代码展示了一个名为 PrepStation 的类,用于实验的预处理和队列管理。
详细代码分析:PrepStation 类及其相关组件
该代码展示了一个名为 PrepStation 的类,用于实验的预处理和队列管理。以下是对代码的详细分析,涵盖导入的模块、类的定义及其成员、注释和错误处理等方面。
PrepStation 类
PrepStation 类是该代码的核心部分,用于管理实验任务的预处理和队列操作。以下是对该类的详细分析:
初始化方法
__init__ 方法:- 初始化类实例,并设置初始状态或配置。
- 接受
browser、parent 和 title 作为参数。 - 初始化各类成员变量,如
parent、browser、queue、expDict、qWidget、layout、buttonLayout、props、_task、paramDir、table 和 prepList。 - 调用
init_ui 和 init_table_actions 方法来设置界面和表格操作。
初始化界面
init_ui 方法:- 配置表格的垂直头,使其根据内容调整大小并隐藏。
- 创建各种按钮并设置其图标、工具提示和点击事件。
- 将按钮添加到布局中,并设置布局对齐方式。
初始化表格操作
init_table_actions 方法:- 创建各种操作(如删除、休眠、推送、循环、编辑、查看和保存)并设置其快捷键和触发事件。
- 将这些操作添加到表格中。
设置模型
set_model 方法:- 创建
PrepModel 实例并设置为表格模型。 - 调整表格列的宽度。
加载之前的任务
load_previous 方法:- 从
prepfile.json 文件中加载之前的任务列表,并打开相关的实验窗口。 - 更新
prepList。
任务操作方法
push 方法:
- 将选中的任务推送到队列中,如果没有选中任务,则推送第一个任务。
push_row 方法:
push_first 方法:
delete_clicked 方法:
set_sleeping 方法:
push_to_looper 方法:
move_up 方法:
move_down 方法:
update_prep_file 方法:
- 更新任务文件,将当前任务列表保存到
prepfile.json。
编辑和查看参数
open_editor 方法:
open_viewer 方法:
save_params 方法:
其他类和辅助函数
ExpEditWindow 类:
- 用于编辑实验参数的窗口。
- 初始化方法
__init__ 和 init_ui。 - 提交修改的方法
submit。
ParViewWindow 类:
- 用于查看实验参数的窗口。
- 初始化方法
__init__ 和 init_ui。
CheckLayout 类:
- 包含复选框和参数输入框的布局。
- 初始化方法
__init__。
DisplayBox 类:
- 显示参数名称、值和单位的布局。
- 初始化方法
__init__ 和 init_ui。
get_experiment 函数:
8.15 - 实验集合管理器
该代码定义了一个用于管理和监控多个进程的图形用户界面(GUI)应用程序。
环境变量设置
代码通过检查操作系统平台设置了 QT_SCALE_FACTOR 环境变量,以调整 MacOS 上的缩放比例。
SingleProcess 类
SingleProcess 类用于表示单个可管理的进程。以下是该类的详细分析:
初始化方法
__init__ 方法:- 初始化类实例,并设置初始状态或配置。
- 接受
script、name、active、category 和 parent 作为参数。 - 根据操作系统平台设置 Python 解释器路径。
- 创建和配置按钮、布局和样式表。
- 配置定时器以定期更新进程状态。
进程管理方法
startProcess 方法:
- 停止现有进程(如果有)。
- 使用
subprocess.Popen 启动新的进程。 - 更新按钮状态。
stopProcess 方法:
- 停止现有进程,根据需要选择终止或强制杀死进程。
- 更新按钮状态。
updateStatus 方法:
- 定期检查进程状态并更新按钮颜色以指示进程是否运行。
析构方法
ProcessManager 类
ProcessManager 类用于管理多个 SingleProcess 实例。以下是该类的详细分析:
初始化方法
__init__ 方法:- 初始化类实例,并设置初始状态或配置。
- 读取配置文件,创建
SingleProcess 实例,并将其添加到布局中。 - 设置窗口样式和布局。
事件处理方法
析构方法
主函数
main 方法:- 设置高 DPI 缩放策略。
- 创建应用程序实例,设置窗口图标,创建和显示主窗口。
- 进入应用程序事件循环。
结论
该代码实现了一个进程管理和监控的 GUI 应用程序。通过 SingleProcess 类,用户可以启动、停止和监控单个进程;通过 ProcessManager 类,用户可以批量管理多个进程。代码结构清晰,使用了 Qt 的多种控件和信号槽机制来实现用户交互和数据更新。
8.16 - 实验参数管理器
该代码定义了一个用于管理和监控多个进程的图形用户界面(GUI)应用程序。
DefaultExp 类概述
DefaultExp 是一个实验类,包含所有设备的属性,并组织这些属性以便于管理和访问。
方法详解
build(self)
- 功能:
- 设置实验的初始参数,如计数器。
- 遍历设备数据库,加载设备并根据设备类型进行分组。
- 处理属性的加载错误,并将设备分为显示和隐藏两类。
run(self)
BasicManager 类概述
BasicManager 是一个基础管理类,用于创建和管理各种类型的参数小部件。
构造方法
参数说明:
props:属性对象,用于与属性数据库交互。parent:父级小部件。kwargs:其他参数,用于初始化属性。
功能:
- 初始化基础属性,如单位、最大最小值、步长等。
- 设置样式并调用
_initGUI 方法。
方法详解
_initGUI(self)
- 功能:
- 初始化图形界面,创建布局和标签。
- 如果存在工具提示,则设置工具提示。
- 创建定时器,用于定期更新参数值。
updateSpin(self)
IntManager 类概述
IntManager 继承自 BasicManager,用于管理整数类型的参数。
方法详解
initSpin(self)
- 功能:
- 创建一个整数选择框 (
QSpinBox)。 - 从属性对象中获取初始值并设置到选择框中。
- 连接选择框的值变化信号到
updateValue 方法。
updateValue(self, v)
updateSpin(self)
- 功能:
- 检查属性对象中的值是否有变化,如果有变化,则更新选择框中的值。
BoolManager 类概述
BoolManager 继承自 QCheckBox,用于管理布尔类型的参数。
方法详解
updateValue(self, val)
updateCheckbox(self)
- 功能:
- 检查属性对象中的布尔值是否有变化,如果有变化,则更新复选框的状态。
FloatManager 类概述
FloatManager 继承自 IntManager,用于管理浮点数类型的参数。
方法详解
initSpin(self)
- 功能:
- 创建一个浮点数选择框 (
QDoubleSpinBox)。 - 从属性对象中获取初始值并设置到选择框中。
- 连接选择框的值变化信号到
updateValue 方法。
ComboManager 类概述
ComboManager 继承自 BasicManager,用于管理下拉列表类型的参数。
方法详解
initSpin(self)
- 功能:
- 创建一个下拉列表 (
QComboBox)。 - 根据提供的字符串列表初始化下拉列表的选项。
- 连接下拉列表的选项变化信号到
updateValue 方法。
updateValue(self, v)
FrequencyManager 类概述
FrequencyManager 继承自 IntManager,用于管理频率类型的参数。
方法详解
initSpin(self)
- 功能:
- 创建一个浮点数选择框 (
QDoubleSpinBox),用于选择频率值。 - 从属性对象中获取初始值并设置到选择框中。
- 连接选择框的值变化信号到
updateValue 方法。
SimpleDefaults 类概述
SimpleDefaults 继承自 QFrame,用于显示和管理实验的默认参数。
构造方法
- 功能:
- 初始化属性对象和实验对象。
- 调用实验对象的
build 方法构建实验。 - 创建和设置主布局。
- 根据实验的分组创建相应的参数管理小部件,并添加到布局中。
主函数
main()
- 功能:
- 创建应用程序实例。
- 创建
SimpleDefaults 窗口并显示。 - 启动应用程序的事件循环。
使用场景
- 该代码主要用于科学实验和数据采集系统中,帮助管理和显示实验的各种参数。
- 适用于需要频繁调整参数和查看参数变化的场景,如实验室研究和工业控制系统。
8.17 - 实验运行监视器
这个代码定义了一个 StreamMonitor 类和一个 TableModel 类,用于监控和显示各种数据流(包括数据流、图像流、命令流和消息流)的内容。它还提供了一个主函数 main,用于初始化和运行一个包含多个标签页的 PyQt 应用程序,每个标签页显示不同类型的数据流。
概述
这个代码定义了一个 StreamMonitor 类和一个 TableModel 类,用于监控和显示各种数据流(包括数据流、图像流、命令流和消息流)的内容。它还提供了一个主函数 main,用于初始化和运行一个包含多个标签页的 PyQt 应用程序,每个标签页显示不同类型的数据流。
StreamMonitor 类
StreamMonitor 类继承自 QWidget,用于监控和显示不同类型的数据流。
主要方法和属性
初始化方法 __init__:
- 接受参数:
name(数据流名称)、streamtype(数据流类型,如 ‘Data’、‘Image’ 等)、parent(父组件)。 - 根据
streamtype 初始化不同类型的客户端对象(如 DataClient、ImageClient 等)。 - 初始化用户界面,包括标签、复选框、组合框、按钮、文本编辑器和表格视图等。
- 设置一个定时器,用于定期更新数据流的内容。
_update_message 方法:
- 定期从消息流中获取新消息,并将其添加到消息列表中。
- 如果启用了保存选项,则将新消息写入文件。
update_text 方法:
- 根据用户选择的过滤条件更新显示的消息内容。
- 使用
QTableView 显示过滤后的消息列表。
_update_selected_message 方法:
_update_list 方法:
- 定期从数据流中获取新数据,并将其添加到消息列表中。
load_selected_message 方法:
- 打开文件对话框,允许用户选择一个消息文件,并加载文件内容。
update_table_selected 方法:
on_checkbox_changed 方法:
TableModel 类
TableModel 类继承自 QAbstractTableModel,用于管理和显示表格数据。
主要方法和属性
初始化方法 __init__:
data 方法:
rowCount 方法:
columnCount 方法:
headerData 方法:
使用场景
- 该代码主要用于需要监控和显示实时数据流的应用程序。
- 适用于数据分析、系统监控和日志管理等场景。
- 提供了一种用户友好的方式,通过图形界面查看和管理不同类型的数据流和消息内容。
主函数 main
- 创建一个包含多个标签页的
QTabWidget,每个标签页显示不同类型的数据流。 - 初始化和运行 PyQt 应用程序。
通过这种方式,用户可以方便地在一个界面中监控和管理多种类型的数据流和消息内容。
8.18 - 实验任务折叠管理
这段代码定义了一个可折叠的对话框组件,允许用户在应用程序中添加和管理可折叠的部分。主要组件包括 SectionExpandButton 类和 CollapsibleDialog 类,它们协同工作以实现可折叠部分的创建和管理。
概述
这段代码定义了一个可折叠的对话框组件,允许用户在应用程序中添加和管理可折叠的部分。主要组件包括 SectionExpandButton 类和 CollapsibleDialog 类,它们协同工作以实现可折叠部分的创建和管理。
主要组件
SectionExpandButton 类继承自 QPushButton,用于创建一个可以展开或折叠其关联部分的按钮。
主要方法和属性
初始化方法 __init__:
- 接受参数:
item(关联的部分项)、text(按钮文本)、parent(父组件)。 - 设置按钮的初始文本,并连接点击事件到
on_clicked 方法。
on_clicked 方法:
- 处理按钮的点击事件,切换关联部分的展开或折叠状态。
- 如果部分是展开的,则将其折叠;如果是折叠的,则将其展开。
CollapsibleDialog 类
CollapsibleDialog 类继承自 QDialog,用于创建一个包含可折叠部分的对话框。
主要方法和属性
初始化方法 __init__:
- 创建并配置一个
QTreeWidget 以隐藏标题,并将其添加到对话框的布局中。 - 设置树的缩进为 0。
add_section 方法:
- 接受参数:
title(部分的标题)、widget(部分的内容部件)。 - 调用
add_button 方法创建一个按钮,并调用 add_widget 方法将内容部件添加为按钮的子项。
define_sections 方法:
- 定义并添加对话框中的所有部分。
- 示例实现中,创建了一个包含两个标签的
QFrame 部件,并将其添加到部分中。
add_button 方法:
- 接受参数:
title(部分的标题)。 - 创建一个
QTreeWidgetItem 项,并将其添加为树的顶级项。 - 创建一个
SectionExpandButton 按钮,将其设置为项的部件,并返回该项。
add_widget 方法:
- 接受参数:
button(按钮项)、widget(部分的内容部件)。 - 创建一个
QTreeWidgetItem 项,将其设置为按钮项的子项,并将内容部件设置为子项的部件。
使用场景
这个组件可以用于需要包含多个可折叠部分的对话框的应用程序,例如设置对话框、信息面板等。通过扩展 CollapsibleDialog 类并重写 define_sections 方法,可以轻松定义和管理对话框中的各个部分。
示例
下面是一个示例,展示如何使用 CollapsibleDialog 和 SectionExpandButton 类:
import sys
from PyQt6.QtWidgets import QApplication
class MyCollapsibleDialog(CollapsibleDialog):
def define_sections(self):
widget1 = QFrame(self.tree)
layout1 = QHBoxLayout(widget1)
layout1.addWidget(QLabel("Content 1"))
self.add_section("Section 1", widget1)
widget2 = QFrame(self.tree)
layout2 = QHBoxLayout(widget2)
layout2.addWidget(QLabel("Content 2"))
self.add_section("Section 2", widget2)
if __name__ == "__main__":
app = QApplication(sys.argv)
dialog = MyCollapsibleDialog()
dialog.define_sections()
dialog.show()
sys.exit(app.exec())
在这个示例中,MyCollapsibleDialog 类继承自 CollapsibleDialog 并重写了 define_sections 方法,定义了两个可折叠部分。运行此代码将显示一个包含两个可折叠部分的对话框。
9 - 应用案例
通过真实实验案例了解 Quatm 框架在量子物理研究中的广泛应用。
Quatm 已在世界一流量子实验室中稳定运行,支撑从基础原子物理到精密量子操控的全链条实验。
超冷原子实验
离子阱实验
原子/离子相互作用
系统校准
| 案例 | 说明 |
|---|
| 系统校准 | 相机暗噪声、快门响应、频率合成器验证、触发延迟标定等自动化校准任务 |
9.1 - MOT 装载优化
利用 Quatm 的参数扫描和多维时序控制,自动优化磁光阱装载效率。
功能介绍
该实验通过继承 Experiment 基类,实现对磁光阱(MOT)磁场线圈、冷却光和回泵光的协同控制。实验支持自动扫描磁场梯度和冷却光失谐两个维度,每次运行后通过吸收成像测量原子数,最终找到最优的 MOT 装载参数组合。
代码结构
- 导入
Experiment 基类和参数类型 - 定义
MOTLoadExperiment 类 - 在
build() 中声明设备和扫描参数 - 在
run() 中编排装载—压缩—探测时序
类:MOTLoadExperiment
简短功能介绍
继承自 Experiment 的实验类,负责 MOT 装载的完整自动控制流程。
方法:build()
功能:声明实验中使用的设备和可调参数。
参数声明:
b_gradient:磁场梯度(NumberValue,单位 G/cm)cooling_detuning:冷却光失谐(NumberValue,单位 MHz)loading_time:装载时间(NumberValue,单位 s)tof_time:自由飞行时间(NumberValue,单位 ms)
设备声明:
trap_coil_x、trap_coil_y、trap_coil_z:DAC 控制的磁场线圈cooling_aom、repump_aom:TTL 控制的激光开关camera_trigger:相机触发 TTL
方法:run()
功能:单次 MOT 装载—探测的执行逻辑。
主要步骤:
- 设置磁场线圈电流,建立梯度磁场
- 开启冷却光和回泵光,开始装载原子
delay(loading_time) 等待装载完成- 关闭磁场和冷却光,开始自由飞行
delay(tof_time) 等待原子云膨胀- 触发探测光脉冲和相机曝光
- 分析吸收图像,通过
DataClient 推送原子数
参数扫描
在 GUI 中为 b_gradient 和 cooling_detuning 设置扫描范围,Quatm 自动遍历所有组合,每次运行记录对应原子数。扫描完成后可绘制二维装载效率图谱。
涉及的设备
Trap 线圈(DAC×3)、冷却光 AOM(TTL+DAC)、回泵光(TTL)、探测光(TTL)、相机触发(TTL)、吸收成像相机
9.2 - 电场偏移补偿辅助工具
该代码实现了一个用于补偿电场漂移的辅助工具(CompensationHelper)。该工具通过使用 Qt 库构建图形界面,帮助进行电压扫描、数据管理和图形绘制。代码包含多个类,每个类负责特定的功能模块,例如图形绘制、控制参数设置和实验序列管理。
代码概述
该代码实现了一个用于补偿电场漂移的辅助工具(CompensationHelper)。该工具通过使用 Qt 库构建图形界面,帮助进行电压扫描、数据管理和图形绘制。代码包含多个类,每个类负责特定的功能模块,例如图形绘制、控制参数设置和实验序列管理。
依赖库
sys, time, numpy:标准库,用于系统操作、时间管理和数值计算。Qt:用于构建 GUI 应用程序。pyqtgraph:用于绘制图形。quatm.servers 和 quatm.GUI:自定义库,用于属性管理和 GUI 组件。
类和方法
CompensationHelper 类
CompensationHelper 继承自 BWidget,实现了电场补偿的主界面。
方法:
__init__(self, parent):初始化补偿助手,设置布局并添加绘图和控制小部件。
PlotWidget 继承自 QFrame,实现了绘图窗口。
方法:
__init__(self, parent):初始化绘图窗口,创建每个陷阱轴的标签页和数据流名称。constructScanRange(self):构建扫描范围,根据中心和跨度生成线性扫描范围。
TabWidget 继承自 QFrame,实现了每个陷阱轴的标签页。
方法:
__init__(self, name, _prop_root, datastream_names, n_yaxis=2, parent=None):初始化标签页,设置布局和按钮。toggleDataTaking(self):切换数据管理器的状态(启动/暂停)。setPlotDefaults(self):设置绘图的默认参数。avModeSwitch(self):切换平均模式的状态。
ControlWidget 继承自 QFrame,实现了控制窗口。
方法:
__init__(self, parent):初始化控制窗口,创建按钮和参数框。run_all_fn(self, progress_callback=None):运行所有轴的扫描函数。run_all(self):启动所有轴的扫描。print_output(self):打印输出。task_done(self):任务完成时调用。progress_fn(self, n):更新进度。init_data_taking(self):初始化数据采集。
SingleAxisWidget 继承自 QFrame,实现了单个轴的扫描控制。
方法:
__init__(self, name, parent):初始化单个轴的扫描控制窗口,设置布局和按钮。switch_tabs(self):切换标签页。findIntersection(self):找到两个线性拟合结果的交点。getFromDefaults(self):从默认值中获取补偿电压。pushToDefaults(self):将补偿电压推送到默认值。run_all_fn(self, progress_callback=None):运行所有扫描函数。init_data_manager(self):初始化数据管理器。start_scan(self):开始扫描。progress_fn(self, n):更新进度。run_done(self):扫描完成时调用。handle_error(self, err_msg):处理错误。clear(self):清除绘图。
CompVoltageScan 类
CompVoltageScan 继承自 QFrame,实现了电压扫描功能。
方法:
__init__(self, parent, axis_name):初始化电压扫描窗口,设置布局和按钮。initGUI(self):初始化用户界面,创建控件和布局。switchTabs(self):切换标签页。constructScanRange(self):构建扫描范围。initExperiment(self):初始化实验参数。updateScan(self):更新扫描参数。runExperimentSequence(self, progress_callback):运行实验序列。stop(self):停止扫描。run(self):启动扫描。progress_fn(self, n):更新进度。print_output(self, s):打印输出。thread_complete(self):线程完成时调用。terminate(self):终止扫描。
辅助函数
find_or_add(box, text)
在组合框中查找或添加项目。
def find_or_add(box, text):
"""if it's in the box, set it, if not, add and set it"""
idx = box.findText(text)
if idx < 0:
box.addItem(text)
idx = box.findText(text)
box.setCurrentIndex(idx)
总结
该代码实现了一个用于补偿电场漂移的辅助工具。通过图形用户界面,用户可以进行电压扫描、数据管理和图形绘制。代码包含多个类,每个类负责特定的功能模块,例如图形绘制、控制参数设置和实验序列管理。
9.3 - 离子装载与冷却
利用 Quatm 的多阶段时序控制,实现从激光烧蚀到荧光探测的完整离子装载流程。
功能介绍
该实验通过四个精确定时阶段:烧蚀、冷却、俘获和荧光探测,实现钡离子(Ba⁺)的自动装载。各阶段参数可在 GUI 中独立调节,支持确定性装载(失败自动重试)。
代码结构
- 导入
Experiment、NumberValue 和 BoolValue - 定义
IonLoading 类 - 在
build() 中声明各阶段参数和设备 - 在
run() 中串联四阶段时序
类:IonLoading
简短功能介绍
继承自 Experiment,管理离子装载的完整多阶段流程。
方法:build()
功能:声明离子装载所需的设备和可调参数。
参数声明:
ablation_power:烧蚀激光功率(NumberValue)cooling_493_power:493 nm 冷却光功率(NumberValue)cooling_650_power:650 nm 回泵光功率(NumberValue)cooling_time:Doppler 冷却时长(NumberValue)detection_time:荧光探测积分时间(NumberValue)enable_auto_retry:是否启用自动重试(BoolValue)
设备声明:
ablation_laser:烧蚀激光 TTLcooling_493:493 nm 冷却光(TTL + DAC)cooling_650:650 nm 回泵光(TTL + DAC)rf_trap:射频囚禁场(DDS)emccd:EMCCD 相机
方法:run()
功能:执行一次完整的离子装载序列。
主要步骤:
- 触发烧蚀激光脉冲,从靶材产生离子
- 开启 493 nm 冷却光和 650 nm 回泵光
delay(cooling_time) Doppler 冷却离子- 开启 EMCCD 曝光,采集荧光图像
delay(detection_time) 荧光积分- 调用
bright_spots.detect() 检测离子存在 - 若未检测到且
enable_auto_retry 为真,自动重试
涉及的设备
烧蚀激光(TTL)、冷却激光 493 nm(TTL+DAC)、回泵光 650 nm(TTL+DAC)、射频源(DDS)、EMCCD 相机
9.4 - 偶极阱优化辅助工具
该代码实现了一个名为 LittleHelper 的 Qt 桌面应用程序,它包含多个标签页,每个标签页提供不同的帮助功能。目前实现了两个帮助功能:xODT Alignment 和 Stray Field Compensation。
功能介绍
该代码实现了一个名为 LittleHelper 的 Qt 应用程序,它包含多个标签页,每个标签页提供不同的帮助功能。目前实现了两个帮助功能:xODT Alignment 和 Stray Field Compensation。
代码结构
- 导入必要的模块和库
- 定义
LittleHelper 类 - 定义
TabWidget 类 - 定义脚本入口
类:LittleHelper
简短功能介绍
LittleHelper 类是一个主窗口类,用于创建和显示包含多个标签页的主窗口。
方法:__init__
功能:初始化 LittleHelper 对象,设置窗口标题并创建标签页部件。
参数:
*args 和 **kwargs:可变参数和关键字参数,用于初始化基类。
主要步骤:
- 调用父类的
__init__ 方法。 - 设置窗口标题为 “Little Helper”。
- 创建并设置
TabWidget 作为中央部件。
简短功能介绍
TabWidget 类是一个包含多个标签页的部件,每个标签页提供不同的帮助功能。
方法:__init__
功能:初始化 TabWidget 对象,创建并添加标签页。
参数:
主要步骤:
- 调用父类的
__init__ 方法。 - 创建主布局并设置为垂直布局。
- 初始化标签页组件
QTabWidget。 - 创建并添加标签页:
tab1:OdtAlignmentHelper 标签页,用于 xODT 对准。tab2:CompensationHelper 标签页,用于杂散场补偿。
- 将标签页添加到
QTabWidget 中。 - 将
QTabWidget 添加到主布局中并设置布局。
脚本入口
简短功能介绍
脚本入口用于创建应用程序实例,显示主窗口并启动应用事件循环。
主要步骤
- 创建
QApplication 实例。 - 创建
LittleHelper 实例。 - 显示主窗口。
- 启动应用事件循环。
主要类和方法
脚本入口
- 创建
QApplication 实例。 - 创建
LittleHelper 实例并显示主窗口。 - 启动应用事件循环。
9.5 - 系统校准
Quatm 在日常实验系统校准与维护中的自动化应用。
功能介绍
除物理实验外,Quatm 将日常校准任务也编为标准实验脚本,实现一键运行和自动记录。覆盖相机暗噪声、快门响应、频率合成器验证和触发延迟标定等常见校准需求。
代码结构
所有校准实验均遵循相同的结构模式:
- 继承
Experiment 类 - 在
build() 中声明被测设备和校准参数 - 在
run() 中执行校准流程并自动记录结果
典型校准任务
相机暗噪声表征
功能:在无光条件下连续采集图像帧,统计暗电流噪声分布。
主要步骤:
- 关闭所有光源,设置相机曝光时间
- 循环采集 N 帧暗图像
- 计算每像素的均值和标准差
- 保存噪声图谱至 HDF5
涉及设备:相机
快门响应时间测量
功能:测量机械快门从 TTL 触发到完全开启/关闭的延迟时间。
主要步骤:
- 光电探测器对准快门后的光束
- TTL 触发快门开启,同步启动高速采集
- 记录探测器信号上升/下降沿时间
- 重复测量取平均
涉及设备:快门(TTL)、光电探测器
频率合成器验证
功能:验证 Valon 5009 或 DDS 频率合成器的实际输出频率和功率。
主要步骤:
- 设置频率合成器到目标频率
- 频谱仪测量实际输出
- 扫描频率范围,记录偏差
- 生成校准曲线
涉及设备:Valon 5009/DDS(串口)、频谱仪
相机触发延迟标定
功能:测量 TTL 触发到相机实际曝光窗口之间的延迟。
主要步骤:
- 脉冲光源与相机触发共享同一 TTL 信号
- 扫描触发延迟参数
- 检测每帧中光脉冲出现位置
- 标定最佳延迟值
涉及设备:相机、脉冲光源(TTL)
9.6 - 原子—离子碰撞实验
利用 Quatm 的多系统协同控制,研究冷原子与单离子之间的碰撞动力学。
功能介绍
该实验同时控制冷原子(Rb)和单离子(Ba⁺)两套独立系统。通过精确的空间和时间重叠,研究低温下原子—离子碰撞的动力学过程。Quatm 将两套系统的设备统一管理,确保时序同步。
代码结构
- 导入
Experiment、NumberValue 和 BoolValue - 定义
AtomIonInteraction 类 - 在
build() 中声明两套系统的设备和参数 - 在
run() 中协调原子和离子的并行时序
类:AtomIonInteraction
简短功能介绍
继承自 Experiment,管理原子和离子两套控制系统的协同运行。
方法:build()
功能:声明原子和离子两侧的全部设备和参数。
原子侧参数声明:
mot_loading_time:MOT 装载时间(NumberValue)mot_b_gradient:磁场梯度(NumberValue)
离子侧参数声明:
ion_position_x、ion_position_y:离子在阱中位置(NumberValue)interaction_time:相互作用等待时间(NumberValue)
设备声明:
- 原子侧:
trap_coil_*(DAC×3)、cooling_aom(TTL)、repump_aom(TTL)、camera(吸收成像) - 离子侧:
paul_electrode_*(DAC×4)、ablation_laser(TTL)、cooling_493(TTL+DAC)、emccd
方法:run()
功能:执行一次原子—离子碰撞实验。
主要步骤:
- 并行启动原子 MOT 装载和离子装载
- 移动离子到预定位置(
ion_position_x、ion_position_y) - 等待 MOT 装载完成,压缩原子云
- 原子云与离子在空间和时间上重合
delay(interaction_time) 等待碰撞发生- 分别检测:吸收成像测原子损失,荧光探测测离子态变化
- 两路数据通过
DataClient 分别推送
涉及的设备
原子侧:MOT 线圈(DAC×3)、冷却/回泵光(TTL×2)、吸收成像相机
离子侧:Paul 阱电极(DAC×4)、烧蚀激光(TTL)、冷却光(TTL+DAC)、EMCCD
9.7 - 量子态操控与检测
利用 Quatm 的精确时序和统计分析,实现离子量子态的光学泵浦与状态相关荧光检测。
功能介绍
该实验实现 D 态 shelving 量子态检测协议:通过光学泵浦将离子制备到暗态,施加微波操控后,利用状态相关荧光区分 S 态和 D 态。自动重复数百次测量,统计量子跃迁概率。
代码结构
- 导入
Experiment、NumberValue 和 StringCombo - 定义
QuantumStateDetection 类 - 在
build() 中声明操控和检测参数 - 在
run() 中编排泵浦—操控—检测序列
类:QuantumStateDetection
简短功能介绍
继承自 Experiment,封装量子态操控与荧光检测的完整协议。
方法:build()
功能:声明量子态检测所需的设备和参数。
参数声明:
mw_frequency:微波频率(NumberValue)mw_duration:微波脉冲宽度(NumberValue)pump_duration:光学泵浦时间(NumberValue)repetitions:重复测量次数(NumberValue)scan_mode:扫描模式(StringCombo:频率扫描/功率扫描/时间扫描)
设备声明:
valon_5009:微波频率合成器cooling_493:冷却/探测光(TTL + DAC)cooling_650:回泵/泵浦光(TTL + DAC)emccd:EMCCD 相机pmt_counter:PMT 光子计数器
方法:run()
功能:执行一次量子态检测序列。
主要步骤:
- Doppler 冷却离子
- 光学泵浦到暗态(D₅/₂)
- 施加微波脉冲驱动量子跃迁
- 开启探测光,PMT 记录荧光光子数
- 根据光子数阈值判断离子终态(亮/暗)
- 重复 N 次,统计跃迁概率
- 切换微波频率/功率,进入下一次扫描点
涉及的设备
微波源(Valon 5009)、冷却光(TTL+DAC)、回泵光(TTL+DAC)、EMCCD、PMT 光子计数器
9.8 - 吸收成像
利用 Quatm 的相机控制和图像分析,实现原子云吸收成像的自动化采集与分析。
功能介绍
该实验通过集成相机触发、图像采集和高斯拟合,实现冷原子吸收成像的全自动流程。支持三帧成像法(原子像、背景像、探测光像),自动计算光学深度分布,并通过 gaussfit 模块拟合提取原子数和温度。
代码结构
- 导入
Experiment、NumberValue 和 gaussfit 分析模块 - 定义
AbsorptionImaging 类 - 在
build() 中声明相机和探测光参数 - 在
run() 中编排成像时序并调用分析
类:AbsorptionImaging
简短功能介绍
继承自 Experiment,封装吸收成像的完整采集与分析流程。
方法:build()
功能:声明实验设备和成像参数。
参数声明:
exposure_time:相机曝光时间(NumberValue)probe_pulse_duration:探测光脉冲宽度(NumberValue)tof_time:自由飞行膨胀时间(NumberValue)
设备声明:
camera:Andor 或 BlackFly 相机probe_aom:探测光 TTL 控制trap_coil_z:Z 方向磁场线圈
方法:run()
功能:执行一次完整的吸收成像探测。
主要步骤:
- 关闭磁场线圈,释放原子云
delay(tof_time) 等待自由飞行- 触发探测光脉冲(
probe_aom = True) - 同步触发相机曝光
- 读取图像数据
- 调用
gaussfit.fit_2d() 拟合光学深度 - 通过
DataClient 发送原子数和温度结果
涉及的设备
探测光 AOM(TTL)、相机(Andor/BlackFly)、磁场线圈(DAC)
9.9 - 光偶极阱实验
利用 Quatm 的双参数扫描和寿命测量功能,研究 ODT 中冷原子的俘获与损耗特性。
功能介绍
该实验实现对光偶极阱(ODT)的功率控制、频率扫描和原子寿命自动测量。支持 ODT 功率和射频频率的双参数扫描,用于精确标定 Feshbach 共振位置。
代码结构
- 导入
Experiment、NumberValue 和 BoolValue - 定义
ODTExperiment 类 - 在
build() 中声明 ODT 设备和扫描参数 - 在
run() 中编排装载、俘获和探测时序
类:ODTExperiment
简短功能介绍
继承自 Experiment,管理 ODT 的功率控制、频率扫描和寿命测量。
方法:build()
功能:声明 ODT 实验所需的设备和参数。
参数声明:
odt_power:ODT 激光功率(NumberValue)rf_frequency:射频频率(NumberValue,用于 Feshbach 扫描)hold_time:原子在 ODT 中的停留时间(NumberValue)enable_rf:是否启用射频(BoolValue)
设备声明:
odt_aom:ODT 光路 AOM(DAC + TTL)valon_5009:射频频率合成器camera:吸收成像相机
方法:run()
功能:执行一次 ODT 俘获—探测循环。
主要步骤:
- MOT 装载原子云
- 开启 ODT 激光,关闭磁场线圈
delay(hold_time) 保持原子在 ODT 中- 关闭 ODT,释放原子
- 吸收成像探测剩余原子数
- 记录 ODT 功率和原子数至 HDF5
涉及的设备
ODT 激光 AOM(DAC+TTL)、射频源(Valon 5009)、磁场线圈(DAC)、吸收成像相机
10 - 实验最佳实践
编写可靠、高效的 Quatm 实验脚本的建议与技巧。
实验结构设计
单一职责原则
每个实验脚本聚焦一个明确的物理目标,避免混合多个不相关的逻辑:
experiments/
├── absorption_imaging.py # 吸收成像
├── fluorescence_detect.py # 荧光探测
├── rabi_scan.py # Rabi 振荡
└── sideband_cooling.py # 边带冷却
复用公共逻辑
将重复步骤提取为 Mixin 类:
class CoolingMixin:
def doppler_cooling(self, duration=5):
self.cooling_laser = True
self.repump_laser = True
from quatm.experiment.experiment import delay
delay(duration)
self.cooling_laser = False
class SidebandExperiment(CoolingMixin, Experiment):
def run(self):
self.doppler_cooling()
# ... 后续步骤
设备管理
在 build 中声明,在 run 中使用
def build(self):
self.setattr_device("camera") # 声明
self.setattr_device("fpga")
def run(self):
self.camera.expose(0.1) # 使用
设备状态检查
在实验开始前检查设备连接和状态:
def run(self):
if not self.controller.is_ready():
raise RuntimeError("控制器未就绪")
self.camera.set_temperature(-70)
错误处理与恢复
异常安全关闭
务必在 finally 或上下文管理器中确保关键设备安全关闭:
def run(self):
try:
self.mot_coils = True
with realtime():
self.cooling_laser = True
delay(5000)
finally:
self.cooling_laser = False
self.mot_coils = False
使用模拟模式测试
在连接真实硬件前,先通过模拟模式验证实验逻辑:
# 在 device_db.py 中设置模拟模式
"/Devices/simulating": True
性能优化
合理使用 realtime 上下文
realtime() 上下文内的代码直接转换为 FPGA 时序指令,避免在其中放入复杂计算:
# ❌ 不推荐
with realtime():
result = complex_computation() # 计算耗时不明确
self.dac_output = result
# ✅ 推荐
result = complex_computation() # 在 realtime 外完成计算
with realtime():
self.dac_output = result
大数据流优化
对于图像等大数据,使用 ImageClient 而非 DataClient,确保数据通道不被阻塞。
测试策略
单元测试
每个自定义驱动和 Mixin 应编写对应的单元测试:
# tests/test_cooling_mixin.py
def test_doppler_cooling():
exp = MockExperiment()
exp.doppler_cooling(duration=1)
assert exp.cooling_laser == False # 冷却结束后应关闭
集成测试
在模拟模式下运行完整实验流程,验证各组件协作正常。
常见问题
| 问题 | 说明 | 解决方案 |
|---|
delay() 单位混淆 | delay(100) 是 100ms,不是 100s | 使用 delay(5*1000) 明确表示秒 |
| 忘记关闭激光/磁场 | 实验异常退出时设备保持开启 | 使用 try/finally 确保关闭 |
| 属性缓存未刷新 | PropertyAttribute 值未及时同步 | 始终使用 .value 读写属性 |
| 相机未冷却就采集 | 暗电流噪声过大 | 采集前检查温度:assert camera.temperature <= -60 |
## 数据管理
通过 `DataClient` 发送结构化的实验数据:
```python
def run(self):
self._dataq.send({
"atom_count": N,
"temperature": T,
"b_field": self.b_field,
})
数据以 HDF5 格式保存,自动包含时间戳和扫描参数。
性能优化
- 减少 GUI 更新频率:仅在关键步骤更新显示
- 使用
simulation_class_decorator 在模拟模式下快速迭代 - 高频循环中避免
print(),使用 send_debug() 代替
错误处理
def run(self):
try:
self.controller.start_process(1)
delay(10)
finally:
self.controller.reset()
self.shutter = False
11 - 物理模型库
量子物理实验的物理建模与计算工具
概述
Quatm 物理模型库(physics)提供冷原子/离子混合实验所需的物理建模和计算工具。它包含原子属性数据库、光与物质相互作用计算、光偶极阱(ODT)势建模、Feshbach 共振分析等功能。
原子数据库 — quatm.physics.odt.atomlib
提供常用实验原子/离子的物理属性数据,包含基态到激发态的跃迁频率、线宽、Clebsch-Gordan 耦合系数等。
预定义原子
| 原子/离子 | 字典名 | 典型用途 |
|---|
| Ba⁺ | BariumDict | 离子阱量子计算 |
| ⁶Li | LithiumDict | 超冷费米气体 |
| Mg⁺ | MagnesiumDict | 离子阱量子计算 |
| ⁸⁷Rb | RubidiumDict | 玻色-爱因斯坦凝聚 |
| Ca⁺ | CalciumDict | 离子阱精密测量 |
属性字段
每个原子字典包含以下物理常数:
| 字段 | 说明 |
|---|
name | 元素/同位素名称 |
charge | 电荷量 (C) |
mass | 原子质量 (kg) |
SP_frequencies | 强跃迁 (S→P) 角频率 |
SP_decays | 强跃迁线宽 (角频率) |
SP_linpolcoupling | Clebsch-Gordan 平方耦合系数 |
DP_frequencies | 弱跃迁 (D 态) 频率 |
DP_decays | 弱跃迁线宽 |
DP_linpolcoupling | 弱跃迁耦合系数 |
使用示例
from quatm.physics.odt.atomlib import Atom, BariumDict
# 创建钡离子实例
ba_ion = Atom(BariumDict)
print(f"质量: {ba_ion.mass:.2e} kg")
print(f"电荷: {ba_ion.charge:.2e} C")
预实例化的原子可直接导入:Ba, Li, Mg, Rb, Ca。
光与物质相互作用 — quatm.physics.odt.lightmatterint
计算给定原子和激光配置下的光-物质相互作用量,基于 Metcalf 和 van der Straten 的形式理论。
LMinteraction 类
from quatm.physics.odt.lightmatterint import LMinteraction
from quatm.physics.odt.atomlib import Ba
from quatm.physics.odt.lasers import Laser
# 创建激光对象和相互作用计算器
laser = Laser(wavelength=532e-9, power=10.0, waist=50e-6)
lm = LMinteraction(ion=Ba, laser=laser)
关键方法
| 方法 | 功能 | 公式 |
|---|
SPStarkShift(transition) | 单跃迁 AC Stark 位移 | \(\delta_n = -\frac{3\pi c^2}{2\omega_0^3} \left(\frac{\Gamma}{\omega_0-\omega_L} + \frac{\Gamma}{\omega_0+\omega_L}\right) I\) |
S12shift() | S→P 总 Stark 位移 | 各跃迁加权求和 |
ScattRate(transition) | 单跃迁散射率 | 非共振光子散射速率 |
TotalScattRate() | 总散射率 | 所有强跃迁散射率之和 |
光偶极阱建模 — quatm.physics.odt.opticaltraputils
Trap 类
建模完整的光偶极阱势,综合计算以下贡献:
- 一个或多个高斯激光束的光学势
- 直流电场(杂散场和四极曲率)
- 与附加囚禁离子的库仑相互作用
from quatm.physics.odt.opticaltraputils import Trap
trap = Trap(
laser=laser,
ion=ba_ion,
efields=efield_config,
laseroffset=(0.0, 0.0) # 激光束偏离阱中心的位置
)
关键方法
| 方法 | 说明 |
|---|
AnalTrapDepth() | 无线性杂散场时的解析阱深 (mK) |
FullPotential2D(x, y) | 计算 (x, y) 处的 2D 完整势 |
FullPotential3D(x, y, z) | 计算 (x, y, z) 处的 3D 完整势 |
FullPotential(point, ion_pos) | 计算空间某点的完整势 (K),可含其他离子位置 |
物理学公式参考
AC Stark 位移
光偶极阱中原子经历的 AC Stark 位移:
$$U_{\text{dip}} = -\frac{3\pi c^2}{2\omega_0^3} \left(\frac{\Gamma}{\omega_0 - \omega_L} + \frac{\Gamma}{\omega_0 + \omega_L}\right) I$$
其中 $\omega_0$ 为原子共振频率,$\omega_L$ 为激光频率,$\Gamma$ 为跃迁线宽,$I$ 为激光强度。
光子散射率
非共振光子散射导致的加热速率为:
$$\Gamma_{\text{sc}} = \frac{3\pi c^2}{2\hbar\omega_0^3} \left(\frac{\omega_L}{\omega_0}\right)^3 \left(\frac{\Gamma}{\omega_0 - \omega_L} + \frac{\Gamma}{\omega_0 + \omega_L}\right)^2 I$$
11.1 - 原子数据库 (atomlib)
Ba、Rb、Li、Mg、Ca 原子属性——质量、跃迁频率、Clebsch-Gordan 系数。
概述
atomlib 提供常用冷原子和离子实验原子种类的预计算物理数据。
预定义原子
| 字典 | 种类 | 典型用途 |
|---|
BariumDict | Ba⁺ | 离子阱量子计算 |
RubidiumDict | ⁸⁷Rb | 玻色-爱因斯坦凝聚 |
LithiumDict | ⁶Li | 超冷费米气体 |
MagnesiumDict | Mg⁺ | 离子阱精密测量 |
CalciumDict | Ca⁺ | 离子阱光钟 |
属性字段
| 属性 | 说明 |
|---|
mass | 原子质量 (kg) |
ground_state | 基态能级标识 |
excited_state | 激发态能级标识 |
transition_frequency | 跃迁频率 (Hz) |
decay_rate | 自发辐射衰减率 (s⁻¹) |
clebsch_gordan | Clebsch-Gordan 耦合系数 |
11.2 - 电场计算 (efields)
离子阱电场势能——杂散场、曲率和一维离子位置计算。
概述
efields 计算 Paul 阱中离子的电场势能分布,支持杂散场和曲率参数,基于 James 方法求解一维离子平衡位置。
类
| 类 | 说明 |
|---|
efields | 电场势能计算,含杂散场和曲率 |
DCTrap | 管理平均/随机杂散场配置 |
from quatm.physics.odt.efields import efields
field = efields(stray_field=(1e-3, 0, 0), curvature=0.01)
potential = field.compute_potential(x_grid)
11.3 - 激光模型 (lasers)
高斯光束激光——光束尺寸、强度、波前曲率和缩放电场。
概述
Laser 类建模高斯光束激光器,管理波长/频率/波数的自动同步转换,计算沿传播方向的光束尺寸、R 曲率半径和缩放电场。
from quatm.physics.odt.lasers import Laser
laser = Laser(wavelength=1064e-9, power=10.0, waist=50e-6)
intensity = laser.intensity(z=0.0)
w = laser.beam_radius(z=0.01)
11.4 - 光物质作用 (lightmatterint)
AC Stark 频移和散射率——S→P 和 D→P 跃迁的 Clebsch-Gordan 加权计算。
概述
LMinteraction 计算激光场与原子的相互作用:包括基态到激发态(S→P)和亚稳态到激发态(D→P)的 AC Stark 频移及离共振光子散射率。
from quatm.physics.odt.lightmatterint import LMinteraction
lm = LMinteraction(atom=Ba, laser=laser)
shift = lm.stark_shift(intensity=1e6) # Hz
rate = lm.scattering_rate(intensity=1e6) # s⁻¹
11.5 - 光阱模型 (opticaltraputils)
复合阱——偶极光束+电场的全 1D/2D/3D 势阱计算。
概述
Trap 将高斯光束光偶极阱与静电场组合为复合势阱模型,计算阱深(势能转折点)和三维势能分布。
from quatm.physics.odt.opticaltraputils import Trap
trap = Trap(laser=odt_laser, efield=dc_field)
depth = trap.trap_depth() # µK
potential_2d = trap.potential_2d(x, y, z=0)
11.6 - 统计工具 (statistics)
二项式 Wilson 评分区间——离子态判别置信区间。
概述
statistics 提供基于 Wilson 评分区间的二项式比例置信区间工具,用于离子态判别的统计误差估计。
| 函数 | 说明 |
|---|
wilson_score(p, n) | 计算比例 p 的 Wilson 评分 |
wilson_err(p, n) | Wilson 置信区间半宽 |
getrandbincont(p, n, N) | 从二项式结果采样 N 次实验概率 |
Wigner 符号 (utils)
utils 模块提供 Wigner3j 和 Wigner6j 符号的完整 Racah 公式实现,用于角动量耦合计算。
12 - 代码贡献指南
如何对Quatm项目贡献您的智慧
Quatm是一个开源项目,我们热爱并欢迎大家提交补丁和贡献,以使Quatm及其文档变得更好。
贡献Quatm
Quatm主要托管在 https://github.com/quatm/quatm,并在项目私有Git服务器进行镜像备份。
贡献者许可协议
在您参与对本项目的贡献时,除非在有书面协议的例外情况下,您(或您的雇主)保留对您的贡献的版权,并自动给予我们使用和重新分发您的贡献作为项目一部分的权限。具体细节请参考本项目的贡献者许可协议。
代码审核
所有提交都需要经过审核。我们使用 GitHub 的Pull Request(Merge Request)进行代码审核。
社区准则
在交流讨论中,请遵循 Quatm社区准则。
创建问题
如果您想在Quatm中看到某些功能(或者发现某些功能没有按预期工作),但您不确定如何自己修复,请创建一个 issue。您也可以通过社交媒体直接与我们联系。
报告 Bug
- 使用 GitHub Issue 的 Bug 报告模板创建新 Issue
- 详细描述问题:你期望看到什么?实际看到了什么?
- 附上截图和 GIF 动画,展示操作步骤和问题现象
- 提供复现步骤,使维护者能快速定位问题
功能建议
- 使用 GitHub Issue 的功能建议模板
- 清晰简洁地描述建议的功能
- 尽可能包含使用场景和预期效果
Pull Request 流程
- Fork 项目仓库
- 创建功能分支:
git checkout -b feature/my-feature - 编写代码并添加测试
- 确保所有状态检查通过
- 提交 PR 并填写 PR 模板
代码风格
Python 代码风格
所有 Python 代码必须遵循 PEP 8 规范:
- 使用 4 空格缩进
- 类名使用
CamelCase,函数和变量使用 snake_case - 导入顺序:标准库 → 第三方库 → 本地模块
- 为公开 API 编写 docstring
Git 提交信息规范
- 使用现在时态(“Add feature”,不是 “Added feature”)
- 使用祈使语气(“Move cursor to…",不是 “Moves cursor to…")
- 第一行限制在 72 字符以内
- 在第一行之后引用相关 Issue 编号
示例:
Add temperature monitor driver for LFI3751
Implement RS-232 communication and PID auto-tuning
for the Wavelength Electronics LFI3751 controller.
Closes #42
社区联系方式
13 - 监控设备
实验室环境监测设备驱动 — 温度控制器、高斯计、示波器、激光控制器、真空规
概述
quatm.monitor 包提供实验室硬件和环境条件的监控驱动。每个监控器作为独立进程运行,通过 RPC 框架暴露功能,持续轮询硬件设备并将读数发布到分布式属性系统,供 GUI、日志和实验反馈使用。
注意:每个监控模块都是可独立运行的脚本。RPC 绑定地址通过命令行参数配置。
温度控制器 — LFI3751
Wavelength Electronics LFI-3751 温度控制器驱动,通过 RS-232 串口通信。
主要功能
- NTC 热敏电阻校准(Steinhart-Hart 系数)
- 温度和电流限制配置
- PID 自动优化 (
auto_PID) - 传感器类型选择(热敏电阻、RTD、AD590、LM335)
使用示例
from quatm.monitor.LFI3751 import LFI3751
tc = LFI3751("/dev/ttyUSB0")
# 配置 NTC 热敏电阻参数
tc.set_sensor_properties(a=1.125e-3, b=2.347e-4, c=8.563e-8)
# 设置温度限制
tc.set_temperature_limits(lo=15.0, hi=35.0)
# 设定目标温度并启动
tc.set_temperature(25.0)
tc.turn_on()
# 读取当前温度
current_temp = tc.get_temperature()
| 参数 | 说明 |
|---|
port | 串口设备路径,如 /dev/ttyUSB0 |
高斯计 — PCE-MFM_3000
PCE-MFM 3000 高斯计驱动,通过串口返回磁场读数(Gauss)。
使用示例
from quatm.monitor.PCE_MFM_3000 import PCE_MFM_3000
gm = PCE_MFM_3000("/dev/ttyUSB1")
b_field = gm.get_b() # 返回磁场值 (Gauss)
⚠️ 注意:霍尔探头的磁场校准会随时间漂移,Feshbach 共振实验建议定期对照已知原子跃迁(如 RF 谱)重新校准。
示波器 — ds1054z
Rigol DS1054Z 数字示波器驱动,通过 PyVISA SCPI 命令进行波形捕获、电压测量和频率分析。
激光控制器 — dlc_pro
Toptica DLC pro 激光控制器接口,监控激光二极管电流、温度设定值、压电扫描参数和锁频状态。
使用示例
from quatm.monitor.dlc_pro import toptica
laser = toptica("192.168.1.50", 1998)
locked = laser.get_lock_status() # 检查锁频状态
error = laser.get_error_signal() # 读取锁频误差信号
真空规 — mvc3
真空规驱动,用于监测实验腔体的真空度。在冷原子实验中,超高真空(UHV)环境对原子寿命至关重要。
13.1 - LFI3751 温控器
Wavelength Electronics LFI3751 温控器驱动——PyVISA 通信。
概述
LFI3751 驱动 Wavelength Electronics 的高精度半导体激光器温控器,通过 PyVISA 通信。
from quatm.monitor.LFI3751 import LFI3751
tc = LFI3751(addr="USB0::...")
temp = tc.get_temperature()
tc.set_setpoint(25.0)
13.2 - 高斯计 (PCE-MFM 3000)
PCE-MFM 3000 高斯计驱动——串口通信,实时磁场测量。
概述
PCE_MFM_3000 驱动 PCE Instruments 的磁场强度测量仪,通过串口实时读取磁感应强度。
from quatm.monitor.PCE_MFM_3000 import PCE_MFM_3000
gauss = PCE_MFM_3000(port="/dev/ttyUSB0")
field = gauss.get_field() # 返回 mT 值
13.3 - 腔体环境传感器
Arduino 温湿度气压传感器——腔体环境实时监测。
概述
arduino 驱动通过 Arduino Nano 读取腔体内的温度、湿度和气压传感器数据。
from quatm.monitor.cavity_arduino import arduino
env = arduino(port="/dev/ttyACM0")
temp, hum, press = env.read_all()
13.4 - PC 健康监控
CPU/内存/磁盘/网络实时监控——基于 psutil。
概述
PC_health 通过 psutil 监控实验控制计算机的 CPU 使用率、内存占用、磁盘空间和网络流量,防止因资源耗尽导致实验中断。
from quatm.monitor.pc_health import PC_health
health = PC_health()
cpu = health.get_cpu_percent()
mem = health.get_memory_usage()
disk = health.get_disk_free()
13.5 - 示波器 (DS1054Z)
Rigol DS1054Z 示波器驱动——PyVISA 波形采集与电压测量。
概述
ds1054z 驱动 Rigol DS1054Z 四通道数字示波器,通过 PyVISA 进行波形采集和自动测量。
from quatm.monitor.ds1054z import ds1054z
scope = ds1054z(addr="USB0::...")
waveform = scope.get_waveform(channel=1)
vpp = scope.measure_vpp(channel=1)
14 - 工具函数
Quatm 通用工具函数 — 变密度采样等辅助功能
概述
quatm.utils 包提供 Quatm 框架中跨模块使用的通用工具函数。
变密度采样 — quatm.utils.vds
变密度采样(Variable Density Sampling, VDS)允许在参数空间中高效探索,将采样点集中在感兴趣的区域(如量子系统中的共振或相变附近)。
核心思想
在物理实验中,某些参数区域比其他区域更有意义。例如:
- Feshbach 共振附近的磁场扫描
- 光谱线中心附近的频率扫描
- 相变临界点附近的参数探索
VDS 通过在感兴趣区域自动加密采样点,在平坦区域稀疏采样,实现以最少的数据点获取最多信息。
gauss_prime_norm — 归一化高斯导数
高斯函数的导数,归一化到最大值为 1:
$$f(x) = \sqrt{e} \cdot \frac{x - \mu}{\sigma} \exp\left(-\frac{(x-\mu)^2}{2\sigma^2}\right)$$
from quatm.utils.vds import gauss_prime_norm
# 计算 x=5.0 处的高斯导数值
val = gauss_prime_norm(5.0, mu=5.0, sigma=1.0)
| 参数 | 说明 |
|---|
x | 输入值,可以是标量或 numpy.ndarray |
mu | 高斯中心 |
sigma | 高斯标准差 |
gauss_prime_norm_abs — 绝对值归一化高斯导数
高斯导数绝对值的归一化形式,适合用作对称峰检测的兴趣函数。
create_support_points_stochastic — 随机支持点生成
从精细等距网格开始,随机移除低兴趣区域的点,保留高兴趣区域的点。
from quatm.utils.vds import (
create_support_points_stochastic,
gauss_prime_norm_abs
)
# 定义兴趣函数:在 x=5.0 附近集中采样
def interest(x, center, width):
return gauss_prime_norm_abs(x, center, width)
points = create_support_points_stochastic(
start=0.0, # 扫描起点
stop=10.0, # 扫描终点
steps=50, # 最终支持点数量
interest_fn=interest,
max_stepsize=0.5, # 最大允许步长
enhancement=0.8, # 0-1,1 表示强增强
center=5.0, # 传递给 interest_fn
width=1.0 # 传递给 interest_fn
)
| 参数 | 说明 |
|---|
start | 扫描起点,始终包含在最终支持点中 |
stop | 扫描终点,始终包含在最终支持点中 |
steps | 最终支持点数量 |
interest_fn | 兴趣函数 f(x, **kwargs),返回 0(低兴趣)到 1(高兴趣) |
max_stepsize | 相邻支持点最大间距 |
enhancement | 0-1,1 表示强增强感兴趣区域,0 表示均匀随机采样 |
**kwargs | 传递给 interest_fn 的额外参数 |
应用场景
变密度采样特别适用于:
- Feshbach 共振谱扫描:在共振峰附近加密采样
- 光谱线扫描:在线心附近提高分辨率
- 相变参数扫描:在临界区域精细探索
- 阱频率测量:在预期共振频率附近集中采样
14.1 - 变密度采样 (VDS)
变密度采样——在感兴趣区域密集采样,边缘稀疏采样的实验参数生成器。
概述
quatm.utils.vds 提供变密度采样(Variable Density Sampling)工具,用于生成实验扫描参数。在参数空间的感兴趣区域密集采样,而在边缘区域稀疏采样,优化有限的实验时间。
函数
| 函数 | 说明 |
|---|
create_support_points_stochastic(limits, n, roi) | 随机变密度采样点生成 |
gauss_prime_norm(x, mu, sigma) | 高斯归一化导数 |
gauss_prime_norm_abs(x, mu, sigma) | 高斯归一化导数的绝对值 |
用法
from quatm.utils.vds import create_support_points_stochastic
points = create_support_points_stochastic(
limits=[(0, 100), (0, 50)], # 参数范围
n=200, # 采样点数
roi=[(30, 70), (20, 30)], # 感兴趣区域(密集采样)
)