Programs#

The programs subpackage includes the classes used to define what is to be executed on control hardware.

keysight.qcs.programs.BaseLinker

A base class for linkers.

keysight.qcs.programs.BaseRepetition

An abstract base class for repeating an object.

keysight.qcs.programs.CalibrationSet

A class that stores calibration data as Variables and Linkers using said data.

keysight.qcs.programs.ConditionalOperation

A class for conditional operations acting on Targets.

keysight.qcs.programs.Layer

A layer of operations to be applied to specified targets.

keysight.qcs.programs.Linker

A class that defines how a quantum BaseOperation should be mapped to HardwareOperations.

keysight.qcs.programs.NestedRepetition

Encapsulates nested repetitions where the first element is the outermost repetition.

keysight.qcs.programs.ParameterizedLinker

A class that defines how a quantum BaseOperation should be mapped to HardwareOperations based on values of specific parameters.

keysight.qcs.programs.Program

A program described as a sequence of back-to-back layers, where each layer describes all the control instructions to be performed during a time interval.

keysight.qcs.programs.QuditGraph

Represents a quantum device as a graph.

keysight.qcs.programs.Repeat

Repeat a specified number of times.

keysight.qcs.programs.Results

A class that accesses results using a map from targets of measurements to associated metadata.

keysight.qcs.programs.SequenceBuilder

Translates a Program containing only channel operations into a map from channels to lists of operations.

keysight.qcs.programs.Synchronization

An enum specifying the supported synchronization values.

keysight.qcs.programs.Sweep

Repeat while changing the values of specified inputs.

Linkers#

class keysight.qcs.programs.BaseLinker#

A base class for linkers.

property operation: BaseOperation#

The operation to map.

property program: Program#

The program that the operation is mapped to.

property targets: Targets#

The targets for this operation.

property yield_variables: Generator[Variable]#

Yield the variables of this linker.

match(operation: BaseOperation, target: Targets) list[Layer] | None#

Returns a map of targets to lists of operations acting on them if operation acting on target matches those on this, otherwise None.

Parameters:
  • operation – The operation to try and match.

  • target – The target to try and match.

class keysight.qcs.programs.Linker(operation: BaseOperation, targets: Targets, program: Program)#

A class that defines how a quantum BaseOperation should be mapped to HardwareOperations.

import keysight.qcs as qcs

# initialize a measurement on one qubit
qudits = qcs.Qudits(1)

# initialize the program to convert the instruction to
replacement = qcs.Program()

# add a constant 30ns pulse on a drive channel
pulse = qcs.DCWaveform(30e-9, qcs.ConstantEnvelope(), 1)
awg = qcs.Channels(range(1), "awg")
replacement.add_waveform(pulse, awg)

# add a 100ns acquisition with a delay
digitizer = qcs.Channels(range(1), "digitizer")
acq_delay = qcs.Scalar("acq_delay", dtype=float)
replacement.add_acquisition(100e-9, digitizer, pre_delay=acq_delay)

# initialize the linker
qcs.Linker(qcs.Measure(), qudits, replacement)
Linker(operation=Measure(2), targets=Qudits(labels=[1], name=qudits, dim=2), program=Program([Layer(Channels(labels=[0], name=awg, absolute_phase=False)=[DCWaveform(duration=Scalar(name=_implicit, value=3e-08, dtype=float, unit=s), envelope={ConstantEnvelope(): Scalar(name=_implicit, value=1.0, dtype=float, unit=none)})], Channels(labels=[0], name=digitizer, absolute_phase=False)=[Delay(Scalar(name=acq_delay, value=None, dtype=float, unit=s)), Acquisition(Scalar(name=_implicit, value=1e-07, dtype=float, unit=s))])]))
Parameters:
  • operation – The operation to match.

  • targets – The targets the operation acts on.

class keysight.qcs.programs.ParameterizedLinker(operation: BaseOperation, targets: Targets, program: Program, target_map: dict[str, TargetMap] | None = None, broadcast: bool = False, prefix: str | None = None)#

A class that defines how a quantum BaseOperation should be mapped to HardwareOperations based on values of specific parameters.

import keysight.qcs as qcs

# initialize three qubits
qudits = qcs.Qudits(range(3))

# define an operation to replace
phis = qcs.Array("phis", shape=(3,), dtype=float)
gate_z = qcs.ParameterizedGate(qcs.PAULIS.rz, phis)

# replace the Z gate with a phase increment
virtual_z = qcs.PhaseIncrement(phis)
channels = qcs.Channels(range(3))

# define the replacement program
replacement_program = qcs.Program()
replacement_program.add_waveform(virtual_z, channels)

# initialize the parameterized linker
virtual_z_linker = qcs.ParameterizedLinker(gate_z, qudits, replacement_program)

# use match to generate the replacement layers
layers_qudit_1 = virtual_z_linker.match(gate_z, qudits[1])

# the Z gate has been replaced with an instruction to increment the phase
layers_qudit_1[0].operations[channels[1]]
[PhaseIncrement(ScalarRef(name=_implicit, value=None, dtype=float, unit=rad))]
Parameters:
  • operation – The operation to match.

  • targets – The targets the operation acts on.

  • program – The program to link the operation acting on the targets to.

  • target_map – An optional map used to redirect targets when matching.

  • broadcast – Whether to broadcast all scalars to arrays so they can be calibrated independently.

  • prefix – The prefix of the variables in this linker that are broadcast.

property target_map: dict[str, TargetMap] | None#

The map used to redirect targets in the program when matching.

static create_single_qudit_gate_linker(gate: Gate | ParameterizedGate, waveform: BaseWaveform, qudits: Qudits | int, channels: Channels | None = None, name: str | None = None, broadcast: bool = True) ParameterizedLinker#

Creates a ParameterizedLinker for a single qudit gate operation.

