Skip to content

Commit

Permalink
Merge pull request #768 from qiboteam/simplify-pulse-6
Browse files Browse the repository at this point in the history
Remove `_if` from `Pulse`
  • Loading branch information
alecandido authored Jan 22, 2024
2 parents 4cf8b6b + 7b43744 commit 162b94d
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 31 deletions.
21 changes: 8 additions & 13 deletions src/qibolab/pulses.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,36 +140,32 @@ def envelope_waveforms(
self.envelope_waveform_q(sampling_rate),
)

def modulated_waveform_i(self, sampling_rate=SAMPLING_RATE) -> Waveform:
def modulated_waveform_i(self, _if: int, sampling_rate=SAMPLING_RATE) -> Waveform:
"""The waveform of the i component of the pulse, modulated with its
frequency."""

return self.modulated_waveforms(sampling_rate)[0]
return self.modulated_waveforms(_if, sampling_rate)[0]

def modulated_waveform_q(self, sampling_rate=SAMPLING_RATE) -> Waveform:
def modulated_waveform_q(self, _if: int, sampling_rate=SAMPLING_RATE) -> Waveform:
"""The waveform of the q component of the pulse, modulated with its
frequency."""

return self.modulated_waveforms(sampling_rate)[1]
return self.modulated_waveforms(_if, sampling_rate)[1]

def modulated_waveforms(self, sampling_rate=SAMPLING_RATE):
def modulated_waveforms(self, _if: int, sampling_rate=SAMPLING_RATE):
"""A tuple with the i and q waveforms of the pulse, modulated with its
frequency."""

pulse = self.pulse
if abs(pulse._if) * 2 > sampling_rate:
if abs(_if) * 2 > sampling_rate:
log.info(
f"WARNING: The frequency of pulse {pulse.id} is higher than the nyqusit frequency ({int(sampling_rate // 2)}) for the device sampling rate: {int(sampling_rate)}"
)
num_samples = int(np.rint(pulse.duration * sampling_rate))
time = np.arange(num_samples) / sampling_rate
global_phase = pulse.global_phase
cosalpha = np.cos(
2 * np.pi * pulse._if * time + global_phase + pulse.relative_phase
)
sinalpha = np.sin(
2 * np.pi * pulse._if * time + global_phase + pulse.relative_phase
)
cosalpha = np.cos(2 * np.pi * _if * time + global_phase + pulse.relative_phase)
sinalpha = np.sin(2 * np.pi * _if * time + global_phase + pulse.relative_phase)

mod_matrix = np.array([[cosalpha, -sinalpha], [sinalpha, cosalpha]]) / np.sqrt(
2
Expand Down Expand Up @@ -753,7 +749,6 @@ class Pulse:
"""Pulse type, as an element of PulseType enumeration."""
qubit: int = 0
"""Qubit or coupler addressed by the pulse."""
_if: int = 0

def __post_init__(self):
if isinstance(self.type, str):
Expand Down
39 changes: 21 additions & 18 deletions tests/test_pulses.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def test_plot_functions():
p5 = Pulse(0, 40, 0.9, 400e6, 0, eCap(alpha=2), 0, PulseType.DRIVE)
p6 = Pulse(0, 40, 0.9, 50e6, 0, GaussianSquare(5, 0.9), 0, PulseType.DRIVE, 2)
ps = PulseSequence([p0, p1, p2, p3, p4, p5, p6])
wf = p0.modulated_waveform_i()
wf = p0.modulated_waveform_i(0)

plot_file = HERE / "test_plot.png"

Expand Down Expand Up @@ -605,15 +605,16 @@ def test_pulseshape_rectangular():
channel=1,
qubit=0,
)
_if = 0

assert pulse.duration == 50
assert isinstance(pulse.shape, Rectangular)
assert pulse.shape.name == "Rectangular"
assert repr(pulse.shape) == "Rectangular()"
assert isinstance(pulse.shape.envelope_waveform_i(), Waveform)
assert isinstance(pulse.shape.envelope_waveform_q(), Waveform)
assert isinstance(pulse.shape.modulated_waveform_i(), Waveform)
assert isinstance(pulse.shape.modulated_waveform_q(), Waveform)
assert isinstance(pulse.shape.modulated_waveform_i(_if), Waveform)
assert isinstance(pulse.shape.modulated_waveform_q(_if), Waveform)

sampling_rate = 1
num_samples = int(pulse.duration / sampling_rate)
Expand All @@ -622,19 +623,19 @@ def test_pulseshape_rectangular():
pulse.amplitude * np.zeros(num_samples),
)
global_phase = (
2 * np.pi * pulse._if * pulse.start / 1e9
2 * np.pi * _if * pulse.start / 1e9
) # pulse start, duration and finish are in ns
mod_i, mod_q = modulate(
i, q, num_samples, pulse._if, global_phase + pulse.relative_phase, sampling_rate
i, q, num_samples, _if, global_phase + pulse.relative_phase, sampling_rate
)

