Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/quantumlib/Stim/llms.txt

Use this file to discover all available pages before exploring further.

A detector error model (.dem) file is a UTF-8 encoded, human-readable description of the probabilistic error mechanisms in a quantum error-correcting code. The format is designed to be consumed by decoders — algorithms that predict the logical observable frame from a set of detected symptoms. Each error mechanism in the model has a probability, a set of syndrome detectors it flips (symptoms), and a set of logical observables it flips (frame changes). Error mechanisms may also suggest a decomposition into simpler sub-mechanisms.

Encoding

Detector error model files are always encoded using UTF-8. Non-ASCII characters may only appear inside comments.

Syntax

A .dem file is a sequence of lines, each of which is blank, an instruction, a block initiator, or a block terminator. Lines may be indented and may end with a # comment. Instruction names are case-insensitive.
<DETECTOR_ERROR_MODEL> ::= <LINE>*
<LINE>                 ::= <INDENT> (<INSTRUCTION> | <BLOCK_START> | <BLOCK_END>)? <COMMENT>? '\n'
<INDENT>               ::= /[ \t]*/
<COMMENT>              ::= '#' /[^\n]*/
<INSTRUCTION>          ::= <NAME> <TAG>? <PARENS_ARGUMENTS>? <TARGETS>
<BLOCK_START>          ::= <INSTRUCTION> /[ \t]*/ '{'
<BLOCK_END>            ::= '}'

Instructions

The error instruction adds an error mechanism to the model. It takes one probability argument and a list of targets that specify the symptoms (detector targets) and frame changes (observable targets) caused by the error. Targets may include a ^ separator to suggest a decomposition.Syntax: error(p) <targets>
# An error affecting detectors D2 and D3 and flipping observable L0
error(0.1) D2 D3 L0

# An error with a suggested decomposition at the ^ separator
# Symptoms: D2, D5, D6 — Frame changes: L0
error(0.02) D2 L0 ^ D5 D6

# Decomposition where L0 appears in both parts (cancels out)
# Symptoms: D2, D3 — Frame changes: none
error(0.03) D2 L0 ^ D3 L0
When two error mechanisms have identical targets, they are typically fused using the combination formula p_combined = p1(1 − p2) + p2(1 − p1). An error mechanism may have frame changes with no symptoms, which implies code distance ≤ 1.
The ^ separator is used to suggest decompositions, not to define independent error mechanisms. For example, in a surface code, a Y error can be decomposed into correlated X and Z parts.
The detector instruction declares a detection event and optionally annotates it with coordinates. Detectors are implicitly declared by being mentioned in error instructions, but an explicit declaration is the only way to attach coordinate hints.Syntax: detector(<coords...>) D<index>The detector index is relative to the current detector offset (accumulated by shift_detectors). Coordinate arguments are relative to the current coordinate offset.
# Declare detector 4 with no coordinates
detector D4

# Declare detectors 5 and 6
detector D5 D6

# Declare detector 7 at coordinates (2.5, 3.5, 6)
detector(2.5, 3.5, 6) D7
The logical_observable instruction ensures a frame change is included in the model even if no error mechanism references it.Syntax: logical_observable L<index>
# Declare observable 1
logical_observable L1

# Declare observables 1 and 2 together
logical_observable L1 L2
The shift_detectors instruction increments the current detector index offset and optionally the coordinate offset. This is essential inside repeat blocks, where each iteration would otherwise declare detectors with the same indices.Syntax: shift_detectors(<coord_offsets...>) <detector_offset>The detector offset argument is a non-negative integer; it can only increase, never decrease. Coordinate offset arguments are floating-point.
# Advance the detector index by 3, and shift the Y coordinate by 1
shift_detectors(0, 1) 3

# Advance detector index by 1, no coordinate shift
shift_detectors 1
The repeat K { ... } block repeats its body exactly K times. It is used to compactly express error models for repetitive circuits such as syndrome extraction rounds.
# Declare a diagonal line of 1000 detectors with errors between them
detector(0, 0) D0
repeat 1000 {
    detector(0.5, 0.5) D1
    error(0.01) D0 D1
    shift_detectors(0.5, 0.5) 1
}

Target types

TargetFormatDescription
Relative detectorD<uint>A detection event. The absolute index is D_value + current_detector_offset.
Logical observableL<uint>A logical frame change that an error can flip.
Numeric<uint>A bare integer used by shift_detectors (detector shift) and repeat (repetition count).
Separator^Splits the targets of an error instruction into a suggested decomposition.

State space

Interpreting a .dem file requires tracking:
  1. Offsets — the current relative detector index and coordinate offset, modified by shift_detectors.
  2. Nodes — the set of all declared detectors and logical observables. The total count equals max_detector_index + 1 and max_observable_index + 1 respectively.
  3. Edges — the list of error mechanisms and their probabilities, symptoms, and frame changes.

Relationship to circuits

A .stim circuit with DETECTOR and OBSERVABLE_INCLUDE annotations can be converted to a .dem file by analyzing how physical errors propagate through the circuit. In Stim’s Python API:
import stim

# Convert a circuit to its detector error model
circuit = stim.Circuit.from_file("my_circuit.stim")
dem = circuit.detector_error_model(decompose_errors=True)

# Save and load a .dem file
dem.to_file("my_model.dem")
dem2 = stim.DetectorErrorModel.from_file("my_model.dem")

# Inspect the model
print(dem)
Pass decompose_errors=True to detector_error_model() to instruct Stim to suggest ^ decompositions for complex error mechanisms, which many decoders (such as minimum-weight perfect matching) require.

Examples

Ten detectors arranged in a ring, with one error mechanism that also carries a logical observable frame change.
error(0.1) D9 D0 L0
error(0.1) D0 D1
error(0.1) D1 D2
error(0.1) D2 D3
error(0.1) D3 D4
error(0.1) D4 D5
error(0.1) D5 D6
error(0.1) D6 D7
error(0.1) D7 D8
error(0.1) D8 D9
The same model using a repeat block:
error(0.1) D9 D0 L0
repeat 9 {
    error(0.1) D0 D1
    shift_detectors 1
}
This is an excerpt from the output of stim --gen repetition_code --task memory --rounds 1000 --distance 4 --after_clifford_depolarization 0.001 | stim --analyze_errors --fold_loops. The repeat block encodes all 998 middle rounds compactly.
error(0.0002667378157289137966) D0
error(0.0002667378157289137966) D0 D1
error(0.0005333333333331479603) D0 D3
error(0.0005333333333331479603) D0 D4
error(0.0002667378157289137966) D1 D2
error(0.0002667378157289137966) D2 L0
error(0.0002667378157289137966) D5 L0
detector(1, 0) D0
detector(3, 0) D1
detector(5, 0) D2
repeat 998 {
    error(0.0002667378157289137966) D3
    error(0.0002667378157289137966) D3 D4
    error(0.0002667378157289137966) D5 L0
    shift_detectors(0, 1) 0
    detector(1, 0) D3
    detector(3, 0) D4
    detector(5, 0) D5
    shift_detectors 3
}

Build docs developers (and LLMs) love