MCS:Maximum Common Substructure
即使查询分子与数据库分子不完全匹配,也想知道其中有多少个通用结构,即最大公共子结构(MCS)。可以使用与子图同构相同的方法来计算。也可以按原样使用公共键(边)的数量作为阈值,或将其转换为相似性指标,例如Jaccard / Tanimoto系数。
部分结构匹配的情况下,可以在结构匹配时(或确定它们不匹配时)中止搜索,但是在MCS的情况下,可以输出最优解,直到搜索到所有可能性为止。有必要设计诸如确定计算时间的上限,当公共边缘的数量超过阈值时中止搜索或者使用高速近似解算法的手段。
尽管即使使用VF2算法也可以计算MCS,但已经开发了许多更高效且针对特定应用的算法。作为开源的MCS实现,RDKit具有基于DFS的算法FMCS和VF2。
导入库
from rdkit import rdBase, Chem
from rdkit.Chem import AllChem, Draw
from rdkit.Chem import rdFMCS
from rdkit.Chem.Scaffolds import MurckoScaffold
import pubchempy as pcp
载入数据
suppl = Chem.SDMolSupplier('sdf_20191011165056.sdf')
mols = [x for x in suppl if x is not None]
len(mols)
子结构匹配
HasSubstructMatch返回是否具有指定的子结构。该方法可用于化合物的简单筛选。
ph_bpin = pcp.get_compounds('phenyl boronic acid pinacol ester', 'name')
len(ph_bpin)
1
ph_bpin = ph_bpin[0]
tmp = Chem.MolFromSmiles(ph_bpin.canonical_smiles)
ph_mols = [x for x in suppl if x.HasSubstructMatch(tmp)]
len(ph_mols)
138
获取匹配的子结构
GetSubstructMatch中,可以将第一个匹配部分的原子索引获取为元组;在GetSubstructMatches中,即使进行多次匹配,所有原子索引也都可以获取为元组。通过将其传递给Draw.MolToImage的highlightAtoms选项,可以显示匹配的片段。
matches = ph_mols[4].GetSubstructMatches(tmp)
Draw.MolToImage(ph_mols[4], highlightAtoms=matches[0])
matches = ph_mols[4].GetSubstructMatches(tmp)
Draw.MolToImage(ph_mols[4], highlightAtoms=matches[0])
Draw.MolToImage(ph_mols[4], highlightAtoms=matches[1])
子结构匹配进行结构转换
使用子结构匹配的结构转换中,可以删除和替换。两种方法都返回一个新的Mol对象,而不更改原始分子。
delete_mols = [AllChem.DeleteSubstructs(x, Chem.MolFromSmiles('CC(C)(C(C)(C)O)O')) for x in ph_mols]
Draw.MolsToGridImage(delete_mols[:10], molsPerRow=5)
将分子分离成主链和侧链
replace_side = [AllChem.ReplaceSidechains(x, tmp) for x in ph_mols]
Draw.MolsToGridImage(replace_side[:10], molsPerRow=5)
replace_core = [AllChem.ReplaceCore(x, tmp) for x in ph_mols]
Chem.MolToSmiles(replace_core[67])
### '[*]N.[*][N+](=O)[O-]'
Draw.MolsToGridImage([ph_mols[67], replace_side[67], replace_core[67]])
side_mol = Chem.GetMolFrags(replace_core[67], asMols=True)
Draw.MolsToGridImage([x for x in side_mol])
RDKit上的分子骨架:Bemis / Murcko(BM)支架
RDKit使用Bemis和Murcko等人的方法实现了一种提取分子主要骨架的方法。例如,以下四个分子仅在我们眼中出现是因为侧链的形状和长度不同。通过使用GetScaffoldForMol,我们可以完全按照我们的想法获得骨架。
compounds = [4,6,9,14]
scaffold1 = [MurckoScaffold.GetScaffoldForMol(ph_mols[i]) for i in compounds]
Draw.MolsToGridImage(scaffold1, molsPerRow=4)
恶二唑和噻二唑没有太大区别。MakeScaffoldGeneric返回一个骨架,其中所有杂原子都变为碳。因此,可以处理具有与相同骨架相似的结构的苯和吡啶,呋喃和吡咯。
Draw.MolsToGridImage([MurckoScaffold.MakeScaffoldGeneric(ph_mols[i]) for i in (23,30)])
MCS:最大公共子结构
到目前为止,在子结构搜索中,需要知道要搜索的结构作为输入结构。RDKit实现了一种使用多个分子作为输入结构来搜索通用部分结构(MCS)的算法。
MCSResult对象
FindMCS方法返回一个MCSResult对象。从这个目的,有可能获得原子和键的数目,并获得所获得结构的Smarts。
mcs_01 = rdFMCS.FindMCS([ph_mols[12], ph_mols[15]])
mol_mcs_01 = Chem.MolFromSmarts(mcs_01.smartsString)
Draw.MolToImage(ph_mols[12], highlightAtoms=ph_mols[12].GetSubstructMatch(mol_mcs_01))
Draw.MolToImage(ph_mols[15], highlightAtoms=ph_mols[15].GetSubstructMatch(mol_mcs_01))
分子的相似性表明在结构上存在某些共同点。这次从输入结构的子结构搜索开始,处理匹配结构的删除/替换以及将分子分离为主链和侧链。此外,我们已经看到,无需指定输入结构即可获得分子骨架,也可以从多个分子中提取通用结构。此内容对于将来将要处理的化合物的聚类等分析非常重要。
参考
http://www.rdkit.org/docs/GettingStartedInPython.html#maximum-common-substructure
http://rdkit.org/docs/source/rdkit.Chem.rdFMCS.html