Skip to content

Commit

Permalink
Merge 175f397 into 5368a5a
Browse files Browse the repository at this point in the history
  • Loading branch information
grahamrow committed May 23, 2019
2 parents 5368a5a + 175f397 commit 3a65412
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 7 deletions.
114 changes: 113 additions & 1 deletion QGL/ChannelLibraries.py
Expand Up @@ -37,14 +37,19 @@
import datetime
import importlib
import inspect
from functools import wraps
import operator
from functools import wraps, reduce
import itertools
import numpy as np
import networkx as nx
import logging

import bbndb

from bqplot import Figure, LinearScale, Axis, Lines, Figure
from bqplot.marks import Graph, Lines, Label
from ipywidgets import Layout, VBox, HBox

from . import config
from . import Channels
from . import PulseShapes
Expand Down Expand Up @@ -150,6 +155,113 @@ def ent_by_type(self, obj_type, show=False):
else:
return q

def show(self, qubits=[]):
# nodes = list(dgraph.nodes())
edges = []
qub_objs = qubits if not qubits == [] else self.qubits()
for q in qub_objs:
edges.append((q, q.measure_chan))
edges.append((q.measure_chan, q.measure_chan.phys_chan))
edges.append((q.measure_chan.phys_chan,q.measure_chan.phys_chan.transmitter))
edges.append((q, q.phys_chan))
edges.append((q.phys_chan, q.phys_chan.transmitter))

#Generators
if q.measure_chan.phys_chan.generator:
edges.append((q.measure_chan.phys_chan, q.measure_chan.phys_chan.generator))
if q.phys_chan.generator:
edges.append((q.phys_chan, q.phys_chan.generator))

# Triggers
if q.measure_chan.trig_chan:
edges.append((q.measure_chan, q.measure_chan.trig_chan))


graph = nx.digraph.DiGraph()
graph.add_edges_from(edges)

indices = {n: i for i, n in enumerate(graph.nodes())}
node_data = [{'label': str(n).replace('(','\r\n(')} for n in graph.nodes()]
link_data = [{'source': indices[s], 'target': indices[t]} for s, t in graph.edges()]

qub_objs.sort(key=lambda x: x.label)
qubit_names = [q.label for q in qub_objs]

loc = {}
def next_level(nodes, iteration=0, offset=0, accum=[]):
if len(accum) == 0:
loc[nodes[0]] = {'x': 0, 'y': 0}
accum = [nodes]
next_gen_nodes = list(reduce(operator.add, [list(graph.successors(n)) for n in nodes]))
l = len(next_gen_nodes)
if l > 0:
for k,n in enumerate(next_gen_nodes):
loc[n] = {'x': k, 'y': -(iteration+1)}
accum.append(next_gen_nodes)
return next_level(next_gen_nodes, iteration=iteration+1, offset=2.5*l, accum=accum)
else:
return accum

hierarchy = [next_level([q]) for q in qub_objs]
widest = [max([len(row) for row in qh]) for qh in hierarchy]
for i in range(1, len(qub_objs)):
offset = sum(widest[:i])
loc[qub_objs[i]]['x'] += offset*3
for n in nx.descendants(graph, qub_objs[i]):
loc[n]['x'] += offset*3

x = [loc[n]['x'] for n in graph.nodes()]
y = [loc[n]['y'] for n in graph.nodes()]
xs = LinearScale(min=min(x)-0.5, max=max(x)+0.6)
ys = LinearScale(min=min(y)-0.5, max=max(y)+0.6)
fig_layout = Layout(width='960px', height='500px')
bq_graph = Graph(node_data=node_data, link_data=link_data, x=x, y=y, scales={'x': xs, 'y': ys},
link_type='line', colors=['orange'] * len(node_data), directed=False)
bgs_lines = []
middles = []
for i in range(len(qub_objs)):
if i==0:
start = -0.4
end = widest[0]-0.6
elif i == len(qub_objs):
start = sum(widest)-0.4
end = max(x)+0.4
else:
start = sum(widest[:i])-0.4
end = sum(widest[:i+1])-0.6

fig = Figure(marks=[bq_graph], layout=fig_layout)
return fig

def show_frequency_plan(self):
c_freqs = {}
m_freqs = {}
for qubit in self.qubits():
c_freqs[qubit.label] = qubit.frequency*1e-9
if qubit.phys_chan.generator:
c_freqs[qubit.label] += qubit.phys_chan.generator.frequency*1e-9

