microsoft / microsoft/Qcodes

SweepMeasurement: better design (employ the power of sweep objects)

Open
#1,141 1 comment 0 reactions 1 assignee Claimed by @astafan8 View on GitHub
enhancement
Dominant language
Python
Stars
459
Forks
359
Avg merge
3d 6h
Merged PRs (30d)
73

Description

## Scope

While implementing the "sweep module", a new `SweepMeasurement` class has been implemented ([see in PR 1107](https://github.com/QCoDeS/Qcodes/pull/1107/files#diff-4963cbfa7200ec4615523838cdbd1589R5) or in qcodes/sweep/measurement.py once #1107 is merged).

The class is implemented by simply subclassing from `Measurement` class, and adding a `register_sweep` method.

## Problem

The implementation is lacking design for the following reasons.

### 1

Thanks to the direct inheritance, `register_parameter` methods can be called on `SweepMeasurement` objects. But this is NOT desirable. The whole point of the `SweepMeasurement` is to get away from `register_parameter`, and use a sweep object for both "measurement definition" and "measurement execution". So, `SweepMeasurement` objects should not have `register_parameter`-like methods. If there is a need to add or remove parameters, that should be done through the sweep object.

### 2

Since `SweepMeasurement` make sense only for once sweep, what is the need for an explicit `register_sweep` method? Why not pass the sweep object directly to the constructor of the `SweepMeasurement`?
Compare two lines
```
sweep_measurement = SweepMeasurement()
sweep_measurement.register_sweep(total_sweep_object)
```
with one line
```
sweep_measurement = SweepMeasurement(total_sweep_object)
```

### 3

Thanks to the sweep object infrastructure, the measurement execution code itself becomes very concise, and more importantly generic. For example:
```
with sweep_measurement.run() as data_saver:
for data_point in total_sweep_object:
data_saver.add_results(*data_point.items())
```
Why not implement a method on `SweepMeasurement` class that does that since `SweepMeasurement` objects are created based on a sweep object and they can contain it inside?

Since the `run` method is considered, it is also worth noting that the `run` method of a `Measurement` object does not actually "run" anything - it just initiates a data set and returns a context manager from within which measurement results can be saved (e.g. added to the data set). On the other hand, a `run` method of the `SweepMeasurement` class can indeed "run" the experiment, because the experiment definition is already known from the sweep object.

## Proposed solution

- Make a private base class `_MeasurementBase` (or `_MeasurementWithDataSetBase`).
- Make `Measurement` class inherit from '_MeasurementBase`, and implement only the register parameter methods in it (like `register_parameter`).
- Make `SweepMeasurement` class inherit from `_MeasurementBase`. Instead of implementing a `register_sweep` method, make the sweep object be an argument for its constructor.
- Implement a `run` method of the `SweepMeasurement` such that it actually "run" the measurement. This might also require renaming of the `run` method of the `Measurement` class.

@sohailc @WilliamHPNielsen @jenshnielsen @Dominik-Vogel

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.