PyWPEM / PyXplore
中文说明书
本说明书根据 src 中的公开 API 和 Tutorial 中的 Jupyter 示例整理,覆盖 PyWPEM 常见分析流程、关键参数和输出文件。
1. 软件简介
PyWPEM 是一个用于 X 射线衍射全谱分解与结构精修的 Python 工具包。它的核心思想是把完整衍射谱看作受物理约束的概率混合分布,并在 EM 迭代中结合 Bragg 定律更新峰位置、峰形、峰权重和晶格参数。
最常用的入口来自 from PyXplore import WPEM。主要函数包括:
WPEM.BackgroundFit:拟合并扣除背景。WPEM.CIFpreprocess:读取 CIF,生成 HKL、2θ、multiplicity 和消光峰。WPEM.XRDfit:运行 WPEM 全谱拟合、分峰和晶格精修。WPEM.Plot_Components:绘制分相或分峰结果。WPEM.XRDSimulation:根据 CIF 模拟 XRD 图谱。WPEM.SubstitutionalSearch:搜索固溶体替位结构。WPEM.Amorphous_fit与WPEM.AmorphousRDFun:非晶宽峰拟合与 RDF 分析。WPEM.XPSfit:XPS 主峰和卫星峰的 EM 分解。
2. 安装与环境
更详细教程:Class 1 Installation
建议使用独立 conda 环境,避免和系统 Python 或其他科研软件的依赖冲突。教程中推荐 Python 3.10。
conda create -n pywpem python=3.10
conda activate pywpem
pip install notebook
pip install PyXplore
pip install --upgrade PyXplore
启动 Jupyter Notebook:
jupyter notebook
在 notebook 或 Python 脚本中测试导入:
from PyXplore import WPEM
如果网络下载较慢,可以先配置 pip 镜像源,或在网络稳定环境中安装依赖。
3. 数据准备
更详细教程:Class 2 Single-phase refinement
3.1 实验谱文件格式
XRD 输入通常是两列数据,不需要表头:第一列为 2theta,第二列为 intensity。CSV 示例:
10.000, 123.4
10.010, 125.1
10.020, 128.7
读取方式:
import pandas as pd
intensity_csv = pd.read_csv("intensity.csv", header=None)
原位 XRD 或部分仪器数据也可以使用 Excel。教程中使用:
intensity_excel = pd.read_excel("intensity.xlsx", header=None)
3.2 CIF 文件
每个候选晶相建议准备一个 CIF 文件。CIFpreprocess 会读取晶格常数、原子坐标、空间群和对称操作,并生成后续拟合需要的 HKL 文件。
latt, atom_coordinates, density = WPEM.CIFpreprocess(
filepath="Mn2O3.cif",
two_theta_range=(15, 75)
)
3.3 工作目录
默认情况下,PyWPEM 会在当前目录写入 ConvertedDocuments、output_xrd、WPEMFittingResults 等输出目录。批处理时强烈建议为每个样品设置独立 work_dir,避免文件互相覆盖。
4. 单相 XRD 精修
更详细教程:Class 2 Single-phase refinement
本流程对应教程中的 Mn2O3 单相示例,适合用户第一次完整跑通 PyWPEM。
步骤 1:导入库并读取数据
from PyXplore import WPEM
import pandas as pd
intensity_csv = pd.read_csv("intensity.csv", header=None)
步骤 2:背景拟合
var = WPEM.BackgroundFit(
intensity_csv,
lowAngleRange=17,
poly_n=13,
bac_split=16,
bac_num=300
)
该步骤会生成 ConvertedDocuments/no_bac_intensity.csv 和 ConvertedDocuments/bac.csv。如果当前工作目录就是数据目录,后续可以直接使用文件名 no_bac_intensity.csv 和 bac.csv;如果使用 work_dir,建议使用完整路径。
步骤 3:CIF 预处理
latt, atom_coordinates, density = WPEM.CIFpreprocess(
filepath="Mn2O3.cif",
two_theta_range=(15, 75)
)
latt 是初始晶格常数,格式为 [a, b, c, alpha, beta, gamma]。density 可用于后续质量分数估计。
步骤 4:运行 WPEM 精修
wavelength = [1.540593, 1.544414]
Lattice_constants = [latt]
WPEM.XRDfit(
wavelength,
var,
Lattice_constants,
"no_bac_intensity.csv",
"intensity.csv",
"bac.csv",
subset_number=11,
low_bound=20,
up_bound=70,
bta=0.85,
iter_max=5,
asy_C=0,
InitializationEpoch=0
)
关键参数解释
wavelength:X 射线波长。Cu Kα1/Kα2 常用[1.540593, 1.544414]。subset_number:用于 Bragg 晶格更新的峰数量。low_bound、up_bound:选择参与晶格更新的 2θ 范围。bta:伪 Voigt 函数中 Lorentzian 分量比例。iter_max:最大迭代次数。首次测试可以设小一些,正式分析可适当增大。InitializationEpoch:初始化阶段冻结峰位置的轮数。
5. 多相 XRD 精修
更详细教程:Class 3 Multiphase refinement
多相流程和单相类似,区别是每个候选相都需要运行 CIFpreprocess,并把多个晶格常数组成列表传给 XRDfit。
from PyXplore import WPEM
import pandas as pd
intensity_csv = pd.read_csv("intensity.csv", header=None)
Var = WPEM.BackgroundFit(
intensity_csv,
LFctg=0.2,
lowAngleRange=20,
window_length=7,
bac_num=500
)
NaCl, _, density_nacl = WPEM.CIFpreprocess("NaCl.cif", two_theta_range=(11, 110))
LiCO, _, density_lico = WPEM.CIFpreprocess("Li2CO3.cif", two_theta_range=(11, 110))
wavelength = [1.540593, 1.544414]
WPEM.XRDfit(
wavelength,
Var,
[NaCl, LiCO],
"no_bac_intensity.csv",
"intensity.csv",
"bac.csv",
subset_number=11,
low_bound=20,
up_bound=50,
bta=0.9,
iter_max=5,
asy_C=0,
InitializationEpoch=2,
num=7,
Ave_Waves=True
)
WPEM.Plot_Components(
lowboundary=10,
upboundary=110,
wavelength=wavelength,
name=["NaCl", "Li2CO3"],
phase=2
)
phase=2 表示绘制两个晶相的分解结果。name 的顺序应与 Lattice_constants 中的相顺序一致。
6. XRD 模拟
更详细教程:Class 4 XRD simulations
XRDSimulation 用 CIF 文件生成模拟谱,可用于相鉴定后的验证,也可构造带扰动的训练或测试数据。
FHKL_square, two_theta_sim, intensity_sim = WPEM.XRDSimulation(
filepath="PSO.cif",
two_theta_range=(10, 120, 0.01),
bacI=True,
GrainSize=30,
orientation=[-0.1, 0.1],
thermo_vib=0.1,
zero_shift=0.01
)
two_theta_range=(start, stop, step)控制模拟角度范围和步长。GrainSize用于模拟晶粒尺寸导致的峰宽变化。orientation用于模拟择优取向导致的强度扰动。thermo_vib用于模拟原子平均位置的热振动扰动。zero_shift用于模拟仪器零点偏移。bacI=True会加入随机多项式背景。
7. 原位 XRD 批处理
更详细教程:Class 5 In situ XRD
原位或 operando XRD 通常包含大量连续谱。推荐给每个谱建立独立临时目录,把输入文件和必要的 peak0.csv 放入该目录,并通过 work_dir 控制输出位置。
import os
import shutil
import pandas as pd
from PyXplore import WPEM
wavelength = [1.540593, 1.544414]
Lattice_constants = [[2.87549, 2.87549, 14.02056, 90.0, 90.0, 120.0]]
results = {}
num_samples = 5
for i in range(num_samples):
idx = i + 1
tmp_dir = f"tmp/{idx}"
os.makedirs(tmp_dir, exist_ok=True)
tmp_intensity = os.path.join(tmp_dir, "intensity.xlsx")
shutil.copyfile(f"data/{idx}.xlsx", tmp_intensity)
shutil.copyfile("peak0.csv", os.path.join(tmp_dir, "peak0.csv"))
intensity_excel = pd.read_excel(tmp_intensity, header=None)
var = WPEM.BackgroundFit(
intensity_excel,
lowAngleRange=17,
LFctg=0.0,
poly_n=8,
bac_split=10,
bac_num=80,
work_dir=tmp_dir
)
no_bac_file = os.path.join(tmp_dir, "ConvertedDocuments", "no_bac_intensity.csv")
bac_file = os.path.join(tmp_dir, "ConvertedDocuments", "bac.csv")
duration, lattice = WPEM.XRDfit(
wavelength,
var,
Lattice_constants,
no_bac_file,
tmp_intensity,
bac_file,
Ave_Waves=True,
subset_number=6,
low_bound=15,
up_bound=60,
bta=0.85,
iter_max=3,
asy_C=0,
InitializationEpoch=0,
work_dir=tmp_dir
)
results[idx] = lattice
批处理完成后,可以把每个样品的晶格参数整理成 Excel 或 CSV,再绘制随时间、温度、电压或循环次数变化的曲线。
8. 固溶体搜索
更详细教程:Class 6 Solid solution searching
固溶体流程通常先做一次 XRD 精修,得到某一晶相的 WPEM 输出文件,再用 SubstitutionalSearch 搜索可能的替位结构。
WPEM.SubstitutionalSearch(
xrd_pattern="CrystalSystem0_WPEMout_2026.6.10_11.1.csv",
cif_file="Mn2O3.cif",
random_num=20,
wavelength="CuKa",
search_cap=20,
SolventAtom="Mn3+",
SoluteAtom="Ru2+",
max_iter=15,
cal_extinction=False
)
搜索完成后,可用 XRDSimulation 对候选结构进行模拟,并与实验谱或 WPEM 分解谱比较。
9. 非晶分析
更详细教程:Class 7 Amorphous study
非晶样品通常包含晶体峰和非晶宽峰。推荐先用 XRDfit 分解晶体峰,再用 Amorphous_fit 拟合剩余宽峰,最后可计算 RDF。
wavelength = [1.03]
Lattice_constants = [[17.53, 17.53, 6.47, 90, 90, 120]]
WPEM.XRDfit(
wavelength,
var,
Lattice_constants,
"no_bac_intensity.csv",
"intensity.csv",
"bac.csv",
subset_number=3,
low_bound=6,
up_bound=16,
bta=0.78,
iter_max=10,
asy_C=0,
InitializationEpoch=0
)
WPEM.Amorphous_fit(
mix_component=2,
sigma2_coef=0.5,
max_iter=200,
peak_location=None,
Wavelength=1.03
)
WPEM.Plot_Components(
lowboundary=4,
upboundary=19,
wavelength=wavelength,
Macromolecule=True,
phase=1
)
WPEM.AmorphousRDFun(
wavelength=1.03,
r_max=4,
density_zero=None,
Nf2=1,
highlight=6
)
mix_component 是非晶宽峰数量。若已知道宽峰大致位置,可用 peak_location=[20, 30, "fixed"] 固定初始峰位。
10. XPS 分解
更详细教程:Class 8 X-Ray spectrograph
PyWPEM 也包含 XPS 的 EM 分解模块。XPS 数据同样是两列:binding energy 和 intensity。通常先用 XPS 模式拟合背景,再定义主峰和卫星峰。
from PyXplore import WPEM
import pandas as pd
intensity_csv = pd.read_csv("CuO.csv", header=None)
var = WPEM.BackgroundFit(
intensity_csv,
segement=[[910, 931], [948, 952], [958, 959], [966, 970]],
bac_num=120,
Model="XPS",
noise=0.05,
bac_var_type="multivariate gaussian"
)
AtomIdentifier = [
["CuII", "2p3/2", 933.7],
["CuII", "2p1/2", 954]
]
satellitePeaks = [
["CuII", "2p3/2", 941.6],
["CuII", "2p3/2", 943.4],
["CuII", "2p1/2", 962.5]
]
WPEM.XPSfit(
var,
AtomIdentifier,
satellitePeaks,
"no_bac_intensity.csv",
"CuO.csv",
"bac.csv",
bta=0.80,
iter_max=50
)
AtomIdentifier 用于定义主峰,格式为 [化学态, 轨道, 初始结合能]。satellitePeaks 用于定义卫星峰。
11. 输出文件
| 目录或文件 | 说明 |
|---|---|
ConvertedDocuments/no_bac_intensity.csv | 扣除背景后的实验谱。 |
ConvertedDocuments/bac.csv | 拟合得到的背景曲线。 |
output_xrd/*HKL.csv | CIF 预处理生成的 HKL、d 间距、2θ 和 multiplicity。 |
output_xrd/*Extinction_peak.csv | 系统消光峰。 |
WPEMFittingResults | XRD 拟合曲线、峰参数、晶相分解结果、质量分数估计和模型参数。 |
DecomposedComponents | 分峰曲线、更新背景、非晶分解结果。 |
Simulation_WPEM | XRD 模拟谱、结构因子和 VASP 结构文件。 |
XPSFittingProfile | XPS 拟合曲线和峰参数。 |
XPScomponents | XPS 分峰组分曲线。 |
12. 常见问题
文件长度不匹配
XRDfit 要求原始谱、扣背景谱和背景谱的点数一致。若出现不匹配,重新运行 BackgroundFit,并确认后续读取的是同一目录下生成的 no_bac_intensity.csv 和 bac.csv。
峰位整体偏移
检查波长是否正确、仪器是否存在零点偏移。必要时测试 ZeroShift=True 或在模拟中设置 zero_shift 理解偏移方向。
多相结果顺序混乱
Lattice_constants、density_list、name 和输出晶相编号必须保持同一顺序。
批处理结果被覆盖
为每个样品设置独立 work_dir。原位教程采用 tmp/1、tmp/2 这类结构,就是为了隔离输出。
背景拟合不理想
调整 LFctg、lowAngleRange、bac_split、bac_num、poly_n。XPS 场景可使用 segement 手动指定背景区间。
