# How to get line fits from sinter.plot_error_rate to calculate logical error rate as function of physical

I would like to print the gradient and intercept values for the line fits generated by sinter.plot_error_rate.

My goal is that I'm trying to find logical error rate as a function of physical error rate for surface codes, i.e. $$\alpha$$ and $$\beta$$ in $$p_L = \alpha (\beta p)^{\frac{d+1}{2}}$$.

I have generated a bunch of threshold graphs so believe the best way to do this would be to find the line fits of $$p_L$$ versus $$p$$ for each distance on my graphs and from there find $$\alpha$$ and $$\beta$$.

Using stim and sinter I can generate threshold graphs with line fits. For example, using the sample code from: https://pypi.org/project/sinter/ but adding line_fits argument to sinter.plot_error_rate (and setting custom xlim and ylim for the plot)


import stim
import sinter
import matplotlib.pyplot as plt

# Generates surface code circuit tasks using Stim's circuit generation.
for p in [0.001, 0.005, 0.01]:
for d in [3, 5]:
circuit=stim.Circuit.generated(
rounds=d,
distance=d,
after_clifford_depolarization=p,
),
'p': p,
'd': d,
},
)

def main():
# Collect the samples (takes a few minutes).
samples = sinter.collect(
num_workers=4,
max_shots=1_000_000,
max_errors=1000,
decoders=['pymatching'],
)

# Print samples as CSV data.
for sample in samples:
print(sample.to_csv_line())

# Render a matplotlib plot of the data.
fig, ax = plt.subplots(1, 1)
sinter.plot_error_rate(
ax=ax,
stats=samples,
group_func=lambda stat: f"Rotated Surface Code d={stat.json_metadata['d']}",
line_fits = ('log','log'),
)
ax.loglog()
ax.set_ylim(1e-6, 1)
ax.set_xlim(1e-4,1e-1)
ax.grid()
ax.set_title('Logical Error Rate vs Physical Error Rate')
ax.set_ylabel('Logical Error Probability (per shot)')
ax.set_xlabel('Physical Error Rate')
ax.legend()

# Save to file and also open in a window.
fig.savefig('plot.png')
plt.show()

# NOTE: This is actually necessary! If the code inside 'main()' was at the
# module level, the multiprocessing children spawned by sinter.collect would
# also attempt to run that code.
if __name__ == '__main__':
main()


creates the following plot which has line fits:

How can I print out the gradient and intercept of what sinter calculated as the line fits so I can then calculate $$p_L(p)$$ ?

Under the hood, sinter is using scipy.stats.linregress. You can use sinter.group_by(stats, key=group_func) to split your stats up into a group for each curve, and then make the x/y points for the fitting function from those stats. Sinter has some helper methods like sinter.fit_line_slope and fit_line_y_at_x that will give you low/best/high ranges instead of a single number, to help quantify uncertainty in the estimate.