Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Input Variants VCF

You can supply a VCF of variants to force into the simulation:

input_vcf: /path/to/variants.vcf.gz

eidolon will place every variant from the VCF into the corresponding position in the simulated reads and the output VCF. Random variants are still generated at mutation_rate for all positions not covered by the input VCF; set mutation_rate: 0.0 to disable random variants entirely and output only the provided set of variants.

Requirements

  • The VCF must be single-sample (one sample column).
  • Every record must include GT in the FORMAT field. eidolon uses the genotype to determine whether to apply the variant to all reads covering the position (homozygous, e.g. 1/1) or only a probabilistic subset (heterozygous, e.g. 0/1). Records without GT are rejected.
  • Contig names must match the short names derived from the reference FASTA (text after > up to the first whitespace character). Variants on unrecognised contigs are skipped with a warning.
  • Both .vcf and .vcf.gz files are accepted.

Supported variant types

TypeConditionHandled
SNPREF and ALT both single baseYes
Insertionsingle-base REF, multi-base ALTYes
Deletionmulti-base REF, single-base ALTYes
Symbolic SVALT is <DEL> / <DUP> / <CNV> / <INS> / <INV> / breakend / other <TAG>Yes — see “Symbolic / structural variants” below
Literal complexmulti-base REF and multi-base ALT (literal bases)No — skipped with warning

Lowercase bases

Bases are case-insensitive. A soft-masked (lowercase) reference is read as plain A/C/G/T, so it simulates exactly as its uppercase copy does. REF and ALT bases from the input VCF are written to the output VCF in uppercase, breakend ALTs included: t]chr2:300] is written T]chr2:300]. The mate’s contig name keeps its case, since contig names are case-sensitive, and <...> IDs such as <INS:ME:Alu> are written as given. VCF 4.2 treats lowercase bases as uppercase, so this changes no variant, only how it is spelled.

Symbolic / structural variants

Symbolic ALTs (VCF 4.2 §1.4) are accepted and round-tripped to the output VCF verbatim apart from base case (see “Lowercase bases” below), with INFO/END, INFO/SVLEN, and INFO/CN preserved. As of v1.10, eidolon can also generate symbolic SVs de novo from a learned model — opt in by setting sv_rate_scale: 1.0 (or higher) in your gen-reads YAML; see “De novo SV generation” below.

SVEffect on read depthEffect on read sequence
<DEL>hom → ×0, het → ×(ploidy−1)/ploidy; or ×CN/ploidy if INFO/CN is setnone — bases in the deleted span just stop producing reads
<DUP>hom → ×2, het → ×(ploidy+1)/ploidy; or ×CN/ploidy if INFO/CN is setnone — extra reads come from the forward-strand reference
<CNV>×CN/ploidy when INFO/CN is set; otherwise warned and passed through with no depth changenone
<INS>none (insertion at a single anchor base — no span to modulate)none — the inserted sequence is not synthesized
<INV>none in this releasenot modeled — reads come from the forward-strand reference, not the inverted sequence
Breakends, unknown <TAG>nonenone — round-tripped only

DEL anchor convention: for <DEL>, POS is the unaffected base immediately before the deletion (per VCF 4.2), so the modulated span is [POS+1, END] in 1-based coords. For <DUP> / <CNV> / <INV>, POS is the first base of the affected region, so the span is [POS, END].

When an SV zeroes out coverage (hom <DEL> or INFO/CN=0), the mutation rate over the same span is also zeroed so de-novo SNPs don’t pollute the output VCF with variants that never appear in reads.

Current caveats

  • Multi-allelic records: only the first ALT allele is used; additional alleles are silently ignored. Split multi-allelic records with bcftools norm -m - before passing to eidolon. (This is true for both literal and symbolic ALTs — <DEL>,<DUP> on the same line is treated as the first ALT only.)
  • REF allele verification: eidolon does not check that the REF field matches the reference sequence at that position. Mismatches will produce biologically incorrect output without any warning.
  • Literal complex variants: records whose REF and ALT are both multi-base strings (and the ALT is literal bases, not a <TAG>) are skipped with a logged warning and do not appear in the output.
  • <INV> interior is forward-strand: inversion junction reads are emitted (the chimeric signal callers use to detect the inversion), but reads from the interior of an inverted span are still transcribed from the forward-strand reference. The <INV> record round-trips to the output VCF.
  • Breakends: <BND> junction reads are generated (chimeric reads spanning the mate locus; validated against Manta — see the ACCESS report), and the record round-trips to the output VCF.

De novo SV generation

eidolon can sample SVs directly from a learned SvModel rather than relying on user-supplied records: <DEL>, <DUP>, <CNV>, <INV> and literal insertions are drawn per contig, and <BND> translocations are drawn separately as mate pairs across two contigs. <BND> therefore needs a reference with at least two contigs — on a single-contig reference the correct yield is zero rather than a same-contig junction, so a chr22-only run reports truth BND: 0 by construction. Generation is off by default (opt-in via sv_rate_scale) so v1.9 pipelines remain unchanged.

To enable, add a single line to your gen-reads YAML:

sv_rate_scale: 1.0
  • 0.0 (the default) disables de novo SV generation entirely — only input_vcf records flow through.
  • 1.0 reproduces the rate from the trained model.
  • Larger values scale the rate proportionally for stress testing.

When enabled, eidolon consults MutationModel.sv_model:

  1. If you trained your own model with eidolon gen-mut-model -c <yaml> against an SV-rich VCF (e.g. a gnomAD-SV slice), the model file includes a fitted SV component covering type / length / copy-number / homozygous frequencies. Pass it via mutation_model: /path/to/your.json.gz in the gen-reads YAML.
  2. If you don’t supply a model, gen-reads loads the bundled default. The default carries approximate gnomAD-SV v2.1 parameters — useful for kicking the tires, but not a substitute for retraining on data that matches your downstream use case. See eidolon-core/src/models/sv_model_defaults.rs for the parameter sources.

Per-contig sampling: Poisson count from per_base_rate × contig_len × sv_rate_scale → weighted type pick → log-normal length (rejected outside [50bp, contig_len / 4]) → uniform anchor with overlap and N-gap rejection → INFO/CN draw for <CNV> → Bernoulli for genotype.

De novo records merge with input_vcf SVs and flow through the same depth-modulation path, so simulated coverage and the golden VCF round-trip behave identically for both sources. compare-vcfs skips both into the skipped.symbolic bucket — symbolic ALTs aren’t byte-comparable.

Caveats:

  • The bundled default is a literature-derived approximation, not a refit on the actual gnomAD VCFs. Don’t use it for distribution-faithful benchmarking — retrain.
  • <INV> and breakends are not generated (the read content for either isn’t modeled yet).
  • A trained model’s sv_model field is None if the training VCF lacked sufficient SV observations (< 2 per type after filtering). Loading that model with sv_rate_scale > 0 is harmless — generation just no-ops.