silq.pulses package¶
Submodules¶
silq.pulses.pulse_modules module¶
-
class
silq.pulses.pulse_modules.
PulseRequirement
(property, requirement)[source]¶ Bases:
object
Pulse
attribute requirement for aPulseImplementation
This class is used in Interfaces when registering a
PulseImplementation
, to impose additional constraints for implementing the pulse.The class is never directly instantiated, but is instead created from a dict passed to the
pulse_requirements
kwarg of aPulseImplementation
.Example
For an AWG can apply sine pulses, but only up to its Nyquist limit
max_frequency
, the following implementation is used:>>> SinePulseImplementation( pulse_requirements=[('frequency', {'max': max_frequency})])
- Parameters
-
verify_requirement
(requirement)[source]¶ Verifies that the requirement is valid.
A valid requirement is either a list, or a dict with keys
min
and/ormax
.- Raises
AssertionError – Requirement is not valid.
-
class
silq.pulses.pulse_modules.
PulseSequence
(pulses=None, allow_untargeted_pulses=True, allow_targeted_pulses=True, allow_pulse_overlap=True, final_delay=None)[source]¶ Bases:
qcodes.instrument.parameter_node.ParameterNode
Pulse
container that can be targeted in theLayout
.It can be used to store untargeted or targeted pulses.
If multiple pulses with the same name are added,
Pulse
.id is set for the pulses sharing the same name, starting with 0 for the first pulse.- Retrieving pulses
To retrieve a pulse with name ‘read’:
>>> pulse_sequence['read'] >>> pulse_sequence.get_pulse(name='read')
Both methods work, but the latter is more versatile, as it also allows filtering of pulses by discriminants other than name.
If there are multiple pulses with the same name, the methods above will raise an error because there is no unique pulse with name
read
. Instead, thePulse
.id must also be passed to discriminate the pulses:>>> pulse_sequence['read[0]'] >>> pulse_sequence.get_pulse(name='read', id=0)
Both methods return the first pulse added whose name is ‘read’.
- Iterating over pulses
Pulses in a pulse sequence can be iterated over via:
>>> for pulse in pulse_sequence: >>> # perform actions
This will return the pulses sorted by
Pulse
.t_start. Pulses for whichPulse
.enabled is False are ignored.- Checking if pulse sequence contains a pulse
Pulse sequences can be treated similar to a list, and so checking if a pulse exists in a list is done as such:
>>> pulse in pulse_sequence
Note that this does not compare object equality, but only checks if all attributes match.
- Checking if a pulse sequence contains pulses
Checking if a pulse sequence contains pulses is similar to a list:
>>> if pulse_sequence: >>> # pulse_sequence contains pulses
- Targeting a pulse sequence in the `Layout`
A pulse sequence can be targeted in the layout, which will distribute the pulses among it’s
InstrumentInterface
such that the pulse sequence is executed. Targeting of a pulse sequence is straightforward:>>> layout.pulse_sequence = pulse_sequence
After this, the instruments can be configured via
Layout.setup
.
- Parameters
pulses (List[Pulse]) –
Pulse
list to place in PulseSequence. Pulses can also be added later usingPulseSequence.add
.allow_untargeted_pulses (bool) – Allow untargeted pulses (without corresponding
Pulse
.implementation) to be added to PulseSequence.InstrumentInterface
.pulse_sequence should have this unchecked.allow_targeted_pulses (bool) – Allow targeted pulses (with corresponding
Pulse
.implementation) to be added to PulseSequence.InstrumentInterface
.pulse_sequence should have this checked.allow_pulse_overlap (bool) – Allow pulses to overlap in time. If False, an error will be raised if a pulse is added that overlaps in time. If pulse has a
Pulse
.connection, an error is only raised if connections match as well.duration (float) – Total duration of pulse sequence. Equal to
Pulse
.t_stop of last pulse, unless explicitly set. Can be reset to t_stop of last pulse by setting to None, and will automatically be reset every time a pulse is added/removed.final_delay (Union[float, None]) – Optional final delay at the end of the pulse sequence. The interface of the primary instrument should incorporate any final delay. The default is .5 ms
enabled_pulses (List[Pulse]) –
Pulse
list withPulse
.enabled True. Updated when a pulse is added orPulse
.enabled is changed.disabled_pulses (List[Pulse]) – Pulse list with
Pulse
.enabled False. Updated when a pulse is added orPulse
.enabled is changed.t_start_list (List[float]) –
Pulse
.t_start list for all enabled pulses. Can contain duplicates if pulses share the samePulse
.t_start.t_stop_list (List[float]) –
Pulse
.t_stop list for all enabled pulses. Can contain duplicates if pulses share the samePulse
.t_stop.t_list (List[float]) – Combined list of
Pulse
.t_start andPulse
.t_stop for all enabled pulses. Does not contain duplicates.
Notes
If pulses are added without
Pulse
.t_start defined, the pulse is assumed to start after the last pulse finishes, and a connection is made with the attributet_stop
of the last pulse, such that if the last pulse t_stop changes, t_start is changed accordingly.All pulses in the pulse sequence are listened to via
Pulse
.signal. Any time an attribute of a pulse changes, a signal will be emitted, which can then be interpreted by the pulse sequence.
-
add
(*pulses, reset_duration=True)[source]¶ Adds pulse(s) to the PulseSequence.
- Parameters
- Returns
Added pulses, which are copies of the original pulses.
- Return type
List[Pulse]
- Raises
AssertionError – The added pulse overlaps with another pulses and
PulseSequence
.allow_pulses_overlap is FalseAssertionError – The added pulse is untargeted and
PulseSequence
.allow_untargeted_pulses is FalseAssertionError – The added pulse is targeted and
PulseSequence
.allow_targeted_pulses is FalseValueError – If a pulse has no duration
Note
When a pulse is added, it is first copied, to ensure that the original pulse remains unmodified. For an speed-optimized version, see
PulseSequence.quick_add
-
connection_conditions
= None¶
-
default_final_delay
= 0.0005¶
-
finish_quick_add
()[source]¶ Finish adding pulses via
PulseSequence.quick_add
Steps performed:
Sorting of pulses
Checking that pulses do not overlap
Adding unique id’s to pulses in case a name is shared by pulses
-
get_connection
(**conditions)[source]¶ Get unique connections from any pulse satisfying conditions.
- Parameters
**conditions – Connection and pulse conditions.
- Returns
Unique Connection satisfying conditions
- Return type
Connection
See also
Pulse.satisfies_conditions
,Connection.satisfies_conditions
.- Raises
AssertionError – No unique connection satisfying conditions.
-
get_pulse
(**conditions)[source]¶ Get unique pulse in pulse sequence satisfying conditions.
- Parameters
**conditions – Connection and pulse conditions.
- Returns
Unique pulse satisfying conditions
- Return type
See also
Pulse.satisfies_conditions
,Connection.satisfies_conditions
.- Raises
RuntimeError – No unique pulse satisfying conditions
-
get_pulses
(enabled=True, connection=None, connection_label=None, **conditions)[source]¶ Get list of pulses in pulse sequence satisfying conditions
- Parameters
enabled – Pulse must be enabled
connection – pulse must have connection
**conditions – Additional connection and pulse conditions.
- Returns
Pulses satisfying conditions
- Return type
List[Pulse]
See also
Pulse.satisfies_conditions
,Connection.satisfies_conditions
.
-
get_trace_shapes
(sample_rate, samples)[source]¶ Get dictionary of trace shapes for given sample rate and samples
- Parameters
- Returns
{
Pulse
.full_name: trace_shape}- Return type
Note
trace shape depends on
Pulse
.average
-
get_transition_voltages
(pulse=None, connection=None, t=None)[source]¶ Finds the voltages at the transition between two pulses.
Note
This method can potentially cause issues, and should be avoided until it’s better thought through
- Parameters
- Return type
- Returns
(Voltage before transition, voltage after transition)
-
plot
(t_range=None, points=2001, subplots=False, scale_ylim=True, figsize=None, legend=True, **connection_kwargs)[source]¶
-
pulse_conditions
= None¶
-
static
pulses_overlap
(pulse1, pulse2)[source]¶ Tests if pulse1 and pulse2 overlap in time and connection.
- Parameters
- Return type
- Returns
True if pulses overlap
Note
If either of the pulses does not have a connection, this is not tested.
-
quick_add
(*pulses, copy=True, connect=True, reset_duration=True)[source]¶ “Quickly add pulses to a sequence skipping steps and checks.
This method is used in the during the
Layout
targeting of a pulse sequence, and should generally only be used if speed is a crucial factor.Note
When using this method, make sure to finish adding pulses with
PulseSequence.finish_quick_add
.The following steps are skipped and are performed in
PulseSequence.finish_quick_add
:Assigning a unique pulse id if multiple pulses share the same name
Sorting pulses
Ensuring no pulses overlapped
- Parameters
- Returns
Added pulses. If copy is False, the original pulses are returned.
Note
If copy is False, the id of original pulses may be set when calling
PulseSequence.quick_add
.
-
remove
(*pulses)[source]¶ Removes
Pulse
or pulses from pulse sequence- Parameters
pulses – Pulse(s) to remove from PulseSequence
- Raises
AssertionError – No unique pulse found
-
snapshot_base
(update=False, params_to_skip_update=[])[source]¶ State of the pulse sequence as a JSON-compatible dict.
- Parameters
update (bool) – If True, update the state by querying the instrument. If False, just use the latest values in memory.
params_to_skip_update (
Sequence
[str
]) – List of parameter names that will be skipped in update even if update is True. This is useful if you have parameters that are slow to update but can be updated in a different way (as in the qdac)
- Returns
base snapshot
- Return type
-
up_to_date
()[source]¶ Checks if a pulse sequence is up to date or needs to be generated.
Used by
PulseSequenceGenerator
.- Return type
- Returns
True by default, can be overridden in subclass.
-
class
silq.pulses.pulse_modules.
PulseImplementation
(pulse_requirements=[])[source]¶ Bases:
object
InstrumentInterface
implementation for aPulse
.Each
InstrumentInterface
should have corresponding pulse implementations for the pulses it can output. These should be subclasses of thePulseImplementation
.When a
PulseSequence
is targeted in the Layout, eachPulse
is directed to the relevantInstrumentInterface
, which will call target the pulse using the corresponding PulseImplementation. DuringPulse
targeting, a copy of the pulse is made, and the PulseImplementation is added toPulse
.implementation.- Creating a PulseImplementation
A PulseImplementation is specific for a certain
Pulse
, which should be defined inPulseImplementation
.pulse_class.A
PulseImplementation
subclass may override the following methods:
- Parameters
pulse_requirements – Requirements that pulses must satisfy to allow implementation.
-
add_pulse_requirement
(property, requirement)[source]¶ Add requirement that any pulse must satisfy to be targeted
-
get_additional_pulses
(interface)[source]¶ Provide any additional pulses needed such as triggering pulses
The additional pulses can be requested should usually have
Pulse
.connection_conditions specified to ensure that the pulse is sent to the right connection.- Parameters
interface (InstrumentInterface) – Interface to which this PulseImplementation belongs
- Returns
List of additional pulses needed.
- Return type
List[Pulse]
-
implement
(*args, **kwargs)[source]¶ Implements a targeted pulse for an InstrumentInterface.
This method is called during
InstrumentInterface.setup
.Implementation of a targeted pulse is very dependent on the interface. For an AWG, this method may return a list of waveform points. For a triggering source, this method may return the triggering time. In very simple cases, this method may not even be necessary.
- Parameters
*args – Interface-specific args to use
**kwargs – Interface-specific kwargs to use
- Return type
- Returns
Instrument-specific return values.
See also
Other interface source codes may serve as a guide for this method.
-
pulse_class
= None¶
-
pulse_config
= None¶
-
satisfies_requirements
(pulse, match_class=True)[source]¶ Checks if a pulse satisfies pulse requirements
- Parameters
pulse (Pulse) – Pulse that is checked
match_class (
bool
) – Pulse class must matchPulseImplementation
.pulse_class
-
target_pulse
(pulse, interface, connections, **kwargs)[source]¶ Tailors a PulseImplementation to a specific pulse.
Targeting happens in three stages:
Both the pulse and pulse implementation are copied.
PulseImplementation
of the copied pulse is set to the copied pulse implementation, andPulseImplementation
.pulse is set to the copied pulse. This way, they can both reference each other.The targeted pulse is returned
- Parameters
pulse (Pulse) – Pulse to be targeted.
interface (InstrumentInterface) – PulseImplementation belongs.
connections (List[Connection]) – All connections in
Layout
.**kwargs – Additional unused kwargs
- Raises
TypeError – Pulse class does not match
PulseImplementation
.pulse_class
silq.pulses.pulse_sequences module¶
-
class
silq.pulses.pulse_sequences.
ESRPulseSequence
(**kwargs)[source]¶ Bases:
silq.pulses.pulse_sequences.PulseSequenceGenerator
PulseSequenceGenerator
for electron spin resonance (ESR).This pulse sequence can handle many of the basic pulse sequences involving ESR. The pulse sequence is generated from its pulse settings attributes.
In general the pulse sequence is as follows:
Perform any pre_pulses defined in
ESRPulseSequence.pre_pulses
.Perform stage pulse
ESRPulseSequence.ESR['stage_pulse']
. By default, this is theplunge
pulse.Perform ESR pulse within plunge pulse, the delay from start of plunge pulse is defined in
ESRPulseSequence.ESR['pulse_delay']
.Perform read pulse
ESRPulseSequence.ESR['read_pulse']
.Repeat steps 2 and 3 for each ESR pulse in
ESRPulseSequence.ESR['ESR_pulses']
, which by default contains single pulseESRPulseSequence.ESR['ESR_pulse']
.Perform empty-plunge-read sequence (EPR), but only if
ESRPulseSequence.EPR['enabled']
is True. EPR pulses are defined inESRPulseSequence.EPR['pulses']
.Perform any post_pulses defined in
ESRPulseSequence.post_pulses
.
- Parameters
ESR (dict) –
Pulse settings for the ESR part of the pulse sequence. Contains the following items:
stage_pulse
(Pulse): Stage pulse in which to perform ESR (e.g. plunge). Default is ‘plungeDCPulse
.ESR_pulse
(Pulse): Default ESR pulse to use. Default is ‘ESR’SinePulse
.ESR_pulses
(List[Union[str, Pulse]]): List of ESR pulses to use. Can be strings, in which case the string should be an item inESR
whose value is aPulse
.pulse_delay
(float): ESR pulse delay after beginning of stage pulse. Default is 5 ms.read_pulse
(Pulse): Pulse after stage pulse for readout and initialization of electron. Default is ‘read_initialize`DCPulse
.
EPR (dict) –
Pulse settings for the empty-plunge-read (EPR) part of the pulse sequence. This part is optional, and is used for non-ESR contast, and to measure dark counts and hence ESR contrast. Contains the following items:
enabled
(bool): Enable EPR sequence.pulses
(List[Pulse]): List of pulses for EPR sequence. Default isempty
,plunge
,read_long
DCPulse
.
pre_pulses (List[Pulse]) – Pulses before main pulse sequence. Empty by default.
post_pulses (List[Pulse]) – Pulses after main pulse sequence. Empty by default.
pulse_settings (dict) – Dict containing all pulse settings.
**kwargs – Additional kwargs to
PulseSequence
.
Examples
The following code measures two ESR frequencies and performs an EPR from which the contrast can be determined for each ESR frequency:
>>> ESR_pulse_sequence = ESRPulseSequence() >>> ESR_pulse_sequence.ESR['pulse_delay'] = 5e-3 >>> ESR_pulse_sequence.ESR['stage_pulse'] = DCPulse['plunge'] >>> ESR_pulse_sequence.ESR['ESR_pulse'] = FrequencyRampPulse('ESR_adiabatic') >>> ESR_pulse_sequence.ESR_frequencies = [39e9, 39.1e9] >>> ESR_pulse_sequence.EPR['enabled'] = True >>> ESR_pulse_sequence.pulse_sequence.generate()
The total pulse sequence is plunge-read-plunge-read-empty-plunge-read with an ESR pulse in the first two plunge pulses, 5 ms after the start of the plunge pulse. The ESR pulses have different frequencies.
Notes
For given pulse settings,
ESRPulseSequence.generate
will recreate the pulse sequence from settings.-
property
ESR_frequencies
¶
-
add_ESR_pulses
(ESR_frequencies=None)[source]¶ Add ESR pulses to the pulse sequence
- Parameters
ESR_frequencies – List of ESR frequencies. If provided, the pulses in ESR[‘ESR_pulses’] will be reset to copies of ESR[‘ESR_pulse’] with the provided frequencies
Note
Each element in ESR_frequencies can also be a list of multiple frequencies, in which case multiple pulses with the provided subfrequencies will be used.
-
class
silq.pulses.pulse_sequences.
ESRRamseyDetuningPulseSequence
(**kwargs)[source]¶ Bases:
silq.pulses.pulse_sequences.ESRPulseSequence
” Created to implement an arbitrary number of DC pulses in a Ramsey sequence during the wait time. Please Refer to ESRPulseSequence for the ESR pulses.
Highlights:
DC pulses can be stored in [‘ESR’][‘detuning_pulses’] and will become the new ‘stage_pulse’
t_start_detuning is the time at which the DC detuning pulses start. In the case the detuning starts right after the ESR pi/2 , then this time should
be equal to [‘pre_delay’] +ESR[‘piHalf’].duration
If the time for the detuning pulses is shorter that the total stage duration, the final part of the pulse (called post_stage) will the standard stage pulse
-
add_ESR_pulses
(ESR_frequencies=None)[source]¶ Add ESR pulses to the pulse sequence
- Parameters
ESR_frequencies – List of ESR frequencies. If provided, the pulses in ESR[‘ESR_pulses’] will be reset to copies of ESR[‘ESR_pulse’] with the provided frequencies
Note
Each element in ESR_frequencies can also be a list of multiple frequencies, in which case multiple pulses with the provided subfrequencies will be used.
-
class
silq.pulses.pulse_sequences.
FlipFlopPulseSequence
(**kwargs)[source]¶ Bases:
silq.pulses.pulse_sequences.PulseSequenceGenerator
PulseSequenceGenerator
for hitting the flip-flop transitionThe flip-flop transition is the one where both the electron and nucleus flip in opposite direction, thus keeping the total spin constant.
This pulse sequence is mainly used to flip the nucleus to a certain state without having to perform NMR or even having to measure the electron.
The flip-flop transitions between a nuclear spin state S1 and (S1+1) is:
f_ESR(S1) + A/2 + gamma_n * B_0,
where f_ESR(S1) is the ESR frequency for nuclear state S1, A is the hyperfine, gamma_n is the nuclear Zeeman, and B_0 is the static magnetic field. The transition will flip (electron down, nucleus S+1) to (electron up, nucleus S) and vice versa.
- Parameters
ESR (dict) –
Pulse settings for the ESR part of the pulse sequence. Contains the following items:
frequency
(float): ESR frequency below the flip-flop transition (Hz).hyperfine
(float): Hyperfine interaction (Hz).nuclear_zeeman
(float): Nuclear zeeman strength (gamma_n*B_0)stage_pulse
(Pulse): Stage pulse in which to perform ESR (e.g. plunge). Default is `DCPulse`(‘plunge’).pre_flip_ESR_pulse
(Pulse): ESR pulse to use before the flip-flop pulse to pre-flip the electron to spin-up, which allows the nucleus to be flipped to a higher state. Default is `SinePulse`(‘ESR’).flip_flop_pulse
(Pulse): Flip-flop ESR pulse, whose frequency will be set to A/2 + gamma_n*B_0 higher than thefrequency
setting. Default pulse is `SinePulse`(‘ESR’)pre_flip
(bool): Whether to pre-flip the electron, to transition to a higher nuclear state. Default is False.pre_delay
(float): Delay between start of stage pulse and first pulse (pre_flip_ESR_pulse
orflip_flop_pulse
).inter_delay
(float): Delay betweenpre_flip_ESR_pulse
andflip_flop_pulse
. Ignored if pre_flip is Falsepost_delay
(float): Delay after last frequency pulse and end of stage pulse.
pre_pulses (List[Pulse]) – Pulses before main pulse sequence. Empty by default.
post_pulses (List[Pulse]) – Pulses after main pulse sequence. Empty by default.
pulse_settings (dict) – Dict containing all pulse settings.
**kwargs – Additional kwargs to
PulseSequence
.
-
class
silq.pulses.pulse_sequences.
NMRCPMGPulseSequence
(pulses=[], **kwargs)[source]¶ Bases:
silq.pulses.pulse_sequences.NMRPulseSequence
PulseSequenceGenerator
for nuclear magnetic resonance (NMR).This pulse sequence can handle many of the basic pulse sequences involving NMR. The pulse sequence is generated from its pulse settings attributes.
In general, the pulse sequence is as follows:
Perform any pre_pulses defined in
NMRPulseSequence.pre_pulses
.Perform NMR sequence
Perform stage pulse
NMRPulseSequence.NMR['stage_pulse']
. Default is ‘empty’DCPulse
.Perform NMR pulses within the stage pulse. The NMR pulses defined in
NMRPulseSequence.NMR['NMR_pulses']
are applied successively. The delay after start of the stage pulse isNMRPulseSequence.NMR['pre_delay']
, delays between NMR pulses isNMRPulseSequence.NMR['inter_delay']
, and the delay after the final NMR pulse isNMRPulseSequence.NMR['post_delay']
.
Perform ESR sequence
Perform stage pulse
NMRPulseSequence.ESR['stage_pulse']
. Default is ‘plunge’DCPulse
.Perform ESR pulse within stage pulse for first pulse in
NMRPulseSequence.ESR['ESR_pulses']
.Perform
NMRPulseSequence.ESR['read_pulse']
, and acquire trace.Repeat steps 1 - 3 for each ESR pulse. The different ESR pulses usually correspond to different ESR frequencies (see
NMRPulseSequence
.ESR_frequencies).Repeat steps 1 - 4 for
NMRPulseSequence.ESR['shots_per_frequency']
This effectively interleaves the ESR pulses, which counters effects of the nucleus flipping within an acquisition.
By measuring the average up proportion for each ESR frequency, a switching between high and low up proportion indicates a flipping of the nucleus
- Parameters
NMR (dict) –
Pulse settings for the NMR part of the pulse sequence. Contains the following items:
stage_pulse
(Pulse): Stage pulse in which to perform NMR (e.g. plunge). Default is ‘empty’DCPulse
. Duration of stage pulse is adapted to NMR pulses and delays.NMR_pulse
(Pulse): Default NMR pulse to use. By default ‘NMR’SinePulse
.NMR_pulses
(List[Union[str, Pulse]]): List of NMR pulses to successively apply. Can be strings, in which case the string should be an item inNMR
whose value is aPulse
. Default is single elementNMRPulseSequence.NMR['NMR_pulse']
.pre_delay
(float): Delay after start ofstage
pulse, until first NMR pulse.inter_delay
(float): Delay between successive NMR pulses.post_delay
(float): Delay after final NMR pulse until stage pulse end.
ESR (dict) –
Pulse settings for the ESR part of the pulse sequence. Contains the following items:
stage_pulse
(Pulse): Stage pulse in which to perform ESR (e.g. plunge). Default is ‘plungeDCPulse
.ESR_pulse
(Pulse): Default ESR pulse to use. Default is ‘ESR’SinePulse
.ESR_pulses
(List[Union[str, Pulse]]): List of ESR pulses to use. Can be strings, in which case the string should be an item inESR
whose value is aPulse
.pulse_delay
(float): ESR pulse delay after beginning of stage pulse. Default is 5 ms.read_pulse
(Pulse): Pulse after stage pulse for readout and initialization of electron. Default is ‘read_initialize`DCPulse
.
EPR (dict) –
Pulse settings for the empty-plunge-read (EPR) part of the pulse sequence. This part is optional, and is used for non-ESR contast, and to measure dark counts and hence ESR contrast. Contains the following items:
enabled
(bool): Enable EPR sequence.pulses
(List[Pulse]): List of pulses for EPR sequence. Default isempty
,plunge
,read_long
DCPulse
.
pre_pulses (List[Pulse]) – Pulses before main pulse sequence. Empty by default.
pre_ESR_pulses (List[Pulse]) – Pulses before ESR readout pulse sequence. Empty by default.
post_pulses (List[Pulse]) – Pulses after main pulse sequence. Empty by default.
pulse_settings (dict) – Dict containing all pulse settings.
**kwargs – Additional kwargs to
PulseSequence
.
See also
NMRParameter
Notes
For given pulse settings,
NMRPulseSequence.generate
will recreate the pulse sequence from settings.
-
class
silq.pulses.pulse_sequences.
NMRPulseSequence
(pulses=[], **kwargs)[source]¶ Bases:
silq.pulses.pulse_sequences.PulseSequenceGenerator
PulseSequenceGenerator
for nuclear magnetic resonance (NMR).This pulse sequence can handle many of the basic pulse sequences involving NMR. The pulse sequence is generated from its pulse settings attributes.
In general, the pulse sequence is as follows:
Perform any pre_pulses defined in
NMRPulseSequence.pre_pulses
.Perform NMR sequence
Perform stage pulse
NMRPulseSequence.NMR['stage_pulse']
. Default is ‘empty’DCPulse
.Perform NMR pulses within the stage pulse. The NMR pulses defined in
NMRPulseSequence.NMR['NMR_pulses']
are applied successively. The delay after start of the stage pulse isNMRPulseSequence.NMR['pre_delay']
, delays between NMR pulses isNMRPulseSequence.NMR['inter_delay']
, and the delay after the final NMR pulse isNMRPulseSequence.NMR['post_delay']
.
Perform ESR sequence
Perform stage pulse
NMRPulseSequence.ESR['stage_pulse']
. Default is ‘plunge’DCPulse
.Perform ESR pulse within stage pulse for first pulse in
NMRPulseSequence.ESR['ESR_pulses']
.Perform
NMRPulseSequence.ESR['read_pulse']
, and acquire trace.Repeat steps 1 - 3 for each ESR pulse. The different ESR pulses usually correspond to different ESR frequencies (see
NMRPulseSequence
.ESR_frequencies).Repeat steps 1 - 4 for
NMRPulseSequence.ESR['shots_per_frequency']
This effectively interleaves the ESR pulses, which counters effects of the nucleus flipping within an acquisition.
By measuring the average up proportion for each ESR frequency, a switching between high and low up proportion indicates a flipping of the nucleus
- Parameters
NMR (dict) –
Pulse settings for the NMR part of the pulse sequence. Contains the following items:
stage_pulse
(Pulse): Stage pulse in which to perform NMR (e.g. plunge). Default is ‘empty’DCPulse
. Duration of stage pulse is adapted to NMR pulses and delays.NMR_pulse
(Pulse): Default NMR pulse to use. By default ‘NMR’SinePulse
.NMR_pulses
(List[Union[str, Pulse]]): List of NMR pulses to successively apply. Can be strings, in which case the string should be an item inNMR
whose value is aPulse
. Default is single elementNMRPulseSequence.NMR['NMR_pulse']
.pre_delay
(float): Delay after start ofstage
pulse, until first NMR pulse.inter_delay
(float): Delay between successive NMR pulses.post_delay
(float): Delay after final NMR pulse until stage pulse end.
ESR (dict) –
Pulse settings for the ESR part of the pulse sequence. Contains the following items:
stage_pulse
(Pulse): Stage pulse in which to perform ESR (e.g. plunge). Default is ‘plungeDCPulse
.ESR_pulse
(Pulse): Default ESR pulse to use. Default is ‘ESR’SinePulse
.ESR_pulses
(List[Union[str, Pulse]]): List of ESR pulses to use. Can be strings, in which case the string should be an item inESR
whose value is aPulse
.pulse_delay
(float): ESR pulse delay after beginning of stage pulse. Default is 5 ms.read_pulse
(Pulse): Pulse after stage pulse for readout and initialization of electron. Default is ‘read_initialize`DCPulse
.
EPR (dict) –
Pulse settings for the empty-plunge-read (EPR) part of the pulse sequence. This part is optional, and is used for non-ESR contast, and to measure dark counts and hence ESR contrast. Contains the following items:
enabled
(bool): Enable EPR sequence.pulses
(List[Pulse]): List of pulses for EPR sequence. Default isempty
,plunge
,read_long
DCPulse
.
pre_pulses (List[Pulse]) – Pulses before main pulse sequence. Empty by default.
pre_ESR_pulses (List[Pulse]) – Pulses before ESR readout pulse sequence. Empty by default.
post_pulses (List[Pulse]) – Pulses after main pulse sequence. Empty by default.
pulse_settings (dict) – Dict containing all pulse settings.
**kwargs – Additional kwargs to
PulseSequence
.
See also
NMRParameter
Notes
For given pulse settings,
NMRPulseSequence.generate
will recreate the pulse sequence from settings.
-
class
silq.pulses.pulse_sequences.
PulseSequenceGenerator
(pulses=[], **kwargs)[source]¶ Bases:
silq.pulses.pulse_modules.PulseSequence
Base class for a
PulseSequence
that is generated from settings.-
up_to_date
()[source]¶ Checks if a pulse sequence is up to date or needs to be generated.
Used by
PulseSequenceGenerator
.- Returns
True by default, can be overridden in subclass.
-
-
class
silq.pulses.pulse_sequences.
T2ElectronPulseSequence
(**kwargs)[source]¶ Bases:
silq.pulses.pulse_sequences.PulseSequenceGenerator
PulseSequenceGenerator
for electron coherence (T2) measurements.This pulse sequence can handle measurements on the electron coherence time, including adding refocusing pulses
In general the pulse sequence is as follows:
Perform any pre_pulses defined in
T2ElectronPulseSequence.pre_pulses
.Perform stage pulse
T2ElectronPulseSequence.ESR['stage_pulse']
. By default, this is theplunge
pulse.Perform initial ESR pulse
T2ElectronPulseSequence.ESR['ESR_initial_pulse']
within plunge pulse, the delay until start of the ESR pulse is defined inT2ElectronPulseSequence.ESR['pre_delay']
.For
T2ElectronPulseSequence.ESR['num_refocusing_pulses']
times, wait forT2ElectronPulseSequence.ESR['inter_delay']` and apply ``T2ElectronPulseSequence.ESR['ESR_refocusing_pulse]
.Wait
T2ElectronPulseSequence.ESR['ESR_refocusing_pulse']
and applyT2ElectronPulseSequence.ESR['ESR_final_pulse']
.Wait
T2ElectronPulseSequence.ESR['post_delay']
, then stop stage pulse and Perform read pulseT2ElectronPulseSequence.ESR['read_pulse']
.Perform empty-plunge-read sequence (EPR), but only if
T2ElectronPulseSequence.EPR['enabled']
is True. EPR pulses are defined inT2ElectronPulseSequence.EPR['pulses']
.Perform any post_pulses defined in
ESRPulseSequence.post_pulses
.
- Parameters
ESR (dict) –
Pulse settings for the ESR part of the pulse sequence. Contains the following items:
- stage_pulse (Pulse)
Stage pulse in which to perform ESR (e.g. plunge). Default is ‘plunge
DCPulse
.- ESR_initial_pulse (Pulse)
Initial ESR pulse to apply within stage pulse. Default is
ESR_piHalf
SinePulse
. Ignored if set toNone
- ESR_refocusing_pulse (Pulse)
Refocusing ESR pulses between initial and final ESR pulse. Zero refocusing pulses measures T2star, one refocusing pulse measures T2Echo. Default is
ESR_pi
SinePulse
.- ESR_final_pulse (Pulse)
Final ESR pulse within stage pulse. Default is
ESR_piHalf
SinePulse
. Ignored if set toNone
.- num_refocusing_pulses (int)
Number of refocusing pulses
T2ElectronPulseSequence.ESR['ESR_refocusing_pulse']
to apply.- pre_delay (float)
Delay after stage pulse before first ESR pulse.
- inter_delay (float)
Delay between successive ESR pulses.
- post_delay (float)
Delay after final ESR pulse.
- read_pulse (Pulse)
Pulse after stage pulse for readout and initialization of electron. Default is ‘read_initialize`
DCPulse
.
EPR (dict) –
Pulse settings for the empty-plunge-read (EPR) part of the pulse sequence. This part is optional, and is used for non-ESR contast, and to measure dark counts and hence ESR contrast. Contains the following items:
- enabled
(bool): Enable EPR sequence.
- pulses
(List[Pulse]): List of pulses for EPR sequence. Default is
empty
,plunge
,read_long
DCPulse
.
pre_pulses (List[Pulse]) – Pulses before main pulse sequence. Empty by default.
post_pulses (List[Pulse]) – Pulses after main pulse sequence. Empty by default.
pulse_settings (dict) – Dict containing all pulse settings.
**kwargs – Additional kwargs to
PulseSequence
.
Notes
For given pulse settings,
T2ElectronPulseSequence.generate
will recreate the pulse sequence from settings.
silq.pulses.pulse_types module¶
-
class
silq.pulses.pulse_types.
Pulse
(name=None, id=None, t_start=None, t_stop=None, duration=None, acquire=False, initialize=False, connection=None, enabled=True, average='none', connection_label=None, connection_requirements={}, connect_to_config=True)[source]¶ Bases:
qcodes.instrument.parameter_node.ParameterNode
Representation of physical pulse, component in a
PulseSequence
.A Pulse is a representation of a physical pulse, usually one that is outputted by an instrument. All pulses have specific timings, defined by
t_start
,t_stop
, andduration
. Additional attributes specify ancillary properties, such as if the acquisition instrument shouldacquire
the pulse. Specific pulse types (subclasses ofPulse
) have additional properties, such as afrequency
.Pulses can be added to a
PulseSequence
, which can in turn be targeted by theLayout
. Here, eachPulse
is targeted to aConnection
, which can modify the pulse (e.g. applying an amplitude scale). Next the pulse is targeted by the output and inputInstrumentInterface
of the connection, which provide an instrument-specific implementation of the pulse.Pulses usually have a name, which is used to retrieve any default properties from the config. If the pulse name is an entry in
silq.config.{environment}.pulses
, the properties in that entry are used by default. These default values can be overridden by either passing them explicitly during the pulse initialization, or afterwards.Example
If
silq.config.{environment}.pulses
contains:>>> {'read': {'amplitude': 0.5, 'duration': 100e-3}}
Then creating the following pulse will partially use these properties:
>>> DCPulse('read', duration=200e-3) DCPulse('read', amplitude=0.5, duration=200e-3)
Here the default
amplitude
value is used, but the duration is overridden during initialization.- Parameters
name (
Optional
[str
]) – Pulse name. If corresponding name is registered in pulse config, its properties will be copied to the pulse.id (
Optional
[int
]) – Unique pulse identifier, assigned when added toPulseSequence
if it already has another pulse with same name. Pre-existing pulse will be assigned id 0, and will increase for each successive pulse added.full_name – Pulse name, including id if not None. If id is not None, full_name is ‘{name}[{id}]’
environment – Config environment to use for pulse config. If not set, default environment (
silq.config.properties.default_environment
) is used.t_start (
Optional
[float
]) – Pulse start time. If undefined and added toPulseSequence
, it will be set toPulse
.t_stop of last pulse. If no pulses are present, it will be set to zero.t_stop (
Optional
[float
]) – Pulse stop time. Is updated whenevert_start
orduration
is changed. Changing this modifiesduration
but nott_start
.acquire (
bool
) – Flag to acquire pulse. If True, pulse will be passed on to the acquisitionInstrumentInterface
by theLayout
during targeting.initialize (
bool
) – Pulse is used for initialization. This signals that the pulse can exist before the pulse sequence starts. In this case, pulse duration should be zero.connection (Connection) – Connection that pulse is targeted to. Is only set for targeted pulse.
enabled (
bool
) – Pulse is enabled. If False, it still exists in a PulseSequence, but is not included in targeting.average (
str
) –Pulse acquisition average mode. Allowed modes are:
’none’: No averaging (return
samples x points_per_trace
).’trace’: Average over time (return
points_per_trace
).’point’: Average over time and sample (return single point).
’point_segment:{N}’ Segment trace into N segment, average each segment into a point.
connection_label (
Optional
[str
]) –Connection
label that Pulse should be targeted to. These are defined insilq.config.{environment}.connections
. If unspecified, pulse can only be targeted ifconnection_requirements
uniquely determine connection.connection_requirements (
dict
) – Requirements that a connection must satisfy for targeting. Ifconnection_label
is defined, these are ignored.pulse_config – Pulse config whose attributes to match. If it exists, equal to
silq.config.{environment}.pulses.{pulse.name}
, otherwise equal to zero.properties_config – General properties config whose attributes to match. If it exists, equal to
silq.config.{environment}.properties
, otherwise None. OnlyPulse
.properties_attrs are matched.properties_attrs (List[str]) – Attributes in properties config to match. Should be defined in
__init__
before callingPulse.__init__
.implementation (PulseImplementation) – Pulse implementation for targeted pulse, see
PulseImplementation
.connect_to_config (
bool
) – Connect parameters to the config (default True)
-
config_link
= 'environment:pulses'¶
-
get_voltage
(t)[source]¶ Get voltage(s) at time(s) t.
- Raises
AssertionError – not all
t
betweenPulse
.t_start andPulse
.t_stop- Return type
-
multiple_senders
= False¶
-
satisfies_conditions
(pulse_class=None, name=None, **kwargs)[source]¶ Checks if pulse satisfies certain conditions.
Each kwarg is a condition, and can be a value (equality testing) or it can be a tuple (relation, value), in which case the relation is tested. Possible relations: ‘>’, ‘<’, ‘>=’, ‘<=’, ‘==’
- Parameters
pulse_class – Pulse must have specific class.
name (
Optional
[str
]) – Pulse must have name, which may include id.**kwargs – Additional pulse attributes to be satisfied. Examples are
t_start
,connection
, etc. Timet
can also be passed, in which case the condition is satisfied if t is betweenPulse
.t_start andPulse
.t_stop (including limits).
- Return type
- Returns
True if all conditions are satisfied.
-
snapshot_base
(update=False, params_to_skip_update=None)[source]¶ State of the instrument as a JSON-compatible dict.
- Parameters
update (bool) – If True, update the state by querying the instrument. If False, just use the latest values in memory.
params_to_skip_update (
Optional
[Sequence
[str
]]) – List of parameter names that will be skipped in update even if update is True. This is useful if you have parameters that are slow to update but can be updated in a different way (as in the qdac)
- Returns
base snapshot
- Return type
-
class
silq.pulses.pulse_types.
SteeredInitialization
(name=None, t_no_blip=None, t_max_wait=None, t_buffer=None, readout_threshold_voltage=None, **kwargs)[source]¶ Bases:
silq.pulses.pulse_types.Pulse
Initialization pulse to ensure a spin-down electron is loaded.
This is performed by continuously measuring at the read stage until no blip has been measured for
t_no_blip
, or untilt_max_wait
has elapsed.- Parameters
t_no_blip (
Optional
[float
]) – Min duration without measuring blips. If condition is met, an event should be fired to the primary instrument to start the pulse sequence.t_max_wait (
Optional
[float
]) – Maximum wait time for the no-blip condition. Ift_max_wait
has elapsed, an event should be fired to the primary instrument to start the pulse seqeuence.t_buffer (
Optional
[float
]) – Duration of a single acquisition buffer. Shorter buffers mean that one can more closely approacht_no_blip
, but too short buffers may cause lagging.readout_threshold_voltage (
Optional
[float
]) – Threshold voltage for a blip.**kwargs – Additional parameters of
Pulse
.
-
class
silq.pulses.pulse_types.
SinePulse
(name=None, frequency=None, phase=None, amplitude=None, power=None, offset=None, frequency_sideband=None, sideband_mode=None, phase_reference=None, **kwargs)[source]¶ Bases:
silq.pulses.pulse_types.Pulse
Sinusoidal pulse
- Parameters
amplitude (
Optional
[float
]) – Pulse amplitude. If not set, power must be set.power (
Optional
[float
]) – Pulse power. If not set, amplitude must be set.offset (
Optional
[float
]) – amplitude offset, zero by defaultfrequency_sideband (
Optional
[float
]) – Mixer sideband frequency (off by default).sideband_mode (
Optional
[float
]) – Sideband frequency to apply. This feature must be existent in interface. Not used if not set.phase_reference (
Optional
[str
]) –What point in the the phase is with respect to. Can be two modes:
’absolute’: phase is with respect to
Pulse.t_start
.’relative’: phase is with respect to t=0 (phase-coherent).
**kwargs – Additional parameters of
Pulse
.
Notes
Either amplitude or power must be set, depending on the instrument that should output the pulse.
-
class
silq.pulses.pulse_types.
FrequencyRampPulse
(name=None, frequency_start=None, frequency_stop=None, frequency=None, frequency_deviation=None, amplitude=None, power=None, offset=None, phase=None, frequency_sideband=None, sideband_mode=None, phase_reference=None, **kwargs)[source]¶ Bases:
silq.pulses.pulse_types.Pulse
Linearly increasing/decreasing frequency
Pulse
.- Parameters
frequency (
Optional
[float
]) – Center frequency, only used iffrequency_start
andfrequency_stop
not used.frequency_deviation (
Optional
[float
]) – Frequency deviation, only used iffrequency_start
andfrequency_stop
not used.frequency_final – Can be either
start
orstop
indicating the frequency when reachingfrequency_stop
should go back to the initial frequency or stay at current frequency. Useful if the pulse doesn’t immediately stop at the end (this depends on how the corresponding instrument/interface is programmed).amplitude (
Optional
[float
]) – Pulse amplitude. If not set, power must be set.power (
Optional
[float
]) – Pulse power. If not set, amplitude must be set.offset (
Optional
[float
]) – amplitude offset, zero by defaultfrequency_sideband (
Optional
[float
]) – Sideband frequency to apply. This feature must be existent in interface. Not used if not set.sideband_mode – Type of mixer sideband (‘IQ’ by default)
**kwargs – Additional parameters of
Pulse
.
Notes
Either amplitude or power must be set, depending on the instrument that should output the pulse.
-
get_voltage
(t)[source]¶ Get voltage(s) at time(s) t.
- Raises
AssertionError – not all
t
betweenPulse
.t_start andPulse
.t_stop
-
class
silq.pulses.pulse_types.
DCPulse
(name=None, amplitude=None, **kwargs)[source]¶ Bases:
silq.pulses.pulse_types.Pulse
DC (fixed-voltage)
Pulse
.- Parameters
-
class
silq.pulses.pulse_types.
DCRampPulse
(name=None, amplitude_start=None, amplitude_stop=None, **kwargs)[source]¶ Bases:
silq.pulses.pulse_types.Pulse
Linearly ramping voltage
Pulse
.- Parameters
-
class
silq.pulses.pulse_types.
TriggerPulse
(name='trigger', duration=1e-07, amplitude=1.0, **kwargs)[source]¶ Bases:
silq.pulses.pulse_types.Pulse
Triggering pulse.
- Parameters
-
default_amplitude
= 1.0¶
-
default_duration
= 1e-07¶
-
class
silq.pulses.pulse_types.
MarkerPulse
(name=None, amplitude=1.0, **kwargs)[source]¶ Bases:
silq.pulses.pulse_types.Pulse
Marker pulse
- Parameters
-
default_amplitude
= 1.0¶
-
class
silq.pulses.pulse_types.
TriggerWaitPulse
(name=None, t_start=None, **kwargs)[source]¶ Bases:
silq.pulses.pulse_types.Pulse
Pulse that wait until condition is met and then applies trigger
- Parameters
Note
Duration is fixed at 0s.
See also
-
class
silq.pulses.pulse_types.
MeasurementPulse
(name=None, acquire=True, **kwargs)[source]¶ Bases:
silq.pulses.pulse_types.Pulse
Pulse that is only used to signify an acquiition
This pulse is not directed to any interface other than the acquisition interface.
- Parameters
name – Pulse name.
acquire – Acquire pulse (default True)
**kwargs – Additional parameters of
Pulse
.
-
class
silq.pulses.pulse_types.
CombinationPulse
(name=None, pulse1=None, pulse2=None, relation=None, **kwargs)[source]¶ Bases:
silq.pulses.pulse_types.Pulse
Pulse that is a combination of multiple pulse types.
Like any other pulse, a CombinationPulse has a name, t_start and t_stop. t_start and t_stop are calculated and updated from the pulses that make up the combination.
A CombinationPulse is itself a child of the Pulse class, therefore a CombinationPulse can also be used in consecutive combinations like:
>>> CombinationPulse1 = SinePulse1 + DCPulse >>>CombinationPulse2 = SinePulse2 + CombinationPulse1
Examples
>>> CombinationPulse = SinePulse + DCPulse >>> CombinationPulse = DCPulse * SinePulse
- Parameters
pulse1 (
Optional
[Pulse
]) – The first pulse this combination is made up from.pulse2 (
Optional
[Pulse
]) – The second pulse this combination is made up from.The relation between pulse1 and pulse2. This must be one of the following:
’+’ : pulse1 + pulse2
’-‘ : pulse1 - pulse2
’*’ : pulse1 * pulse2
**kwargs – Additional kwargs of
Pulse
.
-
property
combination_string
¶
-
get_voltage
(t)[source]¶ Get voltage(s) at time(s) t.
- Raises
AssertionError – not all
t
betweenPulse
.t_start andPulse
.t_stop- Return type
-
property
pulse_details
¶
-
t_start
¶
-
t_stop
¶
-
class
silq.pulses.pulse_types.
AWGPulse
(name=None, fun=None, wf_array=None, interpolate=True, **kwargs)[source]¶ Bases:
silq.pulses.pulse_types.Pulse
Arbitrary waveform pulses that can be implemented by AWGs.
- This class allows the user to create a truly arbitrary pulse by either:
providing a function that converts time-stamps to waveform points
an array of waveform points
The resulting AWGPulse can be sampled at different sample rates, interpolating between waveform points if necessary.
- Parameters