This page was generated from
docs/examples/writing_drivers/A-ParameterWithSetpoints-Example-with-Dual-Setpoints.ipynb.
Interactive online version:
.
A ParameterWithSetpoints Example with Dual Setpoints¶
This notebook explains how you can account for dual setpoints using ParameterWithSetpoints. The basics of writing drivers using ParameterWithSetpoints is covered in the notebook named Simple Example of ParameterWithSetpoints.
In this example we consider a dummy instrument that can return a time trace or the discreet Fourier transform (magnitude square) of that trace. The setpoints are accounted for in an easy way.
[1]:
from pathlib import Path
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing_extensions import Unpack
import numpy as np
import qcodes.validators as vals
from qcodes.dataset import (
Measurement,
initialise_or_create_database_at,
load_or_create_experiment,
plot_dataset,
)
from qcodes.instrument import Instrument, InstrumentBaseKWArgs
from qcodes.parameters import Parameter, ParameterWithSetpoints
[2]:
def timetrace(npts: int, dt: float) -> np.ndarray:
"""
A very realistic-looking signal
"""
# freq = 10/(dt*npts)
# decay = 1/(dt*npts)
freq = 10
decay = 1
time = np.linspace(0, npts * dt, npts, endpoint=False)
signal = np.exp(-decay * time) * np.sin(2 * np.pi * freq * time)
noise = 0.1 * np.random.randn(npts)
return signal + noise
[3]:
class TimeTrace(ParameterWithSetpoints):
def get_raw(self):
npts = self.root_instrument.npts()
dt = self.root_instrument.dt()
return timetrace(npts, dt)
class Periodogram(ParameterWithSetpoints):
def get_raw(self):
tt = self.root_instrument.trace()
return np.abs(np.fft.fft(tt)) ** 2
class TimeAxis(Parameter):
def get_raw(self):
npts = self.root_instrument.npts()
dt = self.root_instrument.dt()
return np.linspace(0, dt * npts, npts, endpoint=False)
class FrequencyAxis(Parameter):
def get_raw(self):
npts = self.root_instrument.npts()
dt = self.root_instrument.dt()
return np.linspace(0, 1 / dt, npts)
class OzzyLowScope(Instrument):
def __init__(self, name: str, **kwargs: "Unpack[InstrumentBaseKWArgs]"):
super().__init__(name, **kwargs)
self.npts = self.add_parameter(
name="npts",
initial_value=500,
label="Number of points",
get_cmd=None,
set_cmd=None,
)
self.dt = self.add_parameter(
name="dt",
initial_value=1e-3,
label="Time resolution",
unit="s",
get_cmd=None,
set_cmd=None,
)
self.time_axis = self.add_parameter(
name="time_axis",
label="Time",
unit="s",
vals=vals.Arrays(shape=(self.npts,)),
parameter_class=TimeAxis,
)
self.freq_axis = self.add_parameter(
name="freq_axis",
label="Frequency",
unit="Hz",
vals=vals.Arrays(shape=(self.npts,)),
parameter_class=FrequencyAxis,
)
self.trace = self.add_parameter(
name="trace",
label="Signal",
unit="V",
vals=vals.Arrays(shape=(self.npts,)),
setpoints=(self.time_axis,),
parameter_class=TimeTrace,
)
self.periodogram = self.add_parameter(
name="periodogram",
label="Periodogram",
unit="V^2/Hz",
vals=vals.Arrays(shape=(self.npts,)),
setpoints=(self.freq_axis,),
parameter_class=Periodogram,
)
[4]:
osc = OzzyLowScope("osc")
[5]:
tutorial_db_path = Path.cwd().parent / "example_output" / "tutorial_doND.db"
initialise_or_create_database_at(tutorial_db_path)
load_or_create_experiment(experiment_name="tutorial_exp", sample_name="no sample")
[5]:
tutorial_exp#no sample#1@/home/runner/work/Qcodes/Qcodes/docs/examples/example_output/tutorial_doND.db
------------------------------------------------------------------------------------------------------
Measurement 1: Time Trace¶
[6]:
timemeas = Measurement()
timemeas.register_parameter(osc.trace)
osc.dt(0.001)
with timemeas.run() as datasaver:
datasaver.add_result((osc.trace, osc.trace.get()))
dataset = datasaver.dataset
Starting experimental run with id: 1.
[7]:
_ = plot_dataset(dataset)
[8]:
osc.dt(0.01) # make the trace 10 times longer
with timemeas.run() as datasaver:
datasaver.add_result((osc.trace, osc.trace.get()))
dataset = datasaver.dataset
Starting experimental run with id: 2.
[9]:
_ = plot_dataset(dataset)
Measurement 2: Periodogram¶
[10]:
freqmeas = Measurement()
freqmeas.register_parameter(osc.periodogram)
osc.dt(0.01)
with freqmeas.run() as datasaver:
datasaver.add_result((osc.periodogram, osc.periodogram.get()))
dataid = datasaver.dataset
Starting experimental run with id: 3.
[11]:
axs, cbax = plot_dataset(dataset)
aa = axs[0]
aa.set_yscale("log")
Just for the fun of it, let’s make a measurement with the averaged periodogram.
[12]:
no_of_avgs = 100
with freqmeas.run() as datasaver:
temp_per = osc.periodogram()
for _ in range(no_of_avgs - 1):
temp_per += osc.periodogram()
datasaver.add_result(
(osc.periodogram, temp_per / no_of_avgs), (osc.freq_axis, osc.freq_axis.get())
)
dataset = datasaver.dataset
Starting experimental run with id: 4.
[13]:
axs, cbax = plot_dataset(dataset)
aa = axs[0]
aa.set_yscale("log")
Measurement 3: 2D Sweeping¶
[14]:
meas = Measurement()
meas.register_parameter(osc.npts)
meas.register_parameter(osc.trace, setpoints=[osc.npts], paramtype="numeric")
with meas.run() as datasaver:
osc.dt(0.001)
for npts in [200, 400, 600, 800, 1000, 1200]:
osc.npts(npts)
datasaver.add_result((osc.trace, osc.trace.get()), (osc.npts, osc.npts()))
dataset = datasaver.dataset
WARNING:root:Tried to set a new paramtype numeric, but this parameter already has paramtype array which does not match
WARNING:root:Tried to set a new paramtype numeric, but this parameter already has paramtype array which does not match
Starting experimental run with id: 5.
[15]:
_ = plot_dataset(dataset)
[ ]:
[ ]: