Skip to content

Commit

Permalink
feat: Enhance Experiment class with customizable amplitude and durati…
Browse files Browse the repository at this point in the history
…on fitting options; add z-values support for signal processing
  • Loading branch information
Akinori Machino committed Dec 29, 2024
1 parent 8eacc65 commit 5efe197
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/qubex/analysis/fitting.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ def fit_polynomial(
try:
root = roots_in_range[np.argmin(np.abs(roots_in_range))]
except ValueError:
print(f"No real root in the range for {target}.")
print(f"No root found in the range ({np.min(x)}, {np.max(x)}).")
root = np.nan

fig = go.Figure()
Expand Down
2 changes: 1 addition & 1 deletion src/qubex/analysis/visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ def __init__(
showlegend=True,
marker=dict(
symbol="circle",
size=30,
size=24,
color=f"rgba{color}",
),
textfont=dict(
Expand Down
85 changes: 80 additions & 5 deletions src/qubex/experiment/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -6688,7 +6688,9 @@ def calibrate_zx90_by_amplitude(
control_qubit: str,
target_qubit: str,
duration: float = 100,
amplitude_range: ArrayLike = np.linspace(0.0, 0.5, 21),
amplitude_range: ArrayLike = np.linspace(0.0, 1.0, 51),
degree: int = 3,
use_zvalues: bool = False,
shots: int = DEFAULT_SHOTS,
interval: int = DEFAULT_INTERVAL,
plot: bool = True,
Expand Down Expand Up @@ -6722,14 +6724,87 @@ def calibrate_zx90_by_amplitude(
plot=plot,
)

data = sweep_result.data[target_qubit].normalized
if use_zvalues:
signal = sweep_result.data[target_qubit].zvalues
else:
signal = sweep_result.data[target_qubit].normalized

fit_result = fitting.fit_polynomial(
target=target_qubit,
x=amplitude_range,
y=data,
degree=3,
y=signal,
degree=degree,
title="ZX90 calibration",
xaxis_title="Amplitude (arb. unit)",
yaxis_title="Signal",
)
return {
"amplitude_range": amplitude_range,
"signal": signal,
**fit_result,
}

def calibrate_zx90_by_duration(
self,
*,
control_qubit: str,
target_qubit: str,
amplitude: float = 1.0,
duration_range: ArrayLike = np.arange(100, 501, 10),
degree: int = 3,
use_zvalues: bool = False,
shots: int = DEFAULT_SHOTS,
interval: int = DEFAULT_INTERVAL,
plot: bool = True,
):
duration_range = np.array(duration_range)

cr_label = f"{control_qubit}-{target_qubit}"
cr_params = self._system_note.get(CR_PARAMS)[cr_label]
cr_ramptime = cr_params["ramptime"]
cr_amplitude = cr_params["cr_pulse"]["amplitude"]
cr_phase = cr_params["cr_pulse"]["phase"]
cancel_amplitude = cr_params["cancel_pulse"]["amplitude"]
cancel_phase = cr_params["cancel_pulse"]["phase"]

sweep_result = self.sweep_parameter(
lambda duration: CrossResonance(
control_qubit=control_qubit,
target_qubit=target_qubit,
cr_amplitude=amplitude,
cr_duration=duration,
cr_ramptime=cr_ramptime,
cr_phase=cr_phase,
cancel_amplitude=cancel_amplitude * amplitude / cr_amplitude,
cancel_phase=cancel_phase,
echo=True,
pi_pulse=self.pi_pulse[target_qubit],
),
sweep_range=duration_range,
shots=shots,
interval=interval,
plot=plot,
)
return fit_result

if use_zvalues:
signal = sweep_result.data[target_qubit].zvalues
else:
signal = sweep_result.data[target_qubit].normalized

fit_result = fitting.fit_polynomial(
target=target_qubit,
x=duration_range,
y=signal,
degree=degree,
title="ZX90 calibration",
xaxis_title="Duration (ns)",
yaxis_title="Signal",
)
return {
"duration_range": duration_range,
"signal": signal,
**fit_result,
}


class ExperimentUtil:
Expand Down

0 comments on commit 5efe197

Please sign in to comment.