diff --git a/docs/changes/newsfragments/7199.improved b/docs/changes/newsfragments/7199.improved new file mode 100644 index 000000000000..56f51b08d4c9 --- /dev/null +++ b/docs/changes/newsfragments/7199.improved @@ -0,0 +1,7 @@ +`qcodes.dataset.descriptions.detect_shapes` and `qcodes.dataset.dond.do_nd_utils` have been updated +to use `parameter.register_name` when creating shape dictionaries for storage in the dataset + +Previously, these methods used `parameter.full_name` which could result in shapes not being stored +or used correctly for parameters that use `parameter.register_name` + +closes #7198 diff --git a/src/qcodes/dataset/descriptions/detect_shapes.py b/src/qcodes/dataset/descriptions/detect_shapes.py index c3d2b896eb36..76a6cdf22017 100644 --- a/src/qcodes/dataset/descriptions/detect_shapes.py +++ b/src/qcodes/dataset/descriptions/detect_shapes.py @@ -54,9 +54,9 @@ def detect_shape_of_measurement( if isinstance(param, MultiParameter): array_shapes.update(_get_shapes_of_multi_parameter(param=param)) elif _param_is_array_like(param): - array_shapes[param.full_name] = _get_shape_of_arrayparam(param) + array_shapes[param.register_name] = _get_shape_of_arrayparam(param) else: - array_shapes[param.full_name] = () + array_shapes[param.register_name] = () shapes: dict[str, tuple[int, ...]] = {} diff --git a/src/qcodes/dataset/dond/do_nd_utils.py b/src/qcodes/dataset/dond/do_nd_utils.py index 2291a400f05d..4864ece31663 100644 --- a/src/qcodes/dataset/dond/do_nd_utils.py +++ b/src/qcodes/dataset/dond/do_nd_utils.py @@ -62,7 +62,7 @@ def _register_parameters( meas.register_parameter(parameter, setpoints=setpoints) if shapes is not None: - parameter_names = [param.full_name for param in real_parameters] + parameter_names = [param.register_name for param in real_parameters] for param in real_parameters: if isinstance(param, MultiParameter): parameter_names.extend(param.full_names) diff --git a/tests/dataset/dond/test_doNd.py b/tests/dataset/dond/test_doNd.py index 20f4a6080c7e..4203458f135b 100644 --- a/tests/dataset/dond/test_doNd.py +++ b/tests/dataset/dond/test_doNd.py @@ -4,6 +4,7 @@ import logging import re +from functools import partial from typing import assert_type import hypothesis.strategies as hst @@ -35,8 +36,13 @@ Multi2DSetPointParam2Sizes, MultiSetPointParam, ) -from qcodes.parameters import ManualParameter, Parameter, ParameterBase -from qcodes.validators import Ints +from qcodes.parameters import ( + ManualParameter, + Parameter, + ParameterBase, + ParameterWithSetpoints, +) +from qcodes.validators import Arrays, Ints from tests.dataset.conftest import ArrayshapedParam @@ -357,6 +363,34 @@ def test_dond_0d_verify_shape( assert param_data.shape == expected_shapes[name] +@pytest.mark.usefixtures("experiment") +def test_dond_0d_pws_with_register_name_has_correct_shape() -> None: + numpoints = 101 + setpoints = Parameter( + "setpoints", + get_cmd=partial(np.linspace, 0, 1, numpoints), + vals=Arrays(shape=(numpoints,)), + ) + + def complex_get_cmd() -> np.ndarray: + reals: np.ndarray = np.linspace(0, 10, numpoints) + imags: np.ndarray = np.linspace(0, 10, numpoints) + return reals + 1.0j * imags + + pws_with_register_name = ParameterWithSetpoints( + name="pws", + setpoints=[setpoints], + get_cmd=complex_get_cmd, + vals=Arrays(shape=(numpoints,), valid_types=[np.complexfloating]), + register_name="register_pws", + ) + ds, _, _ = dond(pws_with_register_name, measurement_name="With register_name") + + expected_shape = {"register_pws": (numpoints,)} + assert isinstance(ds, DataSetProtocol) + assert ds.description.shapes == expected_shape + + @pytest.mark.usefixtures("plot_close", "experiment") def test_dond_0d_output_data(_param) -> None: exp = dond(_param) diff --git a/tests/dataset/test_detect_shape.py b/tests/dataset/test_detect_shape.py index 3015c1f6f1fd..1fa2b097451b 100644 --- a/tests/dataset/test_detect_shape.py +++ b/tests/dataset/test_detect_shape.py @@ -131,6 +131,28 @@ def test_get_shape_for_pws_from_shape( assert (dummyinstrument.A.dummy_n_points(),) == param.vals.shape +@settings(suppress_health_check=(HealthCheck.function_scoped_fixture,)) +@pytest.mark.parametrize("range_func", [range, np.arange]) +@given( + loop_shape=hst.lists( + hst.integers(min_value=1, max_value=1000), min_size=1, max_size=10 + ), + n_points=hst.integers(min_value=1, max_value=1000), +) +def test_get_shape_for_pws_with_register_name_from_shape( + dummyinstrument, loop_shape, range_func, n_points +) -> None: + param = dummyinstrument.A.dummy_parameter_with_setpoints + param._register_name = f"register_{param.full_name}" # register_name can ordinarily only be set at init + dummyinstrument.A.dummy_n_points(n_points) + loop_sequence = tuple(range_func(x) for x in loop_shape) + shapes = detect_shape_of_measurement((param,), loop_sequence) + expected_shapes = {} + expected_shapes[param.register_name] = tuple(loop_shape) + tuple(param.vals.shape) + assert shapes == expected_shapes + assert (dummyinstrument.A.dummy_n_points(),) == param.vals.shape + + @given( loop_shape=hst.lists( hst.integers(min_value=1, max_value=1000), min_size=1, max_size=10