Skip to main content

FN6

Fast, efficient and scalable SNP distance calculation from disk.

FN5 reworked into Rust. Approximately 10x faster, easier to use and maintain, and adds checking for matching reference and mask in FN6 saves, all while retaining interoperability with FN5 saves.

Quickstart

Requirements

Version >= 1.85.0 of cargo, the Rust package manager. Recommended installation can be found here. If an earlier version is installed, please try rustup update instead.

CLI installation

You don't need to clone this repository, but if you're working on M.Tuberculosis then you will probably want to make a copy of masquerade_std_tb_plus.mask and it might be a convenient place from which to obtain NC_000962.3.fasta.

cargo install fn6

Mask

Masking is used for SNP distance calculation to avoid counting SNPs at problematic sites, e.g homoplastic sites. This repo includes an example mask for Mycobacterium Tuberculosis (specifically NC_000962.3) generated by https://github.com/oxfordmmm/masquerade

Masking can be ignored if you would prefer by omitting the --mask argument

Reference

A reference is required to compute SNP distances from FASTA files. Included in this repo are reference genomes for Mycobacterium Tuberculosis and SARS-CoV-2

Cut off

As SNP distances become decreasingly useful for outbreak detection as they increase, FN6 saves computation by stopping compute early when SNPs increase above a given cutoff. This intentionally results in missing distances as they add little information - if you run FN6 and recieve no results, the likely cause is that none of the given samples lie within the SNP cut off.

For M.Tuberculosis, the evolution rate is roughly 1 SNP per year, so transmission networks often look at SNP thresholds of 3, 6, or 12 SNPs.

By default, FN6 uses a cut off of 20 SNPs. This can be controlled with the --cutoff argument. To remove the cutoff, set this arbitrarily high; e.g --cutoff 99999999. This can be useful for things such as building a neighbour joining tree.

Calculate distances directly from FASTA files

With all of your .fasta files within path/to/your/fastas:

fn6 compute --reference NC_000962.3.fasta --mask masquerade_std_tb_plus.mask --directory path/to/your/fastas --allow-fasta

Reference

All FASTA inputs can be optionally gzipped.

Fast, efficient and scalable SNP distance calculation from disk.

Usage: fn6 <COMMAND>

Commands:
  reference-compress  Reference compress a sample genome. This will create a .fn6 file that can be used for fast comparisons with other samples. The .fn6 file is a binary file that contains the compressed representation of the sample genome, as well as metadata about the reference and mask used for compression
  compute             Compute SNP distances
  add-samples         Add some samples to existing samples. Only computes the extra distances required rather than all pairwise distances
  bulk-compress       Reference compress a set of genomes. Dumber than `ReferenceCompress` as it doesn't allow for setting specific IDs or output paths, but much faster as it can be parallelized across samples
  help                Print this message or the help of the given subcommand(s)

Options:
  -h, --help     Print help
  -V, --version  Print version

Reference compress

Reference compress a sample genome. This will create a .fn6 file that can be used for fast comparisons with other samples. The .fn6 file is a binary file that contains the compressed representation of the sample genome, as well as metadata about the reference and mask used for compression

Usage: fn6 reference-compress [OPTIONS] <REFERENCE> <SAMPLE> [MASK]

Arguments:
  <REFERENCE>  Path to the reference genome FASTA file
  <SAMPLE>     Path to the sample genome FASTA file
  [MASK]       Path to the mask file. The mask file is a text file containing the positions of the reference genome that should be masked (i.e., ignored) during the analysis. The positions are 0-based and should be separated by newlines

Options:
      --id <ID>          ID for this sample
      --output <OUTPUT>  Output path for the .fn6 file. If not provided, the .fn6 file will be saved in the same directory as the sample FASTA file with the same name but with a .fn6 extension
      --debug            Whether to print debug information to stderr
  -h, --help             Print help

Compute

Compute SNP distances

Usage: fn6 compute [OPTIONS]

