microsoft / microsoft/Qcodes

xarray dataset dependency is incorrect when adding an independent parameter to the measurement

Open
#5,232 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
459
Forks
359
Avg merge
3d 6h
Merged PRs (30d)
73

Description

I created a parameter with setpoints `Y` which depends on setpoint `X`.
Then I created another parameter `Z` which is independent from the other two.
I measured `Y` and `Z` in the measurement context, then convert the result dataset to an xarray.

### Expected behaviour
I expect that the `Y` would be a data variable that depends on `X`, and `Z` on index, as inferred from the `paramspecs`.
```
{'foo_instrument_X': ParamSpec('foo_instrument_X', 'array', 'X', '', inferred_from=[], depends_on=[]),
'foo_instrument_Y': ParamSpec('foo_instrument_Y', 'array', 'Y', '', inferred_from=[], depends_on=['foo_instrument_X']),
'foo_instrument_Z': ParamSpec('foo_instrument_Z', 'numeric', 'Z', '', inferred_from=[], depends_on=[])}
```

### Actual behaviour
All parameters became data variables that depended on index.
image

### Steps to reproduce
Run the following snippet
```python
import numpy as np
import qcodes as qc
from qcodes import Measurement
from qcodes.instrument import Instrument
from qcodes.parameters import Parameter, ParameterWithSetpoints
from qcodes.validators import Arrays, Numbers
class FooGeneratedSetpoints(Parameter):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def get_raw(self):
return np.array(range(4,8))
class FooArray(ParameterWithSetpoints):
def get_raw(self):
return np.array(range(4))
class FooInstrument(Instrument):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.add_parameter(
"X",
parameter_class=FooGeneratedSetpoints,
vals=Arrays(shape=(4,))
)
self.add_parameter(
"Y",
parameter_class=FooArray,
setpoints=(self.X,),
vals=Arrays(shape=(4,))
)
foo = FooInstrument("foo_instrument")

foo.add_parameter("Z", set_cmd=None)

meas = Measurement()
meas.register_parameter(foo.Y)
meas.register_parameter(foo.Z)
with meas.run() as datasaver:
for z in range(8,12):
datasaver.add_result(
(foo.Y, foo.Y()), (foo.Z, z)
)
dataset = datasaver.dataset
dataset.to_xarray_dataset()
```

If I modify the setpoint to the following, the issue disappeared and the result dataset is as expected.
```python
from random import random
class FooGeneratedSetpoints(Parameter):
...
def get_raw(self):
return np.array([random() + i for i in range(4,8)])
...
```
image

Contributor guide

Open the contributing guide

Research direction

Start with the Measurement, datasaver.dataset, and to_xarray_dataset entry points from the reproduction, then trace how ParamSpec depends_on metadata is converted into xarray variables. Reproduce the example with deterministic setpoints and compare the resulting dependencies for X, Y, and independent Z. Done means Y depends on X while Z depends on the index, with regression coverage for this case.

Written by the indexing model from the issue text.

Assessment

Tech stack
numpy, python
Domain
data
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.