Parameters:
  • gate – The gate to create a linker for.

  • waveform – The waveform to map the gate to.

  • qudits – The qudits or number of qudits the gate can act on.

  • channels – The control channels for the qudits.

  • name – A name for the channel names and variable names in this linker.

  • broadcast – Whether to broadcast all scalars to arrays so they can be calibrated independently.

Raises:
  • ValueError – If the dimensions of the qudits and gate do not match.

  • ValueError – If the dimensions of the qudits and channels do not match.

static create_cross_resonance_gate_linker(gate: Gate | ParameterizedGate, qudits: Iterable[Qudits] | MultiQudits, sq_linker: BaseLinker, control_waveform: BaseWaveform, target_waveform: BaseWaveform | None = None, name: str | None = None, broadcast: bool = True) ParameterizedLinker#

Creates a ParameterizedLinker for a cross-resonance two-qudit gate operation.

This is the simplest implementation of a cross-resonance gate where only one waveform is played on the target qudit and an optional waveform can be played on the control qudit.

Parameters:
  • gate – The two-qudit gate to create a linker for.

  • qudits – The qudits or number of qudits the gate can act on.

  • sq_linker – The linker for single-qudit gates.

  • control_waveform – The waveform to map the gate to for the control qudit.

  • target_waveform – The waveform to map the gate to for the target qudit.

  • name – A name for the channel names and variable names in this linker.

  • broadcast – Whether to broadcast all scalars to arrays so they can be calibrated independently.

Raises:
  • ValueError – If the dimensions of the qudits and gate do not match.

  • ValueError – If the gate linker does not contain a single target.

static create_measurement_linker(waveform: BaseWaveform, qudits: Qudits | int, readout_channels: Channels | None = None, acquire_channels: Channels | None = None, integration_filter: BaseWaveform | None = None, readout_pulse_delay: Variable | float | Iterable[float] | None = None, acquisition_delay: Variable | float | Iterable[float] | None = None, classification_references: Array | None = None, name: str | None = None, broadcast: bool = True) ParameterizedLinker#

Creates a ParameterizedLinker for a measurement operation.

Parameters:
  • waveform – The readout waveform.

  • qudits – The qudits or number of qudits the measurement acts on.

  • readout_channels – The readout channels for the qudits.

  • acquire_channels – The acquisition channels for the qudits.

  • integration_filter – An optional integration filter.

  • readout_pulse_delay – A delay to insert before the readout drive pulse is played.

  • acquisition_delay – A delay to insert before the acquisition operation.

  • classification_references – An optional array of IQ reference points for classification.

  • name – A name for the channel names and variable names in this linker.

  • broadcast – Whether to broadcast all scalars to arrays so they can be calibrated independently.

Raises:
  • ValueError – If the dimensions of the qudits and channels do not match.

  • ValueError – If the number of classification points and number of qudits do not match.

Calibration#

class keysight.qcs.programs.CalibrationSet(topology: QuditGraph | None = None)#

A class that stores calibration data as Variables and Linkers using said data.

import keysight.qcs as qcs

# construct a calibration set with a variable amplitude
cals = qcs.CalibrationSet()
amp = cals.add_variable(qcs.Scalar("amp", dtype=float))

# construct a linker for an X gate on a single qubit with said variable
x_prog = qcs.Program()
dc_wav = qcs.DCWaveform(1e-8, qcs.GaussianEnvelope(), amp)
x_prog.add_waveform(dc_wav, qcs.Channels(0))
x_linker = qcs.Linker(qcs.GATES.x, qcs.Qudits(0), x_prog)

# add the linker to the calibration set, which adds the variable
cals.add_linker("x_linker", x_linker)

# updating the value on the variable set updates the value on the linker
cals.variables.amp.value = 0.5
assert cals.linkers["x_linker"].program.variables.amp.value == 0.5
Parameters:

topology – A QuditGraph representing qudit connectivity.

property active_linkers: dict[str, BaseLinker]#

A user-selected subset of the available linkers. By default, the active linkers include all the linkers in this calibration set.

property linkers: dict[str, BaseLinker]#

The linkers using calibration data.

property num_qudits: int | None#

Returns the number of qudits in this calibration set.

property target_variables: dict[Qudits | MultiQudits, Iterable[str]]#

The linkers using calibration data.

property variable_list: list[Variable]#

Returns a list of all the variables in the calibration set.

Returns:

List of Variable objects in the calibration.

property channels: set[str]#

Returns the names of all the virtual channels in the calibration set.

Returns:

Set of unique channel name strings found in the operations.

property topology: QuditGraph#

The qudit graph in this calibration set.

property variables: VariableSet#

The variable set containing calibration variables.

activate(names: str | Iterable[str]) None#

Activate the specified linkers.

Names:

The names of the linkers to activate.

Raises:

ValueError – If one of the names is not a linker in this.

add_linker(name: str, linker: BaseLinker, activate: bool = True, allow_different_values: bool = False) None#

Adds a linker to this.

Parameters:
  • name – The alias of the linker.

  • linker – The linker to add.

  • activate – Whether to activate the linker.

  • allow_different_values – Whether to overwrite the variables in linker with variables of the same name from this even if the values are different.

Raises:
  • ValueError – If there is already a linker with alias name in this.

  • ValueError – If the linker program contains a variable with the same alias as but not equal to one on variables.

add_cr_gate(gate: Gate | ParameterizedGate, qudits: Iterable[Qudits] | MultiQudits, sq_linker: BaseLinker | str, control_waveform: BaseWaveform, target_waveform: BaseWaveform | None = None, name: str | None = None, broadcast: bool = True) None#

Add a linker for two-qudit cross-resonance gates to this.

