Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 0 additions & 82 deletions qctrlopencontrols/driven_controls/driven_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,88 +531,6 @@ def export(self, coordinates=CYLINDRICAL, dimensionless_rabi_rate=True):

return plot_dictionary

def get_plot_formatted_arrays(self, coordinates=CARTESIAN, dimensionless_rabi_rate=True):
""" Gets arrays for plotting a driven control.

Parameters
----------
dimensionless_rabi_rate: boolean
If True, calculates the dimensionless values for segments
coordinates : string
Indicated the type of segments that need to be transformed can be 'cartesian' or
'cylindrical'.

Returns
-------
dict
A dict with keywords depending on the chosen coordinates. For 'cylindrical', we have
'rabi_rate', 'azimuthal_angle', 'detuning' and 'times', and for 'cartesian' we have
'amplitude_x', 'amplitude_y', 'detuning' and 'times'.

Notes
-----
The plot data can have repeated times and for amplitudes, because it is expected
that these coordinates are to be used with plotting software that 'joins the dots' with
linear lines between each coordinate. The time array gives the x values for all the
amplitude arrays, which give the y values.

Raises
------
ArgumentsValueError
Raised when an argument is invalid.
"""
if coordinates not in [CARTESIAN, CYLINDRICAL]:
raise ArgumentsValueError(
'Unsupported coordinates provided: ',
arguments={'coordinates': coordinates})

if dimensionless_rabi_rate:
normalizer = self.maximum_rabi_rate
else:
normalizer = 1

if coordinates == CARTESIAN:
control_segments = np.vstack((
self.amplitude_x / normalizer,
self.amplitude_y / normalizer,
self.detunings,
self.durations)).T
elif coordinates == CYLINDRICAL:
control_segments = np.vstack((
self.rabi_rates / normalizer,
self.azimuthal_angles,
self.detunings,
self.durations)).T

segment_times = np.insert(np.cumsum(control_segments[:, 3]), 0, 0.)
plot_time = (segment_times[:, np.newaxis] * np.ones((1, 2))).flatten()
plot_amplitude_x = control_segments[:, 0]
plot_amplitude_y = control_segments[:, 1]
plot_amplitude_z = control_segments[:, 2]

plot_amplitude_x = np.concatenate(
([0.], (plot_amplitude_x[:, np.newaxis] * np.ones((1, 2))).flatten(), [0.]))
plot_amplitude_y = np.concatenate(
([0.], (plot_amplitude_y[:, np.newaxis] * np.ones((1, 2))).flatten(), [0.]))
plot_amplitude_z = np.concatenate(
([0.], (plot_amplitude_z[:, np.newaxis] * np.ones((1, 2))).flatten(), [0.]))

plot_dictionary = {}
if coordinates == CARTESIAN:
plot_dictionary = {
'amplitudes_x': plot_amplitude_x,
'amplitudes_y': plot_amplitude_y,
'detunings': plot_amplitude_z,
'times': plot_time}

if coordinates == CYLINDRICAL:
plot_dictionary = {
'rabi_rates': plot_amplitude_x,
'azimuthal_angles': plot_amplitude_y,
'detunings': plot_amplitude_z,
'times': plot_time}
return plot_dictionary

def __str__(self):
"""Prepares a friendly string format for a Driven Control
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,68 +170,6 @@ def export(self):

return plot_dictionary

def get_plot_formatted_arrays(self, plot_format=MATPLOTLIB):
"""Gets arrays for plotting a pulse.

Parameters
----------
plot_format : string, optional
Indicates the format of the plot; Defaults to `matplotlib`

Returns
-------
dict
A dict with keywords 'rabi_rotations', 'azimuthal_angles',
'detuning_rotations' and 'times'.

