Skip to content

Latest commit

 

History

History
62 lines (44 loc) · 2.98 KB

moleculesInBlender.md

File metadata and controls

62 lines (44 loc) · 2.98 KB

首先,让我们看看我们将如何指定化学结构。化学世界充斥着可怕的文件格式,并且由于传统标准的普遍弹性,我们需要考虑它们。 然而,在我们开始之前,让我们决定分子数据的良好扩展表示。编码中使用的常用表示称为Javascript Objiect Notation或json, 它非常擅长简洁地表示任意数据。如果你以前从未听说过,我强烈建议你继续阅读它。这是 wiki 由于分子是任意数据的一个子集,json应该适合我们的需要。我们的drawer需要原子元素类型和3D位置,以及键连接和顺序。 因此,让我们使用如下所示的东西(例子是乙烷)

{
    "atoms": [
        { "element": "C", "location": [ 0.252, -0.116, -0.704 ] },
        { "element": "C", "location": [ -0.252, 0.116, 0.704 ] }
    ],
    "bonds": [
        { "atoms": [ 0, 1 ], "order": 1 }
    ]
}

这很容易在Python中解析

import json
data =json.loads(string)

在这两行中,我们现在有一个Python数据结构!如果我们想要打印第一个原子的y坐标,我们可以这样做

pirnt(data["atoms"][0]["location"][1]).

这将在以后派上用场。

现在,回到手头的问题。我们希望为数百种文件格式提供支持(molfiles,smiles,sdf,cif,pdb等,但解析他们都是绝对的噩梦。 在这篇文章那的先前版本中,我建议直接解析molfile。我现在收回我的话。那太愚蠢了。让我们使用Pybel,一个 openbabel 库的Python包。下载它,然后我们可以在一行代码中统一所有这些文件格式。

molecule = pybel.readstring(format,sting).

如果输入文件格式中没有位置数据,我们可以通过简单地调用来生成它。

molecule.make3D()

现在,我们可以将这种统一格式转换为json,我们将拥有统一的数据格式,而无需再编写任何解析逻辑

def molecule_to_json(molecule):
    """Converts an OpenBabel molecule to json for use in Blender."""

    # Save atom element type and 3D location.
    atoms = [{"element": atom.type,
            "location": atom.coords}
            for atom in molecule.atoms]

    # Save number of bonds and indices of endpoint atoms
    bonds = [{"atoms": [b.GetBeginAtom().GetIndex(), b.GetEndAtom().GetIndex()],
            "order": b.GetBondOrder()}
            for b in openbabel.OBMolBondIter(molecule.OBMol)]

    return json.dumps({"atoms": atoms, "bonds": bonds})

github存储库中存在一些额外的混乱来处理极端情况,但是这个函数通常应该可以工作。

从分子对象转换为json将在很多方面帮助我们。例如,我们可以测试文件格式转换器的质量, 甚至不需要涉及blender(在隔离块中调试代码比调试整个事件更好)。

link