예제 #1
0
    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),
        ]
예제 #2
0
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
예제 #4
0
 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
예제 #5
0
 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')
예제 #10
0
    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
예제 #11
0
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']
예제 #13
0
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)
예제 #15
0
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)