这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

实验最佳实践

编写可靠、高效的 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