v9.0.0 — Level 7: a from-scratch nanopore basecaller
BioForge now reads raw electrical signal from Oxford Nanopore devices and turns it
into bases with a classical basecaller built entirely from scratch — pure NumPy, no
neural network, no GPU. The same algorithmic family (Viterbi dynamic programming) as
the Level 3 aligner.
What's new
- Signal I/O:
read_pod5(modern) andread_fast5(legacy) readers. The only
place an optional dependency is used (pip install "bioforge[nanopore]"), purely
to open the file format. - Pure-NumPy science: normalisation, event detection, our own pore-model
estimation (estimate_pore_model— we learn the table, not copy it), and a Viterbi
decoder with stay/step/skip states (viterbi_basecall) plus per-read
moment-scaling. basecall(): raw signal to bases in one call.
Honest, reproducible numbers
On real captured R9.4 signal (E. coli, n=36, identity to the production Guppy
basecall): mean ~70%, median ~71%, range 63–77%. That is in the range of the
historical classical basecallers (nanocall ~68–85%) and far below the ~99% of the
neural Dorado. That gap is the honest point: the classical route is an R9-era method
and, without AI, it has a ceiling. Reproduce it: python tools/bench_basecaller.py.
Modern R10 chemistry is out of scope by design (9-mers → 262,144 hidden states make
an O(T·states) Viterbi infeasible on a laptop, and ONT ships no flat R10 k-mer table)
— which is the real reason the field moved to neural basecalling.
Requirements
- Python >= 3.10, NumPy. For nanopore signal I/O:
pip install "bioforge[nanopore]".
Tests
523 passing.