Skip to content

Commit

Permalink
Merge pull request #70 from qua-platform/feat/drag-cosine-pulse
Browse files Browse the repository at this point in the history
feat: Add DragCosinePulse and rename DragPulse to DragGaussianPulse
  • Loading branch information
nulinspiratie authored Aug 23, 2024
2 parents 261a23c + 6062e01 commit 6b0f3fb
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
- Added `Channel.update_frequency` to allow for updating the frequency of a channel
- Added `OctaveOld.connectivity` as it was needed for (deprecated) compatibility with multiple OPX instruments
- Added ports for different hardware. As a consequence we now also support the LF-FEM and MW-FEM
- Added `DragCosinePulse`.

### Changed
- Allow `QuamBase.get_reference(attr)` to return a reference of one of its attributes
- Octave RF input 2 has `LO_source = "external"` by default
- Rename `DragPulse -> DragGaussianPulse`, deprecate `DragPulse`

### Fixed
- Fix quam object instantiation error when a parameter type uses pipe operator
Expand Down
67 changes: 66 additions & 1 deletion quam/components/pulses.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"Pulse",
"BaseReadoutPulse",
"ReadoutPulse",
"DragGaussianPulse",
"DragCosinePulse",
"DragPulse",
"SquarePulse",
"SquareReadoutPulse",
Expand Down Expand Up @@ -396,7 +398,7 @@ def integration_weights_function(self) -> List[Tuple[Union[complex, float], int]


@quam_dataclass
class DragPulse(Pulse):
class DragGaussianPulse(Pulse):
"""Gaussian-based DRAG pulse that compensate for the leakage and AC stark shift.
These DRAG waveforms has been implemented following the next Refs.:
Expand Down Expand Up @@ -431,6 +433,9 @@ class DragPulse(Pulse):
detuning: float = 0.0
subtracted: bool = True

def __post_init__(self) -> None:
return super().__post_init__()

def waveform_function(self):
from qualang_tools.config.waveform_tools import drag_gaussian_pulse_waveforms

Expand All @@ -451,6 +456,66 @@ def waveform_function(self):
return I_rot + 1.0j * Q_rot


@quam_dataclass
class DragPulse(DragGaussianPulse):
def __post_init__(self) -> None:
warnings.warn(
"DragPulse is deprecated. Use DragGaussianPulse instead.",
DeprecationWarning,
)
return super().__post_init__()


@quam_dataclass
class DragCosinePulse(Pulse):
"""Cosine based DRAG pulse that compensate for the leakage and AC stark shift.
These DRAG waveforms has been implemented following the next Refs.:
Chen et al. PRL, 116, 020501 (2016)
https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.116.020501
and Chen's thesis
https://web.physics.ucsb.edu/~martinisgroup/theses/Chen2018.pdf
Args:
length (int): The pulse length in ns.
axis_angle (float, optional): IQ axis angle of the output pulse in radians.
If None (default), the pulse is meant for a single channel or the I port
of an IQ channel
If not None, the pulse is meant for an IQ channel (0 is X, pi/2 is Y).
amplitude (float): The amplitude in volts.
alpha (float): The DRAG coefficient.
anharmonicity (float): f_21 - f_10 - The differences in energy between the 2-1
and the 1-0 energy levels, in Hz.
detuning (float): The frequency shift to correct for AC stark shift, in Hz.
"""

axis_angle: float
amplitude: float
alpha: float
anharmonicity: float
detuning: float = 0.0

def __post_init__(self) -> None:
return super().__post_init__()

def waveform_function(self):
from qualang_tools.config.waveform_tools import drag_cosine_pulse_waveforms

I, Q = drag_cosine_pulse_waveforms(
amplitude=self.amplitude,
length=self.length,
alpha=self.alpha,
anharmonicity=self.anharmonicity,
detuning=self.detuning,
)
I, Q = np.array(I), np.array(Q)

I_rot = I * np.cos(self.axis_angle) - Q * np.sin(self.axis_angle)
Q_rot = I * np.sin(self.axis_angle) + Q * np.cos(self.axis_angle)

return I_rot + 1.0j * Q_rot


@quam_dataclass
class SquarePulse(Pulse):
"""Square pulse QuAM component.
Expand Down
38 changes: 36 additions & 2 deletions tests/components/pulses/test_pulses.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
from quam.utils.dataclass import get_dataclass_attr_annotations


def test_drag_pulse():
drag_pulse = pulses.DragPulse(
def test_drag_gaussian_pulse():
drag_pulse = pulses.DragGaussianPulse(
amplitude=1, sigma=4, alpha=2, anharmonicity=200e6, length=20, axis_angle=0
)

Expand All @@ -33,6 +33,30 @@ def test_drag_pulse():
assert np.iscomplexobj(waveform)


def test_drag_cosine_pulse():
drag_pulse = pulses.DragCosinePulse(
amplitude=1, alpha=2, anharmonicity=200e6, length=20, axis_angle=0
)

assert drag_pulse.operation == "control"
assert drag_pulse.length == 20
assert drag_pulse.get_attrs() == {
"id": None,
"length": 20,
"axis_angle": 0.0,
"digital_marker": None,
"amplitude": 1,
"alpha": 2,
"anharmonicity": 200000000.0,
"detuning": 0.0,
}

waveform = drag_pulse.calculate_waveform()
assert len(waveform) == 20
assert isinstance(waveform, np.ndarray)
assert np.iscomplexobj(waveform)


def test_channel():
channel = Channel()
d = channel.to_dict()
Expand Down Expand Up @@ -192,3 +216,13 @@ def test_pulse_attr_annotations():
attr_annotations = get_dataclass_attr_annotations(pulses.SquareReadoutPulse)

assert list(attr_annotations["required"]) == ["length", "amplitude"]


def test_deprecated_drag_pulse():
with pytest.warns(
DeprecationWarning,
match="DragPulse is deprecated. Use DragGaussianPulse instead.",
):
pulses.DragPulse(
axis_angle=0, amplitude=1, sigma=4, alpha=2, anharmonicity=200e6, length=20
)

0 comments on commit 6b0f3fb

Please sign in to comment.