2015-09-07 06:08:57 +08:00
|
|
|
# Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com>
|
|
|
|
|
2014-10-04 09:55:53 +08:00
|
|
|
import numpy as np
|
|
|
|
|
2016-01-26 07:03:01 +08:00
|
|
|
from artiq.experiment import *
|
2016-01-20 11:09:10 +08:00
|
|
|
from artiq.wavesynth.coefficients import SplineSource
|
2014-10-04 09:55:53 +08:00
|
|
|
|
2016-02-17 00:42:28 +08:00
|
|
|
|
2015-07-14 04:08:20 +08:00
|
|
|
class Transport(EnvExperiment):
|
2015-03-08 22:43:04 +08:00
|
|
|
"""Transport"""
|
2015-02-21 05:01:34 +08:00
|
|
|
|
2015-07-14 04:08:20 +08:00
|
|
|
def build(self):
|
2016-02-17 00:42:28 +08:00
|
|
|
self.setattr_device("core")
|
|
|
|
self.setattr_device("bd_sw")
|
|
|
|
self.setattr_device("pmt")
|
|
|
|
self.setattr_device("electrodes")
|
2015-10-04 00:18:21 +08:00
|
|
|
|
2016-02-17 00:42:28 +08:00
|
|
|
self.setattr_argument("wait_at_stop", NumberValue(100*us))
|
2016-02-22 22:29:19 +08:00
|
|
|
self.setattr_argument("speed", NumberValue(1/(10*us)))
|
2016-02-24 21:47:27 +08:00
|
|
|
self.repeats = int(self.get_argument("repeats", NumberValue(100)))
|
|
|
|
self.bins = int(self.get_argument("bins", NumberValue(100)))
|
2014-10-19 13:09:10 +08:00
|
|
|
|
2016-02-22 22:29:19 +08:00
|
|
|
t = np.linspace(0, 10, 101) # waveform time
|
|
|
|
u = 1 - np.cos(np.pi*t/t[-1])
|
|
|
|
# 4 devices, 3 board each, 3 dacs each
|
|
|
|
u = np.arange(4*3*3)[:, None]*.1 + u
|
|
|
|
self.data = SplineSource(x=t, y=u)
|
|
|
|
|
2015-07-14 04:08:20 +08:00
|
|
|
def calc_waveforms(self, stop):
|
2016-02-22 22:29:19 +08:00
|
|
|
scale = self.speed/(50*MHz)
|
2015-03-23 05:31:59 +08:00
|
|
|
self.electrodes.disarm()
|
2014-10-17 00:04:30 +08:00
|
|
|
self.tf = self.electrodes.create_frame()
|
2016-02-22 22:29:19 +08:00
|
|
|
self.data.extend_segment(self.tf.create_segment("to_stop"),
|
|
|
|
0, stop, scale=scale)
|
2014-10-04 09:55:53 +08:00
|
|
|
# append the reverse transport (from stop to 0)
|
|
|
|
# both durations are the same in this case
|
2016-02-22 22:29:19 +08:00
|
|
|
self.data.extend_segment(self.tf.create_segment("from_stop"),
|
|
|
|
stop, 0, scale=scale)
|
2014-10-19 13:09:10 +08:00
|
|
|
# distributes frames to the sub-devices in CompoundPDQ2
|
|
|
|
# and uploads them
|
2015-03-23 05:31:59 +08:00
|
|
|
self.electrodes.arm()
|
2014-10-04 09:55:53 +08:00
|
|
|
|
|
|
|
@kernel
|
|
|
|
def cool(self):
|
2016-01-20 11:09:10 +08:00
|
|
|
self.bd_sw.pulse(1*ms)
|
2014-10-04 09:55:53 +08:00
|
|
|
|
|
|
|
@kernel
|
|
|
|
def transport(self):
|
2015-03-23 05:31:59 +08:00
|
|
|
# selects transport frame
|
2014-10-04 09:55:53 +08:00
|
|
|
# triggers pdqs to start transport frame segment
|
|
|
|
# plays the transport waveform from 0 to stop
|
|
|
|
# delay()s the core by the duration of the waveform segment
|
2014-10-17 00:04:30 +08:00
|
|
|
self.tf.to_stop.advance()
|
2014-10-04 09:55:53 +08:00
|
|
|
# leaves the ion in the dark at the transport endpoint
|
|
|
|
delay(self.wait_at_stop)
|
|
|
|
# transport back (again: trigger, delay())
|
2014-10-17 00:04:30 +08:00
|
|
|
# segments can only be advance()ed in order
|
2015-03-23 05:31:59 +08:00
|
|
|
# since this is the last segment, pdq will go back to jump table
|
2014-10-17 00:04:30 +08:00
|
|
|
self.tf.from_stop.advance()
|
2014-10-04 09:55:53 +08:00
|
|
|
|
|
|
|
@kernel
|
|
|
|
def detect(self):
|
2016-01-20 11:09:10 +08:00
|
|
|
self.bd_sw.on()
|
2016-02-17 21:35:02 +08:00
|
|
|
self.pmt.gate_rising(100*us)
|
2014-10-04 09:55:53 +08:00
|
|
|
return self.pmt.count()
|
|
|
|
|
|
|
|
@kernel
|
|
|
|
def one(self):
|
|
|
|
self.cool()
|
|
|
|
self.transport()
|
|
|
|
return self.detect()
|
|
|
|
|
|
|
|
@kernel
|
2015-01-10 15:41:35 +08:00
|
|
|
def repeat(self):
|
2016-02-25 17:44:05 +08:00
|
|
|
self.core.break_realtime()
|
2016-02-17 00:42:28 +08:00
|
|
|
hist = [0 for _ in range(self.bins)]
|
2015-01-10 15:41:35 +08:00
|
|
|
for i in range(self.repeats):
|
2014-10-04 09:55:53 +08:00
|
|
|
n = self.one()
|
2016-02-17 00:42:28 +08:00
|
|
|
if n >= self.bins:
|
|
|
|
n = self.bins - 1
|
|
|
|
hist[n] += 1
|
|
|
|
self.set_dataset("hist", hist)
|
2014-10-04 09:55:53 +08:00
|
|
|
|
2015-01-10 15:41:35 +08:00
|
|
|
def scan(self, stops):
|
2014-10-04 09:55:53 +08:00
|
|
|
for s in stops:
|
2015-07-14 04:08:20 +08:00
|
|
|
# non-kernel, build frames
|
2014-10-04 09:55:53 +08:00
|
|
|
# could also be rpc'ed from repeat()
|
2015-07-14 04:08:20 +08:00
|
|
|
self.calc_waveforms(s)
|
2014-10-04 09:55:53 +08:00
|
|
|
# kernel part
|
2015-01-10 15:41:35 +08:00
|
|
|
self.repeat()
|
2014-10-04 09:55:53 +08:00
|
|
|
|
2015-01-10 15:41:35 +08:00
|
|
|
def run(self):
|
2014-10-04 09:55:53 +08:00
|
|
|
# scan transport endpoint
|
2016-02-22 22:29:19 +08:00
|
|
|
stops = np.linspace(0, 10, 10)
|
2015-01-10 15:41:35 +08:00
|
|
|
self.scan(stops)
|
2016-02-17 00:42:28 +08:00
|
|
|
|
|
|
|
|
|
|
|
# class Benchmark(Transport):
|
|
|
|
# def build(self):
|
|
|
|
# Transport.build(self)
|
|
|
|
# self.calc_waveforms(.3)
|
|
|
|
#
|
|
|
|
# @kernel
|
|
|
|
# def run(self):
|
|
|
|
# self.repeat()
|