Parameters:
  • gate – The two-qudit gate to create a linker for.

  • qudits – The qudits or number of qudits the gate can act on.

  • sq_linker – The linker or the name of the linker for single-qudit gates.

  • control_waveform – The waveform to map the gate to for the control qudit.

  • target_waveform – The waveform to map the gate to for the target qudit.

  • name – A name for the channel names and variable names in this linker.

  • broadcast – Whether to broadcast all scalars to arrays so they can be calibrated independently.

add_sq_gate(name: str, gate: Gate | ParameterizedGate, waveform: HardwareOperation, qudits: int | Qudits | None = None, channels: Channels | None = None, broadcast: bool = True) None#

Add a linker for single-qudit gates to this.

Parameters:
  • name – The name of the linker.

  • gate – The gate to create a linker for.

  • waveform – The waveform to map the gate to.

  • qudits – The qudits or number of qudits the gate can act on.

  • channels – The control channels for the qudits.

  • broadcast – Whether to broadcast all scalars to arrays so they can be calibrated independently.

add_measurement(waveform: BaseWaveform, qudits: int | Qudits | None = None, readout_channels: Channels | None = None, acquire_channels: Channels | None = None, integration_filter: IntegrationFilter | None = None, pre_delay: Variable | float | Iterable[float] | None = None, acquisition_delay: Variable | float | Iterable[float] | None = None, classification_references: Array | None = None, name: str | None = None, broadcast: bool = True) None#

Add a linker for qudit measurements to this.

Parameters:
  • qudits – The qudits or number of qudits the gate can act on.

  • readout_channels – The readout drive channels for the qudits.

  • acquire_channels – The digitizer channels for the acquisition.

  • integration_filter – An optional integration filter.

  • pre_delay – A delay to insert before the readout drive pulse is played.

  • acquisition_delay – A delay to insert before the acquisition operation.

  • classification_references – An optional array of IQ reference points for classification.

  • broadcast – Whether to broadcast all scalars to arrays so they can be calibrated independently.

add_variable(variable: Variable)#

Adds a variable to this calibration set.

deactivate(names: str | Iterable[str]) None#

Deactivate the specified linkers.

Names:

The names of the linkers to deactivate.

export_values(filename: Path | str) None#

Export the values of variables in this to a human-readable json file.

Parameters:

filename – The name of the file to export the values to.

get_active_linkers() list[BaseLinker]#

Gets the active linkers from this calibration set.

get_multi_qudit_gates(active_only: bool = True) dict[str, BaseOperation]#

Gets all the multi-qudit gates in the linkers of this calibration set.

Parameters:

active_only – Whether to only include gates from active linkers.

get_single_qudit_gates(active_only: bool = True) dict[str, BaseOperation]#

Gets all the single-qudit gates in the linkers of this calibration set.

Parameters:

active_only – Whether to only include gates from active linkers.

get_variable(name: str, qudits: Qudits | tuple[Qudits] | None) Variable#

Returns the variable corresponding to a qudit or qudit pair.

Parameters:
  • name – The name of the variable.

  • qudits – The qudit or qudit pair.

Raises:

ValueError – If the tag of name does not match qudits.

import_values(filename: Path | str) None#

Update the values of variables in this from a human-readable json file.

Parameters:

filename – The name of the file to load from.

class keysight.qcs.programs.QuditGraph(qudits: Qudits | Iterable[Qudits] | None = None, couplings: Iterable[tuple[Qudits, Qudits]] | MultiQudits | Iterable[MultiQudits] | None = None)#

Represents a quantum device as a graph. The vertices of the graph represent qudits and edges as possible couplings. Assigns each qudit and coupling a unique index.

import keysight.qcs as qcs

n_qudits = 10
qudits = qcs.Qudits(range(n_qudits))

# define a linear topology for the qudits
pairs = [(qudits[i], qudits[i + 1]) for i in range(n_qudits - 1)]

topology = qcs.QuditGraph(qudits, pairs)
Parameters:
  • qudits – The qudits in the hardware configuration.

  • couplings – A list of Qudits pairs that define the coupling or a single or list of MultiQudits.

property num_qudits: int#

The number of qudit targets in this.

property qudits: Iterable[Qudits]#

The qudit targets in this.

property multi_qudits: MultiQudits#

The multi-qudit targets in this.

add(qudits: Qudits | tuple[Qudits, Qudits] | MultiQudits)#

Adds qudits or multi-qudit couplings to this.

ConditionalOperation#

class keysight.qcs.programs.ConditionalOperation(operations: Iterable[BaseOperation], register: Register)#

A class for conditional operations acting on Targets.

Parameters:
  • operations – The list of operations to select from.

  • register – The register to use to select the operation.

property operations: list[BaseOperation]#

The operations to select from.

property register: Register#

The register to use to select the operation.

Layer#

class keysight.qcs.programs.Layer(operations: dict[Targets, BaseOperation | Iterable[BaseOperation]] | None = None, synchronization=Synchronization.Start)#

A layer of operations to be applied to specified targets.

Parameters:
  • operations – The operations in this layer.

  • synchronization – How the operations in this layer are to be synchronized.

Raises:

ValueError – If there are partially overlapping targets in operations.

property data_transactions: TransactionList#

The data transactions that take place during this layer.

property operations: dict[Targets, list[BaseOperation]]#

The operations in this layer.

property synchronization: Synchronization#

Specifies how the operations acting on different targets are to be synchronized.

property synchronized: bool#

Whether delays have been inserted to synchronize the operations acting on different targets.

property yield_variables: Generator[Variable]#

Yield the variables of this layer.

duration(duration_map: dict[BaseOperation, float | Scalar[float]] | None = None) Max[float]#

The duration of this layer in seconds.

Parameters:

duration_map – A map from operations to their durations.

insert(target: Targets, operations: Iterable[BaseOperation] | BaseOperation) Layer | None#

