1. QM9 数据集的XYZ格式详解
这个数据集使用的 “XYZ-like” 格式是一种扩展的、非标准的XYZ格式。
| 行号 | 内容 | 解释 |
|---|---|---|
| 第 1 行 | na |
一个整数,代表分子中的原子总数。 |
| 第 2 行 | Properties 1-17 |
包含17个理化性质的数值,用制表符或空格分隔。 |
| 第 3 到 na+2 行 | Element x y z charge |
每行代表一个原子。依次是:元素符号、x/y/z坐标(单位:埃)、Mulliken部分电荷(单位:e)。 |
| 第 na+3 行 | Frequencies |
分子的振动频率(3na-5或3na-6个)。 |
| 第 na+4 行 | SMILES_GDB9 SMILES_relaxed |
来自GDB9的SMILES字符串和弛豫后的几何构型的SMILES字符串。 |
| 第 na+5 行 | InChI_GDB9 InChI_relaxed |
对应的InChI字符串。 |
与标准XYZ格式对比: * 标准格式只有第1行(原子数)、第2行(注释)和后续的原子坐标行(仅含元素和xyz坐标)。 * QM9格式在第2行插入了大量属性数据,在原子坐标行增加了电荷列,并在文件末尾附加了频率、SMILES和InChI信息。
2. readme
- 数据集核心内容:
- 它包含了133,885个小型有机分子(由H, C, N, O, F元素组成)的量子化学计算数据。
- 所有分子的几何构型都经过了DFT/B3LYP/6-31G(2df,p)水平的优化。
dsC7O2H10nsd.xyz.tar.bz2是该数据集的一个子集,专门包含6,095个C₇H₁₀O₂的同分异构体,其能量学性质在更高精度的G4MP2理论水平下计算。
- 文件结构与格式:
- 明确指出每个分子存储在单独的
.xyz文件中,并详细描述了上述的非标准XYZ扩展格式。 - 详细列出了记录在文件第2行的17种理化性质,包括转动常数(A, B, C)、偶极矩(mu)、HOMO/LUMO能级、零点振动能(zpve)、内能(U)、焓(H)和吉布斯自由能(G)等。
- 明确指出每个分子存储在单独的
- 数据来源与计算方法:
- 数据源于GDB-9化学数据库。
- 主要使用了两种量子化学理论水平:B3LYP用于大部分属性计算,G4MP2用于C₇H₁₀O₂子集的能量计算。
- 引用要求:
- 文件明确要求,如果使用该数据集,需要引用Raghunathan Ramakrishnan等人在2014年发表于《Scientific Data》的论文。
- 其他信息:
- 提供了一些额外文件(如
validation.txt,uncharacterized.txt)的说明。 - 提到了数据集中有少数几个分子在几何优化时难以收敛。
- 提供了一些额外文件(如
3. 可视化
1 | import ase.io |
- 定义解析函数
parse_qm9_xyz:- 目的: 将这个函数作为专门处理QM9特殊格式的工具。代码主体清晰,易于复用。
- 读取文件:
with open(...)安全地打开文件,并用f.readlines()将文件所有行一次性读入一个列表lines中。 - 提取原子数量:
num_atoms = int(lines[0].strip())读取第一行(lines[0]),去除可能存在的空格(.strip()),并将其转换为整数。这是构建标准XYZ格式的必要信息。 - 提取坐标信息:
coord_lines = lines[2:2+num_atoms]标信息从第3行开始(索引为2),持续num_atoms行。通过列表切片,精确地提取出所有包含原子坐标的行,跳过了第2行的属性信息。 - 构建标准XYZ格式字符串:
- 创建一个名为
standard_xyz的新字符串。 - 首先,将原子数量和换行符写入。
- 然后,添加一行标准的注释(“Comment line”),这是标准XYZ格式所要求的。
- 最后,遍历刚刚提取的
coord_lines列表。对于每一行,使用.split()将其拆分成多个部分(例如:['C', 'x', 'y', 'z', 'charge'])。只取前四部分(元素符号和xyz坐标),并重新组合成新的一行,从而丢弃了末尾的Mulliken电荷数据。
- 创建一个名为
- 返回结果: 函数返回一个包含了标准XYZ格式数据的、干净的字符串。
- 主程序执行流程:
- 调用函数:
standard_xyz_data = parse_qm9_xyz(file_path)调用上面的函数,完成从文件到标准格式字符串的转换。 - 在内存中读取:
ase.io.read(io.StringIO(standard_xyz_data), format="xyz")这一步非常高效。io.StringIO将我们的字符串变量standard_xyz_data模拟成一个内存中的文本文件。这样,ase.io.read就可以直接读取它,而无需先将清洗后的数据写入一个临时文件再读取,节省了磁盘I/O操作。 - 可视化: 接下来的代码 (
nv.show_ase等) 就和最初的设想一样了,因为此时atoms对象已经是通过标准、干净的数据成功创建的了。
- 调用函数:
