Skip to content

Commit 778e020

Browse files
authored
Merge pull request #36 from qctrl/enhanced-figures
Removing deprecated get_plot_formatted_arrays methods and updating the tests to use the new export methods
2 parents c58eb96 + adcc938 commit 778e020

File tree

4 files changed

+36
-219
lines changed

4 files changed

+36
-219
lines changed

qctrlopencontrols/driven_controls/driven_control.py

Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -531,88 +531,6 @@ def export(self, coordinates=CYLINDRICAL, dimensionless_rabi_rate=True):
531531

532532
return plot_dictionary
533533

534-
def get_plot_formatted_arrays(self, coordinates=CARTESIAN, dimensionless_rabi_rate=True):
535-
""" Gets arrays for plotting a driven control.
536-
537-
Parameters
538-
----------
539-
dimensionless_rabi_rate: boolean
540-
If True, calculates the dimensionless values for segments
541-
coordinates : string
542-
Indicated the type of segments that need to be transformed can be 'cartesian' or
543-
'cylindrical'.
544-
545-
Returns
546-
-------
547-
dict
548-
A dict with keywords depending on the chosen coordinates. For 'cylindrical', we have
549-
'rabi_rate', 'azimuthal_angle', 'detuning' and 'times', and for 'cartesian' we have
550-
'amplitude_x', 'amplitude_y', 'detuning' and 'times'.
551-
552-
Notes
553-
-----
554-
The plot data can have repeated times and for amplitudes, because it is expected
555-
that these coordinates are to be used with plotting software that 'joins the dots' with
556-
linear lines between each coordinate. The time array gives the x values for all the
557-
amplitude arrays, which give the y values.
558-
559-
Raises
560-
------
561-
ArgumentsValueError
562-
Raised when an argument is invalid.
563-
"""
564-
if coordinates not in [CARTESIAN, CYLINDRICAL]:
565-
raise ArgumentsValueError(
566-
'Unsupported coordinates provided: ',
567-
arguments={'coordinates': coordinates})
568-
569-
if dimensionless_rabi_rate:
570-
normalizer = self.maximum_rabi_rate
571-
else:
572-
normalizer = 1
573-
574-
if coordinates == CARTESIAN:
575-
control_segments = np.vstack((
576-
self.amplitude_x / normalizer,
577-
self.amplitude_y / normalizer,
578-
self.detunings,
579-
self.durations)).T
580-
elif coordinates == CYLINDRICAL:
581-
control_segments = np.vstack((
582-
self.rabi_rates / normalizer,
583-
self.azimuthal_angles,
584-
self.detunings,
585-
self.durations)).T
586-
587-
segment_times = np.insert(np.cumsum(control_segments[:, 3]), 0, 0.)
588-
plot_time = (segment_times[:, np.newaxis] * np.ones((1, 2))).flatten()
589-
plot_amplitude_x = control_segments[:, 0]
590-
plot_amplitude_y = control_segments[:, 1]
591-
plot_amplitude_z = control_segments[:, 2]
592-
593-
plot_amplitude_x = np.concatenate(
594-
([0.], (plot_amplitude_x[:, np.newaxis] * np.ones((1, 2))).flatten(), [0.]))
595-
plot_amplitude_y = np.concatenate(
596-
([0.], (plot_amplitude_y[:, np.newaxis] * np.ones((1, 2))).flatten(), [0.]))
597-
plot_amplitude_z = np.concatenate(
598-
([0.], (plot_amplitude_z[:, np.newaxis] * np.ones((1, 2))).flatten(), [0.]))
599-
600-
plot_dictionary = {}
601-
if coordinates == CARTESIAN:
602-
plot_dictionary = {
603-
'amplitudes_x': plot_amplitude_x,
604-
'amplitudes_y': plot_amplitude_y,
605-
'detunings': plot_amplitude_z,
606-
'times': plot_time}
607-
608-
if coordinates == CYLINDRICAL:
609-
plot_dictionary = {
610-
'rabi_rates': plot_amplitude_x,
611-
'azimuthal_angles': plot_amplitude_y,
612-
'detunings': plot_amplitude_z,
613-
'times': plot_time}
614-
return plot_dictionary
615-
616534
def __str__(self):
617535
"""Prepares a friendly string format for a Driven Control
618536
"""

qctrlopencontrols/dynamic_decoupling_sequences/dynamic_decoupling_sequence.py

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -170,68 +170,6 @@ def export(self):
170170

171171
return plot_dictionary
172172

