nx_sequence_ambig.nx
buildroot/runtime/nx_sequence_ambig.nx
about
nx_sequence_ambig.nx -- N / IUPAC ambiguity sidecar for nx_sequence.
license_tier: INDEPENDENT_REDERIVE
genealogy_id: international-research-sources/iupac-1985-nucleic-acid-nomenclature
G0.5a of NISHI_GENOMICS_SUBSTRATE_ROADMAP.md. Closes the
N-handling gap in nx_sequence: G0.1 dna_pack refuses any non-ACGT
input (returns -1), which is correct for clean fixtures but
blocks real-world FASTQ reads where N is the universal "unknown
base" marker (Illumina low-quality cycles, ONT undetermined,
PacBio CCS hard-mask, reference-genome assembly gaps).
Design -- parallel sidecar bitset:
The 2-bit packed bases array stays the same as G0.1 -- existing
primitives (revcomp / k-mer / FM-index / alignment) read it
unchanged. N positions are encoded as code-A (0b00) in the bases
array AND have the corresponding bit set in n_bits[]. Caller
checks dna_is_n at any position to know whether the A code is
real or a stand-in for N.
Why a sidecar bitset, not 4-bit IUPAC codes throughout:
- Preserves bit-for-bit compatibility with G0.1 primitives
- Memory: 1 bit per base vs 4 bits = same 4x compression factor
applied to ambiguity tracking
- Most positions are NOT ambiguous; sidecar is mostly zeros
and compresses well in any downstream blob storage
- Full IUPAC (R Y K M S W B D H V) is rare outside reference
ambiguity codes and lives in G0.5b nx_sequence_iupac (a
separate primitive that uses 4-bit codes per position)
Bitset layout (matches 2-bit DNA packing convention):
bit (7 - pos%8) of n_bits[pos/8] holds the N-flag for base pos.
MSB-first within byte to mirror the bases packing.
Position 0 is in the high bit (bit 7) of n_bits[0].
API:
dna_pack_ambig(ascii, len, out_bases, out_nbits) -> i64
dna_unpack_ambig(bases, nbits, len, out_ascii) -> i64
dna_is_n(nbits, pos) -> i64
dna_set_n(nbits, pos, is_n) -> i64
dependencies 3 imports · 3 importers
imports: nx_syscalls.nxnx_const.nxnx_sequence.nx
imported by: nx_pileup.nxnx_pileup_test.nxnx_sequence_ambig_test.nx
structs
| none |
consts
| none |
functions
| 84 | func dna_is_n(nbits: *u8, pos: i64) -> i64 |
| 94 | func dna_set_n(nbits: *u8, pos: i64, is_n: i64) -> i64 |
| 112 | func dna_pack_ambig(ascii: *u8, len: i64, |
| 139 | func dna_unpack_ambig(bases: *u8, nbits: *u8, len: i64, out_ascii: *u8) -> i64 |