Skip to main content

IsoForge

IsoForge uses a hypergraph, rather than a splice graph, to preserve transcript models and the reads behind them. Each long read is kept whole, with its intron chain and both ends, as one hyperedge. From Oxford Nanopore or PacBio RNA-seq, a single run reports annotated and novel isoforms with their transcription start and poly(A) sites, read counts per sample (annotated small RNAs included) and gene fusions.

IsoForge at a glance

Installation

pip install isoforge

IsoForge needs Python 3.10 or later and is tested on Linux (x86-64), where pip installs a ready-built package: minimap2 and htslib are compiled in, so there is nothing else to install. On other systems pip builds IsoForge from source, which takes a few minutes and needs Rust 1.85 or later and the C build tools (a compiler, make, cmake).

To build from this repository with conda:

git clone https://github.com/MustafaElshani/IsoForge.git
cd IsoForge
bash install.sh              # creates the conda environment "isoforge" and builds into it
conda activate isoforge

bash install.sh --help shows the other ways to call the script. The repository as it stands is installed with pip install git+https://github.com/MustafaElshani/IsoForge.git; the conda environment of environment.yml has what that build needs (conda env create -f environment.yml, then conda activate isoforge).

Quick start

IsoForge needs the reads, the genome and the annotation:

# from FASTQ
isoforge annotate --reads Control_1.fastq.gz Treated_1.fastq.gz \
    --genome hg38.fa --annotation gencode.v49.annotation.gtf --o results/project

# or from sorted BAM files
isoforge annotate --bam Control_1.bam Treated_1.bam \
    --genome hg38.fa --annotation gencode.v49.annotation.gtf --o results/project

FASTQ files are aligned with the minimap2 built into IsoForge. The annotation is indexed on the first run, beside the GTF, and the index is used again after that. Every output is written; nothing else has to be set.

If your genome has a minisplice score table (human GRCh38: human-GRCh38.v4.tsv.gz), add --splice_scores human-GRCh38.v4.tsv.gz. It is used to place and check novel splice sites.

Command Use
isoforge annotate The run: from FASTQ or BAM to transcript models, counts and fusions
isoforge post Filter and write the outputs again from a kept run, without reading the alignments again
isoforge export Write coverage tracks or the read table again from a finished run
isoforge index Build the annotation index ahead of a run, for example on a cluster

isoforge <command> --help shows the main options of a command, and isoforge annotate --help-all every option.

Input

Reads

Give one file per sample: FASTQ or FASTA, gzipped or not, with --reads, or sorted BAM with --bam. The samples are named after their files unless --names gives the names. For FASTQ, set the library type:

Library Options minimap2, if you align yourself
Nanopore cDNA none -ax splice
Nanopore direct RNA, or cDNA oriented with pychopper --oriented -k 14 -ax splice -uf -k14
PacBio Iso-Seq --platform hifi --oriented -ax splice:hq -uf

--oriented (-uf) is only for reads that run in the transcript's direction. --write_bam keeps the alignments IsoForge makes, which IsoTracks reads.

BAM files of your own must be aligned to the genome with minimap2, sorted and indexed:

minimap2 -ax splice --junc-bed annotation.bed hg38.fa reads.fastq.gz | samtools sort -o sample.bam
samtools index sample.bam

annotation.bed is made with paftools.js gff2bed annotation.gtf; --junc_bed gives the same file to the built-in aligner.

Poly(A) tail lengths are read from the pt:i tag when the reads carry it, and measured in the soft clip otherwise. To keep Dorado's tag, convert with samtools fastq -T pt and add --copy_comment (minimap2 -y).

Sample sheet

For many samples, --config takes a CSV in place of --reads or --bam, with one sample per line: name, description, platform and file.

Control_rep1,Control replicate 1,ONT,/data/control_rep1.fastq.gz
Control_rep2,Control replicate 2,ONT,/data/control_rep2.fastq.gz
Treated_rep1,Treated replicate 1,ONT,/data/treated_rep1.fastq.gz
Treated_rep2,Treated replicate 2,ONT,/data/treated_rep2.fastq.gz

The part of a sample name before the first underscore is the condition (Control, Treated).

Output

With --o results/project:

File Content
project_isoforge.gtf Transcript models that pass the filters, with their TSS, poly(A) site and poly(A) signal
project_isoforge_abundance_filtered.tsv Read counts per transcript and dataset
project_isoforge_read_annot.parquet Every read: its transcript, TSS, poly(A) site and signal, and tail length
project_isoforge_read_annot.tsv The whole reads of the reported transcripts, as text; their other reads are in ..._unsupported.tsv
project_isoforge_summary.tsv Genes, transcripts and reads per category and dataset
project_filter.csv IDs of the transcripts that pass
project_TSS_TES_Clusters/ TSS and poly(A) site clusters (BED and Parquet), and read-end coverage tracks per dataset
project_isoforge_fusions.tsv Fusion candidates. The calls are the rows with PASS in the filter column, also written as .bedpe
project_isoforge_fusion_* The reads, parts and transcripts of each fusion (TSV, Parquet, GTF)

--hypergraph also writes the read hypergraph of the reported models (project_isoforge_hypergraph.tsv) and tests of which exons are spliced together in the same molecules (project_isoforge_coordination.tsv).