Options:
  -r, --reference <REFERENCE>
          Path to the reference genome FASTA file. Only required if >=1 of the samples specified are fasta files
  -m, --mask <MASK>
          Path to the mask file. The mask file is a text file containing the positions of the reference genome that should be masked (i.e., ignored) during the analysis. The positions are 0-based and should be separated by newlines. Only required if >=1 of the samples specified are fasta files
  -s, --samples <SAMPLES>...
          Paths to sample files. Either .fn6, .fn5 or FASTA files. If FASTA files are provided, the `allow-fasta` flag must also be used. They will then be reference compressed on the fly (using the provided reference and mask) before distance computation
  -d, --directory <DIRECTORY>
          Directory to load from. Either .fn6, .fn5 or FASTA files. If FASTA files are provided, the `allow-fasta` flag must also be used. They will then be reference compressed on the fly (using the provided reference and mask) before distance computation
      --cutoff <CUTOFF>
          SNP threshold [default: 20]
  -o, --output <OUTPUT>
          Path to a file to store distances in using a space-separated file. Columns are sample1, sample2, distance. If not provided, distances will be printed to stdout in the same format
      --fasta-extension <FASTA_EXTENSION>
          FASTA file extension to look for when loading from a directory. Only used if loading from a directory and if reference and mask are provided (i.e., if FASTA files need to be reference compressed on the fly). Default is "fasta" [default: fasta]
      --allow-fasta
          Whether to enable computation from FASTAs. It is recommended to pre-cache the reference compressed versions of the new samples to speed up computation
      --debug
          Whether to print debug information to stderr
  -h, --help
          Print help

Add samples

Add some samples to existing samples. Only computes the extra distances required rather than all pairwise distances

Usage: fn6 add-samples [OPTIONS]

Options:
  -r, --reference <REFERENCE>
          Path to the reference genome FASTA file. Only required if >=1 of the samples specified are fasta files
  -m, --mask <MASK>
          Path to the mask file. The mask file is a text file containing the positions of the reference genome that should be masked (i.e., ignored) during the analysis. The positions are 0-based and should be separated by newlines. Only required if >=1 of the samples specified are fasta files
  -s, --existing-samples <EXISTING_SAMPLES>...
          Paths to existing sample files. Either .fn6, .fn5 or FASTA files. If FASTA files are provided, the `allow-fasta` flag must also be used. They will then be reference compressed on the fly (using the provided reference and mask) before distance computation
  -d, --existing-directory <EXISTING_DIRECTORY>
          Directory to load existing saves from. Either .fn6, .fn5 or FASTA files. If FASTA files are provided, the `allow-fasta` flag must also be used. They will then be reference compressed on the fly (using the provided reference and mask) before distance computation
  -S, --new-samples <NEW_SAMPLES>...
          Paths to sample files to add. Either .fn6, .fn5 or FASTA files. If FASTA files are provided, the `allow-fasta` flag must also be used. They will then be reference compressed on the fly (using the provided reference and mask) before distance computation
  -D, --new-directory <NEW_DIRECTORY>
          Directory to load new saves from. Either .fn6, .fn5 or FASTA files. If FASTA files are provided, the `allow-fasta` flag must also be used. They will then be reference compressed on the fly (using the provided reference and mask) before distance computation
      --cutoff <CUTOFF>
          SNP threshold [default: 20]
  -o, --output <OUTPUT>
          Path to a file to store distances in using a space-separated file. Columns are sample1, sample2, distance. If not provided, distances will be printed to stdout in the same format
  -f, --fasta-extension <FASTA_EXTENSION>
          FASTA file extension to look for when loading from a directory. Only used if loading from a directory and if reference and mask are provided (i.e., if FASTA files need to be reference compressed on the fly). Default is "fasta" [default: fasta]
      --allow-fasta
          Whether to enable computation from FASTAs. It is recommended to pre-cache the reference compressed versions of the new samples to speed up computation
      --debug
          Whether to print debug information to stderr
  -h, --help
          Print help

