Skip to content

Commit

Permalink
Merge f52d820 into 146a533
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewware committed Sep 24, 2019
2 parents 146a533 + f52d820 commit 4924fc7
Show file tree
Hide file tree
Showing 8 changed files with 1,728 additions and 28 deletions.
57 changes: 45 additions & 12 deletions QGL/ChannelLibraries.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,14 @@ def update_channelDict(self):

def ls(self):
cdb = Channels.ChannelDatabase
q = self.session.query(cdb.label, cdb.time, cdb.id).\
order_by(Channels.ChannelDatabase.id, Channels.ChannelDatabase.label).all()
q = self.session.query(cdb.label, cdb.time, cdb.id, cdb.notes).\
order_by(Channels.ChannelDatabase.id, Channels.ChannelDatabase.label, Channels.ChannelDatabase.notes).all()
table_code = ""
for i, (label, time, id) in enumerate(q):
for i, (label, time, id, notes) in enumerate(q):
y, d, t = map(time.strftime, ["%Y", "%b. %d", "%I:%M:%S %p"])
# t = time.strftime("(%Y) %b. %d @ %I:%M:%S %p")
table_code += f"<tr><td>{id}</td><td>{y}</td><td>{d}</td><td>{t}</td><td>{label}</td></tr>"
display(HTML(f"<table><tr><th>id</th><th>Year</th><th>Date</th><th>Time</th><th>Name</th></tr><tr>{table_code}</tr></table>"))
table_code += f"<tr><td>{id}</td><td>{y}</td><td>{d}</td><td>{t}</td><td>{label}</td><td>{notes}</td></tr>"
display(HTML(f"<table><tr><th>id</th><th>Year</th><th>Date</th><th>Time</th><th>Name</th><th>Notes</th></tr><tr>{table_code}</tr></table>"))

def ent_by_type(self, obj_type, show=False):
q = self.session.query(obj_type).filter(obj_type.channel_db.has(label="working")).order_by(obj_type.label).all()
Expand Down Expand Up @@ -183,7 +183,7 @@ def show(self, qubits=[]):
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]

Expand Down Expand Up @@ -225,7 +225,7 @@ def next_level(nodes, iteration=0, offset=0, accum=[]):
end = widest[0]-0.6
elif i == len(qub_objs):
start = sum(widest)-0.4
end = max(x)+0.4
end = max(x)+0.4
else:
start = sum(widest[:i])-0.4
end = sum(widest[:i+1])-0.6
Expand All @@ -240,7 +240,7 @@ def show_frequency_plan(self):
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
Expand Down Expand Up @@ -333,13 +333,14 @@ def revert(self):
self.session.rollback()

@check_session_dirty
def save_as(self, name):
def save_as(self, name, notes = ''):
if name == "working":
raise ValueError("Cannot save as `working` since that is the default working environment name...")
self.commit()
new_channelDatabase = bbndb.deepcopy_sqla_object(self.channelDatabase, self.session)
new_channelDatabase.label = name
new_channelDatabase.time = datetime.datetime.now()
new_channelDatabase.notes = notes
self.commit()

def add_and_update_dict(self, el):
Expand Down Expand Up @@ -376,6 +377,19 @@ def build_connectivity_graph(self):
self.connectivityG.add_edge(chan.source, chan.target)
self.connectivityG[chan.source][chan.target]['channel'] = chan

@check_for_duplicates
def new_APS3(self, label, address, serial_port, **kwargs):
chan1 = Channels.PhysicalQuadratureChannel(label=f"{label}-1", channel=0, instrument=label, translator="APS3Pattern", sampling_rate=2.5e9, channel_db=self.channelDatabase)
chan2 = Channels.PhysicalQuadratureChannel(label=f"{label}-2", channel=1, instrument=label, translator="APS3Pattern", sampling_rate=2.5e9, channel_db=self.channelDatabase)
m1 = Channels.PhysicalMarkerChannel(label=f"{label}-m1", channel=0, instrument=label, translator="APS3Pattern", sampling_rate=2.5e9, channel_db=self.channelDatabase)

this_transmitter = Channels.Transmitter(label=label, model="APS3", address=address, serial_port=serial_port, channels=[chan1, chan2, m1], channel_db=self.channelDatabase, **kwargs)
this_transmitter.trigger_source = 'external' if 'trigger_source' not in kwargs else kwargs['trigger_source']

self.add_and_update_dict(this_transmitter)
return this_transmitter


