From 7364518d731b553a715fbaf1e21cee8ff9fac551 Mon Sep 17 00:00:00 2001 From: Rajib Chakravorty Date: Fri, 7 Jun 2019 18:10:08 +1000 Subject: [PATCH 1/4] Public methods are bundled as __all__; changed ported over to notebooks; base object removed; repr method created --- examples/export_a_dds_to_qiskit.ipynb | 6 +- qctrlopencontrols/__init__.py | 23 +- qctrlopencontrols/base/__init__.py | 4 +- qctrlopencontrols/base/qctrl_object.py | 107 --------- qctrlopencontrols/base/utils.py | 63 ++++++ qctrlopencontrols/cirq/__init__.py | 3 + qctrlopencontrols/driven_controls/__init__.py | 21 +- .../driven_controls/constants.py | 4 +- .../driven_controls/driven_control.py | 45 +++- .../driven_controls/predefined.py | 36 +-- .../dynamic_decoupling_sequences/__init__.py | 6 + .../dynamic_decoupling_sequences/constants.py | 6 +- .../driven_controls.py | 6 +- .../dynamic_decoupling_sequence.py | 52 ++++- .../predefined.py | 102 ++++----- qctrlopencontrols/exceptions/__init__.py | 2 + qctrlopencontrols/globals/__init__.py | 3 + qctrlopencontrols/qiskit/__init__.py | 4 +- qctrlopencontrols/qiskit/quantum_circuit.py | 2 +- tests/test_driven_controls.py | 2 +- tests/test_dynamical_decoupling.py | 11 +- tests/test_predefined_driven_controls.py | 71 +++--- tests/test_predefined_dynamical_decoupling.py | 209 ++++++++++-------- tests/test_qctrl_object.py | 66 ------ tests/test_qiskit_sequence.py | 4 +- 25 files changed, 446 insertions(+), 412 deletions(-) delete mode 100644 qctrlopencontrols/base/qctrl_object.py create mode 100644 qctrlopencontrols/base/utils.py delete mode 100644 tests/test_qctrl_object.py diff --git a/examples/export_a_dds_to_qiskit.ipynb b/examples/export_a_dds_to_qiskit.ipynb index a5c254fd..7b07491a 100755 --- a/examples/export_a_dds_to_qiskit.ipynb +++ b/examples/export_a_dds_to_qiskit.ipynb @@ -31,7 +31,7 @@ "from matplotlib.gridspec import GridSpec\n", "\n", "#Q-CTRL Open Controls\n", - "from qctrlopencontrols import new_predefined_dds, convert_dds_to_quantum_circuit\n", + "from qctrlopencontrols import new_predefined_dds, convert_dds_to_qiskit_quantum_circuit\n", "\n", "#Qiskit\n", "##To define a backend (simulated or real)\n", @@ -166,7 +166,7 @@ "\n", "## convert the quadratic sequence to QuantumCircuit\n", "\n", - "quadratic_quantum_circuit = convert_dds_to_quantum_circuit(\n", + "quadratic_quantum_circuit = convert_dds_to_qiskit_quantum_circuit(\n", " dynamic_decoupling_sequence=quadratic_sequence,\n", " target_qubits=target_qubits,\n", " gate_time=gate_time,\n", @@ -176,7 +176,7 @@ "\n", "## convert the ramsey sequence to QuantumCircuit\n", "circuit_name = 'ramsey-sequence-circuit'\n", - "ramsey_quantum_circuit = convert_dds_to_quantum_circuit(\n", + "ramsey_quantum_circuit = convert_dds_to_qiskit_quantum_circuit(\n", " dynamic_decoupling_sequence=ramsey_sequence,\n", " target_qubits=target_qubits,\n", " gate_time=gate_time,\n", diff --git a/qctrlopencontrols/__init__.py b/qctrlopencontrols/__init__.py index e586f815..7bc0bfeb 100644 --- a/qctrlopencontrols/__init__.py +++ b/qctrlopencontrols/__init__.py @@ -14,14 +14,21 @@ """ ================= -qcrtlopencontrols +qctrlopencontrols ================= """ -from .dynamic_decoupling_sequences import (DynamicDecouplingSequence, - new_predefined_dds, - convert_dds_to_driven_control) -from .driven_controls import DrivenControl, new_predefined_driven_control -from .qiskit import convert_dds_to_quantum_circuit -from .cirq import (convert_dds_to_cirq_circuit, - convert_dds_to_cirq_schedule) +from . import dynamic_decoupling_sequences +from .dynamic_decoupling_sequences import * +from . import driven_controls +from .driven_controls import * +from . import qiskit +from .qiskit import * +from . import cirq +from .cirq import * + +__all__ = [] +__all__.extend(dynamic_decoupling_sequences.__all__) +__all__.extend(driven_controls.__all__) +__all__.extend(qiskit.__all__) +__all__.extend(cirq.__all__) diff --git a/qctrlopencontrols/base/__init__.py b/qctrlopencontrols/base/__init__.py index 705fccab..68a2205d 100644 --- a/qctrlopencontrols/base/__init__.py +++ b/qctrlopencontrols/base/__init__.py @@ -18,4 +18,6 @@ =========== """ -from .qctrl_object import QctrlObject +from .utils import create_repr_from_attributes + +__all__ = ['create_repr_from_attributes'] diff --git a/qctrlopencontrols/base/qctrl_object.py b/qctrlopencontrols/base/qctrl_object.py deleted file mode 100644 index baf276a7..00000000 --- a/qctrlopencontrols/base/qctrl_object.py +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright 2019 Q-CTRL Pty Ltd & Q-CTRL Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -================= -base.qctrl_object -================= -""" - -from qctrlopencontrols.exceptions import ArgumentsValueError - - -class QctrlObject(object): - """Base class for all classes in QCtrl library. - - Parameters - ---------- - base_attributes : list, optional - List of names of attributes. Defaults to None - - Raises - ------ - ArgumentsValueError - If base_attributes is not list type or empty list - If any of the base_attributes is not str type - - Notes - ----- - If the base_attributes is None, __repr__ and __str__ - return a default string "No attributes provided for object - of class self.__class__.__name__" - """ - - def __init__(self, base_attributes=None): - - self.base_attributes = base_attributes - - if self.base_attributes is not None: - - if not isinstance(base_attributes, list): - - raise ArgumentsValueError('Attributes must be provided as a list object', - {'base_attributes': self.base_attributes}, - extras={'base_attributes_type': type(base_attributes)}) - - if not self.base_attributes: - raise ArgumentsValueError('No attributes provided', - {'base_attributes': self.base_attributes}) - - for attribute in self.base_attributes: - - if not isinstance(attribute, str): - raise ArgumentsValueError('Each attribute must be a string. Found ' - '{0} type.'.format(type(attribute)), - {'attribute': attribute, - 'attribute_type': type(attribute)}, - extras={'base_attributes': self.base_attributes}) - - def __repr__(self): - """The returned string looks like a valid Python expression that could be used - to recreate the object, including default arguments. - - - Returns - ------- - str - String representation of the object including the values of the arguments. - However, if the base_attributes is None, return a fixed string "No attributes - provided for object of class self.__class__.__name__" - """ - - if self.base_attributes is None: - - return "No attributes provided for object of class {0.__class__.__name__!s}".format( - self) - - repr_string = '{0.__class__.__name__!s}('.format(self) - - attributes_string = ','.join('{0}={1}'.format(attribute, - repr(getattr(self, attribute))) - for attribute in self.base_attributes) - repr_string += attributes_string - repr_string += ')' - - return repr_string - - def __str__(self): - """Returns a string representation of the object. - - Returns - ------- - str - The object definition as a string - """ - - return str(self.__repr__()) diff --git a/qctrlopencontrols/base/utils.py b/qctrlopencontrols/base/utils.py new file mode 100644 index 00000000..0cb30557 --- /dev/null +++ b/qctrlopencontrols/base/utils.py @@ -0,0 +1,63 @@ +# Copyright 2019 Q-CTRL Pty Ltd & Q-CTRL Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +========== +base.utils +========== +""" + +from qctrlopencontrols.exceptions import ArgumentsValueError + + +def create_repr_from_attributes(class_name, **attributes): + + """Returns a string representation of an object + + Parameters + ---------- + class_name : str + The name of the class + attributes : dict + A dict of attributes in (attribute_name:attribute_value) format + + Returns + ------- + str + A string representing the attributes + + Raises + ------ + ArgumentsValueError + If no class name is provided or any of the attribute name is not string type + """ + + if not attributes: + return "No attributes provided for object of class {0}".format(class_name) + + for attribute in attributes: + if not isinstance(attribute, str): + raise ArgumentsValueError('Each attribute name must be a string. Found ' + '{0} type.'.format(type(attribute)), + {'attribute': attribute, + 'type(attribute)': type(attribute)}) + + repr_string = '{0}('.format(class_name) + attributes_string = ','.join('{0}={1}'.format(attribute, + repr(attributes[attribute])) + for attribute in attributes) + repr_string += attributes_string + repr_string += ')' + + return repr_string diff --git a/qctrlopencontrols/cirq/__init__.py b/qctrlopencontrols/cirq/__init__.py index b003e992..524f0c0d 100644 --- a/qctrlopencontrols/cirq/__init__.py +++ b/qctrlopencontrols/cirq/__init__.py @@ -20,3 +20,6 @@ from .circuit import convert_dds_to_cirq_circuit from .schedule import convert_dds_to_cirq_schedule + +__all__ = ['convert_dds_to_cirq_circuit', + 'convert_dds_to_cirq_schedule'] diff --git a/qctrlopencontrols/driven_controls/__init__.py b/qctrlopencontrols/driven_controls/__init__.py index 779ff29a..b7161012 100644 --- a/qctrlopencontrols/driven_controls/__init__.py +++ b/qctrlopencontrols/driven_controls/__init__.py @@ -13,9 +13,9 @@ # limitations under the License. """ -============= +====================== driven_controls module -============= +====================== """ from .driven_control import DrivenControl @@ -31,12 +31,11 @@ SCROFULOUS, CORPSE_IN_SCROFULOUS) -from .predefined import ( - new_predefined_driven_control, - new_primitive_control, new_wimperis_1_control, new_solovay_kitaev_1_control, - new_compensating_for_off_resonance_with_a_pulse_sequence_control, - new_compensating_for_off_resonance_with_a_pulse_sequence_with_solovay_kitaev_control, - new_compensating_for_off_resonance_with_a_pulse_sequence_with_wimperis_control, - new_short_composite_rotation_for_undoing_length_over_and_under_shoot_control, - new_walsh_amplitude_modulated_filter_1_control, - new_corpse_in_scrofulous_control) +from .predefined import new_predefined_driven_control + +__all__ = ['UPPER_BOUND_RABI_RATE', 'UPPER_BOUND_DETUNING_RATE', + 'UPPER_BOUND_DURATION', 'LOWER_BOUND_DURATION', 'UPPER_BOUND_SEGMENTS', + 'PRIMITIVE', 'BB1', 'SK1', + 'WAMF1', 'CORPSE', 'CORPSE_IN_SK1', 'CORPSE_IN_BB1', 'SCROFULOUS', + 'CORPSE_IN_SCROFULOUS', 'new_predefined_driven_control', + 'DrivenControl'] diff --git a/qctrlopencontrols/driven_controls/constants.py b/qctrlopencontrols/driven_controls/constants.py index 5ef657a8..6952a751 100644 --- a/qctrlopencontrols/driven_controls/constants.py +++ b/qctrlopencontrols/driven_controls/constants.py @@ -13,9 +13,9 @@ # limitations under the License. """ -================ +========================== driven_controls.constants -================ +========================== """ #maximum and minimum values diff --git a/qctrlopencontrols/driven_controls/driven_control.py b/qctrlopencontrols/driven_controls/driven_control.py index 874de8b6..d73b8d64 100644 --- a/qctrlopencontrols/driven_controls/driven_control.py +++ b/qctrlopencontrols/driven_controls/driven_control.py @@ -21,7 +21,7 @@ import numpy as np from qctrlopencontrols.exceptions import ArgumentsValueError -from qctrlopencontrols.base import QctrlObject +from qctrlopencontrols.base import create_repr_from_attributes from qctrlopencontrols.globals import ( QCTRL_EXPANDED, CSV, JSON, CARTESIAN, CYLINDRICAL) @@ -31,7 +31,7 @@ UPPER_BOUND_DURATION, LOWER_BOUND_DURATION) -class DrivenControl(QctrlObject): #pylint: disable=too-few-public-methods +class DrivenControl(object): #pylint: disable=too-few-public-methods """ Creates a driven control. A driven is a set of segments made up of amplitude vectors and corresponding durations. @@ -136,17 +136,12 @@ def __init__(self, + ' than zero.', {'durations': self.durations}) - self.number_of_segments = rabi_rates.shape[0] if self.number_of_segments > UPPER_BOUND_SEGMENTS: raise ArgumentsValueError( 'The number of segments must be smaller than the upper bound:' + str(UPPER_BOUND_SEGMENTS), {'number_of_segments': self.number_of_segments}) - super(DrivenControl, self).__init__( - base_attributes=['rabi_rates', 'azimuthal_angles', 'detunings', - 'durations', 'name']) - if self.maximum_rabi_rate > UPPER_BOUND_RABI_RATE: raise ArgumentsValueError( 'Maximum rabi rate of segments must be smaller than the upper bound: ' @@ -169,6 +164,19 @@ def __init__(self, + str(LOWER_BOUND_DURATION), {'minimum_duration': self.minimum_duration}) + @property + def number_of_segments(self): + + """Returns the number of segments + + Returns + ------- + int + The number of segments in the driven control + """ + + return self.rabi_rates.shape[0] + @property def maximum_rabi_rate(self): """Returns the maximum rabi rate of the control @@ -594,6 +602,29 @@ def __str__(self): return driven_control_string + def __repr__(self): + + """Returns a string representation for the object. The returned string looks like a valid + Python expression that could be used to recreate the object, including default arguments. + + Returns + ------- + str + String representation of the object including the values of the arguments. + """ + + attributes = { + 'rabi_rates': self.rabi_rates, + 'azimuthal_angles': self.azimuthal_angles, + 'detunings': self.detunings, + 'durations': self.durations, + 'name': self.name + } + + class_name = '{0.__class__.__name__!s}'.format(self) + + return create_repr_from_attributes(class_name, **attributes) + if __name__ == '__main__': pass diff --git a/qctrlopencontrols/driven_controls/predefined.py b/qctrlopencontrols/driven_controls/predefined.py index c47d9b6e..748f33be 100644 --- a/qctrlopencontrols/driven_controls/predefined.py +++ b/qctrlopencontrols/driven_controls/predefined.py @@ -73,30 +73,30 @@ def new_predefined_driven_control( # Forced to import here to avoid cyclic imports, need to review # Raise error if the input driven_control_type is not known if scheme == PRIMITIVE: - driven_control = new_primitive_control(**kwargs) + driven_control = _new_primitive_control(**kwargs) elif scheme == BB1: - driven_control = new_wimperis_1_control(**kwargs) + driven_control = _new_wimperis_1_control(**kwargs) elif scheme == SK1: - driven_control = new_solovay_kitaev_1_control(**kwargs) + driven_control = _new_solovay_kitaev_1_control(**kwargs) elif scheme == WAMF1: - driven_control = new_walsh_amplitude_modulated_filter_1_control(**kwargs) + driven_control = _new_walsh_amplitude_modulated_filter_1_control(**kwargs) elif scheme == CORPSE: - driven_control = new_compensating_for_off_resonance_with_a_pulse_sequence_control( + driven_control = _new_compensating_for_off_resonance_with_a_pulse_sequence_control( **kwargs) elif scheme == CORPSE_IN_BB1: driven_control = \ - new_compensating_for_off_resonance_with_a_pulse_sequence_with_wimperis_control( + _new_compensating_for_off_resonance_with_a_pulse_sequence_with_wimperis_control( **kwargs) elif scheme == \ CORPSE_IN_SK1: driven_control = \ - new_compensating_for_off_resonance_with_a_pulse_sequence_with_solovay_kitaev_control( + _new_compensating_for_off_resonance_with_a_pulse_sequence_with_solovay_kitaev_control( **kwargs) elif scheme == SCROFULOUS: driven_control = \ - new_short_composite_rotation_for_undoing_length_over_and_under_shoot_control(**kwargs) + _new_short_composite_rotation_for_undoing_length_over_and_under_shoot_control(**kwargs) elif scheme == CORPSE_IN_SCROFULOUS: - driven_control = new_corpse_in_scrofulous_control(**kwargs) + driven_control = _new_corpse_in_scrofulous_control(**kwargs) else: raise ArgumentsValueError( 'Unknown predefined pulse type. See help(new_predefined_driven_control) to display all' @@ -204,7 +204,7 @@ def _derive_segments(angles, amplitude=2. * np.pi): return segments -def new_primitive_control( +def _new_primitive_control( rabi_rotation=None, azimuthal_angle=0., maximum_rabi_rate=2. * np.pi, @@ -240,7 +240,7 @@ def new_primitive_control( **kwargs) -def new_wimperis_1_control( +def _new_wimperis_1_control( rabi_rotation=None, azimuthal_angle=0., maximum_rabi_rate=2. * np.pi, @@ -285,7 +285,7 @@ def new_wimperis_1_control( durations=durations, **kwargs) -def new_solovay_kitaev_1_control( +def _new_solovay_kitaev_1_control( rabi_rotation=None, azimuthal_angle=0., maximum_rabi_rate=2. * np.pi, @@ -330,7 +330,7 @@ def new_solovay_kitaev_1_control( **kwargs) -def new_short_composite_rotation_for_undoing_length_over_and_under_shoot_control( # pylint: disable=invalid-name +def _new_short_composite_rotation_for_undoing_length_over_and_under_shoot_control( # pylint: disable=invalid-name rabi_rotation=None, azimuthal_angle=0., maximum_rabi_rate=2. * np.pi, @@ -410,7 +410,7 @@ def degrees_to_radians(angle_in_degrees): **kwargs) -def new_compensating_for_off_resonance_with_a_pulse_sequence_control( # pylint: disable=invalid-name +def _new_compensating_for_off_resonance_with_a_pulse_sequence_control( # pylint: disable=invalid-name rabi_rotation=None, azimuthal_angle=0., maximum_rabi_rate=2. * np.pi, @@ -455,7 +455,7 @@ def new_compensating_for_off_resonance_with_a_pulse_sequence_control( # pylint: **kwargs) -def new_compensating_for_off_resonance_with_a_pulse_sequence_with_wimperis_control( # pylint: disable=invalid-name +def _new_compensating_for_off_resonance_with_a_pulse_sequence_with_wimperis_control( # pylint: disable=invalid-name rabi_rotation=None, azimuthal_angle=0., maximum_rabi_rate=2. * np.pi, @@ -505,7 +505,7 @@ def new_compensating_for_off_resonance_with_a_pulse_sequence_with_wimperis_contr **kwargs) -def new_compensating_for_off_resonance_with_a_pulse_sequence_with_solovay_kitaev_control( # pylint: disable=invalid-name +def _new_compensating_for_off_resonance_with_a_pulse_sequence_with_solovay_kitaev_control( # pylint: disable=invalid-name rabi_rotation=None, azimuthal_angle=0., maximum_rabi_rate=2. * np.pi, @@ -554,7 +554,7 @@ def new_compensating_for_off_resonance_with_a_pulse_sequence_with_solovay_kitaev **kwargs) -def new_corpse_in_scrofulous_control( # pylint: disable=invalid-name +def _new_corpse_in_scrofulous_control( # pylint: disable=invalid-name rabi_rotation=None, azimuthal_angle=0., maximum_rabi_rate=2. * np.pi, @@ -647,7 +647,7 @@ def degrees_to_radians(angle_in_degrees): **kwargs) -def new_walsh_amplitude_modulated_filter_1_control( # pylint: disable=invalid-name +def _new_walsh_amplitude_modulated_filter_1_control( # pylint: disable=invalid-name rabi_rotation=None, azimuthal_angle=0., maximum_rabi_rate=2. * np.pi, diff --git a/qctrlopencontrols/dynamic_decoupling_sequences/__init__.py b/qctrlopencontrols/dynamic_decoupling_sequences/__init__.py index a71c2aa7..c81a5b79 100644 --- a/qctrlopencontrols/dynamic_decoupling_sequences/__init__.py +++ b/qctrlopencontrols/dynamic_decoupling_sequences/__init__.py @@ -27,3 +27,9 @@ from .dynamic_decoupling_sequence import DynamicDecouplingSequence from .predefined import new_predefined_dds from .driven_controls import convert_dds_to_driven_control + +__all__ = ['UPPER_BOUND_OFFSETS', 'SPIN_ECHO', 'CARR_PURCELL', + 'CARR_PURCELL_MEIBOOM_GILL', 'UHRIG_SINGLE_AXIS', + 'PERIODIC_SINGLE_AXIS', 'WALSH_SINGLE_AXIS', 'QUADRATIC', + 'X_CONCATENATED', 'XY_CONCATENATED', 'DynamicDecouplingSequence', + 'new_predefined_dds', 'convert_dds_to_driven_control'] diff --git a/qctrlopencontrols/dynamic_decoupling_sequences/constants.py b/qctrlopencontrols/dynamic_decoupling_sequences/constants.py index d4404887..2fa06ff7 100644 --- a/qctrlopencontrols/dynamic_decoupling_sequences/constants.py +++ b/qctrlopencontrols/dynamic_decoupling_sequences/constants.py @@ -13,9 +13,9 @@ # limitations under the License. """ -=================== -sequences.constants -=================== +====================================== +dynamic_decoupling_sequences.constants +====================================== """ UPPER_BOUND_OFFSETS = 10000 diff --git a/qctrlopencontrols/dynamic_decoupling_sequences/driven_controls.py b/qctrlopencontrols/dynamic_decoupling_sequences/driven_controls.py index 228dc192..092c9e4e 100644 --- a/qctrlopencontrols/dynamic_decoupling_sequences/driven_controls.py +++ b/qctrlopencontrols/dynamic_decoupling_sequences/driven_controls.py @@ -13,9 +13,9 @@ # limitations under the License. """ -========================= -sequences.driven_controls -========================= +============================================= +dynamic_decoupling_sequences.driven_controls +============================================= """ import numpy as np diff --git a/qctrlopencontrols/dynamic_decoupling_sequences/dynamic_decoupling_sequence.py b/qctrlopencontrols/dynamic_decoupling_sequences/dynamic_decoupling_sequence.py index 61f13e0c..6cb551fb 100644 --- a/qctrlopencontrols/dynamic_decoupling_sequences/dynamic_decoupling_sequence.py +++ b/qctrlopencontrols/dynamic_decoupling_sequences/dynamic_decoupling_sequence.py @@ -13,14 +13,14 @@ # limitations under the License. """ -=================== -sequences.sequences -=================== +======================================================== +dynamic_decoupling_sequences.dynamic_decoupling_sequence +======================================================== """ import numpy as np -from qctrlopencontrols.base import QctrlObject +from qctrlopencontrols.base import create_repr_from_attributes from qctrlopencontrols.exceptions import ArgumentsValueError from qctrlopencontrols.globals import ( @@ -30,7 +30,7 @@ from .driven_controls import convert_dds_to_driven_control -class DynamicDecouplingSequence(QctrlObject): #pylint: disable=too-few-public-methods +class DynamicDecouplingSequence(object): #pylint: disable=too-few-public-methods """ Create a dynamic decoupling sequence. Can be made of perfect operations, or realistic pulses. @@ -72,7 +72,7 @@ def __init__(self, detuning_rotations=None, name=None ): - + """ super(DynamicDecouplingSequence, self).__init__([ 'duration', 'offsets', @@ -80,6 +80,7 @@ def __init__(self, 'azimuthal_angles', 'detuning_rotations', 'name']) + """ self.duration = duration if self.duration <= 0.: @@ -117,8 +118,6 @@ def __init__(self, self.azimuthal_angles = np.array(azimuthal_angles, dtype=np.float) self.detuning_rotations = np.array(detuning_rotations, dtype=np.float) - self.number_of_offsets = len(self.offsets) - if len(self.rabi_rotations) != self.number_of_offsets: raise ArgumentsValueError( 'rabi rotations must have the same length as offsets. ', @@ -143,6 +142,19 @@ def __init__(self, if self.name is not None: self.name = str(self.name) + @property + def number_of_offsets(self): + + """Returns the number of offsets + + Returns + ------ + int + The number of offsets in the dynamic decoupling sequence + """ + + return len(self.offsets) + def get_plot_formatted_arrays(self, plot_format=MATPLOTLIB): """Gets arrays for plotting a pulse. @@ -206,6 +218,30 @@ def get_plot_formatted_arrays(self, plot_format=MATPLOTLIB): return plot_data + def __repr__(self): + + """Returns a string representation for the object. The returned string looks like a valid + Python expression that could be used to recreate the object, including default arguments. + + Returns + ------- + str + String representation of the object including the values of the arguments. + """ + + attributes = { + 'duration': self.duration, + 'offsets': self.offsets, + 'rabi_rotations': self.rabi_rotations, + 'azimuthal_angles': self.azimuthal_angles, + 'detuning_rotations': self.detuning_rotations, + 'name': self.name + } + + class_name = '{0.__class__.__name__!s}'.format(self) + + return create_repr_from_attributes(class_name, **attributes) + def __str__(self): """Prepares a friendly string format for a Dynamic Decoupling Sequence """ diff --git a/qctrlopencontrols/dynamic_decoupling_sequences/predefined.py b/qctrlopencontrols/dynamic_decoupling_sequences/predefined.py index b4d2e375..27b4a6bd 100644 --- a/qctrlopencontrols/dynamic_decoupling_sequences/predefined.py +++ b/qctrlopencontrols/dynamic_decoupling_sequences/predefined.py @@ -13,9 +13,9 @@ # limitations under the License. """ -=================== -sequence.predefined -=================== +======================================== +dynamic_decoupling_sequences.predefined +======================================== """ import numpy as np @@ -69,25 +69,25 @@ def new_predefined_dds(scheme=SPIN_ECHO, **kwargs): """ if scheme == RAMSEY: - sequence = new_ramsey_sequence(**kwargs) + sequence = _new_ramsey_sequence(**kwargs) elif scheme == SPIN_ECHO: - sequence = new_spin_echo_sequence(**kwargs) + sequence = _new_spin_echo_sequence(**kwargs) elif scheme == CARR_PURCELL: - sequence = new_carr_purcell_sequence(**kwargs) + sequence = _new_carr_purcell_sequence(**kwargs) elif scheme == CARR_PURCELL_MEIBOOM_GILL: - sequence = new_carr_purcell_meiboom_gill_sequence(**kwargs) + sequence = _new_carr_purcell_meiboom_gill_sequence(**kwargs) elif scheme == UHRIG_SINGLE_AXIS: - sequence = new_uhrig_single_axis_sequence(**kwargs) + sequence = _new_uhrig_single_axis_sequence(**kwargs) elif scheme == PERIODIC_SINGLE_AXIS: - sequence = new_periodic_single_axis_sequence(**kwargs) + sequence = _new_periodic_single_axis_sequence(**kwargs) elif scheme == WALSH_SINGLE_AXIS: - sequence = new_walsh_single_axis_sequence(**kwargs) + sequence = _new_walsh_single_axis_sequence(**kwargs) elif scheme == QUADRATIC: - sequence = new_quadratic_sequence(**kwargs) + sequence = _new_quadratic_sequence(**kwargs) elif scheme == X_CONCATENATED: - sequence = new_x_concatenated_sequence(**kwargs) + sequence = _new_x_concatenated_sequence(**kwargs) elif scheme == XY_CONCATENATED: - sequence = new_xy_concatenated_sequence(**kwargs) + sequence = _new_xy_concatenated_sequence(**kwargs) # Raise an error if the input sequence is not known else: raise ArgumentsValueError( @@ -131,9 +131,9 @@ def _check_duration(duration): return duration -def new_ramsey_sequence(duration=None, - pre_post_rotation=False, - **kwargs): +def _new_ramsey_sequence(duration=None, + pre_post_rotation=False, + **kwargs): """Ramsey sequence @@ -179,9 +179,9 @@ def new_ramsey_sequence(duration=None, **kwargs) -def new_spin_echo_sequence(duration=None, - pre_post_rotation=False, - **kwargs): +def _new_spin_echo_sequence(duration=None, + pre_post_rotation=False, + **kwargs): """Spin Echo Sequence. @@ -227,10 +227,10 @@ def new_spin_echo_sequence(duration=None, **kwargs) -def new_carr_purcell_sequence(duration=None, - number_of_offsets=None, - pre_post_rotation=False, - **kwargs): +def _new_carr_purcell_sequence(duration=None, + number_of_offsets=None, + pre_post_rotation=False, + **kwargs): """Carr-Purcell Sequence. @@ -285,10 +285,10 @@ def new_carr_purcell_sequence(duration=None, detuning_rotations=detuning_rotations, **kwargs) -def new_carr_purcell_meiboom_gill_sequence(duration=None, # pylint: disable=invalid-name - number_of_offsets=None, - pre_post_rotation=False, - **kwargs): +def _new_carr_purcell_meiboom_gill_sequence(duration=None, # pylint: disable=invalid-name + number_of_offsets=None, + pre_post_rotation=False, + **kwargs): """Carr-Purcell-Meiboom-Gill Sequences. Parameters @@ -347,9 +347,9 @@ def new_carr_purcell_meiboom_gill_sequence(duration=None, # pylint: disable=inv **kwargs) -def new_uhrig_single_axis_sequence(duration=None, number_of_offsets=None, - pre_post_rotation=False, - **kwargs): +def _new_uhrig_single_axis_sequence(duration=None, number_of_offsets=None, + pre_post_rotation=False, + **kwargs): """Uhrig Single Axis Sequence. @@ -408,10 +408,10 @@ def new_uhrig_single_axis_sequence(duration=None, number_of_offsets=None, **kwargs) -def new_periodic_single_axis_sequence(duration=None, # pylint: disable=invalid-name - number_of_offsets=None, - pre_post_rotation=False, - **kwargs): +def _new_periodic_single_axis_sequence(duration=None, # pylint: disable=invalid-name + number_of_offsets=None, + pre_post_rotation=False, + **kwargs): """Periodic Single Axis Sequence. @@ -468,10 +468,10 @@ def new_periodic_single_axis_sequence(duration=None, # pylint: disable=invali **kwargs) -def new_walsh_single_axis_sequence(duration=None, - paley_order=None, - pre_post_rotation=False, - **kwargs): +def _new_walsh_single_axis_sequence(duration=None, + paley_order=None, + pre_post_rotation=False, + **kwargs): """Welsh Single Axis Sequence. @@ -546,11 +546,11 @@ def new_walsh_single_axis_sequence(duration=None, **kwargs) -def new_quadratic_sequence(duration=None, - number_inner_offsets=None, - number_outer_offsets=None, - pre_post_rotation=False, - **kwargs): +def _new_quadratic_sequence(duration=None, + number_inner_offsets=None, + number_outer_offsets=None, + pre_post_rotation=False, + **kwargs): """Quadratic Decoupling Sequence @@ -649,10 +649,10 @@ def new_quadratic_sequence(duration=None, **kwargs) -def new_x_concatenated_sequence(duration=1.0, - concatenation_order=None, - pre_post_rotation=False, - **kwargs): +def _new_x_concatenated_sequence(duration=1.0, + concatenation_order=None, + pre_post_rotation=False, + **kwargs): """X-Concatenated Dynamic Decoupling Sequence Concatenation of base sequence C(\tau/2)XC(\tau/2)X @@ -727,10 +727,10 @@ def new_x_concatenated_sequence(duration=1.0, **kwargs) -def new_xy_concatenated_sequence(duration=1.0, - concatenation_order=None, - pre_post_rotation=False, - **kwargs): +def _new_xy_concatenated_sequence(duration=1.0, + concatenation_order=None, + pre_post_rotation=False, + **kwargs): """XY-Concatenated Dynamic Decoupling Sequence Concatenation of base sequence C(\tau/4)XC(\tau/4)YC(\tau/4)XC(\tau/4)Y diff --git a/qctrlopencontrols/exceptions/__init__.py b/qctrlopencontrols/exceptions/__init__.py index 57f3d09c..9b5e06ea 100644 --- a/qctrlopencontrols/exceptions/__init__.py +++ b/qctrlopencontrols/exceptions/__init__.py @@ -19,3 +19,5 @@ """ from .exceptions import ArgumentsValueError + +__all__ = ['ArgumentsValueError'] diff --git a/qctrlopencontrols/globals/__init__.py b/qctrlopencontrols/globals/__init__.py index d3d25a39..d93432fd 100644 --- a/qctrlopencontrols/globals/__init__.py +++ b/qctrlopencontrols/globals/__init__.py @@ -49,3 +49,6 @@ """Algorithm to convert a DDS to Quantum circuit where the unitaties are considered as instantaneous operation. """ + +__all__ = ['QCTRL_EXPANDED', 'CSV', 'JSON', 'CARTESIAN', + 'CYLINDRICAL', 'FIX_DURATION_UNITARY', 'INSTANT_UNITARY'] diff --git a/qctrlopencontrols/qiskit/__init__.py b/qctrlopencontrols/qiskit/__init__.py index 899a7499..3377237b 100644 --- a/qctrlopencontrols/qiskit/__init__.py +++ b/qctrlopencontrols/qiskit/__init__.py @@ -18,4 +18,6 @@ ============= """ -from .quantum_circuit import (convert_dds_to_quantum_circuit) +from .quantum_circuit import (convert_dds_to_qiskit_quantum_circuit) + +__all__ = ['convert_dds_to_qiskit_quantum_circuit'] diff --git a/qctrlopencontrols/qiskit/quantum_circuit.py b/qctrlopencontrols/qiskit/quantum_circuit.py index 913f8f4f..c322f0f6 100644 --- a/qctrlopencontrols/qiskit/quantum_circuit.py +++ b/qctrlopencontrols/qiskit/quantum_circuit.py @@ -29,7 +29,7 @@ from qctrlopencontrols.globals import (FIX_DURATION_UNITARY, INSTANT_UNITARY) -def convert_dds_to_quantum_circuit( +def convert_dds_to_qiskit_quantum_circuit( dynamic_decoupling_sequence, target_qubits=None, gate_time=0.1, diff --git a/tests/test_driven_controls.py b/tests/test_driven_controls.py index 3782c495..da2b336b 100644 --- a/tests/test_driven_controls.py +++ b/tests/test_driven_controls.py @@ -24,7 +24,7 @@ from qctrlopencontrols.exceptions import ArgumentsValueError from qctrlopencontrols import DrivenControl -from qctrlopencontrols.driven_controls.constants import ( +from qctrlopencontrols import ( UPPER_BOUND_SEGMENTS, UPPER_BOUND_RABI_RATE, UPPER_BOUND_DETUNING_RATE) diff --git a/tests/test_dynamical_decoupling.py b/tests/test_dynamical_decoupling.py index e65ed4cd..6670ff71 100644 --- a/tests/test_dynamical_decoupling.py +++ b/tests/test_dynamical_decoupling.py @@ -65,9 +65,18 @@ def test_dynamical_decoupling_sequence(): _repr_string = '{0.__class__.__name__!s}('.format(sequence) + attributes = { + 'duration': sequence.duration, + 'offsets': sequence.offsets, + 'rabi_rotations': sequence.rabi_rotations, + 'azimuthal_angles': sequence.azimuthal_angles, + 'detuning_rotations': sequence.detuning_rotations, + 'name': sequence.name + } + attributes_string = ','.join('{0}={1}'.format(attribute, repr(getattr(sequence, attribute))) - for attribute in sequence.base_attributes) + for attribute in attributes) _repr_string += attributes_string _repr_string += ')' diff --git a/tests/test_predefined_driven_controls.py b/tests/test_predefined_driven_controls.py index 11b440cf..e9addc12 100644 --- a/tests/test_predefined_driven_controls.py +++ b/tests/test_predefined_driven_controls.py @@ -22,17 +22,10 @@ from qctrlopencontrols.exceptions import ArgumentsValueError -from qctrlopencontrols.driven_controls import ( +from qctrlopencontrols import ( new_predefined_driven_control, - new_primitive_control, new_wimperis_1_control, new_solovay_kitaev_1_control, - PRIMITIVE, BB1, SK1, CORPSE, - new_short_composite_rotation_for_undoing_length_over_and_under_shoot_control, - new_corpse_in_scrofulous_control, - new_compensating_for_off_resonance_with_a_pulse_sequence_control, - new_compensating_for_off_resonance_with_a_pulse_sequence_with_solovay_kitaev_control, - new_compensating_for_off_resonance_with_a_pulse_sequence_with_wimperis_control, - new_walsh_amplitude_modulated_filter_1_control -) + PRIMITIVE, BB1, SK1, CORPSE, SCROFULOUS, CORPSE_IN_SCROFULOUS, + CORPSE_IN_BB1, CORPSE_IN_SK1, WAMF1) def test_new_predefined_driven_control(): @@ -69,7 +62,8 @@ def test_primitive_control_segments(): _rabi_rotation ] - primitive_control_1 = new_primitive_control( + primitive_control_1 = new_predefined_driven_control( + scheme=PRIMITIVE, rabi_rotation=_rabi_rotation, maximum_rabi_rate=_rabi_rate, azimuthal_angle=_azimuthal_angle @@ -77,10 +71,10 @@ def test_primitive_control_segments(): # Test the new_predefined_driven_control function also primitive_control_2 = new_predefined_driven_control( + scheme=PRIMITIVE, rabi_rotation=_rabi_rotation, maximum_rabi_rate=_rabi_rate, azimuthal_angle=_azimuthal_angle, - scheme=PRIMITIVE ) for control in [primitive_control_1, primitive_control_2]: @@ -110,16 +104,17 @@ def test_wimperis_1_control(): [np.cos(phi_p + _azimuthal_angle), np.sin(phi_p + _azimuthal_angle)] ]) - wimperis_control_1 = new_wimperis_1_control( + wimperis_control_1 = new_predefined_driven_control( + scheme=BB1, rabi_rotation=_rabi_rotation, azimuthal_angle=_azimuthal_angle, maximum_rabi_rate=_maximum_rabi_rate ) wimperis_control_2 = new_predefined_driven_control( + scheme=BB1, rabi_rotation=_rabi_rotation, azimuthal_angle=_azimuthal_angle, maximum_rabi_rate=_maximum_rabi_rate, - scheme=BB1 ) durations = [np.pi, np.pi, np.pi * 2, np.pi] @@ -149,7 +144,8 @@ def test_solovay_kitaev_1_control(): np.sin(phi_p + _azimuthal_angle)] ] - sk1_control_1 = new_solovay_kitaev_1_control( + sk1_control_1 = new_predefined_driven_control( + scheme=SK1, rabi_rotation=_rabi_rotation, azimuthal_angle=_azimuthal_angle, maximum_rabi_rate=1 @@ -180,12 +176,14 @@ def test_scofulous_control(): # Test that exceptions are raised upon wrong inputs for rabi_rotation # (SCROFULOUS is only defined for pi/4, pi/2 and pi pulses) with pytest.raises(ArgumentsValueError): - _ = new_short_composite_rotation_for_undoing_length_over_and_under_shoot_control( + _ = new_predefined_driven_control( + scheme=SCROFULOUS, rabi_rotation=0.3 ) # Construct SCROFULOUS controls for target rotations pi/4, pi/2 and pi - scrofulous_pi = new_short_composite_rotation_for_undoing_length_over_and_under_shoot_control( + scrofulous_pi = new_predefined_driven_control( + scheme=SCROFULOUS, rabi_rotation=np.pi, azimuthal_angle=0.5, maximum_rabi_rate=2*np.pi ) @@ -201,7 +199,8 @@ def test_scofulous_control(): assert np.allclose(pi_segments, _pi_segments) - scrofulous_pi2 = new_short_composite_rotation_for_undoing_length_over_and_under_shoot_control( + scrofulous_pi2 = new_predefined_driven_control( + scheme=SCROFULOUS, rabi_rotation=np.pi/2, azimuthal_angle=-0.5, maximum_rabi_rate=2*np.pi ) @@ -217,7 +216,8 @@ def test_scofulous_control(): assert np.allclose(pi_on_2_segments, _pi_on_2_segments) - scrofulous_pi4 = new_short_composite_rotation_for_undoing_length_over_and_under_shoot_control( + scrofulous_pi4 = new_predefined_driven_control( + scheme=SCROFULOUS, rabi_rotation=np.pi/4, azimuthal_angle=0, maximum_rabi_rate=2*np.pi ) @@ -239,7 +239,8 @@ def test_corpse_in_scrofulous_control(): defined numerically as well. """ # Test pi and pi/2 rotations - cs_pi = new_corpse_in_scrofulous_control( + cs_pi = new_predefined_driven_control( + scheme=CORPSE_IN_SCROFULOUS, rabi_rotation=np.pi, azimuthal_angle=0.5, maximum_rabi_rate=2*np.pi ) @@ -261,7 +262,8 @@ def test_corpse_in_scrofulous_control(): assert np.allclose(pi_segments, _pi_segments) - cs_pi_on_2 = new_corpse_in_scrofulous_control( + cs_pi_on_2 = new_predefined_driven_control( + scheme=CORPSE_IN_SCROFULOUS, rabi_rotation=np.pi/2, azimuthal_angle=0.25, maximum_rabi_rate=np.pi ) @@ -300,7 +302,8 @@ def test_corpse_control(): [np.cos(_azimuthal_angle), np.sin(_azimuthal_angle), 0., _rabi_rotation / 2. - k] ] - corpse_control_1 = new_compensating_for_off_resonance_with_a_pulse_sequence_control( + corpse_control_1 = new_predefined_driven_control( + scheme=CORPSE, rabi_rotation=_rabi_rotation, azimuthal_angle=_azimuthal_angle, maximum_rabi_rate=1 @@ -323,7 +326,8 @@ def test_corpse_control(): def test_cinbb_control(): """Test the segments of the CinBB (BB1 made up of CORPSEs) driven control """ - cinbb = new_compensating_for_off_resonance_with_a_pulse_sequence_with_wimperis_control( + cinbb = new_predefined_driven_control( + scheme=CORPSE_IN_BB1, rabi_rotation=np.pi/3, azimuthal_angle=0.25, maximum_rabi_rate=np.pi ) @@ -342,7 +346,8 @@ def test_cinbb_control(): assert np.allclose(segments, _segments) - cinbb = new_compensating_for_off_resonance_with_a_pulse_sequence_with_wimperis_control( + cinbb = new_predefined_driven_control( + scheme=CORPSE_IN_BB1, rabi_rotation=np.pi/5, azimuthal_angle=-0.25, maximum_rabi_rate=np.pi ) @@ -365,7 +370,8 @@ def test_cinbb_control(): def test_cinsk1_control(): """Test the segments of the CinSK1 (SK1 made up of CORPSEs) driven control """ - cinsk = new_compensating_for_off_resonance_with_a_pulse_sequence_with_solovay_kitaev_control( + cinsk = new_predefined_driven_control( + scheme=CORPSE_IN_SK1, rabi_rotation=np.pi/2, azimuthal_angle=0.5, maximum_rabi_rate=2*np.pi ) @@ -383,7 +389,8 @@ def test_cinsk1_control(): assert np.allclose(segments, _segments) - cinsk = new_compensating_for_off_resonance_with_a_pulse_sequence_with_solovay_kitaev_control( + cinsk = new_predefined_driven_control( + scheme=CORPSE_IN_SK1, rabi_rotation=2*np.pi, azimuthal_angle=-0.5, maximum_rabi_rate=2*np.pi ) @@ -407,11 +414,13 @@ def test_walsh_control(): # Test that exceptions are raised upon wrong inputs for rabi_rotation # (WALSH control is only defined for pi/4, pi/2 and pi pulses) with pytest.raises(ArgumentsValueError): - _ = new_walsh_amplitude_modulated_filter_1_control( + _ = new_predefined_driven_control( + scheme=WAMF1, rabi_rotation=0.3 ) # test pi rotation - walsh_pi = new_walsh_amplitude_modulated_filter_1_control( + walsh_pi = new_predefined_driven_control( + scheme=WAMF1, rabi_rotation=np.pi, azimuthal_angle=-0.35, maximum_rabi_rate=2*np.pi ) @@ -429,7 +438,8 @@ def test_walsh_control(): assert np.allclose(pi_segments, _pi_segments) # test pi/2 rotation - walsh_pi_on_2 = new_walsh_amplitude_modulated_filter_1_control( + walsh_pi_on_2 = new_predefined_driven_control( + scheme=WAMF1, rabi_rotation=np.pi/2, azimuthal_angle=0.57, maximum_rabi_rate=2*np.pi ) @@ -447,7 +457,8 @@ def test_walsh_control(): assert np.allclose(pi_on_2_segments, _pi_on_2_segments) # test pi/4 rotation - walsh_pi_on_4 = new_walsh_amplitude_modulated_filter_1_control( + walsh_pi_on_4 = new_predefined_driven_control( + scheme=WAMF1, rabi_rotation=np.pi/4, azimuthal_angle=-0.273, maximum_rabi_rate=2*np.pi ) pi_on_4_segments = np.vstack(( diff --git a/tests/test_predefined_dynamical_decoupling.py b/tests/test_predefined_dynamical_decoupling.py index 22009174..2470d381 100644 --- a/tests/test_predefined_dynamical_decoupling.py +++ b/tests/test_predefined_dynamical_decoupling.py @@ -24,8 +24,8 @@ from qctrlopencontrols.exceptions import ArgumentsValueError -import qctrlopencontrols.dynamic_decoupling_sequences.predefined as pre -from qctrlopencontrols.dynamic_decoupling_sequences import ( +from qctrlopencontrols import new_predefined_dds +from qctrlopencontrols import ( SPIN_ECHO, CARR_PURCELL, CARR_PURCELL_MEIBOOM_GILL, WALSH_SINGLE_AXIS, PERIODIC_SINGLE_AXIS, UHRIG_SINGLE_AXIS, QUADRATIC, X_CONCATENATED, @@ -39,8 +39,9 @@ def test_ramsey(): duration = 10. - sequence = pre.new_predefined_dds(scheme='Ramsey', - duration=duration) + sequence = new_predefined_dds( + scheme='Ramsey', + duration=duration) _offsets = np.array([]) _rabi_rotations = np.array([]) @@ -52,8 +53,11 @@ def test_ramsey(): assert np.allclose(_azimuthal_angles, sequence.azimuthal_angles) assert np.allclose(_detuning_rotations, sequence.detuning_rotations) - sequence = pre.new_predefined_dds(scheme='Ramsey', duration=duration, - pre_post_rotation=True) + sequence = new_predefined_dds( + scheme='Ramsey', + duration=duration, + pre_post_rotation=True) + _rabi_rotations = np.array([np.pi/2, np.pi/2]) _azimuthal_angles = np.array([0., 0.]) _detuning_rotations = np.array([0., 0.]) @@ -71,8 +75,9 @@ def test_spin_echo(): duration = 10. - sequence = pre.new_predefined_dds(scheme=SPIN_ECHO, - duration=duration) + sequence = new_predefined_dds( + scheme=SPIN_ECHO, + duration=duration) _offsets = np.array([duration/2.]) _rabi_rotations = np.array([np.pi]) @@ -84,9 +89,10 @@ def test_spin_echo(): assert np.allclose(_azimuthal_angles, sequence.azimuthal_angles) assert np.allclose(_detuning_rotations, sequence.detuning_rotations) - sequence = pre.new_predefined_dds(scheme=SPIN_ECHO, - duration=duration, - pre_post_rotation=True) + sequence = new_predefined_dds( + scheme=SPIN_ECHO, + duration=duration, + pre_post_rotation=True) _offsets = np.array([0, duration / 2., duration]) _rabi_rotations = np.array([np.pi/2, np.pi, np.pi/2]) @@ -107,9 +113,10 @@ def test_curr_purcell(): duration = 10. number_of_offsets = 4 - sequence = pre.new_predefined_dds(scheme=CARR_PURCELL, - duration=duration, - number_of_offsets=number_of_offsets) + sequence = new_predefined_dds( + scheme=CARR_PURCELL, + duration=duration, + number_of_offsets=number_of_offsets) _spacing = duration/number_of_offsets _offsets = np.array([_spacing*0.5, _spacing*0.5+_spacing, @@ -123,10 +130,11 @@ def test_curr_purcell(): assert np.allclose(_azimuthal_angles, sequence.azimuthal_angles) assert np.allclose(_detuning_rotations, sequence.detuning_rotations) - sequence = pre.new_predefined_dds(scheme=CARR_PURCELL, - duration=duration, - number_of_offsets=number_of_offsets, - pre_post_rotation=True) + sequence = new_predefined_dds( + scheme=CARR_PURCELL, + duration=duration, + number_of_offsets=number_of_offsets, + pre_post_rotation=True) _offsets = np.array([0, _spacing * 0.5, _spacing * 0.5 + _spacing, _spacing * 0.5 + 2 * _spacing, _spacing * 0.5 + 3 * _spacing, @@ -149,9 +157,10 @@ def test_curr_purcell_meiboom_sequence(): # pylint: disable=invalid-name duration = 10. number_of_offsets = 4 - sequence = pre.new_predefined_dds(scheme=CARR_PURCELL_MEIBOOM_GILL, - duration=duration, - number_of_offsets=number_of_offsets) + sequence = new_predefined_dds( + scheme=CARR_PURCELL_MEIBOOM_GILL, + duration=duration, + number_of_offsets=number_of_offsets) _spacing = duration/number_of_offsets _offsets = np.array([_spacing*0.5, _spacing*0.5+_spacing, @@ -165,10 +174,11 @@ def test_curr_purcell_meiboom_sequence(): # pylint: disable=invalid-name assert np.allclose(_azimuthal_angles, sequence.azimuthal_angles) assert np.allclose(_detuning_rotations, sequence.detuning_rotations) - sequence = pre.new_predefined_dds(scheme=CARR_PURCELL_MEIBOOM_GILL, - duration=duration, - number_of_offsets=number_of_offsets, - pre_post_rotation=True) + sequence = new_predefined_dds( + scheme=CARR_PURCELL_MEIBOOM_GILL, + duration=duration, + number_of_offsets=number_of_offsets, + pre_post_rotation=True) _offsets = np.array([0, _spacing * 0.5, _spacing * 0.5 + _spacing, _spacing * 0.5 + 2 * _spacing, _spacing * 0.5 + 3 * _spacing, duration]) @@ -190,9 +200,10 @@ def test_uhrig_single_axis_sequence(): duration = 10. number_of_offsets = 4 - sequence = pre.new_predefined_dds(scheme=UHRIG_SINGLE_AXIS, - duration=duration, - number_of_offsets=number_of_offsets) + sequence = new_predefined_dds( + scheme=UHRIG_SINGLE_AXIS, + duration=duration, + number_of_offsets=number_of_offsets) constant = 0.5 / (number_of_offsets+1) _delta_positions = [duration*(np.sin(np.pi*(k+1)*constant))**2 @@ -208,10 +219,11 @@ def test_uhrig_single_axis_sequence(): assert np.allclose(_azimuthal_angles, sequence.azimuthal_angles) assert np.allclose(_detuning_rotations, sequence.detuning_rotations) - sequence = pre.new_predefined_dds(scheme=UHRIG_SINGLE_AXIS, - duration=duration, - number_of_offsets=number_of_offsets, - pre_post_rotation=True) + sequence = new_predefined_dds( + scheme=UHRIG_SINGLE_AXIS, + duration=duration, + number_of_offsets=number_of_offsets, + pre_post_rotation=True) _offsets = np.array(_delta_positions) _offsets = np.insert(_offsets, [0, _offsets.shape[0]], [0, duration]) @@ -234,9 +246,10 @@ def test_periodic_single_axis_sequence(): # pylint: disable=invalid-name duration = 10. number_of_offsets = 4 - sequence = pre.new_predefined_dds(scheme=PERIODIC_SINGLE_AXIS, - duration=duration, - number_of_offsets=number_of_offsets) + sequence = new_predefined_dds( + scheme=PERIODIC_SINGLE_AXIS, + duration=duration, + number_of_offsets=number_of_offsets) constant = 1 / (number_of_offsets+1) # prepare the offsets for delta comb @@ -251,10 +264,11 @@ def test_periodic_single_axis_sequence(): # pylint: disable=invalid-name assert np.allclose(_azimuthal_angles, sequence.azimuthal_angles) assert np.allclose(_detuning_rotations, sequence.detuning_rotations) - sequence = pre.new_predefined_dds(scheme=PERIODIC_SINGLE_AXIS, - duration=duration, - number_of_offsets=number_of_offsets, - pre_post_rotation=True) + sequence = new_predefined_dds( + scheme=PERIODIC_SINGLE_AXIS, + duration=duration, + number_of_offsets=number_of_offsets, + pre_post_rotation=True) _offsets = np.array(_delta_positions) _offsets = np.insert(_offsets, [0, _offsets.shape[0]], [0, duration]) @@ -277,9 +291,10 @@ def test_walsh_single_axis_sequence(): duration = 10. paley_order = 20 - sequence = pre.new_predefined_dds(scheme=WALSH_SINGLE_AXIS, - duration=duration, - paley_order=paley_order) + sequence = new_predefined_dds( + scheme=WALSH_SINGLE_AXIS, + duration=duration, + paley_order=paley_order) hamming_weight = 5 samples = 2 ** hamming_weight @@ -308,10 +323,12 @@ def test_walsh_single_axis_sequence(): assert np.allclose(_azimuthal_angles, sequence.azimuthal_angles) assert np.allclose(_detuning_rotations, sequence.detuning_rotations) - sequence = pre.new_predefined_dds(scheme=WALSH_SINGLE_AXIS, - duration=duration, - paley_order=paley_order, - pre_post_rotation=True) + sequence = new_predefined_dds( + scheme=WALSH_SINGLE_AXIS, + duration=duration, + paley_order=paley_order, + pre_post_rotation=True) + _offsets = np.insert(_offsets, [0, _offsets.shape[0]], [0, duration]) _rabi_rotations = np.insert(_rabi_rotations, [0, _rabi_rotations.shape[0]], [np.pi/2, np.pi/2]) @@ -333,9 +350,10 @@ def test_quadratic_sequence(): number_inner_offsets = 4 number_outer_offsets = 4 - sequence = pre.new_predefined_dds(scheme=QUADRATIC, duration=duration, - number_inner_offsets=number_inner_offsets, - number_outer_offsets=number_outer_offsets) + sequence = new_predefined_dds( + scheme=QUADRATIC, duration=duration, + number_inner_offsets=number_inner_offsets, + number_outer_offsets=number_outer_offsets) _offsets = np.zeros((number_outer_offsets+1, number_inner_offsets + 1)) @@ -379,10 +397,11 @@ def test_quadratic_sequence(): assert np.allclose(_azimuthal_angles, sequence.azimuthal_angles) assert np.allclose(_detuning_rotations, sequence.detuning_rotations) - sequence = pre.new_predefined_dds(scheme=QUADRATIC, duration=duration, - number_inner_offsets=number_inner_offsets, - number_outer_offsets=number_outer_offsets, - pre_post_rotation=True) + sequence = new_predefined_dds( + scheme=QUADRATIC, duration=duration, + number_inner_offsets=number_inner_offsets, + number_outer_offsets=number_outer_offsets, + pre_post_rotation=True) _offsets = np.insert(_offsets, [0, _offsets.shape[0]], [0, duration]) _rabi_rotations = np.insert(_rabi_rotations, [0, _rabi_rotations.shape[0]], @@ -406,9 +425,10 @@ def test_xconcatenated_sequence(): duration = 10. concatenation_order = 3 - sequence = pre.new_predefined_dds(scheme=X_CONCATENATED, - duration=duration, - concatenation_order=concatenation_order) + sequence = new_predefined_dds( + scheme=X_CONCATENATED, + duration=duration, + concatenation_order=concatenation_order) _spacing = duration/(2**concatenation_order) _offsets = [_spacing, 3*_spacing, 4 * _spacing, 5 * _spacing, 7 * _spacing] @@ -423,10 +443,11 @@ def test_xconcatenated_sequence(): assert np.allclose(_azimuthal_angles, sequence.azimuthal_angles) assert np.allclose(_detuning_rotations, sequence.detuning_rotations) - sequence = pre.new_predefined_dds(scheme=X_CONCATENATED, - duration=duration, - concatenation_order=concatenation_order, - pre_post_rotation=True) + sequence = new_predefined_dds( + scheme=X_CONCATENATED, + duration=duration, + concatenation_order=concatenation_order, + pre_post_rotation=True) _offsets = np.insert(_offsets, [0, _offsets.shape[0]], [0, duration]) _rabi_rotations = np.insert(_rabi_rotations, [0, _rabi_rotations.shape[0]], @@ -448,9 +469,10 @@ def test_xyconcatenated_sequence(): duration = 10. concatenation_order = 2 - sequence = pre.new_predefined_dds(scheme=XY_CONCATENATED, - duration=duration, - concatenation_order=concatenation_order) + sequence = new_predefined_dds( + scheme=XY_CONCATENATED, + duration=duration, + concatenation_order=concatenation_order) _spacing = duration / (2 ** (concatenation_order*2)) _offsets = [_spacing, 2*_spacing, 3 * _spacing, 4 * _spacing, @@ -471,10 +493,11 @@ def test_xyconcatenated_sequence(): assert np.allclose(_azimuthal_angles, sequence.azimuthal_angles) assert np.allclose(_detuning_rotations, sequence.detuning_rotations) - sequence = pre.new_predefined_dds(scheme=XY_CONCATENATED, - duration=duration, - concatenation_order=concatenation_order, - pre_post_rotation=True) + sequence = new_predefined_dds( + scheme=XY_CONCATENATED, + duration=duration, + concatenation_order=concatenation_order, + pre_post_rotation=True) _offsets = np.insert(_offsets, [0, _offsets.shape[0]], [0, duration]) _rabi_rotations = np.insert(_rabi_rotations, [0, _rabi_rotations.shape[0]], @@ -499,29 +522,39 @@ def test_attribute_values(): # duration cannot be <= 0 with pytest.raises(ArgumentsValueError): - _ = pre.new_predefined_dds(scheme=SPIN_ECHO, duration=-2) + _ = new_predefined_dds(scheme=SPIN_ECHO, duration=-2) # number_of_offsets cannot be <= 0 - _ = pre.new_predefined_dds(scheme=CARR_PURCELL_MEIBOOM_GILL, duration=2, - number_of_offsets=-1) + _ = new_predefined_dds( + scheme=CARR_PURCELL_MEIBOOM_GILL, duration=2, + number_of_offsets=-1) # for QDD, none of the offsets can be <=0 - _ = pre.new_predefined_dds(scheme=QUADRATIC, duration=2, - number_inner_offsets=-1, number_outer_offsets=2) - _ = pre.new_predefined_dds(scheme=QUADRATIC, duration=2, - number_inner_offsets=1, number_outer_offsets=-2) - _ = pre.new_predefined_dds(scheme=QUADRATIC, duration=2, - number_inner_offsets=-1, number_outer_offsets=-2) + _ = new_predefined_dds( + scheme=QUADRATIC, duration=2, + number_inner_offsets=-1, number_outer_offsets=2) + _ = new_predefined_dds( + scheme=QUADRATIC, duration=2, + number_inner_offsets=1, number_outer_offsets=-2) + _ = new_predefined_dds( + scheme=QUADRATIC, duration=2, + number_inner_offsets=-1, number_outer_offsets=-2) # for x-cdd and xy-cdd concatenation_order cannot be <=0 - _ = pre.new_predefined_dds(scheme=X_CONCATENATED, duration=2, - concatenation_order=-1) - _ = pre.new_predefined_dds(scheme=X_CONCATENATED, duration=-2, - concatenation_order=1) - _ = pre.new_predefined_dds(scheme=X_CONCATENATED, duration=-2, - concatenation_order=-1) - _ = pre.new_predefined_dds(scheme=XY_CONCATENATED, duration=2, - concatenation_order=-1) - _ = pre.new_predefined_dds(scheme=XY_CONCATENATED, duration=-2, - concatenation_order=1) - _ = pre.new_predefined_dds(scheme=XY_CONCATENATED, duration=-2, - concatenation_order=-1) + _ = new_predefined_dds( + scheme=X_CONCATENATED, duration=2, + concatenation_order=-1) + _ = new_predefined_dds( + scheme=X_CONCATENATED, duration=-2, + concatenation_order=1) + _ = new_predefined_dds( + scheme=X_CONCATENATED, duration=-2, + concatenation_order=-1) + _ = new_predefined_dds( + scheme=XY_CONCATENATED, duration=2, + concatenation_order=-1) + _ = new_predefined_dds( + scheme=XY_CONCATENATED, duration=-2, + concatenation_order=1) + _ = new_predefined_dds( + scheme=XY_CONCATENATED, duration=-2, + concatenation_order=-1) diff --git a/tests/test_qctrl_object.py b/tests/test_qctrl_object.py deleted file mode 100644 index de21bc47..00000000 --- a/tests/test_qctrl_object.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2019 Q-CTRL Pty Ltd & Q-CTRL Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -===================== -Tests for base module -===================== -""" - -import pytest -from qctrlopencontrols.exceptions import ArgumentsValueError -from qctrlopencontrols.base import QctrlObject - - -class SampleClass(QctrlObject): #pylint: disable=too-few-public-methods - - """A sample class with attributes - - Parameters - ---------- - sample_attribute : int - A sample attribute of integer type - base_attributes : list - A list of attributes to be used as base_attributes - """ - - def __init__(self, sample_attribute, base_attributes): - super(SampleClass, self).__init__(base_attributes=base_attributes) - self.sample_attribute = sample_attribute - - -def test_qctrl_object(): # pylint: disable=too-few-public-methods - """Tests the __repr__ and __str__ methods of base.QctrlObject - """ - - sample_class = SampleClass(sample_attribute=50, base_attributes=['sample_attribute']) - - _sample_repr = '{0.__class__.__name__!s}(sample_attribute={0.sample_attribute!r})'.format( - sample_class) - - assert repr(sample_class) == _sample_repr - assert str(sample_class) == str(_sample_repr) - - sample_class = SampleClass(sample_attribute=50, base_attributes=None) - _sample_repr = 'No attributes provided for object of class {0.__class__.__name__!s}'.format( - sample_class) - - assert repr(sample_class) == _sample_repr - assert str(sample_class) == str(_sample_repr) - - with pytest.raises(ArgumentsValueError): - - _ = SampleClass(sample_attribute=50., base_attributes=[]) - _ = SampleClass(sample_attribute=50., base_attributes=['sample_1', 40]) - _ = SampleClass(sample_attribute=50., base_attributes='no list') diff --git a/tests/test_qiskit_sequence.py b/tests/test_qiskit_sequence.py index c4c95fde..e58ca8f1 100644 --- a/tests/test_qiskit_sequence.py +++ b/tests/test_qiskit_sequence.py @@ -24,7 +24,7 @@ from qiskit import BasicAer from qctrlopencontrols import ( - new_predefined_dds, convert_dds_to_quantum_circuit) + new_predefined_dds, convert_dds_to_qiskit_quantum_circuit) def _create_test_sequence(sequence_scheme, pre_post_rotation): @@ -93,7 +93,7 @@ def _check_circuit_unitary(pre_post_rotation, multiplier, algorithm): 'quadratic', 'X concatenated', 'XY concatenated']: sequence = _create_test_sequence(sequence_scheme, pre_post_rotation) - quantum_circuit = convert_dds_to_quantum_circuit( + quantum_circuit = convert_dds_to_qiskit_quantum_circuit( dynamic_decoupling_sequence=sequence, add_measurement=False, algorithm=algorithm) From be4b5b00be930409760ebfbac521717e3a5399e9 Mon Sep 17 00:00:00 2001 From: Rajib Chakravorty Date: Tue, 11 Jun 2019 13:15:35 +1000 Subject: [PATCH 2/4] additional error handling for new repr method --- qctrlopencontrols/base/utils.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/qctrlopencontrols/base/utils.py b/qctrlopencontrols/base/utils.py index 0cb30557..d7a78b67 100644 --- a/qctrlopencontrols/base/utils.py +++ b/qctrlopencontrols/base/utils.py @@ -30,19 +30,27 @@ def create_repr_from_attributes(class_name, **attributes): class_name : str The name of the class attributes : dict - A dict of attributes in (attribute_name:attribute_value) format + A dict of attributes in (attribute_name:attribute_value) format. + The attribute name must be a string. Returns ------- str - A string representing the attributes + A string representing the attributes; If no attribute is provided + a constant string is returned + 'No attributes provided for object of class {0}".format(class_name)' Raises ------ ArgumentsValueError - If no class name is provided or any of the attribute name is not string type + If class name is not a string or any of the attribute name is not string type """ + if not isinstance(class_name, str): + raise ArgumentsValueError('The class name must be a string', + {'class_name': class_name, + 'type(class_name)': type(class_name)}) + if not attributes: return "No attributes provided for object of class {0}".format(class_name) From 75019db77ba057198e72c1a3158d7b28d7b75694 Mon Sep 17 00:00:00 2001 From: Rajib Chakravorty Date: Tue, 11 Jun 2019 16:49:40 +1000 Subject: [PATCH 3/4] repr method updated with class instance as input --- qctrlopencontrols/base/utils.py | 30 +++++++++++-------- qctrlopencontrols/driven_controls/__init__.py | 22 ++++++++++---- .../driven_controls/driven_control.py | 19 +++++------- .../dynamic_decoupling_sequences/__init__.py | 18 +++++++---- .../dynamic_decoupling_sequence.py | 28 +++++------------ 5 files changed, 63 insertions(+), 54 deletions(-) diff --git a/qctrlopencontrols/base/utils.py b/qctrlopencontrols/base/utils.py index d7a78b67..34a9f275 100644 --- a/qctrlopencontrols/base/utils.py +++ b/qctrlopencontrols/base/utils.py @@ -21,24 +21,25 @@ from qctrlopencontrols.exceptions import ArgumentsValueError -def create_repr_from_attributes(class_name, **attributes): +def create_repr_from_attributes(class_instance=None, attributes=None): """Returns a string representation of an object Parameters ---------- - class_name : str - The name of the class - attributes : dict - A dict of attributes in (attribute_name:attribute_value) format. - The attribute name must be a string. + class_instance : object, optional + The instance of a class (object)l defaults to None + attributes : list, optional + A list of string where each entry is the name of the attribute to collect + from the class instance. Returns ------- str A string representing the attributes; If no attribute is provided a constant string is returned - 'No attributes provided for object of class {0}".format(class_name)' + 'No attributes provided for object of class {0.__class__.__name__}". + format(class_instance)' Raises ------ @@ -46,10 +47,15 @@ def create_repr_from_attributes(class_name, **attributes): If class name is not a string or any of the attribute name is not string type """ - if not isinstance(class_name, str): - raise ArgumentsValueError('The class name must be a string', - {'class_name': class_name, - 'type(class_name)': type(class_name)}) + if class_instance is None: + raise ArgumentsValueError('Class instance must be a valid object.', + {'class_instance': class_instance}) + + class_name = '{0.__class__.__name__}'.format(class_instance) + + if attributes is None: + raise ArgumentsValueError('Attributes must be a list of string', + {'attributes': attributes}) if not attributes: return "No attributes provided for object of class {0}".format(class_name) @@ -63,7 +69,7 @@ def create_repr_from_attributes(class_name, **attributes): repr_string = '{0}('.format(class_name) attributes_string = ','.join('{0}={1}'.format(attribute, - repr(attributes[attribute])) + repr(getattr(class_instance, attribute))) for attribute in attributes) repr_string += attributes_string repr_string += ')' diff --git a/qctrlopencontrols/driven_controls/__init__.py b/qctrlopencontrols/driven_controls/__init__.py index b7161012..c74d48d7 100644 --- a/qctrlopencontrols/driven_controls/__init__.py +++ b/qctrlopencontrols/driven_controls/__init__.py @@ -33,9 +33,19 @@ from .predefined import new_predefined_driven_control -__all__ = ['UPPER_BOUND_RABI_RATE', 'UPPER_BOUND_DETUNING_RATE', - 'UPPER_BOUND_DURATION', 'LOWER_BOUND_DURATION', 'UPPER_BOUND_SEGMENTS', - 'PRIMITIVE', 'BB1', 'SK1', - 'WAMF1', 'CORPSE', 'CORPSE_IN_SK1', 'CORPSE_IN_BB1', 'SCROFULOUS', - 'CORPSE_IN_SCROFULOUS', 'new_predefined_driven_control', - 'DrivenControl'] +__all__ = ['BB1', + 'CORPSE', + 'CORPSE_IN_BB1', + 'CORPSE_IN_SCROFULOUS', + 'CORPSE_IN_SK1', + 'LOWER_BOUND_DURATION', + 'PRIMITIVE', + 'SCROFULOUS', + 'SK1', + 'UPPER_BOUND_DETUNING_RATE', + 'UPPER_BOUND_DURATION', + 'UPPER_BOUND_RABI_RATE', + 'UPPER_BOUND_SEGMENTS', + 'WAMF1', + 'DrivenControl', + 'new_predefined_driven_control'] diff --git a/qctrlopencontrols/driven_controls/driven_control.py b/qctrlopencontrols/driven_controls/driven_control.py index d73b8d64..222a346b 100644 --- a/qctrlopencontrols/driven_controls/driven_control.py +++ b/qctrlopencontrols/driven_controls/driven_control.py @@ -613,17 +613,14 @@ def __repr__(self): String representation of the object including the values of the arguments. """ - attributes = { - 'rabi_rates': self.rabi_rates, - 'azimuthal_angles': self.azimuthal_angles, - 'detunings': self.detunings, - 'durations': self.durations, - 'name': self.name - } - - class_name = '{0.__class__.__name__!s}'.format(self) - - return create_repr_from_attributes(class_name, **attributes) + attributes = [ + 'rabi_rates', + 'azimuthal_angles', + 'detunings', + 'durations', + 'name'] + + return create_repr_from_attributes(self, attributes) if __name__ == '__main__': diff --git a/qctrlopencontrols/dynamic_decoupling_sequences/__init__.py b/qctrlopencontrols/dynamic_decoupling_sequences/__init__.py index c81a5b79..30a359ab 100644 --- a/qctrlopencontrols/dynamic_decoupling_sequences/__init__.py +++ b/qctrlopencontrols/dynamic_decoupling_sequences/__init__.py @@ -28,8 +28,16 @@ from .predefined import new_predefined_dds from .driven_controls import convert_dds_to_driven_control -__all__ = ['UPPER_BOUND_OFFSETS', 'SPIN_ECHO', 'CARR_PURCELL', - 'CARR_PURCELL_MEIBOOM_GILL', 'UHRIG_SINGLE_AXIS', - 'PERIODIC_SINGLE_AXIS', 'WALSH_SINGLE_AXIS', 'QUADRATIC', - 'X_CONCATENATED', 'XY_CONCATENATED', 'DynamicDecouplingSequence', - 'new_predefined_dds', 'convert_dds_to_driven_control'] +__all__ = ['CARR_PURCELL', + 'CARR_PURCELL_MEIBOOM_GILL', + 'UPPER_BOUND_OFFSETS', + 'PERIODIC_SINGLE_AXIS', + 'QUADRATIC', + 'SPIN_ECHO', + 'UHRIG_SINGLE_AXIS', + 'WALSH_SINGLE_AXIS', + 'X_CONCATENATED', + 'XY_CONCATENATED', + 'DynamicDecouplingSequence', + 'convert_dds_to_driven_control', + 'new_predefined_dds'] diff --git a/qctrlopencontrols/dynamic_decoupling_sequences/dynamic_decoupling_sequence.py b/qctrlopencontrols/dynamic_decoupling_sequences/dynamic_decoupling_sequence.py index 6cb551fb..9b5c097c 100644 --- a/qctrlopencontrols/dynamic_decoupling_sequences/dynamic_decoupling_sequence.py +++ b/qctrlopencontrols/dynamic_decoupling_sequences/dynamic_decoupling_sequence.py @@ -72,15 +72,6 @@ def __init__(self, detuning_rotations=None, name=None ): - """ - super(DynamicDecouplingSequence, self).__init__([ - 'duration', - 'offsets', - 'rabi_rotations', - 'azimuthal_angles', - 'detuning_rotations', - 'name']) - """ self.duration = duration if self.duration <= 0.: @@ -229,18 +220,15 @@ def __repr__(self): String representation of the object including the values of the arguments. """ - attributes = { - 'duration': self.duration, - 'offsets': self.offsets, - 'rabi_rotations': self.rabi_rotations, - 'azimuthal_angles': self.azimuthal_angles, - 'detuning_rotations': self.detuning_rotations, - 'name': self.name - } - - class_name = '{0.__class__.__name__!s}'.format(self) + attributes = [ + 'duration', + 'offsets', + 'rabi_rotations', + 'azimuthal_angles', + 'detuning_rotations', + 'name'] - return create_repr_from_attributes(class_name, **attributes) + return create_repr_from_attributes(self, attributes) def __str__(self): """Prepares a friendly string format for a Dynamic Decoupling Sequence From 20f32f95de1449aac396a6474c7302f0db588c8e Mon Sep 17 00:00:00 2001 From: Rajib Chakravorty Date: Wed, 12 Jun 2019 18:07:19 +1000 Subject: [PATCH 4/4] __all__ in sub-packages removed; constants moved to respective __init__ of sub-package --- qctrlopencontrols/__init__.py | 32 +++--- qctrlopencontrols/base/__init__.py | 10 -- qctrlopencontrols/base/utils.py | 2 +- qctrlopencontrols/cirq/__init__.py | 12 --- qctrlopencontrols/cirq/circuit.py | 6 +- qctrlopencontrols/cirq/schedule.py | 4 +- qctrlopencontrols/driven_controls/__init__.py | 101 +++++++++++------- .../driven_controls/constants.py | 78 -------------- .../driven_controls/driven_control.py | 8 +- .../driven_controls/predefined.py | 15 +-- .../dynamic_decoupling_sequences/__init__.py | 83 +++++++++----- .../dynamic_decoupling_sequences/constants.py | 68 ------------ .../driven_controls.py | 7 +- .../dynamic_decoupling_sequence.py | 8 +- .../predefined.py | 15 +-- qctrlopencontrols/exceptions/__init__.py | 10 -- qctrlopencontrols/globals/__init__.py | 3 - qctrlopencontrols/qiskit/__init__.py | 10 -- qctrlopencontrols/qiskit/quantum_circuit.py | 6 +- tests/test_driven_controls.py | 4 +- tests/test_dynamical_decoupling.py | 2 +- tests/test_predefined_driven_controls.py | 6 +- tests/test_predefined_dynamical_decoupling.py | 4 +- 23 files changed, 178 insertions(+), 316 deletions(-) delete mode 100644 qctrlopencontrols/driven_controls/constants.py delete mode 100644 qctrlopencontrols/dynamic_decoupling_sequences/constants.py diff --git a/qctrlopencontrols/__init__.py b/qctrlopencontrols/__init__.py index 7bc0bfeb..2f0f11ee 100644 --- a/qctrlopencontrols/__init__.py +++ b/qctrlopencontrols/__init__.py @@ -18,17 +18,23 @@ ================= """ -from . import dynamic_decoupling_sequences -from .dynamic_decoupling_sequences import * -from . import driven_controls -from .driven_controls import * -from . import qiskit -from .qiskit import * -from . import cirq -from .cirq import * +from .cirq.circuit import convert_dds_to_cirq_circuit +from .cirq.schedule import convert_dds_to_cirq_schedule -__all__ = [] -__all__.extend(dynamic_decoupling_sequences.__all__) -__all__.extend(driven_controls.__all__) -__all__.extend(qiskit.__all__) -__all__.extend(cirq.__all__) +from .driven_controls.driven_control import DrivenControl +from .driven_controls.predefined import new_predefined_driven_control + +from .dynamic_decoupling_sequences.dynamic_decoupling_sequence import DynamicDecouplingSequence +from .dynamic_decoupling_sequences.predefined import new_predefined_dds +from .dynamic_decoupling_sequences.driven_controls import convert_dds_to_driven_control + +from .qiskit.quantum_circuit import convert_dds_to_qiskit_quantum_circuit + +__all__ = ['convert_dds_to_cirq_circuit', + 'convert_dds_to_cirq_schedule', + 'convert_dds_to_driven_control', + 'convert_dds_to_qiskit_quantum_circuit', + 'new_predefined_dds', + 'new_predefined_driven_control', + 'DrivenControl', + 'DynamicDecouplingSequence'] diff --git a/qctrlopencontrols/base/__init__.py b/qctrlopencontrols/base/__init__.py index 68a2205d..a2b61496 100644 --- a/qctrlopencontrols/base/__init__.py +++ b/qctrlopencontrols/base/__init__.py @@ -11,13 +11,3 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - -""" -=========== -Base module -=========== -""" - -from .utils import create_repr_from_attributes - -__all__ = ['create_repr_from_attributes'] diff --git a/qctrlopencontrols/base/utils.py b/qctrlopencontrols/base/utils.py index 34a9f275..cbddb2e4 100644 --- a/qctrlopencontrols/base/utils.py +++ b/qctrlopencontrols/base/utils.py @@ -18,7 +18,7 @@ ========== """ -from qctrlopencontrols.exceptions import ArgumentsValueError +from ..exceptions.exceptions import ArgumentsValueError def create_repr_from_attributes(class_instance=None, attributes=None): diff --git a/qctrlopencontrols/cirq/__init__.py b/qctrlopencontrols/cirq/__init__.py index 524f0c0d..a2b61496 100644 --- a/qctrlopencontrols/cirq/__init__.py +++ b/qctrlopencontrols/cirq/__init__.py @@ -11,15 +11,3 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - -""" -============= -cirq module -============= -""" - -from .circuit import convert_dds_to_cirq_circuit -from .schedule import convert_dds_to_cirq_schedule - -__all__ = ['convert_dds_to_cirq_circuit', - 'convert_dds_to_cirq_schedule'] diff --git a/qctrlopencontrols/cirq/circuit.py b/qctrlopencontrols/cirq/circuit.py index cb54e9f6..fc23ba36 100644 --- a/qctrlopencontrols/cirq/circuit.py +++ b/qctrlopencontrols/cirq/circuit.py @@ -22,9 +22,9 @@ import cirq -from qctrlopencontrols.dynamic_decoupling_sequences import DynamicDecouplingSequence -from qctrlopencontrols.exceptions import ArgumentsValueError -from qctrlopencontrols.globals import (FIX_DURATION_UNITARY, INSTANT_UNITARY) +from ..dynamic_decoupling_sequences.dynamic_decoupling_sequence import DynamicDecouplingSequence +from ..exceptions.exceptions import ArgumentsValueError +from ..globals import (FIX_DURATION_UNITARY, INSTANT_UNITARY) def convert_dds_to_cirq_circuit( diff --git a/qctrlopencontrols/cirq/schedule.py b/qctrlopencontrols/cirq/schedule.py index 00360b6b..88df4c10 100644 --- a/qctrlopencontrols/cirq/schedule.py +++ b/qctrlopencontrols/cirq/schedule.py @@ -22,8 +22,8 @@ import cirq -from qctrlopencontrols.dynamic_decoupling_sequences import DynamicDecouplingSequence -from qctrlopencontrols.exceptions import ArgumentsValueError +from ..dynamic_decoupling_sequences.dynamic_decoupling_sequence import DynamicDecouplingSequence +from ..exceptions.exceptions import ArgumentsValueError def convert_dds_to_cirq_schedule( diff --git a/qctrlopencontrols/driven_controls/__init__.py b/qctrlopencontrols/driven_controls/__init__.py index c74d48d7..40858ed5 100644 --- a/qctrlopencontrols/driven_controls/__init__.py +++ b/qctrlopencontrols/driven_controls/__init__.py @@ -13,39 +13,68 @@ # limitations under the License. """ -====================== -driven_controls module -====================== -""" - -from .driven_control import DrivenControl - -from .constants import ( - UPPER_BOUND_RABI_RATE, UPPER_BOUND_DETUNING_RATE, - UPPER_BOUND_DURATION, LOWER_BOUND_DURATION, UPPER_BOUND_SEGMENTS, - PRIMITIVE, BB1, SK1, - WAMF1, - CORPSE, - CORPSE_IN_SK1, - CORPSE_IN_BB1, - SCROFULOUS, - CORPSE_IN_SCROFULOUS) - -from .predefined import new_predefined_driven_control - -__all__ = ['BB1', - 'CORPSE', - 'CORPSE_IN_BB1', - 'CORPSE_IN_SCROFULOUS', - 'CORPSE_IN_SK1', - 'LOWER_BOUND_DURATION', - 'PRIMITIVE', - 'SCROFULOUS', - 'SK1', - 'UPPER_BOUND_DETUNING_RATE', - 'UPPER_BOUND_DURATION', - 'UPPER_BOUND_RABI_RATE', - 'UPPER_BOUND_SEGMENTS', - 'WAMF1', - 'DrivenControl', - 'new_predefined_driven_control'] +=============== +driven_controls +=============== +""" + +##### Maximum and Minimum bounds ###### + +UPPER_BOUND_RABI_RATE = 1e10 +"""Maximum allowed rabi rate +""" + +UPPER_BOUND_DETUNING_RATE = UPPER_BOUND_RABI_RATE +"""Maximum allowed detuning rate +""" + +UPPER_BOUND_DURATION = 1e6 +"""Maximum allowed duration of a control +""" + +LOWER_BOUND_DURATION = 1e-12 +"""Minimum allowed duration of a control +""" + +UPPER_BOUND_SEGMENTS = 10000 +"""Maximum number of segments allowed in a control +""" + +##### Types of driven controls ###### + +PRIMITIVE = 'primitive' +"""Primitive control +""" + +BB1 = 'BB1' +"""First-order Wimperis control, also known as BB1 +""" + +SK1 = 'SK1' +"""First-order Solovay-Kitaev control +""" + +WAMF1 = 'WAMF1' +"""First-order Walsh sequence control +""" + +CORPSE = 'CORPSE' +"""Dynamically corrected control - Compensating for Off-Resonance with a Pulse Sequence (COPRSE) +""" + +CORPSE_IN_BB1 = 'CORPSE in BB1' +"""Concatenated dynamically corrected control - BB1 inside COPRSE +""" + +CORPSE_IN_SK1 = 'CORPSE in SK1' +"""Concatenated dynamically corrected control - First order Solovay-Kitaev inside COPRSE +""" + +SCROFULOUS = 'SCROFULOUS' +"""Dynamically corrected control - + Short Composite Rotation For Undoing Length Over and Under Shoot (SCROFULOUS) +""" + +CORPSE_IN_SCROFULOUS = 'CORPSE in SCROFULOUS' +"""Concatenated dynamically corrected control - CORPSE inside SCROFULOUS +""" diff --git a/qctrlopencontrols/driven_controls/constants.py b/qctrlopencontrols/driven_controls/constants.py deleted file mode 100644 index 6952a751..00000000 --- a/qctrlopencontrols/driven_controls/constants.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright 2019 Q-CTRL Pty Ltd & Q-CTRL Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -========================== -driven_controls.constants -========================== -""" - -#maximum and minimum values -UPPER_BOUND_RABI_RATE = 1e10 -"""Maximum allowed rabi rate -""" - -UPPER_BOUND_DETUNING_RATE = UPPER_BOUND_RABI_RATE -"""Maximum allowed detuning rate -""" - -UPPER_BOUND_DURATION = 1e6 -"""Maximum allowed duration of a control -""" - -LOWER_BOUND_DURATION = 1e-12 -"""Minimum allowed duration of a control -""" - -UPPER_BOUND_SEGMENTS = 10000 -"""Maximum number of segments allowed in a control -""" - -#Driven control types -PRIMITIVE = 'primitive' -"""Primitive control -""" - -BB1 = 'BB1' -"""First-order Wimperis control, also known as BB1 -""" - -SK1 = 'SK1' -"""First-order Solovay-Kitaev control -""" - -WAMF1 = 'WAMF1' -"""First-order Walsh sequence control -""" - -CORPSE = 'CORPSE' -"""Dynamically corrected control - Compensating for Off-Resonance with a Pulse Sequence (COPRSE) -""" - -CORPSE_IN_BB1 = 'CORPSE in BB1' -"""Concatenated dynamically corrected control - BB1 inside COPRSE -""" - -CORPSE_IN_SK1 = 'CORPSE in SK1' -"""Concatenated dynamically corrected control - First order Solovay-Kitaev inside COPRSE -""" - -SCROFULOUS = 'SCROFULOUS' -"""Dynamically corrected control - - Short Composite Rotation For Undoing Length Over and Under Shoot (SCROFULOUS) -""" - -CORPSE_IN_SCROFULOUS = 'CORPSE in SCROFULOUS' -"""Concatenated dynamically corrected control - CORPSE inside SCROFULOUS -""" diff --git a/qctrlopencontrols/driven_controls/driven_control.py b/qctrlopencontrols/driven_controls/driven_control.py index 222a346b..736f1326 100644 --- a/qctrlopencontrols/driven_controls/driven_control.py +++ b/qctrlopencontrols/driven_controls/driven_control.py @@ -20,13 +20,13 @@ import json import numpy as np -from qctrlopencontrols.exceptions import ArgumentsValueError -from qctrlopencontrols.base import create_repr_from_attributes +from ..exceptions.exceptions import ArgumentsValueError +from ..base.utils import create_repr_from_attributes -from qctrlopencontrols.globals import ( +from ..globals import ( QCTRL_EXPANDED, CSV, JSON, CARTESIAN, CYLINDRICAL) -from .constants import ( +from ..driven_controls import ( UPPER_BOUND_SEGMENTS, UPPER_BOUND_RABI_RATE, UPPER_BOUND_DETUNING_RATE, UPPER_BOUND_DURATION, LOWER_BOUND_DURATION) diff --git a/qctrlopencontrols/driven_controls/predefined.py b/qctrlopencontrols/driven_controls/predefined.py index 748f33be..ee529af3 100644 --- a/qctrlopencontrols/driven_controls/predefined.py +++ b/qctrlopencontrols/driven_controls/predefined.py @@ -23,17 +23,12 @@ import numpy as np -from qctrlopencontrols.exceptions import ArgumentsValueError -from .driven_control import DrivenControl +from ..exceptions.exceptions import ArgumentsValueError +from ..driven_controls import ( + BB1, CORPSE, CORPSE_IN_BB1, CORPSE_IN_SCROFULOUS, CORPSE_IN_SK1, + PRIMITIVE, SCROFULOUS, SK1, WAMF1) -from .constants import ( - PRIMITIVE, BB1, SK1, - WAMF1, - CORPSE, - CORPSE_IN_SK1, - CORPSE_IN_BB1, - SCROFULOUS, - CORPSE_IN_SCROFULOUS) +from .driven_control import DrivenControl def new_predefined_driven_control( diff --git a/qctrlopencontrols/dynamic_decoupling_sequences/__init__.py b/qctrlopencontrols/dynamic_decoupling_sequences/__init__.py index 30a359ab..7018cc57 100644 --- a/qctrlopencontrols/dynamic_decoupling_sequences/__init__.py +++ b/qctrlopencontrols/dynamic_decoupling_sequences/__init__.py @@ -13,31 +13,58 @@ # limitations under the License. """ -================ -Sequences module -================ -""" - -from .constants import ( - UPPER_BOUND_OFFSETS, SPIN_ECHO, CARR_PURCELL, - CARR_PURCELL_MEIBOOM_GILL, UHRIG_SINGLE_AXIS, - PERIODIC_SINGLE_AXIS, WALSH_SINGLE_AXIS, QUADRATIC, - X_CONCATENATED, XY_CONCATENATED) - -from .dynamic_decoupling_sequence import DynamicDecouplingSequence -from .predefined import new_predefined_dds -from .driven_controls import convert_dds_to_driven_control - -__all__ = ['CARR_PURCELL', - 'CARR_PURCELL_MEIBOOM_GILL', - 'UPPER_BOUND_OFFSETS', - 'PERIODIC_SINGLE_AXIS', - 'QUADRATIC', - 'SPIN_ECHO', - 'UHRIG_SINGLE_AXIS', - 'WALSH_SINGLE_AXIS', - 'X_CONCATENATED', - 'XY_CONCATENATED', - 'DynamicDecouplingSequence', - 'convert_dds_to_driven_control', - 'new_predefined_dds'] +============================ +dynamic_decoupling_sequences +============================ +""" + +UPPER_BOUND_OFFSETS = 10000 +"""Maximum number of offsets allowed in a Dynamical +Decoupling sequence. +""" + +MATPLOTLIB = 'matplotlib' +"""Matplotlib format of data for plotting +""" + +###### Types of Dynamic Decoupling Sequences ####### + +RAMSEY = 'Ramsey' +"""Ramsey sequence +""" + +SPIN_ECHO = 'spin echo' +"""Spin echo (SE) dynamical decoupling sequence +""" + +CARR_PURCELL = 'Carr-Purcell' +"""Carr-Purcell (CP) dynamical decoupling sequence +""" + +CARR_PURCELL_MEIBOOM_GILL = 'Carr-Purcell-Meiboom-Gill' +"""Carr-Purcell-Meiboom-Gill (CPMG) dynamical decoupling sequence +""" + +UHRIG_SINGLE_AXIS = 'Uhrig single-axis' +"""Uhrig (single-axis) dynamical decoupling sequence +""" + +PERIODIC_SINGLE_AXIS = 'periodic single-axis' +"""Periodical dynamical decoupling sequence +""" + +WALSH_SINGLE_AXIS = 'Walsh single-axis' +"""Walsh dynamical decoupling sequence +""" + +QUADRATIC = 'quadratic' +"""Quadratic dynamical decoupling sequence +""" + +X_CONCATENATED = 'X concatenated' +"""X-Concatenated dynamical decoupling sequence +""" + +XY_CONCATENATED = 'XY concatenated' +"""XY-Concatenated dynamical decoupling sequence +""" diff --git a/qctrlopencontrols/dynamic_decoupling_sequences/constants.py b/qctrlopencontrols/dynamic_decoupling_sequences/constants.py deleted file mode 100644 index 2fa06ff7..00000000 --- a/qctrlopencontrols/dynamic_decoupling_sequences/constants.py +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright 2019 Q-CTRL Pty Ltd & Q-CTRL Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -====================================== -dynamic_decoupling_sequences.constants -====================================== -""" - -UPPER_BOUND_OFFSETS = 10000 -"""Maximum number of offsets allowed in a Dynamical -Decoupling sequence. -""" - -RAMSEY = 'Ramsey' -"""Ramsey sequence -""" - -SPIN_ECHO = 'spin echo' -"""Spin echo (SE) dynamical decoupling sequence -""" - -CARR_PURCELL = 'Carr-Purcell' -"""Carr-Purcell (CP) dynamical decoupling sequence -""" - -CARR_PURCELL_MEIBOOM_GILL = 'Carr-Purcell-Meiboom-Gill' -"""Carr-Purcell-Meiboom-Gill (CPMG) dynamical decoupling sequence -""" - -UHRIG_SINGLE_AXIS = 'Uhrig single-axis' -"""Uhrig (single-axis) dynamical decoupling sequence -""" - -PERIODIC_SINGLE_AXIS = 'periodic single-axis' -"""Periodical dynamical decoupling sequence -""" - -WALSH_SINGLE_AXIS = 'Walsh single-axis' -"""Walsh dynamical decoupling sequence -""" - -QUADRATIC = 'quadratic' -"""Quadratic dynamical decoupling sequence -""" - -X_CONCATENATED = 'X concatenated' -"""X-Concatenated dynamical decoupling sequence -""" - -XY_CONCATENATED = 'XY concatenated' -"""XY-Concatenated dynamical decoupling sequence -""" - -MATPLOTLIB = 'matplotlib' -"""Matplotlib format of data for plotting -""" diff --git a/qctrlopencontrols/dynamic_decoupling_sequences/driven_controls.py b/qctrlopencontrols/dynamic_decoupling_sequences/driven_controls.py index 092c9e4e..6ca05197 100644 --- a/qctrlopencontrols/dynamic_decoupling_sequences/driven_controls.py +++ b/qctrlopencontrols/dynamic_decoupling_sequences/driven_controls.py @@ -20,9 +20,10 @@ import numpy as np -from qctrlopencontrols.exceptions import ArgumentsValueError -from qctrlopencontrols.driven_controls import ( - UPPER_BOUND_RABI_RATE, UPPER_BOUND_DETUNING_RATE, DrivenControl) +from ..exceptions.exceptions import ArgumentsValueError +from ..driven_controls import ( + UPPER_BOUND_RABI_RATE, UPPER_BOUND_DETUNING_RATE) +from ..driven_controls.driven_control import DrivenControl def _check_valid_operation(rabi_rotations, detuning_rotations): diff --git a/qctrlopencontrols/dynamic_decoupling_sequences/dynamic_decoupling_sequence.py b/qctrlopencontrols/dynamic_decoupling_sequences/dynamic_decoupling_sequence.py index 9b5c097c..33eff97c 100644 --- a/qctrlopencontrols/dynamic_decoupling_sequences/dynamic_decoupling_sequence.py +++ b/qctrlopencontrols/dynamic_decoupling_sequences/dynamic_decoupling_sequence.py @@ -20,13 +20,13 @@ import numpy as np -from qctrlopencontrols.base import create_repr_from_attributes -from qctrlopencontrols.exceptions import ArgumentsValueError +from ..base.utils import create_repr_from_attributes +from ..exceptions.exceptions import ArgumentsValueError -from qctrlopencontrols.globals import ( +from ..globals import ( QCTRL_EXPANDED, CSV, CYLINDRICAL) -from .constants import (UPPER_BOUND_OFFSETS, MATPLOTLIB) +from ..dynamic_decoupling_sequences import (UPPER_BOUND_OFFSETS, MATPLOTLIB) from .driven_controls import convert_dds_to_driven_control diff --git a/qctrlopencontrols/dynamic_decoupling_sequences/predefined.py b/qctrlopencontrols/dynamic_decoupling_sequences/predefined.py index 27b4a6bd..78cd9fb9 100644 --- a/qctrlopencontrols/dynamic_decoupling_sequences/predefined.py +++ b/qctrlopencontrols/dynamic_decoupling_sequences/predefined.py @@ -20,16 +20,11 @@ import numpy as np -from qctrlopencontrols.exceptions import ArgumentsValueError - -from .constants import (RAMSEY, SPIN_ECHO, CARR_PURCELL, - CARR_PURCELL_MEIBOOM_GILL, - UHRIG_SINGLE_AXIS, - PERIODIC_SINGLE_AXIS, - WALSH_SINGLE_AXIS, - QUADRATIC, - X_CONCATENATED, - XY_CONCATENATED) +from ..exceptions.exceptions import ArgumentsValueError + +from ..dynamic_decoupling_sequences import ( + CARR_PURCELL, CARR_PURCELL_MEIBOOM_GILL, PERIODIC_SINGLE_AXIS, QUADRATIC, RAMSEY, + SPIN_ECHO, UHRIG_SINGLE_AXIS, WALSH_SINGLE_AXIS, X_CONCATENATED, XY_CONCATENATED) from .dynamic_decoupling_sequence import DynamicDecouplingSequence diff --git a/qctrlopencontrols/exceptions/__init__.py b/qctrlopencontrols/exceptions/__init__.py index 9b5e06ea..a2b61496 100644 --- a/qctrlopencontrols/exceptions/__init__.py +++ b/qctrlopencontrols/exceptions/__init__.py @@ -11,13 +11,3 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - -""" -================= -Exceptions module -================= -""" - -from .exceptions import ArgumentsValueError - -__all__ = ['ArgumentsValueError'] diff --git a/qctrlopencontrols/globals/__init__.py b/qctrlopencontrols/globals/__init__.py index d93432fd..d3d25a39 100644 --- a/qctrlopencontrols/globals/__init__.py +++ b/qctrlopencontrols/globals/__init__.py @@ -49,6 +49,3 @@ """Algorithm to convert a DDS to Quantum circuit where the unitaties are considered as instantaneous operation. """ - -__all__ = ['QCTRL_EXPANDED', 'CSV', 'JSON', 'CARTESIAN', - 'CYLINDRICAL', 'FIX_DURATION_UNITARY', 'INSTANT_UNITARY'] diff --git a/qctrlopencontrols/qiskit/__init__.py b/qctrlopencontrols/qiskit/__init__.py index 3377237b..a2b61496 100644 --- a/qctrlopencontrols/qiskit/__init__.py +++ b/qctrlopencontrols/qiskit/__init__.py @@ -11,13 +11,3 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - -""" -============= -qiskit module -============= -""" - -from .quantum_circuit import (convert_dds_to_qiskit_quantum_circuit) - -__all__ = ['convert_dds_to_qiskit_quantum_circuit'] diff --git a/qctrlopencontrols/qiskit/quantum_circuit.py b/qctrlopencontrols/qiskit/quantum_circuit.py index c322f0f6..e5177453 100644 --- a/qctrlopencontrols/qiskit/quantum_circuit.py +++ b/qctrlopencontrols/qiskit/quantum_circuit.py @@ -24,9 +24,9 @@ QuantumRegister, ClassicalRegister, QuantumCircuit) from qiskit.qasm import pi -from qctrlopencontrols.dynamic_decoupling_sequences import DynamicDecouplingSequence -from qctrlopencontrols.exceptions import ArgumentsValueError -from qctrlopencontrols.globals import (FIX_DURATION_UNITARY, INSTANT_UNITARY) +from ..dynamic_decoupling_sequences.dynamic_decoupling_sequence import DynamicDecouplingSequence +from ..exceptions.exceptions import ArgumentsValueError +from ..globals import (FIX_DURATION_UNITARY, INSTANT_UNITARY) def convert_dds_to_qiskit_quantum_circuit( diff --git a/tests/test_driven_controls.py b/tests/test_driven_controls.py index da2b336b..564987f9 100644 --- a/tests/test_driven_controls.py +++ b/tests/test_driven_controls.py @@ -21,10 +21,10 @@ import numpy as np import pytest -from qctrlopencontrols.exceptions import ArgumentsValueError +from qctrlopencontrols.exceptions.exceptions import ArgumentsValueError from qctrlopencontrols import DrivenControl -from qctrlopencontrols import ( +from qctrlopencontrols.driven_controls import ( UPPER_BOUND_SEGMENTS, UPPER_BOUND_RABI_RATE, UPPER_BOUND_DETUNING_RATE) diff --git a/tests/test_dynamical_decoupling.py b/tests/test_dynamical_decoupling.py index 6670ff71..50fb21b0 100644 --- a/tests/test_dynamical_decoupling.py +++ b/tests/test_dynamical_decoupling.py @@ -20,7 +20,7 @@ import os import pytest import numpy as np -from qctrlopencontrols.exceptions import ArgumentsValueError +from qctrlopencontrols.exceptions.exceptions import ArgumentsValueError from qctrlopencontrols import ( DynamicDecouplingSequence, convert_dds_to_driven_control) diff --git a/tests/test_predefined_driven_controls.py b/tests/test_predefined_driven_controls.py index e9addc12..5adbbaf0 100644 --- a/tests/test_predefined_driven_controls.py +++ b/tests/test_predefined_driven_controls.py @@ -20,10 +20,10 @@ import numpy as np import pytest -from qctrlopencontrols.exceptions import ArgumentsValueError +from qctrlopencontrols.exceptions.exceptions import ArgumentsValueError -from qctrlopencontrols import ( - new_predefined_driven_control, +from qctrlopencontrols import new_predefined_driven_control +from qctrlopencontrols.driven_controls import( PRIMITIVE, BB1, SK1, CORPSE, SCROFULOUS, CORPSE_IN_SCROFULOUS, CORPSE_IN_BB1, CORPSE_IN_SK1, WAMF1) diff --git a/tests/test_predefined_dynamical_decoupling.py b/tests/test_predefined_dynamical_decoupling.py index 2470d381..bb7a275d 100644 --- a/tests/test_predefined_dynamical_decoupling.py +++ b/tests/test_predefined_dynamical_decoupling.py @@ -23,9 +23,9 @@ import pytest -from qctrlopencontrols.exceptions import ArgumentsValueError +from qctrlopencontrols.exceptions.exceptions import ArgumentsValueError from qctrlopencontrols import new_predefined_dds -from qctrlopencontrols import ( +from qctrlopencontrols.dynamic_decoupling_sequences import ( SPIN_ECHO, CARR_PURCELL, CARR_PURCELL_MEIBOOM_GILL, WALSH_SINGLE_AXIS, PERIODIC_SINGLE_AXIS, UHRIG_SINGLE_AXIS, QUADRATIC, X_CONCATENATED,