From 83af270f644221c649726b04e1dd39e9a121fda3 Mon Sep 17 00:00:00 2001
From: Li Li
Date: Thu, 3 Dec 2020 17:44:07 +1100
Subject: [PATCH 1/9] fix some type issue
---
mypy.ini | 2 +-
qctrlopencontrols/driven_controls/driven_control.py | 6 +++++-
.../dynamic_decoupling_sequences/predefined.py | 7 ++++---
3 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/mypy.ini b/mypy.ini
index 7d2e8add..f1ea4cb4 100644
--- a/mypy.ini
+++ b/mypy.ini
@@ -1,6 +1,6 @@
[mypy]
files = qctrlopencontrols/**/*.py,tests/**/*.py
-check_untyped_defs = False
+check_untyped_defs = True
[mypy-deprecation.*]
ignore_missing_imports = True
diff --git a/qctrlopencontrols/driven_controls/driven_control.py b/qctrlopencontrols/driven_controls/driven_control.py
index 6848deed..4c540440 100644
--- a/qctrlopencontrols/driven_controls/driven_control.py
+++ b/qctrlopencontrols/driven_controls/driven_control.py
@@ -16,7 +16,11 @@
Driven control module.
"""
import json
-from typing import Optional
+from typing import (
+ Any,
+ Dict,
+ Optional,
+)
import numpy as np
diff --git a/qctrlopencontrols/dynamic_decoupling_sequences/predefined.py b/qctrlopencontrols/dynamic_decoupling_sequences/predefined.py
index cefaa715..8167239f 100644
--- a/qctrlopencontrols/dynamic_decoupling_sequences/predefined.py
+++ b/qctrlopencontrols/dynamic_decoupling_sequences/predefined.py
@@ -186,7 +186,7 @@ def new_ramsey_sequence(duration, pre_post_rotation=False, name=None):
offsets = duration * np.array([0.0, 1.0])
rabi_rotations = np.array([np.pi / 2, np.pi / 2])
azimuthal_angles = np.array([0.0, np.pi])
- detuning_rotations = np.zeros(offsets.shape)
+ detuning_rotations = np.zeros((2,))
return DynamicDecouplingSequence(
duration=duration,
@@ -915,12 +915,13 @@ def new_x_concatenated_sequence(
values, counts = np.unique(pos_cum_sum, return_counts=True)
- offsets = [value for value, count in zip(values, counts) if count % 2 == 0]
+ offsets = np.array(
+ [value for value, count in zip(values, counts) if count % 2 == 0]
+ )
if concatenation_order % 2 == 1:
offsets = offsets[:-1]
- offsets = np.array(offsets)
rabi_rotations = np.zeros(offsets.shape)
rabi_rotations[0:] = np.pi
azimuthal_angles = np.zeros(offsets.shape)
From dae8e1f897f890e436efd31d7c4dd0119ff445a2 Mon Sep 17 00:00:00 2001
From: Li Li
Date: Fri, 11 Dec 2020 10:39:44 +1100
Subject: [PATCH 2/9] dict
---
.../driven_controls/driven_control.py | 144 ++++++------------
1 file changed, 47 insertions(+), 97 deletions(-)
diff --git a/qctrlopencontrols/driven_controls/driven_control.py b/qctrlopencontrols/driven_controls/driven_control.py
index f7847afb..5a26d940 100644
--- a/qctrlopencontrols/driven_controls/driven_control.py
+++ b/qctrlopencontrols/driven_controls/driven_control.py
@@ -15,9 +15,9 @@
"""
Driven control module.
"""
+import csv
import json
from typing import (
- Any,
Dict,
Optional,
)
@@ -331,91 +331,52 @@ def duration(self) -> float:
return np.sum(self.durations)
- def _qctrl_expanded_export_content(self, file_type, coordinates):
+ def _qctrl_expanded_export_content(self, coordinates: str) -> Dict:
"""
Prepare the content to be saved in Q-CTRL expanded format.
Parameters
----------
- file_type : str, optional
- One of 'CSV' or 'JSON'; defaults to 'CSV'.
coordinates : str, optional
Indicates the co-ordinate system requested. Must be one of
- 'cylindrical', 'cartesian' or 'polar'; defaults to 'cylindrical'
+ 'cylindrical', 'cartesian' or 'polar'. Defaults to 'cylindrical'.
Returns
-------
- list or dict
- Based on file_type; list if 'CSV', dict if 'JSON'
+ Dict
+ A dictionary containing the information of the control.
"""
- control_info = None
- amplitude_x = self.amplitude_x
- amplitude_y = self.amplitude_y
- if coordinates == Coordinate.CARTESIAN.value:
- if file_type == FileType.CSV.value:
- control_info = list()
- control_info.append(
- "amplitude_x,amplitude_y,detuning,duration,maximum_rabi_rate"
- )
- for segment_idx in range(self.number_of_segments):
- control_info.append(
- "{},{},{},{},{}".format(
- amplitude_x[segment_idx] / self.maximum_rabi_rate,
- amplitude_y[segment_idx] / self.maximum_rabi_rate,
- self.detunings[segment_idx],
- self.durations[segment_idx],
- self.maximum_rabi_rate,
- )
- )
- else:
- control_info = dict()
- if self.name is not None:
- control_info["name"] = self.name
- control_info["maximum_rabi_rate"] = self.maximum_rabi_rate
- control_info["amplitude_x"] = list(amplitude_x / self.maximum_rabi_rate)
- control_info["amplitude_y"] = list(amplitude_y / self.maximum_rabi_rate)
- control_info["detuning"] = list(self.detunings)
- control_info["duration"] = list(self.durations)
- else:
+ control_info = {
+ "maximum_rabi_rate": self.maximum_rabi_rate,
+ "detuning": list(self.detunings),
+ "duration": list(self.durations),
+ }
- if file_type == FileType.CSV.value:
- control_info = list()
- control_info.append(
- "rabi_rate,azimuthal_angle,detuning,duration,maximum_rabi_rate"
- )
- for segment_idx in range(self.number_of_segments):
- control_info.append(
- "{},{},{},{},{}".format(
- self.rabi_rates[segment_idx] / self.maximum_rabi_rate,
- self.azimuthal_angles[segment_idx],
- self.detunings[segment_idx],
- self.durations[segment_idx],
- self.maximum_rabi_rate,
- )
- )
-
- else:
- control_info = dict()
- if self.name is not None:
- control_info["name"] = self.name
- control_info["maximum_rabi_rate"] = self.maximum_rabi_rate
- control_info["rabi_rates"] = list(
- self.rabi_rates / self.maximum_rabi_rate
- )
- control_info["azimuthal_angles"] = list(self.azimuthal_angles)
- control_info["detuning"] = list(self.detunings)
- control_info["duration"] = list(self.durations)
+ if self.name is not None:
+ control_info["name"] = self.name
+
+ if coordinates == Coordinate.CARTESIAN.value:
+ control_info["amplitude_x"] = list(
+ self.amplitude_x / self.maximum_rabi_rate
+ )
+ control_info["amplitude_y"] = list(
+ self.amplitude_y / self.maximum_rabi_rate
+ )
+ else:
+ control_info["rabi_rates"] = list(self.rabi_rates / self.maximum_rabi_rate)
+ control_info["azimuthal_angles"] = list(self.azimuthal_angles)
return control_info
def _export_to_qctrl_expanded_format(
self,
- filename=None,
+ filename,
file_type=FileType.CSV.value,
coordinates=Coordinate.CYLINDRICAL.value,
):
- """Private method to save control in qctrl_expanded_format
+ """
+ Saves control in qctrl_expanded_format.
Parameters
----------
@@ -429,9 +390,8 @@ def _export_to_qctrl_expanded_format(
'cylindrical', 'cartesian'; defaults to 'cylindrical'
"""
- control_info = self._qctrl_expanded_export_content(
- file_type=file_type, coordinates=coordinates
- )
+ control_info = self._qctrl_expanded_export_content(coordinates=coordinates)
+
if file_type == FileType.CSV.value:
with open(filename, "wt") as handle:
@@ -443,7 +403,7 @@ def _export_to_qctrl_expanded_format(
def export_to_file(
self,
- filename=None,
+ filename,
file_format=FileFormat.QCTRL.value,
file_type=FileType.CSV.value,
coordinates=Coordinate.CYLINDRICAL.value,
@@ -464,11 +424,6 @@ def export_to_file(
The coordinate system in which to save the control. Must be 'cylindrical' or
'cartesian'. Defaults to 'cylindrical'.
- Raises
- ------
- ArgumentsValueError
- Raised if some of the parameters are invalid.
-
Notes
-----
The Q-CTRL expanded format is designed for direct integration of control solutions into
@@ -517,31 +472,26 @@ def export_to_file(
_file_formats = [v.value for v in FileFormat]
_coordinate_systems = [v.value for v in Coordinate]
- if filename is None:
- raise ArgumentsValueError(
- "Invalid filename provided.", {"filename": filename}
- )
-
- if file_format not in _file_formats:
- raise ArgumentsValueError(
- "Requested file format is not supported. Please use "
- "one of {}".format(_file_formats),
- {"file_format": file_format},
- )
+ check_arguments(
+ file_format in _file_formats,
+ "Requested file format is not supported. Please use "
+ "one of {}".format(_file_formats),
+ {"file_format": file_format},
+ )
- if file_type not in _file_types:
- raise ArgumentsValueError(
- "Requested file type is not supported. Please use "
- "one of {}".format(_file_types),
- {"file_type": file_type},
- )
+ check_arguments(
+ file_type in _file_types,
+ "Requested file type is not supported. Please use "
+ "one of {}".format(_file_types),
+ {"file_type": file_type},
+ )
- if coordinates not in _coordinate_systems:
- raise ArgumentsValueError(
- "Requested coordinate type is not supported. Please use "
- "one of {}".format(_coordinate_systems),
- {"coordinates": coordinates},
- )
+ check_arguments(
+ coordinates in _coordinate_systems,
+ "Requested coordinate type is not supported. Please use "
+ "one of {}".format(_coordinate_systems),
+ {"coordinates": coordinates},
+ )
if file_format == FileFormat.QCTRL.value:
self._export_to_qctrl_expanded_format(
From 81397f7484094cfc0fcf20d9c8e425be141a0dd8 Mon Sep 17 00:00:00 2001
From: Li Li
Date: Fri, 11 Dec 2020 20:35:31 +1100
Subject: [PATCH 3/9] fix export
---
.../driven_controls/driven_control.py | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/qctrlopencontrols/driven_controls/driven_control.py b/qctrlopencontrols/driven_controls/driven_control.py
index 5a26d940..c767d61c 100644
--- a/qctrlopencontrols/driven_controls/driven_control.py
+++ b/qctrlopencontrols/driven_controls/driven_control.py
@@ -391,12 +391,20 @@ def _export_to_qctrl_expanded_format(
"""
control_info = self._qctrl_expanded_export_content(coordinates=coordinates)
-
if file_type == FileType.CSV.value:
- with open(filename, "wt") as handle:
-
- control_info = "\n".join(control_info)
- handle.write(control_info)
+ _ = control_info.pop("name")
+ control_info["maximum_rabi_rate"] = [
+ self.maximum_rabi_rate
+ ] * self.number_of_segments
+ field_names = sorted(control_info.keys())
+ with open(filename, "w", newline="") as file:
+ writer = csv.DictWriter(file, fieldnames=field_names)
+ writer.writeheader()
+
+ for index in range(self.number_of_segments):
+ writer.writerow(
+ {name: control_info[name][index] for name in field_names}
+ )
else:
with open(filename, "wt") as handle:
json.dump(control_info, handle, sort_keys=True, indent=4)
From 7d78cef8cc4c973fabb60bf87204dbe681b4991f Mon Sep 17 00:00:00 2001
From: Li Li
Date: Fri, 11 Dec 2020 21:03:07 +1100
Subject: [PATCH 4/9] rep
---
.../driven_controls/driven_control.py | 58 ++++++++++---------
1 file changed, 31 insertions(+), 27 deletions(-)
diff --git a/qctrlopencontrols/driven_controls/driven_control.py b/qctrlopencontrols/driven_controls/driven_control.py
index c767d61c..2a20bb76 100644
--- a/qctrlopencontrols/driven_controls/driven_control.py
+++ b/qctrlopencontrols/driven_controls/driven_control.py
@@ -580,46 +580,50 @@ def __str__(self):
"""
Prepares a friendly string format for a Driven Control.
"""
- driven_control_string = list()
+ driven_control = list()
if self.name is not None:
- driven_control_string.append("{}:".format(self.name))
+ driven_control.append("{}:".format(self.name))
+
+ pretty_rabi_rates = ",".join(
+ [
+ str(rabi_rate / self.maximum_rabi_rate)
+ if self.maximum_rabi_rate != 0
+ else "0"
+ for rabi_rate in self.rabi_rates
+ ]
+ )
- pretty_rabi_rates = [
- str(rabi_rate / self.maximum_rabi_rate)
- if self.maximum_rabi_rate != 0
- else "0"
- for rabi_rate in list(self.rabi_rates)
- ]
- pretty_rabi_rates = ",".join(pretty_rabi_rates)
- pretty_azimuthal_angles = [
- str(azimuthal_angle / np.pi) for azimuthal_angle in self.azimuthal_angles
- ]
- pretty_azimuthal_angles = ",".join(pretty_azimuthal_angles)
- pretty_detuning = [
- str(detuning / self.maximum_detuning) if self.maximum_detuning != 0 else "0"
- for detuning in list(self.detunings)
- ]
- pretty_detuning = ",".join(pretty_detuning)
+ pretty_azimuthal_angles = ",".join(
+ [str(azimuthal_angle / np.pi) for azimuthal_angle in self.azimuthal_angles]
+ )
- pretty_durations = [
- str(duration / self.duration) for duration in self.durations
- ]
- pretty_durations = ",".join(pretty_durations)
+ pretty_detuning = ",".join(
+ [
+ str(detuning / self.maximum_detuning)
+ if self.maximum_detuning != 0
+ else "0"
+ for detuning in self.detunings
+ ]
+ )
+
+ pretty_durations = ",".join(
+ [str(duration / self.duration) for duration in self.durations]
+ )
- driven_control_string.append(
+ driven_control.append(
"Rabi Rates = [{}] x {}".format(pretty_rabi_rates, self.maximum_rabi_rate)
)
- driven_control_string.append(
+ driven_control.append(
"Azimuthal Angles = [{}] x pi".format(pretty_azimuthal_angles)
)
- driven_control_string.append(
+ driven_control.append(
"Detunings = [{}] x {}".format(pretty_detuning, self.maximum_detuning)
)
- driven_control_string.append(
+ driven_control.append(
"Durations = [{}] x {}".format(pretty_durations, self.duration)
)
- driven_control_string = "\n".join(driven_control_string)
+ driven_control_string = "\n".join(driven_control)
return driven_control_string
From b147612ad0f2efbba7ecf4216b6b6bdfd3462cac Mon Sep 17 00:00:00 2001
From: Li Li
Date: Fri, 11 Dec 2020 21:28:50 +1100
Subject: [PATCH 5/9] test
---
tests/test_driven_controls.py | 60 ++++------
tests/test_dynamical_decoupling.py | 20 ++--
tests/test_predefined_dynamical_decoupling.py | 111 ++++++++----------
3 files changed, 82 insertions(+), 109 deletions(-)
diff --git a/tests/test_driven_controls.py b/tests/test_driven_controls.py
index 283852fd..13f47983 100644
--- a/tests/test_driven_controls.py
+++ b/tests/test_driven_controls.py
@@ -298,18 +298,14 @@ def test_pretty_print():
durations=_durations,
)
- _pretty_rabi_rates = [
+ _pretty_rabi_rates = ",".join([
str(_rabi_rate / _maximum_rabi_rate) for _rabi_rate in _rabi_rates
- ]
- _pretty_azimuthal_angles = [
+ ])
+ _pretty_azimuthal_angles = ",".join([
str(azimuthal_angle / np.pi) for azimuthal_angle in _azimuthal_angles
- ]
- _pretty_detunings = [str(detuning / _maximum_detuning) for detuning in _detunings]
- _pretty_durations = [str(duration / 3.0) for duration in _durations]
- _pretty_rabi_rates = ",".join(_pretty_rabi_rates)
- _pretty_azimuthal_angles = ",".join(_pretty_azimuthal_angles)
- _pretty_detunings = ",".join(_pretty_detunings)
- _pretty_durations = ",".join(_pretty_durations)
+ ])
+ _pretty_detunings = ",".join([str(detuning / _maximum_detuning) for detuning in _detunings])
+ _pretty_durations = ",".join([str(duration / 3.0) for duration in _durations])
_pretty_string = []
_pretty_string.append(
@@ -323,9 +319,9 @@ def test_pretty_print():
)
_pretty_string.append("Durations = [{}] x 3.0".format(_pretty_durations))
- _pretty_string = "\n".join(_pretty_string)
+ expected_string = "\n".join(_pretty_string)
- assert str(driven_control) == _pretty_string
+ assert str(driven_control) == expected_string
_maximum_rabi_rate = 0.0
_maximum_detuning = 1.0
@@ -341,16 +337,12 @@ def test_pretty_print():
durations=_durations,
)
- _pretty_rabi_rates = ["0", "0", "0"]
- _pretty_azimuthal_angles = [
+ _pretty_rabi_rates = ",".join(["0", "0", "0"])
+ _pretty_azimuthal_angles = ",".join([
str(azimuthal_angle / np.pi) for azimuthal_angle in _azimuthal_angles
- ]
- _pretty_detunings = [str(detuning / _maximum_detuning) for detuning in _detunings]
- _pretty_durations = [str(duration / 3.0) for duration in _durations]
- _pretty_rabi_rates = ",".join(_pretty_rabi_rates)
- _pretty_azimuthal_angles = ",".join(_pretty_azimuthal_angles)
- _pretty_detunings = ",".join(_pretty_detunings)
- _pretty_durations = ",".join(_pretty_durations)
+ ])
+ _pretty_detunings = ",".join([str(detuning / _maximum_detuning) for detuning in _detunings])
+ _pretty_durations = ",".join([str(duration / 3.0) for duration in _durations])
_pretty_string = []
_pretty_string.append(
@@ -364,15 +356,15 @@ def test_pretty_print():
)
_pretty_string.append("Durations = [{}] x 3.0".format(_pretty_durations))
- _pretty_string = "\n".join(_pretty_string)
+ expected_string = "\n".join(_pretty_string)
- assert str(driven_control) == _pretty_string
+ assert str(driven_control) == expected_string
_maximum_rabi_rate = 2 * np.pi
_maximum_detuning = 0.0
_rabi_rates = [np.pi, 2 * np.pi, np.pi]
_azimuthal_angles = [0, np.pi / 2, -np.pi / 2]
- _detunings = [0, 0.0, 0]
+ _detunings = [0, 0, 0]
_durations = [1.0, 1.0, 1.0]
driven_control = DrivenControl(
@@ -382,18 +374,14 @@ def test_pretty_print():
durations=_durations,
)
- _pretty_rabi_rates = [
+ _pretty_rabi_rates = ",".join([
str(_rabi_rate / _maximum_rabi_rate) for _rabi_rate in _rabi_rates
- ]
- _pretty_azimuthal_angles = [
+ ])
+ _pretty_azimuthal_angles = ",".join([
str(azimuthal_angle / np.pi) for azimuthal_angle in _azimuthal_angles
- ]
- _pretty_detunings = ["0", "0", "0"]
- _pretty_durations = [str(duration / 3.0) for duration in _durations]
- _pretty_rabi_rates = ",".join(_pretty_rabi_rates)
- _pretty_azimuthal_angles = ",".join(_pretty_azimuthal_angles)
- _pretty_detunings = ",".join(_pretty_detunings)
- _pretty_durations = ",".join(_pretty_durations)
+ ])
+ _pretty_detunings = ",".join(["0", "0", "0"])
+ _pretty_durations = ",".join([str(duration / 3.0) for duration in _durations])
_pretty_string = []
_pretty_string.append(
@@ -407,6 +395,6 @@ def test_pretty_print():
)
_pretty_string.append("Durations = [{}] x 3.0".format(_pretty_durations))
- _pretty_string = "\n".join(_pretty_string)
+ expected_string = "\n".join(_pretty_string)
- assert str(driven_control) == _pretty_string
+ assert str(driven_control) == expected_string
diff --git a/tests/test_dynamical_decoupling.py b/tests/test_dynamical_decoupling.py
index 46a2df12..cf82bfa0 100644
--- a/tests/test_dynamical_decoupling.py
+++ b/tests/test_dynamical_decoupling.py
@@ -242,9 +242,9 @@ def test_pretty_string_format():
)
)
- _pretty_string = "\n".join(_pretty_string)
+ expected_string = "\n".join(_pretty_string)
- assert _pretty_string == str(dd_sequence)
+ assert expected_string == str(dd_sequence)
dd_sequence = DynamicDecouplingSequence(
duration=_duration,
@@ -282,9 +282,9 @@ def test_pretty_string_format():
_detuning_rotations[2] / np.pi,
)
)
- _pretty_string = "\n".join(_pretty_string)
+ expected_string = "\n".join(_pretty_string)
- assert _pretty_string == str(dd_sequence)
+ assert expected_string == str(dd_sequence)
def test_conversion_to_driven_controls():
@@ -779,17 +779,13 @@ def test_free_evolution_conversion():
"""
_duration = 10.0
_name = "test_sequence"
- _offsets = []
- _rabi_rotations = []
- _azimuthal_angles = []
- _detuning_rotations = []
dd_sequence = DynamicDecouplingSequence(
duration=_duration,
- offsets=_offsets,
- rabi_rotations=_rabi_rotations,
- azimuthal_angles=_azimuthal_angles,
- detuning_rotations=_detuning_rotations,
+ offsets=[],
+ rabi_rotations=[],
+ azimuthal_angles=[],
+ detuning_rotations=[],
name=_name,
)
diff --git a/tests/test_predefined_dynamical_decoupling.py b/tests/test_predefined_dynamical_decoupling.py
index d48f3cb1..0fba4292 100644
--- a/tests/test_predefined_dynamical_decoupling.py
+++ b/tests/test_predefined_dynamical_decoupling.py
@@ -313,13 +313,14 @@ def test_walsh_sequence():
** binary_order[hamming_weight - 1 - i]
)
- walsh_relative_offsets = []
- for i in range(samples - 1):
- if walsh_array[i] != walsh_array[i + 1]:
- walsh_relative_offsets.append((i + 1) * (1.0 / samples))
- walsh_relative_offsets = np.array(walsh_relative_offsets, dtype=np.float)
+ walsh_relative_offsets = np.array(
+ [
+ (i + 1) * (1.0 / samples)
+ for i in range(samples - 1)
+ if walsh_array[i] != walsh_array[i + 1]
+ ]
+ )
_offsets = duration * walsh_relative_offsets
- _offsets = np.array(_offsets)
_rabi_rotations = np.pi * np.ones(_offsets.shape)
_azimuthal_angles = np.zeros(_offsets.shape)
@@ -446,8 +447,9 @@ def test_x_concatenated_sequence():
)
_spacing = duration / (2 ** concatenation_order)
- _offsets = [_spacing, 3 * _spacing, 4 * _spacing, 5 * _spacing, 7 * _spacing]
- _offsets = np.array(_offsets)
+ _offsets = np.array(
+ [_spacing, 3 * _spacing, 4 * _spacing, 5 * _spacing, 7 * _spacing]
+ )
_rabi_rotations = np.pi * np.ones(_offsets.shape)
_azimuthal_angles = np.zeros(_offsets.shape)
@@ -490,59 +492,46 @@ def test_xy_concatenated_sequence():
)
_spacing = duration / (2 ** (concatenation_order * 2))
- _offsets = [
- _spacing,
- 2 * _spacing,
- 3 * _spacing,
- 4 * _spacing,
- 5 * _spacing,
- 6 * _spacing,
- 7 * _spacing,
- 9 * _spacing,
- 10 * _spacing,
- 11 * _spacing,
- 12 * _spacing,
- 13 * _spacing,
- 14 * _spacing,
- 15 * _spacing,
- ]
- _offsets = np.array(_offsets)
- _rabi_rotations = [
- np.pi,
- np.pi,
- np.pi,
- 0.0,
- np.pi,
- np.pi,
- np.pi,
- np.pi,
- np.pi,
- np.pi,
- 0,
- np.pi,
- np.pi,
- np.pi,
- ]
- _rabi_rotations = np.array(_rabi_rotations)
- _azimuthal_angles = [
- 0,
- np.pi / 2,
- 0,
- 0,
- 0,
- np.pi / 2,
- 0,
- 0,
- np.pi / 2,
- 0,
- 0,
- 0,
- np.pi / 2,
- 0,
- ]
- _azimuthal_angles = np.array(_azimuthal_angles)
- _detuning_rotations = [0, 0, 0, np.pi, 0, 0, 0, 0, 0, 0, np.pi, 0, 0, 0]
- _detuning_rotations = np.array(_detuning_rotations)
+ _offsets = np.array(
+ [
+ _spacing,
+ 2 * _spacing,
+ 3 * _spacing,
+ 4 * _spacing,
+ 5 * _spacing,
+ 6 * _spacing,
+ 7 * _spacing,
+ 9 * _spacing,
+ 10 * _spacing,
+ 11 * _spacing,
+ 12 * _spacing,
+ 13 * _spacing,
+ 14 * _spacing,
+ 15 * _spacing,
+ ]
+ )
+ _rabi_rotations = np.array(
+ [
+ np.pi,
+ np.pi,
+ np.pi,
+ 0.0,
+ np.pi,
+ np.pi,
+ np.pi,
+ np.pi,
+ np.pi,
+ np.pi,
+ 0,
+ np.pi,
+ np.pi,
+ np.pi,
+ ]
+ )
+ _azimuthal_angles = np.array(
+ [0, np.pi / 2, 0, 0, 0, np.pi / 2, 0, 0, np.pi / 2, 0, 0, 0, np.pi / 2, 0,]
+ )
+ _detuning_rotations = np.array([0, 0, 0, np.pi, 0, 0, 0, 0, 0, 0, np.pi, 0, 0, 0])
assert np.allclose(_offsets, sequence.offsets)
assert np.allclose(_rabi_rotations, sequence.rabi_rotations)
From 7da5975f7f07043a9c7041c1ee0e59dafe2ce174 Mon Sep 17 00:00:00 2001
From: Li Li
Date: Fri, 11 Dec 2020 21:33:42 +1100
Subject: [PATCH 6/9] black
---
tests/test_driven_controls.py | 38 +++++++++++++++++++----------------
1 file changed, 21 insertions(+), 17 deletions(-)
diff --git a/tests/test_driven_controls.py b/tests/test_driven_controls.py
index 13f47983..e7f1770e 100644
--- a/tests/test_driven_controls.py
+++ b/tests/test_driven_controls.py
@@ -298,13 +298,15 @@ def test_pretty_print():
durations=_durations,
)
- _pretty_rabi_rates = ",".join([
- str(_rabi_rate / _maximum_rabi_rate) for _rabi_rate in _rabi_rates
- ])
- _pretty_azimuthal_angles = ",".join([
- str(azimuthal_angle / np.pi) for azimuthal_angle in _azimuthal_angles
- ])
- _pretty_detunings = ",".join([str(detuning / _maximum_detuning) for detuning in _detunings])
+ _pretty_rabi_rates = ",".join(
+ [str(_rabi_rate / _maximum_rabi_rate) for _rabi_rate in _rabi_rates]
+ )
+ _pretty_azimuthal_angles = ",".join(
+ [str(azimuthal_angle / np.pi) for azimuthal_angle in _azimuthal_angles]
+ )
+ _pretty_detunings = ",".join(
+ [str(detuning / _maximum_detuning) for detuning in _detunings]
+ )
_pretty_durations = ",".join([str(duration / 3.0) for duration in _durations])
_pretty_string = []
@@ -338,10 +340,12 @@ def test_pretty_print():
)
_pretty_rabi_rates = ",".join(["0", "0", "0"])
- _pretty_azimuthal_angles = ",".join([
- str(azimuthal_angle / np.pi) for azimuthal_angle in _azimuthal_angles
- ])
- _pretty_detunings = ",".join([str(detuning / _maximum_detuning) for detuning in _detunings])
+ _pretty_azimuthal_angles = ",".join(
+ [str(azimuthal_angle / np.pi) for azimuthal_angle in _azimuthal_angles]
+ )
+ _pretty_detunings = ",".join(
+ [str(detuning / _maximum_detuning) for detuning in _detunings]
+ )
_pretty_durations = ",".join([str(duration / 3.0) for duration in _durations])
_pretty_string = []
@@ -374,12 +378,12 @@ def test_pretty_print():
durations=_durations,
)
- _pretty_rabi_rates = ",".join([
- str(_rabi_rate / _maximum_rabi_rate) for _rabi_rate in _rabi_rates
- ])
- _pretty_azimuthal_angles = ",".join([
- str(azimuthal_angle / np.pi) for azimuthal_angle in _azimuthal_angles
- ])
+ _pretty_rabi_rates = ",".join(
+ [str(_rabi_rate / _maximum_rabi_rate) for _rabi_rate in _rabi_rates]
+ )
+ _pretty_azimuthal_angles = ",".join(
+ [str(azimuthal_angle / np.pi) for azimuthal_angle in _azimuthal_angles]
+ )
_pretty_detunings = ",".join(["0", "0", "0"])
_pretty_durations = ",".join([str(duration / 3.0) for duration in _durations])
From e5dabd6f653238c862c8917b6b1d83cb876244f7 Mon Sep 17 00:00:00 2001
From: Li Li
Date: Fri, 11 Dec 2020 21:40:50 +1100
Subject: [PATCH 7/9] fix test
---
tests/test_driven_controls.py | 74 ++++++------
tests/test_dynamical_decoupling.py | 20 ++--
tests/test_predefined_dynamical_decoupling.py | 111 ++++++++----------
3 files changed, 91 insertions(+), 114 deletions(-)
diff --git a/tests/test_driven_controls.py b/tests/test_driven_controls.py
index 283852fd..e7f1770e 100644
--- a/tests/test_driven_controls.py
+++ b/tests/test_driven_controls.py
@@ -298,18 +298,16 @@ def test_pretty_print():
durations=_durations,
)
- _pretty_rabi_rates = [
- str(_rabi_rate / _maximum_rabi_rate) for _rabi_rate in _rabi_rates
- ]
- _pretty_azimuthal_angles = [
- str(azimuthal_angle / np.pi) for azimuthal_angle in _azimuthal_angles
- ]
- _pretty_detunings = [str(detuning / _maximum_detuning) for detuning in _detunings]
- _pretty_durations = [str(duration / 3.0) for duration in _durations]
- _pretty_rabi_rates = ",".join(_pretty_rabi_rates)
- _pretty_azimuthal_angles = ",".join(_pretty_azimuthal_angles)
- _pretty_detunings = ",".join(_pretty_detunings)
- _pretty_durations = ",".join(_pretty_durations)
+ _pretty_rabi_rates = ",".join(
+ [str(_rabi_rate / _maximum_rabi_rate) for _rabi_rate in _rabi_rates]
+ )
+ _pretty_azimuthal_angles = ",".join(
+ [str(azimuthal_angle / np.pi) for azimuthal_angle in _azimuthal_angles]
+ )
+ _pretty_detunings = ",".join(
+ [str(detuning / _maximum_detuning) for detuning in _detunings]
+ )
+ _pretty_durations = ",".join([str(duration / 3.0) for duration in _durations])
_pretty_string = []
_pretty_string.append(
@@ -323,9 +321,9 @@ def test_pretty_print():
)
_pretty_string.append("Durations = [{}] x 3.0".format(_pretty_durations))
- _pretty_string = "\n".join(_pretty_string)
+ expected_string = "\n".join(_pretty_string)
- assert str(driven_control) == _pretty_string
+ assert str(driven_control) == expected_string
_maximum_rabi_rate = 0.0
_maximum_detuning = 1.0
@@ -341,16 +339,14 @@ def test_pretty_print():
durations=_durations,
)
- _pretty_rabi_rates = ["0", "0", "0"]
- _pretty_azimuthal_angles = [
- str(azimuthal_angle / np.pi) for azimuthal_angle in _azimuthal_angles
- ]
- _pretty_detunings = [str(detuning / _maximum_detuning) for detuning in _detunings]
- _pretty_durations = [str(duration / 3.0) for duration in _durations]
- _pretty_rabi_rates = ",".join(_pretty_rabi_rates)
- _pretty_azimuthal_angles = ",".join(_pretty_azimuthal_angles)
- _pretty_detunings = ",".join(_pretty_detunings)
- _pretty_durations = ",".join(_pretty_durations)
+ _pretty_rabi_rates = ",".join(["0", "0", "0"])
+ _pretty_azimuthal_angles = ",".join(
+ [str(azimuthal_angle / np.pi) for azimuthal_angle in _azimuthal_angles]
+ )
+ _pretty_detunings = ",".join(
+ [str(detuning / _maximum_detuning) for detuning in _detunings]
+ )
+ _pretty_durations = ",".join([str(duration / 3.0) for duration in _durations])
_pretty_string = []
_pretty_string.append(
@@ -364,15 +360,15 @@ def test_pretty_print():
)
_pretty_string.append("Durations = [{}] x 3.0".format(_pretty_durations))
- _pretty_string = "\n".join(_pretty_string)
+ expected_string = "\n".join(_pretty_string)
- assert str(driven_control) == _pretty_string
+ assert str(driven_control) == expected_string
_maximum_rabi_rate = 2 * np.pi
_maximum_detuning = 0.0
_rabi_rates = [np.pi, 2 * np.pi, np.pi]
_azimuthal_angles = [0, np.pi / 2, -np.pi / 2]
- _detunings = [0, 0.0, 0]
+ _detunings = [0, 0, 0]
_durations = [1.0, 1.0, 1.0]
driven_control = DrivenControl(
@@ -382,18 +378,14 @@ def test_pretty_print():
durations=_durations,
)
- _pretty_rabi_rates = [
- str(_rabi_rate / _maximum_rabi_rate) for _rabi_rate in _rabi_rates
- ]
- _pretty_azimuthal_angles = [
- str(azimuthal_angle / np.pi) for azimuthal_angle in _azimuthal_angles
- ]
- _pretty_detunings = ["0", "0", "0"]
- _pretty_durations = [str(duration / 3.0) for duration in _durations]
- _pretty_rabi_rates = ",".join(_pretty_rabi_rates)
- _pretty_azimuthal_angles = ",".join(_pretty_azimuthal_angles)
- _pretty_detunings = ",".join(_pretty_detunings)
- _pretty_durations = ",".join(_pretty_durations)
+ _pretty_rabi_rates = ",".join(
+ [str(_rabi_rate / _maximum_rabi_rate) for _rabi_rate in _rabi_rates]
+ )
+ _pretty_azimuthal_angles = ",".join(
+ [str(azimuthal_angle / np.pi) for azimuthal_angle in _azimuthal_angles]
+ )
+ _pretty_detunings = ",".join(["0", "0", "0"])
+ _pretty_durations = ",".join([str(duration / 3.0) for duration in _durations])
_pretty_string = []
_pretty_string.append(
@@ -407,6 +399,6 @@ def test_pretty_print():
)
_pretty_string.append("Durations = [{}] x 3.0".format(_pretty_durations))
- _pretty_string = "\n".join(_pretty_string)
+ expected_string = "\n".join(_pretty_string)
- assert str(driven_control) == _pretty_string
+ assert str(driven_control) == expected_string
diff --git a/tests/test_dynamical_decoupling.py b/tests/test_dynamical_decoupling.py
index 46a2df12..cf82bfa0 100644
--- a/tests/test_dynamical_decoupling.py
+++ b/tests/test_dynamical_decoupling.py
@@ -242,9 +242,9 @@ def test_pretty_string_format():
)
)
- _pretty_string = "\n".join(_pretty_string)
+ expected_string = "\n".join(_pretty_string)
- assert _pretty_string == str(dd_sequence)
+ assert expected_string == str(dd_sequence)
dd_sequence = DynamicDecouplingSequence(
duration=_duration,
@@ -282,9 +282,9 @@ def test_pretty_string_format():
_detuning_rotations[2] / np.pi,
)
)
- _pretty_string = "\n".join(_pretty_string)
+ expected_string = "\n".join(_pretty_string)
- assert _pretty_string == str(dd_sequence)
+ assert expected_string == str(dd_sequence)
def test_conversion_to_driven_controls():
@@ -779,17 +779,13 @@ def test_free_evolution_conversion():
"""
_duration = 10.0
_name = "test_sequence"
- _offsets = []
- _rabi_rotations = []
- _azimuthal_angles = []
- _detuning_rotations = []
dd_sequence = DynamicDecouplingSequence(
duration=_duration,
- offsets=_offsets,
- rabi_rotations=_rabi_rotations,
- azimuthal_angles=_azimuthal_angles,
- detuning_rotations=_detuning_rotations,
+ offsets=[],
+ rabi_rotations=[],
+ azimuthal_angles=[],
+ detuning_rotations=[],
name=_name,
)
diff --git a/tests/test_predefined_dynamical_decoupling.py b/tests/test_predefined_dynamical_decoupling.py
index d48f3cb1..0fba4292 100644
--- a/tests/test_predefined_dynamical_decoupling.py
+++ b/tests/test_predefined_dynamical_decoupling.py
@@ -313,13 +313,14 @@ def test_walsh_sequence():
** binary_order[hamming_weight - 1 - i]
)
- walsh_relative_offsets = []
- for i in range(samples - 1):
- if walsh_array[i] != walsh_array[i + 1]:
- walsh_relative_offsets.append((i + 1) * (1.0 / samples))
- walsh_relative_offsets = np.array(walsh_relative_offsets, dtype=np.float)
+ walsh_relative_offsets = np.array(
+ [
+ (i + 1) * (1.0 / samples)
+ for i in range(samples - 1)
+ if walsh_array[i] != walsh_array[i + 1]
+ ]
+ )
_offsets = duration * walsh_relative_offsets
- _offsets = np.array(_offsets)
_rabi_rotations = np.pi * np.ones(_offsets.shape)
_azimuthal_angles = np.zeros(_offsets.shape)
@@ -446,8 +447,9 @@ def test_x_concatenated_sequence():
)
_spacing = duration / (2 ** concatenation_order)
- _offsets = [_spacing, 3 * _spacing, 4 * _spacing, 5 * _spacing, 7 * _spacing]
- _offsets = np.array(_offsets)
+ _offsets = np.array(
+ [_spacing, 3 * _spacing, 4 * _spacing, 5 * _spacing, 7 * _spacing]
+ )
_rabi_rotations = np.pi * np.ones(_offsets.shape)
_azimuthal_angles = np.zeros(_offsets.shape)
@@ -490,59 +492,46 @@ def test_xy_concatenated_sequence():
)
_spacing = duration / (2 ** (concatenation_order * 2))
- _offsets = [
- _spacing,
- 2 * _spacing,
- 3 * _spacing,
- 4 * _spacing,
- 5 * _spacing,
- 6 * _spacing,
- 7 * _spacing,
- 9 * _spacing,
- 10 * _spacing,
- 11 * _spacing,
- 12 * _spacing,
- 13 * _spacing,
- 14 * _spacing,
- 15 * _spacing,
- ]
- _offsets = np.array(_offsets)
- _rabi_rotations = [
- np.pi,
- np.pi,
- np.pi,
- 0.0,
- np.pi,
- np.pi,
- np.pi,
- np.pi,
- np.pi,
- np.pi,
- 0,
- np.pi,
- np.pi,
- np.pi,
- ]
- _rabi_rotations = np.array(_rabi_rotations)
- _azimuthal_angles = [
- 0,
- np.pi / 2,
- 0,
- 0,
- 0,
- np.pi / 2,
- 0,
- 0,
- np.pi / 2,
- 0,
- 0,
- 0,
- np.pi / 2,
- 0,
- ]
- _azimuthal_angles = np.array(_azimuthal_angles)
- _detuning_rotations = [0, 0, 0, np.pi, 0, 0, 0, 0, 0, 0, np.pi, 0, 0, 0]
- _detuning_rotations = np.array(_detuning_rotations)
+ _offsets = np.array(
+ [
+ _spacing,
+ 2 * _spacing,
+ 3 * _spacing,
+ 4 * _spacing,
+ 5 * _spacing,
+ 6 * _spacing,
+ 7 * _spacing,
+ 9 * _spacing,
+ 10 * _spacing,
+ 11 * _spacing,
+ 12 * _spacing,
+ 13 * _spacing,
+ 14 * _spacing,
+ 15 * _spacing,
+ ]
+ )
+ _rabi_rotations = np.array(
+ [
+ np.pi,
+ np.pi,
+ np.pi,
+ 0.0,
+ np.pi,
+ np.pi,
+ np.pi,
+ np.pi,
+ np.pi,
+ np.pi,
+ 0,
+ np.pi,
+ np.pi,
+ np.pi,
+ ]
+ )
+ _azimuthal_angles = np.array(
+ [0, np.pi / 2, 0, 0, 0, np.pi / 2, 0, 0, np.pi / 2, 0, 0, 0, np.pi / 2, 0,]
+ )
+ _detuning_rotations = np.array([0, 0, 0, np.pi, 0, 0, 0, 0, 0, 0, np.pi, 0, 0, 0])
assert np.allclose(_offsets, sequence.offsets)
assert np.allclose(_rabi_rotations, sequence.rabi_rotations)
From f98778bce192b386b8ea4e675f6ff9d257b598cf Mon Sep 17 00:00:00 2001
From: Li Li
Date: Fri, 18 Dec 2020 14:21:30 +1100
Subject: [PATCH 8/9] doc
---
.../driven_controls/driven_control.py | 23 ++++++++-----------
1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/qctrlopencontrols/driven_controls/driven_control.py b/qctrlopencontrols/driven_controls/driven_control.py
index 2a20bb76..4f9b07ec 100644
--- a/qctrlopencontrols/driven_controls/driven_control.py
+++ b/qctrlopencontrols/driven_controls/driven_control.py
@@ -24,7 +24,6 @@
import numpy as np
-from ..exceptions import ArgumentsValueError
from ..utils import (
Coordinate,
FileFormat,
@@ -380,9 +379,8 @@ def _export_to_qctrl_expanded_format(
Parameters
----------
- filename : str, optional
+ filename : str
Name and path of the file to save the control into.
- Defaults to None
file_type : str, optional
One of 'CSV' or 'JSON'; defaults to 'CSV'.
coordinates : str, optional
@@ -397,10 +395,12 @@ def _export_to_qctrl_expanded_format(
self.maximum_rabi_rate
] * self.number_of_segments
field_names = sorted(control_info.keys())
+
+ # note that the newline parameter here is necessary
+ # see details at https://docs.python.org/3/library/csv.html#id3
with open(filename, "w", newline="") as file:
writer = csv.DictWriter(file, fieldnames=field_names)
writer.writeheader()
-
for index in range(self.number_of_segments):
writer.writerow(
{name: control_info[name][index] for name in field_names}
@@ -529,18 +529,13 @@ def export(
method of the ``qctrl-visualizer`` package. It has keywords 'Rabi rate'
and 'Detuning' for 'cylindrical' coordinates and 'X amplitude', 'Y amplitude',
and 'Detuning' for 'cartesian' coordinates.
-
- Raises
- ------
- ArgumentsValueError
- Raised when an argument is invalid.
"""
- if coordinates not in [v.value for v in Coordinate]:
- raise ArgumentsValueError(
- "Unsupported coordinates provided: ",
- arguments={"coordinates": coordinates},
- )
+ check_arguments(
+ coordinates not in [v.value for v in Coordinate],
+ "Unsupported coordinates provided: ",
+ {"coordinates": coordinates},
+ )
if dimensionless_rabi_rate:
normalizer = self.maximum_rabi_rate
From ae72cc2cfc8adf334541bfb97af346266da5edaf Mon Sep 17 00:00:00 2001
From: Li Li
Date: Fri, 18 Dec 2020 14:30:49 +1100
Subject: [PATCH 9/9] doc & fix
---
qctrlopencontrols/driven_controls/driven_control.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/qctrlopencontrols/driven_controls/driven_control.py b/qctrlopencontrols/driven_controls/driven_control.py
index 4f9b07ec..7c7ee020 100644
--- a/qctrlopencontrols/driven_controls/driven_control.py
+++ b/qctrlopencontrols/driven_controls/driven_control.py
@@ -337,8 +337,8 @@ def _qctrl_expanded_export_content(self, coordinates: str) -> Dict:
Parameters
----------
coordinates : str, optional
- Indicates the co-ordinate system requested. Must be one of
- 'cylindrical', 'cartesian' or 'polar'. Defaults to 'cylindrical'.
+ Indicates the co-ordinate system requested. Must be
+ 'cylindrical'or 'cartesian'. Defaults to 'cylindrical'.
Returns
-------
@@ -532,7 +532,7 @@ def export(
"""
check_arguments(
- coordinates not in [v.value for v in Coordinate],
+ coordinates in [v.value for v in Coordinate],
"Unsupported coordinates provided: ",
{"coordinates": coordinates},
)