예제 #1
0
    def setup_arb(
            self):  #, gate_bias, gate_pulse_amplitude, gate_pulse_duration):
        self.arb.abort()
        self.arb.delete_all_waveforms()
        self.arb.reset_sequence_table()

        seg_ids_ch1 = []
        seg_ids_ch2 = []

        # For the measurements pulses along the channel
        wf = measure_pulse(amplitude=self.measure_amplitude,
                           duration=self.measure_duration,
                           frequency=self.measure_frequency)
        wf_data = KeysightM8190A.create_binary_wf_data(wf, sync_mkr=1)
        seg_id = self.arb.define_waveform(len(wf_data), channel=1)
        self.arb.upload_waveform(wf_data, seg_id, channel=1)
        seg_ids_ch1.append(seg_id)

        # Build in a delay between sequences
        settle_pts = 640 * np.int(
            np.ceil(self.repeat_time * self.sample_rate / 640))
        # settle_pts2 = 640*np.ceil(8*2.4e-9 * self.sample_rate / 640)

        scenario = Scenario()
        seq = Sequence(sequence_loop_ct=self.attempts * len(self.gate_amps) *
                       len(self.gate_durs))
        for si in seg_ids_ch1:
            seq.add_waveform(si)
            seq.add_idle(settle_pts, 0.0)
        scenario.sequences.append(seq)
        self.arb.upload_scenario(scenario, start_idx=0, channel=1)

        for amp in self.gate_amps:
            for dur in self.gate_durs:
                # For the switching pulses along the gate
                wf = switching_pulse(
                    amplitude=amp,
                    duration=dur)  #self.gate_pulse_duration.value)
                wf_data = KeysightM8190A.create_binary_wf_data(wf)
                seg_id = self.arb.define_waveform(len(wf_data), channel=2)
                self.arb.upload_waveform(wf_data, seg_id, channel=2)
                seg_ids_ch2.append(seg_id)

        scenario = Scenario()
        seq = Sequence(sequence_loop_ct=self.attempts)
        for si in seg_ids_ch2:
            seq.add_waveform(si)
            seq.add_idle(settle_pts, 0.0)
        scenario.sequences.append(seq)
        self.arb.upload_scenario(scenario, start_idx=0, channel=2)

        self.arb.set_sequence_mode("SCENARIO", channel=1)
        self.arb.set_scenario_advance_mode("SINGLE", channel=1)
        self.arb.set_scenario_start_index(0, channel=1)
        self.arb.set_sequence_mode("SCENARIO", channel=2)
        self.arb.set_scenario_advance_mode("SINGLE", channel=2)
        self.arb.set_scenario_start_index(0, channel=2)
        self.arb.initiate(channel=1)
        self.arb.initiate(channel=2)
        self.arb.advance()
    def setup_arb(self,volt):
        def arb_pulse(amplitude, duration, sample_rate=12e9):
            arb_voltage = arb_voltage_lookup()
            pulse_points = int(duration*sample_rate)
            if pulse_points < 320:
                wf = np.zeros(320)
            else:
                wf = np.zeros(64*np.ceil(pulse_points/64.0))
            wf[:pulse_points] = np.sign(amplitude)*arb_voltage(abs(amplitude))
            return wf

        self.arb.abort()
        self.arb.delete_all_waveforms()
        self.arb.reset_sequence_table()

        # Reset waveform
        reset_wf    = arb_pulse(-self.polarity*self.reset_amplitude, self.reset_duration)
        wf_data     = KeysightM8190A.create_binary_wf_data(reset_wf)
        rst_segment_id  = self.arb.define_waveform(len(wf_data))
        self.arb.upload_waveform(wf_data, rst_segment_id)

        # Switching waveform
        switch_wf    = arb_pulse(self.polarity*volt, self.pulse_duration.value)
        wf_data     = KeysightM8190A.create_binary_wf_data(switch_wf)
        sw_segment_id  = self.arb.define_waveform(len(wf_data))
        self.arb.upload_waveform(wf_data, sw_segment_id)

        # NIDAQ trigger waveform
        nidaq_trig_wf = KeysightM8190A.create_binary_wf_data(np.zeros(3200), sync_mkr=1)
        nidaq_trig_segment_id = self.arb.define_waveform(len(nidaq_trig_wf))
        self.arb.upload_waveform(nidaq_trig_wf, nidaq_trig_segment_id)

        settle_pts = int(640*np.ceil(self.settle_delay * 12e9 / 640))

        scenario = Scenario()
        seq = Sequence(sequence_loop_ct=int(self.attempts))
        #First try with reset flipping pulse
        seq.add_waveform(rst_segment_id)
        seq.add_idle(settle_pts, 0.0)
        seq.add_waveform(nidaq_trig_segment_id)
        seq.add_idle(1 << 16, 0.0) # bonus non-contiguous memory delay
        seq.add_waveform(sw_segment_id)
        seq.add_idle(settle_pts, 0.0)
        seq.add_waveform(nidaq_trig_segment_id)
        seq.add_idle(1 << 16, 0.0) # bonus non-contiguous memory delay
        scenario.sequences.append(seq)
        self.arb.upload_scenario(scenario, start_idx=0)
        self.arb.sequence_mode = "SCENARIO"
        self.arb.scenario_advance_mode = "REPEAT"
        self.arb.scenario_start_index = 0
        self.arb.run()
