Skip to content

Commit a291675

Browse files
authored
Making sure all pulse durations are positive in DDS to controls conversion (#68)
* Improving checks to make sure that the outputted controls contain only pulses with positive durations * Writing more helpful error messages
1 parent 2e3b8ea commit a291675

File tree

1 file changed

+22
-33
lines changed

1 file changed

+22
-33
lines changed

qctrlopencontrols/dynamic_decoupling_sequences/driven_controls.py

Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -77,21 +77,20 @@ def _check_maximum_rotation_rate(
7777
"""
7878

7979
# check against global parameters
80-
if maximum_rabi_rate < 0. or maximum_rabi_rate > UPPER_BOUND_RABI_RATE:
80+
if maximum_rabi_rate <= 0. or maximum_rabi_rate > UPPER_BOUND_RABI_RATE:
8181
raise ArgumentsValueError(
82-
'Maximum rabi rate must be between 0. and maximum value of {0}'.format(
82+
'Maximum rabi rate must be greater than 0 and less or equal to {0}'.format(
8383
UPPER_BOUND_RABI_RATE),
8484
{'maximum_rabi_rate': maximum_rabi_rate},
8585
extras={'maximum_detuning_rate': maximum_detuning_rate,
8686
'allowed_maximum_rabi_rate': UPPER_BOUND_RABI_RATE})
8787

88-
if maximum_detuning_rate < 0. or maximum_detuning_rate > UPPER_BOUND_DETUNING_RATE:
88+
if maximum_detuning_rate <= 0. or maximum_detuning_rate > UPPER_BOUND_DETUNING_RATE:
8989
raise ArgumentsValueError(
90-
'Maximum detuning rate must be between 0. and maximum value of {0}'.format(
90+
'Maximum detuning rate must be greater than 0 and less or equal to {0}'.format(
9191
UPPER_BOUND_DETUNING_RATE),
9292
{'maximum_detuning_rate': maximum_detuning_rate, },
9393
extras={'maximum_rabi_rate': maximum_rabi_rate,
94-
'allowed_maximum_rabi_rate': UPPER_BOUND_RABI_RATE,
9594
'allowed_maximum_detuning_rate': UPPER_BOUND_DETUNING_RATE})
9695

9796

@@ -112,9 +111,11 @@ def convert_dds_to_driven_control(
112111
dynamic_decoupling_sequence : qctrlopencontrols.DynamicDecouplingSequence
113112
The base DDS
114113
maximum_rabi_rate : float, optional
115-
Maximum Rabi Rate; Defaults to 2*pi
114+
Maximum Rabi Rate; Defaults to 2*pi.
115+
Must be greater than 0 and less or equal to UPPER_BOUND_RABI_RATE, if set.
116116
maximum_detuning_rate : float, optional
117-
Maximum Detuning Rate; Defaults to 2*pi
117+
Maximum Detuning Rate; Defaults to 2*pi.
118+
Must be greater than 0 and less or equal to UPPER_BOUND_DETUNING_RATE, if set.
118119
minimum_segment_duration : float, optional
119120
If set, further restricts the duration of every segment of the Driven Controls.
120121
Defaults to 0, in which case it does not affect the duration of the pulses.
@@ -172,6 +173,12 @@ def convert_dds_to_driven_control(
172173
azimuthal_angles = dynamic_decoupling_sequence.azimuthal_angles
173174
detuning_rotations = dynamic_decoupling_sequence.detuning_rotations
174175

176+
# check if all Rabi rotations are valid (i.e. have positive values)
177+
if np.any(np.less(rabi_rotations, 0.)):
178+
raise ArgumentsValueError(
179+
'Sequence contains negative values for Rabi rotations.',
180+
{'dynamic_decoupling_sequence': str(dynamic_decoupling_sequence)})
181+
175182
# check for valid operation
176183
if not _check_valid_operation(rabi_rotations=rabi_rotations,
177184
detuning_rotations=detuning_rotations):
@@ -182,15 +189,6 @@ def convert_dds_to_driven_control(
182189
extras={'maximum_rabi_rate': maximum_rabi_rate,
183190
'maximum_detuning_rate': maximum_detuning_rate})
184191

185-
# check if detuning rate is supplied if there is a detuning_rotation > 0
186-
if np.any(detuning_rotations > 0.) and maximum_detuning_rate is None:
187-
raise ArgumentsValueError(
188-
'Sequence operation includes detuning rotations. Please supply a valid '
189-
'maximum_detuning_rate.',
190-
{'detuning_rotations': dynamic_decoupling_sequence.detuning_rotations,
191-
'maximum_detuning_rate': maximum_detuning_rate},
192-
extras={'maximum_rabi_rate': maximum_rabi_rate})
193-
194192
if offsets.size == 0:
195193
offsets = np.array([0, sequence_duration])
196194
rabi_rotations = np.array([0, 0])
@@ -239,29 +237,19 @@ def convert_dds_to_driven_control(
239237
# check if any of the pulses have gone outside the time limit [0, sequence_duration]
240238
# if yes, adjust the segment timing
241239
if pulse_start_ends[0, 0] < 0.:
242-
243-
if np.sum(np.abs(pulse_start_ends[0, :])) == 0:
244-
pulse_start_ends[0, 0] = 0
245-
else:
246-
translation = 0. - (pulse_start_ends[0, 0])
247-
pulse_start_ends[0, :] = pulse_start_ends[0, :] + translation
240+
translation = 0. - (pulse_start_ends[0, 0])
241+
pulse_start_ends[0, :] = pulse_start_ends[0, :] + translation
248242

249243
if pulse_start_ends[-1, 1] > sequence_duration:
244+
translation = pulse_start_ends[-1, 1] - sequence_duration
245+
pulse_start_ends[-1, :] = pulse_start_ends[-1, :] - translation
250246

251-
if np.sum(np.abs(pulse_start_ends[0, :])) == 2 * sequence_duration:
252-
pulse_start_ends[-1, 1] = sequence_duration
253-
else:
254-
translation = pulse_start_ends[-1, 1] - sequence_duration
255-
pulse_start_ends[-1, :] = pulse_start_ends[-1, :] - translation
256-
257-
# four conditions to check
247+
# three conditions to check
258248
# 1. Control segment start times should be monotonically increasing
259249
# 2. Control segment end times should be monotonically increasing
260-
# 3. Control segment start time must be less than its end time
261-
# 4. Adjacent segments should not be overlapping
250+
# 3. Adjacent segments should not be overlapping
262251
if (np.any(pulse_start_ends[0:-1, 0] - pulse_start_ends[1:, 0] > 0.) or
263252
np.any(pulse_start_ends[0:-1, 1] - pulse_start_ends[1:, 1] > 0.) or
264-
np.any(pulse_start_ends[:, 0] - pulse_start_ends[:, 1] > 0.) or
265253
np.any(pulse_start_ends[1:, 0]-pulse_start_ends[0:-1, 1] < 0.)):
266254

267255
raise ArgumentsValueError('Pulse timing could not be properly deduced from '
@@ -284,7 +272,8 @@ def convert_dds_to_driven_control(
284272
'maximum_detuning_rate': maximum_detuning_rate,
285273
'minimum_segment_duration': minimum_segment_duration},
286274
extras={'deduced_pulse_start_timing': pulse_start_ends[:, 0],
287-
'deduced_pulse_end_timing': pulse_start_ends[:, 1]})
275+
'deduced_pulse_end_timing': pulse_start_ends[:, 1],
276+
'gap_durations': gap_durations})
288277

289278

290279
if np.allclose(pulse_start_ends, 0.0):

0 commit comments

Comments
 (0)