Skip to content

Instantly share code, notes, and snippets.

@sriharijayaram5
Created July 1, 2021 07:58
Show Gist options
  • Save sriharijayaram5/dac313adede587011ef5d7583a526781 to your computer and use it in GitHub Desktop.
Save sriharijayaram5/dac313adede587011ef5d7583a526781 to your computer and use it in GitHub Desktop.
Qudi pulsed measurement control notebook 20210701
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import matplotlib\n",
"from tqdm.autonotebook import tqdm\n",
"import datetime\n",
"import glob\n",
"import logic.pulsed.pulse_objects as po\n",
"import scipy.signal"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def determine_ideal_mw_power(v0, p0, v1):\n",
" p1 = p0 - 20*np.log10(v0/v1) \n",
" return np.round(p1,2)\n",
"\n",
"v1s = np.linspace(1/4000e-9, 1/10e-9, 1/1e-4)\n",
"\n",
"y = determine_ideal_mw_power(1/(460e-9), -2, v1s)\n",
"plt.ylabel('dBm')\n",
"plt.xlabel('us')\n",
"plt.plot(1/v1s*1e6, y, label='V1')\n",
"\n",
"v2s = np.linspace(1/4000e-9, 1/10e-9, 1/1e-4)\n",
"\n",
"y = determine_ideal_mw_power(1/(2*460e-9), -2, v1s)\n",
"plt.ylabel('dBm')\n",
"plt.xlabel('us')\n",
"plt.plot(1/v1s*1e6, y, label='V2')\n",
"\n",
"plt.legend()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Creating pulse ensemble, uploading, running, collecting images - loop and save"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Main classes"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class PulseClass:\n",
" def __init__(self, rep, pulse_func, rabi_ns):\n",
" self.repetitions = rep\n",
" self.pulse_func_name = pulse_func\n",
" self.two_pi = rabi_ns\n",
" self.pulses = {\n",
" 'Rabi': self.rabi,\n",
" 'Pulsed_ODMR': self.pulsed_odmr,\n",
" 'T1': self.t1,\n",
" 'Hahn_Echo': self.hahn_echo,\n",
" 'Ramsey': self.ramsey,\n",
" 'Trigger': self.trigger,\n",
" 'Wait': self.wait\n",
" }\n",
" \n",
" def __call__(self, tau_ns):\n",
" self.tau_ns = tau_ns\n",
" self._make_pulse_blocks()\n",
" return self._make_pulse_ensemble()\n",
" \n",
" def _make_pulse_blocks(self):\n",
" if self.pulse_func_name not in self.pulses.keys():\n",
" pulsedmeasurement.log.error('Pulse function not found.')\n",
" self.pulse_signal = self.pulses[self.pulse_func_name](True)\n",
" self.pulse_reference = self.pulses[self.pulse_func_name](False)\n",
" self.trigger_signal = self.pulses['Trigger'](26, False)\n",
" self.trigger_reference = self.pulses['Trigger'](26, self.pulse_func_name=='Pulsed_ODMR')\n",
" self.wait_block = self.pulses['Wait'](100)\n",
" self.created_blocks = [self.pulse_signal, self.pulse_reference, self.trigger_signal,\n",
" self.trigger_reference, self.wait_block]\n",
" for block in self.created_blocks:\n",
" sequencegeneratorlogic.save_block(block)\n",
" \n",
" def _make_pulse_ensemble(self):\n",
" block_list = [(self.trigger_signal.name, 1), (self.pulse_signal.name, self.repetitions), (self.wait_block.name, 1),\n",
" (self.trigger_reference.name, 1), (self.pulse_reference.name, self.repetitions)]\n",
" \n",
" auto_pulse_CW = po.PulseBlockEnsemble(name=f'auto_pulse_CW_{self.tau_ns}', block_list=block_list, rotating_frame=False)\n",
"\n",
" ensemble = auto_pulse_CW\n",
" ensemblename = auto_pulse_CW.name\n",
" sequencegeneratorlogic.save_ensemble(ensemble)\n",
" ret,_,_ = sequencegeneratorlogic.sample_pulse_block_ensemble(ensemblename)\n",
" sequencegeneratorlogic.load_ensemble(ensemblename)\n",
" return ret\n",
" \n",
" def rabi(self, not_ref):\n",
" ele = []\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': not_ref, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=self.tau_ns*1e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': True, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=3e-6, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=500e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=1e-6, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" pulse_block = po.PulseBlock(name=f'auto_rabi_P95B_{self.tau_ns}_{not_ref}', element_list=ele)\n",
"\n",
" return pulse_block\n",
" \n",
" def pulsed_odmr(self, not_ref):\n",
" ele = []\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': not_ref, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=self.two_pi/2*1e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': True, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=3e-6, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=500e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=1e-6, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" pulse_block = po.PulseBlock(name=f'auto_odmr_P95B_{not_ref}', element_list=ele)\n",
"\n",
" return pulse_block\n",
" \n",
" def t1(self, not_ref):\n",
" ele = []\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': not_ref, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=self.two_pi/2*1e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=self.tau_ns*1e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': True, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=3e-6, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=500e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=1e-6, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" pulse_block = po.PulseBlock(name=f'auto_T1_P95B_{self.tau_ns}_{not_ref}', element_list=ele)\n",
"\n",
" return pulse_block\n",
" \n",
" def hahn_echo(self, not_ref):\n",
" if not_ref:\n",
" last_ns = self.two_pi/4\n",
" else:\n",
" last_ns = self.two_pi*3/4\n",
" ele = []\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': True, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=self.two_pi/4*1e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=self.tau_ns/2*1e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': True, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=self.two_pi/2*1e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=self.tau_ns/2*1e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': True, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=last_ns*1e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': True, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=3e-6, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=500e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=1e-6, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" pulse_block = po.PulseBlock(name=f'auto_HEcho_P95B_{self.tau_ns}_{not_ref}', element_list=ele)\n",
"\n",
" return pulse_block\n",
" \n",
" def ramsey(self, not_ref):\n",
" ele = []\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': not_ref, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=self.two_pi/4*1e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=self.tau_ns*1e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': not_ref, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=self.two_pi/4*1e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': True, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=3e-6, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=500e-9, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=1e-6, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" pulse_block = po.PulseBlock(name=f'auto_Ramsey_P95B_{ns}_{not_ref}', element_list=ele)\n",
"\n",
" return pulse_block\n",
" \n",
" def trigger(self, ms, podmr):\n",
" ele = []\n",
" d_ch = {'d_ch1': False, 'd_ch2': True, 'd_ch4': False, 'd_ch3': podmr}\n",
" ele.append(po.PulseBlockElement(init_length_s=ms*1e-3, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" pulse_block = po.PulseBlock(name=f'trigger_cam_{podmr}_{ms}', element_list=ele)\n",
"\n",
" return pulse_block\n",
"\n",
" def wait(self, ms):\n",
" ele = []\n",
" d_ch = {'d_ch1': False, 'd_ch2': False, 'd_ch4': False, 'd_ch3': False}\n",
" ele.append(po.PulseBlockElement(init_length_s=ms*1e-3, increment_s=0, pulse_function=None, digital_high=d_ch, laser_on=False))\n",
"\n",
" pulse_block = po.PulseBlock(name=f'wait_block_{ms}', element_list=ele)\n",
"\n",
" return pulse_block\n",
" \n",
"\n",
" \n",
"class MeasurementClass:\n",
" def __init__(self, start, stop, step, n_runs, rep, power, freq, two_pi, pulse_func, tag, explicit_tau_list=None):\n",
" sequencegeneratorlogic.pulse_generator_settings = {'activation_config':'pulsed_1'}\n",
" self.size = mycamlogic.get_size()\n",
" self.start = start\n",
" self.stop = stop\n",
" self.step = step\n",
" self.power = power\n",
" self.freq = freq\n",
" self.tag = tag\n",
" self.pulse_func_name = pulse_func\n",
" self.podmr = self.pulse_func_name=='Pulsed_ODMR'\n",
" self. two_pi = two_pi\n",
" self.set_MW()\n",
" self.tau_list = explicit_tau_list if explicit_tau_list else np.arange(self.start,self.stop,self.step)\n",
" self.n_runs = n_runs\n",
" self.repetitions = rep\n",
" self.pulse_inst = PulseClass(self.repetitions, self.pulse_func_name, self.two_pi)\n",
" \n",
" self.odmr_imgs = np.zeros((len(self.tau_list), self.n_runs, 2, self.size[1], self.size[0]), dtype = np.float64)\n",
" self.save_array = np.zeros((len(self.tau_list), 2, self.size[1], self.size[0]), dtype = np.float64)\n",
" self.err_array = np.zeros((len(self.tau_list), 2), dtype = np.float32)\n",
" self.plot_array = np.full((len(self.tau_list)), np.nan)\n",
"\n",
" def __call__(self):\n",
" pulsedmeasurement._mw.action_toggle_jupyter.toggle()\n",
" qdplotlogic.add_plot()\n",
" \n",
" for n in range(self.n_runs if self.podmr else 1): \n",
" for tau_idx, tau_ns in enumerate(tqdm(self.tau_list, leave=False, desc=f'Run {n}')):\n",
" if not pulsedmeasurement._mw.action_toggle_jupyter.isChecked():\n",
" pulsedmeasurement.log.error('Measurement interrupted')\n",
" self.err=-1\n",
" break\n",
"\n",
" self.err = self.pulse_inst(tau_ns)\n",
" if self.err==-1:\n",
" pulsedmeasurement.log.error('Memory error')\n",
" break\n",
"\n",
" img = np.zeros((self.n_runs if not self.podmr else 1, 2, self.size[1], self.size[0]), dtype = np.float64)\n",
" for i in range(img.shape[0]):\n",
" img[i] = self.do_measurement()\n",
"\n",
" self.process(img, tau_idx, n)\n",
" \n",
" self.save()\n",
" self.finish()\n",
" \n",
" def process(self, img, tau_idx, n):\n",
" cameragui._mw.counts_label.setText(f'{np.mean(img):.2f}')\n",
" \n",
" if 400<np.mean(img)>60000:\n",
" pulsedmeasurement.log.error('Saturation/Noise floor nearby.')\n",
" self.err=-1\n",
" \n",
" if self.podmr:\n",
" self.odmr_imgs[tau_idx, n] = img\n",
" img[0] = np.mean(self.odmr_imgs[tau_idx], axis=0)\n",
" \n",
" self.save_array[tau_idx] = np.mean(img, axis=0)\n",
" self.err_array[tau_idx] = np.std(np.mean(img, axis=(2,3)), ddof=1, axis=0)/np.sqrt(self.n_runs)\n",
" self.plot_array[tau_idx] = np.mean((self.save_array[tau_idx,1,:,:]-self.save_array[tau_idx,0,:,:])/(self.save_array[tau_idx,1,:,:]+self.save_array[tau_idx,0,:,:])) * 100\n",
" qdplotlogic.set_data(x=self.tau_list, y=self.plot_array, clear_old=True, plot_index=qdplotlogic.number_of_plots-1)\n",
" \n",
" def save(self):\n",
" timestamp = datetime.datetime.now()\n",
" t = timestamp.strftime(\"%Y%m%d-%H%M-%S\")\n",
" self.parameters = {\n",
" 'Tag': self.tag,\n",
" 'Start_ns': self.start,\n",
" 'Step_ns': self.step,\n",
" 'Stop_ns': self.stop,\n",
" 'ROI Size(px)': self.size,\n",
" 'No. of averaging runs': self.n_runs,\n",
" 'Repetitions': self.repetitions,\n",
" 'Pulse function': self.pulse_func_name,\n",
" 'Rabi period(ns)': self.two_pi,\n",
" 'MW Freq': self.freq,\n",
" 'MW power': self.power,\n",
" 'ODMR': self.podmr\n",
" }\n",
" data = {\n",
" 'Tau list (ns or Hz)': self.tau_list\n",
" }\n",
" if self.err!=-1:\n",
" save.save_data(data, filepath=save.get_path_for_module('Pulsed'), parameters=self.parameters, filename=None, filelabel=self.tag, timestamp=timestamp, filetype='text', fmt='%.15e', delimiter='\\t', plotfig=None)\n",
" np.savez_compressed(f'{save.get_path_for_module(\"Pulsed\")}/{t}_{self.tag}_{self.start}_{self.stop}_{self.step}_{self.n_runs}_{self.power}dBm', data=self.save_array, err=self.err_array, x=np.asarray(self.tau_list))\n",
" pulsedmeasurement._mw.action_toggle_jupyter.toggle()\n",
" \n",
" def finish(self):\n",
" pulsedmasterlogic.delete_all_pulse_blocks()\n",
" pulsedmasterlogic.delete_all_block_ensembles()\n",
" pulsedmasterlogic.clear_pulse_generator()\n",
" if self.podmr:\n",
" odmrlogic.reset_sweep()\n",
" pulsedmeasurementlogic.microwave_off()\n",
" mycamera.pulsed_done()\n",
" \n",
" def do_measurement(self):\n",
" mycamera.ready_pulsed(trigger_mode='Trigger Level', mode=2)\n",
"\n",
" pulsedmeasurementlogic.pulse_generator_on()\n",
" mycamlogic.start_trigger_seq(2)\n",
"\n",
" pulsedmeasurementlogic.pulse_generator_off()\n",
" return mycamlogic.get_last_image()\n",
"\n",
" def set_MW(self):\n",
" if self.podmr:\n",
" self.start, self.stop, self.step, self.power = odmrlogic.set_sweep_parameters(self.start, self.stop, self.step, self.power)\n",
" odmrlogic.set_trigger(0, 1)\n",
" odmrlogic.mw_sweep_on()\n",
" odmrlogic.reset_sweep()\n",
" else:\n",
" settings = {\n",
" 'power': self.power,\n",
" 'frequency': self.freq,\n",
" 'use_ext_microwave': True\n",
" }\n",
" pulsedmeasurementlogic.set_microwave_settings(settings_dict=settings)\n",
" pulsedmeasurementlogic.microwave_on()\n",
" \n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Pulsed ODMR"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for rabi in np.arange(100,2500,100):\n",
" podmr = MeasurementClass(start=2.88e9, stop=2.92e9, step=1e6, n_runs=5, rep=50000, power=-10, freq=None, two_pi=rabi, \n",
" pulse_func='Pulsed_ODMR', tag=f'podmr_RuCl3_10.5K_4r_map2_{rabi}', explicit_tau_list=None)\n",
" podmr()\n",
" if podmr.err==-1:\n",
" break"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Rabi"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"rabi_measurement = MeasurementClass(start=10, stop=100, step=50, n_runs=2, rep=200, power=-2, freq=2.898, two_pi=None, \n",
" \n",
" pulse_func='Rabi', tag='rabi_RuCl3_10.5K_4r', explicit_tau_list=None)\n",
"rabi_measurement()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for x in range(qdplotlogic.number_of_plots):\n",
" qdplotlogic.remove_plot()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Qudi",
"language": "python",
"name": "qudi"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": "3.6.5"
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment