Deep generalizable prediction of RNA secondary structure via base pair motif energy
Heqin Zhu · Fenghe Tang · Quan Quan · Ke Chen · Peng Xiong* · S. Kevin Zhou*
Paper | PDF | poster | GitHub | PyPI
Introduction
Deep learning methods have demonstrated great performance for RNA secondary structure prediction. However, generalizability is a common unsolved issue on unseen out-of-distribution RNA families, which hinders further improvement of the accuracy and robustness of deep learning methods. Here we construct a base pair motif library that enumerates the complete space of locally adjacent three-neighbor base pair and records the thermodynamic energy of corresponding base pair motifs through de novo modeling of tertiary structures, and we further develop a deep learning approach for RNA secondary structure prediction, named BPfold, which learns relationship between RNA sequence and the energy map of base pair motif. Experiments on sequence-wise and family-wise datasets have demonstrated the great superiority of BPfold compared to other state-of-the-art approaches in accuracy and generalizability. We hope this work contributes to integrating physical priors and deep learning methods for the further discovery of RNA structures and functionalities.
Installation
Requirements
- python3.8+
- anaconda
Use base pair motif library
pip3 install BPfold
Predict RNA secondary structure
- Clone this repo
git clone https://github.com/heqin-zhu/BPfold.git
cd BPfold
- Create and activate BPfold environment.
conda env create -f BPfold_environment.yaml
conda activate BPfold
- Download model_predict.tar.gz in releases and decompress it.
wget https://github.com/heqin-zhu/BPfold/releases/latest/download/model_predict.tar.gz
tar -xzf model_predict.tar.gz
- Optional (for training and evaluation): Download datasets BPfold_data.tar.gz in releases and decompress them.
wget https://github.com/heqin-zhu/BPfold/releases/latest/download/BPfold_data.tar.gz
tar -xzf BPfold_data.tar.gz
Usage
Base pair motif library
The base pair motif library is publicly available in releases, which contains the motif:energy pairs. The motif is represented as sequence_pairIdx_pairIdx-chainBreak where pairIdx is 0-indexed, and the energy is a reference score of statistical and physical thermodynamic energy.
For instance, CAAAAUG_0_6-3 -49.7835 represents motif CAAAAUG has a known pair C-G whose indexes are 0 and 6, with chainBreak lying at position 3.
[!NOTE] The base pair motif library can be used as thermodynamic priors in other models.
For an input RNA sequence seq, the base pair motif energy matrix mat can be directly obatined as follows:
from BPfold.util.base_pair_motif import BPM_energy
BPM = BPM_energy()
seq = 'AUGCGUAGTa'
# default, recommended, normed according to the major energy of each motif type, BPfold used, shape 2xLxL
mat = BPM.get_energy(seq)
# origin energy, value may be -50.3, 49.7, ..., shape 1xLxL
mat2 = BPM.get_energy(seq, normalize_energy=False, dispart_outer_inner=False)
To get a folding score of a sequence for reference, we accumulate all energy items from canonical base pairs assigned by greedy search matching algorithm (issue #2).
from src.BPfold.util.base_pair_motif import BPM_energy()
seq = 'GCGCAGGACUCGGCUUCUUCGGAAGGGACGAGGGGCGC'
score = BPM_energy().get_score(seq)
print(score)
BPfold for secondary structure prediction
Run command line
Args:
--checkpoint_dir: required, specify checkpoint dir path.--seq: specify one or more input RNA sequences.--input: specify input file of RNA seqs in format of.fasta(multiple seqs are supported),.bpseq,.ct, or.dbn.--output: output dir (will be created automatically), defaultBPfold_results.--out_type: out format of RNA secondary structures, can be.csv,.bpseq,.ct, or.dbn, default.csvHere are some examples:
BPfold --checkpoint_dir PATH_TO_CHECKPOINT_DIR --seq GGUAAAACAGCCUGU AGUAGGAUGUAUAUG --output BPfold_results
BPfold --checkpoint_dir PATH_TO_CHECKPOINT_DIR --input examples/examples.fasta --out_type csv # (multiple sequences are supported)
BPfold --checkpoint_dir PATH_TO_CHECKPOINT_DIR --input examples/URS0000D6831E_12908_1-117.bpseq
Example of BPfold prediction
Here are the outputs after running BPfold --checkpoint_dir model_predict --input examples/examples.fasta --out_type bpseq:
>> Welcome to use "BPfold" for predicting RNA secondary structure!
Loading model_predict/BPfold_1-6.pth
Loading model_predict/BPfold_2-6.pth
Loading model_predict/BPfold_3-6.pth
Loading model_predict/BPfold_4-6.pth
Loading model_predict/BPfold_5-6.pth
Loading model_predict/BPfold_6-6.pth
[ 1] saved in "BPfold_results/1M5L.bpseq", CI=0.913
GCGCAGGACUCGGCUUCUUCGGAAGGGACGAGGGGCGC
((((....((((.(((((..)))))...))))..))))
............(..............).......... NC
((((....((((((((((..)))))..)))))..)))) MIX
[ 2] saved in "BPfold_results/URS0000D6831E_12908_1-117.bpseq", CI=0.892
UUAUCUCAUCAUGAGCGGUUUCUCUCACAAACCCGCCAACCGAGCCUAAAAGCCACGGUGGUCAGUUCCGCUAAAAGGAAUGAUGUGCCUUUUAUUAGGAAAAAGUGGAACCGCCUG
......((((((.....((((.......))))..(((.((((.((......))..))))))).................))))))..(((......)))..................
..................................................................................................................... NC
......((((((.....((((.......))))..(((.((((.((......))..))))))).................))))))..(((......))).................. MIX
Confidence indexes are saved in "BPfold_results_confidence_20250915_03h19m33s.yaml"
Program Finished!
[!NOTE] Results (dbn, connects, bpseq...) with no tag are predicted canonical pairs, tagged with
_ncare predicted non-canonical pairs, and tagged with_mixare mixed canonical and non-canonical pairs (i.e., all base pairs). If you want to ignore non-canonical pairs, pass argument--ignore_ncto BPfold.
Run command BPfold -h for more help information.
Import python code
Specify arguments:
checkpiont_dir- at least one of
input_seqs(list of seqs) andinput_path(fasta_path)
from BPfold.predict import BPfold_predict
from BPfold.util.RNA_kit import connects2dbn
## arguments
checkpoint_dir = '' # to be specified
input_seqs = ['GCGCAGGACUCGGCUUCUUCGGAAGGGACGAGGGGCGC', 'AUGUAUGUCCUGUCGUA']
input_path = 'examples/examples.fasta'
## init model
BPfold_predictor = BPfold_predict(checkpoint_dir)
## BPfold predict # specify at least one of input_seqs and input_path
pred_results = BPfold_predictor.predict(input_seqs=input_seqs, input_path=input_path, ignore_nc=False)
for dic in pred_results:
print(f'>{dic["seq_name"]}')
print(dic["seq"])
print(connects2dbn(dic["connects"]), f'CI={dic["CI"]:.3f}')
Results of BPfold prediction
Loading /public2/home/heqinzhu/gitrepo/RNA/SS_pred/BPfold/src/BPfold/paras/model_predict/BPfold_1-6.pth
Loading /public2/home/heqinzhu/gitrepo/RNA/SS_pred/BPfold/src/BPfold/paras/model_predict/BPfold_2-6.pth
Loading /public2/home/heqinzhu/gitrepo/RNA/SS_pred/BPfold/src/BPfold/paras/model_predict/BPfold_3-6.pth
Loading /public2/home/heqinzhu/gitrepo/RNA/SS_pred/BPfold/src/BPfold/paras/model_predict/BPfold_4-6.pth
Loading /public2/home/heqinzhu/gitrepo/RNA/SS_pred/BPfold/src/BPfold/paras/model_predict/BPfold_5-6.pth
Loading /public2/home/heqinzhu/gitrepo/RNA/SS_pred/BPfold/src/BPfold/paras/model_predict/BPfold_6-6.pth
>seq_20250929_14h23m28s_1
GCGCAGGACUCGGCUUCUUCGGAAGGGACGAGGGGCGC
((((....((((.(((((..)))))...))))..)))) CI=0.913
>seq_20250929_14h23m28s_2
AUGUAUGUCCUGUCGUA
.....((......)).. CI=0.807
>1M5L
GCGCAGGACUCGGCUUCUUCGGAAGGGACGAGGGGCGC
((((....((((.(((((..)))))...))))..)))) CI=0.913
>URS0000D6831E_12908_1-117
UUAUCUCAUCAUGAGCGGUUUCUCUCACAAACCCGCCAACCGAGCCUAAAAGCCACGGUGGUCAGUUCCGCUAAAAGGAAUGAUGUGCCUUUUAUUAGGAAAAAGUGGAACCGCCUG
......((((((.....((((.......))))..(((.((((.((......))..))))))).................))))))..(((......))).................. CI=0.892
Evaluation
Specify pred_dir and gt_dir. In each directory, there are secondary structures in format of bpseq, ct, or dbn.
BPfold_eval --pred_dir BPfold_results --gt_dir PATH_TO_NATIVE_STRUCTURES
Reproduction
For reproduction of all the quantitative results, we provide the predicted secondary structures and model parameters of BPfold in experiments. You can directly downalod the predicted secondary structures by BPfold or use BPfold v0.2.0 with trained parameters to predict these secondary structures, and then evaluate the predicted results.
Directly download
wget https://github.com/heqin-zhu/BPfold/releases/download/v0.2/BPfold_test_results.tar.gz
tar -xzf BPfold_test_results.tar.gz
Use BPfold
- Download the checkpoints of BPfold: BPfold_reproduce.tar.gz.
wget https://github.com/heqin-zhu/BPfold/releases/download/v0.2/model_reproduce.tar.gz
tar -xzf model_reproduce.tar.gz
- Install BPfold version 0.2.4.
pip install BPfold==0.2.4
- Use BPfold to predict RNA sequences in test datasets.
Evaluate
BPfold_eval --gt_dir BPfold_data --pred_dir BPfold_test_results
After running above commands for evaluation, you will see the following outputs:
Outputs of evaluating BPfold
Time used: 29s
[Summary] eval_BPfold_test_results.yaml
Pred/Total num: [('PDB_test', 116, 116), ('Rfam12.3-14.10', 10791, 10791), ('archiveII', 3966, 3966), ('bpRNA', 1305, 1305), ('bpRNAnew', 5401, 5401)]
-------------------------len>600-------------------------
dataset & num & INF & F1 & P & R \\
Rfam12.3-14.10 & 64 & 0.395 & 0.387 & 0.471 & 0.333\\
archiveII & 55 & 0.352 & 0.311 & 0.580 & 0.242\\
------------------------len<=600-------------------------
dataset & num & INF & F1 & P & R \\
PDB_test & 116 & 0.817 & 0.814 & 0.840 & 0.801\\
Rfam12.3-14.10 & 10727 & 0.696 & 0.690 & 0.662 & 0.743\\
archiveII & 3911 & 0.829 & 0.827 & 0.821 & 0.843\\
bpRNA & 1305 & 0.670 & 0.658 & 0.599 & 0.770\\
bpRNAnew & 5401 & 0.655 & 0.647 & 0.604 & 0.723\\
---------------------------all---------------------------
dataset & num & INF & F1 & P & R \\
PDB_test & 116 & 0.817 & 0.814 & 0.840 & 0.801\\
Rfam12.3-14.10 & 10791 & 0.694 & 0.689 & 0.660 & 0.741\\
archiveII & 3966 & 0.823 & 0.820 & 0.818 & 0.834\\
bpRNA & 1305 & 0.670 & 0.658 & 0.599 & 0.770\\
bpRNAnew & 5401 & 0.655 & 0.647 & 0.604 & 0.723\\
Acknowledgement
We appreciate the following open source projects:
LICENSE
Citation
If you find our work helpful, please cite our paper:
@article{BPfold,
title = {Deep generalizable prediction of {RNA} secondary structure via base pair motif energy},
author = {Zhu, Heqin and Tang, Fenghe and Quan, Quan and Chen, Ke and Xiong, Peng and Zhou, S. Kevin},
volume = {16},
issn = {2041-1723},
url = {https://doi.org/10.1038/s41467-025-60048-1},
doi = {10.1038/s41467-025-60048-1},
number = {1},
journal = {Nature Communications},
month = jul,
year = {2025},
pages = {5856},
}
Release files for BPfold 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| bpfold-0.3.1.tar.gz | 435.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bpfold-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 879.6 kB
Release files / bpfold-0.3.1.tar.gz
| Download URL | bpfold-0.3.1.tar.gz |
|---|---|
| Size | 435.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e7b9db98d0693a67c9051a5b2062ec951941c69dfd3d63d3f4e9b3ac2c6037e0
|
|
BLAKE2b-256 checksum How to use checksums |
ce04c3ea9359eed51c260f5898274bdabc68b108b2890e6d609455fe1745c29b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Jan 8, 2026.
Transparency logRelease files / bpfold-0.3.1-py3-none-any.whl
| Download URL | bpfold-0.3.1-py3-none-any.whl |
|---|---|
| Size | 443.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
44126a2048b401da7dabd9081d444f678ed4951fb295d5e1017dd3060ee7ba82
|
|
BLAKE2b-256 checksum How to use checksums |
3b576705d8493ab56da99545755f086e3f39f497f9b880db8054cf9f9ceae6a0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Jan 8, 2026.
Transparency log