Setpoints are not handled correctly in measurement
Measuring two different ParametersWithSetpoints (say pws1, pws2) in one measurement fails when pws1 has p1 as setpoints and pws2 has p1 and p2 as setpoints. Individual measurements of pws1 and pws2 are running smoothly.
Steps to reproduce
I will attach a jupyternotebook with an example.
Expected behaviour
Measurement should complete with measuring the 1D and the 2D parameter.
Actual behaviour
Measurement fails with the following error:
ValueError: Incompatible shapes. Parameter data1d has shape (3,), but its setpoint t has shape (3, 2).
System
operating system windows 10
qcodes branch version 0.27.0
There is a jupyter notebook in the zip file. I also post the code below. testing_qcodes_setpoints.zip
import qcodes as qc
import numpy as np
from qcodes.utils.dataset.doNd import do0d, do1d, do2d
from qcodes import Parameter, ParameterWithSetpoints
from qcodes.utils.validators import Numbers, Arrays, Enum, Ints, Strings
class axis_1D(Parameter):
"""
A parameter that holds a 1D axis, e.g. time
"""
def __init__(self, dim, *args, **kwargs):
super().__init__(*args, **kwargs)
self._dim = dim
self.vals=Arrays(shape=(self._dim,))
def get_raw(self):
# return dummy axis
axis = np.linspace(1,self._dim,self._dim)
return axis
# create two instances of the axis_1D, e.g. time and frequency
t_axis = axis_1D(name='t', dim=3)
f_axis = axis_1D(name='f', dim=2)
t_axis()
array([1., 2., 3.])
f_axis()
array([1., 2.])
# Let's have a ParameterWithSetpoints depending on only the t_axis
class data1d(ParameterWithSetpoints):
"""
A ParameterWithSetpoints that depends on one of these axes
"""
def __init__(self, setpoints1, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setpoints=(setpoints1, )
# print((len(self.setpoints[0]()), len(self.setpoints[1]()),))
# print(np.zeros((len(self.setpoints[0]()), len(self.setpoints[1]()),)))
# print(np.zeros((len(self.setpoints[0]()), len(self.setpoints[1]()),)).shape)
def get_raw(self):
# return dummy array of correct shape
data_array = np.ones((len(self.setpoints[0]()),))
return data_array
dat1d = data1d(name='data1d', setpoints1=t_axis,vals=Arrays(shape=(len(t_axis()),)))
dat1d()
array([1., 1., 1.])
# Let's have aother ParameterWithSetpoints depending on now both of these tow axes
class data2d(ParameterWithSetpoints):
"""
A ParameterWithSetpoints that depends on both of these axes
"""
def __init__(self, setpoints1, setpoints2, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setpoints=(setpoints1, setpoints2, )
# print((len(self.setpoints[0]()), len(self.setpoints[1]()),))
# print(np.zeros((len(self.setpoints[0]()), len(self.setpoints[1]()),)))
# print(np.zeros((len(self.setpoints[0]()), len(self.setpoints[1]()),)).shape)
def get_raw(self):
# return dummy array of correct shape
data_array = np.zeros((len(self.setpoints[0]()), len(self.setpoints[1]()),))
return data_array
dat2d = data2d(name='data2d', setpoints1=t_axis, setpoints2=f_axis, vals=Arrays(shape=(len(t_axis()), len(f_axis()),)))
dat2d()
array([[0., 0.],
[0., 0.],
[0., 0.]])
# Let's measure them individually
do0d(dat1d, measurement_name='data1d', do_plot=True)
Starting experimental run with id: 32. Using 'qcodes.utils.dataset.doNd.do0d'

# Let's measure them individually
do0d(dat2d, measurement_name='data2d', do_plot=True)
Starting experimental run with id: 33. Using 'qcodes.utils.dataset.doNd.do0d'

- Here it fails
# Let's measure them both
do0d(dat1d, dat2d, measurement_name='data1d_and_data2d', do_plot=True)
2021-08-12 11:12:09,504 ¦ qcodes.dataset.measurements ¦ WARNING ¦ measurements ¦ __exit__ ¦ 638 ¦ An exception occured in measurement with guid: aaaaaaaa-0000-0000-0000-017b39a21810;
Traceback:
Traceback (most recent call last):
File "C:\Users\G-GRE-GRE058050\Miniconda3\lib\site-packages\qcodes\utils\dataset\doNd.py", line 151, in do0d
datasaver.add_result(
File "C:\Users\G-GRE-GRE058050\Miniconda3\lib\site-packages\qcodes\dataset\measurements.py", line 214, in add_result
self._validate_result_shapes(results_dict)
File "C:\Users\G-GRE-GRE058050\Miniconda3\lib\site-packages\qcodes\dataset\measurements.py", line 419, in _validate_result_shapes
raise ValueError(f'Incompatible shapes. Parameter '
ValueError: Incompatible shapes. Parameter data1d has shape (3,), but its setpoint t has shape (3, 2).
Starting experimental run with id: 34. Using 'qcodes.utils.dataset.doNd.do0d'
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
C:\Users\G-GRE-~1\AppData\Local\Temp/ipykernel_66732/553837965.py in <module>
1 # Let's measure them both
----> 2 do0d(dat1d, dat2d, measurement_name='data1d_and_data2d', do_plot=True)
~\Miniconda3\lib\site-packages\qcodes\utils\dataset\doNd.py in do0d(write_period, measurement_name, exp, do_plot, use_threads, log_info, *param_meas)
149
150 with meas.run() as datasaver:
--> 151 datasaver.add_result(
152 *process_params_meas(
153 param_meas,
~\Miniconda3\lib\site-packages\qcodes\dataset\measurements.py in add_result(self, *res_tuple)
212
213 self._validate_result_deps(results_dict)
--> 214 self._validate_result_shapes(results_dict)
215 self._validate_result_types(results_dict)
216
~\Miniconda3\lib\site-packages\qcodes\dataset\measurements.py in _validate_result_shapes(self, results_dict)
417 #print('Setpoint {} has shape: {}'.format(setpoint.name, setpoint_shape)) ##SZ
418 if setpoint_shape not in [(), required_shape]:
--> 419 raise ValueError(f'Incompatible shapes. Parameter '
420 f"{toplevel_param.name} has shape "
421 f"{required_shape}, but its setpoint "
ValueError: Incompatible shapes. Parameter data1d has shape (3,), but its setpoint t has shape (3, 2).
Yes I think that is an unfortunate limitation of how the dataset is designed. I am not sure how straight forward this would be to solve. Going forward we are intending to make it easier for users create individual datasets for each measurement and encourage that a dataset only contains measured parameters with the same shape. This can currently be done with the measurement context manager interface. The intention is to add this to the generalized dond functions here https://github.com/QCoDeS/Qcodes/pull/3186 as well. This should land before the next qcodes release.
Thanks @jenshnielsen for the rapid response. But I am not sure if I fully understand correctly. Is it a general limitation that one can only measure parameters with the same shape? Because I am only running into the problem of the above example if they share the same setpoints. It seems to me that there is something wrong in the determination of the setpoints of a parameter during the measurement.
The two lines just differ in the order of the parameters to measure:
do0d(dat1d, dat2d, measurement_name='data1d_and_data2d', do_plot=True)
ncompatible shapes. Parameter data1d has shape (3,), but its setpoint t has shape (3, 2)
do0d(dat2d, dat1d, measurement_name='data1d_and_data2d', do_plot=True)
Incompatible shapes. Parameter data2d has shape (3, 2), but its setpoint t has shape (3,).
--> it seems registering the second parameter somehow overwrites the setpoint shape of the first one.
Example with a different setpoint but still different shapes:
# create three instances of the axis_1D, e.g. time, time2, and frequency
t_axis = axis_1D(name='t', dim=3)
t_axis2 = axis_1D(name='t2', dim=3)
f_axis = axis_1D(name='f', dim=2)
# create the parameters with setpoints
dat1d = data1d(name='data1d', setpoints1=t_axis,vals=Arrays(shape=(len(t_axis()),)))
dat2d2 = data2d(name='data2d2', setpoints1=t_axis2, setpoints2=f_axis, vals=Arrays(shape=(len(t_axis()), len(f_axis()),)))
# Let's measure them both
do0d(dat1d, dat2d2, measurement_name='data1d_and_data2d', do_plot=True)
Starting experimental run with id: 73.
(data1d_and_data2d #73@C:\Users\SZ258708\experiments.db
------------------------------------------------------
t - array
t2 - array
f - array
data1d - array
data2d2 - array,
[<AxesSubplot:title={'center':'Run #73, Experiment LETI_test (lot_wafer_die_2G11_1)'}, xlabel='t', ylabel='data1d'>,
<AxesSubplot:title={'center':'Run #73, Experiment LETI_test (lot_wafer_die_2G11_1)'}, xlabel='t2', ylabel='f'>],
[None, <matplotlib.colorbar.Colorbar at 0x1c3a6ee9148>])
