The circuit which measures a Z-type stabilisers in the surface code is:
whereas for X-type stabilisers it's:
Both types of stabilisers are measured in a memory experiment in the inbuilt surface code circuits of Stim, which I am using by following the linux command line instructions for Sinter. Even though both types of stabilisers are measured for each memory experiment, the two extra hadamards for X-type stabiliser measurements (which detect Z errors) means they have higher depth. This causes a higher logical error rate in a memory experiment for memory X (preserving $|+\rangle_L$ which is more affected by $Z$ errors) than for memory Z (preserving $|0\rangle_L$ which is more affected by $X$ errors). That is ${p_L}_X > {p_L}_Z$.
The circuits I am using are stim's inbuilt surface code circuits. These measure both types of stabilisers for both types of memory experiment. See a distance 2, unrotated surface code with 1 round of stabiliser measurements below as an example (though for my simulations I am doing odd distances and $d$ rounds of stabiliser measurements).
Memory Z prepares the data qubits in $|0\rangle ^{\otimes n}$ and measures them in the Z basis at the end (preserving $|0\rangle_L$):
Whereas Memory X prepares the data qubits in $|+\rangle ^{\otimes n}$ and measures them in the X basis at the end (preserving $|+\rangle_L$):
Note that these diagrams are without noise but for my simulations I am using a circuit noise model (setting all of Stim's inbuilt errors to $p$).
When making threshold curves for the rotated surface code using Stim's inbuilt circuits I see, as expected, that ${p_L}_X > {p_L}_Z$. For example for distance 7 and 9 below ${p_L}_X > {p_L}_Z$ for each distance:
On the other hand for the unrotated surface code I am seeing the opposite. Instead of ${p_L}_X > {p_L}_Z$ I am seeing ${p_L}_X < {p_L}_Z$ I have triple checked that I am running and plotting the correct memory experiment type and can not figure out what is causing it. I have simulated every odd distance up to 15 and keep seeing ${p_L}_X < {p_L}_Z$, as per the plots below:
I am running the memory experiments from a linux command line following the instructions for Sinter here which are:
mkdir -p circuits
python -c "
import stim
for p in [0.001, 0.005, 0.01]:
for d in [3, 5]:
with open(f'circuits/d={d},p={p},b=X,type=rotated_surface_memory.stim', 'w') as f:
c = stim.Circuit.generated(
rounds=d,
distance=d,
after_clifford_depolarization=p,
after_reset_flip_probability=p,
before_measure_flip_probability=p,
before_round_data_depolarization=p,
code_task=f'surface_code:rotated_memory_x')
print(c, file=f)
"
sinter collect \
--processes 4 \
--circuits circuits/*.stim \
--metadata_func "sinter.comma_separated_key_values(path)" \
--decoders pymatching \
--max_shots 1_000_000 \
--max_errors 1000 \
--save_resume_filepath stats.csv
sinter plot \
--in stats.csv \
--group_func "'Rotated Surface Code d=' + str(metadata['d'])" \
--x_func "metadata['p']" \
--fig_size 1024 1024 \
--xaxis "[log]Physical Error Rate" \
--out surface_code_figure.png \
--show