Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/changes/newsfragments/7732.improved
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Added parameters that are controlled by a ParameterWithSetpoints setpoints to
``ParameterWithSetpoints.unpack_self``. Dependent parameters will now be
automatically saved in the correct shape alike the corresponding setpoints.
32 changes: 23 additions & 9 deletions src/qcodes/parameters/parameter_with_setpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,16 +160,30 @@ def depends_on(self) -> ParameterSet:
return ParameterSet(self.setpoints)

def unpack_self(self, value: ValuesType) -> list[tuple[ParameterBase, ValuesType]]:
"""
Unpacks the ParameterWithSetpoints, its setpoints and any inferred
parameters controlled by the setpoints.

Args:
value(ValuesType): The data acquired from this parameter.

Returns:
A list of tuples of parameters and values to be added as results
to the dataset.
"""
unpacked_results: list[tuple[ParameterBase, ValuesType]] = []
setpoint_params = []
setpoint_data = []
for setpointparam in self.setpoints:
these_setpoints = setpointparam.get()
setpoint_params.append(setpointparam)
setpoint_data.append(these_setpoints)
output_grids = np.meshgrid(*setpoint_data, indexing="ij")
for param, grid in zip(setpoint_params, output_grids):
unpacked_results.append((param, grid))
setpoint_params = list(self.setpoints)
setpoint_data = [param.get() for param in setpoint_params]
output_grids = list(np.meshgrid(*setpoint_data, indexing="ij"))
for i, param in enumerate(setpoint_params[:]):
for inferred_param in param.has_control_of:
copy_setpoint_data = setpoint_data[:]
copy_setpoint_data[i] = inferred_param.get()
setpoint_params.append(inferred_param)
output_grids.append(
np.meshgrid(*copy_setpoint_data, indexing="ij")[i]
)
unpacked_results = list(zip(setpoint_params, output_grids))
unpacked_results.extend(
super().unpack_self(value)
) # Must come last to preserve original ordering
Expand Down
48 changes: 48 additions & 0 deletions tests/dataset/measurement/test_self_unpacking.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ def __init__(

def set_raw(self, value: ParamRawDataType) -> None:
# Set all dependent parameters based on their mapping functions
self.value = value
for param, slope_offset in self._components_dict.items():
param(value * slope_offset[0] + slope_offset[1])

def get_raw(self) -> ParamRawDataType:
return self.value

def unpack_self(
self, value: "ValuesType"
) -> list[tuple["ParameterBase", "ValuesType"]]:
Expand Down Expand Up @@ -142,6 +146,50 @@ def test_add_result_self_unpack_with_PWS(controlling_parameters, experiment):
assert pws_data["pws"].shape == (11, 11)
assert pws_data["pws_setpoints"].shape == (11, 11)

def test_add_result_self_unpack_with_PWS_and_inferred_setpoints(
experiment, controlling_parameters):
"""
Test that a ParameterWithSetpoints that has setpoints which themselves
have inferred parameters controlled by a ControllingParameter unpacks
correctly.
"""
control1, comp1, comp2 = controlling_parameters
for param in (control1, comp1, comp2):
param.vals = Arrays(shape=(11,))
pws_other_setpoints = Parameter(
"pws_other_setpoints",
get_cmd=lambda: np.linspace(-1, 1, 13),
vals=Arrays(shape=(13,)),
)
pws = ParameterWithSetpoints(
"pws",
setpoints=(control1, pws_other_setpoints,),
vals=Arrays(shape=(11,13)),
get_cmd=lambda: np.zeros((11,13)),
)

meas = Measurement(experiment)
meas.register_parameter(pws)

assert all(
param in meas._registered_parameters
for param in (comp1, comp2, control1, pws)
)
control1.set(np.linspace(-1, 1, 11))
with meas.run() as datasaver:
datasaver.add_result((pws, pws()))
ds = datasaver.dataset

dataset_data = ds.get_parameter_data()
pws_data = dataset_data.get("pws", None)
assert (pws_data) is not None
print(pws_data.keys())
assert all(
param_name in pws_data.keys()
for param_name in ("pws", "comp1", "comp2", "control1", "pws_other_setpoints")
)
for result in ('control1', 'comp1', 'comp2', 'pws', 'pws_other_setpoints'):
assert pws_data[result].shape == (1, 11, 13)

# Testing equality methods for deduplication
def test_non_numeric_values_are_equal() -> None:
Expand Down
Loading