升级 NUPACK 4.1 并支持混合材料设计

This commit is contained in:
Lihatoo 2026-08-20 16:33:16 +08:00
parent 5daa60a464
commit c6189d857d
33 changed files with 5830 additions and 466 deletions

View file

@ -0,0 +1,94 @@
在ununtu上使用该命令安装draw_rna
pip install matplotlib numpy draw_rna --upgrade -i https://pypi.tuna.tsinghua.edu.cn/simple
-------------------------------打开原本步骤中lab中的记事本--------------------------
# 依赖导入
from nupack import *
from draw_rna.ipynb_draw import draw_struct
import os
import matplotlib.pyplot as plt
# 开启显示(恢复正常绘图展示)
plt.ion()
# ======================================
# 仅保留两个核心函数,完全用 draw_rna
# ======================================
def get_mfe_structure(complex_name: str, nupack_result, strands: list):
"""获取复合物MFE结构支持同源二聚体 Y1+Y1"""
strand_names = complex_name.strip('()').split('+')
strand_map = {s.name: s for s in strands}
strand_objs = [strand_map[name] for name in strand_names]
complex_obj = Complex(strand_objs)
return str(nupack_result[complex_obj].mfe[0].structure)
def draw_complex(complex_name: str, nupack_result, strands: list, output_folder="./"):
"""draw_rna绘图无页面显示直接保存图片到目标路径"""
os.makedirs(output_folder, exist_ok=True)
# 获取结构和序列(完全不变)
struct = get_mfe_structure(complex_name, nupack_result, strands)
strand_names = complex_name.strip('()').split('+')
strand_map = {s.name: s for s in strands}
seq = " ".join([str(strand_map[name]) for name in strand_names]) # 序列用空格分隔
draw_structure = struct.replace('+', ' ') # 结构用空格分隔
# 设置全局字体大小,可以根据需要调整数字 (例如 14, 18, 20)
plt.rcParams['font.size'] = 12
# ---------- 修正点:显式创建画布并传递给 draw_struct ----------
fig, ax = plt.subplots(figsize=(15, 15)) # 可调尺寸,保证图形清晰
draw_struct(seq, draw_structure, ax=ax) # 在指定 ax 上绘图
# 保存并关闭
save_name = complex_name.strip('()').replace('+', '_') + '.png'
save_path = os.path.join(output_folder, save_name)
plt.savefig(save_path, dpi=300, bbox_inches='tight')
print(f"\n✅ 图片已保存至:{save_path}")
print(f"MFE 结构:{struct}")
def draw_all_complexes(nupack_result, strands: list, output_folder="./"):
print("\n========== 开始批量绘制所有复合物 ==========")
# 过滤出 Complex 对象
complex_objs = [obj for obj in nupack_result.keys() if not isinstance(obj, Tube)]
total = len(complex_objs)
success_count = 0
for idx, complex_obj in enumerate(complex_objs, 1):
complex_name = complex_obj.name # ✅ 修正点
try:
draw_complex(complex_name, nupack_result, strands, output_folder)
success_count += 1
print(f"进度:{idx}/{total} 完成")
except Exception as e:
print(f"❌ 绘制复合物 {complex_name} 失败: {e}")
print("\n========== 所有复合物绘制完成 ==========")
print(f"✅ 批量绘制完成!成功:{success_count} / 总计:{total}")
print(f"📁 图片保存在:{os.path.abspath(output_folder)}")
-------------------------------- nupack计算--------------------------------------
model1 = Model(material='dna', celsius=37,sodium=0.1, magnesium=0.02)
Y1 = Strand('CGTTAACGCAGTGAGGACGGTAGTTTGTCGTTCCATCGCACC', name='Y1')
Y2 = Strand('CGTTAACGGGTGCGATGGAACGACTTTCGACAGGCCTGGTGTAATTTCACCCATGTTAGTCGA', name='Y2')
Y3 = Strand('ATACGGAAAATGGAGATAGGAAGAGTACAATGTCAGCGATAAATTCCGTATACGACACCAGGCCTGTCGATTACTACCGTCCTCACTG', name='Y3')
t1 = Tube({Y1: 1e-8, Y2: 1e-8, Y3:1e-8 },complexes=SetSpec(max_size=4), name='Tube 1')
my_result = tube_analysis(tubes=[t1], model=model1,
compute=['pfunc', 'pairs', 'mfe', 'sample', 'subopt'],
options={'num_sample': 1, 'energy_gap': 0.5})
print(my_result)
--------------------------- --------------- 单复合物绘图------------------------------
target = '(Y1+Y1+Y2+Y3)' # 替换为你的目标复合物名称
all_strands = [Y1, Y2, Y3] # 所有链的列表
# 1. 获取并打印MFE结构
mfe_struct = get_mfe_structure(target, my_result, all_strands)
#print("MFE结构", mfe_struct)
# 2. 绘制二级结构
draw_complex(target, my_result, all_strands, output_folder="/home/zsy")
--------------------------------------------批量绘图-----------------------------------
strands_list = [Y1, Y2, Y3]
draw_all_complexes(my_result, strands_list, output_folder="/home/zsy/jihe")