예제 #3
0
    def setup_daq(self):
        self.arb.abort()
        self.arb.delete_all_waveforms()
        self.arb.reset_sequence_table()

        # Picosecond trigger waveform
        pspl_trig_wf = KeysightM8190A.create_binary_wf_data(np.zeros(3200),
                                                            samp_mkr=1)
        pspl_trig_segment_id = self.arb.define_waveform(len(pspl_trig_wf))
        self.arb.upload_waveform(pspl_trig_wf, pspl_trig_segment_id)

        # NIDAQ trigger waveform
        nidaq_trig_wf = KeysightM8190A.create_binary_wf_data(np.zeros(3200),
                                                             sync_mkr=1)
        nidaq_trig_segment_id = self.arb.define_waveform(len(nidaq_trig_wf))
        self.arb.upload_waveform(nidaq_trig_wf, nidaq_trig_segment_id)

        settle_pts = int(640 * np.ceil(self.settle_delay * 12e9 / 640))
        scenario = Scenario()
        seq = Sequence(sequence_loop_ct=int(self.attempts))
        seq.add_waveform(pspl_trig_segment_id)
        seq.add_idle(settle_pts, 0.0)
        seq.add_waveform(nidaq_trig_segment_id)
        seq.add_idle(1 << 16, 0.0)  # bonus non-contiguous memory delay
        scenario.sequences.append(seq)
        self.arb.upload_scenario(scenario, start_idx=0)
        self.arb.sequence_mode = "SCENARIO"
        self.arb.scenario_advance_mode = "REPEAT"
        self.arb.scenario_start_index = 0
        self.arb.run()

        # ===================
        #   Setup the NIDAQ
        # ===================
        self.analog_input = Task()
        self.read = int32()
        self.buf_points = self.samps_per_trig * self.attempts
        self.analog_input.CreateAIVoltageChan("Dev1/ai1", "", DAQmx_Val_Diff,
                                              self.min_daq_voltage,
                                              self.max_daq_voltage,
                                              DAQmx_Val_Volts, None)
        self.analog_input.CfgSampClkTiming("", 1e6, DAQmx_Val_Rising,
                                           DAQmx_Val_FiniteSamps,
                                           self.samps_per_trig)
        self.analog_input.CfgInputBuffer(self.buf_points)
        self.analog_input.CfgDigEdgeStartTrig("/Dev1/PFI0", DAQmx_Val_Rising)
        self.analog_input.SetStartTrigRetriggerable(1)
        self.analog_input.StartTask()