np.testing.assert_allclose(pulse.shape.envelope_waveform_i(sampling_rate).data, i)
np.testing.assert_allclose(pulse.shape.envelope_waveform_q(sampling_rate).data, q)
np.testing.assert_allclose(
pulse.shape.modulated_waveform_i(sampling_rate).data, mod_i
pulse.shape.modulated_waveform_i(_if, sampling_rate).data, mod_i
)
np.testing.assert_allclose(
pulse.shape.modulated_waveform_q(sampling_rate).data, mod_q
pulse.shape.modulated_waveform_q(_if, sampling_rate).data, mod_q
)


Expand All @@ -649,6 +650,7 @@ def test_pulseshape_gaussian():
channel=1,
qubit=0,
)
_if = 0

assert pulse.duration == 50
assert isinstance(pulse.shape, Gaussian)
Expand All @@ -657,8 +659,8 @@ def test_pulseshape_gaussian():
assert repr(pulse.shape) == "Gaussian(5)"
assert isinstance(pulse.shape.envelope_waveform_i(), Waveform)
assert isinstance(pulse.shape.envelope_waveform_q(), Waveform)
assert isinstance(pulse.shape.modulated_waveform_i(), Waveform)
assert isinstance(pulse.shape.modulated_waveform_q(), Waveform)
assert isinstance(pulse.shape.modulated_waveform_i(_if), Waveform)
assert isinstance(pulse.shape.modulated_waveform_q(_if), Waveform)

sampling_rate = 1
num_samples = int(pulse.duration / sampling_rate)
Expand All @@ -675,16 +677,16 @@ def test_pulseshape_gaussian():
2 * np.pi * pulse.frequency * pulse.start / 1e9
) # pulse start, duration and finish are in ns
mod_i, mod_q = modulate(
i, q, num_samples, pulse._if, global_phase + pulse.relative_phase, sampling_rate
i, q, num_samples, _if, global_phase + pulse.relative_phase, sampling_rate
)

np.testing.assert_allclose(pulse.shape.envelope_waveform_i(sampling_rate).data, i)
np.testing.assert_allclose(pulse.shape.envelope_waveform_q(sampling_rate).data, q)
np.testing.assert_allclose(
pulse.shape.modulated_waveform_i(sampling_rate).data, mod_i
pulse.shape.modulated_waveform_i(_if, sampling_rate).data, mod_i
)
np.testing.assert_allclose(
pulse.shape.modulated_waveform_q(sampling_rate).data, mod_q
pulse.shape.modulated_waveform_q(_if, sampling_rate).data, mod_q
)


Expand All @@ -699,6 +701,7 @@ def test_pulseshape_drag():
channel=1,
qubit=0,
)
_if = 0

assert pulse.duration == 50
assert isinstance(pulse.shape, Drag)
Expand All @@ -708,8 +711,8 @@ def test_pulseshape_drag():
assert repr(pulse.shape) == "Drag(5, 0.2)"
assert isinstance(pulse.shape.envelope_waveform_i(), Waveform)
assert isinstance(pulse.shape.envelope_waveform_q(), Waveform)
assert isinstance(pulse.shape.modulated_waveform_i(), Waveform)
assert isinstance(pulse.shape.modulated_waveform_q(), Waveform)
assert isinstance(pulse.shape.modulated_waveform_i(_if), Waveform)
assert isinstance(pulse.shape.modulated_waveform_q(_if), Waveform)

sampling_rate = 1
num_samples = int(pulse.duration / 1 * sampling_rate)
Expand All @@ -728,19 +731,19 @@ def test_pulseshape_drag():
* sampling_rate
)
global_phase = (
2 * np.pi * pulse._if * pulse.start / 1e9
2 * np.pi * _if * pulse.start / 1e9
) # pulse start, duration and finish are in ns
mod_i, mod_q = modulate(
i, q, num_samples, pulse._if, global_phase + pulse.relative_phase, sampling_rate
i, q, num_samples, _if, global_phase + pulse.relative_phase, sampling_rate
)

np.testing.assert_allclose(pulse.shape.envelope_waveform_i(sampling_rate).data, i)
np.testing.assert_allclose(pulse.shape.envelope_waveform_q(sampling_rate).data, q)
np.testing.assert_allclose(
pulse.shape.modulated_waveform_i(sampling_rate).data, mod_i
pulse.shape.modulated_waveform_i(_if, sampling_rate).data, mod_i
)
np.testing.assert_allclose(
pulse.shape.modulated_waveform_q(sampling_rate).data, mod_q
pulse.shape.modulated_waveform_q(_if, sampling_rate).data, mod_q
)


Expand Down

0 comments on commit 162b94d

Please sign in to comment.