def setUp(self): """Called before every test in the class.""" # Random instrument name, otherwise error if tests are run too fast... id = random.randint(1, 1000000) self.pulsar = Pulsar(f"pulsar_{id}") self.awg5014 = VirtualAWG5014(f"awg5014_{id}", timeout=20, address='TCPIP0::192.168.1.4') self.hdawg = ZI_HDAWG_qudev(f"hdawg_{id}", device="dev8000", interface="1GbE", server="emulator") # TODO: SHFQ currently has no virtual driver, so we do not unit test it. # self.shfqa = SHFQA(name=f"shfqa_{id}", serial="dev12000", host="localhost") self.uhfqc = UHFQA(f"uhfqc_{id}", device='dev2000', interface='1GbE', server="emulator") self.awgs: List[Tuple[Instrument, Type[PulsarAWGInterface]]] = [ (self.awg5014, AWG5014Pulsar), (self.hdawg, HDAWG8Pulsar), # (self.shfqa, SHFQAPulsar), (self.uhfqc, UHFQCPulsar), ]
def make5014pulsar(awg): awg = awg.name pulsar = Pulsar(name='PuLsAr', default_AWG=awg, master_AWG=awg) # pulsar = ps.Pulsar() # pulsar.AWG = AWG marker1highs = [2, 2, 2.7, 2, 2, 2, 2.7, 2] for i in range(8): pulsar.define_channel(id='ch{}'.format(i % 4 + 1), name='ch{}'.format(i + 1), type='analog', high=.7, low=-.7, offset=0.0, delay=0, active=True, AWG=awg) pulsar.define_channel(id='ch{}_marker1'.format(i % 4 + 1), name='ch{}_marker1'.format(i + 1), type='marker', high=marker1highs[i], low=0, offset=0., delay=0, active=True, AWG=awg) pulsar.define_channel(id='ch{}_marker2'.format(i % 4 + 1), name='ch{}_marker2'.format(i + 1), type='marker', high=2, low=0, offset=0., delay=0, active=True, AWG=awg) return pulsar
def setUp(self): # set up a pulsar with some mock settings for the element self.pulsar = Pulsar() for i in range(4): self.pulsar.define_channel(id='ch{}'.format(i+1), name='ch{}'.format(i+1), type='analog', # max safe IQ voltage high=.7, low=-.7, offset=0.0, delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker1'.format(i+1), name='ch{}_marker1'.format(i+1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker2'.format(i+1), name='ch{}_marker2'.format(i+1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True) self.pulse_pars = { 'I_channel': 'ch1', 'Q_channel': 'ch2', 'amplitude': .5, 'amp90_scale': .5, 'sigma': 10e-9, 'nr_sigma': 4, 'motzoi': .8, 'mod_frequency': 100e-6, 'pulse_delay': 0, 'phi_skew': 0, 'alpha': 1, 'phase': 0, 'pulse_type': 'SSB_DRAG_pulse'} self.RO_pars = { 'I_channel': 'ch3', 'Q_channel': 'ch4', 'RO_pulse_marker_channel': 'ch3_marker1', 'amplitude': '.5', 'length': 300e-9, 'pulse_delay': 0, 'mod_frequency': 50e6, 'fixed_point_frequency': -50e6, 'acq_marker_delay': 0, 'acq_marker_channel': 'ch1_marker1', 'phase': 0, 'pulse_type': 'MW_IQmod_pulse_tek'} station = Bunch(pulsar=self.pulsar) sqs.station = station
def _prepare_new_process(self): try: mp.set_start_method('spawn') except RuntimeError: if mp.get_start_method() != 'spawn': log.warning('Child process should be spawned') # pulsar object can't be pickled (and thus can't be passed to # new process), pass PulsarShadow object instead self.p_shadow = pulsar_shadow.PulsarShadow(Pulsar.get_instance()) for seq in self.sequences: seq.pulsar = self.p_shadow for seg in seq.segments.values(): seg.pulsar = self.p_shadow
def setUp(self): # set up a pulsar with some mock settings for the element self.station = qc.Station() self.AWG = VirtualAWG5014('AWG'+str(time.time())) self.AWG.clock_freq(1e9) self.pulsar = Pulsar('Pulsar' + str(time.time()), self.AWG.name) self.station.pulsar = self.pulsar for i in range(4): self.pulsar.define_channel(id='ch{}'.format(i+1), name='ch{}'.format(i+1), type='analog', # max safe IQ voltage high=.7, low=-.7, offset=0.0, delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker1'.format(i+1), name='ch{}_marker1'.format(i+1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker2'.format(i+1), name='ch{}_marker2'.format(i+1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True)
def setUp(self): # set up a pulsar with some mock settings for the element self.pulsar = Pulsar() for i in range(4): self.pulsar.define_channel(id='ch{}'.format(i+1), name='ch{}'.format(i+1), type='analog', # max safe IQ voltage high=.7, low=-.7, offset=0.0, delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker1'.format(i+1), name='ch{}_marker1'.format(i+1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker2'.format(i+1), name='ch{}_marker2'.format(i+1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True)
def set_5014pulsar(awg, awg2): awg = awg.name awg2 = awg2.name pulsar = Pulsar(name = 'PuLsAr', default_AWG = awg, master_AWG = awg) marker1highs = [2, 2, 2, 2, 2, 2, 2, 2] for i in range(8): pulsar.define_channel(id='ch{}'.format(i%4 + 1), name='ch{}'.format(i + 1), type='analog', high=2, low=-2, offset=0.0, delay=0, active=True, AWG = awg if i<4 else awg2) pulsar.define_channel(id='ch{}_marker1'.format(i%4 + 1), name='ch{}_marker1'.format(i + 1), type='marker', high=marker1highs[i], low=0, offset=0., delay=0, active=True, AWG = awg if i<4 else awg2) pulsar.define_channel(id='ch{}_marker2'.format(i%4 + 1), name='ch{}_marker2'.format(i + 1), type='marker', high=2, low=0, offset=0., delay=0, active=True, AWG = awg if i<4 else awg2) return pulsar
def set_5014pulsar(): pulsar = Pulsar(name='PuLsAr', ) marker1highs = [2, 2, 2, 2, 2, 2, 2, 2] for i in range(8): pulsar.define_channel( id='ch{}'.format(i + 1), name='ch{}'.format(i + 1), type='analog', high=2, low=-2, offset=0.0, delay=0, active=True, ) pulsar.define_channel( id='ch{}_marker1'.format(i + 1), name='ch{}_marker1'.format(i + 1), type='marker', high=marker1highs[i], low=0, offset=0., delay=0, active=True, ) pulsar.define_channel( id='ch{}_marker2'.format(i + 1), name='ch{}_marker2'.format(i + 1), type='marker', high=2, low=0, offset=0., delay=0, active=True, ) return pulsar
class Test_SingleQubitTek(unittest.TestCase): def setUp(self): # set up a pulsar with some mock settings for the element self.pulsar = Pulsar() for i in range(4): self.pulsar.define_channel(id='ch{}'.format(i+1), name='ch{}'.format(i+1), type='analog', # max safe IQ voltage high=.7, low=-.7, offset=0.0, delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker1'.format(i+1), name='ch{}_marker1'.format(i+1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker2'.format(i+1), name='ch{}_marker2'.format(i+1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True) self.pulse_pars = { 'I_channel': 'ch1', 'Q_channel': 'ch2', 'amplitude': .5, 'amp90_scale': .5, 'sigma': 10e-9, 'nr_sigma': 4, 'motzoi': .8, 'mod_frequency': 100e-6, 'pulse_delay': 0, 'phi_skew': 0, 'alpha': 1, 'phase': 0, 'pulse_type': 'SSB_DRAG_pulse'} self.RO_pars = { 'I_channel': 'ch3', 'Q_channel': 'ch4', 'RO_pulse_marker_channel': 'ch3_marker1', 'amplitude': '.5', 'length': 300e-9, 'pulse_delay': 0, 'mod_frequency': 50e6, 'fixed_point_frequency': -50e6, 'acq_marker_delay': 0, 'acq_marker_channel': 'ch1_marker1', 'phase': 0, 'pulse_type': 'MW_IQmod_pulse_tek'} station = Bunch(pulsar=self.pulsar) sqs.station = station def test_ramsey_no_detuning(self): times = np.linspace(0, 5e-6, 41) f_fix_pt = self.RO_pars['fixed_point_frequency'] # Sequence with no artificial detuning seq, el_list = sqs.Ramsey_seq(times, self.pulse_pars, self.RO_pars, artificial_detuning=None, cal_points=True, verbose=False, upload=False, return_seq=True) self.assertEqual(len(times), len(seq.elements)) self.assertEqual(len(times), len(el_list)) for i, el in enumerate(el_list): t_RO = el.effective_pulse_start_time('RO_tone-0', 'ch1') t_ROm = el.effective_pulse_start_time('Acq-trigger-0', 'ch1') self.assertAlmostEqual(t_RO, t_ROm, places=10) # test if fix point put pulses at the right spot. self.assertTrue(element.is_divisible_by_clock(t_RO, abs(f_fix_pt))) # Check pulse delay if i < (len(times)-4): t0 = el.effective_pulse_start_time('pulse_0-0', 'ch1') t1 = el.effective_pulse_start_time('pulse_1-0', 'ch1') self.assertAlmostEqual(t1-t0, times[i], places=10) p0 = el.pulses['pulse_0-0'] self.assertEqual(p0.phase, 0) p1 = el.pulses['pulse_1-0'] self.assertEqual(p1.phase, 0) else: # Calibration points do not have two pulses with self.assertRaises(KeyError): t1 = el.effective_pulse_start_time('pulse_1-0', 'ch1') def test_ramsey_freq_detuning(self): times = np.linspace(0, 5e-6, 41) for f_fix_pt in [50e-6, -50e-6]: self.RO_pars['fixed_point_frequency'] = f_fix_pt for RO_pulse_type in ['Gated_MW_RO_pulse', 'MW_IQmod_pulse_tek']: self.RO_pars['pulse_type'] = RO_pulse_type f_detuning = 300e3 # 300 kHz detuning # Sequence with artificial detuning specified in Hz seq, el_list = sqs.Ramsey_seq(times, self.pulse_pars, self.RO_pars, artificial_detuning=f_detuning, cal_points=True, verbose=False, upload=False, return_seq=True) self.assertEqual(len(times), len(seq.elements)) self.assertEqual(len(times), len(el_list)) for i, el in enumerate(el_list): if RO_pulse_type == 'MW_IQmod_pulse_tek': t_RO = el.effective_pulse_start_time( 'RO_tone-0', 'ch1') else: t_RO = el.effective_pulse_start_time( 'RO_marker-0', 'ch1') t_ROm = el.effective_pulse_start_time( 'Acq-trigger-0', 'ch1') self.assertAlmostEqual(t_RO, t_ROm, places=10) # test if fix point put pulses at the right spot. self.assertTrue( element.is_divisible_by_clock(t_RO, f_fix_pt)) # Check Ramsey pulse spacing if i < (len(times)-4): t0 = el.effective_pulse_start_time( 'pulse_0-0', 'ch1') t1 = el.effective_pulse_start_time( 'pulse_1-0', 'ch1') self.assertAlmostEqual(t1-t0, times[i], places=10) p0 = el.pulses['pulse_0-0'] self.assertEqual(p0.phase, 0) p1 = el.pulses['pulse_1-0'] exp_phase = (360*f_detuning*(t1-t0)) % 360 if exp_phase == 360: exp_phase = 0 self.assertAlmostEqual(p1.phase, exp_phase, places=3) else: # Calibration points do not have two pulses with self.assertRaises(KeyError): t1 = el.effective_pulse_start_time( 'pulse_1-0', 'ch1')
def setUp(self): # set up a pulsar with some mock settings for the element self.AWG = VirtualAWG5014('AWG' + str(time.time())) self.AWG.clock_freq(1e9) self.pulsar = Pulsar('Pulsar' + str(time.time()), self.AWG.name) for i in range(4): self.pulsar.define_channel( id='ch{}'.format(i + 1), name='ch{}'.format(i + 1), type='analog', # max safe IQ voltage high=.7, low=-.7, offset=0.0, delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker1'.format(i + 1), name='ch{}_marker1'.format(i + 1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker2'.format(i + 1), name='ch{}_marker2'.format(i + 1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True) self.pulse_pars = { 'I_channel': 'ch1', 'Q_channel': 'ch2', 'amplitude': .5, 'amp90_scale': .5, 'sigma': 10e-9, 'nr_sigma': 4, 'motzoi': .8, 'mod_frequency': 100e-6, 'pulse_delay': 0, 'phi_skew': 0, 'alpha': 1, 'phase': 0, 'pulse_type': 'SSB_DRAG_pulse' } self.RO_pars = { 'I_channel': 'ch3', 'Q_channel': 'ch4', 'operation_type': 'RO', 'RO_pulse_marker_channel': 'ch3_marker1', 'amplitude': '.5', 'length': 300e-9, 'pulse_delay': 0, 'mod_frequency': 50e6, 'acq_marker_delay': 0, 'acq_marker_channel': 'ch1_marker1', 'phase': 0, 'pulse_type': 'MW_IQmod_pulse_tek' } station = Bunch(pulsar=self.pulsar) sqs.station = station
class Test_SingleQubitTek(unittest.TestCase): def setUp(self): # set up a pulsar with some mock settings for the element self.AWG = VirtualAWG5014('AWG' + str(time.time())) self.AWG.clock_freq(1e9) self.pulsar = Pulsar('Pulsar' + str(time.time()), self.AWG.name) for i in range(4): self.pulsar.define_channel( id='ch{}'.format(i + 1), name='ch{}'.format(i + 1), type='analog', # max safe IQ voltage high=.7, low=-.7, offset=0.0, delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker1'.format(i + 1), name='ch{}_marker1'.format(i + 1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker2'.format(i + 1), name='ch{}_marker2'.format(i + 1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True) self.pulse_pars = { 'I_channel': 'ch1', 'Q_channel': 'ch2', 'amplitude': .5, 'amp90_scale': .5, 'sigma': 10e-9, 'nr_sigma': 4, 'motzoi': .8, 'mod_frequency': 100e-6, 'pulse_delay': 0, 'phi_skew': 0, 'alpha': 1, 'phase': 0, 'pulse_type': 'SSB_DRAG_pulse' } self.RO_pars = { 'I_channel': 'ch3', 'Q_channel': 'ch4', 'operation_type': 'RO', 'RO_pulse_marker_channel': 'ch3_marker1', 'amplitude': '.5', 'length': 300e-9, 'pulse_delay': 0, 'mod_frequency': 50e6, 'acq_marker_delay': 0, 'acq_marker_channel': 'ch1_marker1', 'phase': 0, 'pulse_type': 'MW_IQmod_pulse_tek' } station = Bunch(pulsar=self.pulsar) sqs.station = station def test_ramsey_no_detuning(self): times = np.linspace(0, 5e-6, 41) # Sequence with no artificial detuning seq, el_list = sqs.Ramsey_seq(times, self.pulse_pars, self.RO_pars, artificial_detuning=None, cal_points=True, verbose=False, upload=False, return_seq=True) self.assertEqual(len(times), len(seq.elements)) self.assertEqual(len(times), len(el_list)) for i, el in enumerate(el_list): t_RO = el.effective_pulse_start_time('RO_tone-0', 'ch1') t_ROm = el.effective_pulse_start_time('Acq-trigger-0', 'ch1') self.assertAlmostEqual(t_RO, t_ROm, places=10) # test if fix point put pulses at the right spot. self.assertAlmostEqual(t_RO, np.round(t_RO / 1e-6) * 1e-6) # Check pulse delay if i < (len(times) - 4): t0 = el.effective_pulse_start_time('SSB_DRAG_pulse_0-0', 'ch1') t1 = el.effective_pulse_start_time('SSB_DRAG_pulse_1-0', 'ch1') self.assertAlmostEqual(t1 - t0, times[i], places=10) p0 = el.pulses['SSB_DRAG_pulse_0-0'] self.assertEqual(p0.phase, 0) p1 = el.pulses['SSB_DRAG_pulse_1-0'] self.assertEqual(p1.phase, 0) else: # Calibration points do not have two pulses with self.assertRaises(KeyError): t1 = el.effective_pulse_start_time('pulse_1-0', 'ch1') def test_ramsey_freq_detuning(self): times = np.linspace(0, 5e-6, 41) for f_fix_pt in [50e-6, -50e-6]: for RO_pulse_type in ['Gated_MW_RO_pulse', 'MW_IQmod_pulse_tek']: self.RO_pars['pulse_type'] = RO_pulse_type f_detuning = 300e3 # 300 kHz detuning # Sequence with artificial detuning specified in Hz seq, el_list = sqs.Ramsey_seq(times, self.pulse_pars, self.RO_pars, artificial_detuning=f_detuning, cal_points=True, verbose=False, upload=False, return_seq=True) self.assertEqual(len(times), len(seq.elements)) self.assertEqual(len(times), len(el_list)) for i, el in enumerate(el_list): if RO_pulse_type == 'MW_IQmod_pulse_tek': t_RO = el.effective_pulse_start_time( 'RO_tone-0', 'ch1') else: t_RO = el.effective_pulse_start_time( 'RO_marker-0', 'ch1') t_ROm = el.effective_pulse_start_time( 'Acq-trigger-0', 'ch1') self.assertAlmostEqual(t_RO, t_ROm, places=10) # test if fix point put pulses at the right spot. self.assertAlmostEqual(t_RO, np.round(t_RO / 1e-6) * 1e-6) # Check Ramsey pulse spacing if i < (len(times) - 4): t0 = el.effective_pulse_start_time( 'SSB_DRAG_pulse_0-0', 'ch1') t1 = el.effective_pulse_start_time( 'SSB_DRAG_pulse_1-0', 'ch1') self.assertAlmostEqual(t1 - t0, times[i], places=10) p0 = el.pulses['SSB_DRAG_pulse_0-0'] self.assertEqual(p0.phase, 0) p1 = el.pulses['SSB_DRAG_pulse_1-0'] exp_phase = (360 * f_detuning * (t1 - t0)) % 360 if exp_phase == 360: exp_phase = 0 self.assertAlmostEqual(p1.phase, exp_phase, places=3) else: # Calibration points do not have two pulses with self.assertRaises(KeyError): t1 = el.effective_pulse_start_time( 'pulse_1-0', 'ch1')
def AWG_Test(): station.pulsar = Pulsar() station.pulsar.AWG = station.components['awg'] marker1highs = [2, 2, 2.7, 2] for i in range(4): # Note that these are default parameters and should be kept so. # the channel offset is set in the AWG itself. For now the amplitude is # hardcoded. You can set it by hand but this will make the value in the # sequencer different. station.pulsar.define_channel( id='ch{}'.format(i + 1), name='ch{}'.format(i + 1), type='analog', # max safe IQ voltage high=.7, low=-.7, offset=0.0, delay=0, active=True) station.pulsar.define_channel(id='ch{}_marker1'.format(i + 1), name='ch{}_marker1'.format(i + 1), type='marker', high=marker1highs[i], low=0, offset=0., delay=0, active=True) station.pulsar.define_channel(id='ch{}_marker2'.format(i + 1), name='ch{}_marker2'.format(i + 1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True) #Implementation of a sequence element. #Basic idea: add different pulses, and compose the actual numeric #arrays that form the amplitudes for the hardware (typically an AWG) V_empty = 0 V_load = 0.05 V_read = 0.025 t_empty = 20e-6 t_load = 10e-6 t_read = 20e-6 Npoints = 1 Empty_elt = Element('Empty_elt', pulsar=station.pulsar) Empty_elt.add(SquarePulse(name='square_empty', channel='ch1', amplitude=V_empty, start=0, length=t_empty), name='Empty') Load_elt = Element('Load_elt', pulsar=station.pulsar) Load_elt.add(SquarePulse(name='square_load', channel='ch1', amplitude=V_load, start=0, length=t_load), name='Load') Read_elt = Element('Read_elt', pulsar=station.pulsar) Read_elt.add(SquarePulse(name='square_read', channel='ch1', amplitude=V_read, start=0, length=t_read), name='Read') ReadEmpty_elt = Element('ReadEmpty_elt', pulsar=station.pulsar) ReadEmpty_elt.add(SquarePulse(name='square_read', channel='ch1', amplitude=V_read, start=0, length=t_read), name='Read') ReadEmpty_elt.add(SquarePulse(name='square_empty', channel='ch1', amplitude=V_empty, start=0, length=t_empty), name='Empty', refpulse='Read', refpoint='end', refpoint_new='start') elts = [Empty_elt, Load_elt, Read_elt, ReadEmpty_elt] T1_seq = Sequence('T1_Sequence') T1_seq.append('Empty_0', 'Empty_elt') for i in range(Npoints): name_Load = 'Load_{}'.format(i) name_ReadEmpty = 'ReadEmpty_{}'.format(i) T1_seq.append(name_Load, 'Load_elt', repetitions=i + 1) T1_seq.append(name_ReadEmpty, 'ReadEmpty_elt') ss = station.pulsar.program_awg(T1_seq, *elts) win = show_element_pyqt(ReadEmpty_elt, QtPlot_win=None, color_idx=None, channels=['ch1', 'ch2', 'ch3', 'ch4']) ch1_wf = test_elt.waveforms()[1]['ch1']
class TestPulsarAWGInterface(TestCase): """Generic tests that apply to all pulsar AWG interfaces.""" def setUp(self): """Called before every test in the class.""" # Random instrument name, otherwise error if tests are run too fast... id = random.randint(1, 1000000) self.pulsar = Pulsar(f"pulsar_{id}") self.awg5014 = VirtualAWG5014(f"awg5014_{id}", timeout=20, address='TCPIP0::192.168.1.4') self.hdawg = ZI_HDAWG_qudev(f"hdawg_{id}", device="dev8000", interface="1GbE", server="emulator") # TODO: SHFQ currently has no virtual driver, so we do not unit test it. # self.shfqa = SHFQA(name=f"shfqa_{id}", serial="dev12000", host="localhost") self.uhfqc = UHFQA(f"uhfqc_{id}", device='dev2000', interface='1GbE', server="emulator") self.awgs: List[Tuple[Instrument, Type[PulsarAWGInterface]]] = [ (self.awg5014, AWG5014Pulsar), (self.hdawg, HDAWG8Pulsar), # (self.shfqa, SHFQAPulsar), (self.uhfqc, UHFQCPulsar), ] def test_interfaces_are_registered(self): for interface in registered_interfaces: self.assertIn(interface, PulsarAWGInterface._pulsar_interfaces) def test_instantiate(self): for awg, interface_class in self.awgs: with self.subTest(interface_class): awg_interface = interface_class(self.pulsar, awg) self.assertEqual(awg, awg_interface.awg) def test_get_interface_class(self): # Assert know class interface = PulsarAWGInterface.get_interface_class(VirtualAWG5014) self.assertEqual(interface, AWG5014Pulsar) # Assert instance of known class awg = VirtualAWG5014("awg_test_get_interface_class") interface = PulsarAWGInterface.get_interface_class(awg) self.assertEqual(interface, AWG5014Pulsar) # Assert error for unknown class with self.assertRaises(ValueError): PulsarAWGInterface.get_interface_class(float) def test_create_awg_parameters(self): for awg, interface_class in self.awgs: with self.subTest(interface_class): awg_interface = interface_class(self.pulsar, awg) awg_interface.create_awg_parameters({}) # Common params defined in PulsarAWGInterface.create_awg_parameters() parameters = [ "_active", "_reuse_waveforms", "_minimize_sequencer_memory", "_enforce_single_element", "_granularity", "_element_start_granularity", "_min_length", "_inter_element_deadtime", "_precompile", "_delay", "_trigger_channels", "_compensation_pulse_min_length", ] parameters = [f"{awg.name}{p}" for p in parameters] assert_has_parameters(self, self.pulsar, parameters) def test_create_channel_parameters(self): for awg, interface_class in self.awgs: with self.subTest(interface_class): awg_interface = interface_class(self.pulsar, awg) for ch_type, suffix in [("analog", ""), ("marker", "m")]: if awg_interface.__class__ in [UHFQCPulsar, SHFQAPulsar] \ and ch_type == "marker": # These classes do not use marker channels continue id = "ch1" ch_name = f"{awg.name}_{id}{suffix}" awg_interface.create_channel_parameters( id, ch_name, ch_type) # Common params defined in PulsarAWGInterface.create_channel_parameters() parameters = [ "_id", "_awg", "_type", "_amp", "_offset", ] parameters = [f"{ch_name}{p}" for p in parameters] analog_parameters = [ "_distortion", "_distortion_dict", "_charge_buildup_compensation", "_compensation_pulse_scale", "_compensation_pulse_delay", "_compensation_pulse_gaussian_filter_sigma", ] analog_parameters = [ f"{ch_name}{p}" for p in analog_parameters ] marker_parameters = [] marker_parameters = [ f"{ch_name}{p}" for p in marker_parameters ] if ch_type == "analog": all_parameters = parameters + analog_parameters else: all_parameters = parameters + marker_parameters assert_has_parameters(self, self.pulsar, all_parameters) def test_program_awg(self): for awg, interface_class in self.awgs: with self.subTest(interface_class): # Register AWG in pulsar self.pulsar.define_awg_channels(awg) awg_interface = self.pulsar.awg_interfaces[awg.name] # Generate sequence pulses = [{ "name": f"pulse", "pulse_type": "SquarePulse", "pulse_delay": 0, "ref_pulse": "previous_pulse", "ref_point": "end", "length": 5e-8, "amplitude": 0.05, "channels": [f"{awg.name}_ch1"], "channel": f"{awg.name}_ch1", }] segment = Segment("segment", pulses) sequence = Sequence("sequence", segments=[segment]) waveforms, awg_sequences = sequence.generate_waveforms_sequences( ) # Actual function to test awg_interface.program_awg( awg_sequences[awg.name], waveforms, ) def test_awg_getter_setter(self): for awg, interface_class in self.awgs: with self.subTest(interface_class): # Register AWG in pulsar self.pulsar.define_awg_channels(awg) awg_interface = self.pulsar.awg_interfaces[awg.name] for param in awg_interface.IMPLEMENTED_ACCESSORS: awg_interface.awg_setter("ch1", param, 0.0123) v = awg_interface.awg_getter("ch1", param) # TODO: Fix the underlying behavior of the UHFQC if param == "amp" and "uhfqc" in awg.name: continue self.assertEqual(v, 0.0123) def test_start_stop_is_running(self): """Test starting/stopping/is_running on the AWGs. Some AWGs (e.g. HDAWG) will not start if they have no waveforms to play, thus we need to upload them to make sure the methods work. """ for awg, interface_class in self.awgs: with self.subTest(interface_class): # TODO AWG5014 fails because virtual instrument not implemented # correctly, missing visa_log and other attributes. if "awg5014" in awg.name: continue # Register AWG in pulsar self.pulsar.define_awg_channels(awg) awg_interface = self.pulsar.awg_interfaces[awg.name] # Generate sequence pulses = [{ "name": f"pulse", "pulse_type": "SquarePulse", "pulse_delay": 0, "ref_pulse": "previous_pulse", "ref_point": "end", "length": 5e-8, "amplitude": 0.05, "channels": [f"{awg.name}_ch1"], "channel": f"{awg.name}_ch1", }] segment = Segment("segment", pulses) sequence = Sequence("sequence", segments=[segment]) waveforms, awg_sequences = sequence.generate_waveforms_sequences( ) awg_interface.program_awg( awg_sequences[awg.name], waveforms, ) # Test start awg_interface.start() self.assertTrue(awg_interface.is_awg_running()) # Test stop awg_interface.stop() self.assertFalse(awg_interface.is_awg_running()) def test_clock(self): EXPECTED_FREQUENCIES = { AWG5014Pulsar: 1.2e9, HDAWG8Pulsar: 2.4e9, SHFQAPulsar: 2.0e9, UHFQCPulsar: 1.8e9, } for awg, interface_class in self.awgs: with self.subTest(interface_class): awg_interface = interface_class(self.pulsar, awg) freq = awg_interface.clock() self.assertEqual(freq, EXPECTED_FREQUENCIES[interface_class])
class Test_Element(unittest.TestCase): def setUp(self): # set up a pulsar with some mock settings for the element self.pulsar = Pulsar() for i in range(4): self.pulsar.define_channel(id='ch{}'.format(i+1), name='ch{}'.format(i+1), type='analog', # max safe IQ voltage high=.7, low=-.7, offset=0.0, delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker1'.format(i+1), name='ch{}_marker1'.format(i+1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker2'.format(i+1), name='ch{}_marker2'.format(i+1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True) def test_basic_element(self): test_elt = element.Element('test_elt', pulsar=self.pulsar) test_elt.add(SquarePulse(name='dummy_square', channel='ch1', amplitude=.3, length=20e-9)) min_samples = 960 ch1_wf = test_elt.waveforms()[1]['ch1'] self.assertEqual(len(ch1_wf), min_samples) expected_wf = np.zeros(960) expected_wf[:20] = .3 np.testing.assert_array_almost_equal(ch1_wf, expected_wf) def test_timing(self): test_elt = element.Element('test_elt', pulsar=self.pulsar) refpulse = SquarePulse(name='dummy_square', channel='ch1', amplitude=0, length=20e-9) test_elt.add(refpulse, start=100e-9, name='dummy_square') test_elt.add(SquarePulse(name='dummy_square', channel='ch1', amplitude=.3, length=20e-9), refpulse='dummy_square', start=100e-9, refpoint='start') min_samples = 960 ch1_wf = test_elt.waveforms()[1]['ch1'] self.assertEqual(len(ch1_wf), min_samples) expected_wf = np.zeros(960) expected_wf[100:120] = .3 np.testing.assert_array_almost_equal(ch1_wf, expected_wf) def test_fixpoint(self): # Fixed point should shift both elements by 2 ns test_elt = element.Element('test_elt', pulsar=self.pulsar) refpulse = SquarePulse(name='dummy_square', channel='ch1', amplitude=.5, length=20e-9) test_elt.add(refpulse, name='dummy_square') test_elt.add(SquarePulse(name='dummy_square', channel='ch1', amplitude=.3, length=20e-9), fixed_point_freq=-200e6, refpulse='dummy_square', start=98e-9, refpoint='start') min_samples = 960 ch1_wf = test_elt.waveforms()[1]['ch1'] self.assertEqual(len(ch1_wf), min_samples) expected_wf = np.zeros(960) expected_wf[2:22] = .5 expected_wf[100:120] = .3 np.testing.assert_array_almost_equal(ch1_wf, expected_wf)
class Test_Element(unittest.TestCase): def setUp(self): # set up a pulsar with some mock settings for the element self.station = qc.Station() self.AWG = VirtualAWG5014('AWG'+str(time.time())) self.AWG.clock_freq(1e9) self.pulsar = Pulsar('Pulsar' + str(time.time()), self.AWG.name) self.station.pulsar = self.pulsar for i in range(4): self.pulsar.define_channel(id='ch{}'.format(i+1), name='ch{}'.format(i+1), type='analog', # max safe IQ voltage high=.7, low=-.7, offset=0.0, delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker1'.format(i+1), name='ch{}_marker1'.format(i+1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True) self.pulsar.define_channel(id='ch{}_marker2'.format(i+1), name='ch{}_marker2'.format(i+1), type='marker', high=2.0, low=0, offset=0., delay=0, active=True) def test_basic_element(self): test_elt = element.Element('test_elt', pulsar=self.pulsar) test_elt.add(SquarePulse(name='dummy_square', channel='ch1', amplitude=.3, length=20e-9)) min_samples = 960 ch1_wf = test_elt.waveforms()[1]['ch1'] self.assertEqual(len(ch1_wf), min_samples) expected_wf = np.zeros(960) expected_wf[:20] = .3 np.testing.assert_array_almost_equal(ch1_wf, expected_wf) def test_timing(self): test_elt = element.Element('test_elt', pulsar=self.pulsar) refpulse = SquarePulse(name='dummy_square', channel='ch1', amplitude=0, length=20e-9) test_elt.add(refpulse, start=100e-9, name='dummy_square') test_elt.add(SquarePulse(name='dummy_square', channel='ch1', amplitude=.3, length=20e-9), refpulse='dummy_square', start=100e-9, refpoint='start') min_samples = 960 ch1_wf = test_elt.waveforms()[1]['ch1'] self.assertEqual(len(ch1_wf), min_samples) expected_wf = np.zeros(960) expected_wf[100:120] = .3 np.testing.assert_array_almost_equal(ch1_wf, expected_wf) def test_fixpoint(self): # Fixed point should shift both elements by 2 ns test_elt = element.Element('test_elt', pulsar=self.pulsar) refpulse = SquarePulse(name='dummy_square', channel='ch1', amplitude=.5, length=20e-9) test_elt.add(refpulse, name='dummy_square') test_elt.add(SquarePulse(name='dummy_square', channel='ch1', amplitude=.3, length=20e-9), operation_type='RO', refpulse='dummy_square', start=98e-9, refpoint='start') min_samples = 1020 ch1_wf = test_elt.waveforms()[1]['ch1'] self.assertEqual(len(ch1_wf), min_samples) expected_wf = np.zeros(1020) expected_wf[902:922] = .5 expected_wf[1000:1020] = .3 np.testing.assert_array_almost_equal(ch1_wf, expected_wf) def test_operation_dependent_buffers_and_compensation(self): # Fixed point should shift both elements by 2 ns RO_amp = 0.1 MW_amp = 0.3 Flux_amp = 0.5 operation_dict = {'RO q0': {'amplitude': RO_amp, 'length': 300e-9, 'operation_type': 'RO', 'channel': 'ch1', 'pulse_delay': 0, 'pulse_type': 'SquarePulse'}, 'MW q0': {'amplitude': MW_amp, 'length': 20e-9, 'operation_type': 'MW', 'channel': 'ch1', 'pulse_delay': 0, 'pulse_type': 'SquarePulse'}, 'Flux q0': {'amplitude': Flux_amp, 'length': 40e-9, 'operation_type': 'Flux', 'channel': 'ch1', 'pulse_delay': 0, 'pulse_type': 'SquarePulse'}, 'sequencer_config': {'Buffer_Flux_Flux': 1e-9, 'Buffer_Flux_MW': 2e-9, 'Buffer_Flux_RO': 3e-9, 'Buffer_MW_Flux': 4e-9, 'Buffer_MW_MW': 5e-9, 'Buffer_MW_RO': 6e-9, 'Buffer_RO_Flux': 7e-9, 'Buffer_RO_MW': 8e-9, 'Buffer_RO_RO': 10e-9, 'RO_fixed_point': 1e-06, 'Flux_comp_dead_time': 3e-6}} sequencer_config = operation_dict['sequencer_config'] fake_seq = ['MW q0', 'MW q0', 'Flux q0', 'MW q0', 'RO q0'] pulses = [] for p in fake_seq: pulses += [operation_dict[p]] test_elt = multi_pulse_elt(0, self.station, pulses, sequencer_config) min_samples = 1800+3040 # 1us fixpoint, 300ns RO pulse and 4ns zeros ch1_wf = test_elt.waveforms()[1]['ch1'] self.assertEqual(len(ch1_wf), min_samples) expected_wf = np.zeros(min_samples) expected_wf[1000:1300] = RO_amp expected_wf[974:994] = MW_amp expected_wf[932:972] = Flux_amp expected_wf[908:928] = MW_amp expected_wf[883:903] = MW_amp expected_wf[4300:4340] = -Flux_amp np.testing.assert_array_almost_equal(ch1_wf, expected_wf)