diff --git a/QGL/Compiler.py b/QGL/Compiler.py index 4d2f0bb1..fca5d786 100644 --- a/QGL/Compiler.py +++ b/QGL/Compiler.py @@ -307,7 +307,11 @@ def compile_to_hardware(seqs, axis_descriptor=None, add_slave_trigger=True, extra_meta=None, - tdm_seq = False): + tdm_seq=False, + meas_qs=None, + meas_decoupled_qs=None, + CR_chs=None, + CR_decoupled_chs=None): ''' Compiles 'seqs' to a hardware description and saves it to 'fileName'. Other inputs: @@ -331,6 +335,10 @@ def compile_to_hardware(seqs, # save input code to file save_code(seqs, fileName + suffix) + # add decoupling pulses + PatternUtils.decouple_seqs(seqs, meas_qs, meas_decoupled_qs, CR_chs, CR_decoupled_chs) + save_code(seqs, fileName + suffix) + # all sequences should start with a WAIT for synchronization for seq in seqs: if not isinstance(seq[0], ControlFlow.Wait): diff --git a/QGL/PatternUtils.py b/QGL/PatternUtils.py index 6b3dcf7a..fab739b5 100644 --- a/QGL/PatternUtils.py +++ b/QGL/PatternUtils.py @@ -20,13 +20,18 @@ import pickle from copy import copy from collections.abc import Iterable +from functools import reduce +import operator from .PulseSequencer import Pulse, TAPulse, PulseBlock, CompositePulse, CompoundGate, align from .PulsePrimitives import BLANK, X from . import ControlFlow from . import BlockLabel from . import TdmInstructions +from . import ChannelLibraries import QGL.drivers +from functools import reduce +import operator def hash_pulse(shape): return hashlib.sha1(shape.tostring()).hexdigest() @@ -364,3 +369,38 @@ def flatten_pulses(): print("Updating pulses for {}".format(awg)) translators[awg].update_wf_library(path + "-" + awg + ".aps", ps, offsets) + +def decouple_seqs(seqs, meas_qs, meas_decoupled_qs, CR_chs, CR_decoupled_chs): + for seq in seqs: + if meas_decoupled_qs: + decouple_meas_pulses(seq, meas_qs, meas_decoupled_qs) + if CR_decoupled_chs: + decouple_CR_pulses(seq, CR_chs, CR_decoupled_chs) + +def decouple_meas_pulses(seq, meas_qs, meas_decoupled_qs): + """ + Add decoupling X pulses to qubits meas_decoupled_qs during measurement on qubits meas_qs + """ + for (k,pulse) in enumerate(seq): + if isinstance(pulse, Pulse): + for qM in meas_qs: + #TODO: check if pulse block + if pulse.channel == ChannelLibraries.MeasFactory('M-%s' % qM.label): + #TODO: add arbitary shift of X from center + seq[k] = align(pulse *\ + reduce(operator.mul, [X(q) for q in meas_decoupled_qs])) + +def decouple_CR_pulses(seq, CR_qs, CR_decoupled_qs): + """ + Add decoupling X pulses to qubits CR_decoupled_qs between CR pulses on qubit pairs CR_qs (list of tuples) + """ + for seq_el in seq: + #for qsCR in CR_qs: + if isinstance(seq_el, CompoundGate): + for (k, pulse) in enumerate(seq_el.seq): + if isinstance(pulse.channel, collections.abc.KeysView) and any([ChannelLibraries.EdgeFactory(*qsCR) in pulse.channel for qsCR in CR_qs]): + seq_el.seq[k+1] = reduce(operator.mul, [seq_el.seq[k+1]] + [X(q) for q in CR_decoupled_qs]) + elif any([pulse.channel == ChannelLibraries.EdgeFactory(*qsCR) for qsCR in CR_qs]):# and pulse.channel == seq_el.seq[k+2].channel: + seq_el.seq[k+1] = reduce(operator.mul, [seq_el.seq[k+1]] + [X(q) for q in CR_decoupled_qs]) + return seq +