Inserts operations acting on specified targets to this layer. If the targets partially overlap with targets in this layer, a new layer is returned.

Parameters:
  • target – The target of the operation.

  • operations – The operations to perform.

Raises:

ValueError – If synchronize has been called.

synchronize(duration_map: dict[BaseOperation, float | Scalar[float]] | None = None) None#

Insert delays to synchronize the operations in this layer. After this method is called, no further operations can be added to the layer.

Parameters:

duration_map – A map from operations to their durations.

class keysight.qcs.programs.Synchronization(value)#

An enum specifying the supported synchronization values.

The names (values) are: Start (0) Center (1) End (2)

Program#

class keysight.qcs.programs.Program(*layers: Layer, name: str | None = None, save_path: str | Path | None = None)#

A program described as a sequence of back-to-back layers, where each layer describes all the control instructions to be performed during a time interval.

Parameters:
  • layers – The layers of this program.

  • name – The name of this program.

  • save_path – The path to save the program to.

property name: str | None#

The name of this program.

property layers: list[Layer]#

The layers in this program.

property pre_program_operations: list[NonHVIOperation]#

Non-HVI operations that are run before program execution.

property post_program_operations: list[NonHVIOperation]#

Non-HVI operations that are run after program execution.

property channels: set[str]#

Returns the names of the virtual channels of the program.

Returns:

Set of unique channel name strings found in the operations

property variable_list: list[Variable]#

Returns a list of all the variables linked to the programs.

Returns:

List of Variable objects in the program.

property repetitions: NestedRepetition#

An ordered sequence of nested ways to repeat this program.

property repetition_shape: tuple[int]#

The shape of the nested repetitions of this program.

property results: Results#

The results of this program.

property save_path: Path | None#

The folder the program is saved to.

property variables: VariableSet#

The variables in this program.

add_acquisition(integration_filter: float | Scalar[float] | HardwareOperation | Iterable[HardwareOperation] | IntegrationFilter, channels: Channels, classifier: Classifier | Iterable[Classifier] | None = None, new_layer: bool | None = None, pre_delay: Variable[float] | float | None = None) None#

Adds an acquisition to perform on a digitizer channel.

The channels are added to the results attribute to enable the results to be retrieved by channel.

Parameters:
  • integration_filter – The integration filter to be used when integrating the acquired data, or a duration in seconds for a raw acquisition.

  • channels – The channels to acquire results from.

  • classifier – The classifiers used to classify the integrated acquisition.

  • new_layer – Whether to insert the operation into a new layer. The default of None will insert in the last layer if possible otherwise it will insert into a new layer.

  • pre_delay – An optional delay in seconds to insert before the operation.

add_conditional_operation(operations: Iterable[BaseOperation], target: Targets, register: Register, new_layer: bool | None = None, pre_delay: Variable[float] | float | Iterable[float] | None = None) None#

Adds a conditional operation to this program.

Parameters:
  • operations – The operations to choose from.

  • target – The targets to apply the selected operation to.

  • register – The register to use to select the operation.

  • new_layer – Whether to insert the operation into a new layer. The default of None will insert in the last layer if possible otherwise it will insert into a new layer.

  • pre_delay – The delay in seconds to insert before the operation.

add_gate(gate: Gate | Iterable[Gate], qudits: Qudits | Iterable[Qudits] | MultiQudits, new_layer: bool | None = None, pre_delay: Variable[float] | float | Iterable[float] | None = None) None#

Adds a gate to this program.

Parameters:
  • gate – The gate.

  • qudits – The qudits to which to apply the gate.

  • new_layer – Whether to insert the operation into a new layer. The default of None will insert in the last layer if possible otherwise it will insert into a new layer.

  • pre_delay – The delay in seconds to insert before the operation.

add_measurement(qudits: Qudits, new_layer: bool | None = None, pre_delay: Variable[float] | float | Iterable[float] | None = None, reset: bool | Iterable[BaseOperation] = False, register: Register | None = None, repeat_reset: int = 1) None#

Adds a measurement instruction to this program.

The qudits are added to the results attribute to enable the results to be retrieved by qudit.

Parameters:
  • qudits – The qudits to measure.

  • new_layer – Whether to insert the operation into a new layer. The default of None will insert in the last layer if possible otherwise it will insert into a new layer.

  • pre_delay – The delay in seconds to insert before the operation.

  • reset – Whether to apply a conditional operation after the measurement. If True, this will add an identity and an X gate conditioned on the outcome of the measurement. If an operation or a list of operations is passed, these will be performed conditioned on the measurement.

Register:

An optional register to write the measurement results to for conditional operations.

Repeat_reset:

The number of times to repeat the reset operation.

add_parametric_gate(gate: ParametricGate, parameters: float | Variable[float] | Iterable[float | Iterable[float] | Variable[float]], qudits: Qudits | Iterable[Qudits] | MultiQudits, new_layer: bool | None = None, pre_delay: Variable[float] | float | Iterable[float] | None = None) None#

Adds a parametric gate to this program.

This uses a Variable to specify each of the parameters of the gate.

Parameters:
  • gate – The parametric gate to add.

  • parameters – An iterable of variables that specify the parameters of the gate.

  • qudits – The qudits to which to apply this gate.

  • new_layer – Whether to insert the operation into a new layer. The default of None will insert in the last layer if possible otherwise it will insert into a new layer.

  • pre_delay – The delay in seconds to insert before the operation.

add_post_program_operation(nonHviOperation: NonHVIOperation)#

Adds a non-HVI operation to run after program execution.

Parameters:

nonHviOperation – Non-Hvi operation.

add_pre_program_operation(nonHviOperation: NonHVIOperation)#

Adds a non-HVI operation to run before program execution.

Parameters:

nonHviOperation – Non-Hvi operation.

