Skip to main content

PeakATail

PeakATail — coiled snake with poly(A) tail

PeakATail is a Python tool for single-cell poly(A) site (PAS) detection and alternative polyadenylation (APA) analysis. It works with any scRNA-seq BAM that carries a CB:Z (corrected cell barcode) tag — STARsolo, CellRanger, Alevin-fry, or any aligner that emits the standard 10x-style tag schema. UMI (UB:Z) tags are NOT required or used: PeakATail counts raw read 3'ends, not UMI-deduplicated molecules. PeakATail does NOT correct barcodes; your aligner must apply a barcode whitelist (e.g. STARsolo's --soloCBwhitelist). From the input BAM it calls polyadenylation sites at the read level, builds a per-cell PAS count matrix, clusters cells by their APA profiles, and provides downstream analyses including differential APA testing between clusters, 3'UTR length quantification, and cross-dataset cluster matching. Developed at BMGLab.

Docs License: MIT Python 3.11+


Quick install

System prerequisites

PeakATail calls samtools and bedtools as subprocesses. Both must be on your PATH before running the pipeline.

# Debian/Ubuntu
sudo apt-get install samtools bedtools

# macOS (Homebrew)
brew install samtools bedtools

The code has been tested against samtools >= 1.10 (enforced at runtime in ema/datasets/manager.py).

Python version

Python 3.11 or later is required (declared in pyproject.toml as requires-python = ">=3.11").

Install from source

git clone https://github.com/BMGLab/PeakATail.git
cd PeakATail

# Create and activate a virtual environment
python3.11 -m venv .venv
source .venv/bin/activate

# Install with uv (recommended — matches the development environment)
pip install uv
uv pip install -e .

# Or with plain pip
pip install -e .

All Python dependencies are declared in pyproject.toml and installed automatically.


Quick start

# Step 1: copy the example config and edit paths
cp example.yaml my_run.yaml
# Edit my_run.yaml — set datasets[].bams, gtf, seqlen, cb_len, barcode_tag

# Step 2: run the full pipeline (peak calling → annotation → clustering)
uv run peakatail run --config my_run.yaml --threads 4

# Step 3: differential APA between every cluster pair
uv run peakatail switch diff \
    -i peakatail_runs/<run>/per_dataset/<ds>/clusters.h5ad \
    --pasbed peakatail_runs/<run>/per_dataset/<ds>/pasbed.bed \
    --strategy fisher

# Step 4: 3'UTR length quantification across clusters
uv run peakatail switch length \
    -i peakatail_runs/<run>/per_dataset/<ds>/clusters.h5ad \
    --strategy classic

The pipeline writes all output under peakatail_runs/<name>_<timestamp>/. A typical run directory looks like:

peakatail_runs/emaout_20240501_143022/
    run_config.json                  # full resolved parameters
    peakatail_<ts>.log               # structured run log
    per_dataset/
        <dataset_id>/
            raw/                     # pre-filter BEDs and matrices
            posbed.bed               # filtered positive-strand PAS BED
            negbed.bed               # filtered negative-strand PAS BED
            pasbed.bed               # combined filtered PAS BED (both strands)
            filtered_cb.tsv          # barcodes that passed min_read filter
            pas_gene.tsv             # PAS-to-gene mapping table
            annotatedpas.bed         # pasbed.bed extended with gene_id column
            annotated_matrix.mtx     # post-annotation count matrix (MatrixMarket)
            annotated_pas_ids.tsv    # row index for annotated_matrix.mtx
            annotated_cells.tsv      # column index for annotated_matrix.mtx
            preprocessed.h5ad        # filtered AnnData before clustering
            clusters.h5ad            # AnnData with leiden cluster labels
    switch_diff_<ts>/                # output of `peakatail switch diff` (auto-routed)
    switch_length_<ts>/              # output of `peakatail switch length` (auto-routed)
    switch_match_<ts>/               # output of `peakatail switch match` (auto-routed)
    switch_geneview_<ts>/            # output of `peakatail switch geneview` (auto-routed)

What PeakATail produces

Peak calling stage

