Stim doesn't currently support recording errors when sampling from a circuit, but it does support recording errors when sampling from a detector error model via the return_errors=True
argument of stim.CompiledDemSampler.sample
. It can also replay errors via the recorded_errors_to_replay
argument, allowing you to e.g. remove or add one error and redo a simulation.
To get samples you would make a surface code stim circuit, get the dem via stim.Circuit.detector_error_model
, get the dem sampler via stim.DetectorErrorModel.compile_sampler
, and collect shots+errors via stim.CompiledDemSampler.sample
.
To do error correction, take the detection event data returned by the sample method and feed it to pymatching. Use pymatching.Matching.from_detector_error_model
to get a decoder and then give your sampled detection event data to pymatching.Matching.decode_batch
to predict the observable flip data.
Whenever it predicts wrong, that's a logical error.
Interpreting the sampled errors is the hard part that requires a lot of glue coding. The error data is just a flat list of bits, with the k'th bit being set if the k'th error declared in the detector error model fired. You need to turn this list of bits into a representation that's useful for your purposes. Typically this would involve iterating through the dem's instructions (use stim.DetectorErrorModel.flattened
to simplify this by inlining loops and coordinate shifting), noting what each error does, creating some dictionary mapping from the error index k to the interpreation. For example, for each error, pull out which detectors it flips and use stim.DetectorErrorModel.get_detector_coordinates
to determine if it's an X type or Z type error. Note that you can sort of map back to circuit errors by using stim.Circuit.explain_detector_error_model_errors
.
An example of what I've done with this kind of workflow is to count how many times an edge is associated with a logical error, and make heat maps. This sort of tells a story of where the weakest error paths are.