add_reset(qudits: Qudits, new_layer: bool | None = None, pre_delay: Variable[float] | float | Iterable[float] | None = None) None#

Adds a reset instruction to this program.

Parameters:
  • qudits – The qudits to reset.

  • new_layer – Whether to insert the operation into a new layer. The default of None will insert in the last layer if possible otherwise it will insert into a new layer.

  • pre_delay – The delay in seconds to insert before the operation.

add_waveform(pulse: HardwareOperation | Iterable[HardwareOperation], channels: Channels, new_layer: bool | None = None, pre_delay: Variable[float] | float | Iterable[float] | None = None) None#

Adds a waveform to play on an AWG channel.

Parameters:
  • pulse – The waveform to play.

  • channels – The channels on which to play the waveform.

  • new_layer – Whether to insert the operation into a new layer. The default of None will insert in the last layer if possible otherwise it will insert into a new layer.

  • pre_delay – The delay in seconds to insert before the operation.

add_delay(duration: float | Scalar[float], targets: Qudits | Channels, new_layer: bool | None = None) None#

Adds a delay to this program.

Parameters:
  • duration – The duration of the delay to apply.

  • targets – The targets to which to apply the delay.

  • new_layer – Whether to apply the delay into a new layer.

declare(variable: Variable) Variable#

Declares a variable as part of this program.

Parameters:

variable – The variable to be declared.

duration(duration_map: dict[BaseOperation, float | Scalar[float]] | None = None) Scalar[float]#

The duration of this program in seconds.

Parameters:

duration_map – A map from operation/target pairs to known durations.

extend(*layers: Layer) None#

Extend this program.

Parameters:

layers – The layers to extend this program with.

n_shots(num_reps: int) Program#

Repeat this program a specified number of times.

Parameters:

num_reps – The number of times to repeat this program.

Raises:

Warning – If n_shots has already been called on this program.

render(channel_subplots: bool = True, channels: Channels | Iterable[Channels] | None = None, mapper: ChannelMapper | None = None, lo_frequency: float = 0.0, sample_rate: float = 1000000000.0, plot_imaginary: bool = False, sweep_index: int | tuple[int] | None = None, program_layer: int = -1, condition: int = 0) Figure#

Renders the waveforms in this program with the current values of variables or, if this program has sweeps, the value at the sweep point specified by sweep_idx, with a value of None corresponding to the first sweep point their values at the first sweep point.

import keysight.qcs as qcs

# initialize waveforms
gaus1_amp = qcs.Scalar("gaus1_amp", value=0.8, dtype=float)
gauss1 = qcs.GaussianEnvelope(2)
gauss2 = qcs.GaussianEnvelope(3)
gauss3 = qcs.GaussianEnvelope(4)
const = qcs.ConstantEnvelope()

rf1 = qcs.RFWaveform(
    duration=4e-8, envelope=gauss1, amplitude=gaus1_amp, rf_frequency=1e6
)
rf2 = qcs.RFWaveform(
    duration=4e-8, envelope=gauss2, amplitude=1, rf_frequency=2e6
)
rf3 = qcs.RFWaveform(
    duration=4e-8, envelope=gauss3, amplitude=1, rf_frequency=3e6
)
rf4 = qcs.RFWaveform(
    duration=4e-8, envelope=const, amplitude=1, rf_frequency=4e6
)

# initialize virtual channels
awgs12 = qcs.Channels(range(2), "awgs12")
awg3 = qcs.Channels(range(1), "awg3")
awg4 = qcs.Channels(range(1), "awg4")

# initialize physical channels
my_chan1 = qcs.Address(1, 1, 1)
my_chan2 = qcs.Address(1, 1, 2)
my_chan3 = qcs.Address(1, 1, 3)

# initialize mapper
mapper = qcs.ChannelMapper()
mapper.add_channel_mapping(
    awgs12, [my_chan1, my_chan2], qcs.InstrumentEnum.M5300AWG
)
mapper.add_channel_mapping(awg3, [my_chan3], qcs.InstrumentEnum.M5300AWG)
mapper.add_channel_mapping(awg4, [my_chan3], qcs.InstrumentEnum.M5300AWG)

# set LO frequencies
for chan in mapper.physical_channels:
    chan.settings.lo_frequency.value = 100e6

# initialize a program
prog = qcs.Program()
prog.add_waveform(rf1, awg3)
prog.add_waveform(rf2, awg4)
prog.add_waveform([rf2, rf3], awgs12[1])
prog.add_waveform(rf4, awg3)

# render the program
fig1 = prog.render(channel_subplots=False, mapper=mapper, sample_rate=5e8)
fig1.show()

# sweep the base program while varying the amplitude of one pulse
amp_vals = qcs.Array("amp_vals", value=[0.8, 0.5, 0.2])
prog.sweep(amp_vals, gaus1_amp)

# render the program that will be executed on the third sweep pass
fig2 = prog.render(channel_subplots=False, mapper=mapper, sweep_index=2)
fig2.show()
Parameters:
  • channel_subplots – Whether to split each channel into its own subplot.

  • channels – The channels to include when rendering waveforms. If None, all channels on the program are included.

  • mapper – A ChannelMapper used to retrieve information used to generate the plots, such as the LO frequency and sample rate of the various channels. If None, the LO frequency is set to 0 and the sample rate to 1e9.

  • lo_frequency – The LO frequency used to render, in case the given mapper does not specify one for the channels being plotted.

  • sample_rate – The sample rate used to render, in case the given mapper does not specify one for the channels being plotted.

  • plot_imaginary – Whether to render the imaginary part of the waveforms. This option is included because the imaginary portion is often zero and omitting it reduces the time required to render by half.

  • sweep_index – The sweep point to render. For nested sweeps, provide the index as a tuple where the leftmost index is the outermost sweep.

  • program_layer – The layer number from user to render the program’s merged layer.

  • condition – The condition to be used to render the conditional operator.