m_freqs[qubit.label] = qubit.measure_chan.frequency*1e-9
if qubit.measure_chan.phys_chan.generator:
m_freqs[qubit.label] += qubit.measure_chan.phys_chan.generator.frequency*1e-9
def spike_at(f):
fs = np.linspace(f-0.02,f+0.02,50)
return fs, np.exp(-(fs-f)**2/0.01**2)
figs = []
for freqs, ss in zip([c_freqs, m_freqs],["Control","Measure"]):
sx = LinearScale()
sy = LinearScale()
ax = Axis(scale=sx, label="Frequency (GHz)")
ay = Axis(scale=sy, orientation='vertical')
lines = []
for k,f in freqs.items():
fs, a = spike_at(f)
lines.append(Lines(x=fs, y=a, scales={'x': sx, 'y': sy}))
labels = Label(x=list(freqs.values()), y=[1.1 for f in freqs], text=list(freqs.keys()), align='middle', scales= {'x': sx, 'y': sy},
default_size=14, font_weight='bolder', colors=['#4f6367'])
figs.append(Figure(marks=lines+[labels], axes=[ax, ay], title=f"{ss} Frequency Plan"))
return HBox(figs)

def receivers(self):
return self.ent_by_type(Channels.Receiver)

Expand Down
2 changes: 1 addition & 1 deletion tests/helpers.py
Expand Up @@ -2,7 +2,7 @@

def setup_test_lib():
cl = ChannelLibrary(db_resource_name=":memory:")

cl.clear()
q1 = cl.new_qubit(label='q1')
q2 = cl.new_qubit(label='q2')
q3 = cl.new_qubit(label='q3')
Expand Down
2 changes: 2 additions & 0 deletions tests/test_Compiler.py
Expand Up @@ -6,7 +6,9 @@

class CompileUtils(unittest.TestCase):
def setUp(self):
print("Running setup")
self.cl = ChannelLibrary(db_resource_name=":memory:")
self.cl.clear()
self.q1gate = Channels.LogicalMarkerChannel(label='q1-gate', channel_db=self.cl.channelDatabase)
self.q1gate = Channels.LogicalMarkerChannel(label='q1-gate', channel_db=self.cl.channelDatabase)
self.q1phys = Channels.PhysicalChannel(label='q1-phys', sampling_rate=1.2e9, channel_db=self.cl.channelDatabase)
Expand Down
10 changes: 5 additions & 5 deletions tests/test_Sequences.py
Expand Up @@ -454,15 +454,15 @@ def setUp(self):
AWGTestHelper.__init__(self, APS2Pattern)
for name in ['APS1', 'APS2', 'APS3', 'APS4', 'APS5', 'APS6']:
channelName = name + '-1'
channel = PhysicalQuadratureChannel(label=channelName)
channel = PhysicalQuadratureChannel(label=channelName, channel=0)
channel.sampling_rate = 1.2e9
channel.instrument = name
channel.translator = 'APS2Pattern'
self.channels[channelName] = channel

for m in range(1, 5):
channelName = "{0}-m{1}".format(name, m)
channel = PhysicalMarkerChannel(label=channelName)
channel = PhysicalMarkerChannel(label=channelName, channel=m-1)
channel.sampling_rate = 1.2e9
channel.instrument = name
channel.translator = 'APS2Pattern'
Expand Down Expand Up @@ -509,17 +509,17 @@ class TestAPS1(unittest.TestCase, AWGTestHelper, TestSequences):
def setUp(self):
AWGTestHelper.__init__(self, APSPattern)
for name in ['APS1', 'APS2', 'APS3']:
for ch in ['12', '34']:
for i, ch in enumerate(['12', '34']):
channelName = name + '-' + ch
channel = PhysicalQuadratureChannel(label=channelName)
channel = PhysicalQuadratureChannel(label=channelName, channel=i)
channel.sampling_rate = 1.2e9
channel.instrument = name
channel.translator = 'APSPattern'
self.channels[channelName] = channel

for m in range(1, 5):
channelName = "{0}-{1}m1".format(name, m)
channel = PhysicalMarkerChannel(label=channelName)
channel = PhysicalMarkerChannel(label=channelName, channel=m-1)
channel.sampling_rate = 1.2e9
channel.instrument = name
channel.translator = 'APSPattern'
Expand Down

0 comments on commit 3a65412

Please sign in to comment.