Bulk Compress

Reference compress a set of genomes. Dumber than `ReferenceCompress` as it doesn't allow for setting specific IDs or output paths, but much faster as it can be parallelized across samples

Usage: fn6 bulk-compress [OPTIONS] <REFERENCE> [MASK]

Arguments:
  <REFERENCE>  Path to the reference genome FASTA file
  [MASK]       Path to the mask file. The mask file is a text file containing the positions of the reference genome that should be masked (i.e., ignored) during the analysis. The positions are 0-based and should be separated by newlines

Options:
  -s, --samples <SAMPLES>...
          Paths to sample files. Either FASTA files or .fn6 files
  -d, --directory <DIRECTORY>
          Directory to load from
  -l, --list <LIST>
          Line separated file to read paths from
  -o, --output <OUTPUT>
          Output directory to write saves to. Useful when using `list` as it consolidates saves in a single directory. If not provided, the .fn6 files will be saved in the same directory as their corresponding FASTA files with the same name but with a .fn6 extension
      --fasta-extension <FASTA_EXTENSION>
          FASTA file extension to look for when loading from a directory [default: fasta]
      --debug
          Whether to print debug information to stderr
  -h, --help
          Print help

Performance

Both FN5 and FN6 produce the same results, but with condsiderable time differences. Below is a table of comparison between FN5 and FN6 performance on varying sets of Mycobacterium tuberculosis samples, randomly selected from the CRyPTIC dataset https://doi.org/10.5281/zenodo.16041005 All of the benchmarks were run on the same laptop with an Intel i9-13900H and 32GB RAM, directly from SSD.

N Samples (passing QC) Comparisons FN5 Reference compression FN5 Compute pairwise matrix (per comparison) FN5 Compute pairwise matrix (per comparison) no cutoff FN6 Reference compression FN6 Compute pairwise matrix (per comparison) FN6 Compute pairwise matrix (per comparison) no cutoff FN6 Compute pairwise matrix from FN5 saves (per comparison) FN6 Compute pairwise matrix from FN5 saves (per comparison) no cutoff
100 4,950 1.394s 44ms (8.9µs) 175ms (35.6µs) 0.17s 7.93ms (1.60µs) 81.28ms (16.42µs) 9.29ms (1.88µs) 53.49ms (10.81µs)
250 31,125 1.698s 208ms (6.7µs) 1087ms (34.9µs) 0.33s 32.29ms (1.04µs) 280.36ms (9.01µs) 24.75ms (795.00ns) 270.21ms (8.68µs)
500 124,750 3.506s 628ms (5.0µs) 3905ms (31.3µs) 0.67s 84.04ms (673.00ns) 921.34ms (7.39µs) 48.75ms (390.00ns) 1010ms (8.13µs)
750 280,875 5.091s 1298ms (4.6µs) 8179ms (29.1µs) 0.92s 114.78ms (408.00ns) 2000ms (7.14µs) 91.94ms (327.00ns) 5580ms (19.85µs)
1000 499,500 6.735s 2287ms (4.6µs) 14299ms (28.6µs) 0.90s 152.88ms (306.00ns) 3480ms (6.98µs) 143.89ms (288.00ns) 8910ms (17.85µs)
1500 (1493) 1,113,785 11.363s 7481ms (6.7µs) 100481ms (90.2µs) 2.03s 300.10ms (269.00ns) 9130ms (8.20µs) 296.32ms (266.00ns) 22720ms (20.40µs)
2000 (1992) 1,983,044 16.377s 30805ms (15.5µs) 205160ms (103.5µs) 2.69s 487.53ms (245.00ns) 18390ms (9.27µs) 613.04ms (309.00ns) 42150ms (21.25µs)

All of the times to compute a pairwise matrix include the time taken to read the saves from disk. The time taken to load the saves from disk varies by tool, but is an important component of the real world runtime.

Mean time to load a save from disk across all above runs:

FN5 FN6 FN6 (from FN5 saves)
64.6µs 25.0µs 41.3µs

