Source code for WaveformConstructor.composit
from .waveform import CarrierFlopping
from .series import WaveformSeries
import numpy as np
from abc import ABC, abstractmethod
[docs]class CompositePulseCarrierFlopping(ABC):
"""Abstract class for composite pulse carrier flopping waveform."""
[docs] @abstractmethod
def waveform_series(self, angle: float, phase: float) -> WaveformSeries:
"""Return the waveform series for the given angle and phase
Parameters
----------
angle: float
Angle of the rotation
phase: float
Phase of the rotation
"""
pass
[docs]class SinglePulseCarrierFlopping(CompositePulseCarrierFlopping):
"""Single pulse carrier flopping waveform
Parameters
----------
amp: float
Amplitude of the waveform
freq: float
Frequency of the waveform
pi_time: float
Time of the pi pulse corresponding to the amplitude and frequency
"""
# https://www.sciencedirect.com/science/article/pii/S1064185884711594
def __init__(self, amp: float, freq: float, pi_time: float):
self.amp = amp
self.freq = freq
self.pi_time = pi_time
[docs] def waveform_series(self, angle, phase) -> WaveformSeries:
if angle < 0:
angle = -angle
phase = phase + np.pi
return WaveformSeries(
[angle / np.pi * self.pi_time],
[
CarrierFlopping(self.amp, phase, self.freq)
]
)
[docs]class XSinglePulse(SinglePulseCarrierFlopping):
[docs] def waveform_series(self, angle: float) -> WaveformSeries:
"""Return the waveform series for the given angle and phase
Parameters
----------
angle: float
Angle of the rotation
phase: float
Phase of the rotation
Returns
-------
WaveformSeries
The waveform series for the given angle and phase
"""
return super().waveform_series(angle, 0)
[docs]class YSinglePulse(SinglePulseCarrierFlopping):
[docs] def waveform_series(self, angle: float) -> WaveformSeries:
"""Return the waveform series for the given angle and phase
Parameters
----------
angle: float
Angle of the rotation
phase: float
Phase of the rotation
Returns
-------
WaveformSeries
The waveform series for the given angle and phase
"""
return super().waveform_series(angle, np.pi/2)
[docs]class BB1CarrierFlopping(CompositePulseCarrierFlopping):
"""Composite pulses for carrier flopping using BB1 protocol.
Parameters
----------
amp: float
Amplitude of the waveform
freq: float
Frequency of the waveform
pi_time: float
Time of the pi pulse corresponding to the amplitude and frequency
Notes
-----
Ref: https://www.sciencedirect.com/science/article/pii/S1064185884711594
"""
def __init__(self, amp, freq, pi_time):
self.amp = amp
self.freq = freq
self.pi_time = pi_time
[docs] def waveform_series(self, angle, phase) -> WaveformSeries:
if angle < 0:
angle = -angle
phase = phase + np.pi
phi = np.arccos(-angle/4/np.pi)
return WaveformSeries(
[self.pi_time, self.pi_time * 2, self.pi_time, angle/np.pi * self.pi_time],
[
CarrierFlopping(self.amp, phase + phi, self.freq),
CarrierFlopping(self.amp, phase + 3 * phi, self.freq),
CarrierFlopping(self.amp, phase + phi, self.freq),
CarrierFlopping(self.amp, phase, self.freq)
]
)
[docs]class YBB1(BB1CarrierFlopping):
[docs] def waveform_series(self, angle) -> WaveformSeries:
return super().waveform_series(angle, np.pi/2)
[docs]class BB2CarrierFlopping(CompositePulseCarrierFlopping):
"""Composite pulses for carrier flopping using BB2 protocol.
Parameters
----------
amp: float
Amplitude of the waveform
freq: float
Frequency of the waveform
pi_time: float
Time of the pi pulse corresponding to the amplitude and frequency
Notes
-----
Ref: https://www.sciencedirect.com/science/article/pii/S1064185884711594
"""
def __init__(self, amp, freq, pi_time):
self.amp = amp
self.freq = freq
self.pi_time = pi_time
[docs] def waveform_series(self, angle, phase) -> WaveformSeries:
if angle < 0:
angle = -angle
phase = phase + np.pi
phi = 3 * np.pi / 2 + angle / 4
return WaveformSeries(
[self.pi_time, self.pi_time * 2, self.pi_time, angle/np.pi * self.pi_time],
[
CarrierFlopping(self.amp, phase + np.pi / 2, self.freq),
CarrierFlopping(self.amp, phase + phi, self.freq),
CarrierFlopping(self.amp, phase + np.pi / 2, self.freq),
CarrierFlopping(self.amp, phase, self.freq)
]
)