Raises:

ValueError – If the sweep_index is out of bounds for this program’s repetitions.

sweep(sweep_values: Array | tuple[Array], targets: Variable | tuple[Variable], pre_iterate_operation_list: Iterable[NonHVIOperation] = ()) Program#

Creates a program that sweeps a target variable. Additionally, can sweep several targets provided their sweep value shapes are compatible.

Parameters:
  • sweep_values – The values to sweep.

  • targets – The variables of this program to sweep.

  • pre_iterate_operation_list – Non-HVI operations to be run before iteration.

Raises:

ValueError – If the number of targets does not match the number of sweep values.

draw(filename: str = 'qcs_program.html', display: bool = True) None#

Creates an HTML representation of this Program and saves it to a file.

Parameters:
  • filename – The filename to write the HTML to (if executing in a script)

  • display – Whether to display the HTML. When set to False, this will only save the file to the specified filename.

get_trace(channels: Channels | Qudits | None = None, avg: bool | int = False) DataFrame#

Get the trace data for specified channels or qudits.

Parameters:
  • channels – The channels or qudits to get the data for.

  • avg – Whether to average the data across repetitions.repeat_axis (True) or to treat individual shots separately (False).

Raises:

ValueError – If program was executed with hardware demodulation.

get_trace_pandas(channels: Channels | Qudits | None = None, avg: bool | int = False) DataFrame#

Get the trace data for specified channels or qudits.

Parameters:
  • channels – The channels or qudits to get the data for.

  • avg – Whether to average the data across repetitions.repeat_axis (True) or to treat individual shots separately (False).

Raises:

ValueError – If program was executed with hardware demodulation.

get_trace_array(channels: Channels | Qudits | None = None, avg: bool | int = False) DataArray#

Get the trace data as a xarray.

Parameters:
  • channels – The channels or qudits to get the data for.

  • avg – Whether to average the data across repetitions.repeat_axis (True) or to treat individual shots separately (False).

Raises:

ValueError – If program was executed with hardware demodulation.

get_spectrum(channels: Channels | Qudits | None = None, avg: bool | int = False, window: None | Callable[[int], ndarray] | ndarray | Iterable[ndarray] = None, pad: int | None = None) DataFrame#

Get the power spectrum of the trace data for specified channels or qudits using the discrete Fourier transform.

Parameters:
  • channels – The channels or qudits to get the data for.

  • avg – Whether to average the data across repetitions.repeat_axis (True) or to treat individual shots separately (False).

  • window – An optional window function to multiply the trace data with before calculating the Fourier transform.

  • pad – Whether to pad the traces with zeros before taking the Fourier transform. If an integer n is passed, the traces will be cropped or extended (with zeros) to length n depending on the length of the traces.

Raises:

ValueError – If program was executed with hardware demodulation.

get_iq(channels: Channels | Qudits | None = None, avg: bool | int = False, stack_channels: bool = False, integration_filter: IntegrationFilter | None = None, acq_index: int = -1) DataFrame#

Get the IQ data for specified channels or qudits.

Parameters:
  • channels – The channels or qudits to get the data for.

  • avg – Whether to average the data across repetitions.repeat_axis (True) or to treat individual shots separately (False).

  • stack_channels – Whether to stack the channel index as rows.

  • integration_filter – An optional integration filter to generate IQ data from trace data.

  • acq_index – The index of the acquisition to get. Default -1 returns the last acquisition, None returns all acquisitions.

Raises:

TypeError – If stack_channels is True but the installed pandas version is below 2.1.

get_iq_pandas(channels: Channels | Qudits | None = None, avg: bool | int = False, stack_channels: bool = False, integration_filter: IntegrationFilter | None = None, acq_index: int = -1) DataFrame#

Get the IQ data for specified channels or qudits.

Parameters:
  • channels – The channels or qudits to get the data for.

  • avg – Whether to average the data across repetitions.repeat_axis (True) or to treat individual shots separately (False).

  • stack_channels – Whether to stack the channel index as rows.

  • integration_filter – An optional integration filter to generate IQ data from trace data.

  • acq_index – The index of the acquisition to get. Default -1 returns the last acquisition, None returns all acquisitions.

Raises:

TypeError – If stack_channels is True but the installed pandas version is below 2.1.

get_iq_array(channels: Channels | Qudits | None = None, avg: bool | int = False, integration_filter: IntegrationFilter | None = None, acq_index: int = -1) DataArray#

Get the IQ data as a xarray.

Parameters:
  • channels – The channels or qudits to get the data for.

  • avg – Whether to average the data across repetitions.repeat_axis (True) or to treat individual shots separately (False).

  • integration_filter – An optional integration filter to generate IQ data from trace data.

  • acq_index – The index of the acquisition to get. Default -1 returns the last acquisition, None returns all acquisitions.

Raises:

TypeError – If stack_channels is True but the installed pandas version is below 2.1.

get_classified(channels: Channels | Qudits | None = None, avg: bool | int = False, stack_channels: bool = False, classifier: Classifier | MinimumDistanceClassifier | None = None, integration_filter: IntegrationFilter | None = None, acq_index: int = -1) DataFrame#

Get the classified data for specified channels or qudits.

Parameters:
  • channels – The channels or qudits to get the data for.

  • avg – Whether to average the data across repetitions.repeat_axis (True) or to treat individual shots separately (False).

  • stack_channels – Whether to stack the channel index as rows.

  • classifier – An optional classifier to classify the IQ data.

  • integration_filter – An optional integration filter to generate IQ data from trace data.

  • acq_index – The index of the acquisition to get. Default -1 returns the last acquisition, None returns all acquisitions.

Raises:

TypeError – If stack_channels is True but the installed pandas version is below 2.1.

