Architecture¶
Prozor is an algorithm package, not a proteomics workflow. Peptide matching and protein inference remain reusable without coupling the core to a file format, dataframe, analysis container, or consuming application.
Dependency direction¶
consumer application
├── FASTA parsing and identifier policy
├── sequence normalization and validation policy
├── decoy/contaminant classification
├── persistence and provenance
└── prozor
├── matching/
│ ├── automaton.py
│ └── annotation.py
└── inference/
├── ties.py
└── greedy.py
matching/ and inference/ are independent algorithm families. Neither
imports the other; the consumer turns annotations into edges and composes them.
This boundary is enforced by import-linter. Both package markers are empty.
Production Prozor imports none of NumPy, SciPy, Pydantic, pandas, Polars, AnnData, MuData, FASTA parsers, or workflow engines. FASTA parsing belongs in a separate package because header schemas and validation are input policy, not matching or inference algorithms.
Public module boundaries¶
| Module | Responsibility |
|---|---|
prozor.matching.automaton |
Backend selection and exact multi-pattern matching. |
prozor.matching.annotation |
Peptide occurrences over mappings or streaming records. |
prozor.inference.ties |
Consequential tie value and default resolution operation. |
prozor.inference.greedy |
Edge-based deterministic greedy-parsimony inference. |
The root __init__.py remains empty. Public objects are imported from their
defining modules so ownership stays explicit.
Reproducibility guarantees¶
- backend requests and resolved implementations are both exposed;
autoselects Rust by default and retains a tested pure-Python fallback;- match coordinates are half-open and occurrence-level;
- duplicate occurrences collapse to unique edges before inference;
- identical-evidence proteins are grouped rather than arbitrarily selected;
- disjoint candidates do not invoke the tie resolver;
- overlapping, non-identical ties receive complete unexplained evidence;
- inferred members and group output order are stable; and
- both matching backends are exercised by the same behavioral fixtures.
Measured implementation choice¶
The benchmark suite retains readable name-set and lazy-priority-queue variants outside production. The integer-indexed incidence implementation is the production choice because it returns the same canonical groups while winning all measured graph shapes. Independent overlap components are processed together; this is both the correct tie boundary and the largest speedup.
Alternative tie scores and quantitative-profile clustering remain benchmark experiments. Correlation can reveal incoherent peptide subsets, but a second cluster without protein-unique evidence cannot identify which protein, proteoform, or interference generated it.
Executable enforcement¶
This document is not generated from Python. Its claims are kept executable in the smallest appropriate places:
.importlinterenforces independence betweenmatching/andinference/and forbids data/storage framework imports;tests/test_package.pykeeps package markers empty;- tests under
tests/matching/run the same behavioral contracts against both matching implementations; and - tests under
tests/inference/define grouping, tie, subsumption, and ordering behavior.
Provenance¶
The Python implementation is derived from the behavior of Witold Wolski's R
prozor package. A fixed fixture generated
from the R 0.3.4 source guards equivalent protein-group membership; the Python
implementation canonicalizes group identifier ordering.