Skip to main content

Textual Reuse, Alignment, and Collation Engine — pairwise philological alignment with pluggable language packs

Project description

TRACE

Textual Reuse, Alignment, and Collation Engine — a Python library for philological alignment with pluggable language packs. Pairwise (v0.1) and simultaneous multi-witness (v0.2) alignment.

CI PyPI version Python versions License: MIT Documentation Status DOI

TRACE is designed for textual criticism, manuscript witness comparison, and the creation of digital synopses and critical editions. The core is language-agnostic; the first shipped language pack covers Biblical and Rabbinic Hebrew (hbo).


Highlights

  • Tokenizer pipeline with editorial-marker awareness ([reconstructed], ⟦deletion⟧, 〈insertion〉, (expanded), lacunae).
  • Tiered scoring returning (score, reason) per token pair — EXACT, NIQQUD_STRIPPED, PLENE_DEFECTIVE, ABBREVIATION, ORTHOGRAPHIC, INSERTION, OMISSION, NO_MATCH.
  • Pairwise aligner — semi-global Needleman–Wunsch with affine gap penalties (Gotoh) and a multi-token abbreviation lookahead (ר"ירבי ישמעאל).
  • Multi-witness aligner (v0.2) — N witnesses aligned simultaneously into a canonical variant graph (DAG) plus a derived aligned table view, via pairwise distances → UPGMA guide tree → POA-based progressive merge. Determinism is pinned by a permutation-invariance property test; correctness by a lossless-reconstruction property test.
  • Hebrew language pack with niqqud strip, plene/defective skeleton matching, gershayim/maqqef tokenizer hooks, and a seed lexicon of rabbinic abbreviations (extendable via Lexica.merge()).
  • I/O for plain text, JSON (round-trip for both pairwise and multi-witness results), eScriptorium exports, TEI XML, and Sefaria's public API (tracealign.io.sefaria.load_versions).
  • Reproducible — every AlignmentResult / MultiAlignmentResult carries trace_version and language_pack_version in its params.

Installation

pip install tracealign

Requires Python 3.10, 3.11, or 3.12. Pulls pydantic, numpy, lxml, and rapidfuzz.

From source

git clone https://github.com/bsesic/trace.git
cd trace
pip install -e ".[dev]"

The dev extra adds pytest and flake8 (the project's quality gates). For documentation contributions, use pip install -e ".[docs]" to add Sphinx, furo, and myst-parser.

Verifying the install

python -c "import tracealign; print(tracealign.__version__, tracealign.list_languages())"

Should print the current version and ['hbo'] (the Hebrew language pack registers itself on import).

Quick start — pairwise

import tracealign

w1 = tracealign.tokenize("שלום עולם רַבִּי דויד ר\"י אמר", lang="hbo", seq_label="W1")
w2 = tracealign.tokenize("שלום עולם רבי דוד רבי ישמעאל אמר", lang="hbo", seq_label="W2")

result = tracealign.align(w1, w2, lang="hbo")

print(f"total score: {result.total_score:.2f}")
print(f"summary: {dict(result.summary)}")
for m in result.matches:
    a = m.token_a.text if m.token_a else "—"
    b = m.token_b.text if m.token_b else "—"
    print(f"  {a:>10}{b:<10}  {m.reason.value:<18} {m.score:.2f}")

Output (abridged):

total score: 0.91
summary: {EXACT: 3, NIQQUD_STRIPPED: 1, PLENE_DEFECTIVE: 1, ABBREVIATION: 1}
       שלום ↔ שלום        exact              1.00
       עולם ↔ עולם        exact              1.00
      רַבִּי ↔ רבי         niqqud_stripped    0.95
       דויד ↔ דוד          plene_defective    0.85
        ר"י ↔ רבי          abbreviation       0.85   (primary)
        ר"י ↔ ישמעאל       abbreviation       0.00   (continuation)
        אמר ↔ אמר          exact              1.00

Quick start — multi-witness (v0.2)

import tracealign

witnesses = {
    "W1": tracealign.tokenize("שלום עולם רַבִּי דויד אמר",  lang="hbo", seq_label="W1"),
    "W2": tracealign.tokenize("שלום עולם רבי דוד אמר",       lang="hbo", seq_label="W2"),
    "W3": tracealign.tokenize("שלום עולם ר\"י אמר",          lang="hbo", seq_label="W3"),
    "W4": tracealign.tokenize("שלום עולם רבי דוד אמר טוב",   lang="hbo", seq_label="W4"),
}

result = tracealign.align_multi(witnesses, lang="hbo")

print(result.guide_tree.format_text())
print(result.table.format_text())

for node in result.graph.variants():
    readings = {wid: t.text for wid, t in node.tokens.items()}
    print(node.id, readings)

The MultiAlignmentResult exposes a canonical VariantGraph (DAG with witness trails), a derived AlignedTable (re-anchorable to any witness for presentation), a GuideTree (UPGMA-built, carrying the original distance matrix — useful for downstream stemmatic work), and the same reproducibility-aware params snapshot the pairwise aligner produces.

JSON persistence works the same way as the pairwise aligner, in its own module:

from tracealign.io import multi_result as mr_io

mr_io.dump(result, "alignment.json")
restored = mr_io.load("alignment.json")

See the documentation for the full API, more usage examples, the algorithm details, FAQs, and the design rationale.

Documentation

Section What it covers
Installation pip / from source / dev setup / docs build
Usage Tokenize, pairwise align, multi-witness align, work with the result, custom lexica, I/O
Details Tokenizer pipeline, scoring tiers, pairwise DP algorithm, multi-witness POA pipeline
FAQ Common questions about scope, language packs, performance, multi-witness semantics
Contributing Development workflow, TDD discipline, branch model

Project status

Current PyPI release 0.1.3 (v0.2.0 in flight on feature/v0.2-multi-witness)
Roadmap docs/ROADMAP.md — ten-stage long-term vision
v0.1 design spec docs/superpowers/specs/2026-04-28-trace-v0.1-design.md
v0.2 design spec docs/superpowers/specs/2026-05-21-trace-v0.2-multi-witness-design.md
Released stages 1 (pairwise + Hebrew pack)
In progress 2 (master alignment graph / multi-witness)
Future sub-projects Geniza anchor detection · Text-reuse · Apparatus / critical edition · Cross-tradition Hexapla · Stemmatic reconstruction · Allusion detection · Citation graphs · Reception history

Citation

If you use TRACE in academic work, please cite via the Zenodo concept DOI (always resolves to the latest archived release) or pick a specific version DOI from the Zenodo record. A CITATION.cff is at the repo root — GitHub's "Cite this repository" button generates APA / BibTeX / RIS automatically from it.

License

MIT © 2026 Benjamin Schnabel.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tracealign-0.3.0.tar.gz (38.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tracealign-0.3.0-py3-none-any.whl (39.3 kB view details)

Uploaded Python 3

File details

Details for the file tracealign-0.3.0.tar.gz.

File metadata

  • Download URL: tracealign-0.3.0.tar.gz
  • Upload date:
  • Size: 38.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for tracealign-0.3.0.tar.gz
Algorithm Hash digest
SHA256 e80cd4e31ffd1e2e3598fdae7298501555c029e954ef44172dc81b4f9a3918b4
MD5 cbef13120af5f6e0e7206ed5d73fb306
BLAKE2b-256 4f185b30ecf47d22324feda237e3de0dad1d2e98ec28d0fac4e6fe8817134eb7

See more details on using hashes here.

File details

Details for the file tracealign-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: tracealign-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 39.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for tracealign-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 97f19c84796c477190e5f16e07771398d3959478aa73c97e719a16a7ee101895
MD5 08e0d66734673f7f84491bea2363aacc
BLAKE2b-256 321d935f13d5c7a177ad492c043e2910b101a5e7123c4a32125f18e6be388655

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page