Core Features
Sequence
The Sequence class, where a pulse sequence is defined.
- class pulser.sequence.sequence.Sequence(register, device)
A sequence of operations on a device.
A sequence is composed by
The device in which we want to implement it
The register of qubits on which to act
The device’s channels that are used
The schedule of operations on each channel
A Sequence also supports variable parameters, which have to be obtained through
Sequence.declare_variable()
. From the moment a variable is declared, aSequence
becomes parametrized and stops being built on the fly, instead storing the sequence building calls for later execution. This forgoes some specific functionalities of a “regular”Sequence
, like the ability to validate aPulse
or to draw the sequence as it is being built. Instead, all validation happens upon building (throughSequence.build()
), where values for all declared variables have to be specified and a “regular”Sequence
is created and returned. By changing the values given to the variables, multiple sequences can be generated from a single “parametrized”Sequence
.- Parameters:
register (
Union
[BaseRegister
,MappableRegister
]) – The atom register on which to apply the pulses. If given as a MappableRegister instance, the traps corrresponding to each qubit ID must be given when building the sequence.device (
TypeVar
(DeviceType
, bound=BaseDevice
)) – A valid device in which to execute the Sequence (import it frompulser.devices
).
Note
The register and device do not support variable parameters. As such, they are the same for all Sequences built from a parametrized Sequence.
- property qubit_info
Dictionary with the qubit’s IDs and positions.
- property device
Device that the sequence is using.
- property register
Register with the qubit’s IDs and positions.
- get_register(include_mappable=True)
The atom register on which to apply the pulses.
- Return type:
- property declared_channels
Channels declared in this Sequence.
- property declared_variables
Variables declared in this Sequence.
- property available_channels
Channels still available for declaration.
- property magnetic_field
The magnetic field acting on the array of atoms.
The magnetic field vector is defined on the reference frame of the atoms in the Register (with the z-axis coming outside of the plane).
Note
Only defined in “XY Mode”, the default value being (0, 0, 30) G.
- is_parametrized()
States whether the sequence is parametrized.
A parametrized sequence is one that depends on the values assigned to variables declared within it. Sequence-building calls are not executed right away, but rather stored for deferred execution when all variables are given a value (when
Sequence.build()
is called).- Return type:
bool
- Returns:
Whether the sequence is parametrized.
- is_in_eom_mode(channel)
States whether a channel is currently in EOM mode.
- Parameters:
channel (
str
) – The name of the declared channel to inspect.- Return type:
bool
- Returns:
Whether the channel is in EOM mode.
- is_register_mappable()
States whether the sequence’s register is mappable.
A sequence with a mappable register will require its qubit Id’s to be mapped to trap Ids of its associated RegisterLayout through the Sequence.build() call.
- Return type:
bool
- Returns:
Whether the register is a MappableRegister.
- is_measured()
States whether the sequence has been measured.
- Return type:
bool
- get_measurement_basis()
Gets the sequence’s measurement basis.
- Raises:
RuntimeError – When the sequence has not been measured.
- Return type:
str
- get_duration(channel=None, include_fall_time=False)
Returns the current duration of a channel or the whole sequence.
- Parameters:
channel (
Optional
[str
], default:None
) – A specific channel to return the duration of. If left as None, it will return the duration of the whole sequence.include_fall_time (
bool
, default:False
) – Whether to include in the duration the extra time needed by the last pulse to finish, if there is modulation.
- Return type:
int
- Returns:
The duration of the channel or sequence, in ns.
- get_addressed_bases()
Returns the bases addressed by the declared channels.
- Return type:
tuple
[str
,...
]
- get_addressed_states()
Returns the states addressed by the declared channels.
- Return type:
list
[Literal
['u'
,'d'
,'r'
,'g'
,'h'
,'x'
]]
- current_phase_ref(qubit, basis='digital')
Current phase reference of a specific qubit for a given basis.
- Parameters:
qubit (
Union
[int
,str
]) – The id of the qubit whose phase shift is desired.basis (
str
, default:'digital'
) – The basis (i.e. electronic transition) the phase reference is associated with. Must correspond to the basis of a declared channel.
- Return type:
float
- Returns:
Current phase reference of ‘qubit’ in ‘basis’.
- set_magnetic_field(bx=0.0, by=0.0, bz=30.0)
Sets the magnetic field acting on the entire array.
The magnetic field vector is defined on the reference frame of the atoms in the Register (with the z-axis coming outside of the plane). Can only be defined before there are pulses added to the sequence.
- Return type:
None
Note
The magnetic field only work in the “XY Mode”. If not already defined through the declaration of a Microwave channel, calling this function will enable the “XY Mode”.
- Parameters:
bx (
float
, default:0.0
) – The magnetic field in the x direction (in Gauss).by (
float
, default:0.0
) – The magnetic field in the y direction (in Gauss).bz (
float
, default:30.0
) – The magnetic field in the z direction (in Gauss).
- config_slm_mask(qubits, dmm_id='dmm_0')
Setup an SLM mask by specifying the qubits it targets.
If the sequence is in XY mode, masked qubits don’t interact with the incoming pulses until the end of the first pulse of the global channel starting the earliest in the schedule.
If the sequence is in Ising, the SLM Mask is a DetuningMap where the detuning of each masked qubit is 1.0. DMM “dmm_id” is configured using this Detuning Map, and modulated by a pulse having a large negative detuning and either a duration defined from pulses already present in the sequence (same as in XY mode) or by the first pulse added after this operation.
- Parameters:
qubits (
Collection
[Union
[int
,str
]]) – Collection of qubit ID’s to mask during the first global pulse of the sequence.dmm_id (
str
, default:'dmm_0'
) – Id of the DMM channel to use in the device.
- Return type:
None
- config_detuning_map(detuning_map, dmm_id)
Declares a new DMM channel to the Sequence.
Associates a DetuningMap to a DMM channel of the Device.
- Return type:
None
Note
Regular devices only allow a DMM to be declared once, but
MockDevice
DMM can be repeatedly declared if needed.- Parameters:
detuning_map (
DetuningMap
) – A DetuningMap defining the amount of detuning each atom receives.dmm_id (
str
) – How the channel is identified in the device. See inSequence.available_channels
which DMM IDs are still available (start by “dmm” ) and the associated description.
- switch_register(new_register)
Replicate the sequence with a different register.
The new sequence is reconstructed with the provided register by replicating all the instructions used to build the original sequence. This means that operations referecing specific qubits IDs (eg. Sequence.target()) expect to find the same qubit IDs in the new register. By the same token, switching from a register to a mappable register might fail if one of the instructions does not work with mappable registers (e.g. Sequence.configure_slm_mask()).
- Warns:
UserWarning – If the sequence is configuring a detuning map, a
warning is raised to remind the user that the detuning map is
unchanged and might no longer be aligned with the qubits in
the new register.
- Parameters:
new_register (BaseRegister | MappableRegister) – The new register to give the sequence.
- Return type:
- Returns:
The sequence with the new register.
- switch_device(new_device, strict=False)
Replicate the sequence with a different device.
This method is designed to replicate the sequence with as few changes to the original contents as possible. If the strict option is chosen, the device switch will fail whenever it cannot guarantee that the new sequence’s contents will not be modified in the process.
- Parameters:
new_device (
TypeVar
(DeviceType
, bound=BaseDevice
)) – The target device instance.strict (
bool
, default:False
) – Enforce a strict match between devices and channels to guarantee the pulse sequence is left unchanged.
- Return type:
- Returns:
The sequence on the new device, using the match channels of the former device declared in the sequence.
- declare_channel(name, channel_id, initial_target=None)
Declares a new channel to the Sequence.
The first declared channel implicitly defines the sequence’s mode of operation (i.e. the underlying Hamiltonian). In particular, if the first declared channel is of type
Microwave
, the sequence will work in “XY Mode” and will not allow declaration of channels that do not address the ‘XY’ basis. Inversely, declaration of a channel of another type will block the declaration ofMicrowave
channels.- Return type:
None
Note
Regular devices only allow a channel to be declared once, but
MockDevice
channels can be repeatedly declared if needed.- Parameters:
name (
str
) – Unique name for the channel in the sequence.channel_id (
str
) – How the channel is identified in the device. ConsultSequence.available_channels
to see which channel ID’s are still available and the associated channel’s description.initial_target (
Union
[int
,str
,Collection
[Union
[int
,str
]],None
], default:None
) – For ‘Local’ addressing channels only. Declares the initial target of the channel. If left as None, the initial target will have to be set manually as the first addition to this channel.
- declare_variable(name, size=None, dtype=<class 'float'>)
Declare a new variable within this Sequence.
The declared variables can be used to create parametrized versions of
Waveform
andPulse
objects, which in turn can be added to theSequence
. Additionally, simple arithmetic operations involving variables are also supported and will return parametrized objects that are dependent on the involved variables.- Parameters:
name (
str
) – The name for the variable. Must be unique within a Sequence.size (
Optional
[int
], default:None
) – The number of entries stored in the variable. If defined, returns an array of variables with the given size. If left asNone
, returns a single variable.dtype (
Union
[type
[int
],type
[float
]], default:<class 'float'>
) – The type of the data that will be assigned to the variable. Must befloat
orint
.
- Returns:
The declared Variable instance.
- Return type:
Union
[Variable
,VariableItem
]
Note
To avoid confusion, it is recommended to store the returned Variable instance in a Python variable with the same name.
- enable_eom_mode(channel, amp_on, detuning_on, optimal_detuning_off=0.0, correct_phase_drift=False)
Puts a channel in EOM mode operation.
For channels with a finite modulation bandwidth and an EOM, operation in EOM mode allows for the execution of square pulses with a higher bandwidth than that which is tipically available. It can be turned on and off through the Sequence.enable_eom_mode() and Sequence.disable_eom_mode() methods. A channel in EOM mode can only execute square pulses with a given amplitude (amp_on) and detuning (detuning_on), which are chosen at the moment the EOM mode is enabled. Furthermore, the detuning when there is no pulse being played (detuning_off) is restricted to a set of values that depends on amp_on and detuning_on. While in EOM mode, one can only add pulses of variable duration (through Sequence.add_eom_pulse()) or delays.
- Return type:
None
Note
Enabling the EOM mode will automatically enforce a buffer unless the channel is empty. The detuning will go to the detuning_off value during this buffer. This buffer will not wait for pulses on other channels to finish, so calling Sequence.align() or Sequence.delay() before enabling the EOM mode is necessary to avoid eventual conflicts.
- Parameters:
channel (
str
) – The name of the channel to put in EOM mode.amp_on (
Union
[float
,TensorLike
,Parametrized
]) – The amplitude of the EOM pulses (in rad/µs).detuning_on (
Union
[float
,TensorLike
,Parametrized
]) – The detuning of the EOM pulses (in rad/µs).optimal_detuning_off (
Union
[float
,Parametrized
], default:0.0
) – The optimal value of detuning (in rad/µs) when there is no pulse being played. It will choose the closest value among the existing options.correct_phase_drift (
bool
, default:False
) – Performs a phase shift to correct for the phase drift incurred while turning on the EOM mode.
- disable_eom_mode(channel, correct_phase_drift=False)
Takes a channel out of EOM mode operation.
For channels with a finite modulation bandwidth and an EOM, operation in EOM mode allows for the execution of square pulses with a higher bandwidth than that which is tipically available. It can be turned on and off through the Sequence.enable_eom_mode() and Sequence.disable_eom_mode() methods. A channel in EOM mode can only execute square pulses with a given amplitude (amp_on) and detuning (detuning_on), which are chosen at the moment the EOM mode is enabled. Furthermore, the detuning when there is no pulse being played (detuning_off) is restricted to a set of values that depends on amp_on and detuning_on. While in EOM mode, one can only add pulses of variable duration (through Sequence.add_eom_pulse()) or delays.
- Return type:
None
Note
Disabling the EOM mode will automatically enforce a buffer time from the moment it is turned off.
- Parameters:
channel (
str
) – The name of the channel to take out of EOM mode.correct_phase_drift (
bool
, default:False
) – Performs a phase shift to correct for the phase drift that occured since the last pulse (or the start of the EOM mode, if no pulse was added).
- modify_eom_setpoint(channel, amp_on, detuning_on, optimal_detuning_off=0.0, correct_phase_drift=False)
Modifies the setpoint of an ongoing EOM mode operation.
- Return type:
None
Note
Modifying the EOM setpoint will automatically enforce a buffer. The detuning will go to the detuning_off value during this buffer. This buffer will not wait for pulses on other channels to finish, so calling Sequence.align() or Sequence.delay() beforehand is necessary to avoid eventual conflicts.
- Parameters:
channel (
str
) – The name of the channel currently in EOM mode.amp_on (
Union
[float
,TensorLike
,Parametrized
]) – The new amplitude of the EOM pulses (in rad/µs).detuning_on (
Union
[float
,TensorLike
,Parametrized
]) – The new detuning of the EOM pulses (in rad/µs).optimal_detuning_off (
Union
[float
,Parametrized
], default:0.0
) – The new optimal value of detuning (in rad/µs) when there is no pulse being played. It will choose the closest value among the existing options.correct_phase_drift (
bool
, default:False
) – Performs a phase shift to correct for the phase drift incurred while modifying the EOM setpoint.
- add_eom_pulse(channel, duration, phase, post_phase_shift=0.0, protocol='min-delay', correct_phase_drift=False)
Adds a square pulse to a channel in EOM mode.
For channels with a finite modulation bandwidth and an EOM, operation in EOM mode allows for the execution of square pulses with a higher bandwidth than that which is tipically available. It can be turned on and off through the Sequence.enable_eom_mode() and Sequence.disable_eom_mode() methods. A channel in EOM mode can only execute square pulses with a given amplitude (amp_on) and detuning (detuning_on), which are chosen at the moment the EOM mode is enabled. Furthermore, the detuning when there is no pulse being played (detuning_off) is restricted to a set of values that depends on amp_on and detuning_on. While in EOM mode, one can only add pulses of variable duration (through Sequence.add_eom_pulse()) or delays.
- Return type:
None
Note
When the phase between pulses is changed, the necessary buffer time for a phase jump will still be enforced (unless
protocol='no-delay'
).- Parameters:
channel (
str
) – The name of the channel to add the pulse to.duration (
Union
[int
,Parametrized
]) – The duration of the pulse (in ns).phase (
Union
[float
,TensorLike
,Parametrized
]) – The pulse phase (in radians).post_phase_shift (
Union
[float
,Parametrized
], default:0.0
) – Optionally lets you add a phase shift (in rad) immediately after the end of the pulse.protocol (
Literal
['min-delay'
,'no-delay'
,'wait-for-all'
], default:'min-delay'
) – Stipulates how to deal with eventual conflicts with other channels (see Sequence.add() for more details).correct_phase_drift (
bool
, default:False
) – Adjusts the phase to correct for the phase drift that occured since the last pulse (or the start of the EOM mode, if adding the first pulse). This effectively changes the phase of the EOM pulse, so an extra delay might be added to enforce the phase jump time.
- add(pulse, channel, protocol='min-delay')
Adds a pulse to a channel.
- Parameters:
pulse (
Union
[Pulse
,Parametrized
]) – The pulse object to add to the channel.channel (
str
) – The channel’s name provided when declared.protocol (
Literal
['min-delay'
,'no-delay'
,'wait-for-all'
], default:'min-delay'
) –Stipulates how to deal with eventual conflicts with other channels, specifically in terms of having multiple channels act on the same target simultaneously.
'min-delay'
: Before adding the pulse, introduces the smallest possible delay that avoids all exisiting conflicts.'no-delay'
: Adds the pulse to the channel, regardless of existing conflicts.'wait-for-all'
: Before adding the pulse, adds a delay that idles the channel until the end of the other channels’ latest pulse.
- Return type:
None
Note
When the phase of the pulse to add is different than the phase of the previous pulse on the channel, a delay between the two pulses might be automatically added to ensure the channel’s phase_jump_time is respected. To override this behaviour, use the
'no-delay'
protocol.
- add_dmm_detuning(waveform, dmm_name, protocol='no-delay')
Add a waveform to the detuning of a DMM.
- Parameters:
waveform (
Union
[Waveform
,Parametrized
]) – The waveform to add to the detuning of the DMM.dmm_name (
str
) – The name of the DMM channel to modulate.protocol (
Literal
['min-delay'
,'no-delay'
,'wait-for-all'
], default:'no-delay'
) –Stipulates how to deal with eventual conflicts with other channels, specifically in terms of having multiple channels act on the same target simultaneously (defaults to “no-delay”).
'min-delay'
: Before adding the pulse, introduces the smallest possible delay that avoids all exisiting conflicts.'no-delay'
: Adds the pulse to the channel, regardless of existing conflicts.'wait-for-all'
: Before adding the pulse, adds a delay that idles the channel until the end of the other channels’ latest pulse.
- Return type:
None
- target(qubits, channel)
Changes the target qubit of a ‘Local’ channel.
- Parameters:
qubits (
Union
[int
,str
,Collection
[Union
[int
,str
]]]) – The new target for this channel. Must correspond to a qubit ID in device or a collection of qubit IDs, when multi-qubit addressing is possible.channel (
str
) – The channel’s name provided when declared. Must be a channel with ‘Local’ addressing.
- Return type:
None
- target_index(qubits, channel)
Changes the target qubit of a ‘Local’ channel.
- Parameters:
qubits (
Union
[int
,Collection
[int
],Parametrized
]) – The new target for this channel. Must correspond to a qubit index or an collection of qubit indices, when multi-qubit addressing is possible. A qubit index is a number between 0 and the number of qubits. It is then converted to a Qubit ID using the order in which they were declared when instantiating theRegister
orMappableRegister
.channel (
str
) – The channel’s name provided when declared. Must be a channel with ‘Local’ addressing.
- Return type:
None
Note
Cannot be used on non-parametrized sequences using a mappable register.
- delay(duration, channel, at_rest=False)
Idles a given channel for a specific duration.
- Parameters:
duration (
Union
[int
,Parametrized
]) – Time to delay (in ns).channel (
str
) – The channel’s name provided when declared.at_rest (
bool
, default:False
) – Whether to wait until the previous pulse on the channel has finished (including output modulation) before starting the delay.
- Return type:
None
Note
Delays added automatically by other instructions will generally take into account the output modulation.
- estimate_added_delay(pulse, channel, protocol='min-delay')
Delay that will be added before the pulse when added to a channel.
When adding a pulse to a channel of the Sequence, a delay can be added to account for the modulation bandwidth of the channel or the protocol chosen. This method estimates the delay that will be added before the pulse if this pulse was added to this channel with this protocol. It works even if the channel is in EOM mode, but to be appropriate, the Pulse should be a ConstantPulse with amplitude and detuning respectively the rabi_freq and detuning_on of the EOM block.
- Parameters:
pulse (
Union
[Pulse
,Parametrized
]) – The pulse object to add to the channel.channel (
str
) – The channel’s name provided when declared.protocol (
Literal
['min-delay'
,'no-delay'
,'wait-for-all'
], default:'min-delay'
) –Stipulates how to deal with eventual conflicts with other channels, specifically in terms of having multiple channels act on the same target simultaneously.
'min-delay'
: Before adding the pulse, introduces the smallest possible delay that avoids all exisiting conflicts.'no-delay'
: Adds the pulse to the channel, regardless of existing conflicts.'wait-for-all'
: Before adding the pulse, adds a delay that idles the channel until the end of the other channels’ latest pulse.
- Return type:
int
- Returns:
The delay that would be added before the pulse.
- measure(basis='ground-rydberg')
Measures in a valid basis.
- Return type:
None
Note
In addition to the supported bases of the selected device, allowed measurement bases will depend on the mode of operation. In particular, if using
Microwave
channels (XY mode), only measuring in the ‘XY’ basis is allowed. Inversely, it is not possible to measure in the ‘XY’ basis outside of XY mode.- Parameters:
basis (
str
, default:'ground-rydberg'
) – Valid basis for measurement (consult thesupported_bases
attribute of the selected device for the available options).
- phase_shift(phi, *targets, basis='digital')
Shifts the phase of a qubit’s reference by ‘phi’, on a given basis.
This is equivalent to an \(R_z(\phi)\) gate (i.e. a rotation of the target qubit’s state by an angle \(\phi\) around the z-axis of the Bloch sphere).
- Parameters:
phi (float | Parametrized) – The intended phase shift (in rad).
targets (QubitId) – The ids of the qubits to apply the phase shift to.
basis (str, default:
'digital'
) – The basis (i.e. electronic transition) to associate the phase shift to. Must correspond to the basis of a declared channel.
- Return type:
None
- phase_shift_index(phi, *targets, basis='digital')
Shifts the phase of a qubit’s reference by ‘phi’, on a given basis.
This is equivalent to an \(R_z(\phi)\) gate (i.e. a rotation of the target qubit’s state by an angle \(\phi\) around the z-axis of the Bloch sphere).
- Parameters:
phi (float | Parametrized) – The intended phase shift (in rad).
targets (int | Parametrized) – The indices of the qubits to apply the phase shift to. A qubit index is a number between 0 and the number of qubits. It is then converted to a Qubit ID using the order in which they were declared when instantiating the
Register
orMappableRegister
.basis (str, default:
'digital'
) – The basis (i.e. electronic transition) to associate the phase shift to. Must correspond to the basis of a declared channel.
- Return type:
None
Note
Cannot be used on non-parametrized sequences using a mappable register.
- align(*channels, at_rest=True)
Aligns multiple channels in time.
Introduces delays that align the provided channels with the one that finished the latest, such that the next action added to any of them will start right after the latest channel has finished.
- Parameters:
channels (
str
) – The names of the channels to align, as given upon declaration.at_rest (
bool
, default:True
) – Whether to consider the output modulation of a channel’s contents when determining that it has finished.
- Return type:
None
- build(*, qubits=None, **vars)
Builds a sequence from the programmed instructions.
- Parameters:
qubits (
Optional
[Mapping
[Union
[int
,str
],int
]], default:None
) – A mapping between qubit IDs and trap IDs used to define the register. Must only be provided when the sequence is initialized with a MappableRegister.vars (
Union
[_SupportsArray
[dtype
[Any
]],_NestedSequence
[_SupportsArray
[dtype
[Any
]]],bool
,int
,float
,complex
,str
,bytes
,_NestedSequence
[Union
[bool
,int
,float
,complex
,str
,bytes
]],TensorLike
]) – The values for all the variables declared in this Sequence instance, indexed by the name given upon declaration. CheckSequence.declared_variables
to see all the variables.
- Returns:
The Sequence built with the given variable values.
- Return type:
Example
# Check which variables are declared >>> print(seq.declared_variables) {'x': Variable(name='x', dtype=<class 'float'>, size=1), 'y': Variable(name='y', dtype=<class 'int'>, size=3)} # Build a sequence with specific values for both variables >>> seq1 = seq.build(x=0.5, y=[1, 2, 3])
- to_abstract_repr(seq_name='pulser-exported', json_dumps_options={}, skip_validation=False, **defaults)
Serializes the Sequence into an abstract JSON object.
- Keyword Arguments:
seq_name (str) – A name for the sequence. If not defined, defaults to “pulser-exported”.
json_dumps_options – A mapping between optional parameters of
json.dumps()
(as string) and their value (parameter cannot be “cls”).skip_validation – Whether to skip the validation of the serialized sequence against the abstract representation’s JSON schema. Skipping the validation is useful to cut down on execution time, as this step takes significantly longer than the serialization itself; it is also low risk, as the validation is only defensively checking that there are no bugs in the serialized sequence.
defaults – The default values for all the variables declared in this Sequence instance, indexed by the name given upon declaration. Check
Sequence.declared_variables
to see all the variables. When using a MappableRegister, the Qubit IDs to trap IDs mapping must also be provided under the qubits keyword.
- Return type:
str
Note
Providing the defaults is optional but, when done, it is mandatory to give default values for all the expected parameters.
- Returns:
The sequence encoded as an abstract JSON object.
- Return type:
str
- static from_abstract_repr(obj_str)
Deserialize a sequence from an abstract JSON object.
- Parameters:
obj_str (str) – the JSON string representing the sequence encoded in the abstract JSON format.
- Returns:
The Pulser sequence.
- Return type:
- draw(mode='input+output', as_phase_modulated=False, draw_phase_area=False, draw_interp_pts=True, draw_phase_shifts=False, draw_register=False, draw_phase_curve=True, draw_detuning_maps=False, draw_qubit_amp=False, draw_qubit_det=False, fig_name=None, kwargs_savefig={}, show=True)
Draws the sequence in its current state.
- Parameters:
mode (str, default:
'input+output'
) – The curves to draw. ‘input’ draws only the programmed curves, ‘output’ the expected curves after modulation. ‘input+output’ will draw both curves except for channels without a defined modulation bandwidth, in which case only the input is drawn.as_phase_modulated (bool, default:
False
) – Instead of displaying the detuning and phase offsets, displays the equivalent phase modulation.draw_phase_area (bool, default:
False
) – Whether phase and area values need to be shown as text on the plot, defaults to False. Doesn’t work in ‘output’ mode.draw_interp_pts (bool, default:
True
) – When the sequence has pulses with waveforms of type InterpolatedWaveform, draws the points of interpolation on top of the respective input waveforms (defaults to True). Doesn’t work in ‘output’ mode.draw_phase_shifts (bool, default:
False
) – Whether phase shift and reference information should be added to the plot, defaults to False.draw_register (bool, default:
False
) – Whether to draw the register before the pulse sequence, with a visual indication (square halo) around the qubits masked by the SLM, defaults to False. Can’t be set to True if the sequence is defined with a mappable register.draw_phase_curve (bool, default:
True
) – Draws the changes in phase in its own curve (ignored if the phase doesn’t change throughout the channel).draw_detuning_maps (bool, default:
False
) – Whether to draw the detuning maps applied on the qubits of the register of the sequence. Shown before the pulse sequence, defaults to False.draw_qubit_amp (bool, default:
False
) – Draws the amplitude seen by the qubits locally after the drawing of the sequence.draw_qubit_det (bool, default:
False
) – Draws the detuning seen by the qubits locally after the drawing of the sequence.fig_name (str | None, default:
None
) – The name on which to save the figures. Figures are saved if fig_name is not None. If draw_register, draw_qubit_amp and draw_qubit_det are False, only the pulses are saved, with no suffix. If one of them is True, the pulses will be saved with a suffix_pulses
. If draw_register is True, the register is saved in another figure, with a suffix_register
in the file name. If draw_qubit_amp or draw_qubit_det is True, the evolution of the quantities along time for group of qubits is saved in another figure with the prefix ‘_per_qubit’, and the group of qubits having same evolution of quantities along time are saved in a figure with suffix ‘_per_qubit_legend’.kwargs_savefig (dict, default:
{}
) – Keywords arguments formatplotlib.pyplot.savefig
. Not applicable if fig_name isNone
.show (bool, default:
True
) – Whether or not to call plt.show() before returning. When combining this plot with other ones in a single figure, one may need to set this flag to False.
- Return type:
None
See also
QutipEmulator.draw(): Draws the provided sequence and the one used by the solver.
Register
Register classes
The register classes allow for the creation of arbitrary registers.
- class pulser.register.base_register.BaseRegister(qubits, **kwargs)
The abstract class for a register.
- property qubits
Dictionary of the qubit names and their position coordinates.
- property qubit_ids
The qubit IDs of this register.
- property layout
The layout used to define the register.
- find_indices(id_list)
Computes indices of qubits.
This can especially be useful when building a Pulser Sequence with a parameter denoting qubits.
- Return type:
list
[int
]
Example
Let
reg
be a register with qubit Ids “a”, “b” and “c”:>>> reg.find_indices(["a", "b", "c", "a"])
It returns
[0, 1, 2, 0]
, following the qubit order of the register.Then, it is possible to use these indices when building a sequence, typically by assigning them to an array of variables that can be provided as an argument to
target_index
andphase_shift_index
.- Parameters:
id_list (
Sequence
[Union
[int
,str
]]) – IDs of the qubits to find.- Returns:
Indices of the qubits to denote, only valid for the given mapping.
- classmethod from_coordinates(coords, center=True, prefix=None, labels=None, **kwargs)
Creates the register from an array of coordinates.
- Parameters:
coords (ArrayLike | pm.TensorLike) – The coordinates of each qubit to include in the register.
center (bool, default:
True
) – Whether or not to center the entire array around the origin.prefix (Optional[str], default:
None
) – The prefix for the qubit ids. If defined, each qubit id starts with the prefix, followed by an int from 0 to N-1 (e.g. prefix=’q’ -> IDs: ‘q0’, ‘q1’, ‘q2’, …).labels (Optional[abcSequence[QubitId]], default:
None
) – The list of qubit ids. If defined, each qubit id will be set to the corresponding value.
- Return type:
T
- Returns:
A register with qubits placed on the given coordinates.
- define_detuning_map(detuning_weights, slug=None)
Defines a DetuningMap for some qubits of the register.
- Parameters:
detuning_weights (Mapping[QubitId, float]) – A mapping between the IDs of the targeted qubits and detuning weights (between 0 and 1).
slug (str | None, default:
None
) – An optional identifier for the detuning map.
- Return type:
- Returns:
- A DetuningMap associating detuning weights to the trap coordinates
of the targeted qubits.
- coords_hex_hash()
Returns the idempotent hash of the coordinates.
- Returns:
An hexstring encoding the hash.
- Return type:
str
Note
This hash will be returned as an hexstring without the ‘0x’ prefix (unlike what is returned by ‘hex()’).
- to_abstract_repr()
Serializes the register into an abstract JSON object.
- Return type:
str
- class pulser.register.register.Register(qubits, **kwargs)
Bases:
BaseRegister
,RegDrawer
A 2D quantum register containing a set of qubits.
- Parameters:
qubits (Mapping[Any, ArrayLike | pm.TensorLike]) – Dictionary with the qubit names as keys and their position coordinates (in μm) as values (e.g. {‘q0’:(2, -1, 0), ‘q1’:(-5, 10, 0), …}).
- classmethod square(side, spacing=4.0, prefix=None)
Initializes the register with the qubits in a square array.
- Parameters:
side (int) – Side of the square in number of qubits.
spacing (float | pm.TensorLike, default:
4.0
) – The distance between neighbouring qubits in μm.prefix (Optional[str], default:
None
) – The prefix for the qubit ids. If defined, each qubit id starts with the prefix, followed by an int from 0 to N-1 (e.g. prefix=’q’ -> IDs: ‘q0’, ‘q1’, ‘q2’, …).
- Return type:
- Returns:
A register with qubits placed in a square array.
- classmethod rectangle(rows, columns, spacing=4.0, prefix=None)
Creates a rectangular array of qubits on a square lattice.
- Parameters:
rows (int) – Number of rows.
columns (int) – Number of columns.
spacing (float | pm.TensorLike, default:
4.0
) – The distance between neighbouring qubits in μm.prefix (Optional[str], default:
None
) – The prefix for the qubit ids. If defined, each qubit id starts with the prefix, followed by an int from 0 to N-1 (e.g. prefix=’q’ -> IDs: ‘q0’, ‘q1’, ‘q2’, …)
- Return type:
- Returns:
A register with qubits placed in a rectangular array.
- classmethod rectangular_lattice(rows, columns, row_spacing=4.0, col_spacing=2.0, prefix=None)
Creates a rectangular array of qubits on a rectangular lattice.
- Parameters:
rows (int) – Number of rows.
columns (int) – Number of columns.
row_spacing (float | pm.TensorLike, default:
4.0
) – The distance between rows in μm.col_spacing (float | pm.TensorLike, default:
2.0
) – The distance between columns in μm.prefix (Optional[str], default:
None
) – The prefix for the qubit ids. If defined, each qubit id starts with the prefix, followed by an int from 0 to N-1 (e.g. prefix=’q’ -> IDs: ‘q0’, ‘q1’, ‘q2’, …)
- Return type:
- Returns:
Register with qubits placed in a rectangular array on a rectangular lattice.
- classmethod triangular_lattice(rows, atoms_per_row, spacing=4.0, prefix=None)
Initializes the register with the qubits in a triangular lattice.
Initializes the qubits in a triangular lattice pattern, more specifically a triangular lattice with horizontal rows, meaning the triangles are pointing up and down.
- Parameters:
rows (int) – Number of rows.
atoms_per_row (int) – Number of atoms per row.
spacing (float | pm.TensorLike, default:
4.0
) – The distance between neighbouring qubits in μm.prefix (Optional[str], default:
None
) – The prefix for the qubit ids. If defined, each qubit id starts with the prefix, followed by an int from 0 to N-1 (e.g. prefix=’q’ -> IDs: ‘q0’, ‘q1’, ‘q2’, …).
- Return type:
- Returns:
A register with qubits placed in a triangular lattice.
- classmethod hexagon(layers, spacing=4.0, prefix=None)
Initializes the register with the qubits in a hexagonal layout.
- Parameters:
layers (int) – Number of layers around a central atom.
spacing (float | pm.TensorLike, default:
4.0
) – The distance between neighbouring qubits in μm.prefix (Optional[str], default:
None
) – The prefix for the qubit ids. If defined, each qubit id starts with the prefix, followed by an int from 0 to N-1 (e.g. prefix=’q’ -> IDs: ‘q0’, ‘q1’, ‘q2’, …).
- Return type:
- Returns:
A register with qubits placed in a hexagonal layout.
- classmethod max_connectivity(n_qubits, device, spacing=None, prefix=None)
Initializes the register with maximum connectivity for a device.
In order to maximize connectivity, the basic pattern is the triangle. Atoms are first arranged as layers of hexagons around a central atom. Extra atoms are placed in such a manner that C3 and C6 rotational symmetries are enforced as often as possible.
- Parameters:
n_qubits (int) – Number of qubits.
device (pulser.devices._device_datacls.BaseDevice) – The device whose constraints must be obeyed.
spacing (float | pm.TensorLike | None, default:
None
) – The distance between neighbouring qubits in μm. If omitted, the minimal distance for the device is used.prefix (str | None, default:
None
) – The prefix for the qubit ids. If defined, each qubit id starts with the prefix, followed by an int from 0 to N-1 (e.g. prefix=’q’ -> IDs: ‘q0’, ‘q1’, ‘q2’, …).
- Return type:
- Returns:
A register with qubits placed for maximum connectivity.
- with_automatic_layout(device, layout_slug=None)
Replicates the register with an automatically generated layout.
The generated RegisterLayout can be accessed via Register.layout.
- Parameters:
device (Device) – The device constraints for the layout generation.
layout_slug (str | None, default:
None
) – An optional slug for the generated layout.
- Raises:
RuntimeError – If the automatic layout generation fails to meet the device constraints.
NotImplementedError – When the register has differentiable coordinates (ie torch Tensors with requires_grad=True).
- Returns:
A new register instance with identical qubit IDs and coordinates but also the newly generated RegisterLayout.
- Return type:
- rotated(degrees)
Makes a new rotated register.
All coordinates are rotated counter-clockwise around the origin.
- Parameters:
degrees (
float
) – The angle of rotation in degrees.- Returns:
A new register rotated around the origin by the given angle.
- Return type:
- draw(with_labels=True, blockade_radius=None, draw_graph=True, draw_half_radius=False, qubit_colors={}, fig_name=None, kwargs_savefig={}, custom_ax=None, show=True)
Draws the entire register.
- Parameters:
with_labels (bool, default:
True
) – If True, writes the qubit ID’s next to each qubit.blockade_radius (Optional[float], default:
None
) – The distance (in μm) between atoms below the Rydberg blockade effect occurs.draw_half_radius (bool, default:
False
) – Whether or not to draw the half the blockade radius surrounding each atoms. If True, requires blockade_radius to be defined.draw_graph (bool, default:
True
) – Whether or not to draw the interaction between atoms as edges in a graph. Will only draw if the blockade_radius is defined.qubit_colors (Mapping[QubitId, str], default:
{}
) – By default, atoms are drawn with a common default color. If this parameter is present, it replaces the colors for the specified atoms. Non-specified ones are stilled colored with the default value.fig_name (str | None, default:
None
) – The name on which to save the figure. If None the figure will not be saved.kwargs_savefig (dict, default:
{}
) – Keywords arguments formatplotlib.pyplot.savefig
. Not applicable if fig_name isNone
.custom_ax (Optional[Axes], default:
None
) – If present, instead of creating its own Axes object, the function will use the provided one. Warning: if fig_name is set, it may save content beyond what is drawn in this function.show (bool, default:
True
) – Whether or not to call plt.show() before returning. When combining this plot with other ones in a single figure, one may need to set this flag to False.
- Return type:
None
Note
When drawing half the blockade radius, we say there is a blockade effect between atoms whenever their respective circles overlap. This representation is preferred over drawing the full Rydberg radius because it helps in seeing the interactions between atoms.
- class pulser.register.register3d.Register3D(qubits, **kwargs)
Bases:
BaseRegister
,RegDrawer
A 3D quantum register containing a set of qubits.
- Parameters:
qubits (Mapping[Any, ArrayLike | pm.TensorLike]) – Dictionary with the qubit names as keys and their position coordinates (in μm) as values (e.g. {‘q0’:(2, -1, 0), ‘q1’:(-5, 10, 0), …}).
- classmethod cubic(side, spacing=4.0, prefix=None)
Initializes the register with the qubits in a cubic array.
- Parameters:
side (int) – Side of the cube in number of qubits.
spacing (float | pm.TensorLike, default:
4.0
) – The distance between neighbouring qubits in μm.prefix (Optional[str], default:
None
) – The prefix for the qubit ids. If defined, each qubit id starts with the prefix, followed by an int from 0 to N-1 (e.g. prefix=’q’ -> IDs: ‘q0’, ‘q1’, ‘q2’, …).
- Return type:
- Returns:
A 3D register with qubits placed in a cubic array.
- classmethod cuboid(rows, columns, layers, spacing=4.0, prefix=None)
Initializes the register with the qubits in a cuboid array.
- Parameters:
rows (int) – Number of rows.
columns (int) – Number of columns.
layers (int) – Number of layers.
spacing (float | pm.TensorLike, default:
4.0
) – The distance between neighbouring qubits in μm.prefix (Optional[str], default:
None
) – The prefix for the qubit ids. If defined, each qubit id starts with the prefix, followed by an int from 0 to N-1 (e.g. prefix=’q’ -> IDs: ‘q0’, ‘q1’, ‘q2’, …)
- Return type:
- Returns:
A 3D register with qubits placed in a cuboid array.
- to_2D(tol_width=0.0)
Converts a Register3D into a Register (if possible).
- Parameters:
tol_width (
float
, default:0.0
) – The allowed transverse width ofprojected. (the register to be) –
- Return type:
- Returns:
Returns a 2D register with the coordinates of the atoms in a plane, if they are coplanar.
- Raises:
ValueError – If the atoms are not coplanar.
- draw(with_labels=False, blockade_radius=None, draw_graph=True, draw_half_radius=False, qubit_colors={}, projection=False, fig_name=None, kwargs_savefig={})
Draws the entire register.
- Parameters:
with_labels (bool, default:
False
) – If True, writes the qubit ID’s next to each qubit.blockade_radius (Optional[float], default:
None
) – The distance (in μm) between atoms below the Rydberg blockade effect occurs.draw_half_radius (bool, default:
False
) – Whether or not to draw the half the blockade radius surrounding each atoms. If True, requires blockade_radius to be defined.draw_graph (bool, default:
True
) – Whether or not to draw the interaction between atoms as edges in a graph. Will only draw if the blockade_radius is defined.qubit_colors (Mapping[QubitId, str], default:
{}
) – By default, atoms are drawn with a common default color. If this parameter is present, it replaces the colors for the specified atoms. Non-specified ones are stilled colored with the default value.projection (bool, default:
False
) – Whether to draw a 2D projection instead of a perspective view.fig_name (str | None, default:
None
) – The name on which to save the figure. If None the figure will not be saved.kwargs_savefig (dict, default:
{}
) – Keywords arguments formatplotlib.pyplot.savefig
. Not applicable if fig_name isNone
.
- Return type:
None
Note
When drawing half the blockade radius, we say there is a blockade effect between atoms whenever their respective circles overlap. This representation is preferred over drawing the full Rydberg radius because it helps in seeing the interactions between atoms.
- static from_abstract_repr(obj_str)
Deserialize a 3D register from an abstract JSON object.
- Parameters:
obj_str (str) – the JSON string representing the register encoded in the abstract JSON format.
- Return type:
Register layout
A RegisterLayout
is used to define a register from a set of traps. It is
intended to be given to the user by the hardware provider as a way of showing
which layouts are already available on a given device. In turn, the user
can create a Register
by selecting the traps on which to place atoms, or
even a MappableRegister
, which allows for the creation of sequences whose
register can be defined at build time.
- class pulser.register.register_layout.RegisterLayout(trap_coordinates, slug=None)
A layout of traps out of which registers can be defined.
The traps are always sorted under the same convention: ascending order along x, then along y, then along z (if applicable). Respecting this order, the traps are then numbered starting from 0.
- Parameters:
trap_coordinates (ArrayLike) – The trap coordinates defining the layout.
slug (str | None, default:
None
) – An optional identifier for the layout.
- property coords
A shorthand for ‘sorted_coords’.
- define_register(*trap_ids, qubit_ids=None)
Defines a register from selected traps.
- Parameters:
trap_ids (
int
) – The trap IDs selected to form the Register.qubit_ids (
Optional
[Sequence
[Union
[int
,str
]]], default:None
) – A sequence of unique qubit IDs to associated to the selected traps. Must be of the same length as the selected traps.
- Return type:
- Returns:
The respective register instance.
- define_detuning_map(detuning_weights, slug=None)
Defines a DetuningMap for some trap ids of the register layout.
- Parameters:
detuning_weights (Mapping[int, float]) – A mapping between the IDs of the targeted traps and detuning weights (between 0 and 1).
slug (str | None, default:
None
) – An optional identifier for the detuning map.
- Return type:
- Returns:
- A DetuningMap associating detuning weights to the trap coordinates
of the targeted traps.
- draw(blockade_radius=None, draw_graph=False, draw_half_radius=False, projection=True, fig_name=None, kwargs_savefig={})
Draws the entire register layout.
- Parameters:
blockade_radius (Optional[float], default:
None
) – The distance (in μm) between atoms below which the Rydberg blockade effect occurs.draw_half_radius (bool, default:
False
) – Whether or not to draw half the blockade radius surrounding each trap. If True, requires blockade_radius to be defined.draw_graph (bool, default:
False
) – Whether or not to draw the interaction between atoms as edges in a graph. Will only draw if the blockade_radius is defined.projection (bool, default:
True
) – If the layout is in 3D, draws it as projections on different planes.fig_name (str | None, default:
None
) – The name on which to save the figure. If None the figure will not be saved.kwargs_savefig (dict, default:
{}
) – Keywords arguments formatplotlib.pyplot.savefig
. Not applicable if fig_name isNone
.
- Return type:
None
Note
When drawing half the blockade radius, we say there is a blockade effect between atoms whenever their respective circles overlap. This representation is preferred over drawing the full Rydberg radius because it helps in seeing the interactions between atoms.
- make_mappable_register(n_qubits, prefix='q')
Creates a mappable register associated with this layout.
A mappable register is a register whose atoms’ positions have not yet been defined. It can be used to create a sequence whose register is only defined when it is built. Note that not all the qubits ‘reserved’ in a MappableRegister need to be in the final Register, as qubits not associated with trap IDs won’t be included. If you intend on defining registers of different sizes from the same mappable register, reserve as many qubits as you need for your largest register.
- Parameters:
n_qubits (
int
) – The number of qubits to reserve in the mappable register.prefix (
str
, default:'q'
) – The prefix for the qubit ids. Each qubit ID starts with the prefix, followed by an int from 0 to N-1 (e.g. prefix=’q’ -> IDs: ‘q0’, ‘q1’, ‘q2’, …).
- Return type:
- Returns:
A substitute for a regular register that can be used to initialize a Sequence.
- to_abstract_repr()
Serializes the layout into an abstract JSON object.
- Return type:
str
- static from_abstract_repr(obj_str)
Deserialize a layout from an abstract JSON object.
- Parameters:
obj_str (str) – the JSON string representing the layout encoded in the abstract JSON format.
- Return type:
- property dimensionality
The dimensionality of the coordinates (2 or 3).
- get_traps_from_coordinates(*coordinates)
Finds the trap ID for a given set of trap coordinates.
- Parameters:
coordinates (
Union
[_SupportsArray
[dtype
[Any
]],_NestedSequence
[_SupportsArray
[dtype
[Any
]]],bool
,int
,float
,complex
,str
,bytes
,_NestedSequence
[Union
[bool
,int
,float
,complex
,str
,bytes
]]]) – The coordinates to return the trap IDs.- Return type:
list
[int
]- Returns:
The list of trap IDs corresponding to the coordinates.
- property number_of_traps
The number of traps in the layout.
- property sorted_coords
The sorted coordinates.
- static_hash()
Returns the idempotent hash.
Python’s standard hash is not idempotent as it changes between sessions. This hash can be used when an idempotent hash is required.
- Returns:
An hexstring encoding the hash.
- Return type:
str
Note
This hash will be returned as an hexstring without the ‘0x’ prefix (unlike what is returned by ‘hex()’).
- property traps_dict
Mapping between trap IDs and coordinates.
- class pulser.register.mappable_reg.MappableRegister(register_layout, *qubit_ids)
A register with the traps of each qubit still to be defined.
- Parameters:
register_layout (
RegisterLayout
) – The register layout on which this register will be defined.qubit_ids (
Union
[int
,str
]) – The Ids for the qubits to pre-declare on this register.
- property qubit_ids
The qubit IDs of this mappable register.
- property layout
The layout used to define the register.
- build_register(qubits)
Builds an actual register.
- Parameters:
qubits (
Mapping
[Union
[int
,str
],int
]) – A map between the qubit IDs to use and the layout traps where the qubits will be placed. Qubit IDs declared in the MappableRegister but not defined here will simply be left out of the final register.- Return type:
- Returns:
The resulting register.
- find_indices(id_list)
Computes indices of qubits.
This can especially be useful when building a Pulser Sequence with a parameter denoting qubits.
- Return type:
list
[int
]
Example
Let
reg
be a mappable register with qubit Ids “a”, “b”, “c” and “d”.>>> reg.find_indices(["a", "b", "d", "a"])
It returns
[0, 1, 3, 0]
, following the qubits order of the mappable register (defined by qubit_ids).Then, it is possible to use these indices when building a sequence, typically to instanciate an array of variables that can be provided as an argument to
target_index
andphase_shift_index
.When building a sequence and declaring N qubits, their ids should refer to the first N elements of qubit_id.
- Parameters:
id_list (
Sequence
[Union
[int
,str
]]) – IDs of the qubits to denote.- Returns:
Indices of the qubits to denote, only valid for the given mapping.
- define_detuning_map(detuning_weights, slug=None)
Defines a DetuningMap for some trap ids of the register layout.
- Parameters:
detuning_weights (Mapping[int, float]) – A mapping between the IDs of the targeted traps and detuning weights (between 0 and 1).
slug (str | None, default:
None
) – An optional identifier for the detuning map.
- Return type:
- Returns:
- A DetuningMap associating detuning weights to the trap coordinates
of the targeted traps.
Special cases
Special register layouts defined for convenience.
- class pulser.register.special_layouts.RectangularLatticeLayout(rows, columns, col_spacing, row_spacing)
Bases:
RegisterLayout
RegisterLayout with rectangular lattice pattern in a rectangular shape.
- Parameters:
rows (
int
) – The number of rows of traps.columns (
int
) – The number of columns of traps.col_spacing (
float
) – Horizontal distance between neighbouring traps (in µm).row_spacing (
float
) – Vertical distance between neighbouring traps (in µm)
- square_register(side, prefix='q')
Defines a register with a square shape.
- Parameters:
side (
int
) – The length of the square’s side, in number of atoms.prefix (
str
, default:'q'
) – The prefix for the qubit ids. Each qubit ID starts with the prefix, followed by an int from 0 to N-1 (e.g. prefix=’q’ -> IDs: ‘q0’, ‘q1’, ‘q2’, …).
- Return type:
- Returns:
The register instance created from this layout.
- rectangular_register(rows, columns, prefix='q')
Defines a register with a rectangular shape.
- Parameters:
rows (
int
) – The number of rows in the register.columns (
int
) – The number of columns in the register.prefix (
str
, default:'q'
) – The prefix for the qubit ids. Each qubit ID starts with the prefix, followed by an int from 0 to N-1 (e.g. prefix=’q’ -> IDs: ‘q0’, ‘q1’, ‘q2’, …).
- Return type:
- Returns:
The register instance created from this layout.
- class pulser.register.special_layouts.SquareLatticeLayout(rows, columns, spacing)
Bases:
RectangularLatticeLayout
A RegisterLayout with a square lattice pattern in a rectangular shape.
- Parameters:
rows (
int
) – The number of rows of traps.columns (
int
) – The number of columns of traps.spacing (
float
) – The distance between neighbouring traps (in µm).
- class pulser.register.special_layouts.TriangularLatticeLayout(n_traps, spacing)
Bases:
RegisterLayout
A RegisterLayout with a triangular lattice pattern in a hexagonal shape.
- Parameters:
n_traps (
int
) – The number of traps in the layout.spacing (
float
) – The distance between neighbouring traps (in µm).
- hexagonal_register(n_atoms, prefix='q')
Defines a register with an hexagonal shape.
- Parameters:
n_atoms (
int
) – The number of atoms in the register.prefix (
str
, default:'q'
) – The prefix for the qubit ids. Each qubit ID starts with the prefix, followed by an int from 0 to N-1 (e.g. prefix=’q’ -> IDs: ‘q0’, ‘q1’, ‘q2’, …).
- Return type:
- Returns:
The register instance created from this layout.
- rectangular_register(rows, atoms_per_row, prefix='q')
Defines a register with a rectangular shape.
- Parameters:
rows (
int
) – The number of rows in the register.atoms_per_row (
int
) – The number of atoms in each row.prefix (
str
, default:'q'
) – The prefix for the qubit ids. Each qubit ID starts with the prefix, followed by an int from 0 to N-1 (e.g. prefix=’q’ -> IDs: ‘q0’, ‘q1’, ‘q2’, …).
- Return type:
- Returns:
The register instance created from this layout.
DetuningMap
A DetuningMap
is associated to a DMM
in a Sequence
. It links a set
of weights to a set of trap coordinates. It is intended to be defined by the user
from a RegisterLayout
, a Register
or a MappableRegister
using
define_detuning_map
.
- class pulser.register.weight_maps.DetuningMap(trap_coordinates, weights, slug=None)
Defines a DetuningMap.
A DetuningMap associates a detuning weight (a value between 0 and 1) to the coordinates of a trap.
- Parameters:
trap_coordinates (ArrayLike) – An array containing the coordinates of the traps.
weights (Sequence[float]) – A list of detuning weights (between 0 and 1) to associate to the traps.
- property dimensionality
The dimensionality of the coordinates (2 or 3).
- draw(labels=None, fig_name=None, kwargs_savefig={}, custom_ax=None, show=True)
Draws the detuning map.
- Parameters:
labels (typing.Sequence[QubitId] | None, default:
None
) – If defined, writes the labels next to each site. Must have the same length and order like the trap_coordinates.fig_name (str | None, default:
None
) – The name on which to save the figure. If None the figure will not be saved.kwargs_savefig (dict, default:
{}
) – Keywords arguments formatplotlib.pyplot.savefig
. Not applicable if fig_name isNone
.custom_ax (Optional[Axes], default:
None
) – If present, instead of creating its own Axes object, the function will use the provided one. Warning: if fig_name is set, it may save content beyond what is drawn in this function.show (bool, default:
True
) – Whether or not to call plt.show() before returning. When combining this plot with other ones in a single figure, one may need to set this flag to False.
- Return type:
None
- get_qubit_weight_map(qubits)
Creates a map between qubit IDs and the weight on their sites.
- Return type:
dict
[Union
[int
,str
],float
]
- get_traps_from_coordinates(*coordinates)
Finds the trap ID for a given set of trap coordinates.
- Parameters:
coordinates (
Union
[_SupportsArray
[dtype
[Any
]],_NestedSequence
[_SupportsArray
[dtype
[Any
]]],bool
,int
,float
,complex
,str
,bytes
,_NestedSequence
[Union
[bool
,int
,float
,complex
,str
,bytes
]]]) – The coordinates to return the trap IDs.- Return type:
list
[int
]- Returns:
The list of trap IDs corresponding to the coordinates.
- property number_of_traps
The number of traps in the layout.
- property sorted_coords
The sorted coordinates.
- property sorted_weights
The weights sorted to match the sorted trap coordinates.
- static_hash()
Returns the idempotent hash.
Python’s standard hash is not idempotent as it changes between sessions. This hash can be used when an idempotent hash is required.
- Returns:
An hexstring encoding the hash.
- Return type:
str
Note
This hash will be returned as an hexstring without the ‘0x’ prefix (unlike what is returned by ‘hex()’).
- property trap_coordinates
The array of trap coordinates, in the order they were given.
- property traps_dict
Mapping between trap IDs and coordinates.
Pulse
Contains the Pulse class, the building block of a pulse sequence.
- class pulser.pulse.Pulse(amplitude, detuning, phase, post_phase_shift=0.0)
A generic pulse.
In Pulser, a Pulse is a modulation of a frequency signal in amplitude and/or frequency, with a specific phase, over a given duration. Amplitude and frequency modulations are defined by
Waveform
child classes. Frequency modulation is determined by a detuning waveform, which describes the shift in frequency from the channel’s central frequency over time. If either quantity is constant throughout the entire pulse, use theConstantDetuning
,ConstantAmplitude
orConstantPulse
class method to create it. If defining the pulse’s phase modulation is preferred over its frequency modulation, usePulse.ArbitraryPhase()
.Note
We define the
amplitude
of a pulse to be its Rabi frequency, \(\Omega\), in rad/µs. Equivalently, thedetuning
is \(\delta\), also in rad/µs.- Parameters:
amplitude (Waveform | Parametrized) – The pulse amplitude waveform (in rad/µs).
detuning (Waveform | Parametrized) – The pulse detuning waveform (in rad/µs).
phase (float | pm.TensorLike | Parametrized) – The pulse phase (in radians).
post_phase_shift (float | Parametrized, default:
0.0
) – Optionally lets you add a phase shift(in rad) immediately after the end of the pulse. This allows for enconding of arbitrary single-qubit gates into a single pulse (seeSequence.phase_shift()
for more information).
- property duration
The duration of the pulse (in ns).
- classmethod ConstantDetuning(cls, amplitude, detuning, phase, post_phase_shift=0.0)
Creates a Pulse with an amplitude waveform and a constant detuning.
- Parameters:
amplitude (Waveform | Parametrized) – The pulse amplitude waveform (in rad/µs).
detuning (float | pm.TensorLike | Parametrized) – The detuning value (in rad/µs).
phase (float | pm.TensorLike | Parametrized) – The pulse phase (in radians).
post_phase_shift (float | Parametrized, default:
0.0
) – Optionally lets you add a phase shift (in rad) immediately after the end of the pulse.
- Return type:
- classmethod ConstantAmplitude(cls, amplitude, detuning, phase, post_phase_shift=0.0)
Pulse with a constant amplitude and a detuning waveform.
- Parameters:
amplitude (float | pm.TensorLike | Parametrized) – The pulse amplitude value (in rad/µs).
detuning (Waveform | Parametrized) – The pulse detuning waveform (in rad/µs).
phase (float | pm.TensorLike | Parametrized) – The pulse phase (in radians).
post_phase_shift (float | Parametrized, default:
0.0
) – Optionally lets you add a phase shift (in rad) immediately after the end of the pulse.
- Return type:
- classmethod ConstantPulse(duration, amplitude, detuning, phase, post_phase_shift=0.0)
Pulse with a constant amplitude and a constant detuning.
- Parameters:
duration (int | Parametrized) – The pulse duration (in ns).
amplitude (float | pm.TensorLike | Parametrized) – The pulse amplitude value (in rad/µs).
detuning (float | pm.TensorLike | Parametrized) – The detuning value (in rad/µs).
phase (float | pm.TensorLike | Parametrized) – The pulse phase (in radians).
post_phase_shift (float | Parametrized, default:
0.0
) – Optionally lets you add a phase shift (in rad) immediately after the end of the pulse.
- Return type:
- classmethod ArbitraryPhase(cls, amplitude, phase, post_phase_shift=0.0)
Pulse with an arbitrary phase waveform.
- Parameters:
- Return type:
Note
Due to how the Hamiltonian is defined in Pulser, the phase and detuning are related by
\[\phi(t) = \phi_c - \sum_{k=0}^{t} \delta(k)\]where \(\phi_c\) is the pulse’s constant phase offset. From a given phase waveform, we extract the phase offset and detuning waveform that respect this formula for every sample of \(\phi(t)\) and use these quantities to define the Pulse.
Warning
Except when the phase waveform is a
ConstantWaveform
or aRampWaveform
, the extracted detuning waveform will be aCustomWaveform
. This makes the Pulse uncapable of automatically extending its duration to fit a channel’s clock period.- Returns:
A regular Pulse, with the phase waveform translated into a detuning waveform and a constant phase offset.
- draw()
Draws the pulse’s amplitude and frequency waveforms.
- Return type:
None
- fall_time(channel, in_eom_mode=False)
Calculates the extra time needed to ramp down to zero.
- Return type:
int
- get_full_duration(channel, in_eom_mode=False)
Calculates the pulse’s full duration after output modulation.
The full duration of a pulse is the total time between the start of the input signal and the end of the output signal, as shown in the sequence.
- Parameters:
channel (
Channel
) – The pulse executing the channel.in_eom_mode (
bool
, default:False
) – Whether the pulse is executed in EOM mode.
- Return type:
int
Waveforms
All built-in types of waveforms and their Waveform parent class.
- class pulser.waveforms.Waveform(duration)
Bases:
ABC
The abstract class for a pulse’s waveform.
- abstract property duration
The duration of the pulse (in ns).
- property samples
The value at each time step that describes the waveform.
- Returns:
A numpy array with a value for each time step.
- property first_value
The first value in the waveform.
- property last_value
The last value in the waveform.
- property integral
Integral of the waveform (in [waveform units].µs).
- draw(output_channel=None, ylabel=None)
Draws the waveform.
- Parameters:
output_channel (Optional[Channel], default:
None
) – The output channel. If given, will draw the modulated waveform on top of the input one.ylabel (str | None, default:
None
) – An optional label for the y-axis of the plot.
- Return type:
None
- change_duration(new_duration)
Returns a new waveform with modified duration.
- Parameters:
new_duration (
int
) – The duration of the new waveform.- Return type:
- modulated_samples(channel, eom=False)
The waveform samples as output of a given channel.
This duration is adjusted according to the minimal buffer times.
- Parameters:
channel (
Channel
) – The channel modulating the waveform.eom (
bool
, default:False
) – Whether to modulate for the EOM.
- Return type:
AbstractArray
- Returns:
The array of samples after modulation.
- modulation_buffers(channel, eom=False)
The minimal buffers needed around a modulated waveform.
- Parameters:
channel (
Channel
) – The channel modulating the waveform.eom (
bool
, default:False
) – Whether to calculate the modulation buffers with the EOM bandwidth.
- Return type:
tuple
[int
,int
]- Returns:
The minimum buffer times at the start and end of the samples, in ns.
- class pulser.waveforms.CompositeWaveform(*waveforms)
Bases:
Waveform
A waveform combining multiple smaller waveforms.
- Parameters:
waveforms (
Union
[Parametrized
,Waveform
]) – Two or more waveforms to combine.
- property duration
The duration of the pulse (in ns).
- property waveforms
The waveforms encapsulated in the composite waveform.
- class pulser.waveforms.CustomWaveform(samples)
Bases:
Waveform
A custom waveform.
- Parameters:
samples (ArrayLike | pm.TensorLike) – The modulation values at each time step. The number of samples dictates the duration, in ns.
- property duration
The duration of the pulse (in ns).
- class pulser.waveforms.ConstantWaveform(duration, value)
Bases:
Waveform
A waveform of constant value.
- Parameters:
duration (
Union
[int
,Parametrized
]) – The waveform duration (in ns).value (
Union
[float
,TensorLike
,Parametrized
]) – The value.
- property duration
The duration of the pulse (in ns).
- change_duration(new_duration)
Returns a new waveform with modified duration.
- Parameters:
new_duration (
int
) – The duration of the new waveform.- Return type:
- Returns:
The new waveform with the given duration.
- class pulser.waveforms.RampWaveform(duration, start, stop)
Bases:
Waveform
A linear ramp waveform.
- Parameters:
duration (
Union
[int
,Parametrized
]) – The waveform duration (in ns).start (
Union
[float
,TensorLike
,Parametrized
]) – The value at the initial sample.stop (
Union
[float
,TensorLike
,Parametrized
]) – The value at the final sample.
- property duration
The duration of the pulse (in ns).
- property slope
Slope of the ramp, in [waveform units] / ns.
- change_duration(new_duration)
Returns a new waveform with modified duration.
- Parameters:
new_duration (
int
) – The duration of the new waveform.- Return type:
- Returns:
The new waveform with the given duration.
- class pulser.waveforms.BlackmanWaveform(duration, area)
Bases:
Waveform
A Blackman window of a specified duration and area.
Warning
The BlackmanWaveform assumes its values are in rad/µs for the area calculation. If this is not the case, the ‘area’ value should be scaled accordingly.
- Parameters:
duration (
Union
[int
,Parametrized
]) – The waveform duration (in ns).area (
Union
[float
,TensorLike
,Parametrized
]) – The integral of the waveform. Can be negative, in which case it takes the positive waveform and changes the sign of all its values.
- classmethod from_max_val(cls, max_val, area)
Creates a Blackman waveform with a threshold on the maximum value.
Instead of defining a duration, the waveform is defined by its area and the maximum value. The duration is chosen so that the maximum value is not surpassed, but approached as closely as possible.
- Return type:
Warning
The BlackmanWaveform assumes its values are in rad/µs for the area calculation. If this is not the case, the ‘max_val’ and ‘area’ values should be scaled accordingly.
- Parameters:
max_val (
Union
[float
,Parametrized
]) – The maximum value threshold (in rad/µs). If negative, it is taken as the lower bound i.e. the minimum value that can be reached. The sign of max_val must match the sign of area.area (
Union
[float
,TensorLike
,Parametrized
]) – The area under the waveform.
- property duration
The duration of the pulse (in ns).
- change_duration(new_duration)
Returns a new waveform with modified duration.
- Parameters:
new_duration (
int
) – The duration of the new waveform.- Return type:
- Returns:
The new waveform with the same area but a new duration.
- class pulser.waveforms.InterpolatedWaveform(duration, values, times=None, interpolator='PchipInterpolator', **interpolator_kwargs)
Bases:
Waveform
Creates a waveform from interpolation of a set of data points.
- Parameters:
duration (
Union
[int
,Parametrized
]) – The waveform duration (in ns).values (
Union
[_SupportsArray
[dtype
[Any
]],_NestedSequence
[_SupportsArray
[dtype
[Any
]]],bool
,int
,float
,complex
,str
,bytes
,_NestedSequence
[Union
[bool
,int
,float
,complex
,str
,bytes
]],Parametrized
]) – Values of the interpolation points.times (
Union
[_SupportsArray
[dtype
[Any
]],_NestedSequence
[_SupportsArray
[dtype
[Any
]]],bool
,int
,float
,complex
,str
,bytes
,_NestedSequence
[Union
[bool
,int
,float
,complex
,str
,bytes
]],Parametrized
,None
], default:None
) – Fractions of the total duration (between 0 and 1), indicating where to place each value on the time axis. If not given, the values are spread evenly throughout the full duration of the waveform.interpolator (
str
, default:'PchipInterpolator'
) – The SciPy interpolation class to use. Supports “PchipInterpolator” and “interp1d”.**interpolator_kwargs (
Any
) – Extra parameters to give to the chosen interpolator class.
- property duration
The duration of the pulse (in ns).
- property interp_function
The interpolating function.
- property data_points
Points (t[ns], value[arb. units]) that define the interpolation.
- change_duration(new_duration)
Returns a new waveform with modified duration.
- Parameters:
new_duration (
int
) – The duration of the new waveform.- Return type:
- Returns:
The new waveform with the same coordinates for interpolation but a new duration.
- class pulser.waveforms.KaiserWaveform(duration, area, beta=14.0)
Bases:
Waveform
A Kaiser window of a specified duration and beta parameter.
For more information on the Kaiser window and the beta parameter, check the numpy documentation for the kaiser(M, beta) function: https://numpy.org/doc/stable/reference/generated/numpy.kaiser.html
Warning
The KaiserWaveform assumes its values are in rad/µs for the area calculation. If this is not the case, the ‘area’ value should be scaled accordingly.
- Parameters:
duration (
Union
[int
,Parametrized
]) – The waveform duration (in ns).area (
Union
[float
,TensorLike
,Parametrized
]) – The integral of the waveform. Can be negative, in which case it takes the positive waveform and changes the sign of all its values.beta (
Union
[float
,Parametrized
,None
], default:14.0
) – The beta parameter of the Kaiser window. The default value is 14.
- classmethod from_max_val(cls, max_val, area, beta=14.0)
Creates a Kaiser waveform with a threshold on the maximum value.
Instead of defining a duration, the waveform is defined by its area and the maximum value. The duration is chosen so that the maximum value is not surpassed, but approached as closely as possible.
- Return type:
Warning
The KaiserWaveform assumes its values are in rad/µs for the area calculation. If this is not the case, the ‘max_val’ and ‘area’ values should be scaled accordingly.
- Parameters:
max_val (
Union
[float
,Parametrized
]) – The maximum value threshold (in rad/µs). If negative, it is taken as the lower bound i.e. the minimum value that can be reached. The sign of max_val must match the sign of area.area (
Union
[float
,TensorLike
,Parametrized
]) – The area under the waveform.beta (
Union
[float
,Parametrized
,None
], default:14.0
) – The beta parameter of the Kaiser window. The default value is 14.
- property duration
The duration of the pulse (in ns).
- change_duration(new_duration)
Returns a new waveform with modified duration.
- Parameters:
new_duration (
int
) – The duration of the new waveform.- Return type:
- Returns:
The new waveform with the same area and beta but a new duration.
Devices
Structure of a Device
The Device
class sets the structure of a physical device,
while VirtualDevice
is a more permissive device type which can
only be used in emulators, as it does not necessarily represent the
constraints of a physical device.
Illustrative instances of Device
(see Physical Devices) and VirtualDevice
(the MockDevice) come included in the pulser.devices module.
- class pulser.devices._device_datacls.Device(name, dimensions, rydberg_level, min_atom_distance, max_atom_num, max_radial_distance, interaction_coeff_xy=None, supports_slm_mask=False, max_layout_filling=0.5, optimal_layout_filling=None, min_layout_traps=1, max_layout_traps=None, max_sequence_duration=None, max_runs=None, requires_layout=True, channel_ids=None, channel_objects=<factory>, dmm_objects=<factory>, default_noise_model=None, pre_calibrated_layouts=<factory>, accepts_new_layouts=True)
Specifications of a neutral-atom device.
A Device instance is immutable and must have all of its parameters defined. For usage in emulations, it can be converted to a VirtualDevice through the Device.to_virtual() method.
- name
The name of the device.
- dimensions
Whether it supports 2D or 3D arrays.
- channel_objects
The Channel subclass instances specifying each channel in the device.
- channel_ids
Custom IDs for each channel object. When defined, an ID must be given for each channel. If not defined, the IDs are generated internally based on the channels’ names and addressing.
- dmm_objects
The DMM subclass instances specifying each channel in the device. They are referenced by their order in the list, with the ID “dmm_[index in dmm_objects]”.
- rydberg_level
The value of the principal quantum number \(n\) when the Rydberg level used is of the form \(|nS_{1/2}, m_j = +1/2\rangle\).
- max_atom_num
Maximum number of atoms supported in an array.
- Type:
int
- max_radial_distance
The furthest away an atom can be from the center of the array (in μm).
- Type:
int
- min_atom_distance
The closest together two atoms can be (in μm).
- interaction_coeff_xy
\(C_3/\hbar\) (in \(rad \cdot \mu s^{-1} \cdot \mu m^3\)), which sets the van der Waals interaction strength between atoms in different Rydberg states. Needed only if there is a Microwave channel in the device. If unsure, 3700.0 is a good default value.
- supports_slm_mask
Whether the device supports the SLM mask feature.
- max_layout_filling
The largest fraction of a layout that can be filled with atoms.
- optimal_layout_filling
An optional value for the fraction of a layout that should be filled with atoms.
- min_layout_traps
The minimum number of traps a layout can have.
- max_layout_traps
An optional value for the maximum number of traps a layout can have.
- max_sequence_duration
The maximum allowed duration for a sequence (in ns).
- max_runs
The maximum number of runs allowed on the device. Only used for backend execution.
- default_noise_model
An optional noise model characterizing the default noise of the device. Can be used by emulator backends that support noise.
- requires_layout
Whether the register used in the sequence must be created from a register layout. Only enforced in QPU execution.
- Type:
bool
- pre_calibrated_layouts
RegisterLayout instances that are already available on the Device.
- Type:
tuple[RegisterLayout, …]
- accepts_new_layouts
Whether registers built from register layouts that are not already calibrated are accepted. Only enforced in QPU execution.
- Type:
bool
- property calibrated_register_layouts
Register layouts already calibrated on this device.
- is_calibrated_layout(register_layout)
Checks whether a layout is within the calibrated layouts.
- Parameters:
register_layout (
RegisterLayout
) – The RegisterLayout to check.- Return type:
bool
- Returns:
True if register_layout is found among calibrated_register_layouts, False otherwise.
- register_is_from_calibrated_layout(register)
Checks whether a register was constructed from a calibrated layout.
If the register is a BaseRegister, checks that it has a layout. If so, or if it is a MappableRegister, check that its layout is within the calibrated layouts.
- Parameters:
register_layout – the Register or MappableRegister to check.
- Return type:
bool
- Returns:
True if register has a layout and it is found among calibrated_register_layouts, False otherwise.
- to_virtual()
Converts the Device into a VirtualDevice.
- Return type:
- print_specs()
Prints the device specifications.
- Return type:
None
- static from_abstract_repr(obj_str)
Deserialize a Device from an abstract JSON object.
- Return type:
Warning
Raises an error if the JSON string represents a VirtualDevice. VirtualDevice.from_abstract_repr should be used for this case.
- Parameters:
obj_str (str) – the JSON string representing the Device encoded in the abstract JSON format.
- property channels
Dictionary of available channels on this device.
- property dmm_channels
Dictionary of available DMM channels on this device.
- property interaction_coeff
The interaction coefficient for the chosen Rydberg level.
Corresponds to \(C_6/\hbar\) (in units of \(rad \cdot \mu s^{-1} \cdot \mu m^6\)) for the interaction term of the Ising hamiltonian.
- rabi_from_blockade(blockade_radius)
The maximum Rabi frequency value to enforce a given blockade radius.
- Parameters:
blockade_radius (
float
) – The Rydberg blockade radius, in µm.- Return type:
float
- Returns:
The maximum rabi frequency value, in rad/µs.
- rydberg_blockade_radius(rabi_frequency)
Calculates the Rydberg blockade radius for a given Rabi frequency.
- Parameters:
rabi_frequency (
float
) – The Rabi frequency, in rad/µs.- Return type:
float
- Returns:
The rydberg blockade radius, in μm.
- property supported_bases
Available electronic transitions for control and measurement.
- property supported_states
Available states ranked by their energy levels (highest first).
- to_abstract_repr()
Serializes the device into an abstract JSON object.
- Return type:
str
- validate_layout(layout)
Checks if a register layout is compatible with this device.
- Parameters:
layout (
RegisterLayout
) – The RegisterLayout to validate.- Return type:
None
- validate_layout_filling(register)
Checks if a register properly fills its layout.
- Parameters:
register (BaseRegister | MappableRegister) – The register to validate. Must be created from a register layout.
- Return type:
None
- validate_register(register)
Checks if ‘register’ is compatible with this device.
- Parameters:
register (
BaseRegister
) – The Register to validate.- Return type:
None
- class pulser.devices._device_datacls.VirtualDevice(name, dimensions, rydberg_level, min_atom_distance=0, max_atom_num=None, max_radial_distance=None, interaction_coeff_xy=None, supports_slm_mask=True, max_layout_filling=0.5, optimal_layout_filling=None, min_layout_traps=1, max_layout_traps=None, max_sequence_duration=None, max_runs=None, requires_layout=False, reusable_channels=True, channel_ids=None, channel_objects=<factory>, dmm_objects=(DMM(addressing='Global', max_abs_detuning=None, max_amp=0, min_retarget_interval=None, fixed_retarget_t=None, max_targets=None, clock_period=1, min_duration=1, max_duration=100000000, min_avg_amp=0, mod_bandwidth=None, eom_config=None, propagation_dir=None, bottom_detuning=None, total_bottom_detuning=None), ), default_noise_model=None)
Specifications of a virtual neutral-atom device.
A VirtualDevice can only be used for emulation and allows some parameters to be left undefined. Furthermore, it optionally allows the same channel to be declared multiple times in the same Sequence (when reusable_channels=True) and allows the Rydberg level to be changed.
- name
The name of the device.
- dimensions
Whether it supports 2D or 3D arrays.
- channel_objects
The Channel subclass instances specifying each channel in the device.
- channel_ids
Custom IDs for each channel object. When defined, an ID must be given for each channel. If not defined, the IDs are generated internally based on the channels’ names and addressing.
- dmm_objects
The DMM subclass instances specifying each channel in the device. They are referenced by their order in the list, with the ID “dmm_[index in dmm_objects]”.
- Type:
tuple[DMM, …]
- rydberg_level
The value of the principal quantum number \(n\) when the Rydberg level used is of the form \(|nS_{1/2}, m_j = +1/2\rangle\).
- max_atom_num
Maximum number of atoms supported in an array.
- Type:
int | None
- max_radial_distance
The furthest away an atom can be from the center of the array (in μm).
- Type:
int | None
- min_atom_distance
The closest together two atoms can be (in μm).
- Type:
float
- interaction_coeff_xy
\(C_3/\hbar\) (in \(rad \cdot \mu s^{-1} \cdot \mu m^3\)), which sets the van der Waals interaction strength between atoms in different Rydberg states. Needed only if there is a Microwave channel in the device. If unsure, 3700.0 is a good default value.
- supports_slm_mask
Whether the device supports the SLM mask feature.
- Type:
bool
- max_layout_filling
The largest fraction of a layout that can be filled with atoms.
- optimal_layout_filling
An optional value for the fraction of a layout that should be filled with atoms.
- min_layout_traps
The minimum number of traps a layout can have.
- max_layout_traps
An optional value for the maximum number of traps a layout can have.
- max_sequence_duration
The maximum allowed duration for a sequence (in ns).
- max_runs
The maximum number of runs allowed on the device. Only used for backend execution.
- default_noise_model
An optional noise model characterizing the default noise of the device. Can be used by emulator backends that support noise.
- requires_layout
Whether the register used in the sequence must be created from a register layout. Only enforced in QPU execution.
- reusable_channels
Whether each channel can be declared multiple times on the same pulse sequence.
- Type:
bool
- change_rydberg_level(ryd_lvl)
Changes the Rydberg level used in the Device.
Find the \(C_6/\hbar\) coefficient matching the Rydberg level on this page
- Parameters:
ryd_lvl (
int
) – the Rydberg level to use (between 50 and 100).- Return type:
None
- static from_abstract_repr(obj_str)
Deserialize a VirtualDevice from an abstract JSON object.
- Return type:
Warning
If the JSON string represents a Device, the Device is converted into a VirtualDevice using the Device.to_virtual method.
- Parameters:
obj_str (str) – the JSON string representing the noise model encoded in the abstract JSON format.
- property channels
Dictionary of available channels on this device.
- property dmm_channels
Dictionary of available DMM channels on this device.
- property interaction_coeff
The interaction coefficient for the chosen Rydberg level.
Corresponds to \(C_6/\hbar\) (in units of \(rad \cdot \mu s^{-1} \cdot \mu m^6\)) for the interaction term of the Ising hamiltonian.
- rabi_from_blockade(blockade_radius)
The maximum Rabi frequency value to enforce a given blockade radius.
- Parameters:
blockade_radius (
float
) – The Rydberg blockade radius, in µm.- Return type:
float
- Returns:
The maximum rabi frequency value, in rad/µs.
- rydberg_blockade_radius(rabi_frequency)
Calculates the Rydberg blockade radius for a given Rabi frequency.
- Parameters:
rabi_frequency (
float
) – The Rabi frequency, in rad/µs.- Return type:
float
- Returns:
The rydberg blockade radius, in μm.
- property supported_bases
Available electronic transitions for control and measurement.
- property supported_states
Available states ranked by their energy levels (highest first).
- to_abstract_repr()
Serializes the device into an abstract JSON object.
- Return type:
str
- validate_layout(layout)
Checks if a register layout is compatible with this device.
- Parameters:
layout (
RegisterLayout
) – The RegisterLayout to validate.- Return type:
None
- validate_layout_filling(register)
Checks if a register properly fills its layout.
- Parameters:
register (BaseRegister | MappableRegister) – The register to validate. Must be created from a register layout.
- Return type:
None
- validate_register(register)
Checks if ‘register’ is compatible with this device.
- Parameters:
register (
BaseRegister
) – The Register to validate.- Return type:
None
Physical Devices
Each Device` instance holds the characteristics of a physical device,
which when associated with a pulser.Sequence
condition its development.
- pulser.devices.AnalogDevice = AnalogDevice
- Register parameters:
Dimensions: 2D
Rydberg level: 60
Maximum number of atoms: 25
Maximum distance from origin: 35 μm
Minimum distance between neighbouring atoms: 5 μm
Maximum layout filling fraction: 0.5
SLM Mask: No
Maximum sequence duration: 4000 ns
- Channels:
- ID: ‘rydberg_global’
Type: Rydberg (ground-rydberg basis)
Addressing: Global
Maximum \(\Omega\): 12.57 rad/µs
Maximum \(|\delta|\): 125.7 rad/µs
Minimum average amplitude: 0 rad/µs
Clock period: 4 ns
Minimum instruction duration: 16 ns
- pulser.devices.DigitalAnalogDevice = DigitalAnalogDevice
- Register parameters:
Dimensions: 2D
Rydberg level: 70
Maximum number of atoms: 100
Maximum distance from origin: 50 μm
Minimum distance between neighbouring atoms: 4 μm
Maximum layout filling fraction: 0.5
SLM Mask: Yes
- Channels:
- ID: ‘rydberg_global’
Type: Rydberg (ground-rydberg basis)
Addressing: Global
Maximum \(\Omega\): 15.71 rad/µs
Maximum \(|\delta|\): 125.7 rad/µs
Minimum average amplitude: 0 rad/µs
Clock period: 4 ns
Minimum instruction duration: 16 ns
- ID: ‘rydberg_local’
Type: Rydberg (ground-rydberg basis)
Addressing: Local
Maximum \(\Omega\): 62.83 rad/µs
Maximum \(|\delta|\): 125.7 rad/µs
Minimum average amplitude: 0 rad/µs
Minimum time between retargets: 220 ns
Fixed retarget time: 0 ns
Maximum simultaneous targets: 1
Clock period: 4 ns
Minimum instruction duration: 16 ns
- ID: ‘raman_local’
Type: Raman (digital basis)
Addressing: Local
Maximum \(\Omega\): 62.83 rad/µs
Maximum \(|\delta|\): 125.7 rad/µs
Minimum average amplitude: 0 rad/µs
Minimum time between retargets: 220 ns
Fixed retarget time: 0 ns
Maximum simultaneous targets: 1
Clock period: 4 ns
Minimum instruction duration: 16 ns
- ID: ‘dmm_0’
Type: DMM (ground-rydberg basis)
Addressing: Global
Maximum \(\Omega\): 0 rad/µs
Bottom \(|\delta|\): -125.7 rad/µs
Minimum average amplitude: 0 rad/µs
Clock period: 4 ns
Minimum instruction duration: 16 ns
Noise Model
Defines a noise model class for emulator backends.
- class pulser.noise_model.NoiseModel(runs=None, samples_per_run=None, state_prep_error=None, p_false_pos=None, p_false_neg=None, temperature=None, laser_waist=None, amp_sigma=None, relaxation_rate=None, dephasing_rate=None, hyperfine_dephasing_rate=None, depolarizing_rate=None, eff_noise_rates=(), eff_noise_opers=(), with_leakage=False)
Specifies the noise model parameters for emulation.
Supported noise types:
- leakage: Adds an error state ‘x’ to the computational
basis, that can interact with the other states via an effective noise channel. Must be defined with an effective noise channel, but is incompatible with dephasing and depolarizing noise channels.
relaxation: Noise due to a decay from the Rydberg to the ground state (parametrized by
relaxation_rate
), commonly characterized experimentally by the T1 time.dephasing: Random phase (Z) flip (parametrized by
dephasing_rate
), commonly characterized experimentally by the T2* time.depolarizing: Quantum noise where the state is turned into the maximally mixed state with rate
depolarizing_rate
. While it does not describe a physical phenomenon, it is a commonly used tool to test the system under a uniform combination of phase flip (Z) and bit flip (X) errors.eff_noise: General effective noise channel defined by the set of collapse operators
eff_noise_opers
and their corresponding rateseff_noise_rates
.doppler: Local atom detuning due to termal motion of the atoms and Doppler effect with respect to laser frequency. Parametrized by the
temperature
field.amplitude: Gaussian damping due to finite laser waist and laser amplitude fluctuations. Parametrized by
laser_waist
andamp_sigma
.SPAM: SPAM errors. Parametrized by
state_prep_error
,p_false_pos
andp_false_neg
.
- Parameters:
runs (int | None, default:
None
) – When reconstructing the Hamiltonian from random noise is necessary, this determines how many times that happens. Not to be confused with the number of times the resulting bitstring distribution is sampled when calculating bitstring counts.samples_per_run (int | None, default:
None
) – Number of samples per noisy Hamiltonian. Useful for cutting down on computing time, but unrealistic.state_prep_error (float | None, default:
None
) – The state preparation error probability.p_false_pos (float | None, default:
None
) – Probability of measuring a false positive.p_false_neg (float | None, default:
None
) – Probability of measuring a false negative.temperature (float | None, default:
None
) – Temperature, set in µK, of the atoms in the array. Also sets the standard deviation of the speed of the atoms.laser_waist (float | None, default:
None
) – Waist of the gaussian lasers, set in µm, for global pulses. Assumed to be the same for all global channels.amp_sigma (float | None, default:
None
) – Dictates the fluctuations in amplitude of global pulses from run to run as a standard deviation of a normal distribution centered in 1. Assumed to be the same for all global channels.relaxation_rate (float | None, default:
None
) – The rate of relaxation from the Rydberg to the ground state (in 1/µs). Corresponds to 1/T1.dephasing_rate (float | None, default:
None
) – The rate of a dephasing occuring (in 1/µs) in a Rydberg state superpostion. Only used if a Rydberg state is involved. Corresponds to 1/T2*.hyperfine_dephasing_rate (float | None, default:
None
) – The rate of dephasing occuring (in 1/µs) between hyperfine ground states. Only used if the hyperfine state is involved.depolarizing_rate (float | None, default:
None
) – The rate (in 1/µs) at which a depolarizing error occurs.eff_noise_rates (tuple[float, …], default:
()
) – The rate associated to each effective noise operator (in 1/µs).eff_noise_opers (tuple[ArrayLike, …], default:
()
) – The operators for the effective noise model.with_leakage (bool, default:
False
) – Whether or not to include an error state in the computations (default to False).
- to_abstract_repr()
Serializes the noise model into an abstract JSON object.
- Return type:
str
- static from_abstract_repr(obj_str)
Deserialize a noise model from an abstract JSON object.
- Parameters:
obj_str (str) – the JSON string representing the noise model encoded in the abstract JSON format.
- Return type:
Channels
Base Channel
Defines the Channel ABC.
- pulser.channels.base_channel.get_states_from_bases(bases)
The states associated to a list of bases, ranked by their energies.
- Return type:
list
[Literal
['u'
,'d'
,'r'
,'g'
,'h'
,'x'
]]
- class pulser.channels.base_channel.Channel(addressing, max_abs_detuning, max_amp, min_retarget_interval=None, fixed_retarget_t=None, max_targets=None, clock_period=1, min_duration=1, max_duration=100000000, min_avg_amp=0, mod_bandwidth=None, propagation_dir=None)
Base class of a hardware channel.
Not to be initialized itself, but rather through a child class and the
Local
orGlobal
classmethods.- Parameters:
addressing (Literal['Global', 'Local']) – “Local” or “Global”.
max_abs_detuning (Optional[float]) – Maximum possible detuning (in rad/µs), in absolute value.
max_amp (Optional[float]) – Maximum pulse amplitude (in rad/µs).
min_retarget_interval (Optional[int], default:
None
) – Minimum time required between the ends of two target instructions (in ns).fixed_retarget_t (Optional[int], default:
None
) – Time taken to change the target (in ns).max_targets (Optional[int], default:
None
) – How many qubits can be addressed at once by the same beam.clock_period (int, default:
1
) – The duration of a clock cycle (in ns). The duration of a pulse or delay instruction is enforced to be a multiple of the clock cycle.min_duration (int, default:
1
) – The shortest duration an instruction can take.max_duration (Optional[int], default:
100000000
) – The longest duration an instruction can take.min_avg_amp (float, default:
0
) – The minimum average amplitude of a pulse (when not zero).mod_bandwidth (Optional[float], default:
None
) – The modulation bandwidth at -3dB (50% reduction), in MHz.propagation_dir (tuple[float, float, float] | None, default:
None
) – The propagation direction of the beam associated with the channel, given as a vector in 3D space.
Example
To create a channel targeting the ‘ground-rydberg’ transition globally, call
Rydberg.Global(...)
.- property name
The name of the channel.
- abstract property basis
The addressed basis name.
- property eigenstates
The eigenstates associated with the basis.
Returns a tuple of labels, ranked in decreasing order of their associated eigenenergy, as such:
Name
Eigenstate (see Conventions)
Associated label
Up state
\(|0\rangle\)
"u"
Down state
\(|1\rangle\)
"d"
Rydberg state
\(|r\rangle\)
"r"
Ground state
\(|g\rangle\)
"g"
Hyperfine state
\(|h\rangle\)
"h"
Error state
\(|x\rangle\)
"x"
- property rise_time
The rise time (in ns).
Defined as the time taken to go from 10% to 90% output in response to a step change in the input.
- property phase_jump_time
Time taken to change the phase between consecutive pulses (in ns).
Corresponds to two times the rise time.
- is_virtual()
Whether the channel is virtual (i.e. partially defined).
- Return type:
bool
- supports_eom()
Whether the channel supports EOM mode operation.
- Return type:
bool
- classmethod Local(max_abs_detuning, max_amp, min_retarget_interval=0, fixed_retarget_t=0, max_targets=None, **kwargs)
Initializes the channel with local addressing.
- Parameters:
max_abs_detuning (
Optional
[float
]) – Maximum possible detuning (in rad/µs), in absolute value.max_amp (
Optional
[float
]) – Maximum pulse amplitude (in rad/µs).min_retarget_interval (
int
, default:0
) – Minimum time required between two target instructions (in ns).fixed_retarget_t (
int
, default:0
) – Time taken to change the target (in ns).max_targets (
Optional
[int
], default:None
) – Maximum number of atoms the channel can target simultaneously.
- Keyword Arguments:
clock_period (int, default=4) – The duration of a clock cycle (in ns). The duration of a pulse or delay instruction is enforced to be a multiple of the clock cycle.
min_duration (int, default=1) – The shortest duration an instruction can take.
max_duration (Optional[int], default=10000000) – The longest duration an instruction can take.
mod_bandwidth (Optional[float], default=None) – The modulation bandwidth at -3dB (50% reduction), in MHz.
min_avg_amp – The minimum average amplitude of a pulse (when not zero).
- Return type:
TypeVar
(ChannelType
, bound= Channel)
- classmethod Global(max_abs_detuning, max_amp, **kwargs)
Initializes the channel with global addressing.
- Parameters:
max_abs_detuning (
Optional
[float
]) – Maximum possible detuning (in rad/µs), in absolute value.max_amp (
Optional
[float
]) – Maximum pulse amplitude (in rad/µs).
- Keyword Arguments:
clock_period (int, default=4) – The duration of a clock cycle (in ns). The duration of a pulse or delay instruction is enforced to be a multiple of the clock cycle.
min_duration (int, default=1) – The shortest duration an instruction can take.
max_duration (Optional[int], default=10000000) – The longest duration an instruction can take.
mod_bandwidth (Optional[float], default=None) – The modulation bandwidth at -3dB (50% reduction), in MHz.
min_avg_amp – The minimum average amplitude of a pulse (when not zero).
propagation_dir – The propagation direction of the beam associated with the channel, given as a vector in 3D space.
- Return type:
TypeVar
(ChannelType
, bound= Channel)
- validate_duration(duration)
Validates and adapts the duration of an instruction on this channel.
- Parameters:
duration (
int
) – The duration to validate.- Return type:
int
- Returns:
The duration, potentially adapted to the channels specs.
- validate_pulse(pulse)
Checks if a pulse can be executed this channel.
- Parameters:
pulse (
Pulse
) – The pulse to validate.- Return type:
None
- modulate(input_samples, keep_ends=False, eom=False)
Modulates the input according to the channel’s modulation bandwidth.
- Parameters:
input_samples (
Union
[_SupportsArray
[dtype
[Any
]],_NestedSequence
[_SupportsArray
[dtype
[Any
]]],bool
,int
,float
,complex
,str
,bytes
,_NestedSequence
[Union
[bool
,int
,float
,complex
,str
,bytes
]]]) – The samples to modulate.keep_ends (
bool
, default:False
) – Assume the end values of the samples were kept constant (i.e. there is no ramp from zero on the ends).eom (
bool
, default:False
) – Whether to calculate the modulation using the EOM bandwidth.
- Return type:
AbstractArray
- Returns:
The modulated output signal.
- static apply_modulation(input_samples, mod_bandwidth)
Applies the modulation transfer fuction to the input samples.
- Return type:
AbstractArray
Note
This is strictly the application of the modulation transfer function. The samples should be padded beforehand.
- Parameters:
input_samples (
Union
[_SupportsArray
[dtype
[Any
]],_NestedSequence
[_SupportsArray
[dtype
[Any
]]],bool
,int
,float
,complex
,str
,bytes
,_NestedSequence
[Union
[bool
,int
,float
,complex
,str
,bytes
]]]) – The samples to modulate.mod_bandwidth (
float
) – The modulation bandwidth at -3dB (50% reduction), in MHz.
- calc_modulation_buffer(input_samples, mod_samples, max_allowed_diff=0.01, eom=False)
Calculates the minimal buffers needed around a modulated waveform.
- Parameters:
input_samples (
Union
[_SupportsArray
[dtype
[Any
]],_NestedSequence
[_SupportsArray
[dtype
[Any
]]],bool
,int
,float
,complex
,str
,bytes
,_NestedSequence
[Union
[bool
,int
,float
,complex
,str
,bytes
]]]) – The input samples.mod_samples (
Union
[_SupportsArray
[dtype
[Any
]],_NestedSequence
[_SupportsArray
[dtype
[Any
]]],bool
,int
,float
,complex
,str
,bytes
,_NestedSequence
[Union
[bool
,int
,float
,complex
,str
,bytes
]]]) – The modulated samples. Must be of sizelen(input_samples) + 2 * self.rise_time
.max_allowed_diff (
float
, default:0.01
) – The maximum allowed difference between the input and modulated samples at the end points.eom (
bool
, default:False
) – Whether to calculate the modulation buffers with the EOM bandwidth.
- Return type:
tuple
[int
,int
]- Returns:
The minimum buffer times at the start and end of the samples, in ns.
- default_id()
Generates the default ID for indexing this channel in a Device.
- Return type:
str
Available Channels
The Channel subclasses.
- class pulser.channels.channels.Raman(addressing, max_abs_detuning, max_amp, min_retarget_interval=None, fixed_retarget_t=None, max_targets=None, clock_period=1, min_duration=1, max_duration=100000000, min_avg_amp=0, mod_bandwidth=None, propagation_dir=None)
Bases:
Channel
Raman beam channel.
Channel targeting the transition between the hyperfine ground states, in which the ‘digital’ basis is encoded. See base class.
- property basis
The addressed basis name.
- class pulser.channels.channels.Rydberg(addressing, max_abs_detuning, max_amp, min_retarget_interval=None, fixed_retarget_t=None, max_targets=None, clock_period=1, min_duration=1, max_duration=100000000, min_avg_amp=0, mod_bandwidth=None, eom_config=None, propagation_dir=None)
Bases:
Channel
Rydberg beam channel.
Channel targeting the transition between the ground and rydberg states, thus encoding the ‘ground-rydberg’ basis. See base class.
- property basis
The addressed basis name.
- class pulser.channels.channels.Microwave(addressing, max_abs_detuning, max_amp, min_retarget_interval=None, fixed_retarget_t=None, max_targets=None, clock_period=1, min_duration=1, max_duration=100000000, min_avg_amp=0, mod_bandwidth=None, propagation_dir=None)
Bases:
Channel
Microwave adressing channel.
Channel targeting the transition between two rydberg states, thus encoding the ‘XY’ basis. See base class.
- property basis
The addressed basis name.
- default_id()
Generates the default ID for indexing this channel in a Device.
- Return type:
str
- class pulser.channels.dmm.DMM(clock_period=1, min_duration=1, max_duration=100000000, min_avg_amp=0, mod_bandwidth=None, propagation_dir=None, bottom_detuning=None, total_bottom_detuning=None)
Bases:
Channel
Defines a Detuning Map Modulator (DMM) Channel.
A Detuning Map Modulator can be used to define Global detuning Pulses (of zero amplitude and phase). These Pulses are locally modulated by the weights of a DetuningMap, thus providing a local control over the detuning. The detuning of the pulses added to a DMM has to be negative, between 0 and bottom_detuning, and the sum of the weights multiplied by that detuning has to be below total_bottom_detuning. Channel targeting the transition between the ground and rydberg states, thus encoding the ‘ground-rydberg’ basis.
Note
The protocol to add pulses to the DMM Channel is by default “no-delay”.
- Parameters:
bottom_detuning (float | None, default:
None
) – Minimum possible detuning per atom (in rad/µs), must be below zero.total_bottom_detuning (float | None, default:
None
) – Minimum possible detuning distributed on all atoms (in rad/µs), must be below zero.clock_period (int, default:
1
) – The duration of a clock cycle (in ns). The duration of a pulse or delay instruction is enforced to be a multiple of the clock cycle.min_duration (int, default:
1
) – The shortest duration an instruction can take.max_duration (Optional[int], default:
100000000
) – The longest duration an instruction can take.min_avg_amp (float, default:
0
) – The minimum average amplitude of a pulse (when not zero).mod_bandwidth (Optional[float], default:
None
) – The modulation bandwidth at -3dB (50% reduction), in MHz.
- property basis
The addressed basis name.
- is_virtual()
Whether the channel is virtual (i.e. partially defined).
- Return type:
bool
- validate_pulse(pulse, detuning_map=DetuningMap_9bac4c689e17c53052ff99b9305bfdc6be69a86f17e60e68f62375e7b5ef871a)
Checks if a pulse can be executed via this DMM on a DetuningMap.
- Parameters:
pulse (
Pulse
) – The pulse to validate.detuning_map (
DetuningMap
, default:DetuningMap_9bac4c689e17c53052ff99b9305bfdc6be69a86f17e60e68f62375e7b5ef871a
) – The detuning map on which the pulse is applied (defaults to a detuning map with weight 1.0).
- Return type:
None
EOM Mode Configuration
Configuration parameters for a channel’s EOM.
- class pulser.channels.eom.RydbergBeam(value)
Bases:
Flag
The beams that make up a Rydberg channel.
- class pulser.channels.eom.BaseEOM(mod_bandwidth, custom_buffer_time=None)
Bases:
_BaseEOMDefaults
,_BaseEOM
A base class for the EOM configuration.
- mod_bandwidth
The EOM modulation bandwidth at -3dB (50% reduction), in MHz.
- custom_buffer_time
A custom wait time to enforce during EOM buffers.
- Type:
int | None
- property rise_time
The rise time (in ns).
Defined as the time taken to go from 10% to 90% output in response to a step change in the input.
- class pulser.channels.eom.RydbergEOM(limiting_beam, max_limiting_amp, intermediate_detuning, controlled_beams, mod_bandwidth, custom_buffer_time=None, multiple_beam_control=True, blue_shift_coeff=1.0, red_shift_coeff=1.0)
Bases:
_RydbergEOMDefaults
,BaseEOM
,_RydbergEOM
The EOM configuration for a Rydberg channel.
- limiting_beam
The beam with the smallest amplitude range.
- max_limiting_amp
The maximum amplitude the limiting beam can reach, in rad/µs.
- intermediate_detuning
The detuning between the two beams, in rad/µs.
- controlled_beams
The beams that can be switched on/off with an EOM.
- mod_bandwidth
The EOM modulation bandwidth at -3dB (50% reduction), in MHz.
- custom_buffer_time
A custom wait time to enforce during EOM buffers.
- multiple_beam_control
Whether both EOMs can be used simultaneously. Ignored when only one beam can be controlled.
- Type:
bool
- blue_shift_coeff
The weight coefficient of the blue beam’s contribution to the lightshift.
- Type:
float
- red_shift_coeff
The weight coefficient of the red beam’s contribution to the lightshift.
- Type:
float
- calculate_detuning_off(amp_on, detuning_on, optimal_detuning_off, return_switching_beams=False)
Calculates the detuning when the amplitude is off in EOM mode.
- Parameters:
amp_on (float | pm.TensorLike) – The amplitude of the EOM pulses (in rad/µs).
detuning_on (float | pm.TensorLike) – The detuning of the EOM pulses (in rad/µs).
optimal_detuning_off (float) – The optimal value of detuning (in rad/µs) when there is no pulse being played. It will choose the closest value among the existing options.
return_switching_beams (bool, default:
False
) – Whether to return the beams that switch on on and off.
- Return type:
pm.AbstractArray | tuple[pm.AbstractArray, tuple[RydbergBeam, …]]
- detuning_off_options(rabi_frequency, detuning_on)
Calculates the possible detuning values when the amplitude is off.
- Parameters:
rabi_frequency (float | pm.TensorLike) – The Rabi frequency when executing a pulse, in rad/µs.
detuning_on (float | pm.TensorLike) – The detuning when executing a pulse, in rad/µs.
- Return type:
pm.AbstractArray
- Returns:
The possible detuning values when in between pulses.
Sampler
The main function for sequence sampling.
- pulser.sampler.sampler.sample(seq, modulation=False, extended_duration=None)
Construct samples of a Sequence.
- Parameters:
seq (
Sequence
) – The sequence to sample.modulation (
bool
, default:False
) – Whether to modulate the samples.extended_duration (
Optional
[int
], default:None
) – If defined, extends the samples duration to the desired value.
- Return type:
Dataclasses for storing and processing the samples.
- class pulser.sampler.samples.ChannelSamples(amp, det, phase, slots=<factory>, eom_blocks=<factory>, eom_start_buffers=<factory>, eom_end_buffers=<factory>, target_time_slots=<factory>, _centered_phase=None)
Gathers samples of a channel.
- property initial_targets
Returns the initial targets.
- property centered_phase
The phase samples centered in ]-π, π].
- property phase_modulation
The phase modulation samples (in rad).
Constructed by combining the integral of the detuning samples with the phase offset samples according to
\[\phi(t) = \phi_c(t) - \sum_{k=0}^{t} \delta(k)\]
- extend_duration(new_duration)
Extends the duration of the samples.
Pads the amplitude and detuning samples with zeros and the phase with its last value (or zero if empty).
- Parameters:
new_duration (
int
) – The new duration for the samples (in ns). Must be greater than or equal to the current duration.- Return type:
- Returns:
The extended channel samples.
- is_empty()
Whether the channel is effectively empty.
The channel is considered empty if all amplitude and detuning samples are zero.
- Return type:
bool
- get_eom_mode_intervals()
Returns EOM mode intervals.
- Return type:
list
[tuple
[int
,int
]]
- in_eom_mode(slot)
States if a time slot is inside an EOM mode block.
- Return type:
bool
- modulate(channel_obj, max_duration=None)
Modulates the samples for a given channel.
It assumes that the detuning and phase start at their initial values and are kept at their final values.
- Parameters:
channel_obj (
Channel
) – The channel object for which to modulate the samples.max_duration (
Optional
[int
], default:None
) – The maximum duration of the modulation samples. If defined, truncates them to have a duration less than or equal to the given value.
- Return type:
- Returns:
The modulated channel samples.
- class pulser.sampler.samples.DMMSamples(amp, det, phase, slots=<factory>, eom_blocks=<factory>, eom_start_buffers=<factory>, eom_end_buffers=<factory>, target_time_slots=<factory>, _centered_phase=None, detuning_map=None, qubits=<factory>)
Gathers samples of a DMM channel.
- class pulser.sampler.samples.SequenceSamples(channels, samples_list, _ch_objs, _basis_ref=<factory>, _slm_mask=<factory>, _magnetic_field=None, _measurement=None)
Gather samples for each channel in a sequence.
- property channel_samples
Mapping between the channel name and its samples.
- property max_duration
The maximum duration among the channel samples.
- property used_bases
The bases with non-zero pulses.
- property eigenbasis
The basis of eigenstates used for simulation.
- extend_duration(new_duration)
Extend the duration of each samples to a new duration.
- Return type:
- to_nested_dict(all_local=False, samples_type='array')
Format in the nested dictionary form.
This is the format expected by pulser_simulation.QutipEmulator().
- Parameters:
all_local (
bool
, default:False
) – Forces all samples to be distributed by their individual targets, even when applied by a global channel.samples_type (
Literal
['abstract'
,'array'
,'tensor'
], default:'array'
) – The array type to return the samples in. Can be “array” (the default), “tensor” or “abstract”.
- Return type:
dict
- Returns:
A nested dictionary splitting the samples according to their addressing (‘Global’ or ‘Local’), the targeted basis and, in the ‘Local’ case, the targeted qubit.
Result
Classes to store measurement results.
- class pulser.result.Result(atom_order, meas_basis)
Bases:
ABC
Base class for storing the result of a sequence run.
- property sampling_dist
Sampling distribution of the measured bitstring.
- Parameters:
atom_order – The order of the atoms in the bitstrings that represent the measured states.
meas_basis – The measurement basis.
- abstract property sampling_errors
The sampling error associated to each bitstring’s sampling rate.
Uses the standard error of the mean as a quantifier for sampling error.
- get_samples(n_samples)
Takes multiple samples from the sampling distribution.
- Parameters:
n_samples (
int
) – Number of samples to return.- Return type:
Counter
[str
]- Returns:
Samples of bitstrings corresponding to measured quantum states.
- get_state()
Gets the quantum state associated with the result.
Can only be defined for emulation results that don’t resort to sampling a quantum state (which is the case for certain types of noise).
- Return type:
Any
- plot_histogram(min_rate=0.001, max_n_bitstrings=None, show=True)
Plots the result in an histogram.
- Parameters:
min_rate (float, default:
0.001
) – The minimum sampling rate a bitstring must have to be displayed.max_n_bitstrings (int | None, default:
None
) – An optional limit on the number of bitrstrings displayed.show (bool, default:
True
) – Whether or not to call plt.show() before returning.
- Return type:
None
- class pulser.result.SampledResult(atom_order, meas_basis, bitstring_counts)
Bases:
Result
Represents the result of a run from a series of samples.
- Parameters:
atom_order (
tuple
[Union
[int
,str
],...
]) – The order of the atoms in the bitstrings that represent the measured states.meas_basis (
str
) – The measurement basis.bitstring_counts (
dict
[str
,int
]) – The number of times each bitstring was measured.
- property sampling_errors
The sampling error associated to each bitstring’s sampling rate.
Uses the standard error of the mean as a quantifier for sampling error.
- class pulser.result.Results
Bases:
Sequence
[ResultType
]An immutable sequence of results.