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}, )