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.
- 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
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.
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 |
The escpod binary lives in the escapepod-cli crate.
Default build (stable commands only):
cargo install --git https://github.com/rnabioco/escapepod-rs escapepod-cliOpt into experimental commands:
# repack, resquiggle, index
cargo install --git https://github.com/rnabioco/escapepod-rs escapepod-cli --features experimentalThe escapepod Python package — a pod5-compatible API — is published on PyPI:
uv pip install escapepodPrebuilt 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.
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.
escapepod-rs stands on the shoulders of giants. The format, algorithms, and prior tools that made this project possible:
- 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::ttestis based on the Tombo algorithm. - dorado and remora — used as references for signal handling conventions.
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::llris adapted from ADAPTed, andescapepod-demux::adapter_cnnis a runtime port of ADAPTed'sBoundariesCNNthroughtract-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-detectfeature ships only the inference code; users must export their own ONNX file from a local ADAPTed install (seescripts/export_adapter_cnn_to_onnx.py) and accept ADAPTed's license terms separately.
- fishnet by
Brickner et al. The banded DP refinement and signal rescaling in
escapepod-signal::resquiggleis 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.
- 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.
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.