173-
def get_plot_formatted_arrays(self, plot_format=MATPLOTLIB):
174-
"""Gets arrays for plotting a pulse.
175-
176-
Parameters
177-
----------
178-
plot_format : string, optional
179-
Indicates the format of the plot; Defaults to `matplotlib`
180-
181-
Returns
182-
-------
183-
dict
184-
A dict with keywords 'rabi_rotations', 'azimuthal_angles',
185-
'detuning_rotations' and 'times'.
186-
187-
Raises
188-
------
189-
ArgumentsValueError
190-
Raised if `plot_format` is not recognized.
191-
"""
192-
193-
if plot_format != MATPLOTLIB:
194-
raise ArgumentsValueError("Open Controls currently supports `matplotlib` "
195-
"data format only.",
196-
{'data_format': plot_format})
197-
198-
offsets = self.offsets
199-
number_of_offsets = self.number_of_offsets
200-
201-
plot_data = dict()
202-
203-
rabi_rotations = self.rabi_rotations
204-
azimuthal_angles = self.azimuthal_angles
205-
detuning_rotations = self.detuning_rotations
206-
207-
rabi_rotations = np.reshape(rabi_rotations, (-1, 1))
208-
azimuthal_angles = np.reshape(azimuthal_angles, (-1, 1))
209-
detuning_rotations = np.reshape(detuning_rotations, (-1, 1))
210-
211-
plot_times = offsets[:, np.newaxis]
212-
plot_times = np.repeat(plot_times, 3, axis=1)
213-
214-
multiplier = np.array([0, 1, 0])
215-
multiplier = multiplier[np.newaxis, :]
216-
multiplier = np.repeat(multiplier, number_of_offsets, axis=0)
217-
multiplier = multiplier[np.newaxis, :]
218-
219-
rabi_rotations = rabi_rotations * multiplier
220-
azimuthal_angles = azimuthal_angles * multiplier
221-
detuning_rotations = detuning_rotations * multiplier
222-
223-
plot_times = plot_times.flatten()
224-
rabi_rotations = rabi_rotations.flatten()
225-
azimuthal_angles = azimuthal_angles.flatten()
226-
detuning_rotations = detuning_rotations.flatten()
227-
228-
plot_data['rabi_rotations'] = rabi_rotations
229-
plot_data['azimuthal_angles'] = azimuthal_angles
230-
plot_data['detuning_rotations'] = detuning_rotations
231-
plot_data['times'] = plot_times
232-
233-
return plot_data
234-
235173
def __repr__(self):
236174
"""Returns a string representation for the object. The returned string looks like a valid
237175
Python expression that could be used to recreate the object, including default arguments.

tests/test_driven_controls.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,19 +197,20 @@ def test_plot_data():
197197
durations=_durations
198198
)
199199

200-
x_amplitude = [0., np.pi, np.pi, 0., 0., 0., 0., 0.]
201-
y_amplitude = [0., 0., 0., 2*np.pi, 2*np.pi, -np.pi, -np.pi, 0.]
202-
z_amplitude = [0., 0., 0., 1., 1., 0., 0., 0.]
203-
times = [0., 0., 1., 1., 2.25, 2.25, 3.75, 3.75]
200+
x_amplitude = [np.pi, 0., 0.]
201+
y_amplitude = [0., 2*np.pi, -np.pi]
204202

205-
plot_data = driven_control.get_plot_formatted_arrays(
203+
plot_data = driven_control.export(
206204
dimensionless_rabi_rate=False, coordinates='cartesian'
207205
)
208206

209-
assert np.allclose(plot_data['times'], times)
210-
assert np.allclose(plot_data['amplitudes_x'], x_amplitude)
211-
assert np.allclose(plot_data['amplitudes_y'], y_amplitude)
212-
assert np.allclose(plot_data['detunings'], z_amplitude)
207+
assert np.allclose([point['duration'] for point in plot_data['X amplitude']], _durations)
208+
assert np.allclose([point['duration'] for point in plot_data['Y amplitude']], _durations)
209+
assert np.allclose([point['duration'] for point in plot_data['Detuning']], _durations)
210+
211+
assert np.allclose([point['value'] for point in plot_data['X amplitude']], x_amplitude)
212+
assert np.allclose([point['value'] for point in plot_data['Y amplitude']], y_amplitude)
213+
assert np.allclose([point['value'] for point in plot_data['Detuning']], _detunings)
213214

214215
def test_pretty_print():
215216

tests/test_dynamical_decoupling.py

Lines changed: 26 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -133,95 +133,55 @@ def test_sequence_plot():
133133
_azimuthal_angle = np.array([0, 0, 0, 0, 0])
134134
_detuning_rotations = np.array([0, 0, 0, 0, 0])
135135

136-
_plot_times = np.array([0, 0, 0,
137-
0.25, 0.25, 0.25,
138-
0.5, 0.5, 0.5,
139-
0.75, 0.75, 0.75,
140-
1., 1., 1.])
141-
_plot_rabi_rotations = np.array([0, 0, 0,
142-
0, np.pi, 0,
143-
0, 0, 0,
144-
0, np.pi, 0,
145-
0, 0, 0])
146-
_plot_azimuthal_angles = np.array([0, 0, 0,
147-
0, 0, 0,
148-
0, 0, 0,
149-
0, 0, 0,
150-
0, 0, 0])
151-
152-
_plot_detuning_rotations = np.array([0, 0, 0,
153-
0, 0, 0,
154-
0, 0, 0,
155-
0, 0, 0,
156-
0, 0, 0])
157-
158136
seq = DynamicDecouplingSequence(
159137
duration=1.0,
160138
offsets=_offsets,
161139
rabi_rotations=_rabi_rotations,
162140
azimuthal_angles=_azimuthal_angle,
163141
detuning_rotations=_detuning_rotations)
164142

165-
plot_data = seq.get_plot_formatted_arrays()
166-
plot_rabi, plot_azimuthal, plot_detuning, plot_times = (
167-
plot_data['rabi_rotations'],
168-
plot_data['azimuthal_angles'],
169-
plot_data['detuning_rotations'],
170-
plot_data['times']
171-
)
143+
plot_data = seq.export()
144+
145+
_plot_rabi_offsets = [pulse['offset'] for pulse in plot_data['Rabi']]
146+
_plot_detuning_offsets = [pulse['offset'] for pulse in plot_data['Detuning']]
147+
_plot_rabi_rotations = [pulse['rotation'] for pulse in plot_data['Rabi']]
148+
_plot_detuning_rotations = [pulse['rotation'] for pulse in plot_data['Detuning']]
149+
150+
assert np.allclose(_plot_rabi_offsets, _offsets)
151+
assert np.allclose(_plot_detuning_offsets, _offsets)
152+
153+
assert np.allclose(np.abs(_plot_rabi_rotations), _rabi_rotations)
154+
assert np.allclose(np.angle(_plot_rabi_rotations), _azimuthal_angle)
172155

173-
assert np.allclose(_plot_rabi_rotations, plot_rabi)
174-
assert np.allclose(_plot_azimuthal_angles, plot_azimuthal)
175-
assert np.allclose(_plot_detuning_rotations, plot_detuning)
176-
assert np.allclose(_plot_times, plot_times)
156+
assert np.allclose(_plot_detuning_rotations, _detuning_rotations)
177157

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

184-
_plot_rabi_rotations = np.array([0, 0, 0,
185-
0, np.pi, 0,
186-
0, 0, 0,
187-
0, np.pi, 0,
188-
0, 0, 0])
189-
_plot_azimuthal_angles = np.array([0, 0, 0,
190-
0, np.pi/2, 0,
191-
0, 0, 0,
192-
0, np.pi/2, 0,
193-
0, 0, 0])
194-
195-
_plot_detuning_rotations = np.array([0, 0, 0,
196-
0, 0, 0,
197-
0, 0, 0,
198-
0, 0, 0,
199-
0, 0, 0])
200-
201-
_plot_times = np.array([0, 0, 0,
202-
0.25, 0.25, 0.25,
203-
0.5, 0.5, 0.5,
204-
0.75, 0.75, 0.75,
205-
1., 1., 1.])
206164
seq = DynamicDecouplingSequence(
207165
duration=1.0,
208166
offsets=_offsets,
209167
rabi_rotations=_rabi_rotations,
210168
azimuthal_angles=_azimuthal_angle,
211169
detuning_rotations=_detuning_rotations)
212170

213-
plot_data = seq.get_plot_formatted_arrays()
214-
plot_rabi, plot_azimuthal, plot_detuning, plot_times = (
215-
plot_data['rabi_rotations'],
216-
plot_data['azimuthal_angles'],
217-
plot_data['detuning_rotations'],
218-
plot_data['times']
219-
)
171+
plot_data = seq.export()
172+
173+
_plot_rabi_offsets = [pulse['offset'] for pulse in plot_data['Rabi']]
174+
_plot_detuning_offsets = [pulse['offset'] for pulse in plot_data['Detuning']]
175+
_plot_rabi_rotations = [pulse['rotation'] for pulse in plot_data['Rabi']]
176+
_plot_detuning_rotations = [pulse['rotation'] for pulse in plot_data['Detuning']]
177+
178+
assert np.allclose(_plot_rabi_offsets, _offsets)
179+
assert np.allclose(_plot_detuning_offsets, _offsets)
180+
181+
assert np.allclose(np.abs(_plot_rabi_rotations), _rabi_rotations)
182+
assert np.allclose(np.angle(_plot_rabi_rotations), _azimuthal_angle)
220183

221-
assert np.allclose(_plot_rabi_rotations, plot_rabi)
222-
assert np.allclose(_plot_azimuthal_angles, plot_azimuthal)
223-
assert np.allclose(_plot_detuning_rotations, plot_detuning)
224-
assert np.allclose(_plot_times, plot_times)
184+
assert np.allclose(_plot_detuning_rotations, _detuning_rotations)
225185

226186

227187
def test_pretty_string_format():

0 commit comments

Comments
 (0)