@check_for_duplicates
def new_APS2(self, label, address, **kwargs):
chan1 = Channels.PhysicalQuadratureChannel(label=f"{label}-1", channel=0, instrument=label, translator="APS2Pattern", channel_db=self.channelDatabase)
Expand Down Expand Up @@ -409,7 +423,12 @@ def new_APS(self, label, address, **kwargs):

@check_for_duplicates
def new_TDM(self, label, address, **kwargs):
return Channels.Processor(label=label, model="TDM", address=address, trigger_interval=250e-6)
chans = []
for k in range(7): # TDM has 7 digital inputs
chans.append(Channels.DigitalInput(label=f"DigitalInput-{label}-{k}", channel=k, channel_db=self.channelDatabase))
tdm = Channels.Processor(label=label, model="TDM", address=address, trigger_interval=250e-6, channels=chans, channel_db=self.channelDatabase)
self.add_and_update_dict(tdm)
return tdm

@check_for_duplicates
def new_spectrum_analzyer(self, label, address, source, **kwargs):
Expand Down Expand Up @@ -541,7 +560,7 @@ def set_qubit_connectivity(self, graph):
self.add_and_update_dict(new_edges)
return new_edges

def set_measure(self, qubit, transmitter, receivers, generator=None, trig_channel=None, gate=False, gate_channel=None, trigger_length=1e-7):
def set_measure(self, qubit, transmitter, receivers, generator=None, trig_channel=None, gate=False, gate_channel=None, trigger_length=1e-7, tdm_chan=None):

