nx_vcf.nx
buildroot/runtime/nx_vcf.nx
about
nx_vcf.nx -- VCF (Variant Call Format) single-line writer.
license_tier: INDEPENDENT_REDERIVE
genealogy_id: international-research-sources/danecek-2011-vcf-spec-v4.2
G2.4 of NISHI_GENOMICS_SUBSTRATE_ROADMAP.md. Closes the variant
output side: called variants from snv_call become VCF lines that
every downstream tool (bcftools / vcftools / IGV / ClinVar /
dbSNP / gnomAD / nf-core pipelines) consumes.
VCF v4.2 data-line format (Danecek 2011, NCBI hosts canonical):
CHROM POS ID REF ALT QUAL FILTER INFO [FORMAT SAMPLE...]
tab-separated, terminated by LF (or CRLF on Windows)
G2.4 emits the 8 required fields:
CHROM : caller-supplied reference sequence name (no validation)
POS : 1-indexed (VCF spec); caller converts from substrate's
0-indexed internal coords
ID : "." (no rsID lookup yet; G2.4b composes dbSNP table)
REF : single ACGT letter from ref_code (NX_DNA_A/C/G/T)
ALT : single ACGT letter from alt_code
QUAL : integer Phred-scaled quality (typically 0..60 mapq-equivalent)
FILTER : "PASS" if pass_flag=1, "." if 0
INFO : "DP=<depth>" (caller can extend; G2.4 just emits DP)
Why a single-line writer (not a streaming serialiser):
VCF lines are line-by-line composable. Caller drives the per-
variant loop, calls this per variant, accumulates bytes into a
buffer or writes them to a file. Keeps this primitive small +
composable + testable without I/O surface.
What G2.4 does NOT do (deferred):
- VCF header (##fileformat=VCFv4.2 + ##INFO + ##FILTER + #CHROM) -- G2.4a
- Multi-allelic ALT (A>G,T) -- G2.4b
- FORMAT + per-sample fields (GT:AD:DP) -- G2.4c
- INFO extension (AF, AC, AN, MQ, MQRankSum, etc.) -- G2.4d
- VCF parsing (read existing VCF files) -- G2.4e
- bgzip + tabix indexing -- G2.4f
- VCF -> SAM rsID annotation lookup -- G2.4g
dependencies 4 imports · 2 importers
imports: nx_syscalls.nxnx_const.nxnx_sequence.nxnx_cigar.nx
imported by: nx_sam.nxnx_vcf_test.nx
structs
| none |
consts
| 118 | const NX_VCF_FIELD_POS: i64 = 0 |
| 119 | const NX_VCF_FIELD_REF: i64 = 1 |
| 120 | const NX_VCF_FIELD_ALT: i64 = 2 |
| 121 | const NX_VCF_FIELD_QUAL: i64 = 3 |
| 122 | const NX_VCF_FIELD_PASS: i64 = 4 |
| 123 | const NX_VCF_FIELD_DEPTH: i64 = 5 |
| 128 | const NX_VCF_VAR_FIELD_POS: i64 = 0 |
| 129 | const NX_VCF_VAR_FIELD_QUAL: i64 = 1 |
| 130 | const NX_VCF_VAR_FIELD_PASS: i64 = 2 |
| 131 | const NX_VCF_VAR_FIELD_DEPTH: i64 = 3 |
| 132 | const NX_VCF_VAR_FIELD_REF_LEN: i64 = 4 |
| 133 | const NX_VCF_VAR_FIELD_ALT_LEN: i64 = 5 |
functions
| 86 | func nx_copy_bytes(src: *u8, src_len: i64, |
| 98 | func nx_copy_byte(b: i64, dst: *u8, dst_off: i64, max_dst: i64) -> i64 |
| 105 | func nx_emit_int(n: i64, dst: *u8, dst_off: i64, max_dst: i64) -> i64 |
| 147 | func vcf_write_header(out_ascii: *u8, max_out: i64) -> i64 called by 1: main |
| 248 | func vcf_write_var_line(chrom: *u8, chrom_len: i64, |
| 343 | func vcf_write_snv_line(chrom: *u8, chrom_len: i64, |