Skip to content

rnabioco/escapepod-rs

Repository files navigation

escapepod

Warning

escapepod is alpha quality and under active development. APIs, CLI flags, and output formats may change without notice, and bugs are expected. Verify results against the official ONT pod5 tools before relying on it for anything important.

A Rust library and CLI for reading and writing Oxford Nanopore POD5 files.

PyPI Rust License

escapepod demo

Highlights

  • Fast - Up to 9x faster than Python pod5 tools on large-file operations
  • Memory efficient - Memory-mapped I/O for large files
  • Full featured - View, inspect, merge, filter, subset
  • BAM integration - Filter reads by alignment status
  • Crash-safe writes - Output is staged and renamed into place, so an interrupted run never leaves a corrupt archive or damages an existing one

Output durability

Every POD5 archive is written to a temporary file beside its destination and renamed into place only once it is complete and valid. An error, a panic, or a Ctrl-C therefore leaves the destination either untouched (if a file was already there) or absent — never truncated. escpod also traps SIGINT and SIGTERM (the latter is what SLURM sends on scancel and at walltime expiry) to remove staging files on the way out.

Renaming does not by itself make the bytes durable against a machine crash. Use --fsync file to sync each output before it is renamed, or --fsync full to also sync the directory. The default is --fsync none, which is the right trade on scratch filesystems where output is cheap to regenerate.

If a run is killed outright (kill -9, node failure), staging files may be left behind. They are identifiable by prefix:

find <output-dir> -name '.escpod-tmp-*'

Experimental features — repack, resquiggle, index, and barcode demultiplexing (demux) — live behind Cargo feature flags. See the docs for status and build instructions.

GPU-accelerated DTW for demux classify is available via --features gpu (opt-in, experimental). Uses NVRTC to compile a CUDA kernel at runtime — no nvcc needed at build time, only the CUDA driver + libnvrtc at run.

Performance

Numbers are for the I/O-bound operations where runtime is large enough to matter; sub-second commands (inspect, view) are omitted. Measured with benchmarks/benchmark.sh (hyperfine, 3 runs) versus the official Python pod5 (v0.3.36) on ~500k RNA004 reads (two ~250k-read files).

Command escapepod pod5 Speedup
filter 361 ms 3.4 s 9.3x
subset 1.4 s 5.1 s 3.6x
merge 2.0 s 6.7 s 3.3x

Install

CLI (escpod)

The escpod binary lives in the escapepod-cli crate.

Default build (stable commands only):

cargo install --git https://github.com/rnabioco/escapepod-rs escapepod-cli

Opt into experimental commands:

# repack, resquiggle, index
cargo install --git https://github.com/rnabioco/escapepod-rs escapepod-cli --features experimental

Python library

The escapepod Python package — a pod5-compatible API — is published on PyPI:

uv pip install escapepod

Prebuilt wheels cover CPython 3.9+ (abi3) on Linux (x86_64/aarch64, manylinux + musllinux) and macOS (x86_64/arm64). See the Python API docs for usage and building from source.

License

MIT. The resquiggle module is an independent implementation of algorithms inspired by fishnet (see Acknowledgments), not a derivative of its source, and is MIT-licensed like the rest of the workspace.

Acknowledgments

escapepod-rs stands on the shoulders of giants. The format, algorithms, and prior tools that made this project possible:

POD5 format and Oxford Nanopore tooling

  • POD5 file format — Oxford Nanopore Technologies. escapepod-rs is a pure-Rust reader/writer for the POD5 specification. The official C++/Python reference is licensed under MPL-2.0; we do not redistribute any of its code.
  • Tombo — Oxford Nanopore Technologies. The t-test changepoint segmentation in escapepod-signal::segmentation::ttest is based on the Tombo algorithm.
  • dorado and remora — used as references for signal handling conventions.

Barcode demultiplexing — KleistLab (van der Toorn / von Kleist labs)

The escpod demux workflow is a pure-Rust reimplementation of algorithms from the KleistLab:

  • WarpDemuX — DTW+SVM barcode classifier. We reimplement the model JSON loader, DTW distance, RBF kernel, OvO dual coefficients, Platt scaling, and probability coupling to be byte-for-byte compatible with exported WarpDemuX models.

  • ADAPTed (Adapter and poly(A) Detection And Profiling Tool) by Wiep K. van der Toorn et al. The LLR boundary detector in escapepod-signal::segmentation::llr is adapted from ADAPTed, and escapepod-demux::adapter_cnn is a runtime port of ADAPTed's BoundariesCNN through tract-onnx.

    Note on CNN weights: ADAPTed's trained CNN weights are licensed under CC BY-NC 4.0 and are not bundled with escapepod-rs. The cnn-detect feature ships only the inference code; users must export their own ONNX file from a local ADAPTed install (see scripts/export_adapter_cnn_to_onnx.py) and accept ADAPTed's license terms separately.

Signal-to-base resquiggle

  • fishnet by Brickner et al. The banded DP refinement and signal rescaling in escapepod-signal::resquiggle is inspired by fishnet.
  • Remora — Oxford Nanopore Technologies. Referenced for signal-to-sequence anchoring conventions.
  • nanopolish by Jared Simpson et al. Referenced for its event-alignment approach to signal-to-base assignment.

Signal compression

  • StreamVByte by Daniel Lemire. The SVB16 variant used by POD5's VBZ codec is derived from StreamVByte's design; our Rust scalar + SSSE3/AVX2 implementations are clean-room.
  • zstd — the second stage of the VBZ pipeline.

Citation

If you use escapepod-rs in research, please also cite the upstream tools whose algorithms it implements (WarpDemuX, ADAPTed, fishnet, POD5).

If we've missed an acknowledgment, please open an issue.

Releases

Contributors

Languages