예제 #4
0
    def init_instruments(self):
        self.lock.tc = self.tc

        # Setup the Keithley
        # self.keith.triad()
        # self.keith.conf_meas_res(res_range=1e5)
        # self.keith.conf_src_curr(comp_voltage=0.5, curr_range=1.0e-5)
        # self.keith.current = self.measure_current
        self.mag.ramp()

        # Setup the AWG
        self.arb.set_output(True, channel=1)
        self.arb.set_output(False, channel=2)
        self.arb.sample_freq = 12.0e9
        self.arb.waveform_output_mode = "WSPEED"
        self.arb.abort()
        self.arb.delete_all_waveforms()
        self.arb.reset_sequence_table()
        self.arb.set_output_route("DC", channel=1)
        self.arb.voltage_amplitude = 1.0
        self.arb.set_marker_level_low(0.0, channel=1, marker_type="sync")
        self.arb.set_marker_level_high(1.5, channel=1, marker_type="sync")
        self.arb.continuous_mode = False
        self.arb.gate_mode = False

        def arb_pulse(amplitude, duration, sample_rate=12e9):
            arb_voltage = arb_voltage_lookup()
            pulse_points = int(duration * sample_rate)
            if pulse_points < 320:
                wf = np.zeros(320)
            else:
                wf = np.zeros(64 * np.ceil(pulse_points / 64.0))
            wf[:pulse_points] = np.sign(amplitude) * arb_voltage(
                abs(amplitude))
            return wf

        reset_wf = arb_pulse(
            -self.polarity * self.reset_amplitude *
            np.power(10.0, self.circuit_attenuation / 20.0),
            self.reset_duration)
        wf_data = KeysightM8190A.create_binary_wf_data(reset_wf)
        rst_segment_id = self.arb.define_waveform(len(wf_data))
        self.arb.upload_waveform(wf_data, rst_segment_id)

        # no_reset_wf = arb_pulse(0.0, 3.0/12e9)
        # wf_data     = KeysightM8190A.create_binary_wf_data(no_reset_wf)
        # no_rst_segment_id  = self.arb.define_waveform(len(wf_data))
        # self.arb.upload_waveform(wf_data, no_rst_segment_id)

        # Picosecond trigger waveform
        pspl_trig_wf = KeysightM8190A.create_binary_wf_data(np.zeros(3200),
                                                            samp_mkr=1)
        pspl_trig_segment_id = self.arb.define_waveform(len(pspl_trig_wf))
        self.arb.upload_waveform(pspl_trig_wf, pspl_trig_segment_id)

        # NIDAQ trigger waveform
        nidaq_trig_wf = KeysightM8190A.create_binary_wf_data(np.zeros(3200),
                                                             sync_mkr=1)
        nidaq_trig_segment_id = self.arb.define_waveform(len(nidaq_trig_wf))
        self.arb.upload_waveform(nidaq_trig_wf, nidaq_trig_segment_id)

        settle_pts = int(640 * np.ceil(self.settle_delay * 12e9 / 640))

        scenario = Scenario()
        seq = Sequence(sequence_loop_ct=int(self.attempts))
        #First try with reset flipping pulse
        seq.add_waveform(rst_segment_id)
        seq.add_idle(settle_pts, 0.0)
        seq.add_waveform(nidaq_trig_segment_id)
        seq.add_idle(1 << 16, 0.0)  # bonus non-contiguous memory delay
        seq.add_waveform(pspl_trig_segment_id)
        seq.add_idle(settle_pts, 0.0)
        seq.add_waveform(nidaq_trig_segment_id)
        seq.add_idle(1 << 16, 0.0)  # bonus non-contiguous memory delay
        scenario.sequences.append(seq)
        self.arb.upload_scenario(scenario, start_idx=0)
        self.arb.sequence_mode = "SCENARIO"
        self.arb.scenario_advance_mode = "REPEAT"
        self.arb.scenario_start_index = 0
        self.arb.run()

        # Setup the NIDAQ
        self.analog_input = Task()
        self.read = int32()
        self.buf_points = 2 * self.samps_per_trig * self.attempts
        self.analog_input.CreateAIVoltageChan("Dev1/ai0", "", DAQmx_Val_Diff,
                                              self.min_daq_voltage,
                                              self.max_daq_voltage,
                                              DAQmx_Val_Volts, None)
        self.analog_input.CfgSampClkTiming("", 1e6, DAQmx_Val_Rising,
                                           DAQmx_Val_FiniteSamps,
                                           self.samps_per_trig)
        self.analog_input.CfgInputBuffer(self.buf_points)
        self.analog_input.CfgDigEdgeStartTrig("/Dev1/PFI0", DAQmx_Val_Rising)
        self.analog_input.SetStartTrigRetriggerable(1)
        self.analog_input.StartTask()

        # Setup the PSPL
        self.pspl.amplitude = self.polarity * 7.5 * np.power(
            10, (-self.pspl_atten) / 20.0)
        self.pspl.trigger_source = "EXT"
        self.pspl.trigger_level = 0.1
        self.pspl.output = True

        def set_voltage(voltage):
            # Calculate the voltage controller attenuator setting
            vc_atten = abs(20.0 * np.log10(abs(voltage) / 7.5)
                           ) - self.pspl_atten - self.circuit_attenuation
            if vc_atten <= 6.0:
                raise ValueError(
                    "Voltage controlled attenuation under range (6dB).")
            self.atten.set_attenuation(vc_atten)
            time.sleep(0.02)

        # Assign methods
        self.field.assign_method(self.mag.set_field)
        self.pulse_duration.assign_method(self.pspl.set_duration)
        self.pulse_voltage.assign_method(set_voltage)

        # Create hooks for relevant delays
        self.pulse_duration.add_post_push_hook(lambda: time.sleep(0.1))
