Delegate Instruments Approach #6357
Replies: 1 comment
-
I tried using this method by creating parameters for voltage sources and the carrier density. class VoltageParameter(Parameter):
"""
Abstraction of a voltage parameter in some voltage source
"""
def __init__(self, name, voltage: Parameter, range: List[float]):
self._voltage = voltage
self._range = range
super().__init__(name)
@property
def underlying_instrument(self) -> Optional['InstrumentBase']:
return self._dac_param.root_instrument
def get_raw(self):
return self._voltage.get()
def set_raw(self, val):
self._voltage.set(val)
def get_range(self):
return self._range
class DensityParameter(Parameter):
"""
Parameter abstracting carrier density in dual gated capacitance measurement
"""
def __init__(self, name, sources: List[VoltageParameter], capacitances: List[float]):
self.caps = capacitances
self.srcs = sources
rng_low, rng_high = 0,0
for i in range(len(sources)):
rng_low += self.caps[i] * self.srcs[i].get_range()[0]
rng_high += self.caps[i] * self.srcs[i].get_range()[1]
self._range = [rng_low, rng_high]
super().__init__(name)
def get_raw(self):
sum = 0
for i in range(len(self.srcs)):
sum += self.caps[i] * self.srcs[i].get()
return sum
def set_raw(self, val: float):
if val < self._range[0] or val > self._range[1]:
raise ValueError("Value out of range for density: " + str(val))
s1_intermediate = val - self._get_src_vals(1)
if s1_intermediate < self._get_src_range(0)[0]:
s1_intermediate = self._get_src_range(0)[0]
elif s1_intermediate > self._get_src_range(0)[1]:
s1_intermediate = self._get_src_range(0)[1]
s2_new = val - s1_intermediate
self.srcs[0].set(s1_intermediate/self.caps[0])
self.srcs[1].set(s2_new/self.caps[1])
def get_range(self):
return self._range
def _get_src_vals(self, index):
return self.caps[index] * self.srcs[index].get_raw()
def _get_src_range(self, index):
rng = self.srcs[index].get_range()
return [self.caps[index] * rng[0] , self.caps[index] * rng[1]] which works alright with this quick test script dac = DummyInstrument('dac', gates=['ch1', 'ch2'])
dac.ch1.set(5)
dac.ch2.set(8)
vp1 = VoltageParameter('v1', dac.ch1, [0, 10])
vp2 = VoltageParameter('v2', dac.ch2, [0, 23])
n = DensityParameter('density', [vp1, vp2], [-4, 6]) but in the docs, its recommended that manually created parameters are tied to underlying instruments as done in the voltage parameter. However, since carrier density is tied to potentially two instruments, I'm wondering what issues this implementation could cause, and if there's a better solution. |
Beta Was this translation helpful? Give feedback.
-
I'm aiming to write a control script for a dual-gated capacitance sensing experiment. I want to set and get the carrier density$n = C_1V_1 + C_2V_2$ where the $C_i$ are some constants and $V_i$ are voltage parameters defined in possibly different instruments.
I was thinking of using the DelegateInstrument approach here, but the setting function for the carrier density is a little complex since ranges have to be taken into account.
I then thought to write out the DelegateInstrument class on its own with the voltage sources being AbstractInstruments containing a voltage and range parameter.
I'm just wondering if there are more standard approaches to this sort of problem in qcodes and whether there are other classes I should think of using. Or should I just abandon this goal all together and write out plain python functions to set and get the carrier density?
Thanks
Beta Was this translation helpful? Give feedback.
All reactions