Qcodes icon indicating copy to clipboard operation
Qcodes copied to clipboard

Snapshot of ScaledParameter doesn't update when wrapped parameter is set

Open sldesnoo-Delft opened this issue 4 years ago • 5 comments

Steps to reproduce

  1. Create ScaledParameter
  2. Change value of wrapped parameter
  3. Take snapshot of ScaledParameter. => It contains the old value

Expected behaviour

It is expected that also the snapshot of the ScaledParameter reflects the latest value of the wrapped behavior.

Actual behaviour

Snapshot of ScaledParameter is not updated.

System

Windows qcodes release 0.21

Example to reproduce:

import qcodes as qc
from qcodes.tests.instrument_mocks import DummyInstrument
from pprint import pprint

iv_converter = DummyInstrument('iv_converter', gates=('adc1',))

current1 = qc.ScaledParameter(output=iv_converter.adc1, gain=1/1e6, name='current1', unit='A')

# This works fine
current1(4e-6)
pprint(current1.snapshot()) # this snapshot is correct

# Set adc1 to 3
iv_converter.adc1(3)
pprint(current1.snapshot()) # this snapshot  "value" is not correct (old value)

sldesnoo-Delft avatar Jan 20 '21 10:01 sldesnoo-Delft

@sldesnoo-Delft Thanks for your report. In all honesty I think the ScaledParameter should probably be deprecated and its use replaced by the DelegateParameter. Can you check it DelegateParameter solves your needs?

jenshnielsen avatar Jan 20 '21 10:01 jenshnielsen

DelegateParameter does not provide any scaling. I've made a derived class to add fixed scaling, but that does not yet provide the option use a parameter as gain. I'm not sure whether all snapshot options are properly taken into account with this class. It would be nice to have a proper ScaledParameter in qcodes.

class ScaledParameter(qc.DelegateParameter):
	def __init__(self, name, source, gain, *args, **kwargs):
		super().__init__(name, source, *args, **kwargs)
		self._gain = gain

	def get_raw(self):
		return self.source.get() * self._gain

	def set_raw(self, value):
		self.source(value / self._gain)

	def snapshot_base(self, update = True, params_to_skip_update = None):
		snapshot = super().snapshot_base(
			update=update,
			params_to_skip_update=params_to_skip_update
		)

		snapshot.update({'gain': self._gain})
		if 'value' in snapshot and snapshot['value'] is not None:
			snapshot.update(
				{
					'value': snapshot['value'] * self._gain,
					'raw_value': snapshot['raw_value'] * self._gain,
				}
			)

		return snapshot

sldesnoo-Delft avatar Jan 20 '21 11:01 sldesnoo-Delft

Sorry I should have been more clear. All QCoDeS parameters have a scale and and an offset. So you can do something like:

from qcodes.instrument.parameter import DelegateParameter, Parameter
a = Parameter(name='a', unit='V', set_cmd=None, get_cmd=None, initial_value=1)
b = DelegateParameter(name="b", unit="KV", source=a, scale=1e3)
a.get()
1

b.get()
0.001

b.snapshot(update=False)
{'__class__': 'qcodes.instrument.parameter.DelegateParameter',
 'full_name': 'b',
 'value': 0.001,
 'raw_value': 1,
 'ts': '2021-01-20 12:39:18',
 'inter_delay': 0,
 'name': 'b',
 'scale': 1000.0,
 'post_delay': 0,
 'label': 'a',
 'unit': 'KV',
 'source_parameter': {'__class__': 'qcodes.instrument.parameter.Parameter',
  'full_name': 'a',
  'value': 1,
  'raw_value': 1,
  'ts': '2021-01-20 12:39:18',
  'inter_delay': 0,
  'name': 'a',
  'post_delay': 0,
  'label': 'a',
  'unit': 'V'}}

a.set(2)
b.snapshot(update=False)

{'__class__': 'qcodes.instrument.parameter.DelegateParameter',
 'full_name': 'b',
 'value': 0.002,
 'raw_value': 2,
 'ts': '2021-01-20 12:39:48',
 'inter_delay': 0,
 'name': 'b',
 'scale': 1000.0,
 'post_delay': 0,
 'label': 'a',
 'unit': 'KV',
 'source_parameter': {'__class__': 'qcodes.instrument.parameter.Parameter',
  'full_name': 'a',
  'value': 2,
  'raw_value': 2,
  'ts': '2021-01-20 12:39:48',
  'inter_delay': 0,
  'name': 'a',
  'post_delay': 0,
  'label': 'a',
  'unit': 'V'}}

jenshnielsen avatar Jan 20 '21 11:01 jenshnielsen

The scale argument is new to me. Currently this satisfies our needs.

In the future we might want to use a parameter for scale. When an amplifier is controlled as a qcodes instrument, then it would be nice to use the gain parameter of the amplifier as scale of the DelegateParameter.

sldesnoo-Delft avatar Jan 22 '21 12:01 sldesnoo-Delft

Thanks agree that it is handy to be able to bind another parameter to the scale. I will think about how to best handle that

jenshnielsen avatar Jan 22 '21 13:01 jenshnielsen