get_MNV

Reference

Output Formats

get_MNV can write TSV, VCF, BCF, and JSON metadata files.

Default TSV Output

Default file name:

<input_name>.MNV.tsv

With --sample all, one file is written per sample instead, carrying the sample in its name:

<input_name>.sample_<SAMPLE>.MNV.tsv

Characters that cannot appear in a file name are replaced, so a sample called sample/1:bad becomes sample_1_bad. Two samples whose names come out the same after that replacement would write to one file, so the run stops and names them instead of letting one overwrite the other.

Each file holds the variants that sample carries, not every variant in the cohort. A record lists every ALT seen at that site across all samples, so the sample's GT decides which of them belong to it: a genotype of 0/0 carries none, 1/2 carries both alleles of a multiallelic record, and a genotype that is absent or a no-call (./.) keeps the allele, since unknown is not absence. A sample carrying nothing gets a file with only the header. Two adjacent substitutions merge into an MNV only for the samples that carry both.

Use this format for spreadsheets, downstream parsing, and quick inspection.

Main columns:

ColumnMeaning
ChromosomeContig name
GeneGene or feature name. Intergenic variants are marked as intergenic.
PositionsOne position for SNPs, multiple comma-separated positions for MNVs, in ascending genomic order on both strands. The per-SNV columns (Reference Bases, Base Changes, SNP AA Changes, SNP Codon, Event Components, and the read-support columns) are parallel arrays in that same order.
Reference BasesReference bases at those positions.
Base ChangesAlternative bases.
AA ChangesAmino acid change after combining all SNVs in the codon. The protein's first codon is read as an initiator: any initiation codon of the translation table (GTG and TTG among them in bacteria) starts the protein as Met. A change that loses the initiator is written Met1?, as HGVS asks, since where translation then starts cannot be predicted; one that swaps it for another initiation codon keeps the Met (Met1Met). An indel that deletes the start codon, or inserts bases inside it, loses it even when the codon it leaves first is an initiation codon too. An in-frame insertion that repeats the residues just before it is written as their duplication, at the 3'-most copy (Phe433dup, His68_Leu70dup), as HGVS asks; any other insertion names the residues on either side of it (Lys2_Phe3insGly).
SNP AA ChangesAmino acid change for each SNV considered separately.
Local AA ChangesExon-local numbering, which is what get_MNV reported before 1.1.2. Identical to AA Changes when the feature has no transcript context (a genes TSV, a prokaryotic or single-exon CDS, and the first exon of a spliced model), and different for the later exons of a spliced transcript, where AA Changes counts from the start of the protein and this counts from the start of the exon.
Local SNP AA ChangesPer-SNP amino acid changes in local numbering.
Variant TypeSNP, MNV, SNP/MNV, or INDEL.
Change TypeSynonymous, non-synonymous, stop gained/lost, unknown, etc.
Reference CodonOriginal codon, in the transcript's own orientation: on a minus-strand gene these are the coding-strand bases, not the genomic ones, so the codon always translates to the amino acid reported beside it.
SNP CodonCodon with individual SNP substitutions, same orientation as Reference Codon.
MNV CodonCodon with all grouped substitutions, same orientation as Reference Codon.
Event ClassCanonical allele event class: snp, mnv, insertion, deletion, delins, complex_indel, or symbolic.
Event ComponentsREF/ALT decomposition such as SNV:10:A>G, INS:10:+T, or DEL:11-12:TG.
SO TermSequence Ontology consequence term (missense_variant, synonymous_variant, stop_gained, start_lost, frameshift_variant, inframe_deletion, intergenic_variant, …). Variants near an internal exon-exon junction of a spliced transcript also carry a splice term: splice_donor_variant / splice_acceptor_variant (the two essential intronic bases at each intron end, HIGH) or splice_region_variant (the exon's first or last 3 bases, or the intron's 3rd-8th bases, LOW). An exonic change near a junction is combined with its coding consequence, e.g. missense_variant&splice_region_variant for a substitution and frameshift_variant&splice_region_variant for an indel, as one row rather than two. A frameshift that destroys the start codon is frameshift_variant&start_lost, matching the start_lost a substitution there gets. A junction means a real intron: CDS segments that abut or overlap (a ribosomal-slippage join such as SARS-CoV-2 ORF1ab) are one continuous reading frame and carry no splice terms. A variant inside an intron but away from its splice sites is intron_variant (MODIFIER), reported against its gene rather than as intergenic, and a variant in a feature declared non-coding is non_coding_transcript_exon_variant (MODIFIER) with no amino-acid change.
ImpactPredicted impact following SnpEff/VEP conventions: HIGH, MODERATE, LOW or MODIFIER. A combined splice/coding consequence keeps the more severe impact.
GranthamGrantham distance and conservation category of a missense change (e.g. 177 (radical)); - for synonymous, nonsense or non-coding changes.
MNV Consequence ShiftHow the combined MNV compares with its individual SNVs: MNV-gained (more severe than any single SNV, which is what per-SNV annotators miss), MNV-masked (a nonsense SNV rescued by its neighbour) or Concordant. - for single SNVs.
DBS ClassCOSMIC DBS78 class of the doublet this row's substitutions belong to: exactly two adjacent substituted bases, wherever they fall, including across a codon boundary or outside genes, e.g. CC>TT (reverse-complement collapsed, so GG>AA reports as CC>TT). Both rows of a doublet split by a codon boundary carry it. - for single SNVs, indels, non-adjacent substitutions, and runs of three or more adjacent bases, which COSMIC counts as multi-base substitutions instead.
Declared PhaseThe phase the input VCF declared for this row's alleles, as cis:12345 (verdict and PS phase set) or just cis when the caller phased without a phase set. Read from a |-separated GT; a / genotype is the caller saying it did not resolve the phase, and is reported as -. |contradicted-by-reads is appended when the BAM leaves the claim no room: a declared cis that not one spanning read carries whole, or a declared trans that every informative read carries. This is the caller's claim, not an observation; the phasing columns beside it are the evidence. - for single-position rows and unphased input.
MNV Phasing SupportBAM-derived phasing (linkage) support: among the reads that observe every position of the codon and carry the least-supported constituent SNV, the fraction that also carry the full MNV haplotype. 1.0000 = perfect co-occurrence (a genuine haplotype); low values mean the SNVs largely fall on different molecules (a same-codon coincidence, not a real MNV). 0.0000 is a finding: reads did span the codon and none carried both. - means the question could not be answered: no --bam, a single SNV, or no read reaching across the codon (common when a codon straddles an intron and the fragments are shorter than the intron).
Haplotype LDRead-level linkage disequilibrium (D') between the variants this row claims travel together, over the molecules that observed them. It covers both kinds of multi-variant row: a codon MNV and a local indel haplotype. A co-occurrence ratio cannot separate a haplotype from an accident of frequency: two substitutions on 90% of molecules each are found together on 81% of them by arithmetic alone, and the ratio calls that 0.9. D' measures the excess over what the two frequencies predict, normalised by the most it could have been. +1 = they travel together as far as their frequencies allow, so the MNV is one haplotype. ~0 = they co-occur exactly as chance predicts, so they merely share a codon. -1 = they exclude each other: both present, never on one molecule, which in a haploid population is two competing lineages rather than one variant. With three or more variants the weakest pair decides, since the row claims one molecule carries all of them. It answers a different question from the read count beside it: the count is how many molecules are this combination, while D' is whether its variants co-occur more than their own frequencies predict, so a haplotype carried by few molecules can still be perfectly linked and one carried by many can be a coincidence. - when no molecule observed the variants together, or when one of them is on every such molecule or none, which leaves nothing to correlate. Only present with --bam.
Haplotype LD pTwo-tailed Fisher exact p-value for that table, so a D' of 1.0 from four molecules is not read as one from four hundred. - under the same conditions as the column above. Only present with --bam. See Linkage.
MNV Phasing ReadsHow many reads MNV Phasing Support was computed from, so 1.0000 from 3 reads is not read as 1.0000 from 300. - exactly when that column is -, which is not the same condition as the two linkage columns beside it. Only present with --bam.
Frameshift PhasingWhat the reads said about this codon sharing molecules with each upstream indel, as trans:1234:0/18: the verdict, the indel's position, and the cis reads out of the reads able to answer. Several are joined with |. A codon that is not labelled frameshifted otherwise looks the same whether the reads proved the indel is on other molecules or nobody asked; - is that second case. Only present with --bam.
NMD PredictionNonsense-mediated decay prediction for a premature stop under the 50-nt rule: NMD-triggering when the PTC is more than 50 nt upstream of the last exon-exon junction, NMD-escaping when it is in the last exon or within 50 nt of that junction. - for variants without a premature stop and for transcripts with no exon-exon junction. Requires a spliced (GFF/GTF transcript) CDS model whose segments are separated by real introns; a single CDS segment, or segments joined by ribosomal slippage, has no junction.
HGVS g.HGVS genomic descriptor: g.100A>G for an SNV, the allele-bracket g.[28G>T;30T>A] for an MNV, and g.101_102del / g.100_101insTG / g.101delinsC / g.295_297dup for indels. An indel in a repeat is placed at its 3'-most equivalent position in the reference, and an insertion that repeats the bases before it is a dup, as HGVS asks; the Positions column keeps the input's placement. No reference-accession prefix.
HGVS c.HGVS coding descriptor, numbered from the CDS start with coding-strand bases: c.30A>G (SNV), the allele bracket c.[28G>A;30T>C] (MNV), or c.31del, c.30_31insGCT, c.28_30delinsTCGCTA, c.295_297dup (indels, with inserted bases on the coding strand). Like HGVS g., an indel is placed 3'-most, here along the coding sequence (never past its end), and a copy of the bases before it is a dup. A base in an intron of a spliced transcript is numbered from the nearer exon, c.100+2 after an exon's last base and c.101-5 before an exon's first, so intronic and splice-site rows carry a descriptor too (c.100+5G>A, c.101-2_101-1del), and an indel wholly inside an intron is placed 3'-most within it. An insertion right after an internal exon's last base is placed at the exon junction, as the protein change reads it. - for intergenic and non-coding variants and for a change reaching a UTR or the flank (c.-15, c.*3), which the tool does not number. The consequence columns keep reading the change where the input placed it, as VEP does by default.
SBS96 ContextCOSMIC SBS96 class of each single-base substitution in the row, in Event Components order, written from the pyrimidine strand: A[C>T]G for a C>T between A and G, and a G>A in the same context read from the other strand as C[C>T]T. DBS or MBS for a base of a run of two, or three or more, adjacent substitutions, which belongs to that run rather than to the single-base spectrum. - for an entry whose trinucleotide context cannot be read (contig end, ambiguous base) and for rows with no substitution. The report counts these into a mutational spectrum.
Adjacent SubstitutionsHGVS genomic descriptor of the run of two or more adjacent substituted bases this row's substitutions belong to, e.g. g.103_104delinsAT. Every row the run touches carries the same descriptor, which is how the two codon rows of a doublet split by a codon boundary are tied together, whether the caller wrote it as one record or two. Read from positions, as COSMIC tools do; read support for the run as a whole is not counted. - when no substitution of the row has a substituted neighbour.
CatalogueThe --catalogue entries this row matches, each written label (gene variant) and separated by ; , with codon reading only or per-SNV reading only added when a codon row matches through one of its two readings alone. - when nothing matches or no catalogue was given.
Catalogue WithheldThe --catalogue entries this row would match through a reading no molecule carries, written as in Catalogue with the reason: codon reading only: no molecule carries the whole codon when none of the molecules spanning the codon carries every substitution and D' says they exclude each other, per-SNV reading only: no molecule carries this substitution without the rest when every molecule with a substitution carries the whole codon and D' says they travel together. Such an entry names an amino acid nothing in the sample carries, so it is kept apart from Catalogue rather than stated as found. See Read-level linkage. - when nothing is withheld. Only present with --bam.
ID83 ClassCOSMIC ID83 class of a pure insertion or deletion, as SigProfiler labels it: 1:Del:C:2 for a C deleted from a run of three, 3:Ins:R:5 for a three-base insertion next to five or more copies of itself, 4:Del:M:2 for a four-base deletion with two bases of microhomology at its breakpoint. One-base indels are written from the pyrimidine (C or T), and copies are counted on both sides of the event, so the class does not depend on where in a repeat the caller placed it. - for substitutions, deletion-insertions and symbolic alleles.

Extra columns when --bam is used:

ColumnMeaning
SNP ReadsReads carrying each individual SNV without the full MNV haplotype. On a row where every read carries the whole haplotype this is 0 for each constituent and the count lives in MNV Reads, so the two columns partition the support rather than double-count it.
SNP Forward ReadsForward-strand count for the reads above.
SNP Reverse ReadsReverse-strand count for the reads above.
MNV ReadsReads supporting the full MNV haplotype.
MNV Forward ReadsForward-strand MNV support.
MNV Reverse ReadsReverse-strand MNV support.
Total ReadsDepth at the variant positions.
SNP FrequenciesPer-position SNP frequencies.
MNV FrequenciesMNV haplotype frequency.
Event ReadsExact reads supporting an indel/complex event.
Event Forward ReadsForward-strand exact event support.
Event Reverse ReadsReverse-strand exact event support.
Event DepthReads with an observed allele across the indel/complex event span.
Event FrequencyExact event reads divided by event depth.

Exact event support is CIGAR-aware. A read must reconstruct the same local ALT sequence and, for complex haplotypes, contain the expected insertion and deletion components. This prevents net-neutral insertion/deletion combinations from being counted as support merely because their sequence looks like an MNV.

Frequency columns are calculated from BAM support. --min-snp-frequency and --min-mnv-frequency use these same BAM-derived values. The filters are independent: --min-snp-frequency applies to individual SNP observations, and --min-mnv-frequency applies to phased MNV haplotypes. In mixed SNP/MNV calls, a row or VCF record is kept when either component passes its own active threshold. Read-count and strand-support filters (--snp, --mnv, --min-snp-strand, and --min-mnv-strand) follow the same independent SNP/MNV behavior.

When a codon-level MNV overlaps an indel, the MNV row is kept as a positional context row but its amino-acid effect is marked Unknown with Change Type = Indel overlap. If BAM reads support the full combined event, get_MNV emits a separate exact complex_indel row with the combined REF/ALT, event components, and event read support.

Indel overlap follows VCF interbase semantics. Deletions overlap a feature by their deleted reference span. Insertions overlap a feature only when the inserted sequence falls between two reference bases inside that feature, so an insertion anchored at the final feature base is reported outside that feature.

Example:

Chromosome	Gene	Positions	Base Changes	AA Changes	Variant Type	Change Type
MTB_anc	Rv0095c_Rv0095c	104838	T	Asp126Glu	SNP	Non-synonymous
MTB_anc	Rv0095c_Rv0095c	104941, 104942	T, G	Gly92Gln	SNP/MNV	Non-synonymous

VCF Output

Write VCF with:

--convert

or write both TSV and VCF with:

--both

Default file name:

<input_name>.MNV.vcf

Use --vcf-gz for compressed output:

<input_name>.MNV.vcf.gz

Common INFO fields:

FieldMeaning
GENEGene or feature name
AAAmino acid change
CTChange type
TYPEVariant type
ECCanonical allele event class
COMPREF/ALT event components
ODPOriginal depth from the input variant file
OFREQOriginal allele frequency from the input variant file
SR, SRF, SRRSNP reads: total, forward, reverse
MR, MRF, MRRMNV reads: total, forward, reverse
DPDepth recalculated from BAM
FREQFrequency recalculated from BAM
ER, ERF, ERRExact indel/complex event reads: total, forward, reverse
EDPExact event depth for indel/complex alleles
EFREQExact event frequency for indel/complex alleles
SBPSNP strand-bias p-value, in scientific notation (1.923e-7), which is the value --min-strand-bias-p compared
MSBPMNV strand-bias p-value, same notation
SO, IMPACTSequence Ontology consequence term and predicted impact
GDGrantham distance of a missense change
MNVSHIFTCombined MNV consequence vs. its individual SNVs
DBSCOSMIC DBS78 class of the doublet this record belongs to, across codon boundaries too (e.g. CC>TT)
MNVPSMNV phasing support (of the codon-spanning reads carrying the limiting SNV, the fraction carrying the full haplotype)
MNVPRReads that ratio was computed from
FSPHRead-level phasing with each upstream indel, as verdict:position:cis/informative
DPHASEPhase the input VCF declared for this row, verdict:phase_set
LDLinkage disequilibrium D-prime between the codon's substitutions
LDPFisher exact p-value for that linkage table
NMDNonsense-mediated decay prediction for a premature stop (50-nt rule)
HGVSGHGVS genomic descriptor (MNV allele-bracket ; percent-encoded)
HGVSCHGVS coding descriptor for a coding substitution or indel (; percent-encoded)
SBS96COSMIC SBS96 class of each single-base substitution, comma-separated in COMP order (- where the context cannot be read, DBS or MBS for a base of a run of adjacent substitutions)
ADJSUBHGVS genomic descriptor of each run of two or more adjacent substituted bases the record belongs to, shared by every record of the run
CAT--catalogue entries the record matches, as in the Catalogue column (percent-encoded)
CATW--catalogue entries withheld because no read carries the reading they match through, as in the Catalogue Withheld column (percent-encoded, only with --bam)
ID83COSMIC ID83 class of a pure insertion or deletion (e.g. 1:Del:C:2)
ANNThe record's annotation in the format snpEff writes, described below

The VCF header records the get_MNV version, command line, and thresholds used. When --emit-filtered is enabled, VCF records below read-support, frequency, strand-support, or strand-bias thresholds are written with FILTER tags such as LowSupport, LowFrequency, StrandSupport, or StrandBias; otherwise they are skipped.

The ANN field

Every record also carries its annotation in the format snpEff writes, which bcftools +split-vep, SnpSift and most VCF tooling read without knowing get_MNV's own keys:

bcftools +split-vep -a ANN -f '%POS\t%REF\t%ALT\t%Gene_Name\t%Annotation\t%HGVS.c\t%HGVS.p\n' sample.MNV.vcf

Each entry is about its own record's ALT. On the record of one base of a codon that changes two or more, that is the base on its own, as the record's AA already reads; the codon's combined change is on the codon's record, marked INFO_COMPOUND_ANNOTATION, snpEff's mark for an effect that comes from combining variants. SO, IMPACT and CT stay the codon's on every record.

FieldContent
AlleleThe record's ALT
Annotation, Annotation_ImpactSequence Ontology term and impact, as in SO and IMPACT
Gene_Name, Gene_ID, Feature_IDThe gene as get_MNV names it; empty for an intergenic record
Feature_Typetranscript, or intergenic_region
Transcript_BioTypeprotein_coding, or Noncoding for a gene that is not translated
HGVS.c, HGVS.pThe record's coding and protein change (p.Ser450Leu, p.Met1?, p.Ter23Argext*?); empty where AA holds a label rather than a change
ERRORS / WARNINGS / INFOINFO_COMPOUND_ANNOTATION on a codon's record

Rank, the cDNA, CDS and protein positions and the distance are left empty. A value that would break the field is percent-encoded, like the allele list in c.[274G>C%3B275G>A].

An ANN the input already carried is not dropped by --keep-original-info: its entries for the record's ALT follow get_MNV's, so a lab's own snpEff categories stay with the base they were written for. They are left off a codon's record, whose allele no input record had.

The bundled example's input was annotated by snpEff 4.1, and on its 802 bases both annotate, get_MNV's entry gives the same consequence, impact, HGVS.c and HGVS.p as snpEff's apart from two cases: snpEff 4.1 also calls the last bases of a single-exon gene a splice region, and one gene's annotated first codon is not a start codon. On the two bases in RNA genes both say the same thing, under two names for one term: non_coding_transcript_exon_variant is what Sequence Ontology renamed snpEff's non_coding_exon_variant to.

BCF Output

Write BCF with:

--bcf

BCF requires VCF output mode, so use it with --convert or --both.

The conversion is done by bcftools view, taken from PATH. Without bcftools installed the run warns, writes no BCF, and still exits 0 with its TSV and VCF intact. --index-vcf-gz works the same way through tabix.

Default file name:

<input_name>.MNV.bcf

JSON Files

Three flags write JSON, and every payload carries a schema_version so a consumer can tell which shape it is reading.

Summary JSON

Write with:

--summary-json run.summary.json

Top-level keys:

KeyMeaning
schema_versionPayload version, currently 1.0.0
sampleThe sample named with --sample, or null when the flag was not passed. null does not mean no sample was used: a multi-sample VCF still falls back to the first sample column, and its genotype and FORMAT fields still decide the metrics
dry_runWhether --dry-run was in force
bam_providedWhether a BAM was read, which is what decides the read-support fields
translation_tableNCBI translation table number used
inputsThe input paths: vcf, fasta, annotation, bam, plus checksums
output_tsv, output_vcf, output_bcfThe files this run wrote, null for each one it did not
contigsOne entry per contig, with its own counts
timingsparse_inputs_ms, process_ms, emit_ms, total_ms. In the aggregate of a --sample all run the first three add up the samples' own, which run side by side, and total_ms is the cohort's wall-clock time
globalThe run-wide counts, below

Inside global:

KeyMeaning
contig_countContigs seen
snp_records_in_vcfVariant entries kept from the input on that contig. Not the file's line count: an entry the targeted sample's genotype does not carry is not counted, so the same file gives a different number under a different --sample
mapped_genesGenes that had at least one variant on them
produced_variantsAnnotated variants, before the output filters
snp_variants, mnv_variants, snp_mnv_variants, indel_variants, intergenic_variantsThe same total split by type
region_cache_hits, region_cache_missesBAM region cache, only meaningful with --bam

These counts are what get_MNV produced, before the output filters

produced_variants and the per-type counts beside it are taken after annotation and before the read-support, frequency and strand filters that decide what reaches the TSV. On a filtered run the two disagree on purpose: the same command can log produced variants=941 and write a one-row TSV, and the HTML report, which counts rows, will say 1. Read the summary as what the annotation found and the TSV as what passed.

--sample all writes a different object, not a longer one

Every key above moves. A --sample all summary has mode set to sample_all, sample_count, sample_names, one aggregate object holding run-wide totals, and a samples array holding one object per sample. Each of those, and aggregate too, has the single-sample shape described above, so data["global"]["produced_variants"] becomes data["aggregate"]["global"]["produced_variants"].

aggregate sums the counts across samples and names no output file of its own: aggregate.output_tsv is null, and the per-sample paths are on the samples entries. Its contigs array is always empty as well, because the per-contig breakdown belongs to each sample; read it from the samples entries. Branch on the key that only one shape has:

import json

data = json.load(open("run.summary.json"))
if data.get("mode") == "sample_all":
    totals = data["aggregate"]["global"]
    per_sample = {s["sample"]: s["global"] for s in data["samples"]}
else:
    totals = data["global"]
    per_sample = {data["sample"]: data["global"]}

Run Manifest

Write with:

--run-manifest run.manifest.json
KeyMeaning
schema_versionPayload version
tool_versionThe get_MNV version that ran
command_lineThe command with every path reduced to its file name and the program written as get_mnv, so the manifest can be shared without publishing the directory layout it ran in. It records what was run, not a line that can be pasted back into a shell
timestamp_unixSeconds since the Unix epoch
summaryThe whole summary payload, unchanged
output_checksumsoutput_tsv_sha256, output_vcf_sha256, output_bcf_sha256, each null for a file this run did not write

With --sample all the manifest follows the summary: mode, sample_names, aggregate and samples, with no top-level summary key, and each entry in samples carries its own output_checksums.

Error JSON

Write errors as JSON with:

--error-json run.error.json

Written only when the run fails, which makes its presence the signal:

KeyMeaning
schema_versionPayload version
codeThe stable error code, such as E002
exit_codeThe process exit status, matching the table in Troubleshooting
messageThe same text the run printed
{
  "schema_version": "1.0.0",
  "code": "E002",
  "exit_code": 3,
  "message": "Cannot open VCF file '/no/such.vcf': No such file or directory (os error 2)"
}

Interactive HTML report

--report <FILE.html> writes a single self-contained HTML file for exploring the called variants. It embeds its data, loads no external scripts or fonts, and therefore opens offline by double-clicking and can be attached to an email or archived with the results.

Open the example report: 941 variants called from the single-sample dataset bundled in example/, so it is the real output of the command below rather than a mock-up. Regenerate it with scripts/build_example_report.sh. The cohort views (the matrix rows, haplotype recurrence) fill out with --sample all or --report-from across several samples.

# Report for one run
get_mnv --vcf sample.vcf --fasta ref.fasta --gff ref.gff --report sample.html

# One report covering every sample of a multi-sample VCF
get_mnv --vcf cohort.vcf --fasta ref.fasta --gff ref.gff --sample all --report cohort.html

# Cohort processed one sample per run: aggregate the TSVs afterwards
get_mnv --report-from results/*.MNV.tsv --report cohort.html

With --report-from no pipeline runs: the report is built from get_MNV TSV files that already exist, which is the usual shape in a Nextflow or Snakemake workflow that calls get_MNV once per sample. Each file becomes one sample, labelled by its file name with the .MNV.tsv suffix removed (TB-001.MNV.tsv becomes TB-001).

The report contains:

The report follows the operating-system light or dark theme and has its own toggle. Because it is built from the TSV, --report needs TSV output: it works with the default output mode and with --both, but not with --convert alone or with --dry-run. Read-support columns (frequency, depth) are populated only when the run used --bam.

Size scales with the number of variants. Repeated fields are dictionary-encoded, so a cohort of tens of thousands of variants stays in the low megabytes.

Notes

Variant-by-sample matrix

--matrix <FILE.tsv> writes the same variants the report shows as one table with a column per sample, for loading into R or pandas:

get_mnv --report-from results/*.MNV.tsv --matrix cohort_matrix.tsv
get_mnv --vcf cohort.vcf --fasta ref.fasta --gff ref.gff --sample all --matrix cohort_matrix.tsv

It is built from the same TSVs as the report, so it works in a normal run, with --sample all and with --report-from, with or without --report beside it.

ColumnDescription
Chromosome, Gene, Positions, Reference Bases, Base ChangesThe variant. A codon MNV and a lone SNV at one of its bases are different variants here, as they are in the TSV.
AA Changes, Variant Type, SO Term, ImpactTaken from the first sample that carries the variant.
Samples CalledHow many samples have a call.
one column per sampleThe allele frequency the reads gave (0.4500); called for a call with no measured frequency, which is every call of a run without a BAM and a call the BAM does not cover; NA where the sample has no call of this variant. A sample can carry one of its bases inside a different variant, such as a codon MNV, and still read NA here.

NA is never written as 0 on purpose: a get_MNV TSV cannot tell a reference base from a position no read covered, so a missing call means "reference or no coverage". Rows are sorted by contig, then position.

Edit this page on GitHub