Skip to content

Commit

Permalink
Merge pull request #413 from qiboteam/statistics
Browse files Browse the repository at this point in the history
Remove statistics
  • Loading branch information
andrea-pasquale committed Jul 7, 2023
2 parents 0e22736 + 477def4 commit d0b542e
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 132 deletions.
69 changes: 7 additions & 62 deletions src/qibocal/protocols/characterization/resonator_punchout.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from dataclasses import dataclass, field
from statistics import mode
from typing import Optional

import numpy as np
Expand All @@ -13,9 +12,8 @@
from qibolab.sweeper import Parameter, Sweeper, SweeperType

from qibocal.auto.operation import Data, Parameters, Qubits, Results, Routine
from qibocal.config import log

from .utils import GHZ_TO_HZ, HZ_TO_GHZ, V_TO_UV, norm
from .utils import GHZ_TO_HZ, HZ_TO_GHZ, V_TO_UV, fit_punchout, norm


@dataclass
Expand Down Expand Up @@ -48,14 +46,14 @@ class ResonatorPunchoutResults(Results):
metadata=dict(update="readout_frequency")
)
"""Readout frequency [GHz] for each qubit."""
readout_amplitude: dict[QubitId, float] = field(
metadata=dict(update="readout_amplitude")
)
"""Readout amplitude for each qubit."""
bare_frequency: Optional[dict[QubitId, float]] = field(
metadata=dict(update="bare_resonator_frequency")
)
"""Bare resonator frequency [GHz] for each qubit."""
readout_amplitude: dict[QubitId, float] = field(
metadata=dict(update="readout_amplitude")
)
"""Readout amplitude for each qubit."""


