Skip to content

v9.0.0 — Level 7: a from-scratch nanopore basecaller

Choose a tag to compare

@erlanders177 erlanders177 released this 09 Aug 17:51
· 36 commits to main since this release

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) and read_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.