Import


In [1]:
from logic.sequence_generator_logic import Pulse_Block_Element, Pulse_Block, Pulse_Block_Ensemble
import time

Load modules


In [2]:
manager.startModule('logic', 'sequencegenerator')
manager.startModule('logic', 'pulsedmeasurement')


Loading module ".hardware.awg.tektronix_awg70k"
Configuring AWG70K as pulser
<module 'hardware.awg.tektronix_awg70k' from 'C:\\Software\\qudi\\hardware\\awg\\tektronix_awg70k.py'> AWG70K
Loading module ".logic.sequence_generator_logic"
Configuring SequenceGeneratorLogic as sequencegenerator
<module 'logic.sequence_generator_logic' from 'C:\\Software\\qudi\\logic\\sequence_generator_logic.py'> SequenceGeneratorLogic
Loading module ".hardware.ni_card"
Configuring NICard as nicard
<module 'hardware.ni_card' from 'C:\\Software\\qudi\\hardware\\ni_card.py'> NICard
Loading module ".hardware.fpga_fastcounter.fast_counter_fpga_pi3"
Configuring FastCounterFGAPiP3 as fastcounter
<module 'hardware.fpga_fastcounter.fast_counter_fpga_pi3' from 'C:\\Software\\qudi\\hardware\\fpga_fastcounter\\fast_counter_fpga_pi3.py'> FastCounterFGAPiP3
Loading module ".logic.pulse_extraction_logic"
Configuring PulseExtractionLogic as pulseextraction
<module 'logic.pulse_extraction_logic' from 'C:\\Software\\qudi\\logic\\pulse_extraction_logic.py'> PulseExtractionLogic
Loading module ".hardware.microwave.mw_source_dummy"
Configuring MicrowaveDummy as microwave
<module 'hardware.microwave.mw_source_dummy' from 'C:\\Software\\qudi\\hardware\\microwave\\mw_source_dummy.py'> MicrowaveDummy
Loading module ".logic.save_logic"
Configuring SaveLogic as save
<module 'logic.save_logic' from 'C:\\Software\\qudi\\logic\\save_logic.py'> SaveLogic
Loading module ".logic.confocal_logic"
Configuring ConfocalLogic as scanner
<module 'logic.confocal_logic' from 'C:\\Software\\qudi\\logic\\confocal_logic.py'> ConfocalLogic
Loading module ".logic.fit_logic"
Configuring FitLogic as fit
<module 'logic.fit_logic' from 'C:\\Software\\qudi\\logic\\fit_logic.py'> FitLogic
Loading module ".logic.optimizer_logic"
Configuring OptimizerLogic as optimizer
<module 'logic.optimizer_logic' from 'C:\\Software\\qudi\\logic\\optimizer_logic.py'> OptimizerLogic
Loading module ".logic.pulse_analysis_logic"
Configuring PulseAnalysisLogic as pulseanalysis
<module 'logic.pulse_analysis_logic' from 'C:\\Software\\qudi\\logic\\pulse_analysis_logic.py'> PulseAnalysisLogic
Loading module ".logic.pulsed_measurement_logic"
Configuring PulsedMeasurementLogic as pulsedmeasurement
<module 'logic.pulsed_measurement_logic' from 'C:\\Software\\qudi\\logic\\pulsed_measurement_logic.py'> PulsedMeasurementLogic
Out[2]:
0

Input parameters


In [3]:
# static hardware parameters:
mrkr_idle = [False, False, False, False]
mrkr_laser_detect = [False, False, True, True]
mrkr_laser = [False, False, False, True]
mrkr_detect = [False, False, True, False]
mrkr_seqtrig = [True, False, False, False]
activation_config = ['a_ch1', 'd_ch1', 'a_ch2', 'd_ch3', 'd_ch4']
sampling_freq = 25e9
fc_binwidth = 1e-9
aom_delay = 800e-9
seqtrig_time = 20e-9
seqtrig_safety = 100e-9
# convert time intervals to integer number of samples
aom_bins = int(np.rint(aom_delay*sampling_freq))
seqtrig_bins = int(np.rint(seqtrig_time*sampling_freq))
seqtrig_safety_bins = int(np.rint(seqtrig_safety*sampling_freq))


# measurement start input parameters
# for pulsed ODMR:
odmr_laser_length = 3000e-9
odmr_wait_time = 1000e-9
odmr_mw_amp = 0.075
odmr_pi = 300e-9
odmr_resonance_freq = 968.068e6
odmr_freq_res = 200e3
odmr_points = 100
odmr_measurement_time = 600
# for Rabi:
rabi_laser_length = 3000e-9
rabi_wait_time = 1000e-9
rabi_mw_amp = 0.05
rabi_mw_freq = 968.068e6
rabi_tau_start = 10e-9
rabi_tau_res = 20e-9
rabi_points = 100
rabi_measurement_time = 60