예제 #5
0
    def setup_AWG(self, *args):
        self.arb.abort()
        self.arb.delete_all_waveforms()
        self.arb.reset_sequence_table()

        self.arb.set_output_route("DC", channel=1)
        self.arb.voltage_amplitude = 1.0

        self.arb.set_marker_level_low(0.0, channel=1, marker_type="sync")
        self.arb.set_marker_level_high(1.5, channel=1, marker_type="sync")

        self.arb.continuous_mode = False
        self.arb.gate_mode = False

        def arb_pulse(amplitude, sample_rate=12e9):
            pulse_points = int(self.duration.value * sample_rate)

            if pulse_points < 320:
                wf = np.zeros(320)
            else:
                wf = np.zeros(64 * int(np.ceil(pulse_points / 64.0)))
            wf[:pulse_points] = amplitude
            return wf

        segment_ids = []
        arb_voltage = arb_voltage_lookup()
        for amp in self.amplitudes:
            waveform = arb_pulse(np.sign(amp) * arb_voltage(abs(amp)))
            wf_data = KeysightM8190A.create_binary_wf_data(waveform)
            segment_id = self.arb.define_waveform(len(wf_data))
            segment_ids.append(segment_id)
            self.arb.upload_waveform(wf_data, segment_id)

        # NIDAQ trigger waveform
        nidaq_trig_wf = KeysightM8190A.create_binary_wf_data(np.zeros(3200),
                                                             sync_mkr=1)
        nidaq_trig_segment_id = self.arb.define_waveform(len(nidaq_trig_wf))
        self.arb.upload_waveform(nidaq_trig_wf, nidaq_trig_segment_id)

        settle_pts = int(640 * np.ceil(self.settle_delay * 12e9 / 640))
        start_idxs = [0]

        scenario = Scenario()
        seq = Sequence(sequence_loop_ct=int(self.repeats))
        for si in segment_ids:
            # seq = Sequence(sequence_loop_ct=int(1))
            seq.add_waveform(si)  # Apply switching pulse to the sample
            seq.add_idle(settle_pts, 0.0)  # Wait for the measurement to settle
            seq.add_waveform(
                nidaq_trig_segment_id)  # Trigger the NIDAQ measurement
            seq.add_idle(1 << 14, 0.0)  # bonus non-contiguous memory delay
        scenario.sequences.append(seq)

        self.arb.upload_scenario(scenario, start_idx=start_idxs[-1])
        start_idxs.append(start_idxs[-1] + len(scenario.scpi_strings()))
        # The last entry is eroneous
        start_idxs = start_idxs[:-1]

        self.arb.sequence_mode = "SCENARIO"
        self.arb.scenario_advance_mode = "REPEAT"
        self.arb.stop()
        self.arb.scenario_start_index = 0
        self.arb.run()
    def setup_daq(self, attempt):
        def arb_pulse(amplitude, duration, sample_rate=12e9):
            arb_voltage = arb_voltage_lookup()
            pulse_points = int(duration * sample_rate)
            if pulse_points < 320:
                wf = np.zeros(320)
            else:
                wf = np.zeros(64 * np.ceil(pulse_points / 64.0))
            wf[:pulse_points] = np.sign(amplitude) * arb_voltage(
                abs(amplitude))
            return wf

        self.arb.abort()
        self.arb.delete_all_waveforms()
        self.arb.reset_sequence_table()

        reset_wf = arb_pulse(-self.polarity * self.reset_amplitude,
                             self.reset_duration)
        wf_data = KeysightM8190A.create_binary_wf_data(reset_wf)
        rst_segment_id = self.arb.define_waveform(len(wf_data))
        self.arb.upload_waveform(wf_data, rst_segment_id)

        # no_reset_wf = arb_pulse(0.0, 3.0/12e9)
        # wf_data     = KeysightM8190A.create_binary_wf_data(no_reset_wf)
        # no_rst_segment_id  = self.arb.define_waveform(len(wf_data))
        # self.arb.upload_waveform(wf_data, no_rst_segment_id)

        # Picosecond trigger waveform
        pspl_trig_wf = KeysightM8190A.create_binary_wf_data(np.zeros(3200),
                                                            samp_mkr=1)
        pspl_trig_segment_id = self.arb.define_waveform(len(pspl_trig_wf))
        self.arb.upload_waveform(pspl_trig_wf, pspl_trig_segment_id)

        # NIDAQ trigger waveform
        nidaq_trig_wf = KeysightM8190A.create_binary_wf_data(np.zeros(3200),
                                                             sync_mkr=1)
        nidaq_trig_segment_id = self.arb.define_waveform(len(nidaq_trig_wf))
        self.arb.upload_waveform(nidaq_trig_wf, nidaq_trig_segment_id)

        settle_pts = int(640 * np.ceil(self.settle_delay * 12e9 / 640))

        scenario = Scenario()
        seq = Sequence(sequence_loop_ct=int(attempt))
        #First try with reset flipping pulse
        seq.add_waveform(rst_segment_id)
        seq.add_idle(settle_pts, 0.0)
        seq.add_waveform(nidaq_trig_segment_id)
        seq.add_idle(1 << 16, 0.0)  # bonus non-contiguous memory delay
        seq.add_waveform(pspl_trig_segment_id)
        seq.add_idle(settle_pts, 0.0)
        seq.add_waveform(nidaq_trig_segment_id)
        seq.add_idle(1 << 16, 0.0)  # bonus non-contiguous memory delay
        scenario.sequences.append(seq)
        self.arb.upload_scenario(scenario, start_idx=0)
        self.arb.sequence_mode = "SCENARIO"
        self.arb.scenario_advance_mode = "REPEAT"
        self.arb.scenario_start_index = 0
        self.arb.run()

        # ===================
        #   Setup the NIDAQ
        # ===================

        self.analog_input = Task()
        self.read = int32()
        self.buf_points = 2 * self.samps_per_trig * attempt
        self.analog_input.CreateAIVoltageChan("Dev1/ai1", "", DAQmx_Val_Diff,
                                              self.min_daq_voltage,
                                              self.max_daq_voltage,
                                              DAQmx_Val_Volts, None)
        self.analog_input.CfgSampClkTiming("", 1e6, DAQmx_Val_Rising,
                                           DAQmx_Val_FiniteSamps,
                                           self.samps_per_trig)
        self.analog_input.CfgInputBuffer(self.buf_points)
        self.analog_input.CfgDigEdgeStartTrig("/Dev1/PFI0", DAQmx_Val_Rising)
        self.analog_input.SetStartTrigRetriggerable(1)
        self.analog_input.StartTask()
    def setup_arb(self, vpeak):
        self.arb.abort()
        self.arb.delete_all_waveforms()
        self.arb.reset_sequence_table()

        reset_wf = arb_pulse(-self.polarity * self.reset_amplitude,
                             self.reset_duration)
        wf_data = KeysightM8190A.create_binary_wf_data(reset_wf)
        rst_segment_id = self.arb.define_waveform(len(wf_data))
        self.arb.upload_waveform(wf_data, rst_segment_id)

        no_reset_wf = arb_pulse(0.0, 3.0 / 12e9)
        wf_data = KeysightM8190A.create_binary_wf_data(no_reset_wf)
        no_rst_segment_id = self.arb.define_waveform(len(wf_data))
        self.arb.upload_waveform(wf_data, no_rst_segment_id)

        # nTron waveforms
        volt = self.polarity * self.nTron_control_voltage(vpeak)
        logger.debug("Set nTron pulse: {}V -> AWG {}V, {}s".format(
            vpeak, volt, self.nTron_duration.value))
        ntron_wf = ntron_pulse(amplitude=volt,
                               fall_time=self.nTron_duration.value)
        wf_data = KeysightM8190A.create_binary_wf_data(ntron_wf)
        ntron_segment_id = self.arb.define_waveform(len(wf_data))
        self.arb.upload_waveform(wf_data, ntron_segment_id)

        # NIDAQ trigger waveform
        nidaq_trig_wf = KeysightM8190A.create_binary_wf_data(np.zeros(3200),
                                                             sync_mkr=1)
        nidaq_trig_segment_id = self.arb.define_waveform(len(nidaq_trig_wf))
        self.arb.upload_waveform(nidaq_trig_wf, nidaq_trig_segment_id)

        settle_pts = int(640 * np.ceil(self.settle_delay * 12e9 / 640))

        scenario = Scenario()
        seq = Sequence(sequence_loop_ct=int(self.attempts.value))
        seq.add_waveform(rst_segment_id)
        seq.add_idle(settle_pts, 0.0)
        seq.add_waveform(nidaq_trig_segment_id)
        seq.add_idle(1 << 16, 0.0)  # bonus non-contiguous memory delay
        # seq.add_waveform(pspl_trig_segment_id)
        seq.add_waveform(ntron_segment_id)
        seq.add_idle(settle_pts, 0.0)
        seq.add_waveform(nidaq_trig_segment_id)
        seq.add_idle(1 << 16, 0.0)  # bonus non-contiguous memory delay
        scenario.sequences.append(seq)
        self.arb.upload_scenario(scenario, start_idx=0)

        self.arb.sequence_mode = "SCENARIO"
        self.arb.scenario_advance_mode = "REPEAT"
        self.arb.scenario_start_index = 0
        self.arb.run()

        # ===================
        #   Setup the NIDAQ
        # ===================

        self.analog_input = Task()
        self.read = int32()
        self.buf_points = 2 * self.samps_per_trig * self.attempts.value
        self.analog_input.CreateAIVoltageChan("Dev1/ai1", "", DAQmx_Val_Diff,
                                              self.min_daq_voltage,
                                              self.max_daq_voltage,
                                              DAQmx_Val_Volts, None)
        self.analog_input.CfgSampClkTiming("", 1e6, DAQmx_Val_Rising,
                                           DAQmx_Val_FiniteSamps,
                                           self.samps_per_trig)
        self.analog_input.CfgInputBuffer(self.buf_points)
        self.analog_input.CfgDigEdgeStartTrig("/Dev1/PFI0", DAQmx_Val_Rising)
        self.analog_input.SetStartTrigRetriggerable(1)
        self.analog_input.StartTask()
