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..2f0f11ee 100644 --- a/qctrlopencontrols/__init__.py +++ b/qctrlopencontrols/__init__.py @@ -14,14 +14,27 @@ """ ================= -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 .cirq.circuit import convert_dds_to_cirq_circuit +from .cirq.schedule import convert_dds_to_cirq_schedule + +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 705fccab..a2b61496 100644 --- a/qctrlopencontrols/base/__init__.py +++ b/qctrlopencontrols/base/__init__.py @@ -11,11 +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 .qctrl_object import QctrlObject 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..cbddb2e4 --- /dev/null +++ b/qctrlopencontrols/base/utils.py @@ -0,0 +1,77 @@ +# 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 ..exceptions.exceptions import ArgumentsValueError + + +def create_repr_from_attributes(class_instance=None, attributes=None): + + """Returns a string representation of an object + + Parameters + ---------- + 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.__class__.__name__}". + format(class_instance)' + + Raises + ------ + ArgumentsValueError + If class name is not a string or any of the attribute name is not string type + """ + + 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) + + 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(getattr(class_instance, 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..a2b61496 100644 --- a/qctrlopencontrols/cirq/__init__.py +++ b/qctrlopencontrols/cirq/__init__.py @@ -11,12 +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 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 779ff29a..40858ed5 100644 --- a/qctrlopencontrols/driven_controls/__init__.py +++ b/qctrlopencontrols/driven_controls/__init__.py @@ -13,30 +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, - 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) +=============== +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 5ef657a8..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 874de8b6..736f1326 100644 --- a/qctrlopencontrols/driven_controls/driven_control.py +++ b/qctrlopencontrols/driven_controls/driven_control.py @@ -20,18 +20,18 @@ import json import numpy as np -from qctrlopencontrols.exceptions import ArgumentsValueError -from qctrlopencontrols.base import QctrlObject +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) -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,26 @@ 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', + 'azimuthal_angles', + 'detunings', + 'durations', + 'name'] + + return create_repr_from_attributes(self, attributes) + if __name__ == '__main__': pass diff --git a/qctrlopencontrols/driven_controls/predefined.py b/qctrlopencontrols/driven_controls/predefined.py index c47d9b6e..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( @@ -73,30 +68,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 +199,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 +235,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 +280,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 +325,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 +405,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 +450,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 +500,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 +549,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 +642,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..7018cc57 100644 --- a/qctrlopencontrols/dynamic_decoupling_sequences/__init__.py +++ b/qctrlopencontrols/dynamic_decoupling_sequences/__init__.py @@ -13,17 +13,58 @@ # limitations under the License. """ -================ -Sequences module -================ +============================ +dynamic_decoupling_sequences +============================ """ -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) +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 +""" -from .dynamic_decoupling_sequence import DynamicDecouplingSequence -from .predefined import new_predefined_dds -from .driven_controls import convert_dds_to_driven_control +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 d4404887..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. - -""" -=================== -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 228dc192..6ca05197 100644 --- a/qctrlopencontrols/dynamic_decoupling_sequences/driven_controls.py +++ b/qctrlopencontrols/dynamic_decoupling_sequences/driven_controls.py @@ -13,16 +13,17 @@ # limitations under the License. """ -========================= -sequences.driven_controls -========================= +============================================= +dynamic_decoupling_sequences.driven_controls +============================================= """ 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 61f13e0c..33eff97c 100644 --- a/qctrlopencontrols/dynamic_decoupling_sequences/dynamic_decoupling_sequence.py +++ b/qctrlopencontrols/dynamic_decoupling_sequences/dynamic_decoupling_sequence.py @@ -13,24 +13,24 @@ # limitations under the License. """ -=================== -sequences.sequences -=================== +======================================================== +dynamic_decoupling_sequences.dynamic_decoupling_sequence +======================================================== """ import numpy as np -from qctrlopencontrols.base import QctrlObject -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 -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. @@ -73,14 +73,6 @@ def __init__(self, name=None ): - super(DynamicDecouplingSequence, self).__init__([ - 'duration', - 'offsets', - 'rabi_rotations', - 'azimuthal_angles', - 'detuning_rotations', - 'name']) - self.duration = duration if self.duration <= 0.: raise ArgumentsValueError( @@ -117,8 +109,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 +133,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 +209,27 @@ 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', + 'offsets', + 'rabi_rotations', + 'azimuthal_angles', + 'detuning_rotations', + 'name'] + + return create_repr_from_attributes(self, 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..78cd9fb9 100644 --- a/qctrlopencontrols/dynamic_decoupling_sequences/predefined.py +++ b/qctrlopencontrols/dynamic_decoupling_sequences/predefined.py @@ -13,23 +13,18 @@ # limitations under the License. """ -=================== -sequence.predefined -=================== +======================================== +dynamic_decoupling_sequences.predefined +======================================== """ import numpy as np -from qctrlopencontrols.exceptions import ArgumentsValueError +from ..exceptions.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 ..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 @@ -69,25 +64,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 +126,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 +174,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 +222,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 +280,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 +342,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 +403,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 +463,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 +541,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 +644,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 +722,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..a2b61496 100644 --- a/qctrlopencontrols/exceptions/__init__.py +++ b/qctrlopencontrols/exceptions/__init__.py @@ -11,11 +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 diff --git a/qctrlopencontrols/qiskit/__init__.py b/qctrlopencontrols/qiskit/__init__.py index 899a7499..a2b61496 100644 --- a/qctrlopencontrols/qiskit/__init__.py +++ b/qctrlopencontrols/qiskit/__init__.py @@ -11,11 +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_quantum_circuit) diff --git a/qctrlopencontrols/qiskit/quantum_circuit.py b/qctrlopencontrols/qiskit/quantum_circuit.py index 913f8f4f..e5177453 100644 --- a/qctrlopencontrols/qiskit/quantum_circuit.py +++ b/qctrlopencontrols/qiskit/quantum_circuit.py @@ -24,12 +24,12 @@ 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_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..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.driven_controls.constants 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 e65ed4cd..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) @@ -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..5adbbaf0 100644 --- a/tests/test_predefined_driven_controls.py +++ b/tests/test_predefined_driven_controls.py @@ -20,19 +20,12 @@ import numpy as np import pytest -from qctrlopencontrols.exceptions import ArgumentsValueError +from qctrlopencontrols.exceptions.exceptions import ArgumentsValueError -from qctrlopencontrols.driven_controls 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 -) +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) 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..bb7a275d 100644 --- a/tests/test_predefined_dynamical_decoupling.py +++ b/tests/test_predefined_dynamical_decoupling.py @@ -23,8 +23,8 @@ import pytest -from qctrlopencontrols.exceptions import ArgumentsValueError -import qctrlopencontrols.dynamic_decoupling_sequences.predefined as pre +from qctrlopencontrols.exceptions.exceptions import ArgumentsValueError +from qctrlopencontrols import new_predefined_dds from qctrlopencontrols.dynamic_decoupling_sequences import ( SPIN_ECHO, CARR_PURCELL, CARR_PURCELL_MEIBOOM_GILL, WALSH_SINGLE_AXIS, PERIODIC_SINGLE_AXIS, @@ -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)