File Location Description
raw/pos.bed per_dataset/<ds>/raw/ Unfiltered positive-strand PAS calls (concatenated across BAM replicates)
raw/neg.bed per_dataset/<ds>/raw/ Unfiltered negative-strand PAS calls
raw/pas.bed per_dataset/<ds>/raw/ Union of raw pos + neg BED (pre-filter)
raw/pos.mtx per_dataset/<ds>/raw/ Raw count matrix, positive strand (MatrixMarket)
raw/neg.mtx per_dataset/<ds>/raw/ Raw count matrix, negative strand (MatrixMarket)
raw/cb.tsv per_dataset/<ds>/raw/ Raw cell-barcode index aligned to raw MTX columns
posbed.bed per_dataset/<ds>/ Filtered positive-strand PAS BED
negbed.bed per_dataset/<ds>/ Filtered negative-strand PAS BED
pasbed.bed per_dataset/<ds>/ Combined filtered PAS BED (both strands); used as input for downstream commands
filtered_cb.tsv per_dataset/<ds>/ Barcodes that passed the min_read filter, with filter threshold in header

Annotation stage

File Location Description
pas_gene.tsv per_dataset/<ds>/ Two-column table: pas_id, gene_id
annotatedpas.bed per_dataset/<ds>/ pasbed.bed extended with a trailing gene_id column
annotated_matrix.mtx per_dataset/<ds>/ MatrixMarket sparse count matrix (rows = annotated PAS, cols = cells)
annotated_pas_ids.tsv per_dataset/<ds>/ Row index for annotated_matrix.mtx
annotated_cells.tsv per_dataset/<ds>/ Column index for annotated_matrix.mtx

Clustering stage

File Location Description
preprocessed.h5ad per_dataset/<ds>/ AnnData after cell/PAS filtering, before cluster labels are assigned
clusters.h5ad per_dataset/<ds>/ AnnData with leiden cluster labels in .obs; primary input for all switch subcommands

Differential APA stage (peakatail switch diff)

File Location Description
diff_<c1>_vs_<c2>.tsv switch_diff_<ts>/ Per-cluster-pair differential APA results table
cluster_match.tsv switch_match_<ts>/ Cross-dataset cluster correspondence scores (peakatail switch match)
pdui_classic.tsv switch_length_<ts>/ Per-cell PDUI scores when strategy is classic
proportion.tsv switch_length_<ts>/ Per-cell per-PAS proportion scores when strategy is proportion
entropy_shannon.tsv switch_length_<ts>/ Per-cell Shannon entropy scores when strategy is shannon

Available CLI commands

All commands are accessed through the peakatail entry point installed by pip install -e .. The old ema command still works as a deprecated alias.

Command Description Docs
peakatail run Run the full pipeline: peak calling, annotation, clustering cli/run
peakatail reannotate Branch a finished run into a new trim/filter/clustering variant without re-peak-calling cli/reannotate
peakatail switch diff Differential APA test across cluster pairs (Fisher / NB regression) cli/switch-diff
peakatail switch length 3'UTR shortening/lengthening quantification (PDUI variants) cli/switch-length
peakatail switch trend Ordered-covariate (e.g. stage-progression) APA-length trend: slope + Spearman + direction cli
peakatail switch combine Stitch stage/celltype-labelled clusters.h5ad files into one grouped h5ad for cross-group testing cli
peakatail switch match Cross-dataset cluster matching cli/switch-match
peakatail switch geneview Gene-track visualisation: per-cluster PAS coverage and proportions cli/switch-geneview
peakatail collapse Pool samtools merge RG-suffixed run tags back into per-library cells cli
peakatail merge Merge multiple BAM files into one sorted and indexed BAM cli/merge
peakatail parse-gtf Pre-warm the GTF cache so subsequent runs start immediately cli/parse-gtf
peakatail wizard Interactive setup wizard (also invoked by bare ema) cli/wizard

Use --list-strategies on peakatail run, peakatail switch diff, peakatail switch length, and peakatail switch match to see the strategies registered in the current installation.

Every command accepts --help for full flag documentation.


Available strategies

Peak calling (peakatail run --peak-strategy)

Name Description
original Wraps the original pasfind() logic unchanged; used as a baseline for comparison
lambda_poisson MACS2-style: Poisson p-value against a local lambda estimated from floor positions
sierra_iterative Sierra-style iterative peak subtraction; finds multiple PAS per UTR
lambda_gradient Local-lambda estimation combined with gradient-based peak delineation

Clustering (peakatail run --cluster-method)

Name Description
leiden_tfidf TF-IDF normalisation followed by LSI dimensionality reduction and Leiden community detection
leiden_libsize Library-size normalisation followed by PCA and Leiden community detection
external Load pre-computed cluster labels from a file instead of running clustering

