nsqdriver 0.12.11__cp312-cp312-win_amd64.whl → 0.12.13__cp312-cp312-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.
Potentially problematic release.
This version of nsqdriver might be problematic. Click here for more details.
- nsqdriver/NS_DDS_v3.py +309 -122
- nsqdriver/NS_DDS_v4.py +778 -0
- nsqdriver/NS_MCI.py +28 -5
- nsqdriver/__init__.py +3 -3
- nsqdriver/compiler/assembler.cp312-win_amd64.pyd +0 -0
- nsqdriver/compiler/ns_wave.cp312-win_amd64.pyd +0 -0
- nsqdriver/compiler/py_wave_asm.cp312-win_amd64.pyd +0 -0
- nsqdriver/nswave/_checkers.cp312-win_amd64.pyd +0 -0
- nsqdriver/nswave/_errors.cp312-win_amd64.pyd +0 -0
- nsqdriver/nswave/_functions.cp312-win_amd64.pyd +0 -0
- nsqdriver/nswave/_ir.cp312-win_amd64.pyd +0 -0
- nsqdriver/nswave/_ir_pass.cp312-win_amd64.pyd +0 -0
- nsqdriver/nswave/_optimizations.cp312-win_amd64.pyd +0 -0
- nsqdriver/nswave/_rules.cp312-win_amd64.pyd +0 -0
- nsqdriver/nswave/_simulator.cp312-win_amd64.pyd +0 -0
- nsqdriver/nswave/_translate.cp312-win_amd64.pyd +0 -0
- nsqdriver/nswave/kernel.cp312-win_amd64.pyd +0 -0
- {nsqdriver-0.12.11.dist-info → nsqdriver-0.12.13.dist-info}/METADATA +10 -2
- nsqdriver-0.12.13.dist-info/RECORD +41 -0
- {nsqdriver-0.12.11.dist-info → nsqdriver-0.12.13.dist-info}/WHEEL +1 -1
- nsqdriver-0.12.11.dist-info/RECORD +0 -39
- {nsqdriver-0.12.11.dist-info → nsqdriver-0.12.13.dist-info}/top_level.txt +0 -0
nsqdriver/NS_DDS_v3.py
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import copy
|
|
2
2
|
from enum import Enum
|
|
3
|
+
from math import ceil
|
|
3
4
|
from collections import namedtuple
|
|
4
|
-
from waveforms import Waveform, wave_eval
|
|
5
|
+
from waveforms import Waveform, wave_eval, WaveVStack
|
|
6
|
+
from waveforms.waveform import _zero
|
|
5
7
|
from waveforms.math.signal import getFTMatrix, shift
|
|
6
8
|
import nsqdriver.nswave as nw
|
|
7
9
|
|
|
@@ -37,28 +39,6 @@ except ImportError as e:
|
|
|
37
39
|
DEBUG_PRINT = False
|
|
38
40
|
|
|
39
41
|
|
|
40
|
-
@nw.kernel
|
|
41
|
-
def program_cap(param: nw.Var):
|
|
42
|
-
#
|
|
43
|
-
nw.wait_for_trigger()
|
|
44
|
-
i: nw.Var
|
|
45
|
-
# param: [[100e-9, 1e-6], [200e-9, 1e-6]]
|
|
46
|
-
for i in param:
|
|
47
|
-
nw.wait(i[0])
|
|
48
|
-
nw.capture(i[1], i[2], i[3])
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
ProbeSegment = namedtuple('ProbeSegment', ['start', 'stop', 'freq'])
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
CaptureCmd = namedtuple('CaptureCmd', ['start', 'ad_duration', 'delay', 'da_duration', 'freqs'])
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
class DemodulateMode(str, Enum):
|
|
58
|
-
MORE_QUBIT = 'more_qubit'
|
|
59
|
-
COMPLEX_SEQ = 'complex_seq'
|
|
60
|
-
|
|
61
|
-
|
|
62
42
|
def get_coef(coef_info, sampleRate):
|
|
63
43
|
start, stop = coef_info['start'], coef_info['stop']
|
|
64
44
|
numberOfPoints = int(
|
|
@@ -103,56 +83,69 @@ def get_coef(coef_info, sampleRate):
|
|
|
103
83
|
return np.asarray(wList), fList, numberOfPoints, phases, round((stop - t0) * sampleRate), t
|
|
104
84
|
|
|
105
85
|
|
|
106
|
-
def
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
for
|
|
154
|
-
|
|
155
|
-
|
|
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'
|
|
156
149
|
|
|
157
150
|
|
|
158
151
|
class Driver(BaseDriver):
|
|
@@ -222,15 +215,22 @@ class Driver(BaseDriver):
|
|
|
222
215
|
self.handle = None
|
|
223
216
|
self.model = 'NS_MCI' # 默认为设备名字
|
|
224
217
|
self.srate = 8e9
|
|
218
|
+
self.ad_srate = 4e9
|
|
225
219
|
self.addr = addr
|
|
226
220
|
self.timeout = timeout
|
|
227
221
|
self.chs = set() # 记录配置过的ch通道
|
|
228
222
|
self.IQ_cache = {}
|
|
229
223
|
self.coef_cache = {}
|
|
230
224
|
self.res_maps = {}
|
|
225
|
+
self.demod_maps = {}
|
|
231
226
|
self.probe_da_wave = {}
|
|
232
|
-
self.
|
|
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]" = {}
|
|
233
232
|
self.demodulate_mode = DemodulateMode.MORE_QUBIT
|
|
233
|
+
self.demode_calculus: "dict[int, np.ndarray]" = {}
|
|
234
234
|
|
|
235
235
|
def open(self, **kw):
|
|
236
236
|
"""
|
|
@@ -242,40 +242,42 @@ class Driver(BaseDriver):
|
|
|
242
242
|
DArate = 8e9
|
|
243
243
|
ADrate = 4e9
|
|
244
244
|
sysparam = {
|
|
245
|
-
"MixMode":
|
|
245
|
+
"MixMode": 2,
|
|
246
246
|
"RefClock": "out",
|
|
247
247
|
"DArate": DArate,
|
|
248
248
|
"ADrate": ADrate,
|
|
249
249
|
"CaptureMode": 0,
|
|
250
250
|
"INMixMode": 2, # 4~6 GHz 取 1, 6 ~ 8 GHz 取 2
|
|
251
251
|
}
|
|
252
|
+
sysparam.update(kw.get('system_parameter', {}))
|
|
252
253
|
|
|
253
254
|
device = MCIDriver(self.addr, self.timeout)
|
|
254
255
|
device.open(system_parameter=sysparam)
|
|
255
256
|
self.handle = device
|
|
256
257
|
|
|
257
258
|
def granularity4ns(self, delay):
|
|
258
|
-
#
|
|
259
|
-
|
|
260
|
-
delay // 4e-9 * 4e-9, 10
|
|
261
|
-
)
|
|
262
|
-
return out_delay
|
|
259
|
+
# points_4ns = 16 # self.ad_srate*4e-6
|
|
260
|
+
return delay // 4 * 4
|
|
263
261
|
|
|
264
262
|
@staticmethod
|
|
265
|
-
def
|
|
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]:
|
|
266
267
|
w_list = coef_info.get('wList', [])
|
|
267
268
|
time_segments: "list[ProbeSegment]" = []
|
|
268
269
|
|
|
269
|
-
for wave in w_list:
|
|
270
|
-
t0 = wave['t0']
|
|
270
|
+
for idx, wave in enumerate(w_list):
|
|
271
|
+
t0 = int(round(wave['t0'] * 1e9))
|
|
271
272
|
weight_expr = wave['weight']
|
|
272
273
|
|
|
273
274
|
# 假设 weight 表达式格式为 "square(X) >> Y",我们提取实际时间宽度
|
|
274
275
|
# duration = float(weight_expr.split('>>')[1].strip())
|
|
275
276
|
_start, _stop, _ = wave_eval(weight_expr).bounds
|
|
277
|
+
_start, _stop = int(round(_start * 1e9)), int(round(_stop * 1e9))
|
|
276
278
|
|
|
277
279
|
# 将区间加入列表
|
|
278
|
-
seg = ProbeSegment(t0+_start, t0+_stop, wave['Delta'])
|
|
280
|
+
seg = ProbeSegment(t0 + _start, t0 + _stop, wave['Delta'], weight_expr, idx)
|
|
279
281
|
time_segments.append(seg)
|
|
280
282
|
|
|
281
283
|
# 按起始时间排序
|
|
@@ -284,61 +286,154 @@ class Driver(BaseDriver):
|
|
|
284
286
|
# 结果存储
|
|
285
287
|
non_overlapping_segments: list[CaptureCmd] = []
|
|
286
288
|
current_start, current_end = time_segments[0].start, time_segments[0].stop
|
|
287
|
-
current_cmd = CaptureCmd(0, 0, 0, 0, [time_segments[0].freq]
|
|
289
|
+
current_cmd = CaptureCmd(0, 0, 0, 0, [time_segments[0].freq], [0.],[time_segments[0].demod],
|
|
290
|
+
[time_segments[0].idx])
|
|
288
291
|
pointer = 0
|
|
289
|
-
|
|
290
292
|
for seg in time_segments[1:]:
|
|
291
293
|
if seg.start > current_end:
|
|
292
294
|
# 如果不重叠,保存当前段并移动到下一段
|
|
293
|
-
|
|
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)
|
|
294
299
|
current_cmd = current_cmd._replace(ad_duration=current_end - current_start)
|
|
295
|
-
current_cmd = current_cmd._replace(delay=
|
|
300
|
+
current_cmd = current_cmd._replace(delay=self.probe_delay)
|
|
296
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])
|
|
297
303
|
non_overlapping_segments.append(current_cmd)
|
|
298
304
|
|
|
299
|
-
current_cmd = CaptureCmd(0, 0, 0, 0, [seg.freq])
|
|
300
|
-
pointer
|
|
305
|
+
current_cmd = CaptureCmd(0, 0, 0, 0, [seg.freq], [0.], [seg.demod], [seg.idx])
|
|
306
|
+
pointer = current_end
|
|
301
307
|
current_start, current_end = seg.start, seg.stop
|
|
302
308
|
else:
|
|
303
309
|
# 如果有重叠,扩展当前段
|
|
304
310
|
current_end = max(current_end, seg.stop)
|
|
311
|
+
current_cmd.idx_list.append(seg.idx)
|
|
305
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)
|
|
306
316
|
else:
|
|
307
317
|
# 添加最后一个段
|
|
308
|
-
current_cmd = current_cmd._replace(start=current_start -
|
|
318
|
+
current_cmd = current_cmd._replace(start=current_start - self.probe_delay)
|
|
309
319
|
current_cmd = current_cmd._replace(ad_duration=current_end - current_start)
|
|
310
|
-
current_cmd = current_cmd._replace(delay=
|
|
320
|
+
current_cmd = current_cmd._replace(delay=self.probe_delay)
|
|
311
321
|
current_cmd = current_cmd._replace(da_duration=current_end - current_start)
|
|
312
322
|
non_overlapping_segments.append(current_cmd)
|
|
313
323
|
return non_overlapping_segments
|
|
314
324
|
|
|
315
|
-
def
|
|
316
|
-
res_map = []
|
|
325
|
+
def generate_in_program(self, coef_info, ch):
|
|
317
326
|
freq_map = []
|
|
327
|
+
demod_wave_map = []
|
|
318
328
|
seq_param = []
|
|
319
329
|
|
|
320
|
-
self.capture_cmds[ch] = seq = self.
|
|
330
|
+
self.capture_cmds[ch] = seq = self.in_sequence_in_time(coef_info)
|
|
321
331
|
|
|
322
332
|
for segment in seq:
|
|
333
|
+
demod_wave_map.extend(segment.demod_wave_list)
|
|
334
|
+
demod_wave_map = list(set(demod_wave_map))
|
|
323
335
|
freq_map.extend(segment.freqs)
|
|
324
|
-
|
|
336
|
+
freq_map = list(set(freq_map))
|
|
325
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'])
|
|
326
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 #向上取整
|
|
327
346
|
seq_param.append([
|
|
328
|
-
|
|
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,
|
|
329
351
|
])
|
|
330
|
-
|
|
331
|
-
|
|
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
|
|
332
358
|
|
|
333
359
|
self.res_maps[ch] = res_map
|
|
334
|
-
self.
|
|
335
|
-
self.
|
|
336
|
-
|
|
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)
|
|
337
427
|
|
|
338
428
|
def get_coef_res(self, iq_res, ch):
|
|
339
429
|
res = []
|
|
340
430
|
for (freq_num, cap_num) in self.res_maps[ch]:
|
|
341
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
|
+
|
|
342
437
|
return res
|
|
343
438
|
|
|
344
439
|
def close(self, **kw):
|
|
@@ -358,24 +453,29 @@ class Driver(BaseDriver):
|
|
|
358
453
|
|
|
359
454
|
def write(self, name: str, value, **kw):
|
|
360
455
|
channel = kw.get('ch', 1)
|
|
361
|
-
print(
|
|
456
|
+
# print(f'NS_DDS_v3 write: {name=}, {channel=}')
|
|
362
457
|
if name in {'Coefficient'}:
|
|
363
|
-
# data, f_list, numberOfPoints, phases, points, _ = get_coef(value, 4e9)
|
|
364
|
-
|
|
365
|
-
# print('DemoPoints'*10, points, channel)
|
|
366
|
-
# self.handle.set('DemoPoints', points, channel) ############### 16ns-oscillation problem
|
|
367
|
-
# self.handle.set('DemodulationParam', data, channel)
|
|
368
458
|
coef_info = value
|
|
369
459
|
self.chs.add(channel)
|
|
370
|
-
self.
|
|
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)
|
|
371
468
|
self.coef_cache.update({channel: coef_info})
|
|
372
|
-
# elif name in {'Waveform'} and isinstance(value, waveforms.Waveform):
|
|
373
|
-
# self.probe_da_wave[channel] = value
|
|
374
469
|
elif name in {
|
|
375
470
|
'CaptureMode', 'SystemSync', 'ResetTrig', 'TrigPeriod',
|
|
376
471
|
'TrigFrom'
|
|
377
472
|
}:
|
|
378
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)
|
|
379
479
|
else:
|
|
380
480
|
if name in {"Shot"}:
|
|
381
481
|
self.shots = value
|
|
@@ -383,18 +483,13 @@ class Driver(BaseDriver):
|
|
|
383
483
|
|
|
384
484
|
def read(self, name: str, **kw):
|
|
385
485
|
channel = kw.get('ch', 1)
|
|
386
|
-
print(name, kw, "READ " * 6)
|
|
387
486
|
if name in {"IQ"}:
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
# print(np.array(iq_res).shape, "iq shape")
|
|
395
|
-
result = np.array(self.get_coef_res(iq_res, channel)).T
|
|
396
|
-
# print(result.shape, "result.shape," * 3)
|
|
397
|
-
if len(self.chs) != 0:
|
|
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:
|
|
398
493
|
self.chs.remove(channel)
|
|
399
494
|
# self.IQ_cache.update({channel: result})
|
|
400
495
|
if len(self.chs) == 0:
|
|
@@ -402,3 +497,95 @@ class Driver(BaseDriver):
|
|
|
402
497
|
else:
|
|
403
498
|
result = self.handle.get(name, channel)
|
|
404
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
|