Raises
------
ArgumentsValueError
Raised if `plot_format` is not recognized.
"""

if plot_format != MATPLOTLIB:
raise ArgumentsValueError("Open Controls currently supports `matplotlib` "
"data format only.",
{'data_format': plot_format})

offsets = self.offsets
number_of_offsets = self.number_of_offsets

plot_data = dict()

rabi_rotations = self.rabi_rotations
azimuthal_angles = self.azimuthal_angles
detuning_rotations = self.detuning_rotations

rabi_rotations = np.reshape(rabi_rotations, (-1, 1))
azimuthal_angles = np.reshape(azimuthal_angles, (-1, 1))
detuning_rotations = np.reshape(detuning_rotations, (-1, 1))

plot_times = offsets[:, np.newaxis]
plot_times = np.repeat(plot_times, 3, axis=1)

multiplier = np.array([0, 1, 0])
multiplier = multiplier[np.newaxis, :]
multiplier = np.repeat(multiplier, number_of_offsets, axis=0)
multiplier = multiplier[np.newaxis, :]

rabi_rotations = rabi_rotations * multiplier
azimuthal_angles = azimuthal_angles * multiplier
detuning_rotations = detuning_rotations * multiplier

plot_times = plot_times.flatten()
rabi_rotations = rabi_rotations.flatten()
azimuthal_angles = azimuthal_angles.flatten()
detuning_rotations = detuning_rotations.flatten()

plot_data['rabi_rotations'] = rabi_rotations
plot_data['azimuthal_angles'] = azimuthal_angles
plot_data['detuning_rotations'] = detuning_rotations
plot_data['times'] = plot_times

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.
Expand Down
19 changes: 10 additions & 9 deletions tests/test_driven_controls.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,19 +197,20 @@ def test_plot_data():
durations=_durations
)

x_amplitude = [0., np.pi, np.pi, 0., 0., 0., 0., 0.]
y_amplitude = [0., 0., 0., 2*np.pi, 2*np.pi, -np.pi, -np.pi, 0.]
z_amplitude = [0., 0., 0., 1., 1., 0., 0., 0.]
times = [0., 0., 1., 1., 2.25, 2.25, 3.75, 3.75]
x_amplitude = [np.pi, 0., 0.]
y_amplitude = [0., 2*np.pi, -np.pi]

plot_data = driven_control.get_plot_formatted_arrays(
plot_data = driven_control.export(
dimensionless_rabi_rate=False, coordinates='cartesian'
)

assert np.allclose(plot_data['times'], times)
assert np.allclose(plot_data['amplitudes_x'], x_amplitude)
assert np.allclose(plot_data['amplitudes_y'], y_amplitude)
assert np.allclose(plot_data['detunings'], z_amplitude)
assert np.allclose([point['duration'] for point in plot_data['X amplitude']], _durations)
assert np.allclose([point['duration'] for point in plot_data['Y amplitude']], _durations)
assert np.allclose([point['duration'] for point in plot_data['Detuning']], _durations)

assert np.allclose([point['value'] for point in plot_data['X amplitude']], x_amplitude)
assert np.allclose([point['value'] for point in plot_data['Y amplitude']], y_amplitude)
assert np.allclose([point['value'] for point in plot_data['Detuning']], _detunings)

def test_pretty_print():

Expand Down
92 changes: 26 additions & 66 deletions tests/test_dynamical_decoupling.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,95 +133,55 @@ def test_sequence_plot():
_azimuthal_angle = np.array([0, 0, 0, 0, 0])
_detuning_rotations = np.array([0, 0, 0, 0, 0])

_plot_times = np.array([0, 0, 0,
0.25, 0.25, 0.25,
0.5, 0.5, 0.5,
0.75, 0.75, 0.75,
1., 1., 1.])
_plot_rabi_rotations = np.array([0, 0, 0,
0, np.pi, 0,
0, 0, 0,
0, np.pi, 0,
0, 0, 0])
_plot_azimuthal_angles = np.array([0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0])

_plot_detuning_rotations = np.array([0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0])

seq = DynamicDecouplingSequence(
duration=1.0,
offsets=_offsets,
rabi_rotations=_rabi_rotations,
azimuthal_angles=_azimuthal_angle,
detuning_rotations=_detuning_rotations)

plot_data = seq.get_plot_formatted_arrays()
plot_rabi, plot_azimuthal, plot_detuning, plot_times = (
plot_data['rabi_rotations'],
plot_data['azimuthal_angles'],
plot_data['detuning_rotations'],
plot_data['times']
)
plot_data = seq.export()

_plot_rabi_offsets = [pulse['offset'] for pulse in plot_data['Rabi']]
_plot_detuning_offsets = [pulse['offset'] for pulse in plot_data['Detuning']]
_plot_rabi_rotations = [pulse['rotation'] for pulse in plot_data['Rabi']]
_plot_detuning_rotations = [pulse['rotation'] for pulse in plot_data['Detuning']]

assert np.allclose(_plot_rabi_offsets, _offsets)
assert np.allclose(_plot_detuning_offsets, _offsets)

assert np.allclose(np.abs(_plot_rabi_rotations), _rabi_rotations)
assert np.allclose(np.angle(_plot_rabi_rotations), _azimuthal_angle)

assert np.allclose(_plot_rabi_rotations, plot_rabi)
assert np.allclose(_plot_azimuthal_angles, plot_azimuthal)
assert np.allclose(_plot_detuning_rotations, plot_detuning)
assert np.allclose(_plot_times, plot_times)
assert np.allclose(_plot_detuning_rotations, _detuning_rotations)

# with both X and Y pi
_offsets = np.array([0, 0.25, 0.5, 0.75, 1.00])
_rabi_rotations = np.array([0, np.pi, 0, np.pi, 0])
_azimuthal_angle = np.array([0, np.pi/2, 0, np.pi/2, 0])
_detuning_rotations = np.array([0, 0, 0, 0, 0])

_plot_rabi_rotations = np.array([0, 0, 0,
0, np.pi, 0,
0, 0, 0,
0, np.pi, 0,
0, 0, 0])
_plot_azimuthal_angles = np.array([0, 0, 0,
0, np.pi/2, 0,
0, 0, 0,
0, np.pi/2, 0,
0, 0, 0])

_plot_detuning_rotations = np.array([0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0])

_plot_times = np.array([0, 0, 0,
0.25, 0.25, 0.25,
0.5, 0.5, 0.5,
0.75, 0.75, 0.75,
1., 1., 1.])
seq = DynamicDecouplingSequence(
duration=1.0,
offsets=_offsets,
rabi_rotations=_rabi_rotations,
azimuthal_angles=_azimuthal_angle,
detuning_rotations=_detuning_rotations)

plot_data = seq.get_plot_formatted_arrays()
plot_rabi, plot_azimuthal, plot_detuning, plot_times = (
plot_data['rabi_rotations'],
plot_data['azimuthal_angles'],
plot_data['detuning_rotations'],
plot_data['times']
)
plot_data = seq.export()

_plot_rabi_offsets = [pulse['offset'] for pulse in plot_data['Rabi']]
_plot_detuning_offsets = [pulse['offset'] for pulse in plot_data['Detuning']]
_plot_rabi_rotations = [pulse['rotation'] for pulse in plot_data['Rabi']]
_plot_detuning_rotations = [pulse['rotation'] for pulse in plot_data['Detuning']]

assert np.allclose(_plot_rabi_offsets, _offsets)
assert np.allclose(_plot_detuning_offsets, _offsets)

assert np.allclose(np.abs(_plot_rabi_rotations), _rabi_rotations)
assert np.allclose(np.angle(_plot_rabi_rotations), _azimuthal_angle)

assert np.allclose(_plot_rabi_rotations, plot_rabi)
assert np.allclose(_plot_azimuthal_angles, plot_azimuthal)
assert np.allclose(_plot_detuning_rotations, plot_detuning)
assert np.allclose(_plot_times, plot_times)
assert np.allclose(_plot_detuning_rotations, _detuning_rotations)


def test_pretty_string_format():
Expand Down