Method definitions

sequence generation methods:


In [4]:
def generate_pulsed_odmr(laser_time, wait_time, mw_pi_time, mw_amp, center_freq, freq_res, num_of_points):
    """
    This method generates the Pulse_Block_Ensemble object defining a pulsed ODMR measurement.
    """
    # Create ticks array
    start_freq = center_freq - (num_of_points//2)*freq_res
    freq_arr = start_freq + np.array(range(num_of_points))*freq_res
    # Convert times into number of samples
    laser_bins = int(np.rint(laser_time*sampling_freq))
    wait_bins = int(np.rint(wait_time*sampling_freq))
    mw_pi_bins = int(np.rint(mw_pi_time*sampling_freq))
    # Create parameter sets
    param_idle = [{},{}]
    param_mw = [{},{}]
    param_mw[0]['amplitude1'] = mw_amp
    param_mw[0]['phase1'] = 0

    # Create ODMR Pulse_Block object and Pulse_Block_Elements
    laser_detect_element = Pulse_Block_Element(laser_bins, 2, 4, 0, ['Idle', 'Idle'], mrkr_laser_detect, param_idle)
    detect_element = Pulse_Block_Element(aom_bins, 2, 4, 0, ['Idle', 'Idle'], mrkr_detect, param_idle)
    wait_element = Pulse_Block_Element(wait_bins, 2, 4, 0, ['Idle', 'Idle'], mrkr_idle, param_idle)

    odmr_elements = []
    for n in range(num_of_points):
        param_tmp = [param_mw[0].copy(), {}]
        param_tmp[0]['frequency1'] = freq_arr[n]
        mw_element = Pulse_Block_Element(mw_pi_bins, 2, 4, 0, ['Sin', 'Idle'], mrkr_idle, param_tmp)

        odmr_elements.append(mw_element)
        odmr_elements.append(laser_detect_element)
        odmr_elements.append(detect_element)
        odmr_elements.append(wait_element)

    odmr_block = Pulse_Block('pulsedodmr_block', odmr_elements, 2)

    # Create sequence trigger Pulse_Block object and Pulse_Block_Elements
    laser_element = Pulse_Block_Element(laser_bins, 2, 4, 0, ['Idle', 'Idle'], mrkr_laser, param_idle)
    seqtrig_element = Pulse_Block_Element(seqtrig_bins, 2, 4, 0, ['Idle', 'Idle'], mrkr_seqtrig, param_idle)
    safety_element = Pulse_Block_Element(seqtrig_safety_bins, 2, 4, 0, ['Idle', 'Idle'], mrkr_idle, param_idle)
    wait_element = Pulse_Block_Element(wait_bins, 2, 4, 0, ['Idle', 'Idle'], mrkr_idle, param_idle)

    seqtrig_elements = []
    seqtrig_elements.append(safety_element)
    seqtrig_elements.append(seqtrig_element)
    seqtrig_elements.append(safety_element)
    seqtrig_elements.append(laser_element)
    seqtrig_elements.append(wait_element)

    seqtrig_block = Pulse_Block('pulsedodmr_seqtrig_laser_block', seqtrig_elements, 2)

    # Create Pulse_Block_Ensemble for pulsed ODMR
    block_list = [(seqtrig_block, 0), (odmr_block, 0)]
    pulsed_odmr_ensemble = Pulse_Block_Ensemble('pulsed_odmr', block_list, 2, True)
    pulsed_odmr_ensemble.measurement_ticks_list = freq_arr

    # Save blocks and ensembles to file
    sequencegenerator.save_block('pulsedodmr_block', odmr_block)
    sequencegenerator.save_block('pulsedodmr_seqtrig_laser_block', seqtrig_block)
    sequencegenerator.save_ensemble('pulsed_odmr', pulsed_odmr_ensemble)
    return

def generate_rabi(laser_time, wait_time, mw_freq, mw_amp, start_tau, tau_res, num_of_points):
    """
    This method generates the Pulse_Block_Ensemble object defining a rabi measurement.
    """
    # Create ticks array
    tau_arr = start_tau + np.array(range(num_of_points))*tau_res
    # Convert times into number of samples
    laser_bins = int(np.rint(laser_time*sampling_freq))
    wait_bins = int(np.rint(wait_time*sampling_freq))
    tau_arr_bins = np.rint(tau_arr*sampling_freq).astype(int)
    # Create parameter sets
    param_idle = [{},{}]
    param_mw = [{},{}]
    param_mw[0]['frequency1'] = mw_freq
    param_mw[0]['amplitude1'] = mw_amp
    param_mw[0]['phase1'] = 0
    
    # Create rabi Pulse_Block object and Pulse_Block_Elements
    laser_detect_element = Pulse_Block_Element(laser_bins, 2, 4, 0, ['Idle', 'Idle'], mrkr_laser_detect, param_idle)
    detect_element = Pulse_Block_Element(aom_bins, 2, 4, 0, ['Idle', 'Idle'], mrkr_detect, param_idle)
    wait_element = Pulse_Block_Element(wait_bins, 2, 4, 0, ['Idle', 'Idle'], mrkr_idle, param_idle)

    rabi_elements = []
    for tau in tau_arr_bins:
        mw_element = Pulse_Block_Element(tau, 2, 4, 0, ['Sin', 'Idle'], mrkr_idle, param_mw)

        rabi_elements.append(mw_element)
        rabi_elements.append(laser_detect_element)
        rabi_elements.append(detect_element)
        rabi_elements.append(wait_element)

    rabi_block = Pulse_Block('rabi_block', rabi_elements, 2)

    # Create sequence trigger Pulse_Block object and Pulse_Block_Elements
    laser_element = Pulse_Block_Element(laser_bins, 2, 4, 0, ['Idle', 'Idle'], mrkr_laser, param_idle)
    seqtrig_element = Pulse_Block_Element(seqtrig_bins, 2, 4, 0, ['Idle', 'Idle'], mrkr_seqtrig, param_idle)
    safety_element = Pulse_Block_Element(seqtrig_safety_bins, 2, 4, 0, ['Idle', 'Idle'], mrkr_idle, param_idle)
    wait_element = Pulse_Block_Element(wait_bins, 2, 4, 0, ['Idle', 'Idle'], mrkr_idle, param_idle)

    seqtrig_elements = []
    seqtrig_elements.append(safety_element)
    seqtrig_elements.append(seqtrig_element)
    seqtrig_elements.append(safety_element)
    seqtrig_elements.append(laser_element)
    seqtrig_elements.append(wait_element)

    seqtrig_block = Pulse_Block('rabi_seqtrig_laser_block', seqtrig_elements, 2)
    
    # Create Pulse_Block_Ensemble for rabi
    block_list = [(seqtrig_block, 0), (rabi_block, 0)]
    rabi_ensemble = Pulse_Block_Ensemble('rabi', block_list, 2, True)
    rabi_ensemble.measurement_ticks_list = tau_arr

    # Save blocks and ensembles to file
    sequencegenerator.save_block('rabi_block', rabi_block)
    sequencegenerator.save_block('rabi_seqtrig_laser_block', seqtrig_block)
    sequencegenerator.save_ensemble('rabi', rabi_ensemble)
    return

Measurement methods:


In [5]:
def do_rabi():
    """
    This method performs a Rabi measurement and returns the pi and pi/2 times in s as well as the period in Hz
    """
    # Generate rabi
    generate_rabi(rabi_laser_length, rabi_wait_time, rabi_mw_freq, rabi_mw_amp, rabi_tau_start, rabi_tau_res, rabi_points)
    # Sample and upload to AWG
    sequencegenerator.sample_pulse_block_ensemble('rabi', True, False)
    sequencegenerator.upload_asset('rabi')
    # Load into AWG channels
    pulser.load_asset('rabi')
    
    # Get ensemble object to have all parameters
    rabi_ens = sequencegenerator.get_pulse_block_ensemble('rabi', True)
    # Set up measurement parameters in logic
    pulsedmeasurement.aom_delay_s = aom_delay
    pulsedmeasurement.laser_length_s = rabi_laser_length
    pulsedmeasurement.number_of_lasers = rabi_points
    pulsedmeasurement.fast_counter_binwidth = fc_binwidth
    pulsedmeasurement.signal_start_bin = 5
    pulsedmeasurement.signal_width_bin = 200
    pulsedmeasurement.norm_start_bin = 1500
    pulsedmeasurement.norm_width_bin = 1000
    pulsedmeasurement.measurement_ticks_list = rabi_ens.measurement_ticks_list
    pulsedmeasurement.timer_interval = 3
    
    # Configure fast counter
    pulsedmeasurement.configure_fast_counter()
    
    # Start measurement
    pulsedmeasurement.start_pulsed_measurement()
    time.sleep(rabi_measurement_time)
    # Stop measurement
    pulsedmeasurement.stop_pulsed_measurement()
    # Save data
    pulsedmeasurement._save_data(tag = 'rabi')
    
    # Fit data
    fit_x, fit_y, fit_result = pulsedmeasurement.do_fit('Sine')
    return fit_x, fit_y, fit_result

def do_odmr():
    """
    This method performs a pulsed ODMR measurement and returns the resonance frequency and line width in Hz 
    as well as the contrast in %.
    """
    # Generate pulsed ODMR
    generate_pulsed_odmr(odmr_laser_length, odmr_wait_time, odmr_pi, odmr_mw_amp, odmr_resonance_freq, odmr_freq_res, odmr_points)
    # Sample and upload to AWG
    sequencegenerator.sample_pulse_block_ensemble('pulsed_odmr', True, False)
    pulser.upload_asset('pulsed_odmr')
    # Load into AWG channels
    pulser.load_asset('pulsed_odmr')
    
    # Get ensemble object to have all parameters
    odmr_ens = sequencegenerator.get_pulse_block_ensemble('pulsed_odmr', True)
    # Set up measurement parameters in logic
    pulsedmeasurement.aom_delay_s = aom_delay
    pulsedmeasurement.laser_length_s = odmr_laser_length
    pulsedmeasurement.sequence_length_s = odmr_ens.length_bins/sampling_freq
    pulsedmeasurement.number_of_lasers = odmr_points
    pulsedmeasurement.fast_counter_binwidth = fc_binwidth
    pulsedmeasurement.signal_start_bin = 5
    pulsedmeasurement.signal_width_bin = 200
    pulsedmeasurement.norm_start_bin = 1500
    pulsedmeasurement.norm_width_bin = 1000
    pulsedmeasurement.measurement_ticks_list = odmr_ens.measurement_ticks_list
    pulsedmeasurement.timer_interval = 3
    
    # Configure fast counter
    pulsedmeasurement.configure_fast_counter()
    
    # Start measurement
    pulsedmeasurement.start_pulsed_measurement()
    time.sleep(odmr_measurement_time)
    # Stop measurement
    pulsedmeasurement.stop_pulsed_measurement()
    # Save data
    pulsedmeasurement._save_data(tag = 'pulsed_odmr')
    
    # Fit data
    fit_x, fit_y, fit_result = pulsedmeasurement.do_fit('Lorentian (neg)')
    return fit_x, fit_y, fit_result

Set up AWG


In [6]:
# active channels:
current_channel_state = pulser.get_active_channels()
future_channel_state = current_channel_state.copy()
for chnl in future_channel_state:
    if chnl in activation_config:
        future_channel_state[chnl] = True
    else:
        future_channel_state[chnl] = False
        
if current_channel_state != future_channel_state:
    pulser.set_active_channels(future_channel_state)
    print('Set/changed active channels in HW.')

# sample rate:
current_sample_rate = pulser.get_sample_rate()
if current_sample_rate != sampling_freq:
    pulser.set_sample_rate(sampling_freq)
    print('Set/changed sample rate in HW.')
    
# clear AWG:
pulser.clear_all()

# sample mode:
current_mode = pulser.current_sample_mode
if current_mode != pulser.sample_mode['wfmx-file']:
    pulser.current_sample_mode = pulser.sample_mode['wfmx-file']

Perform measurements


In [8]:
odmr_fit_x, odmr_fit_y, odmr_fit_result = do_odmr()

#rabi_fit_x, rabi_fit_y, rabi_fit_result = do_rabi()


# first perform an ODMR measurement
#new_freq, new_linewidth, contrast = do_odmr()
#if contrast < 5:
#    print('====================\nWARNING: ODMR FAILED!!!\n====================')
#    print('ODMR result:\nfrequency = {0} Hz, linewidth = {1} Hz, contrast = {2} %'.format(new_freq, new_linewidth, contrast))
#else:
#    while new_linewidth > 200e3:
#        new_freq, new_linewidth, contrast = do_odmr()
#        print('ODMR result:\nfrequency = {0} Hz, linewidth = {1} Hz, contrast = {2} %'.format(new_freq, new_linewidth, contrast))
#
#        rabi_mw_amp = 0.75*odmr_mw_amp
#        rabi_mw_freq = new_freq
#        odmr_resonance_freq = new_freq
#        odmr_freq_res = new_linewidth/10
#
#        pihalf, pi, rabi_period, contrast = do_rabi()
#        print('Rabi result:\npihalf = {0} s, pi = {1} s, period = {2} s'.format(pihalf, pi, rabi_period))
#        
#        odmr_pi = pi
#        odmr_mw_amp = rabi_mw_amp


Traceback (most recent call last):
  File "C:\Software\qudi\logic\jupyterkernel\qzmqkernel.py", line 789, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-8-8aed31f2c315>", line 2, in <module>
    odmr_fit_x, odmr_fit_y, odmr_fit_result = do_odmr()
  File "<ipython-input-5-2c3607c9eea6>", line 81, in do_odmr
    fit_x, fit_y, fit_result = pulsedmeasurement.do_fit('Lorentian (neg)')
  File "C:\Software\qudi\logic\pulsed_measurement_logic.py", line 798, in do_fit
    error_per = 1/(result.params['frequency'].value/1e9)**2 * result.params['frequency'].stderr/1e9
ZeroDivisionError: float division by zero

In [ ]: