这是离子阱控制软件cion的Alpha开源版本。
This is cion Alpha Version.
Alpha版本作者:李日灵,乔木,郑可立。
Current Authors: Riling Li, Mu Qiao, Keli Zheng.
下面是关于cion的基本介绍。
The English introduction of cion remains to be updated.
Cion是适合运行在 jupyter lab/notebook上的一款离子阱测控软件。
Python环境需求:
* Python >= 3.8.0,
* numpy,
* scipy,
* matplotlib >= 3.5.0,
* h5py,
* pandas,
* networkx,
* pyqt6,
* pyserial
或者见requirements.txt。
首先,我们推荐用户浏览一下debug_mode_example.ipynb, hardware_Load_ion_example.ipynb, AWG test _thc.ipynb来获得对于使用cion的初步印象。特别地,用户可以尝试在本地运行debug_mode_example.ipynb。
下面是更详细一点的关于cion结构的介绍。在接下来的介绍中,如无特别说明,gate和pulse的意义是等价的。
在使用cion进行离子阱实验前,需要做好一系列的准备来保证后续实验的顺利进行。比如:确定离子的数目,做好硬件的对接,并确定每个离子的数据通道(channel)等。其中,在硬件对接这一步,需要通过以太网口连接的硬件要给定对应的ip地址,通过串口连接的硬件要给定对应的端口号等。
Cion使用一个叫Experiment的类来管理实验。每次实验开始前,都应该定义一个Experiment的实例,在Experiment的构造函数里,可以定义好各种全局配置参数和硬件的信息。(后续版本中可以将接口参数存储到本地,从而避免每一次开始实验时都重新输入这些参数) 随后,当实验配置不变时,就可以持续在这个Experiment实例下实验,而不需要新的Experiment的实例/变量。
例如:
exp = Experiment(ion_number=4, chapter_dict=Doppler_chapter_dict, port="COM5", ip_address='192.168.2.30::INSTR1::INSTR')
就定义了一个支持4个离子的Experiment变量。其中port和ip_address分别是串口和ip地址,在我们(Kihwan's lab)当前环境配置中分别连接FPGA和AWG硬件。 chapter_dict存储FPGA上对于不同脉冲的具体映射,能够将一类脉冲(例如Doppler,Detection等)转换成对应的报文包(packet)以便发送给串口,实际实验时由用户根据FPGA配置给定。
Experiment类进行实验是通过对实验序列(sequence)的管理来实现的。在一个Experiment变量内部,可以定义多个序列,每个序列均是Sequence类型。每个序列可以由不同的脉冲(pulse)组成。每个脉冲均是BaseGate类或AdvanceGate类这两者的子类(Sequence类,BaseGate类和AdvanceGate类的定义见文档后面部分)。
例如,在定义好上述exp后:
doppler_cooling = exp.new_sequence()
doppler_cooling.set_sequence(
Doppler(1000, label='Doppler').on(all),
Zero(1).on(all))
就设定好了一个名为doppler_cooling的sequence,其中包括Doppler和Zero两类pulse,均是作用在全体离子上。
像Doppler和Zero这几个pulse类,它们均继承自BaseGate或AdvanceGate。但需要用户进一步在配置文件内手动实现(在根目录的.py里定义,比如像示例文件ZTESTER_Load_ion.py)。 其意义在于不限死pulse的种类,从而在牺牲一定便利程度的情况下增加实验的灵活性。同时,也使得用户可以针对每一类pulse做不同的硬件实现(例如在ZTESTER_Load_ion.py中,有若干pulses用到了Labbrick信号发生器)并写明其硬件参数更新接口。
同时,Experiment实现了扫描频率(frequency)、时间(time)和幅度(amplitude)三种参数的功能。只需要选定具体的序列,并且指定序列中具体要扫描的脉冲,并且输入扫描参数即可实现。
我们使用独立线程(thread)来实时收发数据并进行画图,以提高实验效率。具体可以见Experiment类中的freq_scan, time_scan, amp_scan这几个函数。
注意:由于Python全局解释器锁(GIL)的存在,单纯多线程并没有充分调用到多核cpu的性能,但是应该在一定程度上减缓了数据通信造成的阻塞(Blocking)。Cion后续版本中我们可能尝试多进程模式。
BaseGate类用于描述FPGA与AWG上的各种单比特门(single-qubit gate),由其继承出来的子类可以有Doppler,Optical_pumping,Detection,EIT,RSB,Rx等,由用户自行定义
BaseGate类有如下几个主要的成员变量(member variables):
duration: gate的持续时间
latency: 该单比特门距离这个量子比特上的前一个门的延时
awg_flag: awg_flag为True表示这个gate作用在AWG上;为False时表示作用在FPGA上
label: 加一个标签值,在sequence里面标记这个gate,便于在做实验时随时修改这个gate的部分参数
pulse_type: 只用于表征gate的类型,用于直接生成FPGA上gate对应的chapter,同时在sequence画图(调用sequencer.py里的plot_sequence函数)时有用
amp,freq,phase: 幅度(强度),频率,相位参数。对于AWG上的gate需要明确赋值用以生成AWG波形数据;对于FPGA上的gate则并不需要(FPGA会直接找到pulse_type对应的chapter)
可选的成员变量optional member variables:
segment_flag: 表示awg的生成函数是否是分段函数(仅对AWG上的gate有意义)
segment_number: 表示函数的分段数(可以为1)。segment_flag为False时为-1,仅在segment_flag == True时才有意义。
time_intervals: 分段函数的时间分段。是一个长度为segment_number的list,具有如下形式:
[(lt_0,rt_0),(lt_1,rt_1),...],lt_i,rt_i(0<=i<segment_number)表示第i+1段分段函数的起始和终止时间。
amp,freq,phase的进一步说明:
为了实验的灵活性,我们允许AWG上的gate是分段函数,且每一个分段函数有多个频率成分。具体来说,分成如下两种情况:
1、gate不是分段函数,此时amp, freq, phase是三个实数(float),或者三个tuple(每个tuple长度必须一样)
即amp=1,freq=2,phase=3或者amp=(1,-1), freq=(2,2),phase=(3,-3)都是可以的。
其中参数是tuple类型时,表示该函数有多个sin分量。例如: amp, freq, phase = (1,-1),(2,2),(3,-3)时,整体函数为:
$$f(t) = 1sin(2t+3) - sin(2*t-3)$$
2、gate是分段函数,则amp, freq, phase必须是三个长度等于segment_number的list。list内每一个元素同样可以是float或者tuple。例如:
当segment_number == 4, time_intervals == [(0,9.33), (9.33,17.66), (17.66,28.53), (28.53,57.94)]时,
amp = [1, (1,1), 3, (0.45,0.45,0.45)], freq = [0.2, (2.03,-2.03), 0.2, (0.2, 2.03, -2.03)],
phase = [0.48, (0.308, -0.308), 0.086, (0.48,0.48,-0.48)]
则:
$$f(t) = \begin{cases} sin(0.2t+0.48) & t<9.33 \\ sin(2.03t+0.308) + sin(-2.03t-0.308) & 9.33<=t<17.66 \\ 3sin(0.2t+0.086) & 17.66<=t<28.53 \\ 0.45sin(0.2t+0.48) + 0.45sin(2.03t+0.48) + 0.45sin(-2.03t-0.48) & 28.53<=t<57.94 \end{cases}$$
如何修改分段函数的gate的参数,具体请参考Sequence类中set_parameter函数的说明。后续为了使分段函数的定义更便于理解,我们可能对其使用方法进行修改。
额外添加的AdvanceGate类,专用于AWG上多比特纠缠门。
AdvanceGate依然有duration和latency这两个成员变量。 但不同于BaseGate类,AdvanceGate不再有amp,freq,phase,segment_number等直接描述生成函数的成员变量。 AdvanceGate需要分成三层来描述所有参数,因此直接将所有参数打包成一个字典,存储在成员变量para_table里。 para_table是一个Python字典类型,具体描述如下:
{
"ion_number" : (int)表示此纠缠门涉及到的离子数
"segment_number" : (int)表示生成函数的分段数;当生成函数不是分段函数时,取值为1
"time_intervals" : (list),其结构与BaseGate的time_intervals相同
"data_per_ion" : (list),是一个长度为ion_number的list。list里面每一个元素都是一个字典。结构如下:
{
"amp" : 可以是float,tuple或者list(分两种情况讨论),意义同BaseGate.amp。但segment_number > 1时,必须是list类型
"freq" : 意义同BaseGate.freq。
"phase" : 意义同BaseGate.phase。
}
}
AdvanceGate具体作用在哪几个离子(ion)上由成员函数on()来给定。
想要修改sequence中某一个AdvanceGate变量的参数时,可直接在set_parameters()函数输入参数para_table = new_dict,函数会把label对应的AdvanceGate的 para_table直接修改为new_dict。对于AdvanceGate中只改动某个离子相关的参数或者某一类参数,而不覆盖整体para_table的功能,有待后续开发。
用于生成一个实验序列。主要是对BaseGate,AdvanceGate,sync指令,awg_trigger指令等的组合与拼接。
Sequence有几个主要的成员函数(member function)。
set_sequence(self, *args): 输入参数若干,用于生成一个新的序列。
每一个参数是一个BaseGate.on()实例,AdvanceGate.on()实例,sync指令或者awg_trigger指令。
其中awg_trigger指令至多只允许出现一次。而AWG上的gates必须在awg_trigger指令之后,否则软件会报错。
add_gates(self, *args): 输入参数若干,用于在现有序列之后再拼接上输入的序列。
regenerate_sequence(self): 无需额外输入参数,作用是重新整理已有输入的序列。
主要应用场景在于调用set_parameters()修改序列内某些gates的参数后,需要重新扫一遍序列更新各种信息。
从而使set_parameters()的调用真正生效。
set_parameters(self, label = target_label, duration = None, amp = None, freq = None, phase = None, batch_mode = False, para_table = None):
修改序列中label为target_label的gate的参数。要求: 一个BaseGate和一个AdvanceGate不能拥有相同的label。
1、当target_label对应的集合是BaseGate类的集合,输入想要改变的参数duration,amp,freq,phase。不想改变的参数默认输入为None。
当target_label对应的集合不止一个gate时,假设序列中有n个gates都有当前的label。若:
1) batch_mode为False时,duration,amp,freq,phase(如要修改)必须是一个长度为n的tuple。
例如:set_parameters(label, duration = None, amp = None, freq = (freq1,freq2,freq3),phase=None)
2) batch_mode为True时,表示批量赋值。例如:当amp!=None,则序列所有拥有该label的gates其amp全部修改为输入的amp。
2、当target_label对应的集合是AdvanceGate类的集合,输入参数para_table = new_dict。
1) 当target_label对应单个gate或者batch_mode == True时,直接将修改所有的具有该label的AdvanceGate的成员变量para_table为new_dict。
2) 当target_label对应的集合有n(n>1)个gate时,new_dict应当是一个长度为n的tuple。tuple中第i个元素new_dict[i]就是第i个具有target_label的AdvanceGate需要修改的参数表。
clear(self, make_sure = False):
初始化sequence,将gate_sequence, gate_list_per_ion, time_stamp等成员都重置。
此函数一般不需要手动调用。当手动调用时必须确保make_sure参数设置为True,以防误操作。
def update_hardwares(self, label=None):
更新label中涉及到的这些pulse的硬件参数。
此函数通常接在set_parameters后面。因为set_parameters只是从软件层面修改了pulses的频率,幅度等信息。而有些pulses在硬件上运行时还需要把硬件参数直接给定。update_hardwares便提供此功能。
Experiment类提供两种使用模式:真实实验模式和调试模式。真实实验模式会对接硬件正常进行实验;调试模式可以在没有硬件或硬件未配置好进行使用,以便用户熟悉cion代码和功能。
通过设定Global_Setting的debug_mode变量来确定模式:debug_mode为True表示调试模式,debug_mode为False时表示真实实验模式。
例如,当用户在jupyter中进行实验时,可以调用:Global_Setting.set_debug_mode(True)来预先表明需要在调试模式下运行。 随后,当定义一个Experiment变量时: exp = Experiment(ion_number=3, chapter_dict=Doppler_chapter_dict, port="COM5", ip_address='192.168.2.30::INSTR1::INSTR') 即便我们给出了串口通信端口和IP地址,cion也不会尝试去连接这些地址,因为处于调试模式下。
之后,我们可以在jupyter内随时Global_Setting.set_debug_mode(False)来改为真实实验模式,此时需要重新定义一个Experiment变量: exp_new = Experiment(ion_number=3, chapter_dict=Doppler_chapter_dict, port="COM5", ip_address='192.168.2.30::INSTR1::INSTR') 则exp_new才会去对接这些硬件接口,从而保证后续实验的顺利进行。
Cion还包括但不限于如下功能:
1. 自动保存当次实验数据和实验配置参数,并可以在后续有需要时随时调用。
2. 数据拟合,如:高斯拟合,Rabi拟合,Thermal拟合等。
3. 校准逻辑的实现(Calbiration Graph),此功能正开发中。
后续Readme文档会逐步更新上述功能的使用介绍。再一次,我们推荐有兴趣的用户阅读根目录下几个主要的ipynb文件,以加深对cion用法的理解。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。