Skip to content

Commit

Permalink
Merge pull request #459 from qiboteam/sweeper-types
Browse files Browse the repository at this point in the history
  • Loading branch information
rodolfocarobene committed Jun 5, 2023
2 parents 4767ca5 + 54c0476 commit e870c28
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 15 deletions.
21 changes: 9 additions & 12 deletions src/qibolab/instruments/rfsoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from qibolab.platform import Qubit
from qibolab.pulses import Pulse, PulseSequence, PulseShape, PulseType
from qibolab.result import IntegratedResults, SampleResults
from qibolab.sweeper import Parameter, Sweeper
from qibolab.sweeper import Parameter, Sweeper, SweeperType

HZ_TO_MHZ = 1e-6
NS_TO_US = 1e-3
Expand Down Expand Up @@ -100,8 +100,10 @@ def convert_sweep(sweeper: Sweeper, sequence: PulseSequence, qubits: Dict[int, Q
parameters.append(rfsoc.Parameter.BIAS)
indexes.append(list(qubits.values()).index(qubit))

starts.append(sweeper.values[0] + qubit.flux.bias)
stops.append(sweeper.values[-1] + qubit.flux.bias)
base_value = qubit.flux.bias
values = sweeper.get_values(base_value)
starts.append(values[0])
stops.append(values[-1])

if max(np.abs(starts)) > 1 or max(np.abs(stops)) > 1:
raise ValueError("Sweeper amplitude is set to reach values higher than 1")
Expand All @@ -111,15 +113,10 @@ def convert_sweep(sweeper: Sweeper, sequence: PulseSequence, qubits: Dict[int, Q

name = sweeper.parameter.name
parameters.append(getattr(rfsoc.Parameter, name.upper()))
value = getattr(pulse, name)
if sweeper.parameter in {Parameter.frequency, Parameter.relative_phase}:
starts.append(sweeper.values[0] + value)
stops.append(sweeper.values[-1] + value)
elif sweeper.parameter is Parameter.amplitude:
starts.append(sweeper.values[0] * value)
stops.append(sweeper.values[-1] * value)
else:
raise NotImplementedError(f"Sweep parameter {sweeper.parameter} not implemented")
base_value = getattr(pulse, name)
values = sweeper.get_values(base_value)
starts.append(values[0])
stops.append(values[-1])

return rfsoc.Sweeper(
parameter=parameters,
Expand Down
23 changes: 20 additions & 3 deletions src/qibolab/sweeper.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import operator
from dataclasses import dataclass
from enum import Enum, auto
from functools import partial
from typing import Optional

import numpy.typing as npt
Expand All @@ -19,6 +21,14 @@ class Parameter(Enum):
bias = auto()


class SweeperType(Enum):
"""Type of the Sweeper"""

ABSOLUTE = partial(lambda x, y=None: x)
FACTOR = operator.mul
OFFSET = operator.add


QubitParameter = {Parameter.bias, Parameter.attenuation, Parameter.gain}


Expand Down Expand Up @@ -51,17 +61,20 @@ class Sweeper:
Args:
parameter (`qibolab.sweeper.Parameter`): parameter to be swept, possible choices are frequency, attenuation, amplitude, current and gain.
values (np.ndarray): sweep range. If the parameter is `frequency` the sweep will be a shift around the readout frequency
in case of a `ReadoutPulse` or around the drive frequency for a generic `Pulse`. If the parameter is `amplitude` the range is
normalized with the current amplitude of the pulse. For other parameters the sweep will be performed directly over the range specified.
_values (np.ndarray): sweep range. If the parameter of the sweep is a pulse parameter, if the sweeper type is not ABSOLUTE, the base value
will be taken from the runcard pulse parameters. If the sweep parameter is Bias, the base value will be the sweetspot of the qubits.
pulses (list) : list of `qibolab.pulses.Pulse` to be swept (optional).
qubits (list): list of `qibolab.platforms.abstract.Qubit` to be swept (optional).
type (SweeperType): can be ABSOLUTE (the sweeper range is swept directly),
FACTOR (sweeper values are multiplied by base value), OFFSET (sweeper values are added
to base value)
"""

parameter: Parameter
values: npt.NDArray
pulses: Optional[list] = None
qubits: Optional[list] = None
type: Optional[SweeperType] = SweeperType.ABSOLUTE

def __post_init__(self):
if self.pulses is not None and self.qubits is not None:
Expand All @@ -72,3 +85,7 @@ def __post_init__(self):
raise ValueError(f"Cannot sweep {self.parameter} without specifying pulses.")
elif self.pulses is None and self.qubits is None:
raise ValueError("Cannot use a sweeper without specifying pulses or qubits.")

def get_values(self, base_value):
"""Convert sweeper values depending on the sweeper type"""
return self.type.value(self.values, base_value)

0 comments on commit e870c28

Please sign in to comment.