martinandclaude/expansionscout

expansionscout

REPEAT EXPANSIONS + 5mC

Targeted repeat-expansion calling from Oxford Nanopore BAM files, with per-allele methylation. It genotypes 82 disease loci and tells you, per sample, whether a normal result is actually trustworthy.

● v0.1.0 ● MIT ● one static binary ● 82 loci ● research use only
◧

Clipped reads still count

A read the aligner soft-clipped at the repeat still bounds the allele from below. Reads are classified as spanning, split, partial or uninformative, and partial evidence is reported as a lower bound with its read support rather than discarded.

◔

Detectability, not false comfort

Every expansion-regime locus reports the fraction of reads long enough to have spanned a pathogenic allele. Where that is low, the call is explicitly marked as not being negative evidence instead of looking like a clean result.

◈

Methylation and spread per allele

5mC is summarised per allele over windows declared in gene orientation, so a promoter window lands on the correct flank either strand. Each allele also carries its spread, upward length tail and methylated-read fraction.

01

Install

One statically linked binary for x86-64 Linux. It needs nothing installed, and it carries the STRchive catalogue, the clinical overlay and the VCF dialects, so the file is the whole tool. Each release publishes the binary with its SHA-256, and the build is reproducible: a checkout of the release tag builds the same bytes.

bash
# download the latest release, check it, put it on the PATH
$ gh release download --repo martinandclaude/expansionscout
$ sha256sum -c expansionscout.sha256
$ install -m 755 expansionscout ~/.local/bin/
$ expansionscout --version

# or build it: needs rustup and a C compiler
$ git clone https://github.com/martinandclaude/expansionscout
$ cd expansionscout
$ ./build-static.sh

The binary and its checksum are also on the releases page.

02

Quick start

Point it at a coordinate-sorted, indexed BAM aligned to GRCh38 and the reference it was aligned to. Methylation output additionally needs MM/ML tags from modification-aware basecalling.

expansionscout call 3–4 files out
# the whole catalogue
$ expansionscout call --bam sample.bam --ref hg38.fa.gz --out results/sample

# selected loci, by id, alias or gene name
$ expansionscout call \
    --bam   sample.bam \
    --ref   hg38.fa.gz \
    --out   results/sample \
    --loci  FMR1 C9ORF72 HTT \
    --sex   XY \
    --mosaic \
    --vcf

→ results/sample.loci.tsv      one row per locus
→ results/sample.per_read.tsv  one row per read
→ results/sample.report.html   the sample as a worklist, self-contained
→ results/sample.vcf           one record per locus, with --vcf
03

How it works

STEP 1
Read classification
Each record is sorted from its CIGAR into spanning, left or right partial, split, or uninformative. Split records of one read are paired and sized from read coordinates.
STEP 2
Per-read sizing
A rotation-invariant walk decomposes the tract into units, labelling each canonical, pathogenic, benign, interruption or unrecognised. A single-base indel costs at most one unit.
STEP 3
Allele assignment
Haplotype tags where available, otherwise a Gaussian mixture chosen by BIC, which learns the read-to-read spread from the data rather than assuming it.
STEP 4
Allele sequence
Each allele's sequence, structure and repeat unit are a consensus of its reads, voted unit by unit in the allele's reading frame, so no single read's sequencing errors are written as the allele.
STEP 5
Methylation
Per read from MM/ML tags, summarised per allele over the tract and over gene-5′ and gene-3′ flank windows configured for that locus.
STEP 6
Classification
Clinical size bands where they exist, catalogue thresholds otherwise, plus the evidence state derived from partial reads.
sample.loci.tsv — selected columns illustrative values
locusgenea1a2class5mCdetectevidence
FXS_FMR1FMR130120premutation0.070.98NONE
HD_HTTHTT1721normal.1.00NONE
SCA1_ATXN1ATXN12930normal.1.00NONE
FTDALS1_C9orf72C9orf7228normal0.440.11EXPANSION_LB

The last row is the case the tool exists for. Both alleles look normal, but only 11 % of reads were long enough to have spanned a pathogenic allele, and clipped reads support something much longer. That result is flagged rather than reported as a negative.

04

Limits

What it cannot do

Alleles longer than the reads cannot be measured; no method working on aligned sequence can size a tract no read crosses. Mosaicism is described through spread and minor modes, never quantified as a fraction. Methylation is only as good as the basecalling that produced the tags.

Interpretation is locus-specific: composition loci such as RFC1 turn on which motif is expanded rather than length, and at ATXN1 a long interrupted allele can be benign while a shorter pure one is not.

Validation status

The test suite is synthetic. Alignments are built in process with explicit CIGAR strings, so no sequencing data is needed and none is distributed.

Concordance against orthogonal measurement — PCR fragment analysis, repeat-primed PCR, Southern blot — has not been established. Treat the output accordingly.

Research use only.

This is not a clinical assay and no output is a diagnostic claim. Confirm every size-class boundary against your own laboratory's validated cut-points before relying on a label.

05

Citing

Cite the locus catalogue

expansionscout bundles the STRchive disease-locus catalogue, redistributed under CC BY 4.0. That licence requires attribution, so cite STRchive if you use this tool, and the repository and the release you used.

Hiatt L, Weisburd B, Dolzhenko E, Rubinetti V, Avvaru AK, VanNoy GE, Kurtas NE, Rehm HL, Quinlan AR, Dashnow H. STRchive: a dynamic resource detailing population-level and locus-specific insights at tandem repeat disease loci. Genome Medicine 2025;17(1):29. doi:10.1186/s13073-025-01454-4

Contributing

Issues and pull requests are welcome, particularly locus overlay entries, validation against known-size samples, and anything that improves the honesty of the detectability estimate.