From bb9e2257ae3431b5a3286cbba1120736c815ae45 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Thu, 14 Dec 2023 21:14:53 +0100 Subject: [PATCH] Add dev group and pdbpp as dev dep --- pyproject.toml | 13 +++- tests/test_pulses.py | 153 +++++++++++++++++++++++++++---------------- 2 files changed, 106 insertions(+), 60 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ec9b564434..bd65b51ac6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,16 +27,23 @@ networkx = "^3.0" numpy = "==1.24.4" more-itertools = "^9.1.0" pyyaml = "^6.0" -qblox-instruments = { version = "0.11.0", optional = true} +qblox-instruments = { version = "0.11.0", optional = true } qcodes = { version = "^0.37.0", optional = true } -qcodes_contrib_drivers = { version ="0.18.0", optional = true } +qcodes_contrib_drivers = { version = "0.18.0", optional = true } pyvisa-py = { version = "0.5.3", optional = true } qm-qua = { version = "==1.1.1", optional = true } -qualang-tools = { version = "==0.14.0", optional = true} +qualang-tools = { version = "==0.14.0", optional = true } setuptools = { version = ">67.0.0", optional = true } laboneq = { version = "==2.20.1", optional = true } qibosoq = { version = ">=0.0.4,<0.2", optional = true } +[tool.poetry.group.dev] +optional = true + +[tool.poetry.group.dev.dependencies] +pdbpp = "^0.10.3" +ipython = "^8.12.0" + [tool.poetry.group.docs] optional = true diff --git a/tests/test_pulses.py b/tests/test_pulses.py index 3707f099fe..cc6129555a 100644 --- a/tests/test_pulses.py +++ b/tests/test_pulses.py @@ -72,7 +72,10 @@ def test_pulses_pulse_init(): type=PulseType.READOUT, qubit=0, ) - assert repr(p0) == "Pulse(0, 50, 0.9, 20_000_000, 0, Rectangular(), 0, PulseType.READOUT, 0)" + assert ( + repr(p0) + == "Pulse(0, 50, 0.9, 20_000_000, 0, Rectangular(), 0, PulseType.READOUT, 0)" + ) # initialisation with Symbolic Expressions t1 = se_int(100, "t1") @@ -88,7 +91,10 @@ def test_pulses_pulse_init(): type=PulseType.READOUT, qubit=0, ) - assert repr(p1) == "Pulse(100, 50, 0.9, 20_000_000, 0, Rectangular(), 0, PulseType.READOUT, 0)" + assert ( + repr(p1) + == "Pulse(100, 50, 0.9, 20_000_000, 0, Rectangular(), 0, PulseType.READOUT, 0)" + ) # initialisation with non int (float) frequency p2 = Pulse( @@ -102,7 +108,10 @@ def test_pulses_pulse_init(): type=PulseType.READOUT, qubit=0, ) - assert repr(p2) == "Pulse(0, 50, 0.9, 20_000_000, 0, Rectangular(), 0, PulseType.READOUT, 0)" + assert ( + repr(p2) + == "Pulse(0, 50, 0.9, 20_000_000, 0, Rectangular(), 0, PulseType.READOUT, 0)" + ) assert type(p2.frequency) == int and p2.frequency == 20_000_000 # initialisation with non float (int) relative_phase @@ -117,7 +126,10 @@ def test_pulses_pulse_init(): type=PulseType.READOUT, qubit=0, ) - assert repr(p3) == "Pulse(0, 50, 0.9, 20_000_000, 1, Rectangular(), 0, PulseType.READOUT, 0)" + assert ( + repr(p3) + == "Pulse(0, 50, 0.9, 20_000_000, 1, Rectangular(), 0, PulseType.READOUT, 0)" + ) assert type(p3.relative_phase) == float and p3.relative_phase == 1.0 # initialisation with str shape @@ -132,7 +144,10 @@ def test_pulses_pulse_init(): type=PulseType.READOUT, qubit=0, ) - assert repr(p4) == "Pulse(0, 50, 0.9, 20_000_000, 0, Rectangular(), 0, PulseType.READOUT, 0)" + assert ( + repr(p4) + == "Pulse(0, 50, 0.9, 20_000_000, 0, Rectangular(), 0, PulseType.READOUT, 0)" + ) # initialisation with str channel and str qubit p5 = Pulse( @@ -146,7 +161,10 @@ def test_pulses_pulse_init(): type=PulseType.READOUT, qubit="qubit0", ) - assert repr(p5) == "Pulse(0, 50, 0.9, 20_000_000, 0, Rectangular(), channel0, PulseType.READOUT, qubit0)" + assert ( + repr(p5) + == "Pulse(0, 50, 0.9, 20_000_000, 0, Rectangular(), channel0, PulseType.READOUT, qubit0)" + ) assert p5.qubit == "qubit0" # initialisation with different frequencies, shapes and types @@ -170,7 +188,10 @@ def test_pulses_pulse_init(): type=PulseType.READOUT, qubit=0, ) - assert repr(p12) == "Pulse(5.5, 34.33, 0.9, 20_000_000, 1, Rectangular(), 0, PulseType.READOUT, 0)" + assert ( + repr(p12) + == "Pulse(5.5, 34.33, 0.9, 20_000_000, 1, Rectangular(), 0, PulseType.READOUT, 0)" + ) assert isinstance(p12.start, float) assert isinstance(p12.duration, float) assert p12.finish == 5.5 + 34.33 @@ -196,7 +217,9 @@ def test_pulses_pulse_attributes(): assert type(p10.duration) == int and p10.duration == 50 assert type(p10.amplitude) == float and p10.amplitude == 0.9 assert type(p10.frequency) == int and p10.frequency == 20_000_000 - assert type(p10.phase) == float and np.allclose(p10.phase, 2 * np.pi * p10.start * p10.frequency / 1e9) + assert type(p10.phase) == float and np.allclose( + p10.phase, 2 * np.pi * p10.start * p10.frequency / 1e9 + ) assert isinstance(p10.shape, PulseShape) and repr(p10.shape) == "Rectangular()" assert type(p10.channel) == type(channel) and p10.channel == channel assert type(p10.qubit) == type(qubit) and p10.qubit == qubit @@ -294,7 +317,7 @@ def test_pulses_pulse_attributes(): def test_pulses_is_equal_ignoring_start(): - """Checks if two pulses are equal, not looking at start time""" + """Checks if two pulses are equal, not looking at start time.""" p1 = Pulse(0, 40, 0.9, 0, 0, Rectangular(), 0, PulseType.FLUX, 0) p2 = Pulse(100, 40, 0.9, 0, 0, Rectangular(), 0, PulseType.FLUX, 0) @@ -315,7 +338,10 @@ def test_pulses_is_equal_ignoring_start(): def test_pulses_pulse_serial(): p11 = Pulse(0, 40, 0.9, 50_000_000, 0, Gaussian(5), 0, PulseType.DRIVE) - assert p11.serial == "Pulse(0, 40, 0.9, 50_000_000, 0, Gaussian(5), 0, PulseType.DRIVE, 0)" + assert ( + p11.serial + == "Pulse(0, 40, 0.9, 50_000_000, 0, Gaussian(5), 0, PulseType.DRIVE, 0)" + ) assert repr(p11) == p11.serial @@ -453,7 +479,9 @@ def test_pulses_pulse_aliases(): ) assert repr(dp) == "DrivePulse(0, 2000, 0.9, 200_000_000, 0, Gaussian(5), 0, 0)" - fp = FluxPulse(start=0, duration=300, amplitude=0.9, shape=Rectangular(), channel=0, qubit=0) + fp = FluxPulse( + start=0, duration=300, amplitude=0.9, shape=Rectangular(), channel=0, qubit=0 + ) assert repr(fp) == "FluxPulse(0, 300, 0.9, Rectangular(), 0, 0)" @@ -719,7 +747,12 @@ def test_pulses_waveform(): def modulate( - i: np.ndarray, q: np.ndarray, num_samples: int, frequency: int, phase: float, sampling_rate: float + i: np.ndarray, + q: np.ndarray, + num_samples: int, + frequency: int, + phase: float, + sampling_rate: float, ): # -> tuple[np.ndarray, np.ndarray]: time = np.arange(num_samples) / sampling_rate cosalpha = np.cos(2 * np.pi * frequency * time + phase) @@ -755,14 +788,25 @@ def test_pulses_pulseshape_rectangular(): sampling_rate = 1 num_samples = int(pulse.duration / sampling_rate) - i, q = pulse.amplitude * np.ones(num_samples), pulse.amplitude * np.zeros(num_samples) - global_phase = 2 * np.pi * pulse._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 = ( + pulse.amplitude * np.ones(num_samples), + pulse.amplitude * np.zeros(num_samples), + ) + global_phase = ( + 2 * np.pi * pulse._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 + ) 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) - np.testing.assert_allclose(pulse.shape.modulated_waveform_q(sampling_rate).data, mod_q) + np.testing.assert_allclose( + pulse.shape.modulated_waveform_i(sampling_rate).data, mod_i + ) + np.testing.assert_allclose( + pulse.shape.modulated_waveform_q(sampling_rate).data, mod_q + ) assert ( pulse.shape.envelope_waveform_i().serial @@ -808,16 +852,28 @@ def test_pulses_pulseshape_gaussian(): num_samples = int(pulse.duration / sampling_rate) x = np.arange(0, num_samples, 1) i = pulse.amplitude * np.exp( - -(1 / 2) * (((x - (num_samples - 1) / 2) ** 2) / (((num_samples) / pulse.shape.rel_sigma) ** 2)) + -(1 / 2) + * ( + ((x - (num_samples - 1) / 2) ** 2) + / (((num_samples) / pulse.shape.rel_sigma) ** 2) + ) ) q = pulse.amplitude * np.zeros(num_samples) - global_phase = 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) + global_phase = ( + 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 + ) 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) - np.testing.assert_allclose(pulse.shape.modulated_waveform_q(sampling_rate).data, mod_q) + np.testing.assert_allclose( + pulse.shape.modulated_waveform_i(sampling_rate).data, mod_i + ) + np.testing.assert_allclose( + pulse.shape.modulated_waveform_q(sampling_rate).data, mod_q + ) assert ( pulse.shape.envelope_waveform_i().serial @@ -864,7 +920,11 @@ def test_pulses_pulseshape_drag(): num_samples = int(pulse.duration / 1 * sampling_rate) x = np.arange(0, num_samples, 1) i = pulse.amplitude * np.exp( - -(1 / 2) * (((x - (num_samples - 1) / 2) ** 2) / (((num_samples) / pulse.shape.rel_sigma) ** 2)) + -(1 / 2) + * ( + ((x - (num_samples - 1) / 2) ** 2) + / (((num_samples) / pulse.shape.rel_sigma) ** 2) + ) ) q = ( pulse.shape.beta @@ -872,13 +932,21 @@ def test_pulses_pulseshape_drag(): * i * sampling_rate ) - global_phase = 2 * np.pi * pulse._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) + global_phase = ( + 2 * np.pi * pulse._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 + ) 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) - np.testing.assert_allclose(pulse.shape.modulated_waveform_q(sampling_rate).data, mod_q) + np.testing.assert_allclose( + pulse.shape.modulated_waveform_i(sampling_rate).data, mod_i + ) + np.testing.assert_allclose( + pulse.shape.modulated_waveform_q(sampling_rate).data, mod_q + ) assert ( pulse.shape.envelope_waveform_i().serial @@ -899,7 +967,7 @@ def test_pulses_pulseshape_drag(): def test_pulses_pulseshape_eq(): - """Checks == operator for pulse shapes""" + """Checks == operator for pulse shapes.""" shape1 = Rectangular() shape2 = Rectangular() @@ -1158,32 +1226,3 @@ def test_envelope_waveform_i_q(): with pytest.raises(ValueError): custom_shape_pulse.pulse = pulse custom_shape_pulse.envelope_waveform_q() - - -@pytest.mark.parametrize("start", [0, 10, se_int(0, "t00"), se_int(10, "t10")]) -@pytest.mark.parametrize("duration", [100, 500, se_int(100, "d100"), se_int(500, "d500")]) -def test_pulse_properties(start, duration): - def check_properties(pulse): - assert isinstance(pulse.start, int) - assert isinstance(pulse.se_start, se_int) - assert isinstance(pulse.duration, int) - assert isinstance(pulse.se_duration, se_int) - assert isinstance(pulse.finish, int) - assert isinstance(pulse.se_finish, se_int) - - p0 = Pulse(start, duration, 0.9, 0, 0, Rectangular(), 0) - # Check the getters - check_properties(p0) - # Check the setters - p0.start = start + 10 - p0.duration = duration + 10 - check_properties(p0) - - -def test_pulse_setter_errors(): - faulty_duration = "hello" - faulty_start = "hello" - with pytest.raises(TypeError): - p0 = Pulse(faulty_start, 100, 0.9, 0, 0, Rectangular(), 0) - with pytest.raises(TypeError): - p0 = Pulse(0, faulty_duration, 0.9, 0, 0, Rectangular(), 0)