if isinstance(transmitter, Channels.Transmitter):
quads = [c for c in transmitter.channels if isinstance(c, Channels.PhysicalQuadratureChannel)]
Expand Down Expand Up @@ -600,6 +619,20 @@ def set_measure(self, qubit, transmitter, receivers, generator=None, trig_channe
meas.gate_chan = gate_chan
self.add_and_update_dict([gate_chan])

if tdm_chan:
if isinstance(tdm_chan, Channels.DigitalInput):
phys_tdm_channel = tdm_chan
else:
if not hasattr(self.channelDatabase, 'processors') or not self.channelDatabase.processors:
raise ValueError(f"No processor is defined")
elif len(self.channelDatabase.processors) > 1:
raise ValueError(f"Multiple processors are defined. Please specify digital input channel.")
else:
tdm = self.channelDatabase.processors[0]
phys_tdm_channel = tdm.get_chan(tdm_chan)
meas.processor_chan = phys_tdm_channel
self.add_and_update_dict([meas, phys_tdm_channel])

def set_master(self, master_instrument, trig_channel=None, pulse_length=1e-7):

if isinstance(master_instrument, Channels.Processor):
Expand All @@ -622,7 +655,7 @@ def set_master(self, master_instrument, trig_channel=None, pulse_length=1e-7):
self.add_and_update_dict([st])

else:
raise ValueError(f"Could not determine which transmitter to set as master for {transmitter}:{trig_channel}")
raise ValueError(f"Could not determine which transmitter to set as master for {master_instrument}:{trig_channel}")

def QubitFactory(label):
''' Return a saved qubit channel'''
Expand Down
8 changes: 4 additions & 4 deletions QGL/GSTTools.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

PYGSTI_PRESENT = False
try:
from pygsti.objects import GateString
from pygsti.objects.circuit import Circuit
PYGSTI_PRESENT = True
except:
pass
Expand All @@ -51,11 +51,11 @@ def gst_map_1Q(gst_list, qubit, qgl_map=gst_gate_map, append_meas=True):
Returns:
QGL sequences, preserving the input list nesting (as a generator)
"""
if isinstance(gst_list, GateString):
if isinstance(gst_list, Circuit):
gst_list = [gst_list]
for item in gst_list:
if isinstance(item, GateString):
mapped = map(lambda x: qgl_map[x](qubit), item.tup)
if isinstance(item, Circuit):
mapped = map(lambda x: qgl_map[str(x)](qubit), item.tup)
if append_meas:
yield list(chain(mapped, [MEAS(qubit)]))
else:
Expand Down
1 change: 1 addition & 0 deletions QGL/PatternUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ def convert_lengths_to_samples(instructions, sampling_rate, quantization=1, wf_t
entry.length = int(round(entry.length * sampling_rate))
# TODO: warn when truncating?
entry.length -= entry.length % quantization

return instructions

def convert_length_to_samples(wf_length, sampling_rate, quantization=1):
Expand Down
2 changes: 1 addition & 1 deletion QGL/PulseSequencePlotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ def extract_waveforms(fileNames, nameDecorator='', time=False):

translator = resolve_translator(fileName, translators)
wfs = translator.read_sequence_file(fileName)
print(f"Sampling rate from extract_waveforms {translator.SAMPLING_RATE}")
sample_time = 1.0/translator.SAMPLING_RATE if time else 1

for (k, seqs) in sorted(wfs.items()):
if all_zero_seqs(seqs):
continue
Expand Down
17 changes: 11 additions & 6 deletions QGL/PulseShapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,17 @@ def tanh(amp=1, length=0, sigma=0, cutoff=2, sampling_rate=1e9, **params):
'''
A rounded constant shape from the sum of two tanh shapes.
'''
numPts = int(np.round(length * sampling_rate))
xPts = np.linspace(-length / 2, length / 2, numPts)
x1 = -length / 2 + cutoff * sigma
x2 = +length / 2 - cutoff * sigma
return amp * 0.5 * (np.tanh((xPts - x1) / sigma) + np.tanh(
(x2 - xPts) / sigma)).astype(np.complex)
if length == 0.0:
return np.empty(shape=(0,)).astype(np.complex)
else:
numPts = int(np.round(length * sampling_rate))
xPts = np.linspace(-length / 2, length / 2, numPts)
x1 = -length / 2 + cutoff * sigma
x2 = +length / 2 - cutoff * sigma
assert x1 < 0 and x2 > 0, ("Pulse length must be greater than 2 * "
"cuttoff * sigma. Consider using a Gaussian pulse instead.")
return amp * 0.5 * (np.tanh((xPts - x1) / sigma) + np.tanh(
(x2 - xPts) / sigma)).astype(np.complex)


def exp_decay(amp=1, length=0, sigma=0, sampling_rate=1e9, steady_state=0.4, **params):
Expand Down
13 changes: 9 additions & 4 deletions QGL/drivers/APS2Pattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
MAX_REPEAT_COUNT = 2**16 - 1
MAX_TRIGGER_COUNT = 2**32 - 1

MODULATION_CLOCK = 300e6

# instruction encodings
WFM = 0x0
MARKER = 0x1
Expand Down Expand Up @@ -578,7 +580,6 @@ def to_instruction(self, write_flag=True, label=None):
#Modulator op codes
MODULATOR_OP_OFFSET = 44
NCO_SELECT_OP_OFFSET = 40
MODULATION_CLOCK = 300e6

op_code_map = {"MODULATE": 0x0,
"RESET_PHASE": 0x2,
Expand Down Expand Up @@ -1389,7 +1390,9 @@ def tdm_instructions(seqs):

elif isinstance(s, PulseSequencer.Pulse):
if s.label == 'MEAS' and s.maddr != (-1, 0):
instructions.append(CrossBar(2**s.maddr[1], 0x1, label=label))
# tdm_chan specifies the input channel to the TDM carrying the qubit state. Defaults to 1
tdm_chan = m.channel.processor_chan.channel if getattr(m.channel, 'processor_chan') else 1
instructions.append(CrossBar(2**m.maddr[1], 2**(tdm_chan-1)), label=label)
instructions.append(LoadCmp(label=label))
instructions.append(StoreMeas(s.maddr[0], 1 << 16, label=label))

Expand All @@ -1403,7 +1406,9 @@ def tdm_instructions(seqs):
if len(set(maddr))>1:
raise Exception('Storing simultaneous measurements on different addresses not supported.')
for n,m in enumerate(sim_meas):
instructions.append(CrossBar(2**m.maddr[1], 2**n))
# each tdm_chan specifies the input channel to the TDM carrying the corresponding qubit state. Default values are the first n channels
tdm_chan = m.channel.processor_chan.channel if getattr(m.channel, 'processor_chan') else n+1
instructions.append(CrossBar(2**m.maddr[1], 2**(tdm_chan-1)))
instructions.append(LoadCmp(label=label))
instructions.append(StoreMeas(maddr[0], 1 << 16))

Expand Down Expand Up @@ -1624,7 +1629,7 @@ def open_plotter(addr=None, I=self.waveforms[0][addr:addr+count], Q=self.wavefor
self.tableWidget.setItem(k, j, item)
self.tableWidget.move(0,0)
self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)

app = QApplication(sys.argv[:1])
ex = App(read_instructions(sys.argv[1]), read_waveforms(sys.argv[1]))
sys.exit(app.exec_())

0 comments on commit 4924fc7

Please sign in to comment.