Transcript categories
Category Meaning
Known Full splice match to an annotated transcript
ISM Incomplete splice match: a contiguous part of an annotated intron chain (Prefix, Suffix or Both)
NIC Novel in catalogue: annotated splice sites in a new combination
NNC Novel not in catalogue: at least one new splice site
Novel An intron chain given a new ID because its reads have a start or poly(A) site of their own
Antisense On the opposite strand of an annotated gene
Intergenic Outside annotated genes
Genomic Overlaps an annotated gene without sharing its splice structure
Fusion Spans two or more annotated genes
Columns of the tables and GTF attributes

Abundance table:

Column Content
gene_ID, transcript_ID IsoForge gene and transcript numbers
annot_gene_id, annot_transcript_id Annotation IDs; novel transcripts are ISOFORT…, novel genes ISOFORG…
annot_gene_name, annot_transcript_name Gene and transcript names
n_exons, length Number of exons and transcript length (nt)
gene_novelty, transcript_novelty, ISM_subtype Categories, as above
one column per dataset Read counts. A read that fits several transcripts is shared among them, so counts can be fractional

Read table:

Column Content
read_name, dataset, genome_build Read, dataset and genome build
chromosome, read_start, read_end, strand 5′ and 3′ end of the alignment (1-based) and transcript strand
n_exons, read_length Exons of the assigned transcript, and length of the read
gene_ID … ISM_subtype The assigned gene and transcript, as in the abundance table
fraction_As A content of the 20 nt after the 3′ end
custom_label, allelic_label The lC and lA BAM tags, if present
start_support, end_support TSS and poly(A) cluster the read's ends joined
tss_site, tss_feature TSS position and the annotated feature there
polya_site, polya_feature, polya_signal Poly(A) site, the feature there and the poly(A) signal (a hexamer, or DSE)
cluster_supported True for a whole read of its transcript: every exon, both ends at the transcript's, not internally primed
polya_length Poly(A) tail length

GTF transcript records carry transcript_status, tss_site, tss_Feature, polyA_site, polyA_Feature and polyA_signal. A transcript that has the intron chain of an annotated one and another start or poly(A) site also carries variant_of, the ID of that annotated transcript.

Options

The defaults are meant to be run as they are. These are the options most often changed:

Option Default Effect
--threads all cores Threads
--minCount 5 Reads per dataset a novel transcript needs
--minCountKnown 2 Reads per dataset an annotated transcript needs
--minDatasets 1 Datasets in which a novel transcript must pass (0: all)
--no_polya_filter off Accept 3′ ends without a poly(A) tail, for reads without tail information
--known_ends_as_annotated off Write annotated transcripts at their annotated ends; the read-derived ends stay in the GTF attributes
--no-small_rna counted Do not count annotated small RNAs
--no-fusions called Do not call fusions
--sj_dir, --cage_peaks none STAR SJ.out.tab files and CAGE peaks as further evidence for splice sites and starts
--read_annot_format parquet, --no-end_tracks both, on A smaller output: no read table as text, no coverage tracks
--write_bam off Keep the alignments made from FASTQ, in <prefix>_alignments/
--keep-db off Keep the run database for isoforge post

Filtering a run again

A run kept with --keep-db can be filtered with other settings without reading the alignments again:

isoforge post --database results/project_isoforge_db --annotation gencode.v49.annotation.gtf \
    --genome hg38.fa --minCount 10 --o results/project_min10

isoforge post takes the filtering options of isoforge annotate. Give it --genome and --splice_scores as in the run.

Downstream analysis

Tool Use Reads from a run
SQANTI3 v6 Structural classification and quality control of the transcript models The GTF
IsoForge_Sqanti3 Runs SQANTI3 on a run and writes its classification, coding status and CDS back into the GTF, with a BED12 for genome browsers The GTF
IsoTracks Draws the isoform models of a gene with the reads behind them, their poly(A) tails and coverage, and gene fusions The GTF, the read-annotation Parquet, the clusters, the fusion tables and the BAM files
IsoEnds Statistics on poly(A) tail length, alternative polyadenylation and transcription start sites between conditions The read-annotation Parquet, the GTF and the clusters

IsoForge_Sqanti3, IsoTracks and IsoEnds are companion tools of IsoForge. SQANTI3 itself takes the GTF as it is:

python sqanti3_qc.py --isoforms results/project_isoforge.gtf \
    --refGTF gencode.v49.annotation.gtf --refFasta hg38.fa -d results/sqanti3 -o project

Citation

The IsoForge manuscript is in preparation. Until it is out, please cite this repository:

Elshani M, Zhang Y, Harrison DJ. IsoForge, version 1.0.0. https://github.com/MustafaElshani/IsoForge

License

MIT, see LICENSE.

Metadata

Release files for isoforge 1.0.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 isoforge 1.0.0
File Size Uploaded
isoforge-1.0.0.tar.gz 1.7 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for isoforge 1.0.0
File Interpreter ABI Platform
isoforge-1.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details

Total release size: 8.8 MB

Release files / isoforge-1.0.0.tar.gz

Download URL isoforge-1.0.0.tar.gz
Size 1.7 MB
Tags Source
SHA-256 checksum
How to use checksums
8c069f590a5843f6bac8b1f3f58a9f1661d3e3a83495af0ae683b9451f58cb68
BLAKE2b-256 checksum
How to use checksums
e1f978dad962f67cd172a4345d18a81433104f8fdef17059c256ca58824aa337
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / isoforge-1.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL isoforge-1.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 7.0 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
b2fe2d385866009d15dd5a7d8e2f4e34634020b1699217809f74fbcf440ecda2
BLAKE2b-256 checksum
How to use checksums
e2959b4d996a99b7a4ba6c1c4f82c230f1847515bda5a2bfe05249ab448ff444
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 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