如何利用RDKit优化MCS计算?含数据库Cartridge调用问题
分子成对相似性计算与MCS计算问题
问题背景
需要对数据库中的分子进行成对相似性计算,满足条件时计算MCS(最大公共子结构)。最初用Python itertools实现,尝试用RDKit Cartridge提升速度,已完成成对相似性计算,但无法调用fmcs函数;若Cartridge方法不可行,希望优化Python中MCS计算的性能。
一、RDKit Cartridge调用fmcs函数的问题
当前SQL代码通过交叉连接完成相似性计算,但调用fmcs_smiles失败:
select foo.mol_inchikey, boo.mol_inchikey, foo.mol_ecfp4_sfp, boo.mol_ecfp4_sfp, dice_sml(foo.mol_ecfp4_sfp, boo.mol_ecfp4_sfp) as sml, fmcs_smiles(foo.mol_mol::text, boo.mol_mol::text) as mcs from (select distinct(m.mol_inchikey), m.mol_ecfp4_sfp, m.mol_mol from cipsi_prototype.molecule m inner join cipsi_prototype.pat2mol pm on pm.mol_inchikey = m.mol_inchikey) as foo cross join (select distinct(m.mol_inchikey), m.mol_ecfp4_sfp, m.mol_mol from cipsi_prototype.molecule m inner join cipsi_prototype.pat2mol pm on pm.mol_inchikey = m.mol_inchikey) as boo
解决方案
修正参数类型:
RDKit Cartridge的fmcs_smiles函数需要接收RDKit Mol类型参数,而非文本类型。根据mol_mol字段的存储类型调整:- 若
mol_mol是预存的RDKit Mol类型(如rdkit_mol),直接传入字段即可:fmcs_smiles(foo.mol_mol, boo.mol_mol) as mcs - 若
mol_mol存储的是SMILES文本,需先转成Mol类型:fmcs_smiles(mol_from_smiles(foo.mol_mol), mol_from_smiles(boo.mol_mol)) as mcs
- 若
优化查询效率:
交叉连接会生成重复对(A-B与B-A)和自身对(A-A),添加过滤条件减少无效计算:where foo.mol_inchikey < boo.mol_inchikey
二、Python环境下MCS计算的性能优化
当前Python实现代码:
rdFMCS.FindMCS([molecules[mol1]['mol'], molecules[mol2]['mol']], ringMatchesRingOnly=True, completeRingsOnly=True, timeout=1).smartsString
优化方案
前置相似性过滤:
先计算ECFP4的Dice相似性,仅对相似性高于业务阈值(如0.5)的分子对计算MCS,大幅减少计算量。并行计算:
MCS计算是CPU密集型且无状态任务,用多进程并行处理:from concurrent.futures import ProcessPoolExecutor def calculate_mcs(mol_pair): mol1, mol2 = mol_pair try: return rdFMCS.FindMCS([mol1, mol2], ringMatchesRingOnly=True, completeRingsOnly=True, timeout=1).smartsString except: return None # 准备需要计算的分子对列表(已过滤重复和低相似性) mol_pairs = [(molecules[mol1]['mol'], molecules[mol2]['mol']) for mol1 in molecules for mol2 in molecules if mol1 < mol2 and similarity >= threshold] with ProcessPoolExecutor() as executor: results = list(executor.map(calculate_mcs, mol_pairs))调整计算参数:
根据业务需求放宽约束,减少计算复杂度:- 若无需严格价态匹配,添加
matchValences=False - 评估是否需要
completeRingsOnly=True,仅保留ringMatchesRingOnly=True可降低计算量
- 若无需严格价态匹配,添加
预加载与去重:
- 确保
molecules中的Mol对象已预解析完成,避免重复解析SMILES/InChI - 只计算无序对(
mol1 < mol2),跳过反向和自身对,减少一半计算量
- 确保
内容的提问来源于stack exchange,提问作者María
相关产品推荐
相关产品推荐

