QuLab 需要在 Jupyter Notebook 中使用。
- 安装 MongoDB,用于存储数据、历史代码、仪器配置、用户信息。
- 制作 ssl 证书,用于 InstrumentServer 加密。
python -m pip install QuLab
或者
git clone https://github.com/feihoo87/QuLab.git
cd QuLab
python -m pip install .
创建配置文件 config.yaml
,若使用 Windows 系统,将其置于%ProgramData%\QuLab\
路径下。
ca_cert: &ca_cert /path/to/CACert/ca.pem
db:
db: lab
host: [10.122.7.18, 10.122.7.19, 10.122.7.20]
username: lab_admin
password: 'lab_password'
authentication_source: lab
replicaSet: rs0
ssl: true
ssl_ca_certs: *ca_cert
ssl_match_hostname: true
server_port: 8123
server_name: ['localhost', '127.0.0.1', '10.122.7.18']
ssl:
ca: *ca_cert
cert: /path/to/sslcert/server.crt
key: /path/to/sslkey/server.key
from lab.admin import register
register()
import lab
lab.login()
定义 App
import numpy as np
import asyncio
import lab
class TestApp(lab.Application):
'''一个简单的 App'''
async def work(self):
async for x in self.sweep['x']:
yield x, np.random.randn()
async def set_x(self, x):
await asyncio.sleep(0.5)
# print('x =', x)
@staticmethod
def plot(fig, data):
x, y = data
ax = fig.add_subplot(111)
ax.plot(x, y)
ax.set_xlabel('x (a.u.)')
ax.set_ylabel('y (a.u.)')
将其提交到数据库
TestApp.save(package='test')
一旦将App提交到数据库,以后就不必重复将代码复制过来运行了。直接配置并运行即可。
import lab
import numpy as np
app = lab.make_app('TestApp', package='test').sweep([
('x', np.linspace(0, 1, 11))
])
lab.make_figure_for_app(app)
app.run()
import numpy as np
import asyncio
import lab
class ComplexApp(lab.Application):
'''一个复杂点的 App'''
async def work(self):
async for y in self.sweep['y']:
# 一定要注意设置 parent
app = lab.make_app('test.TestApp', parent=self)
x, z = await app.done()
yield x, y, z
async def set_y(self, y):
await asyncio.sleep(0.5)
# print('x =', x)
def pre_save(self, x, y, z):
if self.data.rows > 1:
x = x[0]
return x, y, z
@staticmethod
def plot(fig, data):
x, y, z = data
ax = fig.add_subplot(111)
if isinstance(y, np.ndarray):
ax.imshow(z, extent=(min(x), max(x), min(y), max(y)),
aspect='auto', origin='lower', interpolation='nearest')
else:
ax.plot(x, z)
ax.set_xlabel('x (a.u.)')
ax.set_ylabel('y (a.u.)')
保存
ComplexApp.save(package='test')
运行
import lab
import numpy as np
app = lab.make_app('ComplexApp', package='test').sweep([
('x', np.linspace(0, 1, 11)),
('y', np.linspace(3,5,11))
])
lab.make_figure_for_app(app)
lab.make_figures_for_App('TestApp')
app.run()
- 安装 drivers
import os
path = 'path/to/drivers'
for f in os.listdir(path):
lab.admin.uploadDriver(os.path.join(path, f))
- 查看已有的 drivers
lab.listDrivers()
- 添加仪器设置
# 第一台网分
lab.admin.setInstrument('PNA-I', 'localhost', 'TCPIP::10.122.7.250', 'NetworkAnalyzer')
# 第二台网分
lab.admin.setInstrument('PNA-II', 'localhost', 'TCPIP::10.122.7.251', 'NetworkAnalyzer')
- 查看已存在的仪器
lab.listInstruments()
定义 App
import numpy as np
import skrf as rf
from lab import Application
class S21(Application):
'''从网分上读取 S21
require:
rc : PNA
settings: repeat(optional)
return: Frequency, Re(S21), Im(S21)
'''
async def work(self):
if self.params.get('power', None) is None:
self.params['power'] = [self.rc['PNA'].getValue('Power'), 'dBm']
x = self.rc['PNA'].get_Frequency()
for i in range(self.settings.get('repeat', 1)):
self.processToChange(100.0 / self.settings.get('repeat', 1))
y = np.array(self.rc['PNA'].get_S())
yield x, np.real(y), np.imag(y)
self.increaseProcess()
def pre_save(self, x, re, im):
if self.data.rows > 1:
x = x[0]
re = np.mean(re, axis=0)
im = np.mean(im, axis=0)
return x, re, im
@staticmethod
def plot(fig, data):
x, re, im = data
s = re + 1j * im
ax = fig.add_subplot(111)
ax.plot(x / 1e9, rf.mag_2_db(np.abs(s)))
ax.set_xlabel('Frequency / GHz')
ax.set_ylabel('S21 / dB')
保存
S21.save(package='PNA')
运行
import lab
app = lab.make_app('PNA.S21').with_rc({
'PNA': 'PNA-II' # PNA-II 必须是已经添加到数据库里的设备名
}).with_settings({
'repeat': 10
}).with_params(
power = [-27, 'dBm'],
att = [-30, 'dB']
).with_tags('5 bits sample', 'Cavity 1')
lab.make_figure_for_app(app)
app.run()
查看已有的 App
lab.listApps()
查询数据
results = lab.query()
results.display()
获取原始数据
res = lab.query(app='TestApp')
x,y = res[0].data
import matplotlib.pyplot as plt
plt.plot(x, y)
plt.show()