Skip to content

Add SEA prediction module#7

Open
Hinna0818 wants to merge 7 commits intoYuLab-SMU:masterfrom
Hinna0818:sea_prediction
Open

Add SEA prediction module#7
Hinna0818 wants to merge 7 commits intoYuLab-SMU:masterfrom
Hinna0818:sea_prediction

Conversation

@Hinna0818
Copy link
Contributor

添加基于SEA的化合物靶点预测。

  1. dataloader.py是从google drive下载数据库和配置文件到本地,如果本地已经有的话脚本就默认跳过这个步骤。
  2. runsea.py是实现SEA预测过程的模块。
  3. main.py是主脚本,导入前面两个模块进行靶点预测。用户可以自己修改该脚本的输出化合物信息,最后会保存一个靶点预测结果的csv文件到文件夹下。

详细的说明可以见该目录的readme文件。

@Hinna0818
Copy link
Contributor Author

这个pr的冲突也解决了,可以作为第二个审阅的对象

@GuangchuangYu
Copy link
Member

SEA官方python文件?

@Hinna0818
Copy link
Contributor Author

SEA官方python文件?

https://sea.bkslab.org/datasets SEA官方提供的数据集如下:
dee3c8aa7391c8f82422be0eda54e3be
一个是化合物的rdata文件,另一个是化合物-靶点的rdata文件,另外一个是模型背景参数的fit文件。我是先对这两个rdata在服务器上与处理了一下:提取化合物结构和靶点信息,利用 RDKit 计算分子指纹,最后将所有处理好的数据和元数据打包保存为一个 Python 的 .pkl 文件,脚本如下:

import pandas as pd
import pyreadr
from rdkit import Chem
from rdkit.Chem import AllChem
import pickle
import os
from tqdm import tqdm

# Configuration paths
BASE_PATH = "/biostack/home/henan/tcmdata/new_data/chembl27_rdkit_ecfp4"
COMPOUNDS_PATH = os.path.join(BASE_PATH, "chembl27_rdkit_ecfp4_compounds.Rdata")
SETS_PATH = os.path.join(BASE_PATH, "chembl27_rdkit_ecfp4_sets.Rdata")
OUTPUT_FILE = "target_fp_db_with_metadata.pkl"

def build_database():
    print("loading Rdata file...")
    comp_data = pyreadr.read_r(COMPOUNDS_PATH)
    sets_data = pyreadr.read_r(SETS_PATH)

    # Extract DataFrame
    chembl_smi = comp_data[list(comp_data.keys())[0]]
    chembl_sets = sets_data[list(sets_data.keys())[0]]

    # Process compound SMILES
    lig = chembl_smi.iloc[:, 0:2].copy()
    lig.columns = ['compound', 'smiles']
    lig = lig.drop_duplicates(subset=['compound'])

    # Merge tables to get target details (Target, Name, Description)
    merged = pd.merge(lig, chembl_sets, on='compound', how='inner')

    # Extract organism
    merged['organism'] = merged['target'].str.split('_').str[-1]

    # Build target metadata dictionary {target_id: {symbol, organism, description}}
    metadata = merged[['target', 'name', 'organism', 'description']].drop_duplicates(subset=['target'])
    metadata_dict = metadata.set_index('target').to_dict('index')

    # Group SMILES by target
    target_smiles_dict = merged.groupby('target')['smiles'].apply(list).to_dict()

    print(f"Starting fingerprint calculation (Total targets: {len(target_smiles_dict)})...")
    final_fps = {}
    for target, smiles_list in tqdm(target_smiles_dict.items()):
        valid_fps = []
        for smi in smiles_list:
            if not smi or smi == 'nan': continue
            mol = Chem.MolFromSmiles(smi)
            if mol:
                # Generate 2048-bit Morgan fingerprint (ECFP4)
                fp = AllChem.GetMorganFingerprintAsBitVect(mol, 2, nBits=2048)
                valid_fps.append(fp)
        
        if valid_fps:
            final_fps[target] = valid_fps

    # Save
    print(f"Saving database to {OUTPUT_FILE} ...")
    with open(OUTPUT_FILE, 'wb') as f:
        pickle.dump({"fingerprints": final_fps, "metadata": metadata_dict}, f)
    print("Database build complete!")

