forked from M-Labs/artiq
pdq2: wire up more of the pipeline
This commit is contained in:
parent
e42fd9ca31
commit
f0860beffd
|
@ -193,6 +193,8 @@ class Pdq2:
|
|||
|
||||
def program_frame(self, frame_data):
|
||||
segments = [c.new_segment() for c in self.channels]
|
||||
for segment in segments:
|
||||
segment.line(typ=3, data=b"", trigger=True, duration=10, aux=1)
|
||||
for i, line in enumerate(frame_data): # segments are concatenated
|
||||
dac_divider = line.get("dac_divider", 1)
|
||||
shift = int(log(dac_divider, 2))
|
||||
|
@ -209,9 +211,11 @@ class Pdq2:
|
|||
shift=shift, duration=duration, trigger=trigger,
|
||||
**target_data)
|
||||
# append an empty line to stall the memory reader before jumping
|
||||
# through the frame table
|
||||
# through the frame table (`wait` does not prevent reading
|
||||
# the next line)
|
||||
for segment in segments:
|
||||
segment.line(typ=3, data=b"", trigger=True, duration=10)
|
||||
segment.line(typ=3, data=b"", trigger=True, duration=1,
|
||||
jump=True, aux=1)
|
||||
return segments
|
||||
|
||||
def program(self, program):
|
||||
|
|
|
@ -111,6 +111,7 @@ class _Frame:
|
|||
"dac_divider": dac_divider,
|
||||
"duration": duration,
|
||||
"channel_data": channel_data,
|
||||
"trigger": False,
|
||||
} for dac_divider, duration, channel_data in segment.lines]
|
||||
segment_program[0]["trigger"] = True
|
||||
r += segment_program
|
||||
|
@ -156,7 +157,7 @@ class _Frame:
|
|||
class CompoundPDQ2:
|
||||
def __init__(self, dmgr, pdq2_devices, trigger_device, frame_devices):
|
||||
self.core = dmgr.get("core")
|
||||
self.pdq2s = [dmgr.get(d) for d in self.pdq2_devices]
|
||||
self.pdq2s = [dmgr.get(d) for d in pdq2_devices]
|
||||
self.trigger = dmgr.get(trigger_device)
|
||||
self.frame0 = dmgr.get(frame_devices[0])
|
||||
self.frame1 = dmgr.get(frame_devices[1])
|
||||
|
|
|
@ -143,14 +143,12 @@ class CoefficientSource:
|
|||
return build_segment(durations, coefficients, target=target,
|
||||
variable=variable)
|
||||
|
||||
def extend_segment(self, segment, trigger=True, *args, **kwargs):
|
||||
def extend_segment(self, segment, *args, **kwargs):
|
||||
"""Extend a wavesynth segment.
|
||||
|
||||
See `get_segment()` for arguments.
|
||||
"""
|
||||
for i, line in enumerate(self.get_segment_data(*args, **kwargs)):
|
||||
if i == 0:
|
||||
line["trigger"] = trigger
|
||||
segment.add_line(**line)
|
||||
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@ import numpy as np
|
|||
|
||||
from artiq import *
|
||||
|
||||
from artiq.wavesynth.coefficients import SplineSource
|
||||
|
||||
# data is usually precomputed offline
|
||||
transport_data = dict(
|
||||
t=np.linspace(0, 10, 101), # waveform time
|
||||
u=np.random.randn(101, 4*3*3), # waveform data,
|
||||
transport = SplineSource(
|
||||
x=np.linspace(0, 10, 101), # waveform time
|
||||
y=np.random.rand(4*3*3, 101)*1e-6, # waveform data,
|
||||
# 4 devices, 3 board each, 3 dacs each
|
||||
)
|
||||
|
||||
|
@ -16,37 +16,33 @@ class Transport(EnvExperiment):
|
|||
"""Transport"""
|
||||
|
||||
def build(self):
|
||||
self.setattr_device("core")
|
||||
self.setattr_device("bd")
|
||||
self.setattr_device("bdd")
|
||||
self.setattr_device("pmt")
|
||||
self.setattr_device("electrodes")
|
||||
self.core = self.get_device("core")
|
||||
self.bd_sw = self.get_device("bd_sw")
|
||||
self.pmt = self.get_device("pmt")
|
||||
self.electrodes = self.get_device("electrodes")
|
||||
|
||||
self.setattr_argument("wait_at_stop", NumberValue(100*us))
|
||||
self.setattr_argument("speed", NumberValue(1.5))
|
||||
self.setattr_argument("repeats", NumberValue(100))
|
||||
self.setattr_argument("nbins", NumberValue(100))
|
||||
self.wait_at_stop = self.get_argument("wait_at_stop",
|
||||
NumberValue(100*us))
|
||||
self.speed = self.get_argument("speed", NumberValue(1.5))
|
||||
self.repeats = self.get_argument("repeats", NumberValue(100))
|
||||
self.nbins = self.get_argument("nbins", NumberValue(100))
|
||||
|
||||
def calc_waveforms(self, stop):
|
||||
t = transport_data["t"][:stop]*self.speed
|
||||
u = transport_data["u"][:stop]
|
||||
|
||||
self.electrodes.disarm()
|
||||
self.tf = self.electrodes.create_frame()
|
||||
self.tf.create_segment(t, u, name="to_stop")
|
||||
to_stop = self.tf.create_segment("to_stop")
|
||||
from_stop = self.tf.create_segment("from_stop")
|
||||
transport.extend_segment(to_stop, 0, stop, scale=self.speed)
|
||||
# append the reverse transport (from stop to 0)
|
||||
# both durations are the same in this case
|
||||
self.tf.create_segment(t[-1] - t[::-1], u[::-1], name="from_stop")
|
||||
transport.extend_segment(from_stop, 0, stop, scale=self.speed)
|
||||
# distributes frames to the sub-devices in CompoundPDQ2
|
||||
# and uploads them
|
||||
self.electrodes.arm()
|
||||
|
||||
@kernel
|
||||
def cool(self):
|
||||
with parallel:
|
||||
self.bd.pulse(200*MHz, 1*ms)
|
||||
self.bdd.pulse(300*MHz, 1*ms)
|
||||
self.bd.pulse(210*MHz, 100*us)
|
||||
self.bd_sw.pulse(1*ms)
|
||||
|
||||
@kernel
|
||||
def transport(self):
|
||||
|
@ -65,10 +61,9 @@ class Transport(EnvExperiment):
|
|||
@kernel
|
||||
def detect(self):
|
||||
with parallel:
|
||||
self.bd.pulse(220*MHz, 100*us)
|
||||
self.bd_sw.pulse(100*us)
|
||||
self.pmt.gate_rising(100*us)
|
||||
self.bd.on(200*MHz)
|
||||
self.bdd.on(300*MHz)
|
||||
self.bd_sw.on()
|
||||
return self.pmt.count()
|
||||
|
||||
@kernel
|
||||
|
@ -79,7 +74,7 @@ class Transport(EnvExperiment):
|
|||
|
||||
@kernel
|
||||
def repeat(self):
|
||||
self.histogram = [0 for _ in range(self.nbins)]
|
||||
self.histogram[:] = [0 for _ in range(self.nbins)]
|
||||
|
||||
for i in range(self.repeats):
|
||||
n = self.one()
|
||||
|
@ -100,5 +95,5 @@ class Transport(EnvExperiment):
|
|||
|
||||
def run(self):
|
||||
# scan transport endpoint
|
||||
stops = range(10, len(transport_data["t"]), 10)
|
||||
stops = range(10, len(transport.x), 10)
|
||||
self.scan(stops)
|
||||
|
|
Loading…
Reference in New Issue