nsqdriver 0.12.17__cp310-cp310-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. nsqdriver/NS_CST.py +260 -0
  2. nsqdriver/NS_DDS_v3.py +591 -0
  3. nsqdriver/NS_DDS_v4.py +778 -0
  4. nsqdriver/NS_MCI.py +597 -0
  5. nsqdriver/NS_QSYNC.py +812 -0
  6. nsqdriver/__init__.py +10 -0
  7. nsqdriver/common.py +20 -0
  8. nsqdriver/compiler/__init__.py +0 -0
  9. nsqdriver/compiler/assembler.cp310-win_amd64.pyd +0 -0
  10. nsqdriver/compiler/ns_wave.cp310-win_amd64.pyd +0 -0
  11. nsqdriver/compiler/ns_wave.pyi +151 -0
  12. nsqdriver/compiler/py_wave_asm.cp310-win_amd64.pyd +0 -0
  13. nsqdriver/compiler/py_wave_asm.pyi +29 -0
  14. nsqdriver/nswave/__init__.py +9 -0
  15. nsqdriver/nswave/_asm.pyi +97 -0
  16. nsqdriver/nswave/_checkers.cp310-win_amd64.pyd +0 -0
  17. nsqdriver/nswave/_checkers.pyi +47 -0
  18. nsqdriver/nswave/_errors.cp310-win_amd64.pyd +0 -0
  19. nsqdriver/nswave/_errors.pyi +24 -0
  20. nsqdriver/nswave/_functions.cp310-win_amd64.pyd +0 -0
  21. nsqdriver/nswave/_functions.pyi +34 -0
  22. nsqdriver/nswave/_ir.cp310-win_amd64.pyd +0 -0
  23. nsqdriver/nswave/_ir.pyi +283 -0
  24. nsqdriver/nswave/_ir_pass.cp310-win_amd64.pyd +0 -0
  25. nsqdriver/nswave/_ir_pass.pyi +7 -0
  26. nsqdriver/nswave/_optimizations.cp310-win_amd64.pyd +0 -0
  27. nsqdriver/nswave/_optimizations.pyi +16 -0
  28. nsqdriver/nswave/_rules.cp310-win_amd64.pyd +0 -0
  29. nsqdriver/nswave/_rules.pyi +56 -0
  30. nsqdriver/nswave/_simulator.cp310-win_amd64.pyd +0 -0
  31. nsqdriver/nswave/_translate.cp310-win_amd64.pyd +0 -0
  32. nsqdriver/nswave/_translate.pyi +12 -0
  33. nsqdriver/nswave/kernel.cp310-win_amd64.pyd +0 -0
  34. nsqdriver/nswave/kernel.pyi +57 -0
  35. nsqdriver/wrapper/AWG_ADC.py +534 -0
  36. nsqdriver/wrapper/ND_NSMCI.py +245 -0
  37. nsqdriver/wrapper/__init__.py +0 -0
  38. nsqdriver-0.12.17.dist-info/METADATA +117 -0
  39. nsqdriver-0.12.17.dist-info/RECORD +41 -0
  40. nsqdriver-0.12.17.dist-info/WHEEL +5 -0
  41. nsqdriver-0.12.17.dist-info/top_level.txt +1 -0
