制作分子编辑器/可视化器:面向对象编程、数据结构和分子

计算科学 计算化学 Python 可视化
2021-12-17 02:19:22

我是编程新手,我正在尝试解决我的第一个大问题并编写我的第一个大程序。我一直在寻找要学习的代码的开源示例,但到目前为止,我只找到了我不完全理解的语言的代码,或者那些相关但仍然太遥远的事情让我无法真正学习。我在这里无法采取一些概念性的步骤。

我想制作一个简单的软件来构建、修改并在以后表示有机小分子。这主要是一个学习练习。用户将给出一个 SMILES 字符串或从一组基本的起始分子中进行选择,然后可以以图形方式或通过文本输入语法在该分子上构建。但是,我什至还没有达到那种复杂程度。我什至无法完全理解如何制作类/对象来存储分子。所以,我的问题很简洁:我如何使用类/对象来构建分子,同时保留所有级别的信息,以及我应该使用哪些数据结构作为哪些对象的属性?而且,对象可以是其他对象的属性吗?

到目前为止,这是我的思路:我想有一个“Molecule”类,然后是“Atom”类/子类和“Bond”子类,也许还有一个“FunctionalGroup”子类。这似乎是一个很好的起点,但也许我误解了 OOP,这很糟糕。但后来我的问题真的变得令人困惑(对我来说)。尽管我拥有所有这些概念/想法/类,但我并没有完全掌握表示分子所需的数据结构。拥有一个原子列表将是一件好事。该列表可以是 Atom 对象的列表吗?我还需要有一种方法来存储连接性。二维矩阵似乎是一个好主意,键序在矩阵位置中是整数。

在这一点上,我开始对这项任务感到不知所措。到目前为止我所做的一切都有意义吗?在此之上附加一个显示/绘图方面可能意味着我需要重写/返工很多这些东西,但我只是想达到一个点,我至少可以将分子与相关数据一起存储,然后访问要检查/修改的数据。我正在考虑在 Python 中执行此操作,因此代码/类可能看起来像这样: http: //pastebin.com/uUi1BMzr

也许这真的是 StackOverflow 的编程问题,但我认为它足够具体到这里。任何帮助将不胜感激,即使您只是指出我在哪里犯了概念性错误。提前致谢。

4个回答

你的目标有很多挑战。我会把它们分成几部分。

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(element number)" 创建一个没有键的新原子,"mol.AddBond(atom1, atom2, bond_type)" 建立键连接。每个键都需要知道它所连接的原子,每个原子都需要一个键列表。这会导致数据结构中出现很多循环,但需要这样才能在线性时间内完成各种算法,例如连通性搜索。

不要使用二维矩阵。虽然对于小分子是可行的,但它的扩展性并不好,也没有必要。很少有算法需要连接矩阵,并且在需要时很容易生成。

没有“功能组”。太专业了 使用诸如“子集”或“片段”之类的东西,其中包含您感兴趣的原子和键的列表。这样,您还可以通过参考来处理诸如“选定原子”和“环子结构”和“脚手架”之类的东西特定的子集。

我看了你的pastebin。解析器不应该那样工作。您应该将解析与实际分子结构分开。尝试这样的事情:

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 主持的“蓝色方尖碑”问答网站。

编写软件是一个迭代过程 - 编写代码 -> 看看你能走多远,然后计划下一步 -> 编写代码 -> 重复。在学习艺术的这个阶段,我建议你尽快跳进去试一试。无需预先规划整个系统。是的,python 将是一种很好的第一语言。对于可视化,试试 MatPlotLib,NumPy 和 SciPy 也很方便。工业规模的软件总是依赖于引入预构建库,而不是自己编写所有内容,但是可以而且应该自己编写简单的解决方案,尤其是在学习编程时。您的 OO 布局现在看起来还可以。当/如果您的对象关系需要稍后更改时,重构代码本身的行为是值得掌握的经验。欢迎登机!

另一种入门方法可能是查看一些已经与您的问题相关的代码。在这种情况下,您的锻炼甚至可能会出现在其他程序中,那会很好,不是吗?

您可能感兴趣的程序是

  • MD 模拟和分子建模包MMTK(如上面 Nate 所建议的)

  • 可视化包PyMol

学习分子对象系统的细节是化学家学习面向对象编程的绝妙方法。你会发现这样一个系统的实施将改进你的分子直觉。你应该从属性和方法的角度认真思考原子、分子,也许还有分子的集合。

这里有一些不错的 python(有点旧)幻灯片,可能会有所帮助: http ://www.wag.caltech.edu/home/rpm/python_course/Lecture_4.pdf

检查您的工作:除了 openbabel(它有 python 绑定!)和 MMTK,还有 phenix 中的 ELBOW。

对于您的多语种,还有 PerlMol (Perlmol.org)。PerlMol 是用面向对象的 perl 编写的,可以从 CPAN 下载。