Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Samanthaho/registered parameter snapshot #6487

Merged
Merged
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
1 change: 1 addition & 0 deletions docs/changes/newsfragments/6487.improved
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Parameters registered in a qcodes Measurement are now snapshotted and stored in the resulting dataset under `dataset.snapshot["parameters"]`
295 changes: 175 additions & 120 deletions docs/examples/DataSet/Working with snapshots.ipynb

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/qcodes/dataset/data_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ def prepare(
parent_datasets: Sequence[Mapping[Any, Any]] = (),
write_in_background: bool = False,
) -> None:
self.add_snapshot(json.dumps({"station": snapshot}, cls=NumpyJSONEncoder))
self.add_snapshot(json.dumps(snapshot, cls=NumpyJSONEncoder))

if interdeps == InterDependencies_():
raise RuntimeError("No parameters supplied")
Expand Down
2 changes: 1 addition & 1 deletion src/qcodes/dataset/data_set_in_memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ def prepare(
if not self.pristine:
raise RuntimeError("Cannot prepare a dataset that is not pristine.")

self.add_snapshot(json.dumps({"station": snapshot}, cls=NumpyJSONEncoder))
self.add_snapshot(json.dumps(snapshot, cls=NumpyJSONEncoder))

if interdeps == InterDependencies_():
raise RuntimeError("No parameters supplied")
Expand Down
37 changes: 31 additions & 6 deletions src/qcodes/dataset/measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@
in_memory_cache: bool | None = None,
dataset_class: DataSetType = DataSetType.DataSet,
parent_span: trace.Span | None = None,
registered_parameters: Sequence[ParameterBase] | None = None,
) -> None:
if in_memory_cache is None:
in_memory_cache = qc.config.dataset.in_memory_cache
Expand Down Expand Up @@ -577,6 +578,7 @@
self._in_memory_cache = in_memory_cache
self._parent_span = parent_span
self.ds: DataSetProtocol
self._registered_parameters = registered_parameters

@staticmethod
def _calculate_write_period(
Expand Down Expand Up @@ -661,9 +663,15 @@
station = self.station

if station is not None:
snapshot = station.snapshot()
snapshot = {"station": station.snapshot()}
else:
snapshot = {}
if self._registered_parameters is not None:
parameter_snapshot = {
param.short_name: param.snapshot()
for param in self._registered_parameters
}
snapshot["parameters"] = parameter_snapshot

self.ds.prepare(
snapshot=snapshot,
Expand Down Expand Up @@ -803,6 +811,7 @@
self._shapes: Shapes | None = None
self._parent_datasets: list[dict[str, str]] = []
self._extra_log_info: str = ""
self._registered_parameters: list[ParameterBase] = []

@property
def parameters(self) -> dict[str, ParamSpecBase]:
Expand Down Expand Up @@ -926,7 +935,6 @@
f"Can not register object of type {type(parameter)}. Can only "
"register a QCoDeS Parameter."
)

paramtype = self._infer_paramtype(parameter, paramtype)
# default to numeric
if paramtype is None:
Expand Down Expand Up @@ -981,6 +989,7 @@
raise RuntimeError(
f"Does not know how to register a parameter of type {type(parameter)}"
)
self._registered_parameters.append(parameter)

return self

Expand Down Expand Up @@ -1034,6 +1043,7 @@
setpoints: setpoints_type | None,
basis: setpoints_type | None,
paramtype: str,
metadata: dict[str, Any] | None = None,
) -> T:
"""
Update the interdependencies object with a new group
Expand Down Expand Up @@ -1278,23 +1288,37 @@
running this measurement
"""
if isinstance(parameter, ParameterBase):
param = str_or_register_name(parameter)
param_name = str_or_register_name(parameter)
elif isinstance(parameter, str):
param = parameter
param_name = parameter
else:
raise ValueError(
"Wrong input type. Must be a QCoDeS parameter or"
" the name (a string) of a parameter."
)

try:
paramspec: ParamSpecBase = self._interdeps[param]
paramspec: ParamSpecBase = self._interdeps[param_name]
except KeyError:
return

self._interdeps = self._interdeps.remove(paramspec)

log.info(f"Removed {param} from Measurement.")
# Must follow interdeps removal, because interdeps removal may error
if isinstance(parameter, ParameterBase):
samantha-ho marked this conversation as resolved.
Show resolved Hide resolved
try:
self._registered_parameters.remove(parameter)
except ValueError:
return

Check warning on line 1312 in src/qcodes/dataset/measurements.py

View check run for this annotation

Codecov / codecov/patch

src/qcodes/dataset/measurements.py#L1311-L1312

Added lines #L1311 - L1312 were not covered by tests
elif isinstance(parameter, str):
with_parameters_removed = [
param
for param in self._registered_parameters
if parameter not in (param.name, param.register_name)
]
self._registered_parameters = with_parameters_removed

log.info(f"Removed {param_name} from Measurement.")

def add_before_run(self: T, func: Callable[..., Any], args: Sequence[Any]) -> T:
"""
Expand Down Expand Up @@ -1412,6 +1436,7 @@
in_memory_cache=in_memory_cache,
dataset_class=dataset_class,
parent_span=parent_span,
registered_parameters=self._registered_parameters,
)


Expand Down
9 changes: 7 additions & 2 deletions tests/dataset/test_snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ def test_station_snapshot_during_measurement(

measurement.register_parameter(dac.ch1)
measurement.register_parameter(dmm.v1, setpoints=[dac.ch1])

snapshot_of_parameters = {
parameter.short_name: parameter.snapshot() for parameter in (dac.ch1, dmm.v1)
}
with measurement.run() as data_saver:
data_saver.add_result((dac.ch1, 7), (dmm.v1, 5))

Expand All @@ -53,7 +55,10 @@ def test_station_snapshot_during_measurement(
json_snapshot_from_dataset = data_saver.dataset.get_metadata("snapshot") # type: ignore[attr-defined]
snapshot_from_dataset = json.loads(json_snapshot_from_dataset)

expected_snapshot = {"station": snapshot_of_station}
expected_snapshot = {
"station": snapshot_of_station,
"parameters": snapshot_of_parameters,
}
assert expected_snapshot == snapshot_from_dataset

# 2. Test `snapshot_raw` property
Expand Down
Loading