Cross-dataset cluster matching (peakatail switch match --strategy / peakatail run --match-method)

Name Description
marker_overlap Match clusters by overlap of top marker PAS sets
jaccard Match clusters by Jaccard similarity of cell sets
mnn Mutual nearest neighbours in a shared LSI embedding

3'UTR length quantification (peakatail switch length --strategy)

Name Output file Description
classic pdui_classic.tsv Classic 2-PAS PDUI: distal_count / (proximal + distal); proximal/distal selected by genomic or transcript-coordinate rank
proportion proportion.tsv Per-PAS proportion vector: reads per PAS as fraction of gene total per cell
shannon entropy_shannon.tsv Shannon entropy of the per-PAS proportion distribution per (gene, cell)

Differential APA testing (peakatail switch diff --strategy)

Name Description
fisher Fisher's exact test on per-PAS read counts between two cluster groups
nb_pairwise Negative binomial regression, pairwise cluster comparison
nb_multi Negative binomial regression, multi-condition

Documentation

Full docs: https://bmglab.github.io/PeakATail/

The MkDocs documentation site is built automatically from the develop and main branches via the .github/workflows/docs.yml GitHub Actions workflow and published to GitHub Pages.


Repository layout

PeakATail/
    ema/                    # core Python package (entry point: ema.cli:main)
        cli/                # Click subcommands and config schema
        strategies/         # peak-calling strategy registry
        clustering/         # clustering strategies and cross-dataset matching
        quantification/     # PDUI / proportion / entropy strategies
        switch_test/        # differential APA testing strategies
        outputs.py          # all file I/O for the pipeline
        main.py             # pipeline orchestration
        downstream_runner.py# per-dataset worker (safe for multiprocessing)
    data/                   # example data files
    test/                   # test suite (pytest)
    other_repos/            # reference implementations (Sierra, SCAPE, scTail, etc.)
    example.yaml            # canonical YAML config template
    combined_polya_scrna_methods.csv  # comparison of poly(A) scRNA methods
    pyproject.toml          # package metadata, dependencies, entry points
    ROADMAP.md              # development and publication roadmap
    LICENSE                 # MIT License
    Dockerfile              # container build

Citation

If you use PeakATail, please cite the software entry below for now. The author field mirrors the package author declared in pyproject.toml; the full manuscript author list and a machine-readable CITATION.cff will be added with the paper release (tracked in the release-engineering issue).

@software{peakatail,
  author  = {Amiri Tabat, Amir},
  title   = {{PeakATail}: single-cell poly(A) site detection and APA analysis},
  url     = {https://github.com/BMGLab/PeakATail},
  version = {0.3.1},
  note    = {Preprint in preparation; replace with the journal citation when available}
}

License

This project is licensed under the MIT License — see the LICENSE file for the full text. pyproject.toml declares the matching SPDX identifier (license = "MIT").

Download files

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

Source Distribution

peakatail-0.3.1.tar.gz (1.0 MB view details)

Uploaded Source

Built Distribution

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

peakatail-0.3.1-py3-none-any.whl (788.6 kB view details)

Uploaded Python 3

File details

Details for the file peakatail-0.3.1.tar.gz.

File metadata

  • Download URL: peakatail-0.3.1.tar.gz
  • Upload date:
  • Size: 1.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for peakatail-0.3.1.tar.gz
Algorithm Hash digest
SHA256 505fbfc8a8c82be1123059ae76614657b862aac09d66fe6cc9923791635962c7
MD5 5ff59f816679a3be373c8b8a1ad5ec1d
BLAKE2b-256 b0bf45d9e2f1ba8d36446a56bd32b00d5164f3f9b08eaff1cc902af536c92c8f

See more details on using hashes here.

Provenance

The following attestation bundles were made for peakatail-0.3.1.tar.gz:

Publisher: release.yml on BMGLab/PeakATail

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file peakatail-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: peakatail-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 788.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for peakatail-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b1f8ff253254258f6b25f8532c981cd3759aeef4fb201f716c53c61f489f554a
MD5 4206cf9c2b64400057d3cfea226d6902
BLAKE2b-256 3eb906f056714d321190f25c7f37da554a04daf275d06ae11fd283eb7f7acff7

See more details on using hashes here.

Provenance

The following attestation bundles were made for peakatail-0.3.1-py3-none-any.whl:

Publisher: release.yml on BMGLab/PeakATail

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 files

0.3.0

2 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