This also demonstrates the importance of utilising a SNP cutoff within the computation. Otherwise, per sample comparison times scale according to how disparate samples are.

Testing

For simplicity, testing is based on a dummy genome with 80 bases. This allows for known SNPs to be introduced and manually calculated

cargo test

Release files for fn6 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for fn6 0.2.1
File
fn6-0.2.1-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
fn6-0.2.1-cp310-abi3-musllinux_1_2_x86_64.whl CPython 3.10 abi3 Linux musl 1.2+ x86-64 Details
fn6-0.2.1-cp310-abi3-musllinux_1_2_i686.whl CPython 3.10 abi3 Linux musl 1.2+ x86-32 Details
fn6-0.2.1-cp310-abi3-musllinux_1_2_armv7l.whl CPython 3.10 abi3 Linux musl 1.2+ ARMv7l Details
fn6-0.2.1-cp310-abi3-musllinux_1_2_aarch64.whl CPython 3.10 abi3 Linux musl 1.2+ ARM64 Details
fn6-0.2.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details
fn6-0.2.1-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl CPython 3.10 abi3 Linux glibc 2.17+ IBM System/390x Details
fn6-0.2.1-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl CPython 3.10 abi3 Linux glibc 2.17+ PowerPC 64-le Details
fn6-0.2.1-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl CPython 3.10 abi3 Linux glibc 2.17+ ARMv7l Details
fn6-0.2.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details
fn6-0.2.1-cp310-abi3-manylinux_2_12_i686.manylinux2010_i686.whl CPython 3.10 abi3 Linux glibc 2.12+ x86-32 Details
fn6-0.2.1-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details

Total release size: 9.6 MB

Release files / fn6-0.2.1-cp310-abi3-win_amd64.whl

Download URL fn6-0.2.1-cp310-abi3-win_amd64.whl
Size 270.0 kB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
4a5c4ea551a532b51eb46a2c6d4737353e3a039f1d36c4a639c446bbf0766fc1
BLAKE2b-256 checksum
How to use checksums
8eb282bb570ba64fce01511809ea118750c2a7e1b28b2da1aa41c4df762d83f7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / fn6-0.2.1-cp310-abi3-musllinux_1_2_x86_64.whl

Download URL fn6-0.2.1-cp310-abi3-musllinux_1_2_x86_64.whl
Size 991.7 kB
Tags CPython 3.10 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
83780b940d9015da20e9f90a5e1864fb809dfe15b5887c076c94f5fd1674746a
BLAKE2b-256 checksum
How to use checksums
796e6a19b8315a4026e4145c2216405af67689713c20704a6eb9ffbd7f560a66
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / fn6-0.2.1-cp310-abi3-musllinux_1_2_i686.whl

Download URL fn6-0.2.1-cp310-abi3-musllinux_1_2_i686.whl
Size 1.0 MB
Tags CPython 3.10 Linux musl 1.2+ x86-32 abi3
SHA-256 checksum
How to use checksums
7024bbaca74e6dc746af6a9775625722badefe5dddaf3bea35d6a044e66ce8a7
BLAKE2b-256 checksum
How to use checksums
4000c632e59e6891e05705269430b514d22acc76481ac74026d7cdd3daca16e6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / fn6-0.2.1-cp310-abi3-musllinux_1_2_armv7l.whl

Download URL fn6-0.2.1-cp310-abi3-musllinux_1_2_armv7l.whl
Size 1.1 MB
Tags CPython 3.10 Linux musl 1.2+ ARMv7l abi3
SHA-256 checksum
How to use checksums
29fc415c096d960a4ac6ee05dd5e427899f98b2ca3d5be7f4ba53bf69b1b5c22
BLAKE2b-256 checksum
How to use checksums
db7cc420724afe29cac420e01f642b7cefd4f010cbdca9701f80833c970fc85c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / fn6-0.2.1-cp310-abi3-musllinux_1_2_aarch64.whl

