1. Pysimxrd 能做什么
Pysimxrd 用 ASE 数据库中的晶体结构生成具有真实物理扰动的粉末 X 射线衍射图谱。仓库中的 sim/ 目录展示了三个核心流程:
generator.parser(database, entry_id) 得到归一化的 2θ 强度曲线。sim/ht_simxrd.py 对大量结构批量模拟,并写入新的 ASE 数据库。程序包含两条模拟路径。默认路径使用 pymatgen 计算峰位,并结合统一的峰展宽、背景和噪声模型。可选的 sim_model="WPEM" 路径使用仓库内部的衍射条件、系统消光、多重度和结构因子计算逻辑。
2. 安装环境
sim/tutorial_sim.ipynb 中建议使用 Python 3.9 以上版本。推荐先创建干净环境:
conda create -n pysimxrd python=3.10
conda activate pysimxrd
发布到 PyPI 后可直接安装:
pip install Pysimxrd
如果从当前仓库开发或测试,进入 src 目录安装:
cd SimXRD/src
pip install -e .
运行示例时建议额外安装:
pip install matplotlib tqdm
PYTHONPATH=src 临时运行脚本;更推荐使用 pip install -e src 或在 src 下安装。3. 从数据开始
Pysimxrd 的输入是 ASE 数据库。仓库提供了一个小型示例数据库:sim/demo_mp.db。
3.1 查看示例数据库
from ase.db import connect
database = connect("sim/demo_mp.db")
print("结构数量:", database.count())
row = database.get(id=1)
atoms = row.toatoms()
print("化学式:", atoms.get_chemical_formula())
print("晶胞参数:", atoms.cell.cellpar())
print("前几个元素:", atoms.get_chemical_symbols()[:10])
ASE 数据库中的每一行保存一个原子结构。Pysimxrd 根据行号读取结构,在需要时转换为 conventional cell,然后返回模拟的 XRD 曲线。
3.2 准备自己的数据库
如果已经有 ASE Atoms 对象,可以直接写入数据库:
from ase.db import connect
db = connect("my_crystals.db")
db.write(atoms, name="sample_001")
如果结构来自 CIF 文件,可以先用 ASE 读取,再写入数据库:
from ase.io import read
from ase.db import connect
db = connect("my_crystals.db")
atoms = read("example.cif")
db.write(atoms, name="example")
之后就可以像使用 sim/demo_mp.db 一样使用 my_crystals.db。
4. 模拟一条 XRD 图谱
核心入口是 Pysimxrd.generator.parser,返回 x 和 y 两个数组。
from ase.db import connect
from Pysimxrd import generator
database = connect("sim/demo_mp.db")
entry_id = 1
x, y = generator.parser(database, entry_id)
print(len(x), len(y))
print(x[:5])
print(y[:5])
默认情况下,x 是 2θ 角度,单位为 degree;y 是归一化强度。
输出 d-spacing 而不是 2θ
x_d, intensity = generator.parser(
database,
entry_id,
xrd="real",
)
5. 绘图和保存图片
sim/XRD.ipynb 展示了默认参数、增强择优取向和增强热振动三种情况。下面是等价的 Python 脚本写法:
import matplotlib.pyplot as plt
from ase.db import connect
from Pysimxrd import generator
database = connect("sim/demo_mp.db")
x, y = generator.parser(database, entry_id=8)
plt.figure(figsize=(8, 6))
plt.plot(x, y, color="royalblue", linewidth=2.5)
plt.xlabel("2θ (degrees)", fontsize=14, weight="bold")
plt.ylabel("Intensity (a.u.)", fontsize=14, weight="bold")
plt.grid(True, which="both", linestyle="--", linewidth=0.5)
plt.tight_layout()
plt.savefig("xrd_pattern.png", dpi=300)
plt.show()
sim/XRD.ipynb 的默认模拟结果。6. 参数说明
sim/ht_simxrd.py 中集中说明了主要参数。最常用的控制项如下:
| 参数 | 含义 | 典型用途 |
|---|---|---|
grainsize | 样品晶粒尺寸,单位 Angstrom。 | 数值越小,峰展宽越明显。 |
prefect_orientation | 择优取向扰动范围。名称保留历史拼写。 | 增大会改变相对峰强。 |
thermo_vibration | 热振动幅度,单位 Angstrom。 | 增大会削弱并展宽峰特征。 |
zero_shift | 2θ 零点偏移,单位 degree。 | 模拟仪器零点误差。 |
background_order | 多项式背景阶数。 | 通常使用 4 或 6。 |
background_ratio | 背景强度相对峰强的比例。 | 增大后基线更明显。 |
mixture_noise_ratio | 均匀混合噪声比例。 | 增大后随机强度噪声更强。 |
deformation | 是否随机扰动晶格常数。 | 用于数据增强。 |
lattice_extinction_ratio | 晶格拉伸/压缩扰动比例。 | 控制晶格长度随机变化。 |
lattice_torsion_ratio | 晶格剪切扰动比例。 | 控制晶格角度或剪切变化。 |
来自 sim/XRD.ipynb 的例子
# 增强择优取向扰动
x, y = generator.parser(database, entry_id=8, prefect_orientation=[0.2, 0.2])
# 增强热振动,同时减小晶粒尺寸
x, y = generator.parser(database, entry_id=8, thermo_vibration=0.4, grainsize=5)
7. WPEM 模式
如果希望使用仓库内部的衍射条件、系统消光、多重度和结构因子流程,可以启用 WPEM 模式。
x, y = generator.parser(
database,
entry_id=1,
sim_model="WPEM",
)
WPEM 模式下启用晶格变形:
x, y = generator.parser(
database,
entry_id=1,
sim_model="WPEM",
deformation=True,
lattice_extinction_ratio=0.01,
lattice_torsion_ratio=0.01,
)
8. 高通量批量模拟
sim/ht_simxrd.py 展示了如何从一个输入数据库批量生成多条模拟图谱,并保存到新的 ASE 数据库。
在 sim/ 目录运行示例:
cd sim
python ht_simxrd.py
长时间任务可以使用 notebook 中建议的方式后台运行:
nohup python ht_simxrd.py &
该脚本读取 demo_mp.db,写入 train.db。示例中默认每个结构生成 1 条模拟谱。
批量模拟的核心写法
from ase.db import connect
from Pysimxrd import generator
input_db = connect("my_crystals.db")
output_db = connect("my_simulated_xrd.db")
for row in input_db.select():
atoms = row.toatoms()
x, y = generator.parser(input_db, row.id, deformation=True)
output_db.write(
atoms=atoms,
latt_dis=str(x),
intensity=str(y),
Label=row.id,
)
完整脚本中还会为每次模拟随机生成晶粒尺寸、择优取向、热振动和零点偏移等参数,从而得到更丰富的训练数据。
9. 读取生成的数据
生成的新数据库会保存原始 atoms,同时把模拟得到的数组写入字符串字段。读取时可按保存格式转回数组。
from ase.db import connect
import numpy as np
db = connect("sim/train.db")
row = db.get(id=1)
atoms = row.toatoms()
x = np.fromstring(row.latt_dis.strip("[]"), sep=" ")
y = np.fromstring(row.intensity.strip("[]"), sep=",")
print(atoms.get_chemical_formula())
print(x.shape, y.shape)
如果保存时使用的是 str(list(x)),可以用 ast.literal_eval:
import ast
import numpy as np
x = np.array(ast.literal_eval(row.latt_dis))
y = np.array(ast.literal_eval(row.intensity))
10. 常见问题
| 问题 | 解决方法 |
|---|---|
ModuleNotFoundError: Pysimxrd | 在仓库根目录运行 pip install -e src,或使用 PYTHONPATH=src。 |
| 找不到数据库路径 | 注意当前工作目录。从项目根目录使用 sim/demo_mp.db;从 sim/ 目录内部使用 demo_mp.db。 |
| entry id 报错 | 先检查 database.count(),ASE 数据库行号通常从 1 开始。 |
| 输出坐标轴不符合预期 | xrd="reciprocal" 输出 2θ;xrd="real" 输出 d-spacing。 |
| 批量模拟太慢 | 参考 sim/ht_simxrd.py 中的多进程写法,先用较小的 times 测试。 |