Skip to main content

PRForm

Predict programmed ribosomal frameshift (PRF) sites in Viral genomes.

prform is a deep-learning tool that scores every nucleotide in viral genome sequence for the probability that a -1 or +1 frameshift event occurs there. Predictions come from a 1D residual network; two trained models are bundled and selectable with --model (see Choosing a model).

The models were trained on NCBI ~50,000 deduplicated viral genomes (as of Feb 2026). Trained model checkpoints and calibrators are bundled with the package and ready to run.

Install

From PyPI:

pip install prform

From bioconda:

conda install -c conda-forge -c bioconda prform

From source (development):

git clone https://github.com/khoa-yelo/PRForm.git
cd PRForm/prform_pkg
pip install -e .[dev]

Usage

prform predict input.fasta --outdir results/

(equivalent: python -m prform predict ... — useful when ~/.local/bin isn't on your PATH.)

Writes two files into results/:

  • predictions.csv — one row per FASTA record: the top-k predicted peak positions, each with its calibrated -1 and +1 probabilities and the predicted frameshift type (-1 PRF, +1 PRF, or no frameshift detected). Peaks are ranked by minus1_PRF_prob + plus1_PRF_prob.
  • predictions.h5 — full per-nucleotide calibrated probability tracks.

predictions.h5 layout:

records/
    accession_id     (R,) str
    length           (R,) int
    top{k}_pos             (R,) int      # k = 1..top_k, 1-based; -1 if no peak
    top{k}_minus1_PRF_prob (R,) float32  # the track values at that position
    top{k}_plus1_PRF_prob  (R,) float32
    top{k}_type            (R,) int8     # -1 PRF, +1 PRF, or 0 = none
per_nucleotide/
    {accession_id}/                # one group per FASTA record
        no_PRF_prob      (L,) float32
        minus1_PRF_prob  (L,) float32
        plus1_PRF_prob   (L,) float32

With --both-strands each orientation gets its own block — fwd_/rev_ column and dataset prefixes, and fwd/rev per-nucleotide subgroups — see Scoring both strands.

Read a record's per-nucleotide tracks in Python:

import h5py
with h5py.File("results/predictions.h5") as f:
    for acc in f["records/accession_id"].asstr()[:]:
        g = f[f"per_nucleotide/{acc}"]
        minus1 = g["minus1_PRF_prob"][:]
        plus1  = g["plus1_PRF_prob"][:]
        prf_track = minus1 + plus1

Choosing a model

Two trained models ship with the package. Both were trained on the same data with the same scheme and differ only in how much sequence context each position sees:

--model context receptive field parameters notes
10k (default) +/-5000 nt 10001 696,739 the original model
2k +/-1000 nt 2001 359,043 half the size, narrower context
prform predict input.fasta --outdir results/ --model 2k

Input and output are identical for both models — same CSV columns, same HDF5 layout, same per-nucleotide track shapes — so you can swap --model without touching anything downstream. Only the probabilities change.

Each model ships with the calibrator that was fit on its own predictions, and --model selects both together. Calibration is specific to a checkpoint's probability scale, so only override --calibrator alongside --checkpoint.

On held-out validation data the two are close: the 10k model is marginally better at ranking (sequence-level PR-AUC 0.892 vs 0.884) while 2k reaches comparable peak localisation at half the parameters. 10k remains the default; 2k is worth trying when context beyond ~1 kb is unlikely to help.

Scoring both strands

PRForm is a directional detector: it only sees a frameshift in the orientation it is given. A PRF encoded on the minus strand of your input is invisible on a forward-only pass. Pass --both-strands to score each record in both orientations:

prform predict genomes.fasta --outdir results/ --both-strands

Both orientations are reported. The peaks and tracks are duplicated into a forward block and a reverse block:

predictions.csv
    accession_id, length,
    fwd_top{k}_pos, fwd_top{k}_minus1_PRF_prob, fwd_top{k}_plus1_PRF_prob, fwd_top{k}_type,
    rev_top{k}_pos, rev_top{k}_minus1_PRF_prob, rev_top{k}_plus1_PRF_prob, rev_top{k}_type

predictions.h5
    records/                       # same fwd_/rev_ prefixes as the CSV
        accession_id, length,
        fwd_top{k}_{pos,minus1_PRF_prob,plus1_PRF_prob,type}
        rev_top{k}_{pos,minus1_PRF_prob,plus1_PRF_prob,type}
    per_nucleotide/
        {accession_id}/
            fwd/  no_PRF_prob, minus1_PRF_prob, plus1_PRF_prob   (L,) each
            rev/  no_PRF_prob, minus1_PRF_prob, plus1_PRF_prob   (L,) each

The reverse block is mirrored back into forward-genome coordinates, so both blocks index the same nucleotide: fwd_top1_pos, rev_top1_pos and index i of either track all refer to position i+1 of the sequence as you supplied it. Class channels are not swapped — a -1 PRF read on the reverse complement stays in minus1_PRF_prob, because the shift direction is defined relative to the strand being read.

Test the install

prform ships with small FASTA fixtures (one folder per labeled frameshift class) so you can verify the install end-to-end without any external data. Copy them into your working directory:

prform download-examples ./prform_examples

Layout after download:

prform_examples/
    plus1_PRF/    influenza_pax.fasta
    minus1_PRF/   coronavirus_khosta2.fasta, phage_tyson.fasta
    no_PRF/       monkeypox, ledantevirus, nanovirus, ourmiavirus, orbivirus

Run predict on each class:

# +1 PRF: peak should land near the labeled site
prform predict prform_examples/plus1_PRF/influenza_pax.fasta \
    --outdir prform_test/plus1

# -1 PRF: peak should land near the labeled site
prform predict prform_examples/minus1_PRF/coronavirus_khosta2.fasta \
    --outdir prform_test/minus1

# no PRF: no frameshift should be called
prform predict prform_examples/no_PRF/nanovirus.fasta \
    --outdir prform_test/no_prf

cat prform_test/plus1/predictions.csv
cat prform_test/minus1/predictions.csv
cat prform_test/no_prf/predictions.csv

Expected behavior:

fixture labeled site what to look for
plus1_PRF/influenza_pax.fasta +1 PRF @ pos 582 top1_pos within a few nt of 582, top1_type == 1
minus1_PRF/coronavirus_khosta2.fasta -1 PRF @ pos 13248 top1_pos near 13248, top1_type == -1
minus1_PRF/phage_tyson.fasta -1 PRF @ pos 10279 top1_pos near 10279, top1_type == -1
no_PRF/*.fasta none top1_type == 0 (no frameshift called)

Each labeled-positive FASTA header carries the labeled site for easy comparison.

Python API

from prform import PRFormPredictor

predictor = PRFormPredictor()                      # default bundled model (10k)
predictor = PRFormPredictor(model="2k")            # narrow-context model
results = predictor.predict_fasta("input.fasta")   # list of dicts
# or
results = predictor.predict_sequences([("rec1", "ACGT" * 1000)])
# score both orientations, keep the better strand per record
results = predictor.predict_fasta("input.fasta", both_strands=True)

Each result entry is:

key type meaning
accession_id str FASTA record id
length int sequence length in nt
strand str +, or - when the reverse complement scored higher
no_PRF_prob (L,) float32 calibrated per-nucleotide class
minus1_PRF_prob (L,) float32 probabilities; the three sum
plus1_PRF_prob (L,) float32 to 1 at each position
top list per peak: {pos, minus1_PRF_prob, plus1_PRF_prob, type}, pos 1-based
fwd, rev dict or None each orientation's own tracks + top

Track names match predictions.h5, and everything is in forward-genome coordinates. fwd/rev are populated only with both_strands=True.

The result schema does not depend on which model is selected. To list the bundled models programmatically:

from prform import available_models
available_models()
# {'10k': '10001 nt context (+/-5000)',
#  '2k':  '2001 nt context (+/-1000), half the parameters'}

Hardware

CPU works. GPU is faster — prform automatically uses CUDA when available. For long sequences (>1 Mb total input) a GPU is recommended.

License

MIT

Metadata

Release files for prform 0.3.0

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

Source distribution (sdist)

Source distribution for prform 0.3.0
File Size Uploaded Provenance Actions
prform-0.3.0.tar.gz 4.1 MB Without provenance Details for prform-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for prform 0.3.0
File Interpreter ABI Platform Actions
prform-0.3.0-py3-none-any.whl Python 3 none any Details for prform-0.3.0-py3-none-any.whl

Total release size: 8.2 MB

Release files / prform-0.3.0.tar.gz

Download URL prform-0.3.0.tar.gz
Size 4.1 MB
Tags Source
SHA-256 checksum
How to use checksums
428a834419f136ad0d9ff8d0bdc202c21b168debbf2fef488ab41849ca6b0f29
BLAKE2b-256 checksum
How to use checksums
8d55cd6767f8f6d2c66e5b9f06a934b4e3b7ec283bb548b3a778ddecb2a02cf0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / prform-0.3.0-py3-none-any.whl

Download URL prform-0.3.0-py3-none-any.whl
Size 4.1 MB
Tags Python 3
SHA-256 checksum
How to use checksums
5d642a4f61d3cefe6683ee80963e2c40288a228c3efc10b3c443f6553ba61905
BLAKE2b-256 checksum
How to use checksums
ce191165bc79ee932cf820711e9b4caef38000880f6bad09a03b6071588d533f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Security for prform 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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