ResPunchoutType = np.dtype(
Expand Down Expand Up @@ -175,61 +173,7 @@ def _acquisition(
def _fit(data: ResonatorPunchoutData, fit_type="amp") -> ResonatorPunchoutResults:
"""Fit frequency and attenuation at high and low power for a given resonator."""

qubits = data.qubits

bare_freqs = {}
dressed_freqs = {}
ro_amplitudes = {}

for qubit in qubits:
qubit_data = data[qubit]
try:
n_amps = len(np.unique(qubit_data.amp))
n_freq = len(np.unique(qubit_data.freq))
for i in range(n_amps):
qubit_data.msr[i * n_freq : (i + 1) * n_freq] = norm(
qubit_data.msr[i * n_freq : (i + 1) * n_freq]
)

min_msr_indices = np.where(
qubit_data.msr == (1 if data.resonator_type == "3D" else 0)
)[0]

max_freq = np.max(qubit_data.freq[min_msr_indices])
min_freq = np.min(qubit_data.freq[min_msr_indices])
middle_freq = (max_freq + min_freq) / 2

hp_points_indices = np.where(
qubit_data.freq[min_msr_indices] < middle_freq
)[0]
lp_points_indices = np.where(
qubit_data.freq[min_msr_indices] >= middle_freq
)[0]

freq_hp = mode(qubit_data.freq[hp_points_indices])
freq_lp = mode(qubit_data.freq[lp_points_indices])

lp_max = np.max(
getattr(qubit_data, fit_type)[np.where(qubit_data.freq == freq_lp)[0]]
)

ro_amp = lp_max

except:
log.warning("resonator_punchout_fit: the fitting was not succesful")
freq_lp = 0.0
freq_hp = 0.0
ro_amp = 0.0

dressed_freqs[qubit] = freq_lp * HZ_TO_GHZ
bare_freqs[qubit] = freq_hp * HZ_TO_GHZ
ro_amplitudes[qubit] = ro_amp

return ResonatorPunchoutResults(
dressed_freqs,
ro_amplitudes,
bare_freqs,
)
return ResonatorPunchoutResults(*fit_punchout(data, fit_type))


def _plot(data: ResonatorPunchoutData, fit: ResonatorPunchoutResults, qubit):
Expand Down Expand Up @@ -257,6 +201,7 @@ def _plot(data: ResonatorPunchoutData, fit: ResonatorPunchoutResults, qubit):
qubit_data.msr[i * n_freq : (i + 1) * n_freq] = norm(
qubit_data.msr[i * n_freq : (i + 1) * n_freq]
)

fig.add_trace(
go.Heatmap(
x=frequencies,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from dataclasses import dataclass, field
from statistics import mode
from typing import Optional

import numpy as np
Expand All @@ -13,9 +12,8 @@
from qibolab.sweeper import Parameter, Sweeper, SweeperType

from qibocal.auto.operation import Data, Parameters, Qubits, Results, Routine
from qibocal.config import log

from .utils import GHZ_TO_HZ, HZ_TO_GHZ, V_TO_UV, norm
from .utils import GHZ_TO_HZ, HZ_TO_GHZ, V_TO_UV, fit_punchout, norm


@dataclass
Expand Down Expand Up @@ -46,13 +44,13 @@ class ResonatorPunchoutAttenuationResults(Results):
metadata=dict(update="readout_frequency")
)
"""Readout frequency [GHz] for each qubit."""
bare_frequency: Optional[dict[QubitId, float]] = field(
metadata=dict(update="bare_resonator_frequency")
)
readout_attenuation: dict[QubitId, int] = field(
metadata=dict(update="readout_attenuation")
)
"""Readout attenuation [dB] for each qubit."""
bare_frequency: Optional[dict[QubitId, float]] = field(
metadata=dict(update="bare_resonator_frequency")
)


ResPunchoutAttType = np.dtype(
Expand Down Expand Up @@ -164,69 +162,7 @@ def _fit(
) -> ResonatorPunchoutAttenuationResults:
"""Fit frequency and attenuation at high and low power for a given resonator."""

qubits = data.qubits

freqs_low_att = {}
freqs_high_att = {}
ro_atts = {}

for qubit in qubits:
qubit_data = data[qubit]
try:
n_att = len(np.unique(qubit_data.att))
n_freq = len(np.unique(qubit_data.freq))
for i in range(n_att):
qubit_data.msr[i * n_freq : (i + 1) * n_freq] = norm(
qubit_data.msr[i * n_freq : (i + 1) * n_freq]
)

min_msr_indices = np.where(
qubit_data.msr == (1 if data.resonator_type == "3D" else 0)
)[0]

max_freq = np.max(qubit_data.freq[min_msr_indices])
min_freq = np.min(qubit_data.freq[min_msr_indices])
middle_freq = (max_freq + min_freq) / 2

low_att_indices = np.where(qubit_data.freq[min_msr_indices] < middle_freq)[
0
]
high_att_indices = np.where(
qubit_data.freq[min_msr_indices] >= middle_freq
)[0]

freq_high_att = mode(qubit_data.freq[high_att_indices])
freq_low_att = mode(qubit_data.freq[low_att_indices])

high_att_max = np.max(
getattr(qubit_data, fit_type)[
np.where(qubit_data.freq == freq_low_att)[0]
]
)
high_att_min = np.min(
getattr(qubit_data, fit_type)[
np.where(qubit_data.freq == freq_low_att)[0]
]
)

ro_att = round((high_att_max + high_att_min) / 2)
ro_att = ro_att + 1 if ro_att % 2 == 1 else ro_att

except:
log.warning("resonator_punchout_fit: the fitting was not succesful")
freq_high_att = 0.0
freq_low_att = 0.0
ro_att = 0.0

freqs_low_att[qubit] = freq_low_att * HZ_TO_GHZ
freqs_high_att[qubit] = freq_high_att * HZ_TO_GHZ
ro_atts[qubit] = ro_att

return ResonatorPunchoutAttenuationResults(
freqs_high_att,
ro_atts,
freqs_low_att,
)
return ResonatorPunchoutAttenuationResults(*fit_punchout(data, fit_type))


def _plot(
Expand Down
72 changes: 71 additions & 1 deletion src/qibocal/protocols/characterization/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from scipy.stats import mode

from qibocal.auto.operation import Results
from qibocal.auto.operation import Data, Results
from qibocal.config import log

GHZ_TO_HZ = 1e9
Expand Down Expand Up @@ -172,3 +173,72 @@ def spectroscopy_plot(data, fit: Results, qubit):

def norm(x_mags):
return (x_mags - np.min(x_mags)) / (np.max(x_mags) - np.min(x_mags))


def fit_punchout(data: Data, fit_type: str):
"""
Punchout fitting function.
Args:
data (Data): Punchout acquisition data.
fit_type (str): Punchout type, it could be `amp` (amplitude)
or `att` (attenuation).
Return:
List of dictionaries containing the low, high amplitude
(attenuation) frequencies and the readout amplitude (attenuation)
for each qubit.
"""
qubits = data.qubits

low_freqs = {}
high_freqs = {}
ro_values = {}

for qubit in qubits:
qubit_data = data[qubit]
freqs = np.unique(qubit_data.freq)
nvalues = len(np.unique(qubit_data[fit_type]))
nfreq = len(freqs)
msrs = np.reshape(qubit_data.msr, (nvalues, nfreq))
if data.resonator_type == "3D":
peak_freqs = freqs[np.argmax(msrs, axis=1)]
else:
peak_freqs = freqs[np.argmin(msrs, axis=1)]

max_freq = np.max(peak_freqs)
min_freq = np.min(peak_freqs)
middle_freq = (max_freq + min_freq) / 2

freq_hp = peak_freqs[peak_freqs < middle_freq]
freq_lp = peak_freqs[peak_freqs >= middle_freq]

freq_hp = mode(freq_hp, keepdims=True)[0]
freq_lp = mode(freq_lp, keepdims=True)[0]

if fit_type == "amp":
if data.resonator_type == "3D":
ro_val = getattr(qubit_data, fit_type)[
np.argmax(qubit_data.msr[np.where(qubit_data.freq == freq_lp)[0]])
]
else:
ro_val = getattr(qubit_data, fit_type)[
np.argmin(qubit_data.msr[np.where(qubit_data.freq == freq_lp)[0]])
]
else:
high_att_max = np.max(
getattr(qubit_data, fit_type)[np.where(qubit_data.freq == freq_hp)[0]]
)
high_att_min = np.min(
getattr(qubit_data, fit_type)[np.where(qubit_data.freq == freq_hp)[0]]
)

ro_val = round((high_att_max + high_att_min) / 2)
ro_val = ro_val + (ro_val % 2)

low_freqs[qubit] = freq_lp.item() * HZ_TO_GHZ
high_freqs[qubit] = freq_hp[0] * HZ_TO_GHZ
ro_values[qubit] = ro_val
return [low_freqs, high_freqs, ro_values]

0 comments on commit d0b542e

Please sign in to comment.