diff --git a/doc/python_api_reference_vDev.md b/doc/python_api_reference_vDev.md
index 65d29fbf2..87fabcd96 100644
--- a/doc/python_api_reference_vDev.md
+++ b/doc/python_api_reference_vDev.md
@@ -62,6 +62,7 @@ API references for stable versions are kept on the [stim github wiki](https://gi
- [`stim.Circuit.to_tableau`](#stim.Circuit.to_tableau)
- [`stim.Circuit.with_inlined_feedback`](#stim.Circuit.with_inlined_feedback)
- [`stim.Circuit.without_noise`](#stim.Circuit.without_noise)
+ - [`stim.Circuit.without_tags`](#stim.Circuit.without_tags)
- [`stim.CircuitErrorLocation`](#stim.CircuitErrorLocation)
- [`stim.CircuitErrorLocation.__init__`](#stim.CircuitErrorLocation.__init__)
- [`stim.CircuitErrorLocation.flipped_measurement`](#stim.CircuitErrorLocation.flipped_measurement)
@@ -187,6 +188,7 @@ API references for stable versions are kept on the [stim github wiki](https://gi
- [`stim.DetectorErrorModel.rounded`](#stim.DetectorErrorModel.rounded)
- [`stim.DetectorErrorModel.shortest_graphlike_error`](#stim.DetectorErrorModel.shortest_graphlike_error)
- [`stim.DetectorErrorModel.to_file`](#stim.DetectorErrorModel.to_file)
+ - [`stim.DetectorErrorModel.without_tags`](#stim.DetectorErrorModel.without_tags)
- [`stim.ExplainedError`](#stim.ExplainedError)
- [`stim.ExplainedError.__init__`](#stim.ExplainedError.__init__)
- [`stim.ExplainedError.circuit_error_locations`](#stim.ExplainedError.circuit_error_locations)
@@ -3593,6 +3595,33 @@ def without_noise(
"""
```
+
+```python
+# stim.Circuit.without_tags
+
+# (in class stim.Circuit)
+def without_tags(
+ self,
+) -> stim.Circuit:
+ """Returns a copy of the circuit with all tags removed.
+
+ Returns:
+ A `stim.Circuit` with the same instructions except all tags have been
+ removed.
+
+ Examples:
+ >>> import stim
+ >>> stim.Circuit('''
+ ... X[test-tag] 0
+ ... M[test-tag-2](0.125) 0
+ ... ''').without_tags()
+ stim.Circuit('''
+ X 0
+ M(0.125) 0
+ ''')
+ """
+```
+
```python
# stim.CircuitErrorLocation
@@ -7589,6 +7618,31 @@ def to_file(
"""
```
+
+```python
+# stim.DetectorErrorModel.without_tags
+
+# (in class stim.DetectorErrorModel)
+def without_tags(
+ self,
+) -> stim.DetectorErrorModel:
+ """Returns a copy of the detector error model with all tags removed.
+
+ Returns:
+ A `stim.DetectorErrorModel` with the same instructions except all tags have
+ been removed.
+
+ Examples:
+ >>> import stim
+ >>> stim.DetectorErrorModel('''
+ ... error[test-tag](0.25) D0
+ ... ''').without_tags()
+ stim.DetectorErrorModel('''
+ error(0.25) D0
+ ''')
+ """
+```
+
```python
# stim.ExplainedError
diff --git a/doc/stim.pyi b/doc/stim.pyi
index 328ece885..abce4a1ab 100644
--- a/doc/stim.pyi
+++ b/doc/stim.pyi
@@ -2792,6 +2792,26 @@ class Circuit:
M 0
''')
"""
+ def without_tags(
+ self,
+ ) -> stim.Circuit:
+ """Returns a copy of the circuit with all tags removed.
+
+ Returns:
+ A `stim.Circuit` with the same instructions except all tags have been
+ removed.
+
+ Examples:
+ >>> import stim
+ >>> stim.Circuit('''
+ ... X[test-tag] 0
+ ... M[test-tag-2](0.125) 0
+ ... ''').without_tags()
+ stim.Circuit('''
+ X 0
+ M(0.125) 0
+ ''')
+ """
class CircuitErrorLocation:
"""Describes the location of an error mechanism from a stim circuit.
@@ -5969,6 +5989,24 @@ class DetectorErrorModel:
>>> contents
'error(0.25) D2 D3\n'
"""
+ def without_tags(
+ self,
+ ) -> stim.DetectorErrorModel:
+ """Returns a copy of the detector error model with all tags removed.
+
+ Returns:
+ A `stim.DetectorErrorModel` with the same instructions except all tags have
+ been removed.
+
+ Examples:
+ >>> import stim
+ >>> stim.DetectorErrorModel('''
+ ... error[test-tag](0.25) D0
+ ... ''').without_tags()
+ stim.DetectorErrorModel('''
+ error(0.25) D0
+ ''')
+ """
class ExplainedError:
"""Describes the location of an error mechanism from a stim circuit.
diff --git a/glue/python/src/stim/__init__.pyi b/glue/python/src/stim/__init__.pyi
index 328ece885..abce4a1ab 100644
--- a/glue/python/src/stim/__init__.pyi
+++ b/glue/python/src/stim/__init__.pyi
@@ -2792,6 +2792,26 @@ class Circuit:
M 0
''')
"""
+ def without_tags(
+ self,
+ ) -> stim.Circuit:
+ """Returns a copy of the circuit with all tags removed.
+
+ Returns:
+ A `stim.Circuit` with the same instructions except all tags have been
+ removed.
+
+ Examples:
+ >>> import stim
+ >>> stim.Circuit('''
+ ... X[test-tag] 0
+ ... M[test-tag-2](0.125) 0
+ ... ''').without_tags()
+ stim.Circuit('''
+ X 0
+ M(0.125) 0
+ ''')
+ """
class CircuitErrorLocation:
"""Describes the location of an error mechanism from a stim circuit.
@@ -5969,6 +5989,24 @@ class DetectorErrorModel:
>>> contents
'error(0.25) D2 D3\n'
"""
+ def without_tags(
+ self,
+ ) -> stim.DetectorErrorModel:
+ """Returns a copy of the detector error model with all tags removed.
+
+ Returns:
+ A `stim.DetectorErrorModel` with the same instructions except all tags have
+ been removed.
+
+ Examples:
+ >>> import stim
+ >>> stim.DetectorErrorModel('''
+ ... error[test-tag](0.25) D0
+ ... ''').without_tags()
+ stim.DetectorErrorModel('''
+ error(0.25) D0
+ ''')
+ """
class ExplainedError:
"""Describes the location of an error mechanism from a stim circuit.
diff --git a/src/stim/circuit/circuit.cc b/src/stim/circuit/circuit.cc
index b158069e1..225acf44d 100644
--- a/src/stim/circuit/circuit.cc
+++ b/src/stim/circuit/circuit.cc
@@ -802,6 +802,22 @@ const Circuit Circuit::aliased_noiseless_circuit() const {
return result;
}
+Circuit Circuit::without_tags() const {
+ Circuit result;
+ for (CircuitInstruction inst : operations) {
+ if (inst.gate_type == GateType::REPEAT) {
+ result.append_repeat_block(
+ inst.repeat_block_rep_count(),
+ inst.repeat_block_body(*this).without_tags(),
+ "");
+ } else {
+ inst.tag = "";
+ result.safe_append(inst);
+ }
+ }
+ return result;
+}
+
Circuit Circuit::without_noise() const {
Circuit result;
for (const auto &op : operations) {
diff --git a/src/stim/circuit/circuit.h b/src/stim/circuit/circuit.h
index 35d1361e2..1785ff689 100644
--- a/src/stim/circuit/circuit.h
+++ b/src/stim/circuit/circuit.h
@@ -147,6 +147,8 @@ struct Circuit {
/// Returns a copy of the circuit with all noise processes removed.
Circuit without_noise() const;
+ /// Returns a copy of the circuit with all tags removed.
+ Circuit without_tags() const;
/// Returns an equivalent circuit without REPEAT or SHIFT_COORDS instructions.
Circuit flattened() const;
diff --git a/src/stim/circuit/circuit.pybind.cc b/src/stim/circuit/circuit.pybind.cc
index 772a7d9f7..06cb84c04 100644
--- a/src/stim/circuit/circuit.pybind.cc
+++ b/src/stim/circuit/circuit.pybind.cc
@@ -2236,6 +2236,29 @@ void stim_pybind::pybind_circuit_methods(pybind11::module &, pybind11::class_>> import stim
+ >>> stim.Circuit('''
+ ... X[test-tag] 0
+ ... M[test-tag-2](0.125) 0
+ ... ''').without_tags()
+ stim.Circuit('''
+ X 0
+ M(0.125) 0
+ ''')
+ )DOC")
+ .data());
+
c.def(
"flattened",
&Circuit::flattened,
diff --git a/src/stim/circuit/circuit.test.cc b/src/stim/circuit/circuit.test.cc
index 4ef0e1e8f..bfe081a6a 100644
--- a/src/stim/circuit/circuit.test.cc
+++ b/src/stim/circuit/circuit.test.cc
@@ -1985,3 +1985,22 @@ TEST(circuit, insert_instruction) {
X 1
)CIRCUIT"));
}
+
+TEST(circuit, without_tags) {
+ Circuit initial(R"CIRCUIT(
+ H[test-1] 0
+ REPEAT[test-2] 100 {
+ REPEAT[test-3] 100 {
+ M[test-4](0.125) 0
+ }
+ }
+ )CIRCUIT");
+ ASSERT_EQ(initial.without_tags(), Circuit(R"CIRCUIT(
+ H 0
+ REPEAT 100 {
+ REPEAT 100 {
+ M(0.125) 0
+ }
+ }
+ )CIRCUIT"));
+}
diff --git a/src/stim/circuit/circuit_pybind_test.py b/src/stim/circuit/circuit_pybind_test.py
index 2bf84480d..effb05b1b 100644
--- a/src/stim/circuit/circuit_pybind_test.py
+++ b/src/stim/circuit/circuit_pybind_test.py
@@ -2351,3 +2351,12 @@ def test_append_pauli_string():
c.append("MPP", object())
with pytest.raises(ValueError, match="Don't know how to target"):
c.append("MPP", object())
+
+
+def test_without_tags():
+ circuit = stim.Circuit("""
+ H[tag] 5
+ """)
+ assert circuit.without_tags() == stim.Circuit("""
+ H 5
+ """)
diff --git a/src/stim/dem/detector_error_model.cc b/src/stim/dem/detector_error_model.cc
index 0ac4e5063..a0f8071c4 100644
--- a/src/stim/dem/detector_error_model.cc
+++ b/src/stim/dem/detector_error_model.cc
@@ -774,3 +774,19 @@ std::map> DetectorErrorModel::get_detector_coordin
return out;
}
+
+DetectorErrorModel DetectorErrorModel::without_tags() const {
+ DetectorErrorModel result;
+ for (DemInstruction inst : instructions) {
+ if (inst.type == DemInstructionType::DEM_REPEAT_BLOCK) {
+ result.append_repeat_block(
+ inst.repeat_block_rep_count(),
+ inst.repeat_block_body(*this).without_tags(),
+ "");
+ } else {
+ inst.tag = "";
+ result.append_dem_instruction(inst);
+ }
+ }
+ return result;
+}
diff --git a/src/stim/dem/detector_error_model.h b/src/stim/dem/detector_error_model.h
index 72c0eb432..1e0e09871 100644
--- a/src/stim/dem/detector_error_model.h
+++ b/src/stim/dem/detector_error_model.h
@@ -63,6 +63,8 @@ struct DetectorErrorModel {
bool approx_equals(const DetectorErrorModel &other, double atol) const;
std::string str() const;
+ DetectorErrorModel without_tags() const;
+
uint64_t total_detector_shift() const;
uint64_t count_detectors() const;
uint64_t count_observables() const;
diff --git a/src/stim/dem/detector_error_model.pybind.cc b/src/stim/dem/detector_error_model.pybind.cc
index 4aed906b9..b2729c070 100644
--- a/src/stim/dem/detector_error_model.pybind.cc
+++ b/src/stim/dem/detector_error_model.pybind.cc
@@ -1204,4 +1204,25 @@ void stim_pybind::pybind_detector_error_model_methods(
... print(diagram, file=f)
)DOC")
.data());
+
+ c.def(
+ "without_tags",
+ &DetectorErrorModel::without_tags,
+ clean_doc_string(R"DOC(
+ Returns a copy of the detector error model with all tags removed.
+
+ Returns:
+ A `stim.DetectorErrorModel` with the same instructions except all tags have
+ been removed.
+
+ Examples:
+ >>> import stim
+ >>> stim.DetectorErrorModel('''
+ ... error[test-tag](0.25) D0
+ ... ''').without_tags()
+ stim.DetectorErrorModel('''
+ error(0.25) D0
+ ''')
+ )DOC")
+ .data());
}
diff --git a/src/stim/dem/detector_error_model_pybind_test.py b/src/stim/dem/detector_error_model_pybind_test.py
index 25fc80ad2..3ebc6c0b7 100644
--- a/src/stim/dem/detector_error_model_pybind_test.py
+++ b/src/stim/dem/detector_error_model_pybind_test.py
@@ -540,3 +540,12 @@ def test_shortest_graphlike_error_remnant():
def test_init_parse():
assert stim.DemInstruction("error(0.125) D0 D1") == stim.DemInstruction("error", [0.125], [stim.DemTarget("D0"), stim.DemTarget("D1")])
+
+
+def test_without_tags():
+ dem = stim.DetectorErrorModel("""
+ error[tag](0.25) D5
+ """)
+ assert dem.without_tags() == stim.DetectorErrorModel("""
+ error(0.25) D5
+ """)