Download URL fn6-0.2.1-cp310-abi3-musllinux_1_2_aarch64.whl
Size 953.0 kB
Tags CPython 3.10 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
e1eb51e94d05728a89817335c49db052c3f94b693425a24fd6607513745ee625
BLAKE2b-256 checksum
How to use checksums
ddadcb94de0ec4092429601875bf2e9a94dc268a810f5b57e5284d190da35d73
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / fn6-0.2.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL fn6-0.2.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 830.5 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
cb100af13f96495cf85d68f5d0950649b6abd4aad47c530893be26f20c26503b
BLAKE2b-256 checksum
How to use checksums
889a85b0f452b798e2c4e545b04f7f8ef47d182dd08e6ef7b23c38f57d799d17
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / fn6-0.2.1-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl

Download URL fn6-0.2.1-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
Size 847.9 kB
Tags CPython 3.10 Linux glibc 2.17+ IBM System/390x abi3
SHA-256 checksum
How to use checksums
99656bcff8d711749057cf2e784a29d93921eb87918926f66a0ffadb478842d8
BLAKE2b-256 checksum
How to use checksums
3f7c7597e07c702ad4d9fa8f2e78bd14d4a626c745690d0a6b0bd609b9144bbc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / fn6-0.2.1-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl

Download URL fn6-0.2.1-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Size 812.8 kB
Tags CPython 3.10 Linux glibc 2.17+ PowerPC 64-le abi3
SHA-256 checksum
How to use checksums
3fef8b8388bbaebb1545a57be741abd9cf9f1cab8798a35b80f1de40498debef
BLAKE2b-256 checksum
How to use checksums
a9489e5f2029c59e15122147ce2bf423d79d7ba662ebd9fa937f7b78f5e6f5f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / fn6-0.2.1-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl

Download URL fn6-0.2.1-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Size 805.6 kB
Tags CPython 3.10 Linux glibc 2.17+ ARMv7l abi3
SHA-256 checksum
How to use checksums
51faab1d98724e36eff0a3ec3a48002e1f04992ed2e23a59871d8d90f93c5143
BLAKE2b-256 checksum
How to use checksums
d6671b3a958385b8825841640998bfc377641b41e2f4824f2e6b9cba464beb24
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / fn6-0.2.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL fn6-0.2.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 776.8 kB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
e1d1cda4ca95463c9edb0f6370e0d6a254c26dbb81281034283f4c6044980894
BLAKE2b-256 checksum
How to use checksums
afc4c8bffd7f37aaae1d3ddad9aaf97977d32dbffc98769103e351871e1561ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / fn6-0.2.1-cp310-abi3-manylinux_2_12_i686.manylinux2010_i686.whl

Download URL fn6-0.2.1-cp310-abi3-manylinux_2_12_i686.manylinux2010_i686.whl
Size 817.0 kB
Tags CPython 3.10 Linux glibc 2.12+ x86-32 abi3
SHA-256 checksum
How to use checksums
793dde6959a9829a4d8a0bc170fb775ca6b99a519903f009bba6d0f82228868c
BLAKE2b-256 checksum
How to use checksums
7168483f5681dd677c6ee2c07cbe31342660321c3fd51fbc0eaad0acfeaab2e1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / fn6-0.2.1-cp310-abi3-macosx_11_0_arm64.whl

Download URL fn6-0.2.1-cp310-abi3-macosx_11_0_arm64.whl
Size 368.9 kB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
341a5c10a8aa40cbeac6250306b482e808a5ba01a57e34060967ad97b695ffdd
BLAKE2b-256 checksum
How to use checksums
b36719632835d8705ae5a0a9b76ad096b3ced597b59deef2f1fe6653aa8c8fdd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release history Release notifications | RSS feed

0.2.2

12 release files

This release

0.2.1 This release

12 release files

0.2.0

12 release files

0.1.3

12 release files

0.1.2

12 release files

0.1.1

12 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page