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
Binary file modified .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions qm_id-41.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
QM-538f590a-f5b0-42fa-994a-e274ed5e5723
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
from scipy.optimize import differential_evolution

from qualibrate import QualibrationNode
from calibration_utils.common_utils.parity_dataset import (
get_pdiff_trace,
get_qubit_names_from_pdiff,
)

_logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -147,7 +151,7 @@ def _profile_residual(t1_arr):
result["offset"] = offset
result["decay_rate"] = decay_rate
result["fitted_curve"] = fitted_curve
result["success"] = np.isfinite(t1_best) and t1_best > 0 and abs(amplitude) > 1e-6
result["success"] = bool(np.isfinite(t1_best) and t1_best > 0 and abs(amplitude) > 1e-6)

_logger.debug(
"T1 fit: T1=%.1f ns, A=%.4f, offset=%.4f, γ=%.6f 1/ns",
Expand Down Expand Up @@ -191,16 +195,13 @@ def fit_raw_data(
qubits = node.namespace["qubits"]
tau_ns = np.asarray(ds.tau.values, dtype=float)

pdiff_vars = [v for v in ds.data_vars if v.startswith("pdiff_")]
qubit_names = [v.replace("pdiff_", "") for v in sorted(pdiff_vars)]
if not qubit_names:
qubit_names = [getattr(q, "name", f"Q{i}") for i, q in enumerate(qubits)]
qubit_names = get_qubit_names_from_pdiff(ds, fallback_qubits=qubits)

fit_results: Dict[str, Dict[str, Any]] = {}

for qname in qubit_names:
pdiff_var = f"pdiff_{qname}"
if pdiff_var not in ds.data_vars:
pdiff = get_pdiff_trace(ds, qname)
if pdiff is None:
fp = FitParameters(
T1=np.nan,
amplitude=0.0,
Expand All @@ -211,7 +212,6 @@ def fit_raw_data(
fit_results[qname] = asdict(fp)
continue

pdiff = np.asarray(ds[pdiff_var].values, dtype=float)
raw = _fit_single_qubit(pdiff, tau_ns)

fp = FitParameters(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
import numpy as np
import xarray as xr

from calibration_utils.common_utils.parity_dataset import (
get_pdiff_trace,
get_qubit_names_from_pdiff,
)


def _get_qubit_names_from_ds(ds: xr.Dataset) -> List[str]:
"""Extract qubit names from ``pdiff_<name>`` data-variable keys."""
pdiff_vars = [v for v in ds.data_vars if v.startswith("pdiff_") and not v.endswith("_fit")]
return [v.replace("pdiff_", "") for v in sorted(pdiff_vars)]
return get_qubit_names_from_pdiff(ds)


def plot_raw_data_with_fit(
Expand Down Expand Up @@ -74,10 +77,8 @@ def plot_raw_data_with_fit(
offset = fr.get("offset", np.nan)
success = fr.get("success", False)

pdiff_var = f"pdiff_{qname}"
if pdiff_var in ds.data_vars:
pdiff = np.asarray(ds[pdiff_var].values, dtype=float)
else:
pdiff = get_pdiff_trace(ds, qname)
if pdiff is None:
pdiff = np.full_like(tau_ns, np.nan)

# Data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ def fit_raw_data(ds: xr.Dataset, node: QualibrationNode) -> Tuple[xr.Dataset, di
ds_fit = ds_fit.assign_coords(success=("sensors", success_list))

# Set node outcomes
node.outcomes = {sensor.id: "successful" if fit_results[sensor.id].success else "fail" for sensor in sensors}
node.outcomes = {sensor.id: "successful" if fit_results[sensor.id].success else "failed" for sensor in sensors}

return ds_fit, fit_results

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""Helpers for parity-difference datasets across fetch conventions."""

from __future__ import annotations

from typing import Iterable, List

import numpy as np
import xarray as xr


def get_qubit_names_from_pdiff(ds: xr.Dataset, fallback_qubits: Iterable | None = None) -> List[str]:
"""Resolve qubit names from grouped or per-variable parity-diff datasets."""
if "pdiff" in ds.data_vars and "qubit" in ds["pdiff"].dims:
return [str(name) for name in np.asarray(ds["pdiff"].coords["qubit"].values)]

pdiff_vars = [v for v in ds.data_vars if v.startswith("pdiff_") and not v.endswith("_fit")]
if pdiff_vars:
return [v.replace("pdiff_", "") for v in sorted(pdiff_vars)]

if fallback_qubits is None:
return []
return [getattr(q, "name", f"Q{i}") for i, q in enumerate(fallback_qubits)]


def get_pdiff_trace(ds: xr.Dataset, qname: str) -> np.ndarray | None:
"""Return 1D/2D parity-difference trace for one qubit name if available."""
if "pdiff" in ds.data_vars and "qubit" in ds["pdiff"].dims:
qubit_coords = [str(name) for name in np.asarray(ds["pdiff"].coords["qubit"].values)]
if qname not in qubit_coords:
return None
return np.asarray(ds["pdiff"].sel(qubit=qname).values, dtype=float)

pdiff_var = f"pdiff_{qname}"
if pdiff_var not in ds.data_vars:
return None
return np.asarray(ds[pdiff_var].values, dtype=float)
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from scipy.optimize import differential_evolution

import xarray as xr
from calibration_utils.common_utils.parity_dataset import get_pdiff_trace

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -117,11 +118,7 @@ def _cost(params: np.ndarray) -> float:

# Sanity: T2 should be positive and finite, amplitude should be non-zero
success = bool(
result.success
and np.isfinite(t2_best)
and t2_best > 0
and np.isfinite(amp_best)
and abs(amp_best) > 1e-6
result.success and np.isfinite(t2_best) and t2_best > 0 and np.isfinite(amp_best) and abs(amp_best) > 1e-6
)

decay_rate = 2.0 / t2_best if t2_best > 0 else 0.0
Expand Down Expand Up @@ -166,14 +163,13 @@ def fit_raw_data(

for qubit in qubits:
qname = qubit.name
var_name = f"pdiff_{qname}"
if var_name not in ds_raw.data_vars:
pdiff = get_pdiff_trace(ds_raw, qname)
if pdiff is None:
logger.warning("No pdiff variable for qubit %s — skipping.", qname)
results[qname] = dict(FitParameters().__dict__, fitted_curve=np.array([]))
continue

pdiff = ds_raw[var_name].values.astype(np.float64)
results[qname] = _fit_single_qubit(tau_ns, pdiff)
results[qname] = _fit_single_qubit(tau_ns, pdiff.astype(np.float64))

return results

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import numpy as np
import xarray as xr

from calibration_utils.common_utils.parity_dataset import get_pdiff_trace


def plot_raw_data_with_fit(
ds_raw: xr.Dataset,
Expand Down Expand Up @@ -53,13 +55,12 @@ def plot_raw_data_with_fit(
for idx, qubit in enumerate(qubits):
ax = axes[idx, 0]
qname = qubit.name
var_name = f"pdiff_{qname}"

if var_name not in ds_raw.data_vars:
pdiff = get_pdiff_trace(ds_raw, qname)
if pdiff is None:
ax.set_title(f"{qname} — no data")
continue

pdiff = ds_raw[var_name].values.astype(np.float64)
pdiff = pdiff.astype(np.float64)
r = fit_results.get(qname, {})

# Raw data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
from scipy.optimize import curve_fit

from qualibrate import QualibrationNode
from calibration_utils.common_utils.parity_dataset import (
get_pdiff_trace,
get_qubit_names_from_pdiff,
)

_logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -252,7 +256,7 @@ def _analyse_single_qubit(
gamma,
)

success = np.isfinite(a_pi) and a_pi > 0
success = bool(np.isfinite(a_pi) and a_pi > 0)

return {
"opt_amp": float(a_pi),
Expand All @@ -275,18 +279,15 @@ def fit_raw_data(
) -> Tuple[xr.Dataset, Dict[str, Dict[str, Any]]]:
"""Fit optimal amplitude per qubit from power-Rabi data."""
qubits = node.namespace["qubits"]
pdiff_vars = [v for v in ds.data_vars if v.startswith("pdiff_")]
qubit_names = [v.replace("pdiff_", "") for v in sorted(pdiff_vars)]
if not qubit_names:
qubit_names = [getattr(q, "name", f"Q{i}") for i, q in enumerate(qubits)]
qubit_names = get_qubit_names_from_pdiff(ds, fallback_qubits=qubits)

amps = np.asarray(ds.amp_prefactor.values, dtype=float)

fit_results: Dict[str, Dict[str, Any]] = {}

for qname in qubit_names:
pdiff_var = f"pdiff_{qname}"
if pdiff_var not in ds.data_vars:
pdiff = get_pdiff_trace(ds, qname)
if pdiff is None:
fp = FitParameters(
opt_amp=np.nan,
rabi_frequency=np.nan,
Expand All @@ -296,7 +297,6 @@ def fit_raw_data(
fit_results[qname] = asdict(fp)
continue

pdiff = np.asarray(ds[pdiff_var].values, dtype=float)
result = _analyse_single_qubit(pdiff, amps)

fp = FitParameters(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
import xarray as xr

from calibration_utils.power_rabi.analysis import FFT_FREQ_MIN, FFT_FREQ_MAX
from calibration_utils.common_utils.parity_dataset import (
get_pdiff_trace,
get_qubit_names_from_pdiff,
)


def _get_qubit_names_from_ds(ds: xr.Dataset) -> List[str]:
pdiff_vars = [v for v in ds.data_vars if v.startswith("pdiff_") and not v.endswith("_fit")]
return [v.replace("pdiff_", "") for v in sorted(pdiff_vars)]
return get_qubit_names_from_pdiff(ds)


def _plot_rabi_trace_ax(
Expand Down Expand Up @@ -103,18 +106,16 @@ def plot_raw_data_with_fit(

for i, qname in enumerate(qubit_names):
ax_trace, ax_fft = axes[i, 0], axes[i, 1]
pdiff_var = f"pdiff_{qname}"
fr = fit_results.get(qname, {})

amps = np.asarray(ds.amp_prefactor.values, dtype=float)

if pdiff_var not in ds.data_vars:
pdiff = get_pdiff_trace(ds, qname)
if pdiff is None:
ax_trace.text(0.5, 0.5, f"No data for {qname}", transform=ax_trace.transAxes, ha="center")
ax_fft.text(0.5, 0.5, f"No data for {qname}", transform=ax_fft.transAxes, ha="center")
continue

pdiff = np.asarray(ds[pdiff_var].values, dtype=float)

_plot_rabi_trace_ax(ax_trace, pdiff, amps, qname, fit_result=fr)
_plot_fft_ax(ax_fft, qname, fit_result=fr)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
from scipy.optimize import curve_fit, differential_evolution

from qualibrate import QualibrationNode
from calibration_utils.common_utils.parity_dataset import (
get_pdiff_trace,
get_qubit_names_from_pdiff,
)

_logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -357,7 +361,7 @@ def _objective(params):
t2_star,
)

success = np.isfinite(t2_star) and t2_star > 0
success = bool(np.isfinite(t2_star) and t2_star > 0)

return {
"freq_offset": freq_offset,
Expand Down Expand Up @@ -401,19 +405,16 @@ def fit_raw_data(
``_diag`` key with diagnostic arrays for plotting.
"""
qubits = node.namespace["qubits"]
pdiff_vars = [v for v in ds.data_vars if v.startswith("pdiff_")]
qubit_names = [v.replace("pdiff_", "") for v in sorted(pdiff_vars)]
if not qubit_names:
qubit_names = [getattr(q, "name", f"Q{i}") for i, q in enumerate(qubits)]
qubit_names = get_qubit_names_from_pdiff(ds, fallback_qubits=qubits)

detuning_hz = np.asarray(ds.detuning.values, dtype=float)
tau_ns = np.asarray(ds.tau.values, dtype=float)

fit_results: Dict[str, Dict[str, Any]] = {}

for qname in qubit_names:
pdiff_var = f"pdiff_{qname}"
if pdiff_var not in ds.data_vars:
pdiff = get_pdiff_trace(ds, qname)
if pdiff is None:
fp = FitParameters(
freq_offset=0.0,
t2_star=np.nan,
Expand All @@ -424,7 +425,6 @@ def fit_raw_data(
fit_results[qname] = asdict(fp)
continue

pdiff = np.asarray(ds[pdiff_var].values, dtype=float)
result = _analyse_single_qubit(pdiff, detuning_hz, tau_ns)

fp = FitParameters(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@
import numpy as np
import xarray as xr

from calibration_utils.common_utils.parity_dataset import (
get_pdiff_trace,
get_qubit_names_from_pdiff,
)


def _get_qubit_names_from_ds(ds: xr.Dataset) -> List[str]:
"""Extract qubit names from ``pdiff_<name>`` data-variable keys."""
pdiff_vars = [v for v in ds.data_vars if v.startswith("pdiff_") and not v.endswith("_fit")]
return [v.replace("pdiff_", "") for v in sorted(pdiff_vars)]
return get_qubit_names_from_pdiff(ds)


def _plot_chevron_ax(
Expand Down Expand Up @@ -127,13 +130,13 @@ def plot_raw_data_with_fit(
fig, axes = plt.subplots(n, ncol, figsize=(6 * ncol, 4 * n), squeeze=False)

for i, qname in enumerate(qubit_names):
pdiff_var = f"pdiff_{qname}"
fr = fit_results.get(qname, {})

tau_ns = np.asarray(ds.tau.values, dtype=float)
detuning_mhz = np.asarray(ds.detuning.values, dtype=float) * 1e-6
pdiff = get_pdiff_trace(ds, qname)

if pdiff_var not in ds.data_vars:
if pdiff is None:
for j in range(ncol):
axes[i, j].text(
0.5,
Expand All @@ -144,8 +147,6 @@ def plot_raw_data_with_fit(
)
continue

pdiff = np.asarray(ds[pdiff_var].values, dtype=float)

_plot_chevron_ax(axes[i, 0], pdiff, tau_ns, detuning_mhz, qname, fr)
_plot_resonance_ax(axes[i, 1], detuning_mhz, qname, fr)

Expand Down
Loading