get_classified_pandas(channels: Channels | Qudits | None = None, avg: bool | int = False, stack_channels: bool = False, classifier: Classifier | MinimumDistanceClassifier | None = None, integration_filter: IntegrationFilter | None = None, acq_index: int = -1) DataFrame#

Get the classified data for specified channels or qudits.

Parameters:
  • channels – The channels or qudits to get the data for.

  • avg – Whether to average the data across repetitions.repeat_axis (True) or to treat individual shots separately (False).

  • stack_channels – Whether to stack the channel index as rows.

  • classifier – An optional classifier to classify the IQ data.

  • integration_filter – An optional integration filter to generate IQ data from trace data.

  • acq_index – The index of the acquisition to get. Default -1 returns the last acquisition, None returns all acquisitions.

Raises:

TypeError – If stack_channels is True but the installed pandas version is below 2.1.

get_classified_array(channels: Channels | Qudits | None = None, avg: bool | int = False, classifier: Classifier | MinimumDistanceClassifier | None = None, integration_filter: IntegrationFilter | None = None, acq_index: int = -1) DataArray#

Get the classified data for as a xarray

Parameters:
  • channels – The channels or qudits to get the data for.

  • avg – Whether to average the data across repetitions.repeat_axis (True) or to treat individual shots separately (False).

  • classifier – An optional classifier to classify the IQ data.

  • integration_filter – An optional integration filter to generate IQ data from trace data.

  • acq_index – The index of the acquisition to get. Default -1 returns the last acquisition, None returns all acquisitions.

Raises:

TypeError – If stack_channels is True but the installed pandas version is below 2.1.

get_sample_rates(channels: Channels | Qudits | None = None) dict[Channels | Qudits, float]#

Get the sample rates for the specified channels or qudits.

Parameters:

channels – The channels or qudits to get the sample rate for.

Raises:

ValueError – If the program has not been run on hardware.

plot_trace(channel_subplots: bool = True, avg: bool | int = True, channels: Channels | None = None) Figure#

Plots the trace data.

Parameters:
  • channel_subplots – Whether to generate subplots for different channels.

  • avg – Whether to average the data across repetitions.repeat_axis (True) or to treat individual shots separately (False).

  • channels – Which channels to plot. Defaults to all channels.

plot_classified(acq_index: int = -1, channel_subplots: bool = True, channels: Channels | None = None, sweep_index: int | tuple[int] | None = None, avg=False, plot_axis: int = 0, plot_type: str = 'linear') Figure#

Plots the classified data.

Parameters:
  • acq_index – The index of the acquisition to get. Default -1 returns the last acquisition.

  • channel_subplots – Whether to generate subplots for different channels.

  • channels – Which channels to plot. Defaults to all channels.

  • sweep_index – The sweep point to plot. For nested sweeps, provide the index as a tuple where the leftmost index is the outermost sweep. Currently, we support plots for 2d sweeps only.

  • avg – Whether to average the data across repetitions.repeat_axis (True) or to treat individual shots separately (False).

  • plot_axis – The axis of the dataframe over which to plot the IQ data. Only when avg is True we consider the plot axis parameter for plotting.

  • plot_type – The type of plot. Available options are “linear” or “2d”.

Raises:

ValueError – If the sweep_index is out of bounds for this program’s repetitions or if specified sweep_index length is greater than 2.

plot_spectrum(channel_subplots: bool = True, avg: bool | int = True, window: None | Callable[[int], ndarray] | ndarray | Iterable[ndarray] = None, pad_zeros: bool | int | Iterable[int] = True, channels: Channels | None = None) Figure#

Plots the power spectrum of the trace data.

Parameters:
  • channel_subplots – Whether to generate subplots for different channels.

  • avg – Whether to average the data across repetitions.repeat_axis (True) or to treat individual shots separately (False).

  • window – An optional window function to multiply the trace data with before calculating the Fourier transform.

  • pad_zeros – Whether to pad the traces with zeros to interpolate the spectrum. The default value True will pad each trace to 5x the trace length. If an integer or a list of integers is passed, each trace will be padded (or truncated) to that number.

  • channels – Which channels to plot. Defaults to all channels.

plot_iq(channel_subplots: bool = True, avg: bool | int = True, plot_type: str = 'scatter', plot_axis: int = 0, group_scatter: bool = True, channels: Channels | None = None, acq_index: int = -1) Figure#

Plots the IQ data.

Parameters:
  • channel_subplots – Whether to generate subplots for different channels.

  • avg – Whether to average the data across repetitions.repeat_axis (True) or to treat individual shots separately (False).

  • plot_type – The type of plot. Available options are “linear”, “scatter”, or “2d”.

  • plot_axis – The axis of the dataframe over which to plot the IQ data.

  • group_scatter – Groups scatter points using the same color and markers.

  • channels – Which channels to plot. Defaults to all channels.

  • acq_index – The index of the acquisition to get. Default -1 returns the last acquisition, None returns all acquisitions.

Raises:

ValueError – When the plot_axis is out of bounds.

to_hdf5(new_file: str | Path | None = None) Program#

Generates a hdf5 file containing the results of this program and returns a new program that loads from said file.

Parameters:

new_file – The optional name of the new file. If None uses save_path and name.

Raises:

ValueError – If the program does not have any results.

reset_repetitions() None#

Removes all repetitions from this program.

class keysight.qcs.programs.SequenceBuilder(duration_map: dict[BaseOperation, float] | None = None, channel_map: ChannelMapper | None = None)#

Translates a Program containing only channel operations into a map from channels to lists of operations.

Parameters:
  • duration_map – The map from operations to durations of the operation.

  • channel_map – The channel map used by this to populate channel delays.

property channel_map: ChannelMapper | None#

The channel map in this sequence builder.

property duration_map: dict[BaseOperation, Scalar[float]]#

