您的目标有很多挑战。我将它们分为几部分。
SMILES并不是一门琐碎的语言,对于芳香感的规则还没有很好的定义。OpenSMILES项目中详细的语法定义应有所帮助。
SMILES定义拓扑,但不提供2D或3D信息。做一个都很难。(也就是说,如果您希望它看起来不错。)
确实,您应该使用RDKit化学格式工具包(或OpenBabel,但我更喜欢RDKit)。它具有内置的SMILES解析器以及2D布局,并且我相信3D构象生成。OpenBabel也是如此。
然后为了显示,您必须弄清楚GUI系统。实际上,这里的Java CDK化学信息工具包是最先进的。
但是您掌握了如何表示分子的基础知识。小分子和大分子(蛋白质,DNA)数据模型之间存在差异,但是由于您对SMILES感兴趣,这意味着您面向小分子。
您可以查看RDKit,OpenBabel,CDK,OEChem和Indigo等的API文档。这将使您了解人们开发其类API的多种方式。其中,我最喜欢OEChem,其次是RDKit。即使OEChem是开源的,该API仍是在线且可免费阅读的,以及使用示例。
简而言之,有一个Molecule类,其中包含Atom和Bond实例的列表。“ mol.AddAtom(元素编号)”创建一个没有键的新原子,“ mol.AddBond(atom1,atom2,bond_type)”建立键连接。每个键都需要知道其连接的原子,每个原子都需要一个键列表。这导致了数据结构中的许多循环,但是这是必需的,以便可以在线性时间内完成各种算法(例如连接性搜索)。
不要使用2D矩阵。虽然对于一个小分子而言可行,但它的缩放比例不够好,因此也不需要它。很少有算法需要连通性矩阵,并且在需要时很容易生成。
没有“ FunctionalGroup”。太专业了。使用诸如“子集”或“片段”之类的东西,其中包含您感兴趣的原子和键的列表。这样,您还可以通过引用来处理“选定原子”,“环子结构”和“支架”之类的东西。特定子集。
我看着你的便签纸。解析器不应该那样工作。您应该将解析与实际的分子结构分开。尝试这样的事情:
class Molecule(object):
def __init__(self):
self.atoms = []
self.bonds = []
self._atom_id = 0
self._bond_id = 0
def _next_atom_id(self):
atom_id = self._atom_id
self.atom_id += 1
return atom_id
def AddAtom(self, eleno):
self.atoms.append(Atom(self, self._next_atom_id(), eleno))
def AddBond(self, atom1, atom2, bondtype):
assert atom1.molecule is atom2.molecule
self.bonds.append(Bond(self, self._next_bond_id(),
atom1, atom2, bondtype))
class Atom(object):
def __init__(self, molecule, id, eleno):
self.molecule = molecule
self.id = id
self.eleno = eleno
self.charge = 0
self.isotope = 0
..
然后,像“ CC O”这样的简单线性链的解析器是:
def parse_linear_chain(text):
mol = Molecule()
prev_atom = None
for atom_symbol in text.split():
eleno = lookup_symbol[atom_symbol]
atom = mol.NewAtom(eleno)
if pre_atom is not None:
mol.AddBond(prev_atom, atom, 1)
prev_atom = atom
return mol
当然,完整的SMILES解析器要比这复杂得多,并且完整的数据模型必须处理诸如氢计数之类的事情,而这通常是隐式的。
如果您决定使用其中一种工具包,OpenBabel,RDKit和CDK邮件列表也是不错的选择。还有Shapado主持的“蓝色方尖碑”问答网站。