diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9a8e5e1..e6bdfda 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,16 @@ and Recore uses semantic versioning.
### Fixed
+- `evolutionary_events.tsv` no longer presents a gain or loss built on gaps
+ Recore never searched as an audited call. New columns `absent_not_searched`
+ and `not_searched_reason` count those absences and say why; a call none of
+ whose absences were searched drops one support level (and so in score and
+ priority), and every affected call is tagged in `mechanism_detail` and
+ explained in `recommended_wording`.
+- `benchmarks/compare_runs.py` counted `NOT_SEARCHED_*` cells as calls, so a
+ comparison against a run from before those states listed every unsearched
+ cell as a new correction. They are absences now, and a cell searched in one
+ run and not the other is `search_coverage_changed`.
- A gap Recore never searched no longer reads like one it searched and found
empty. The states file writes `NOT_SEARCHED_LOW_PREVALENCE`,
`NOT_SEARCHED_NO_CLUSTER_SEQUENCE` or `NOT_SEARCHED_NO_FASTA` where it wrote
diff --git a/benchmarks/README.md b/benchmarks/README.md
index d177e23..b79e17f 100644
--- a/benchmarks/README.md
+++ b/benchmarks/README.md
@@ -112,7 +112,10 @@ python3 benchmarks/compare_runs.py --old old_recore_output --new new_recore_outp
The comparison uses the union of matrix cells, so clusters or genomes present
in only one run are reported as `old_only_cell` / `new_only_cell` instead of
-being silently ignored.
+being silently ignored. A cell absent in both runs but searched in only one of
+them (an `ABSENT` against a `NOT_SEARCHED_*`, as older runs wrote `ABSENT` for
+both) is `search_coverage_changed`, not a correction, and is counted apart from
+`changed_cells`.
Generate a compact Markdown/HTML report:
diff --git a/benchmarks/compare_runs.py b/benchmarks/compare_runs.py
index 372c426..c6b53d3 100644
--- a/benchmarks/compare_runs.py
+++ b/benchmarks/compare_runs.py
@@ -72,19 +72,32 @@ def read_evolution(run_dir: Path) -> dict[str, dict[str, str]]:
return {row["gene_cluster"]: row for row in reader}
+def is_absent(state: str) -> bool:
+ """No presence and no evidence: a gap searched and found empty, or one that
+ was never searched. A NOT_SEARCHED_* state is an absence, and counting it as
+ a call made every unsearched cell a "new correction" against older runs,
+ which wrote ABSENT for both."""
+ return state in {"", "ABSENT"} or state.startswith("NOT_SEARCHED")
+
+
def classify_change(old_state: str, new_state: str) -> str:
if old_state == "MISSING_CELL":
return "new_only_cell"
if new_state == "MISSING_CELL":
return "old_only_cell"
- old_present = old_state not in {"", "ABSENT"}
- new_present = new_state not in {"", "ABSENT"}
if old_state == new_state:
return "same"
+ old_present = not is_absent(old_state)
+ new_present = not is_absent(new_state)
if not old_present and new_present:
return "new_correction"
if old_present and not new_present:
return "lost_correction"
+ if not old_present and not new_present:
+ # Absent in both runs, but searched in one and not the other, or left
+ # out of the search for a different reason: the search changed, the
+ # matrix did not.
+ return "search_coverage_changed"
return "state_changed"
@@ -128,6 +141,7 @@ def main() -> int:
"old_only_cell",
"new_only_cell",
"changed_cells",
+ "search_coverage_changed",
])
for cluster in sorted(cluster_counts):
counts = cluster_counts[cluster]
@@ -138,7 +152,7 @@ def main() -> int:
+ counts["old_only_cell"]
+ counts["new_only_cell"]
)
- if changed:
+ if changed or counts["search_coverage_changed"]:
writer.writerow([
cluster,
counts["same"],
@@ -148,6 +162,7 @@ def main() -> int:
counts["old_only_cell"],
counts["new_only_cell"],
changed,
+ counts["search_coverage_changed"],
])
old_evo = read_evolution(args.old)
@@ -199,6 +214,7 @@ def main() -> int:
"state_changed",
"old_only_cell",
"new_only_cell",
+ "search_coverage_changed",
]:
writer.writerow([key, cell_counts[key]])
diff --git a/docs/assets/example-report.html b/docs/assets/example-report.html
index 917620c..6600d2d 100644
--- a/docs/assets/example-report.html
+++ b/docs/assets/example-report.html
@@ -4203,7 +4203,7 @@
fill="#0265ba"
d="m 734.53229,859.93067 c 6.32782,-1.50009 12.68772,2.36408 14.27189,8.67088 1.58527,6.30791 -2.19262,12.71869 -8.47839,14.38804 -4.14185,1.10073 -8.55473,-0.11394 -11.55159,-3.17829 -2.99576,-3.06324 -4.11197,-7.50267 -2.91942,-11.61907 1.19255,-4.1164 4.50691,-7.27256 8.67751,-8.26156 z"
style="stroke-width:1.10626" />
-Corrected pangenome matrix