Skip to content

Commit

Permalink
Merge pull request #783 from qiboteam/confidence_interval
Browse files Browse the repository at this point in the history
Improving binary masks for flux fitting protocols
  • Loading branch information
andrea-pasquale authored Apr 4, 2024
2 parents 6b7b694 + 47804e1 commit 8877c47
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -196,18 +196,7 @@ def _fit(data: QubitFluxData) -> QubitFluxResults:
frequencies = qubit_data.freq
signal = qubit_data.signal

if data.resonator_type == "3D":
frequencies, biases = utils.extract_min_feature(
frequencies,
biases,
signal,
)
else:
frequencies, biases = utils.extract_max_feature(
frequencies,
biases,
signal,
)
frequencies, biases = utils.extract_feature(frequencies, biases, signal, "max")

try:
popt = curve_fit(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,18 +317,7 @@ def _fit(data: ResonatorFluxData) -> ResonatorFluxResults:
frequencies = qubit_data.freq
signal = qubit_data.signal

if data.resonator_type == "3D":
frequencies, biases = utils.extract_max_feature(
frequencies,
biases,
signal,
)
else:
frequencies, biases = utils.extract_min_feature(
frequencies,
biases,
signal,
)
frequencies, biases = utils.extract_feature(frequencies, biases, signal, "min")

try:
popt = curve_fit(
Expand Down
44 changes: 30 additions & 14 deletions src/qibocal/protocols/characterization/flux_dependence/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

from ..utils import HZ_TO_GHZ

CONFIDENCE_INTERVAL_FIRST_MASK = 99
"""Confidence interval used to mask flux data."""
CONFIDENCE_INTERVAL_SECOND_MASK = 70
"""Confidence interval used to clean outliers."""


def is_crosstalk(data):
"""Check if keys are tuple which corresponds to crosstalk data structure."""
Expand Down Expand Up @@ -231,22 +236,33 @@ def transmon_readout_frequency(x, w_max, d, element, offset, resonator_freq, g):
)


def extract_min_feature(freq, bias, signal, threshold=1.5):
"""Extract min feature using SNR."""
mean_signal = np.mean(signal)
std_signal = np.std(signal)
snr_map = (signal - mean_signal) / std_signal
binary_mask = snr_map < -threshold
return freq[binary_mask], bias[binary_mask]
def extract_feature(freq: np.ndarray, bias: np.ndarray, signal: np.ndarray, feat: str):
"""Extract feature using confidence intervals.
A first mask is construct by looking at 99% confidence interval for each bias bin.
A second mask is applied by looking at 70% confidence interval to remove outliers.
"""

def extract_max_feature(freq, bias, signal, threshold=1.5):
"""Extract max feature using SNR."""
mean_signal = np.mean(signal)
std_signal = np.std(signal)
snr_map = (signal - mean_signal) / std_signal
binary_mask = snr_map > threshold
return freq[binary_mask], bias[binary_mask]
masks = []
for bias_bin in np.unique(bias):
signal_fixed_bias = signal[bias == bias_bin]
min, max = np.percentile(
signal_fixed_bias,
[100 - CONFIDENCE_INTERVAL_FIRST_MASK, CONFIDENCE_INTERVAL_FIRST_MASK],
)
masks.append(
signal_fixed_bias < min if feat == "min" else signal_fixed_bias > max
)

first_mask = np.vstack(masks).ravel()
min, max = np.percentile(
signal[first_mask],
[100 - CONFIDENCE_INTERVAL_SECOND_MASK, CONFIDENCE_INTERVAL_SECOND_MASK],
)
second_mask = (
signal[first_mask] < max if feat == "min" else signal[first_mask] > min
)
return freq[first_mask][second_mask], bias[first_mask][second_mask]


def qubit_flux_dependence_fit_bounds(qubit_frequency: float, bias: np.array):
Expand Down

0 comments on commit 8877c47

Please sign in to comment.