from dataclasses import dataclass, field
from typing import Any, Dict, Optional, Type, TypeVar
[docs]
@dataclass
class IntegrationWeightMapping:
"""Mapping of demodulation weight names to integration weight set identifiers.
This class defines the naming convention for different integration weight sets
used during measurement. Each attribute maps a weight type to its identifier
in the integration weights configuration.
**Standard Weight Sets:**
- ``cos``, ``sin``, ``minus_sin``: Standard cosine/sine demodulation
- ``rotated_cos``, ``rotated_sin``, ``rotated_minus_sin``: Rotated basis demodulation
- ``opt_cos``, ``opt_sin``, ``opt_minus_sin``: Optimized weights for specific experiments
Attributes:
cos (str): Cosine weight set name (default: "cosine_weights")
sin (str): Sine weight set name (default: "sine_weights")
minus_sin (str): Negative sine weight set name (default: "minus_sine_weights")
rotated_cos (str): Rotated cosine weight set (default: "rotated_cosine_weights")
rotated_sin (str): Rotated sine weight set (default: "rotated_sine_weights")
rotated_minus_sin (str): Rotated negative sine weight set (default: "rotated_minus_sine_weights")
opt_cos (str): Optimized cosine weight set (default: "opt_cosine_weights")
opt_sin (str): Optimized sine weight set (default: "opt_sine_weights")
opt_minus_sin (str): Optimized negative sine weight set (default: "opt_minus_sine_weights")
"""
cos: str = "cosine_weights"
sin: str = "sine_weights"
minus_sin: str = "minus_sine_weights"
rotated_cos: str = "rotated_cosine_weights"
rotated_sin: str = "rotated_sine_weights"
rotated_minus_sin: str = "rotated_minus_sine_weights"
opt_cos: str = "opt_cosine_weights"
opt_sin: str = "opt_sine_weights"
opt_minus_sin: str = "opt_minus_sine_weights"
[docs]
def to_dict(self) -> Dict[str, str]:
return {
"cos": self.cos,
"sin": self.sin,
"minus_sin": self.minus_sin,
"rotated_cos": self.rotated_cos,
"rotated_sin": self.rotated_sin,
"rotated_minus_sin": self.rotated_minus_sin,
"opt_cos": self.opt_cos,
"opt_sin": self.opt_sin,
"opt_minus_sin": self.opt_minus_sin,
}
[docs]
def to_opx_config(self) -> Dict[str, str]:
return self.to_dict()
[docs]
@classmethod
def from_dict(cls, d: Dict[str, str]) -> "IntegrationWeightMapping":
if not isinstance(d, dict):
return cls()
return cls(
cos=d.get("cos", "cosine_weights"),
sin=d.get("sin", "sine_weights"),
minus_sin=d.get("minus_sin", "minus_sine_weights"),
rotated_cos=d.get("rotated_cos", "rotated_cosine_weights"),
rotated_sin=d.get("rotated_sin", "rotated_sine_weights"),
rotated_minus_sin=d.get("rotated_minus_sin", "rotated_minus_sine_weights"),
opt_cos=d.get("opt_cos", "opt_cosine_weights"),
opt_sin=d.get("opt_sin", "opt_sine_weights"),
opt_minus_sin=d.get("opt_minus_sin", "opt_minus_sine_weights"),
)
def __repr__(self) -> str:
return f"<IntegrationWeightMapping cos={self.cos} sin={self.sin} opt_cos={self.opt_cos}>"
[docs]
@dataclass
class IntegrationWeight:
"""Configuration for a single integration weight set for demodulation.
Defines how to demodulate and integrate an acquired signal. During measurement,
the acquired signal is multiplied by cosine and sine reference signals (weighted
by these parameters) and integrated over the measurement duration to extract
in-phase (I) and quadrature (Q) components.
Attributes:
length (int): Integration window duration in nanoseconds (default: 0).
Typically matches the measurement pulse length.
real_weight (float): Weight factor for cosine (I) component (default: 1.0).
Scales the in-phase signal amplitude.
imag_weight (float): Weight factor for sine (Q) component (default: 0.0).
Scales the quadrature signal amplitude.
"""
length: int = 0 # in nanoseconds
real_weight: float = 1
imag_weight: float = 0
[docs]
def to_opx_config(self) -> Dict[str, Any]:
return {
"cosine": [(self.real_weight, self.length)],
"sine": [(self.imag_weight, self.length)],
}
[docs]
def to_dict(self) -> Dict[str, Any]:
return {
"length": self.length,
"real_weight": self.real_weight,
"imag_weight": self.imag_weight,
}
[docs]
@classmethod
def from_dict(cls, d: Dict[str, Any]) -> "IntegrationWeight":
return cls(
length=d.get("length", 0),
real_weight=d.get("real_weight", 1),
imag_weight=d.get("imag_weight", 0),
)
def __repr__(self) -> str:
return f"<IntegrationWeight len={self.length} real={self.real_weight} imag={self.imag_weight}>"
[docs]
@dataclass
class IntegrationWeights:
"""Container for all integration weight sets used in the experiment.
Manages a collection of named integration weight configurations. During
measurement, these weights are applied to demodulate and integrate the
acquired signals, extracting I/Q components for data analysis.
Attributes:
weights (dict[str, IntegrationWeight]): Mapping of weight set names
to their configurations (default: empty).
"""
weights: dict[str, IntegrationWeight] = field(default_factory=dict)
[docs]
def add_weight(
self, name: str, length: int, real_weight: float = 1, imag_weight: float = 0
) -> None:
"""
Add an integration weight set to the configuration.
"""
self.weights[name] = IntegrationWeight(
length=length, real_weight=real_weight, imag_weight=imag_weight
)
[docs]
def to_dict(self) -> Dict[str, Any]:
return {name: weight.to_dict() for name, weight in self.weights.items()}
[docs]
def to_opx_config(self) -> Dict[str, Any]:
return {name: weight.to_opx_config() for name, weight in self.weights.items()}
[docs]
@classmethod
def from_dict(cls, d: Dict[str, Any]) -> "IntegrationWeights":
iw = cls()
for name, wd in (d or {}).items():
if isinstance(wd, dict):
iw.weights[name] = IntegrationWeight.from_dict(wd)
return iw
def __repr__(self) -> str:
return f"<IntegrationWeights sets={len(self.weights)}>"