nsqdriver/NS_DDS_v3.py ADDED
@@ -0,0 +1,591 @@
1
+ import copy
2
+ from enum import Enum
3
+ from math import ceil
4
+ from collections import namedtuple
5
+ from waveforms import Waveform, wave_eval, WaveVStack
6
+ from waveforms.waveform import _zero
7
+ from waveforms.math.signal import getFTMatrix, shift
8
+ import nsqdriver.nswave as nw
9
+
10
+ import numpy as np
11
+
12
+ try:
13
+ import waveforms
14
+
15
+ HAS_WAVEFORMS = True
16
+ except ImportError as e:
17
+ HAS_WAVEFORMS = False
18
+
19
+ try:
20
+ from .common import BaseDriver, Quantity, get_coef
21
+ except ImportError as e:
22
+
23
+ class BaseDriver:
24
+
25
+ def __init__(self, addr, timeout, **kw):
26
+ self.addr = addr
27
+ self.timeout = timeout
28
+
29
+
30
+ class Quantity(object):
31
+
32
+ def __init__(self, name: str, value=None, ch: int = 1, unit: str = ''):
33
+ self.name = name
34
+ self.default = dict(value=value, ch=ch, unit=unit)
35
+
36
+ # def get_coef(*args):
37
+ # return '', '', '', ''
38
+
39
+ DEBUG_PRINT = False
40
+
41
+
42
+ def get_coef(coef_info, sampleRate):
43
+ start, stop = coef_info['start'], coef_info['stop']
44
+ numberOfPoints = int(
45
+ (stop - start) * sampleRate)
46
+ if numberOfPoints % 64 != 0:
47
+ numberOfPoints = numberOfPoints + 64 - numberOfPoints % 64
48
+ t = np.arange(numberOfPoints) / sampleRate + start
49
+
50
+ fList = []
51
+ wList = []
52
+ phases = []
53
+
54
+ for kw in coef_info['wList']:
55
+ Delta, t0, weight, w, phase = kw['Delta'], kw['t0'], kw['weight'], kw['w'], kw['phase']
56
+ fList.append(Delta)
57
+
58
+ if w is not None:
59
+ w = np.zeros(numberOfPoints, dtype=complex)
60
+ w[:len(w)] = w
61
+ w = shift(w, t0 - start)
62
+ phases.append(np.mod(phase + 2 * np.pi * Delta * start, 2 * np.pi))
63
+ else:
64
+ weight = weight
65
+ if isinstance(weight, np.ndarray):
66
+ pass
67
+ else:
68
+ if isinstance(weight, str):
69
+ fun = wave_eval(weight) >> t0
70
+ elif isinstance(weight, Waveform):
71
+ fun = weight >> t0
72
+ else:
73
+ raise TypeError(f'Unsupported type {weight}')
74
+ weight = fun(t)
75
+ phase += 2 * np.pi * Delta * start
76
+ w = getFTMatrix([Delta],
77
+ numberOfPoints,
78
+ phaseList=[phase],
79
+ weight=weight,
80
+ sampleRate=sampleRate)[:, 0]
81
+ phases.append(np.mod(phase, 2 * np.pi))
82
+ wList.append(w)
83
+ return np.asarray(wList), fList, numberOfPoints, phases, round((stop - t0) * sampleRate), t
84
+
85
+
86
+ def get_demod_envelope(coef_info, demod_map, sampleRate):
87
+ start, stop = coef_info['start'], coef_info['stop']
88
+ t0 = coef_info['t0']
89
+ numberOfPoints = int(
90
+ (stop - start) * sampleRate)
91
+ if numberOfPoints % 64 != 0:
92
+ numberOfPoints = numberOfPoints + 64 - numberOfPoints % 64
93
+ t = np.arange(numberOfPoints) / sampleRate + start
94
+ demod_map_list = demod_map
95
+ weight_sum = np.empty(numberOfPoints)
96
+ for weight in demod_map_list:
97
+ if isinstance(weight, np.ndarray):
98
+ pass
99
+ else:
100
+ if isinstance(weight, str):
101
+ fun = wave_eval(weight)
102
+ elif isinstance(weight, Waveform):
103
+ fun = weight
104
+ else:
105
+ raise TypeError(f'Unsupported type {weight}')
106
+ weight = fun(t)
107
+ weight_sum += weight
108
+ return weight_sum
109
+
110
+
111
+
112
+
113
+ @nw.kernel
114
+ def program_cap(param: nw.Var):
115
+ #
116
+ nw.wait_for_trigger()
117
+ i: nw.Var
118
+ # param: [[100e-9, 1e-6], [200e-9, 1e-6]]
119
+ # nw.wait(150e-9)
120
+ for i in param:
121
+ nw.wait(i[0])
122
+ nw.capture(i[1], 0, 0)
123
+
124
+
125
+ @nw.kernel
126
+ def program_da(p: nw.Var):
127
+ i: nw.Var
128
+ e: nw.Var
129
+ nw.init_frame(0, 0)
130
+ nw.wait_for_trigger()
131
+ # nw.reset_frame()
132
+ e = nw.ins_envelope(p[0][1])
133
+ for i in p:
134
+ nw.wait(i[0])
135
+ # e = nw.ins_envelope(i[1])
136
+ nw.play_wave(e, 1, 0, 0)
137
+
138
+
139
+ ProbeSegment = namedtuple('ProbeSegment', ['start', 'stop', 'freq', 'demod', 'idx'])
140
+
141
+ CaptureCmd = namedtuple('CaptureCmd', [
142
+ 'start', 'ad_duration', 'delay', 'da_duration', 'freqs', 'delays', 'demod_wave_list', 'idx_list'
143
+ ])
144
+
145
+
146
+ class DemodulateMode(str, Enum):
147
+ MORE_QUBIT = 'more_qubit'
148
+ COMPLEX_SEQ = 'complex_seq'
149
+
150
+
151
+ class Driver(BaseDriver):
152
+ CHs = list(range(1, 25))
153
+ segment = ('ns', '111|112|113|114|115')
154
+ res_map = []
155
+
156
+ quants = [
157
+ Quantity('ReInit', value={}, ch=1), # set, 设备重新初始化
158
+ Quantity('Instruction', value=None, ch=1), # set 参数化波形指令队列配置
159
+ # 采集运行参数
160
+ Quantity('Shot', value=1024, ch=1), # set,运行次数
161
+ Quantity('PointNumber', value=16384, unit='point'), # set/get,AD采样点数
162
+ Quantity('TriggerDelay', value=0, ch=1, unit='s'), # set/get,AD采样延时
163
+ Quantity('FrequencyList', value=[], ch=1,
164
+ unit='Hz'), # set/get,解调频率列表,list,单位Hz
165
+ Quantity('PhaseList', value=[], ch=1,
166
+ unit='Hz'), # set/get,解调频率列表,list,单位Hz
167
+ Quantity('Coefficient', value=None, ch=1),
168
+ Quantity('DemodulationParam', value=None, ch=1),
169
+ Quantity('CaptureMode'),
170
+ Quantity('StartCapture'), # set,开启采集(执行前复位)
171
+ Quantity('TraceIQ', ch=1), # get,获取原始时域数据
172
+ # 返回:array(shot, point)
173
+ Quantity('IQ', ch=1), # get,获取解调后数据,默认复数返回
174
+ # 系统参数,宏定义修改,open时下发
175
+ # 复数返回:array(shot,frequency)
176
+ # 实数返回:array(IQ,shot,frequency)
177
+
178
+ # 任意波形发生器
179
+ Quantity('Waveform', value=np.array([]), ch=1), # set/get,下发原始波形数据
180
+ Quantity('Delay', value=0, ch=1), # set/get,播放延时
181
+ Quantity('KeepAmp', value=0
182
+ ), # set, 电平是否维持在波形最后一个值, 0:波形播放完成后归0,1:保持波形最后一个值,2:保持波形第一个值
183
+ Quantity('Biasing', value=0, ch=1), # set, 播放延迟
184
+ Quantity('LinSpace', value=[0, 30e-6, 1000],
185
+ ch=1), # set/get, np.linspace函数,用于生成timeline
186
+ Quantity('Output', value=True, ch=1), # set/get,播放通道开关设置
187
+ Quantity('GenWave', value=None,
188
+ ch=1), # set/get, 设备接收waveform对象,根据waveform对象直接生成波形
189
+ # set/get, 设备接收IQ分离的waveform对象列表,根据waveform对象列表直接生成波形
190
+ Quantity('GenWaveIQ', value=None, ch=1),
191
+ Quantity('MultiGenWave', value={1: np.ndarray([])}), # 多通道波形同时下发
192
+ Quantity('EnableWaveCache', value=False), # 是否开启waveform缓存
193
+ Quantity('PushWaveCache'), # 使waveform缓存中的波形数据生效
194
+ # 混频相关配置
195
+ Quantity('EnableDAMixer', value=False, ch=1), # DA通道混频模式开关
196
+ Quantity('MixingWave', ), # 修改完混频相关参数后,运行混频器
197
+ Quantity('DAIQRate', value=1e9, ch=1), # 基带信号采样率
198
+ Quantity('DALOFreq', value=100e6, ch=1), # 中频信号频率
199
+ Quantity('DALOPhase', value=0, ch=1), # 基带信号相位,弧度制
200
+ Quantity('DASideband', value='lower', ch=1), # 混频后取的边带
201
+ Quantity('DAWindow', value=None, ch=1),
202
+ # 基带信号升采样率时所使用的窗函数,默认不使用任何窗,
203
+ # 可选:None、boxcar、triang、blackman、hamming、hann、bartlett、flattop、parzen、bohman、blackmanharris、nuttall、
204
+ # barthann、cosine、exponential、tukey、taylor
205
+
206
+ # 内触发
207
+ Quantity('GenerateTrig', value=1e7,
208
+ unit='ns'), # set/get,触发周期单位ns,触发数量=shot
209
+ Quantity('UpdateFirmware', value='', ch=1), # qsync固件更新
210
+ Quantity('PipInstall') # pip install in instance
211
+ ]
212
+
213
+ def __init__(self, addr: str = '', timeout: float = 10.0, **kw):
214
+ super().__init__(addr, timeout=timeout, **kw)
215
+ self.handle = None
216
+ self.model = 'NS_MCI' # 默认为设备名字
217
+ self.srate = 8e9
218
+ self.ad_srate = 4e9
219
+ self.addr = addr
220
+ self.timeout = timeout
221
+ self.chs = set() # 记录配置过的ch通道
222
+ self.IQ_cache = {}
223
+ self.coef_cache = {}
224
+ self.res_maps = {}
225
+ self.demod_maps = {}
226
+ self.probe_da_wave = {}
227
+ # self.probe_delay = 32e-9
228
+ self.probe_delay = 0
229
+ self.capture_cmds: "dict[int, list[CaptureCmd]]" = {}
230
+ self.capture_cali_param: "dict[int, np.ndarray]" = {}
231
+ self.capture_points: "dict[int, np.ndarray]" = {}
232
+ self.demodulate_mode = DemodulateMode.MORE_QUBIT
233
+ self.demode_calculus: "dict[int, np.ndarray]" = {}
234
+
235
+ def open(self, **kw):
236
+ """
237
+ 输入IP打开设备,配置默认超时时间为5秒
238
+ 打开设备时配置RFSoC采样时钟,采样时钟以参数定义
239
+ """
240
+ from nsqdriver import MCIDriver
241
+
242
+ DArate = 8e9
243
+ ADrate = 4e9
244
+ sysparam = {
245
+ "MixMode": 2,
246
+ "RefClock": "out",
247
+ "DArate": DArate,
248
+ "ADrate": ADrate,
249
+ "CaptureMode": 0,
250
+ "INMixMode": 2, # 4~6 GHz 取 1, 6 ~ 8 GHz 取 2
251
+ }
252
+ sysparam.update(kw.get('system_parameter', {}))
253
+
254
+ device = MCIDriver(self.addr, self.timeout)
255
+ device.open(system_parameter=sysparam)
256
+ self.handle = device
257
+
258
+ def granularity4ns(self, delay):
259
+ # points_4ns = 16 # self.ad_srate*4e-6
260
+ return delay // 4 * 4
261
+
262
+ @staticmethod
263
+ def _delay2_phase(delay, freq):
264
+ return 2 * np.pi * freq * (delay * 1e-9)
265
+
266
+ def in_sequence_in_time(self, coef_info: dict) -> list[CaptureCmd]:
267
+ w_list = coef_info.get('wList', [])
268
+ time_segments: "list[ProbeSegment]" = []
269
+
270
+ for idx, wave in enumerate(w_list):
271
+ t0 = int(round(wave['t0'] * 1e9))
272
+ weight_expr = wave['weight']
273
+
274
+ # 假设 weight 表达式格式为 "square(X) >> Y",我们提取实际时间宽度
275
+ # duration = float(weight_expr.split('>>')[1].strip())
276
+ _start, _stop, _ = wave_eval(weight_expr).bounds
277
+ _start, _stop = int(round(_start * 1e9)), int(round(_stop * 1e9))
278
+
279
+ # 将区间加入列表
280
+ seg = ProbeSegment(t0 + _start, t0 + _stop, wave['Delta'], weight_expr, idx)
281
+ time_segments.append(seg)
282
+
283
+ # 按起始时间排序
284
+ time_segments.sort()
285
+
286
+ # 结果存储
287
+ non_overlapping_segments: list[CaptureCmd] = []
288
+ current_start, current_end = time_segments[0].start, time_segments[0].stop
289
+ current_cmd = CaptureCmd(0, 0, 0, 0, [time_segments[0].freq], [0.],[time_segments[0].demod],
290
+ [time_segments[0].idx])
291
+ pointer = 0
292
+ for seg in time_segments[1:]:
293
+ if seg.start > current_end:
294
+ # 如果不重叠,保存当前段并移动到下一段
295
+ if pointer == 0:
296
+ current_cmd = current_cmd._replace(start=current_start)
297
+ else:
298
+ current_cmd = current_cmd._replace(start=current_start - self.probe_delay)
299
+ current_cmd = current_cmd._replace(ad_duration=current_end - current_start)
300
+ current_cmd = current_cmd._replace(delay=self.probe_delay)
301
+ current_cmd = current_cmd._replace(da_duration=current_end - current_start)
302
+ current_cmd = current_cmd._replace(demod_wave_list=[time_segments[0].demod])
303
+ non_overlapping_segments.append(current_cmd)
304
+
305
+ current_cmd = CaptureCmd(0, 0, 0, 0, [seg.freq], [0.], [seg.demod], [seg.idx])
306
+ pointer = current_end
307
+ current_start, current_end = seg.start, seg.stop
308
+ else:
309
+ # 如果有重叠,扩展当前段
310
+ current_end = max(current_end, seg.stop)
311
+ current_cmd.idx_list.append(seg.idx)
312
+ current_cmd.freqs.append(seg.freq)
313
+ current_cmd.demod_wave_list.append(seg.demod)
314
+ # 由delay换算解缠绕相位
315
+ current_cmd.delays.append(seg.start - current_start)
316
+ else:
317
+ # 添加最后一个段
318
+ current_cmd = current_cmd._replace(start=current_start - self.probe_delay)
319
+ current_cmd = current_cmd._replace(ad_duration=current_end - current_start)
320
+ current_cmd = current_cmd._replace(delay=self.probe_delay)
321
+ current_cmd = current_cmd._replace(da_duration=current_end - current_start)
322
+ non_overlapping_segments.append(current_cmd)
323
+ return non_overlapping_segments
324
+
325
+ def generate_in_program(self, coef_info, ch):
326
+ freq_map = []
327
+ demod_wave_map = []
328
+ seq_param = []
329
+
330
+ self.capture_cmds[ch] = seq = self.in_sequence_in_time(coef_info)
331
+
332
+ for segment in seq:
333
+ demod_wave_map.extend(segment.demod_wave_list)
334
+ demod_wave_map = list(set(demod_wave_map))
335
+ freq_map.extend(segment.freqs)
336
+ freq_map = list(set(freq_map))
337
+
338
+ _t_end = 0
339
+ res_map = [[]]*len(coef_info['wList'])
340
+ phase_map = [0]*len(coef_info['wList'])
341
+ points_map = [0]*len(coef_info['wList'])
342
+ for cap_num, segment in enumerate(seq):
343
+ _align_start = self.granularity4ns(segment.start) # 向前取整
344
+ _start_diff = segment.start - _align_start
345
+ _align_end = ceil((segment.start+segment.ad_duration)/4)*4 #向上取整
346
+ seq_param.append([
347
+ (_align_start-_t_end)*1e-9,
348
+ (_align_end-_align_start)*1e-9,
349
+ segment.delay*1e-9,
350
+ (_align_end-_align_start)*1e-9,
351
+ ])
352
+ _t_end = _align_end
353
+ for idx, delay, freq, demod_wave in zip(segment.idx_list, segment.delays, segment.freqs,
354
+ segment.demod_wave_list):
355
+ res_map[idx] = [freq_map.index(freq), cap_num]
356
+ phase_map[idx] = self._delay2_phase(delay + _start_diff, freq) # 向前取整的缩进加上起始时间的差值来计算相位
357
+ points_map[idx] = segment.ad_duration * 1e-9 * self.ad_srate
358
+
359
+ self.res_maps[ch] = res_map
360
+ self.capture_cali_param[ch] = np.exp(-1j * np.array(phase_map)).reshape((-1, 1))
361
+ self.capture_points[ch] = np.array(points_map).reshape((-1, 1))
362
+ return program_cap(seq_param), freq_map, demod_wave_map
363
+
364
+ def out_sequence_in_time(self, wave_list: list):
365
+ last_start = wave_list[0][0]
366
+ last_stop = wave_list[0][1]
367
+ temp_w = [wave_list[0][2]]
368
+ _res = []
369
+
370
+ for idx, (start, stop, seg) in enumerate(wave_list[1:]):
371
+ if start > last_stop:
372
+ _res.append([last_start, last_stop, np.hstack(temp_w)])
373
+ last_start = start
374
+ last_stop = stop
375
+ temp_w.clear()
376
+ temp_w.append(seg)
377
+ else:
378
+ last_stop = max(last_stop, stop)
379
+ temp_w.append(seg)
380
+ else:
381
+ _res.append([last_start, last_stop, np.hstack(temp_w)])
382
+ return _res
383
+
384
+ def gen_wave_frag(self, x, wave: "Waveform"):
385
+ range_list = np.searchsorted(x, wave.bounds)
386
+ # ret = np.zeros_like(x)
387
+ ret = []
388
+ start, stop = 0, 0
389
+ for i, stop in enumerate(range_list):
390
+ if start < stop and wave.seq[i] != _zero:
391
+ _w = copy.deepcopy(wave)
392
+ _w.start = start / self.srate
393
+ _w.stop = stop / self.srate
394
+ part = _w.sample(self.srate)
395
+ part = part if part is None else part[:(stop-start)]
396
+ ret.append((start, stop, part))
397
+ start = stop
398
+ else:
399
+ if not ret:
400
+ ret.append((0, 128, np.zeros((128,))))
401
+ return ret
402
+
403
+ def generate_out_program(self, _wave, ch):
404
+ align_points = 32 # 4ns*8e9
405
+ if isinstance(_wave, WaveVStack):
406
+ _wave = _wave.simplify()
407
+ if len(_wave.seq) == 1 and _wave.seq[0] == _zero:
408
+ wave_list = [(0, 128, np.zeros((128,)))]
409
+ else:
410
+ _wave.stop = _wave.bounds[-2]
411
+ wave_list = self.gen_wave_frag(
412
+ np.linspace(_wave.start, _wave.stop, int((_wave.stop - _wave.start) * self.srate)), _wave)
413
+ # print(f'generate_out_program: {_wave.start=}, {_wave.stop=}, {wave_list=}, {ch=}')
414
+ _t_end = 0
415
+ para = []
416
+ wave = self.out_sequence_in_time(wave_list)
417
+
418
+ for i in wave:
419
+ wait = (i[0] - _t_end)
420
+ align_wait = wait // align_points * align_points
421
+ zero_num = wait - align_wait
422
+ align_end = ceil(i[1] / align_points) * align_points
423
+ align_wave = [np.zeros(zero_num), i[2], np.zeros([align_end - i[1]])]
424
+ para.append([align_wait / self.srate, np.hstack(align_wave)])
425
+ _t_end = align_end
426
+ return program_da(para)
427
+
428
+ def get_coef_res(self, iq_res, ch):
429
+ res = []
430
+ for (freq_num, cap_num) in self.res_maps[ch]:
431
+ res.append(iq_res[freq_num][cap_num::len(self.capture_cmds[ch])])
432
+ # 采样点归一化
433
+ res = np.array(res) / self.demode_calculus[ch]
434
+ # 校准相位
435
+ res *= self.capture_cali_param[ch]
436
+
437
+ return res
438
+
439
+ def close(self, **kw):
440
+ """
441
+ 关闭设备
442
+ """
443
+ if getattr(self, 'handle', None) is not None:
444
+ self.handle.close()
445
+ self.handle = None
446
+
447
+ def set(self, *args, **kwargs):
448
+ return self.handle.set(*args, **kwargs)
449
+
450
+ def get(self, *args, **kwargs):
451
+
452
+ return self.handle.get(*args, **kwargs)
453
+
454
+ def write(self, name: str, value, **kw):
455
+ channel = kw.get('ch', 1)
456
+ # print(f'NS_DDS_v3 write: {name=}, {channel=}')
457
+ if name in {'Coefficient'}:
458
+ coef_info = value
459
+ self.chs.add(channel)
460
+ kernel, freq_map, demod_wave_map = self.generate_in_program(coef_info, channel)
461
+ self.handle.set("ProgramIN", kernel, channel)
462
+ demode_wave = get_demod_envelope(coef_info, demod_wave_map, sampleRate=8e9)
463
+ self.demode_calculus[channel] = np.sum(demode_wave)
464
+ self.handle.set("DemodulationParam", demode_wave, channel)
465
+ self.handle.set('TimeWidth', 2e-6, channel)
466
+
467
+ self.handle.set("FreqList", freq_map, channel)
468
+ self.coef_cache.update({channel: coef_info})
469
+ elif name in {
470
+ 'CaptureMode', 'SystemSync', 'ResetTrig', 'TrigPeriod',
471
+ 'TrigFrom'
472
+ }:
473
+ pass
474
+ elif name in {
475
+ 'GenWave', 'Waveform'
476
+ } and isinstance(value, Waveform):
477
+ kernel_da = self.generate_out_program(value, channel)
478
+ self.handle.set("ProgramOUT", kernel_da, channel)
479
+ else:
480
+ if name in {"Shot"}:
481
+ self.shots = value
482
+ return self.handle.set(name, value, channel)
483
+
484
+ def read(self, name: str, **kw):
485
+ channel = kw.get('ch', 1)
486
+ if name in {"IQ"}:
487
+ iq_res = self.handle.get(
488
+ "IQ", channel, round(self.shots * len(self.capture_cmds[channel]))
489
+ )
490
+
491
+ result = self.get_coef_res(iq_res, channel).T
492
+ if len(self.chs) != 0 and channel in self.chs:
493
+ self.chs.remove(channel)
494
+ # self.IQ_cache.update({channel: result})
495
+ if len(self.chs) == 0:
496
+ self.write("TerminateUpload", 1) # 实验的开始必须加此句话
497
+ else:
498
+ result = self.handle.get(name, channel)
499
+ return result
500
+
501
+
502
+ if __name__ == '__main__':
503
+ co = {'start': 0.0, 'stop': 10e-06, 'wList': [
504
+ {'Delta': 6796613333.333333, 'phase': -0.0, 'weight': 'square(8e-07) >> 4e-07', 'window': (0, 1024), 'w': None,
505
+ 't0': 1.5e-08, 'phi': 2.4311851282940524, 'threshold': 9.645718574523926},
506
+ {'Delta': 6965129999.666667, 'phase': -0.0, 'weight': 'square(8e-07) >> 4e-07', 'window': (0, 1024), 'w': None,
507
+ 't0': 2.345e-06, 'phi': 2.1739656328752264, 'threshold': 20.36802101135254},
508
+ {'Delta': 6866353333.333333, 'phase': -0.0, 'weight': 'square(8e-07) >> 4e-07', 'window': (0, 1024), 'w': None,
509
+ 't0': 2.345e-06, 'phi': 1.851749364542847, 'threshold': 21.65827751159668},
510
+ {'Delta': 6796613333.333333, 'phase': -0.0, 'weight': 'square(8e-07) >> 4e-07', 'window': (0, 1024), 'w': None,
511
+ 't0': 5.175e-06, 'phi': 2.4311851282940524, 'threshold': 9.645718574523926},
512
+ {'Delta': 6965129999.666667, 'phase': -0.0, 'weight': 'square(8e-07) >> 4e-07', 'window': (0, 1024), 'w': None,
513
+ 't0': 5.175e-06, 'phi': 2.1739656328752264, 'threshold': 20.36802101135254},
514
+ {'Delta': 6866353333.333333, 'phase': -0.0, 'weight': 'square(8e-07) >> 4e-07', 'window': (0, 1024), 'w': None,
515
+ 't0': 5.175e-06, 'phi': 1.851749364542847, 'threshold': 21.65827751159668},
516
+ {'Delta': 6796613333.333333, 'phase': -0.0, 'weight': 'square(8e-07) >> 4e-07', 'window': (0, 1024), 'w': None,
517
+ 't0': 7.805e-06, 'phi': 2.4311851282940524, 'threshold': 9.645718574523926},
518
+ {'Delta': 6796613333.333333, 'phase': -0.0, 'weight': 'square(8e-07) >> 4e-07', 'window': (0, 1024), 'w': None,
519
+ 't0': 8.805e-06, 'phi': 2.4311851282940524, 'threshold': 9.645718574523926},
520
+ {'Delta': 6965129999.666667, 'phase': -0.0, 'weight': 'square(8e-07) >> 4e-07', 'window': (0, 1024), 'w': None,
521
+ 't0': 9.005e-06, 'phi': 2.4311851282940524, 'threshold': 9.645718574523926}
522
+ ]}
523
+ import matplotlib.pyplot as plt
524
+ from nsqdriver import QSYNCDriver
525
+ import time
526
+ import waveforms as wf
527
+ from nsqdriver.NS_MCI import SHARED_DEVICE_MEM
528
+
529
+ SHARED_DEVICE_MEM.clear_ip()
530
+ _d = Driver('192.168.0.43', 300)
531
+ qsync = QSYNCDriver("192.168.0.43")
532
+ _d = Driver('192.168.0.228', 30)
533
+ _q = QSYNCDriver('192.168.0.228')
534
+ time.sleep(5)
535
+ _wave = wf.zero()
536
+ for _w in co['wList']:
537
+ t0 = _w['t0']
538
+ _wave += (wf.wave_eval(_w['weight']) * wf.cos(2 * np.pi * _w['Delta'])) >> t0
539
+ # _wave = _wave << 50e-9
540
+ _wave.start = 0
541
+ _wave.stop = 60e-6
542
+
543
+ _wave(np.linspace(0, 20e-6, int(20e-6 * 8e9)), frag=True)
544
+
545
+ wave = _wave.sample(8e9) / 3
546
+ _wave
547
+
548
+ for ch in range(3, 4):
549
+ _d.write('GenWave', _wave, ch=ch)
550
+ _d.write('Coefficient', co, ch=ch)
551
+ # res = _d.generate_para(co, 1)
552
+ _d.write("Coefficient", co, ch=2)
553
+ ch = 2
554
+ # wave = wf.cos(2*wf.pi*0.15e9)
555
+ # wave.start = 0
556
+ # wave.stop = 1e-6
557
+
558
+ _wave = waveforms.zero()
559
+ for _w in co['wList']:
560
+ t0 = _w['t0']
561
+ _wave += (waveforms.wave_eval(_w['weight']) * waveforms.cos(2 * np.pi * _w['Delta'])) >> t0
562
+ # _wave = _wave << 50e-9
563
+ _wave.start = 0
564
+ _wave.stop = co["stop"]
565
+ plt.plot(_wave.sample(8e9))
566
+ plt.show()
567
+ _d.write("GenWave", _wave, ch=2)
568
+ _d.set('CaptureMode', 1)
569
+ shots = 1024
570
+ qsync.set('Shot', shots)
571
+ _d.write('Shot', shots)
572
+ _d.set('StartCapture')
573
+ qsync.set('GenerateTrig', 400e-6)
574
+ time.sleep(400e-6 * shots + 0.5)
575
+ data = _d.get('TraceIQ', ch)
576
+ data = np.array(data)
577
+ print(data.shape)
578
+ data = data.reshape((shots, -1))
579
+ # qsync.set("Shot", 0xFFFFFFFF)
580
+ # qsync.set("GenerateTrig", 500e-6)
581
+ plt.figure()
582
+ plt.plot(data.mean(axis=0)[:])
583
+ plt.show()
584
+ _d.set('CaptureMode', 0)
585
+ _d.write("Coefficient", co, ch=2)
586
+ _d.write("GenWave", _wave, ch=2)
587
+ _d.set('StartCapture')
588
+ qsync.set('GenerateTrig', 40e-6)
589
+ data = _d.read("IQ", ch=2)
590
+ print(20 * np.log10(np.abs(data.mean(axis=0))))
591
+ pass