Skip to main content

Fast, efficient and scalable SNP distance calculation from disk.

Project description

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.

Usage

All FASTA inputs can be optionally gzipped.

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 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> <MASK> <SAMPLE>

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
  <SAMPLE>     Path to the sample genome FASTA file

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]
      --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]
  -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

Tree building

Optionally included in the Python package is code to produce a neighbour joining phylogenetic tree in newick format. This has a few requirements:

  • A minimum of 4 samples within the comparison
  • Distances are computed with no SNP cutoff

Example:

# Optional virtual environment
python -m venv env
source env/bin/activate

# Install fn6, both as a rust CLI tool and a python library
cargo install fn6
pip install "fn6[tree]"

# Create a table of distances with an arbitrarily high cutoff
fn6 compute -d path/to/some/samples -r path/to/a/reference -m path/to/a/mask --cutoff 9999999 > your-distances.txt

# Build a tree
find-neighbour-to-tree --input your-distances.txt --output your-tree.nwk

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

fn6-0.1.1-cp312-cp312-win_amd64.whl (265.8 kB view details)

Uploaded CPython 3.12Windows x86-64

fn6-0.1.1-cp312-cp312-musllinux_1_2_x86_64.whl (987.5 kB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

fn6-0.1.1-cp312-cp312-musllinux_1_2_i686.whl (1.0 MB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ i686

fn6-0.1.1-cp312-cp312-musllinux_1_2_armv7l.whl (1.1 MB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ ARMv7l

fn6-0.1.1-cp312-cp312-musllinux_1_2_aarch64.whl (942.6 kB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ ARM64

fn6-0.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (825.4 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

fn6-0.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl (841.8 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ s390x

fn6-0.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (802.4 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ppc64le

fn6-0.1.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (802.8 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARMv7l

fn6-0.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (769.2 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

fn6-0.1.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl (813.7 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.12+ i686

fn6-0.1.1-cp312-cp312-macosx_11_0_arm64.whl (368.8 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

File details

Details for the file fn6-0.1.1-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: fn6-0.1.1-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 265.8 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.14.1

File hashes

Hashes for fn6-0.1.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 9aa873fd192f9fa67bd50103ca83f8346559b19486e028630c8248b4ba614934
MD5 e9b3ebb8e04e9d51fe9d6086cefc9f7a
BLAKE2b-256 06c185bafe0dd9b055508f5c2316f02fbe276da714ede15d1a3f0ba047f0ef3d

See more details on using hashes here.

File details

Details for the file fn6-0.1.1-cp312-cp312-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for fn6-0.1.1-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 9e5869995c0cc42efa608586727fcb00dcc21d15b35b9a7809e637a8cf7b7e9e
MD5 22ce1d78725843069ac45e74e7741f82
BLAKE2b-256 6d20da84c865e47c0f0b7653b7a2dd828526d2123b0651c10ac7ade3e12fae7d

See more details on using hashes here.

File details

Details for the file fn6-0.1.1-cp312-cp312-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for fn6-0.1.1-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 3b2e60802fac8309bdfd415613256f26ceada8820f2bf40bbba983b18ef47697
MD5 aa97699b33f6a575f2f35304e248d95d
BLAKE2b-256 e96ed7ce8d288eec1c4e10c0ac04a43bf804b65e27c36c936c3433d8aa817525

See more details on using hashes here.

File details

Details for the file fn6-0.1.1-cp312-cp312-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for fn6-0.1.1-cp312-cp312-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 f22e06ca40bfba5627ded031133c35c97c62df0166e53613c46603c8558291db
MD5 4797c7765e92db16568d90cfcc13f457
BLAKE2b-256 6ac9137df9f7562c20c2ad64769f586c0ad909acf9d7d7662b75534844f574cd

See more details on using hashes here.

File details

Details for the file fn6-0.1.1-cp312-cp312-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for fn6-0.1.1-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 c506a34364be6edbe8ee16c39f8421a107aff3b136c8c1c9b18ae0f1183c6fed
MD5 5c8074b51e7ac22110d318ea925c4293
BLAKE2b-256 cc5033083112ab8022e26c67981b85a23143a4bb838dfc23a56cd491a63671b3

See more details on using hashes here.

File details

Details for the file fn6-0.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for fn6-0.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 24feb98d347ed5f43e06c4a597be9e5517ebc0e78ca01a2e867804ef12536524
MD5 f6e99c6c28f52f98c5e5630a40e01efc
BLAKE2b-256 09d66404ec923410ac6aa3f084774cc6c300f4afe04c7b2cde8ea566c43d790b

See more details on using hashes here.

File details

Details for the file fn6-0.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for fn6-0.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 840634c44c2dcda1638cec6c8c786bf357388f9764659f4594507efd0c3cd6cf
MD5 0747ee598ee3141b695099998129471b
BLAKE2b-256 dc210f09804b7962c448d5ddf09b60d7f50aac33cf6903c97c250942069fd0f4

See more details on using hashes here.

File details

Details for the file fn6-0.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for fn6-0.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 9c2f614aa812f8cd565ba7c2fe33a8d00e08df2f8958f32a3b7a885e605c87bd
MD5 1acbd8e16f51527718a4293ad5af57ea
BLAKE2b-256 302ac31b05f5add5953329c474dc56e5f80c55928d5849a395a1f2ee3802ca51

See more details on using hashes here.

File details

Details for the file fn6-0.1.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for fn6-0.1.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 ae193f85d94cff9e085a9b788cf3e8e4735109e2c869b48a8e36768e408da33d
MD5 3ba1440dafe95415c2506e97f44205b5
BLAKE2b-256 dd2946715f8232125f7a7ae55769c4d77bcbf37eec235e0544fe1530270b94b3

See more details on using hashes here.

File details

Details for the file fn6-0.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for fn6-0.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 92b4d6bb00845f4adcf210acebf4d76b477158515de024110de6484e149bb3ff
MD5 a81a48802f7239e6be57d2e08e8fd47b
BLAKE2b-256 a4c9e2cd15a0a3f8f650cf05d25a3a332b257265af1e5b8d442aa13fa20cc662

See more details on using hashes here.

File details

Details for the file fn6-0.1.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for fn6-0.1.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 6834ee0ed4534f0090c7ff6c93cd4ce1b86c2417be2249a722aff795163300ed
MD5 edc27f3b060dbcd4f4dc8ba7bf65d6a6
BLAKE2b-256 5e8259fc14fc4ae8f2171798fabe65a41549446a87ceae54ede6306e6a4524d5

See more details on using hashes here.

File details

Details for the file fn6-0.1.1-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for fn6-0.1.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e0793f0d598facad4c96ff4787152c619fc6c296343362dfeacbf8cd84972a7e
MD5 a9c32d330d3e6012d6589161f3f9e9ea
BLAKE2b-256 54b5d32c0f9c3ee78d78fcecf1b8cc6e7eb62387c43ca0bc7e056232fa0ef52f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page