Skip to content

Shared coords for acquisition channels

High-level description

Note: this issue makes sense only when the "coord" feature is added to quantify-scheduler.

Currently quantify-scheduler's is not properly prepared for experiments where there is a shared coord key between multiple acquisition channels.

For example.

schedule = Schedule("schedule")

schedule.add(Measure("q0", acq_channel="ch_0", coord=dict(amp=0.1)))
schedule.add(Measure("q1", acq_channel="ch_1", coord=dict(amp=0.1)))

In these cases, the user might still want to filter the data (both acquisition channels simultaneously) for amp, for example retrieved_dataset.where(dataset.amp == 0), so requiring the user to not share any coord key between acquisition channels is not an option in some cases.

Task

This ticket is about resolving this issue. In &5 (closed) it was agreed, that the way to handle this case is that for any acquisition channels (multiple, not just any two) that share at least one coord key, they must also share the acquisition index dimension name. This resolves the issue.

(We do not want to share the same acquisition index dimension name for all acquisition channels, because that could be very memory inefficient: if they don't share them, we need to fill the data with a lot of NaNs.)

Details of the problem

Let's say we have the following schedule.

amps = [0.0, 0.5, 1.0, 1.5, 2.0]
schedule = Schedule(name="Simple 1D sweep", repetitions=1)
for amp in amps:
    schedule.add(Measure(qubit="q0", acq_channel="ch_0", coord=dict(amp=amp)))
    schedule.add(Measure(qubit="q1", acq_channel="ch_1", coord=dict(amp=amp)))

The return data is an xarray Dataset. Currently the acquisition index dimension names are "acq_index_ch_0" and "acq_index_ch_1" in the return data. The return data is supposed to be the following.

ch_0 = xarray.DataArray(
    data=[0.0, 0.2, 0.4, 0.6, 0.8],
    dims=["acq_index_ch_0"],
    coords=dict(
        amp=(["acq_index_ch_0"], amps),
        acq_index_ch_0=range(len(amps)),
    ),
)
ch_1 = xarray.DataArray(
    data=[1.0, 1.2, 1.4, 1.6, 1.8],
    dims=["acq_index_ch_1"],
    coords=dict(
        amp=(["acq_index_ch_1"], amps),
        acq_index_ch_1=range(len(amps)),
    ),
)
dataset = xarray.Dataset()
dataset = dataset.merge(xarray.Dataset({"ch_0": ch_0})) # or add compat="override"
dataset = dataset.merge(xarray.Dataset({"ch_1": ch_1})) # or add compat="override"

dataset

Unfortunately, xarray does not allow this, it will raise an error. Even if add compat="override", one of the channels data (either dataset["ch_0"] or dataset["ch_1"]) will not contain the amp coords, and also filtering based on amp will look strange, and incorrect (look at dataset["ch_0"].where(dataset.amp == 0) or dataset["ch_1"].where(dataset.amp == 0)).

However, if the data is the following (channels share the same dimension or acquisition index dimension name, which is "acq_index_ch_0_ch_1"), then all of those filterings based on amp (dataset[acq_channel].where(dataset.amp == 0)) will work, moreover dataset["ch_0"] and dataset["ch_1"] will include the amp as coordinate.

ch_0 = xarray.DataArray(
    data=[0.0, 0.2, 0.4, 0.6, 0.8],
    dims=["acq_index_ch_0_ch_1"],
    coords=dict(
        amp=(["acq_index_ch_0_ch_1"], amps),
        acq_index_ch_0_ch_1=range(len(amps)),
    ),
)
ch_1 = xarray.DataArray(
    data=[1.0, 1.2, 1.4, 1.6, 1.8],
    dims=["acq_index_ch_0_ch_1"],
    coords=dict(
        amp=(["acq_index_ch_0_ch_1"], amps),
        acq_index_ch_0_ch_1=range(len(amps)),
    ),
)
dataset = xarray.Dataset()
dataset = dataset.merge(xarray.Dataset({"ch_0": ch_0}))
dataset = dataset.merge(xarray.Dataset({"ch_1": ch_1}))

dataset

Task in detail

The task is to modify the ./quantify_scheduler/helpers/generate_acq_channels_data.py, so that

  • it generates the acquisition index dimension name, so that whenever to acquisition channels share the at least one coord, they get the same name, and
  • whenever two acquisitions between channels have exactly the same coord values (both keys and their values are exactly the same), then it generates exactly the same acquisition index values.

There are some edge-cases, we need to also take care of: if a coord which is present in one of the acquisition channels is not in the other (both keys and values are not the same exactly), then for this other channel the measured value must be NaN. See examples for this in the example Multiple separate dense data in append mode.

Edited by Gábor Oszkár Dénes