예제 #8
0
    seg_id = arb.define_waveform(len(wf_data), channel=2)
    arb.upload_waveform(wf_data, seg_id, channel=2)
    seg_ids_ch2.append(seg_id)

settle_pts = int(640 * np.ceil(2e-6 * 12e9 / 640))

trig_wf = KeysightM8190A.create_binary_wf_data(np.zeros(3200), sync_mkr=1)
trig_segment_id = arb.define_waveform(len(trig_wf), channel=2)
arb.upload_waveform(trig_wf, trig_segment_id, channel=2)

dummy_trig_wf = KeysightM8190A.create_binary_wf_data(np.zeros(3200),
                                                     sync_mkr=0)
dummy_trig_segment_id = arb.define_waveform(len(dummy_trig_wf), channel=1)
arb.upload_waveform(dummy_trig_wf, dummy_trig_segment_id, channel=1)

scenario = Scenario()
seq = Sequence(sequence_loop_ct=64)
for si in seg_ids_ch1:  #np.random.choice(seg_ids_ch1, 1024):
    # seq.add_waveform(dummy_trig_segment_id)
    # seq.add_idle(1<<16, 0.0)
    seq.add_waveform(si)
    seq.add_idle(settle_pts, 0.0)
scenario.sequences.append(seq)
arb.upload_scenario(scenario, start_idx=0, channel=1)

