qat.ir.measure module

IR models for measurement and post-processing instructions.

This module defines Acquire, PostProcessing and MeasureBlock representations used in the intermediate representation to describe measurement-related operations and software post-processing steps.

class Acquire(**data)

Bases: QuantumInstruction

Instruction representing an acquisition of a resonator/qubit signal.

Parameters:
  • duration – Acquisition duration in seconds.

  • mode – Acquisition mode describing how the hardware returns data.

  • delay – Optional delay inserted before the acquisition value is valid.

  • filter – Optional pulse defining an integration/filter kernel applied on the readout channel by the hardware or software.

  • output_variable – Name of the variable where the acquisition result will be stored.

  • rotation – optional angle in radians applied to the acquired complex value, equivalent to a complex multiplier of exp(-j * rotation). Ignored if filter is provided.

  • threshold – Optional threshold value for discriminating the acquired value into a binary state label. Ignored if filter is provided or if mode is not AcquireMode.INTEGRATOR.

  • purpose – Semantic purpose of this acquisition. Defaults to AcquirePurpose.MEASUREMENT. Set to AcquirePurpose.PRE_SELECTION for compiler-injected ground-state checks.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

delay: float | None
duration: float
filter: Pulse | None
mode: AcquireMode
model_config: ClassVar[ConfigDict] = {'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_assignment': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

output_variable: str
property pulse_channel
purpose: AcquirePurpose
rotation: float | None

Read-only data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.

Attributes:

msg: The deprecation message to be emitted. wrapped_property: The property instance if the deprecated field is a computed field, or None. field_name: The name of the field being deprecated.

property target
threshold: float | None

Read-only data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.

Attributes:

msg: The deprecation message to be emitted. wrapped_property: The property instance if the deprecated field is a computed field, or None. field_name: The name of the field being deprecated.

class Discriminate(**data)

Bases: Instruction

Discriminate equalised values to integer state keys.

For the linear-map path a sign-based threshold comparison is used: values above threshold0, values at or below → 1.

For the maximum-likelihood path the nearest centroid in the complex plane determines the state’s dict key from MaxLikelihoodMethod.states. Non-negative keys are allowed states written to the classical register; negative keys are disallowed and subsequently filtered by PostSelect. When p_min > 0, low-confidence shots are assigned BG_KEY.

Exactly one of threshold or method must be provided.

Runtime implementation: qat.runtime.post_processing.apply_discriminate_instruction().

Parameters:
  • output_variable – Variable name whose data should be discriminated.

  • threshold – Scalar threshold for the linear-map discrimination path. None when method is provided.

  • method – Post-process method object for the ML path. None when threshold is provided.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

method: MaxLikelihoodMethod | None
model_config: ClassVar[ConfigDict] = {'extra': 'ignore', 'use_enum_values': False, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

output_variable: str
threshold: float | None
class Equalise(**data)

Bases: Instruction

Apply an affine transform in the IQ (complex) plane to readout data.

This is the first stage of the granular post-processing pipeline.

In superconducting qubit readout the downconverted IQ signal is distorted by three hardware imperfections: phase imbalance (LO quadrature paths not exactly 90° apart), gain imbalance (unequal I/Q amplifier chains), and DC offsets (mixer leakage and biases). As a result, raw (I, Q) samples cluster on a distorted, offset ellipse rather than a compact point cloud, degrading any downstream discriminator.

The Equalise instruction corrects all three imperfections in a single real affine transform:

\[\begin{split}\begin{pmatrix} I' \\ Q' \end{pmatrix} = A \begin{pmatrix} I \\ Q \end{pmatrix} + \begin{pmatrix} b_I \\ b_Q \end{pmatrix}\end{split}\]

where A is a real 2×2 matrix (transform) and [b_I, b_Q] is the real offset vector (offset). The output is returned as a complex value I' + j Q'.

Each Equalise instruction operates on a single readout channel. To equalise multiple channels, emit one instruction per channel with its own output_variable.

The default transform (2×2 identity) and default offset (zero vector) are a no-op pass-through for already-calibrated hardware.

Runtime implementation: qat.runtime.post_processing.apply_equalise().

Parameters:
  • output_variable – Variable name whose data should be transformed.

  • transform – Real (2, 2) matrix A.

  • offset – Real offset vector [b_I, b_Q], shape (2,). Defaults to the zero vector.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

model_config: ClassVar[ConfigDict] = {'extra': 'ignore', 'use_enum_values': False, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

offset: FloatNDArray
output_variable: str
transform: FloatNDArray
class MeasureBlock(**data)

Bases: QuantumInstructionBlock

Encapsulates a measurement of a single (or multiple) qubit(s).

It should only contain instructions that are associated with a measurement such as a measure pulse, an acquire or a synchronize.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

add(*instructions)
instructions: ValidatedList[VALID_MEASURE_INSTR]
model_config: ClassVar[ConfigDict] = {'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_assignment': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context, /)

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Return type:

None

Args:

self: The BaseModel instance. context: The context.

property output_variables
qubit_targets: Annotated[ValidatedSet[QubitId], BeforeValidator(_validate_set)]
class PostProcessing(**data)

Bases: Instruction

States what post-processing should happen after data has been acquired.

This can happen in the FPGA’s or a software post-process.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

args: list[float | complex]
axes: list[ProcessAxis]
model_config: ClassVar[ConfigDict] = {'extra': 'ignore', 'use_enum_values': False, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

output_variable: str | None
process_type: PostProcessType
result_needed: bool
class PostSelect(**data)

Bases: Instruction

Mark shots for filtering based on discriminated integer state keys.

PostSelect follows Discriminate in the readout pipeline. It does not remove shots inline — instead it records a per-output boolean validity mask. Shots are marked invalid when:

  • Their integer state key is negative (disallowed states or the p_min background key), or

  • Their integer state key is in additional_disallowed.

The runtime ANDs all masks together and filters once at the end.

additional_disallowed allows the pre-selection pass to specify extra state indices to reject.

Runtime implementation: qat.runtime.post_processing.apply_post_select().

See also

Shot Selection (Pre & Post) for full pre/post-selection docs.

Parameters:
  • output_variable – Variable name whose integer state keys should be screened.

  • additional_disallowed – Extra non-negative state indices to treat as disallowed, in addition to any keys already negative in the discriminated output. Defaults to the empty set.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

additional_disallowed: set[int]
model_config: ClassVar[ConfigDict] = {'extra': 'ignore', 'use_enum_values': False, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

output_variable: str