Skip to content

Coupler Ramsey - #1510

Draft
sorewachigauyo wants to merge 2 commits into
mainfrom
coupler-ramsey
Draft

Coupler Ramsey#1510
sorewachigauyo wants to merge 2 commits into
mainfrom
coupler-ramsey

Conversation

@sorewachigauyo

@sorewachigauyo sorewachigauyo commented May 22, 2026

Copy link
Copy Markdown
Contributor

For a generic two qubit coupled system, under the JC model, there should also be a cross-Kerr shift $\chi \propto \frac{g_\text{eff}^2}{\Delta}$, where the effective coupling is dependent on both the static and coupler-mediated coupling. This shift affects the simultaneous use of both qubits due to the frequency shift incurred when conducting parallel single qubit pulses.

After tuning the coupler to the sweetspot, there may be later drifts of the coupler bias resulting in $\chi$ becoming more prominent in simultaneous qubit usage. Hence, we want a quick routine to move the coupler back to the idling spot.

The goal of this experiment is to simply tune the coupler around its current offset to minimize such effects. By performing a ZZ Ramsey experiment, we are able to measure $\chi$. Here, we modify the ZZ Ramsey experiment by inserting a coupler pulse to temporarily adjust $\chi$ during the free evolution time. The amplitude of the coupler pulse and duration of both the coupler pulse and free evolution time are swept to find the point at which $\chi \approx 0$

image

We initially tried to adjust the offset of the channel itself in our coupler tuning. However, this also affected the dressed frequency of the qubits and led to inaccurate idling positions, which then required single qubit calibration for each offset. Hopefully, this procedure removes the need for that.

Results

image

and corresponding Ramsey-ZZ

image

Though, if the qubit frequency is not properly calibrated prior to this experiment, $\chi$ will just compensate for the detuning of the $\pi/2$ pulse and lead to an incorrect result.

Design

We came up with this protocol earlier after the aforementioned problems of calibrating the single qubit parameters for each coupler offset, but were not sure of how to structure the fitting/plotting for Qibocal, so we took it from PR #1504, which operates on the same principle essentially.

We tried to use the mean instead of the variance, but both led to similar results generally
WhatsApp Image 2026-05-19 at 10 50 05

QPU Data
coupler_ramsey.tar.gz

TODO:

  • Fix plot annotation
  • Add tests
  • Update coupler offset
  • Check if new coupler position is better than previous
  • Refactor result handling

@codecov

codecov Bot commented May 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 39.21569% with 62 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.39%. Comparing base (85a7b6f) to head (5a59dc3).

Files with missing lines Patch % Lines
...ls/two_qubit_interaction/chevron/coupler_ramsey.py 37.37% 62 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1510      +/-   ##
==========================================
- Coverage   91.84%   91.39%   -0.46%     
==========================================
  Files         147      148       +1     
  Lines       11635    11735     +100     