The duration map used by this sequence builder.

build(program: Program) tuple[Program, dict[int, int]]#

Compiles a program before execution and returns a tuple of program and a dictionary with user facing layer index and merged layer index.

Parameters:

program – The program to compile.

Results#

class keysight.qcs.programs.Results#

Bases: CsWrapper

A class that accesses results using a map from targets of measurements to associated metadata.

property accession_id: int | None#

The accession ID used to access database results if this program was run using HCL.

property channels: dict[Channels, list[Acquisition]]#

The map from digitizer channels to the acquisitions to perform on them.

property qudits: dict[Qudits, Channels | int]#

The map from qudits to the channels they are measured through or the number of measurements on the given qudit if no channel has been assigned.

property repetitions: NestedRepetition#

An ordered sequence of nested repetitions associated with these results.

get_classified(channels: Channels | Qudits | None = None, avg: bool | int = False, classifier: Classifier | None = None, integration_filter: IntegrationFilter | None = None, acq_index: int | None = -1) dict[Channels | Qudits, ndarray]#

Get the classified data.

Parameters:
  • channels – The channels or qudits to get the data for.

  • avg – Whether to average the data or the axis to average it over. Setting avg=True will average over the last axis.

  • classifier – An optional classifier to classify the IQ data.

  • integration_filter – An optional integration filter to generate IQ data from trace data.

  • acq_index – The index of the acquisition to get. Default -1 returns the last acquisition, None returns all acquisitions.

get_iq(channels: Channels | Qudits | None = None, avg: bool | int = False, integration_filter: IntegrationFilter | None = None, acq_index: int = -1) dict[Channels | Qudits, ndarray]#

Get the IQ data.

Parameters:
  • channels – The channels or qudits to get the data for.

  • avg – Whether to average the data or the axis to average it over. Setting avg=True will average over the last axis.

  • integration_filter – An optional integration filter to generate IQ data from trace data.

  • acq_index – The index of the acquisition to get. Default -1 returns the last acquisition, None returns all acquisitions.

get_trace(channels: Channels | Qudits | None = None, avg: bool | int = False) dict[Channels | Qudits, ndarray]#

Get the trace data for specified channels or qudits.

Parameters:
  • channels – The channels or qudits to get the data for.

  • avg – Whether to average the data or the axis to average it over. Setting avg=True will average over the last axis.

Raises:

ValueError – If program was executed with hardware demodulation.

get_spectrum(channels: Channels | Qudits | None = None, avg: bool | int = False, window: None | Callable[[int], ndarray] | ndarray | Iterable[ndarray] = None, pad: None | int | Iterable[int] = None) dict[Channels | Qudits, ndarray]#

Get the power spectrum of the trace data for specified channels or qudits using the discrete Fourier transform.

Parameters:
  • channels – The channels or qudits to get the data for.

  • avg – Whether to average the data or the axis to average it over. Setting avg=True will average over the last axis.

  • window – An optional window function to multiply the trace data with before calculating the Fourier transform.

  • pad – Whether to pad the traces with zeros before taking the Fourier transform. If an integer n is passed, the traces will be cropped or extended (with zeros) to length n depending on the length of the traces.

Raises:

ValueError – If program was executed with hardware demodulation.

Repetitions#

class keysight.qcs.programs.BaseRepetition#

Bases: CsWrapper

An abstract base class for repeating an object.

abstract property index_name: str#

The name of this repetition in multi-indexed data.

abstract property is_multi_indexable: bool#

Whether this repetition can be used in multi-indexed data.

property num_reps: int#

The number of repetitions.

class keysight.qcs.programs.NestedRepetition#

Bases: CsWrapper

Encapsulates nested repetitions where the first element is the outermost repetition.

property averaged_shape: tuple[int]#

The number of steps performed at each level of repetition that is not repeat_axis.

property hw_items: list[BaseRepetition]#

The repetitions that are looped in hardware.

property is_multi_indexable: bool#

Whether this repetition can be used in multi-indexed data.

property num_hw_reps: int#

The number of steps performed in hardware.

property num_hw_items: int#

The number of repetition items performed in hardware.

property num_sw_reps: int#

The number of steps performed in software.

property repeat_axis: int#

The index of the innermost Repeat in the repetitions of this.

Raises:

ValueError – If no repeat was specified.

property shape: tuple[int]#

The number of steps performed at each level of repetition.

property sw_items: list[BaseRepetition]#

The repetitions that are looped in software.

property num_averages: int#

The number of averages generated.

insert(index: int, repetition: BaseRepetition) None#

Insert a repetition at a specified position.

Parameters:
  • index – The index to insert the repetition.

  • repetition – The repetition to insert.

class keysight.qcs.programs.Repeat(num_reps: int)#

Bases: BaseRepetition

Repeat a specified number of times.

Parameters:

num_reps – The number of times to repeat.

property index_name: str#

The name of this repetition in multi-indexed data.

property is_multi_indexable: bool#

Whether this repetition can be used in multi-indexed data.

class keysight.qcs.programs.Sweep(associations: dict[Variable, Array], pre_iterate_operation_list: Iterable[NonHVIOperation] = ())#

Bases: BaseRepetition

Repeat while changing the values of specified inputs.

Parameters:
  • associations – The map from variables to the values to sweep them by.

  • pre_iterate_operation_list – Non-HVI operations to be run before iteration.

Raises:
  • ValueError – If any sweep value is not specified.

  • ValueError – If the number of sweep points for each target does not match.

property associations: dict[Variable, Array]#

The map from target variables to the values they are to be swept over.

property index_name: str#

The name of this repetition in multi-indexed data.

property is_multi_indexable: bool#

Whether this repetition can be used in multi-indexed data.

property pre_iterate_operations: list[NonHVIOperation]#

Non-HVI operations to be run before iteration.