Skip to content

FAQ

I'm new: where do I start?

Run the getting-started tutorial. It uses example data that ships in the examples/ folder, so you can get a full result in a couple of minutes without any data of your own. Any unfamiliar term is defined in the glossary.

Which mode do I use: fasta or vcf?

  • Comparing sequences (one gene from several species/strains, already aligned)? → eskaks fasta gives you dN/dS.
  • Comparing individuals in a population (you have a reference genome and a VCF of variants)? → eskaks vcf gives you pN/pS per gene.

What input files do I need?

  • eskaks fasta: one codon-aligned FASTA (sequences in frame, all the same length). If yours aren't aligned yet, run MAFFT + PAL2NAL or MACSE first.
  • eskaks vcf: three files, a reference FASTA, a GFF3 annotation, and one or more VCF files. The contig/chromosome names must match across all three.

My eskaks vcf output is empty or all NA

Almost always a name mismatch: the chromosome name in the VCF (e.g. chr1) must be identical to the sequence name in the reference FASTA (>chr1) and the first column of the GFF3. eskaks warns when it can't reconcile them, run with -v to see the details. Also check that your GFF3 has CDS features and that --genetic-code matches your organism (11 for bacteria).

eskaks says my annotation is a GTF, not a GFF3

eskaks vcf reads GFF3 only. The two formats differ in the attributes column: GFF3 writes Parent=gene1;gene=dnaA, GTF writes gene_id "gene1"; transcript_id "t1"; with a space and quotes. Because a GTF row carries no Parent=, gene_id= or ID=, reading one as GFF3 finds no gene to group exons into, so eskaks stops with an error instead of guessing. Convert first:

gffread annotation.gtf -o annotation.gff3
# or
agat_convert_sp_gxf2gxf.pl -g annotation.gtf -o annotation.gff3

Converting is not just cosmetic. A GTF CDS excludes the stop codon, which is written as a separate stop_codon row, so a converter is what puts the full coding sequence back together.

My gene has several transcripts, which one is used?

The longest CDS. When a GFF3 gives one gene several mRNA / transcript children, eskaks keeps the longest coding sequence as the representative and warns, naming the genes it collapsed and how many alternatives it dropped. One row per gene is what keeps each gene at exactly one test in the multiple-testing family: emitting one row per isoform would both duplicate the gene in the table and change every q-value in the genome. If you need a specific transcript, filter the GFF3 down to it before running.

Why is eskaks so much faster?

Three main reasons:

  1. Precomputed lookup tables: All 4,096 codon pairs have their diffs/sites precomputed at startup. Each pairwise comparison is just table lookups + a final correction formula.

  2. Cache optimization: The Li model's lookup table (288 KB) fits in L2 cache. Identical codons (~95% in typical alignments) use a separate 1.5 KB table that fits in L1 cache.

  3. Parallel + streaming: Rayon distributes pairs across CPU cores, and a dedicated writer thread handles I/O without blocking computation.

Why do I get NaN values?

NaN means the substitution proportion has reached saturation (p ≥ 0.749 for Nei-Gojobori, or denominator ≤ 0 for Li). This happens when sequences are too divergent, the correction formula breaks down because there have been so many substitutions that the signal is lost.

What to do: This is biologically correct. Very divergent sequences simply can't be reliably compared at the nucleotide level. Consider using protein-level methods instead.

Which model should I use?

  • Nei-Gojobori: Simpler, faster, good for quick scans. Use when you want results comparable to most published analyses.
  • Li (1993): More accurate because it accounts for the well-known transition/transversion bias. Use when accuracy matters more than speed (though the speed difference is minimal).

My sequences have internal stop codons

eskaks warns about these automatically. Common causes: - Wrong reading frame: Shift your sequences by 1 or 2 bases - Pseudogene: The gene has been inactivated - Frameshift mutation: An indel has disrupted the reading frame - Wrong genetic code: Try --genetic-code 2 (mitochondrial) etc.

Can I use eskaks with non-standard genetic codes?

Yes! Use --genetic-code <N> with any of the 20 supported NCBI tables. Run eskaks --list-codes to see all options.

How do I enable tab-completion?

Print a completion script for your shell and install it, e.g. for Bash:

eskaks --completions bash | sudo tee /etc/bash_completion.d/eskaks > /dev/null

zsh, fish, elvish, and powershell are also supported — see Installation.

How do I control what eskaks prints?

Each run ends with a short "Done" confirmation (counts, model, output files) on stderr. Use --quiet to show only errors, -v/-vv for progress and debug detail, or --summary for the full statistics block. RUST_LOG overrides the log level entirely.

How do I cite eskaks?

Cite the archived version you actually ran. Each release is deposited on Zenodo, and 0.1.0 is 10.5281/zenodo.21992154:

Ruiz-Rodriguez P, Coscollá M. eskaks: fast pairwise dN/dS and per-gene pN/pS from sequences or VCFs. Zenodo, 2026. https://doi.org/10.5281/zenodo.21992154

To refer to eskaks in general rather than to one version, use the concept DOI 10.5281/zenodo.21992153, which always resolves to the newest release.

The CITATION.cff file carries the same metadata in machine-readable form, and GitHub's "Cite this repository" button reads it to hand you BibTeX or APA directly.

What is the difference between dN/dS and pN/pS?

dN/dS measures fixed substitutions between diverged sequences (from aligned FASTA). It applies corrections for multiple substitutions (Jukes-Cantor or Kimura).

pN/pS measures polymorphism within a population (from VCF). It counts raw variant proportions without multiple-hit correction. Use eskaks fasta for dN/dS and eskaks vcf for pN/pS.

Can I use eskaks as a library?

Yes. eskaks exposes a lib.rs with public modules. Add it as a dependency in your Cargo.toml:

[dependencies]
eskaks = { git = "https://github.com/PathoGenOmics-Lab/eskaks.git" }

Then use eskaks::models::nei::NeiTables or eskaks::models::li::LiTables directly.