==========================================
+ Hits        10686    10725      +39     
- Misses        949     1010      +61     
Flag Coverage Δ
unittests 91.39% <39.21%> (-0.46%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...ibocal/protocols/two_qubit_interaction/__init__.py 100.00% <100.00%> (ø)
...rotocols/two_qubit_interaction/chevron/__init__.py 100.00% <100.00%> (ø)
...ls/two_qubit_interaction/chevron/coupler_ramsey.py 37.37% <37.37%> (ø)

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@alecandido

alecandido commented May 28, 2026

Copy link
Copy Markdown
Member

Thanks @sorewachigauyo for the clean PR and explanation

On the one side it is great to have this contribution, as we are also moving in the same direction. The unfortunate part is that also @lballerio was working on something similar, and he implemented essentially the same protocol in April, taking it from https://arxiv.org/abs/2005.08863

image

You could not know it, nor make any use of it, since it was never published (yet). In a sense, it is still good that you worked on it, since one of the main blocking issues on our side was the lack of a testing platform (which we'll soon be solved, hopefully - but we're still waiting for it). You may have saved the implementation, but it is just an iteration of the Ramsey ZZ experiment. So, fine as it is.

In this sense, @lballerio is accumulating some experience in optimizing these protocols. Both in terms of code reuse and fitting.
For the plotting, your proposal is already good enough. We will brainstorm anyhow, considering whether we could improve it or not - but I do not expect any drastic change.

Instead, fitting is always the complex part. Your approach is not terrible, since it is already locating the area of interest. But, at first sight, it does not seem necessarily the most accurate (since sometimes is locating the position on a side of the band), and possibly is not consuming the physics insight associated to the Ramsey experiment.
Still, it is performing quite well in well-behaving cases, and reasonably noise-resilient in a range of scenarios. Therefore, I would be inclined to merge it as it is (fit-wise), and iterate in separate PRs.

Data query

Do you have any understanding regarding why, in some cases, the images seem to be "broken"?

image

Since they "resume" after a certain duration (which would make no sense for a single experiment - i.e. a unique evolution), it seems like something is happening to your qubits while performing that portion of the sweep. But it looks like a coherent effect (e.g. as if it shifted in frequency for some time, before getting back to the original state)

Comment on lines +167 to +173
for amp in amplitudes:
mask = pair_data["amplitude"] == amp
probs = pair_data["prob"][mask]
variances.append(float(np.var(probs)))

best_idx = int(np.argmin(variances))
best_amp = float(amplitudes[best_idx])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say that there is no need to go through each line separately, masking the 2D array in this way.
Instead, you could just use the axis= argument of np.var(), to compute the variance along the relevant axis.

In principle, this vectorization could be applied also to the pairs loop, since your array is regular over all the dimensions (pair, amplitude, duration). And you could just apply the np.var() along the last axis, to obtain a 2D array of variances, with shape (pairs, amplitude). To which applying the np.argmin() along the amplitude axis, and then access the values on the amplitudes array.
But it would require stacking the pairs arrays (which right now are shipped separately).

In any case, you could try yourself, or I will make a code proposal testing on the data you uploaded.
In general, we have plans to incrementally improve the data handling as regular arrays soon, gradually reviewing al protocols.

@sorewachigauyo

Copy link
Copy Markdown
Contributor Author

Data query

Do you have any understanding regarding why, in some cases, the images seem to be "broken"?

image

Since they "resume" after a certain duration (which would make no sense for a single experiment - i.e. a unique evolution), it seems like something is happening to your qubits while performing that portion of the sweep. But it looks like a coherent effect (e.g. as if it shifted in frequency for some time, before getting back to the original state)

My guess would be some uncorrelated hysteresis in the flux lines. For the current keysight driver, the offset is not exactly a true offset but only held on during the pulse sequence. Its kept high during the hardware sweepers, but between software sweepers it goes off and back on. Here, the coupler amplitude sweep (x-axis) is hardware swept but the duration (y-axis) is software swept, so the discontinuity mainly between software sweeps supports that. This will be fixed with qiboteam/qibolab#1462.

By uncorrelated I mean that we did all 30 couplers with next-next nearest neighbouring pairs in 8-ish batches and we didn't observe correlation in the flux jumps between pairs.

We'll repeat it when the offset gets patched and see if it reappears.

@alecandido

Copy link
Copy Markdown
Member

Thanks for the explanation @sorewachigauyo.

However, I'm not fully convinced: if it is software swept, this is potentially happening for each line. So, this is explaining why the patches are horizontal, and not vertical. But not entirely why there are patches.

I'm not saying that it is fully unrelated, and it may actually disappear with the fix you mention.
But, to actually produce the patches, I guess there should be something retaining memory of the switching process. It could be the magnetic field itself, with some hysteretical process. But this has to happen through the material, and in a way which is only occasionally triggered.

In any case, I'm just curious, and speculating about the system. It is perfectly fine not to have a full explanation. But it is an interesting phenomenon, so it just triggered my interest :)
Let's simply monitor and see whether it disappear after the fix!

@lballerio lballerio left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for me is quite good, my plans are to test it on our qpus, I'll keep you updated on that

@alecandido alecandido linked an issue Jun 18, 2026 that may be closed by this pull request
@alecandido
alecandido changed the base branch from coupler-protocols to main July 3, 2026 14:41
@alecandido

Copy link
Copy Markdown
Member

Hi @sorewachigauyo!

We are now closer and closer to be able to properly test this one. Then, we decided that this is more fundamental than the protocols in #1160, and we'd like to merge it first. Thus, I rebased on main.

Thank you again for the contribution :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Couplers: nulling point

3 participants