Skip to content

v2.11.0: fix nanopore reverse-strand m6A encoding

Choose a tag to compare

@mtcicero26 mtcicero26 released this 07 May 18:41
· 476 commits to main since this release

Bug fix

Nanopore-fiber mode silently dropped all m6A on reverse-aligned reads, causing every reverse read to be called as one whole-read nucleosome regardless of actual m6A density. Forward-aligned reads were unaffected. For typical ONT fiber-seq BAMs where ~50% of reads are reverse-aligned, this means half the data was producing incorrect calls.

Root cause

The nanopore encoder only looked for A positions in SAM SEQ (target_int=0, do_rc=False). For reverse-aligned reads, SAM SEQ is the reverse-complement of the basecalled-forward strand — basecalled A's appear as T's. The MM/ML parser correctly converted mod positions to SEQ frame (v2.9 fix), but those positions landed on T's which the encoder skipped entirely.

Fix

encode_from_query_sequence() now accepts an is_reverse parameter. In nanopore-fiber mode with is_reverse=True, it encodes T positions with RC context to recover the basecalled-forward emission space. Forward reads continue to encode A positions with forward context as before. PacBio-fiber and DAF modes are unaffected.

Workaround for older versions

Use --seq pacbio instead of --seq nanopore — PacBio mode already handles both A and T positions with RC, giving strand-symmetric calls (though with slightly miscalibrated emissions).

Tests

5 new regression tests validate forward/reverse strand symmetry in nanopore encoding mode.

All 297 tests pass.