|
7 | 7 | import abc |
8 | 8 | from dataclasses import dataclass |
9 | 9 | import logging |
| 10 | +import math |
10 | 11 | from typing import Any, Final, Generic, TypeVar |
11 | 12 |
|
12 | 13 | import networkx as nx |
@@ -228,29 +229,65 @@ def compile_register(self) -> pl.Register: |
228 | 229 |
|
229 | 230 | def compile_pulse( |
230 | 231 | self, |
231 | | - amplitude: float = SEQUENCE_DEFAULT_AMPLITUDE_RAD_PER_US, |
232 | | - duration: int = SEQUENCE_DEFAULT_DURATION_NS, |
| 232 | + normalized_amplitude: float | None = None, |
| 233 | + normalized_duration: float | None = None, |
233 | 234 | ) -> pl.Pulse: |
234 | 235 | """Extract a Pulse for this graph. |
235 | 236 |
|
236 | 237 | A Pulse represents the laser applied to the atoms on the device. |
237 | 238 |
|
238 | 239 | Arguments: |
239 | | - amplitude: The amplitude for the laser pulse, in rad per microseconds. |
240 | | - By default, use the value demonstrated in the companion paper. |
241 | | - duration: The duration of the laser pulse, in nanoseconds. |
242 | | - By default, use the value demonstrated in the companion paper. |
| 240 | + normalized_amplitude (optional): The normalized amplitude for the laser pulse, as a value in [0, 1], |
| 241 | + where 0 is no pulse and 1 is the maximal amplitude for the device. By default, |
| 242 | + use the value demonstrated in the companion paper. |
| 243 | + normalized_duration (optional): The normalized duration of the laser pulse, as a value in [0, 1], |
| 244 | + where 0 is the shortest possible duration and 1 is the longest possible |
| 245 | + duration. By default, use the value demonstrated in the companion paper. |
243 | 246 | """ |
244 | 247 | # Note: In the low-level API, we separate register and pulse compilation for |
245 | 248 | # pedagogical reasons, because we want to take the opportunity to teach them |
246 | 249 | # about registers and pulses, rather than pulser sequences. |
247 | 250 |
|
248 | | - # See the companion paper for an explanation on these constants. |
249 | | - Omega_max = amplitude |
250 | | - t_max = duration |
| 251 | + channel = self.device.channels["rydberg_global"] |
| 252 | + assert channel is not None |
| 253 | + |
| 254 | + max_amp = channel.max_amp |
| 255 | + assert max_amp is not None |
| 256 | + |
| 257 | + min_duration = channel.min_duration |
| 258 | + max_duration = channel.max_duration |
| 259 | + assert max_duration is not None |
| 260 | + |
| 261 | + if normalized_amplitude is None: |
| 262 | + absolute_amplitude = self.SEQUENCE_DEFAULT_AMPLITUDE_RAD_PER_US |
| 263 | + if absolute_amplitude > max_amp: |
| 264 | + # Unlikely, but let's defend in depth. |
| 265 | + raise ValueError( |
| 266 | + f"This device does not support pulses with amplitude {absolute_amplitude} rad per us, amplitudes should be <= {max_amp}" |
| 267 | + ) |
| 268 | + else: |
| 269 | + if normalized_amplitude < 0 or normalized_amplitude > 1: |
| 270 | + raise ValueError("Invalid amplitude, expected a value in [0, 1] or None") |
| 271 | + absolute_amplitude = normalized_amplitude * max_amp |
| 272 | + |
| 273 | + if normalized_duration is None: |
| 274 | + absolute_duration = self.SEQUENCE_DEFAULT_DURATION_NS |
| 275 | + if absolute_duration < min_duration or absolute_duration > max_duration: |
| 276 | + # Unlikely, but let's defend in depth. |
| 277 | + raise ValueError( |
| 278 | + f"This device does not support pulses with duration {absolute_duration} ns, pulses should be within [{min_duration}, {max_duration}]" |
| 279 | + ) |
| 280 | + else: |
| 281 | + if normalized_duration < 0 or normalized_duration > 1: |
| 282 | + raise ValueError("Invalid duration, expected a value in [0, 1] or None") |
| 283 | + absolute_duration = ( |
| 284 | + math.ceil(normalized_duration * (max_duration - min_duration)) + min_duration |
| 285 | + ) |
| 286 | + |
| 287 | + # For an explanation on these constants, see the companion paper. |
251 | 288 | pulse = pl.Pulse.ConstantAmplitude( |
252 | | - amplitude=Omega_max, |
253 | | - detuning=pl.waveforms.RampWaveform(t_max, 0, 0), |
| 289 | + amplitude=absolute_amplitude, |
| 290 | + detuning=pl.waveforms.RampWaveform(absolute_duration, 0, 0), |
254 | 291 | phase=0.0, |
255 | 292 | ) |
256 | 293 | return pulse |
|
0 commit comments