if __name__ == "__main__":
    build_database()

最后生成一个二进制文件target_fp_db_with_metadata.pkl,再把这个文件和一开始的背景模型参数.fit文件打包到Google Drive上,就作为这个模块的一个小数据集。后面的dataloader.py, runsea.py, main.py都是根据给定参数和文献方法从头实现SEA的预测模块。

@GuangchuangYu
Copy link
Member

从头实现为什么不用R?

@Hinna0818
Copy link
Contributor Author

从头实现为什么不用R?

目前的问题在于指纹生成的算法一致性。原有的SEA统计模型(即 .fit 背景文件)是基于RDKit的Morgan指纹训练出来的,R原生的rcdk包虽然也能计算ECFP4指纹,但其底层的哈希算法和 RDKit(C++底层)存在细微差异。如果直接用rcdk算出的指纹去匹配基于 RDKit训练的统计模型,会导致计算出的Z-score和 P-value 出现偏差。

如果要用R,目前我想到比较好的方法就是用reticulate包调用python的RDKit库来计算,但这样会不会安装和使用起来困难一些?

@GuangchuangYu
Copy link
Member

我是先对这两个rdata在服务器上与处理了一下:提取化合物结构和靶点信息,利用 RDKit 计算分子指纹,最后将所有处理好的数据和元数据打包保存为一个 Python 的 .pkl 文件

目前的问题在于指纹生成的算法一致性。原有的SEA统计模型(即 .fit 背景文件)是基于RDKit的Morgan指纹训练出来的,R原生的rcdk包虽然也能计算ECFP4指纹,但其底层的哈希算法和 RDKit(C++底层)存在细微差异。如果直接用rcdk算出的指纹去匹配基于 RDKit训练的统计模型,会导致计算出的Z-score和 P-value 出现偏差。

你这不思路有点坑!

@Hinna0818
Copy link
Contributor Author

我是先对这两个rdata在服务器上与处理了一下:提取化合物结构和靶点信息,利用 RDKit 计算分子指纹,最后将所有处理好的数据和元数据打包保存为一个 Python 的 .pkl 文件

目前的问题在于指纹生成的算法一致性。原有的SEA统计模型(即 .fit 背景文件)是基于RDKit的Morgan指纹训练出来的,R原生的rcdk包虽然也能计算ECFP4指纹,但其底层的哈希算法和 RDKit(C++底层)存在细微差异。如果直接用rcdk算出的指纹去匹配基于 RDKit训练的统计模型,会导致计算出的Z-score和 P-value 出现偏差。

你这不思路有点坑!

老师我没明白您的意思,官方的数据描述是:Uniprot Entry to Zinc ID with Extended Connectivity Fingerprint with diameter 4 (Hashed) fingerprints。这个数据库(包括 .fit 文件里的统计参数 MU 和 SIGMA)在构建的时候,也就是原作者在做数据的时候,用的就是 RDKit 的 Morgan 指纹(Radius=2, 相当于 Diameter=4)。我处理的时候用的也是RDKit,参数和官方一样也是 Radius=2(即 Diameter=4),这样就和官方的一致了。

@GuangchuangYu
Copy link
Member

GuangchuangYu commented Jan 30, 2026

为什么觉得有坑,因为不兼容是你自己搞出来的。你应该统一在R里,这个功能才是可用的。现在这上,等同于没有用。

用rcdk,如果差别太大,不能接受,那就用C++版的RDKit,用R封装。要么不做,要么就做到让别人容易用。

@Hinna0818
Copy link
Contributor Author

为什么觉得有坑,因为不兼容是你自己搞出来的。你应该统一在R里,这个功能才是可用的。现在这上,等同于没有用。

用rcdk,如果差别太大,不能接受,那就用C++版的RDKit,用R封装。要么不做,要么就做到让别人容易用。

我明白了老师,我研究一下能否用R封装C++版的RDKit来实现这个功能。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants