-
Notifications
You must be signed in to change notification settings - Fork 0
Python API
The wrapper is a thin layer over the C++ binary. It writes inputs to a temp dir, shells out, and reads the TSVs back as pandas DataFrames. The C++ binary remains the source of truth for every mapping decision — Python only assembles BED rows, runs the binary, and parses the outputs.
Two functions mirror the index / fetch commands and return the Path to a .idx (see Index):
import prot2exon as p2e
idx = p2e.build_index("combined.gtf", out="human.idx") # build from a local GTF (`prot2exon index`)
idx = p2e.fetch_index("human") # pre-built, from Zenodo (`prot2exon fetch`)
idx = p2e.fetch_index("human", release="50") # or build a specific releasebuild_index(gtf, out=None, *, binary=None, force=False) caches: if out exists it's returned untouched unless force=True.
import prot2exon as p2e
mapper = p2e.Mapper(
index="human.idx",
binary=None, # auto-discovered via PROT2EXON_BIN / repo / $PATH
threads=None, # default: all cores
batch_size=0, # 0 = unbounded (one-shot); >0 enables streaming
extra_args=(),
)result = mapper.map(
"ENSP00000269305",
aa_start=102, aa_end=292, domain_id="TP53_DBD",
)
result.summary # one-row DataFrame
result.isoform # plot-ready DataFrame
result.bed12 # IGV-ready DataFrameENST also works — it resolves to the same intervals as the matching ENSP, so the two give identical mapping output:
mapper.map("ENST00000269305", aa_start=102, aa_end=292, domain_id="TP53_DBD")result = mapper.map_batch([
{"protein_id": "ENSP00000269305", "aa_start": 102, "aa_end": 292, "domain_id": "TP53_DBD"},
{"protein_id": "ENSP00000269305", "aa_start": 10, "aa_end": 50, "domain_id": "TP53_AD1"},
])For very large query sets (millions), bound RAM by setting batch_size:
mapper = p2e.Mapper(index="human.idx", batch_size=10000, threads=8)
result = mapper.map_batch(million_queries)See Performance and Benchmarking for the 1 M-query benchmark.
result = p2e.map_query(
"ENSP00000269305", 102, 292, "TP53_DBD",
index="human.idx",
)Use Mapper(...).map_batch(...) if you have many queries — each map_query call reloads the index from disk.
By default Mapper.map / map_batch use a temp dir that's deleted when the MappingResult goes out of scope. Pass keep_outputs="path/" to keep the TSVs and BEDs on disk:
result = mapper.map("ENSP00000269305", 102, 292, "TP53_DBD",
keep_outputs="my_results/")
# my_results/{domain_mapping_summary.tsv, isoform_structure.tsv, ...}Same files the CLI would write under --out-dir.
result = p2e.read_results_dir("my_results/")
result.summary # pandas DataFrame
result.isoform # ...read_results_dir parses the output directory of a previous run into a fresh MappingResult — useful for picking up where a long batch left off, or analysing CLI runs from Python.
Mapper(index=...) finds the C++ binary by checking, in order:
- The
binary=constructor argument. -
$PROT2EXON_BIN. -
<repo>/build/prot2exon(development checkouts). -
<repo>/bin/prot2exon(the shell wrapper). -
prot2exon-coreon$PATH, thenprot2exonon$PATH.
For installed users, ship the compiled binary on $PATH (pip / conda installs do this automatically) or set PROT2EXON_BIN explicitly.
Dataclass with these attributes (all DataFrames):
| Attribute | Source TSV |
|---|---|
summary |
domain_mapping_summary.tsv |
isoform |
isoform_structure.tsv |
cds_segments |
domain_cds_segments.tsv |
introns |
domain_introns.tsv |
cds_bed, introns_bed, span_bed, bed12
|
the four *.bed files |
unmapped |
unmapped_domains.tsv (empty if all rows mapped) |
metadata |
parsed run_metadata.json (only when --output all) |
out_dir |
path to the temp dir while alive |
Properties: n_total, n_mapped, n_unmapped.
Persist outputs to a permanent location:
result.write("results/my_run/")Filter to one input_id:
sub = result.by_input_id("TP53_DBD")p2e.plot(
source, # a MappingResult, an isoform DataFrame, or a path to isoform_structure.tsv
input_id="TP53_DBD",
out="tp53_dbd.pdf", # matplotlib
html=None, # plotly HTML
html_interactive=None, # interactive HTML
show_introns=True,
show_utr=True,
compact_genomic=False, # clamp introns to 80 bp
spliced=False, # drop introns entirely (mutex with compact_genomic)
link_template=None, # URL template with {protein_id}, {gene_name}, {transcript_id}, {chrom}
title=None,
)To render every input_id in the source, pass all=True instead of input_id, or use the explicit helper:
p2e.plot_all(result, out="all_queries.pdf") # multipage PDF (matplotlib)
p2e.plot_all(result, html="all_queries.html") # one plotly file per input_idsource can be a MappingResult, an isoform DataFrame, or a path to isoform_structure.tsv — all three are accepted:
p2e.plot(result, input_id="TP53_DBD", out="tp53.pdf")
p2e.plot(result.isoform, input_id="TP53_DBD", out="tp53.pdf")
p2e.plot("results/isoform_structure.tsv", input_id="TP53_DBD", out="tp53.pdf")# Standalone HTML file (any browser, offline)
p2e.render_interactive_html(segs, "out.html",
link_template="https://...",
plot_height=80)
# Inline in a Jupyter notebook
p2e.render_interactive_jupyter(segs,
height=None, # default: auto-resize via postMessage
plot_height=140, # main-track height in px
link_template="https://...")segs is a list[Segment]. Build it from a MappingResult:
from prot2exon.plot import _segments_from_dataframe
segs_by_id = _segments_from_dataframe(result.isoform)
segs = segs_by_id["TP53_DBD"]Or load straight from disk:
from prot2exon.plot import load_isoform_tsv
segs_by_id = load_isoform_tsv("results/isoform_structure.tsv")See Plotting for renderer-specific gestures and flags.
1 - How to install
2 - Building an index
(fastCDS index, fastCDS fetch)
3 - Mapping
(fastCDS map)
4 - Plotting
(fastCDS plot)
6 - Performance and benchmarking
7 - Reference