Skip to content

Commit

Permalink
Fix bugs and get working, albeit with custom qualibrate version (see q…
Browse files Browse the repository at this point in the history
  • Loading branch information
deanpoulos committed Jan 23, 2025
1 parent 43d5715 commit 1e1d682
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
- Update the qubits frequency and T2_ramsey in the state.
- Save the current state
"""

from dataclasses import asdict

# %% {Imports}
from qualibrate import QualibrationNode
Expand Down Expand Up @@ -57,7 +57,7 @@

machine = QuAM.load()

qubits = machine.get_qubits_used_in_node(node)
qubits = machine.get_qubits_used_in_node(node.parameters)
num_qubits = len(qubits)

config = machine.generate_config()
Expand All @@ -66,7 +66,7 @@

# %% {QUA_program}
n_avg = node.parameters.num_averages
idle_times = node.parameters.idle_times()
idle_times = node.parameters.get_idle_times_in_clock_cycles()
detuning = node.parameters.frequency_detuning_in_mhz * u.MHz
flux_point = node.parameters.flux_point_joint_or_independent

Expand Down Expand Up @@ -169,7 +169,7 @@

# %% {Data_analysis}
fits = fit_frequency_detuning_and_t2_decay(ds, qubits, node.parameters)
node.results["fit_results"] = fits
node.results["fit_results"] = {k: asdict(v) for k, v in fits.items()}

for fit in fits.values():
fit.log_frequency_offset()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

__all__ = ["QuAM", "FEMQuAM", "OPXPlusQuAM"]

from ..experiments.node_parameters import QubitsExperimentNodeParameters
from ..experiments.node_parameters import QubitsExperimentNodeParameters, MultiplexableNodeParameters


@quam_dataclass
Expand Down Expand Up @@ -207,18 +207,27 @@ def calibrate_octave_ports(self, QM: QuantumMachine) -> None:
print(f"No calibration elements found for {name}. Skipping calibration.")


def get_qubits_used_in_node(self, node: QubitExperimentNodeParameters) -> Sequence[Transmon]:
if node.parameters.qubits is None or node.parameters.qubits == "":
def get_qubits_used_in_node(self, node_parameters: QubitsExperimentNodeParameters) -> Sequence[Transmon]:
if node_parameters.qubits is None or node_parameters.qubits == "":
qubits = self.active_qubits
else:
qubits = [self.qubits[q] for q in node.parameters.qubits]
qubits = [self.qubits[q] for q in node_parameters.qubits]

return BatchableList(qubits, node.multiplexed)
return make_batchable_list(qubits, node_parameters)

def get_resonators_used_in_node(self, node: QubitExperimentNodeParameters) -> Sequence[ReadoutResonator]:
resonators = [qubit.resonator for qubit in self.get_qubits_used_in_node(node)]
def get_resonators_used_in_node(self, node_parameters: QubitsExperimentNodeParameters) -> Sequence[ReadoutResonator]:
resonators = [qubit.resonator for qubit in self.get_qubits_used_in_node(node_parameters)]

return make_batchable_list(resonators, node_parameters)

def make_batchable_list(items, node_parameters: QubitsExperimentNodeParameters) -> BatchableList:
if isinstance(node_parameters, MultiplexableNodeParameters):
multiplexed = node_parameters.multiplexed
else:
multiplexed = False

return BatchableList(items, multiplexed)

return BatchableList(resonators, node.multiplexed)

@quam_dataclass
class FEMQuAM(QuAM):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
from dataclasses import dataclass
from typing import List, Optional, Tuple
from dataclasses import dataclass, asdict
from typing import List, Optional

import numpy as np
import xarray as xr
Expand All @@ -18,7 +18,7 @@ class RamseyFit:
decay_error: float

qubit_name: Optional[str] = ""
raw_fit_results: Optional[xr.DataArray] = None
raw_fit_results: Optional[xr.Dataset] = None

def log_frequency_offset(self, logger=None):
if logger is None:
Expand Down Expand Up @@ -55,7 +55,7 @@ def fit_frequency_detuning_and_t2_decay(ds: xr.Dataset, qubits: List[Transmon],
freq_offset=1e9 * freq_offset.loc[q.name].values,
decay=decay.loc[q.name].values,
decay_error=decay_error.loc[q.name].values,
raw_fit_results=fit
raw_fit_results=fit.to_dataset(name="fit")
)

for q in qubits
Expand Down Expand Up @@ -131,7 +131,7 @@ def calculate_fit_results(frequency, tau, tau_error, fit, detuning):
within_detuning = (1e9 * frequency < 2 * detuning).mean(dim="sign") == 1
positive_shift = frequency.sel(sign=1) > frequency.sel(sign=-1)
freq_offset = (
within_detuning * (frequency * fit.detuning_sign).mean(dim="sign")
within_detuning * (frequency * fit.sign).mean(dim="sign")
+ ~within_detuning * positive_shift * frequency.mean(dim="sign")
- ~within_detuning * ~positive_shift * frequency.mean(dim="sign")
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import numpy as np
from qualibrate import NodeParameters
from qualibrate.parameters import RunnableParameters

from quam_libs.experiments.node_parameters import (
QubitsExperimentNodeParameters,
Expand All @@ -13,15 +14,7 @@
)


class Parameters(
NodeParameters,
QubitsExperimentNodeParameters,
SimulatableNodeParameters,
FluxControlledNodeParameters,
MultiplexableNodeParameters,
DataLoadableNodeParameters,
QmSessionNodeParameters
):
class RamseyParameters(RunnableParameters):
num_averages: int = 100
frequency_detuning_in_mhz: float = 1.0
min_wait_time_in_ns: int = 16
Expand All @@ -30,6 +23,17 @@ class Parameters(
log_or_linear_sweep: Literal["log", "linear"] = "log"
use_state_discrimination: bool = False

class Parameters(
NodeParameters,
SimulatableNodeParameters,
DataLoadableNodeParameters,
QmSessionNodeParameters,
RamseyParameters,
FluxControlledNodeParameters,
MultiplexableNodeParameters,
QubitsExperimentNodeParameters,
):

def get_idle_times_in_clock_cycles(self) -> np.ndarray:
"""
Get the idle-times sweep axis according to the sweep type.
Expand All @@ -38,9 +42,9 @@ def get_idle_times_in_clock_cycles(self) -> np.ndarray:
The minimum is 4 clock cycles.
"""
if self.log_or_linear_sweep == "linear":
idle_times = self._get_idle_times_linear_sweep()
idle_times = self._get_idle_times_linear_sweep_in_clock_cycles()
elif self.log_or_linear_sweep == "log":
idle_times = self._get_idle_times_log_sweep()
idle_times = self._get_idle_times_log_sweep_in_clock_cycles()
else:
raise ValueError(f"Expected sweep type to be 'log' or 'linear', got {self.log_or_linear_sweep}")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def plot_ramseys_data_with_fit(ds: xr.Dataset, qubits: List[Transmon],
grid = QubitGrid(ds, [q.grid_location for q in qubits])

for ax, qubit in grid_iter(grid):
plot_ramsey_data_with_fit(ax, ds, qubit, node_parameters, fits[qubit.name])
plot_ramsey_data_with_fit(ax, ds, qubit, node_parameters, fits[qubit["qubit"]])

grid.fig.suptitle("Ramsey: I vs. idle time")

Expand All @@ -42,7 +42,7 @@ def plot_ramsey_data_with_fit(ax, ds, qubit, node_parameters, fit):
plot_state(ax, ds, qubit, fitted_ramsey_data)
ax.set_ylabel("State")
else:
plot_trans_amplitude(ax, ds, qubit, fitted_ramsey_data)
plot_transmission_amplitude(ax, ds, qubit, fitted_ramsey_data)
ax.set_ylabel("Trans. amp. I [mV]")

ax.set_xlabel("Idle time [ns]")
Expand All @@ -59,20 +59,20 @@ def plot_state(ax, ds, qubit, fitted):
ds.sel(sign=-1).loc[qubit].state.plot(
ax=ax, x="time", c="C1", marker=".", ms=5.0, ls="", label="$\Delta$ = -"
)
ax.plot(ds.time, fitted.loc[qubit].sel(sign=1), c="C0", ls="-", lw=1)
ax.plot(ds.time, fitted.loc[qubit].sel(sign=-1), c="C1", ls="-", lw=1)
ax.plot(ds.time, fitted.fit.loc[qubit].sel(sign=1), c="C0", ls="-", lw=1)
ax.plot(ds.time, fitted.fit.loc[qubit].sel(sign=-1), c="C1", ls="-", lw=1)


def plot_trans_amplitude(ax, ds, qubit, fitted):
def plot_transmission_amplitude(ax, ds, qubit, fitted):
"""Plot transmission amplitude for a qubit."""
(ds.sel(sign=1).loc[qubit].I * 1e3).plot(
ax=ax, x="time", c="C0", marker=".", ms=5.0, ls="", label="$\Delta$ = +"
)
(ds.sel(sign=-1).loc[qubit].I * 1e3).plot(
ax=ax, x="time", c="C1", marker=".", ms=5.0, ls="", label="$\Delta$ = -"
)
ax.plot(ds.time, 1e3 * fitted.loc[qubit].sel(sign=1), c="C0", ls="-", lw=1)
ax.plot(ds.time, 1e3 * fitted.loc[qubit].sel(sign=-1), c="C1", ls="-", lw=1)
ax.plot(ds.time, 1e3 * fitted.fit.loc[qubit].sel(sign=1), c="C0", ls="-", lw=1)
ax.plot(ds.time, 1e3 * fitted.fit.loc[qubit].sel(sign=-1), c="C1", ls="-", lw=1)


def add_fit_text(ax, fit):
Expand Down

0 comments on commit 1e1d682

Please sign in to comment.