scenario = Scenario()
seq = Sequence(sequence_loop_ct=64)
for si in seg_ids_ch2:  #np.random.choice(seg_ids_ch2, 1024):
    # seq.add_waveform(trig_segment_id)
    # seq.add_idle(1<<16, 0.0)
    seq.add_waveform(si)
예제 #9
0
    def init_instruments(self):
        # ===================
        #    Setup the Lockin
        # ===================
        self.lock.tc = self.tc
        self.lock.filter_slope = self.fdB
        self.lock.amp = self.res_reference * self.measure_current
        sense_vals = np.array(self.lock.SENSITIVITY_VALUES)
        self.lock.sensitivity = sense_vals[np.argmin(
            np.absolute(sense_vals - 2 * self.sample_resistance *
                        self.measure_current * np.ones(sense_vals.size)))]
        time.sleep(20 * self.lock.measure_delay())

        # Rescale lockin analogue output for NIDAQ
        self.lock.r_offset_enable = True
        #self.lock.r_expand = 10
        #self.lock.r_offset = 100 * ((self.sample_resistance*self.measure_current/self.lock.sensitivity) - (0.5/self.lock.r_expand))
        self.lock.r_expand = 100
        self.lock.auto_offset("R")
        self.lock.r_offset = 0.995 * self.lock.r_offset
        time.sleep(20 * self.lock.measure_delay())

        self.mag.ramp()
        self.atten.set_supply_method(self.lock.set_ao2)
        self.atten.set_control_method(self.lock.set_ao3)

        # Setup the AWG
        self.arb.set_output(True, channel=1)
        self.arb.set_output(False, channel=2)
        self.arb.sample_freq = 12.0e9
        self.arb.waveform_output_mode = "WSPEED"
        self.arb.abort()
        self.arb.delete_all_waveforms()
        self.arb.reset_sequence_table()
        self.arb.set_output_route("DC", channel=1)
        self.arb.voltage_amplitude = 1.0
        self.arb.set_marker_level_low(0.0, channel=1, marker_type="sync")
        self.arb.set_marker_level_high(1.5, channel=1, marker_type="sync")
        self.arb.continuous_mode = False
        self.arb.gate_mode = False

        def arb_pulse(amplitude, duration, sample_rate=12e9):
            arb_voltage = arb_voltage_lookup()
            pulse_points = int(duration * sample_rate)
            if pulse_points < 320:
                wf = np.zeros(320)
            else:
                wf = np.zeros(64 * np.ceil(pulse_points / 64.0))
            wf[:pulse_points] = np.sign(amplitude) * arb_voltage(
                abs(amplitude))
            return wf

        reset_wf = arb_pulse(
            -self.polarity * abs(self.reset_amplitude) *
            np.power(10.0, self.circuit_attenuation / 20.0),
            self.reset_duration)
        wf_data = KeysightM8190A.create_binary_wf_data(reset_wf)
        rst_segment_id = self.arb.define_waveform(len(wf_data))
        self.arb.upload_waveform(wf_data, rst_segment_id)

        # Picosecond trigger waveform
        pspl_trig_wf = KeysightM8190A.create_binary_wf_data(np.zeros(3200),
                                                            samp_mkr=1)
        pspl_trig_segment_id = self.arb.define_waveform(len(pspl_trig_wf))
        self.arb.upload_waveform(pspl_trig_wf, pspl_trig_segment_id)

        # NIDAQ trigger waveform
        nidaq_trig_wf = KeysightM8190A.create_binary_wf_data(np.zeros(3200),
                                                             sync_mkr=1)
        nidaq_trig_segment_id = self.arb.define_waveform(len(nidaq_trig_wf))
        self.arb.upload_waveform(nidaq_trig_wf, nidaq_trig_segment_id)

        settle_pts = int(640 * np.ceil(self.lock.measure_delay() * 12e9 / 640))

        scenario = Scenario()
        seq = Sequence(sequence_loop_ct=int(self.attempts))
        #First try with reset flipping pulse
        seq.add_waveform(rst_segment_id)
        seq.add_idle(settle_pts, 0.0)
        seq.add_waveform(nidaq_trig_segment_id)
        seq.add_idle(1 << 16, 0.0)  # bonus non-contiguous memory delay
        seq.add_waveform(pspl_trig_segment_id)
        seq.add_idle(settle_pts, 0.0)
        seq.add_waveform(nidaq_trig_segment_id)
        seq.add_idle(1 << 16, 0.0)  # bonus non-contiguous memory delay
        scenario.sequences.append(seq)
        self.arb.upload_scenario(scenario, start_idx=0)
        self.arb.sequence_mode = "SCENARIO"
        self.arb.scenario_advance_mode = "REPEAT"
        self.arb.scenario_start_index = 0
        self.arb.run()

        # Setup the NIDAQ
        self.analog_input = Task()
        self.read = int32()
        self.buf_points = 2 * self.samps_per_trig * self.attempts
        self.analog_input.CreateAIVoltageChan("Dev1/ai0", "", DAQmx_Val_Diff,
                                              self.min_daq_voltage,
                                              self.max_daq_voltage,
                                              DAQmx_Val_Volts, None)
        self.analog_input.CfgSampClkTiming("", 1e6, DAQmx_Val_Rising,
                                           DAQmx_Val_FiniteSamps,
                                           self.samps_per_trig)
        self.analog_input.CfgInputBuffer(self.buf_points)
        self.analog_input.CfgDigEdgeStartTrig("/Dev1/PFI0", DAQmx_Val_Rising)
        self.analog_input.SetStartTrigRetriggerable(1)
        self.analog_input.StartTask()

        # Setup the PSPL
        self.pspl.amplitude = self.polarity * 7.5 * np.power(
            10, (-self.pspl_base_attenuation) / 20.0)
        self.pspl.trigger_source = "EXT"
        self.pspl.trigger_level = 0.1
        self.pspl.output = True

        def set_voltage(voltage):
            # Calculate the voltage controller attenuator setting
            self.pspl.amplitude = self.polarity * 7.5 * np.power(
                10, -self.pspl_base_attenuation / 20.0)
            vc_atten = abs(
                20.0 * np.log10(abs(voltage) / 7.5)
            ) - self.pspl_base_attenuation - self.circuit_attenuation

            if vc_atten <= self.atten.minimum_atten():
                logger.error(
                    "Voltage controlled attenuation {} under range.".format(
                        vc_atten))
                raise ValueError(
                    "Voltage controlled attenuation {} under range.".format(
                        vc_atten))

            if self.atten.maximum_atten() < vc_atten:
                logger.error(
                    "Voltage controlled attenuation {} over range.".format(
                        vc_atten))
                raise ValueError(
                    "Voltage controlled attenuation {} over range.".format(
                        vc_atten))

            self.atten.set_attenuation(vc_atten)
            time.sleep(0.02)

        # Assign methods
        self.field.assign_method(self.mag.set_field)
        self.pulse_duration.assign_method(self.pspl.set_duration)
        self.pulse_voltage.assign_method(set_voltage)

        # Create hooks for relevant delays
        self.pulse_duration.add_post_push_hook(lambda: time.sleep(0.1))
    def setup_arb(self):
        self.arb.abort()
        self.arb.delete_all_waveforms()
        self.arb.reset_sequence_table()

        reset_wf = arb_pulse(-self.polarity * self.reset_amplitude,
                             self.reset_duration)
        wf_data = KeysightM8190A.create_binary_wf_data(reset_wf)
        rst_segment_id = self.arb.define_waveform(len(wf_data))
        self.arb.upload_waveform(wf_data, rst_segment_id)

        no_reset_wf = arb_pulse(0.0, 3.0 / 12e9)
        wf_data = KeysightM8190A.create_binary_wf_data(no_reset_wf)
        no_rst_segment_id = self.arb.define_waveform(len(wf_data))
        self.arb.upload_waveform(wf_data, no_rst_segment_id)

        # nTron waveforms
        nTron_control_voltage = pulse_voltage_lookup()
        nTron_segment_ids = []
        for dur, vpeak in zip(self.pulse_durations, self.pulse_voltages):
            volt = self.polarity * nTron_control_voltage(vpeak)
            logger.debug("Set nTron pulse: {}V -> AWG {}V, {}s".format(
                vpeak, volt, dur))
            ntron_wf = ntron_pulse(amplitude=volt, fall_time=dur)
            wf_data = KeysightM8190A.create_binary_wf_data(ntron_wf)
            ntron_segment_id = self.arb.define_waveform(len(wf_data))
            self.arb.upload_waveform(wf_data, ntron_segment_id)
            nTron_segment_ids.append(ntron_segment_id)

        # NIDAQ trigger waveform
        nidaq_trig_wf = KeysightM8190A.create_binary_wf_data(np.zeros(3200),
                                                             sync_mkr=1)
        nidaq_trig_segment_id = self.arb.define_waveform(len(nidaq_trig_wf))
        self.arb.upload_waveform(nidaq_trig_wf, nidaq_trig_segment_id)

        settle_pts = int(640 * np.ceil(self.settle_delay * 12e9 / 640))

        self.start_idxs = [0]
        self.start_id = 0
        for si in nTron_segment_ids:
            scenario = Scenario()
            seq = Sequence(sequence_loop_ct=int(self.attempts))
            seq.add_waveform(rst_segment_id)
            seq.add_idle(settle_pts, 0.0)
            seq.add_waveform(nidaq_trig_segment_id)
            seq.add_idle(1 << 16, 0.0)  # bonus non-contiguous memory delay
            # seq.add_waveform(pspl_trig_segment_id)
            seq.add_waveform(si)
            seq.add_idle(settle_pts, 0.0)
            seq.add_waveform(nidaq_trig_segment_id)
            seq.add_idle(1 << 16, 0.0)  # bonus non-contiguous memory delay
            scenario.sequences.append(seq)
            self.arb.upload_scenario(scenario, start_idx=self.start_idxs[-1])
            self.start_idxs.append(self.start_idxs[-1] +
                                   len(scenario.scpi_strings()))

        # The last entry is eroneous
        self.start_idxs = self.start_idxs[:-1]
        self.arb.sequence_mode = "SCENARIO"
        self.arb.scenario_advance_mode = "SINGLE"
        self.arb.scenario_start_index = 0