1. 工作流程总览
本流程用于处理在 HEPS ID05 线站使用面探测器采集的粉末衍射数据。原始数据由 del scan 组成,即探测器以递增的 del 角度采集一系列二维衍射图像。
三步工作流程:
- 配置 — 在
config.py中设置实验参数(路径、样品名、探测器类型)。 - 校准 — 运行
HEPS_ID05_calibration.py,确定探测器距离、Beam Center 等几何参数,生成calibration.txt。 - 拼接与积分 — 运行
HEPS_ID05_stitch_integrate.py,自动读取校准参数,将所有帧按角度重叠拼接成一张大图,在指定 2θ 范围内执行圆环积分(粉末积分),输出一维衍射谱。
HEPS_ID05_stitch_integrate_no_calib.py,它使用硬编码的校准值而非从 calibration.txt 读取。只有在已经确切知道探测器参数时使用此版本。
2. 数据目录结构
计算中心的原始数据布局:
{_DISK_ROOT}/
└── {BEAMTIME_DATE}/
└── Data/
└── {BEAMTIME_ID}/
├── raw/
│ └── {PROJECT_NAME}/
│ ├── {SAMPLE_NAME}.spec
│ └── images/
│ └── {SAMPLE_NAME_1}/
│ ├── S001/
│ │ ├── xxx_00001.tif
│ │ ├── xxx_00002.tif
│ │ └── ...
│ ├── S002/
│ └── ...
└── processed/
└── {PROJECT_NAME}/
├── calibration.txt
└── {SAMPLE_NAME_1}_{scan_num}/
├── scan{num}_integral_N{N}.dat
├── scan{num}_integral_N{N}.png
└── scan{num}_stitched.png
| 变量 | 示例值 | 说明 |
|---|---|---|
_DISK_ROOT | /heps/beamline/ID05 | 数据存储根目录 |
BEAMTIME_DATE | 202606 | 实验日期(年月) |
BEAMTIME_ID | PLT-26-02091-ID05-01 | 实验申请编号 |
PROJECT_NAME | ZhengZhong | 项目/用户名(spec 初始化) |
SAMPLE_NAME | Sample1 | 样品标识(spec 初始化) |
3. 第一步 — 配置 config.py
编辑项目根目录下的 config.py,使其与你的实验匹配。每次换实验只需修改顶部的输入参数,所有脚本自动使用新路径。
# ====== 输入参数(每次实验修改这里) ====== BEAMTIME_ID = "PLT-26-02091-ID05-01" BEAMTIME_DATE = "202606" # 年月,如 202606 PROJECT_NAME = "ZhengZhong" SAMPLE_NAME = "Sample1" DETECTOR_NAME = "pilatus" # "e4m" | "pilatus" | "newdet" MASK_ON = 1 # 1 = 使用掩膜, 0 = 不使用 # ====== 数据存储根目录 ====== # _DISK_ROOT = "/heps/beamline/ID05" # HEPS Torch 集群 _DISK_ROOT = "D:/Torch" # 本地 PC
SAMPLE_NAME_1 由 SAMPLE_NAME + "_1" 自动生成。它决定了 images/ 下的原始数据子文件夹名和输出文件夹名。请确保它与你的 .spec 文件名一致(如 Sample1_1.spec)。
4. 第二步 — 运行校准
校准脚本 scripts/alignment/HEPS_ID05_calibration.py 用于确定探测器的几何参数,并将结果写入 PATHSAVE 下的 calibration.txt。
4.1 选择校准模式
设置脚本顶部的 Calibration_type 变量。对于粉末衍射,通常执行 detector 校准步骤:
Calibration_type = 'detector' # ← 先运行这个 # Calibration_type = 'crystal infor' # Calibration_type = 'single Bragg 6C' # Calibration_type = 'multiple Bragg 6C' # Calibration_type = 'hkl_to_angles'
4.2 确认扫描号
确保 scan_num 指向正确的校准扫描(即在不同探测器角度下采集直束的扫描):
if Calibration_type == 'detector': sample_name = SAMPLE_NAME_1 scan_num = 4 # ← 改为你的校准扫描号
4.3 运行校准
在 Spyder 中打开 scripts/alignment/HEPS_ID05_calibration.py,直接运行或在控制台执行 calibration()。
4.4 calibration.txt 中保存的参数
| 参数名 | 所属章节 | 说明 |
|---|---|---|
beamline | General Information | 线站名称(如 id05_6c) |
direct_beam_position | Detector calibration | [Y_center, X_center],0-based 像素坐标 |
detector_distance | Detector calibration | 样品到探测器的距离,单位为 mm |
pixelsize | Detector calibration | 像素大小,mm(Pilatus: 0.172) |
detector_rotation | Detector calibration | 探测器旋转角度(度) |
calibration.txt 检查数值是否合理。
5. 第三步 — 拼接与圆环积分
主处理脚本为 scripts/Powder_Diff/HEPS_ID05_stitch_integrate.py。它自动从 calibration.txt 读取校准参数。
5.1 调整处理参数
打开脚本,修改 # %% Inputs 单元中的参数:
| 参数名 | 示例值 | 说明 |
|---|---|---|
scan_num | 44 | 粉末衍射数据的目标扫描号 |
image_x_range | [10, 185] | X(探测器列)像素范围,1-based |
image_y_band | 3 | 每个匹配角度像素周围的半带宽(±行数) |
mon_normalize | 0 | Monitor 归一化。0=关闭,1=开启 |
delta_start | None | 起始 2θ 角度(度)。None=从数据自动获取 |
delta_end | None | 结束 2θ 角度(度)。None=从数据自动获取 |
N | 30 | 每度的插值点数(网格密度) |
stitch_cmap | "jet" | 拼接图像显示所用的色图 |
stitch_vmin | 0 | 显示下限百分位(0=关闭) |
stitch_vmax | 99 | 显示上限百分位 |
5.2 脚本执行流程
- 读取扫描信息 — 通过
HEPSTifImporter加载.spec文件、TIF 图像和元数据。 - 加载校准参数 — 从
calibration.txt读取direct_beam_position、detector_distance。 - 获取能量 — 从扫描电机位置读取束线能量,计算波长 λ。
- 逐帧角度计算 — 对每一帧,根据探测器几何计算每个像素的 2θ 角。
- 拼接 — 寻找相邻帧之间的角度重叠区域,在重叠处归一化强度,然后将非重叠部分拼接起来。结果是一张完整的大图。
- 圆环积分 — 对目标角度网格中的每个角度,在拼接图像中寻找匹配像素,在 ±
image_y_band行内求和强度,得到一维谱。 - 输出 — 保存一维谱(
.dat)、积分图(.png)和拼接图像(.png)。
5.3 运行脚本
在 Spyder 中打开 scripts/Powder_Diff/HEPS_ID05_stitch_integrate.py,运行 stitch_integrate() 函数或直接运行整个文件。
5.4 使用无校准版
如果你希望手动指定探测器参数而不是从 calibration.txt 读取,请使用 HEPS_ID05_stitch_integrate_no_calib.py。直接在脚本中设置:
L = 31.0623 # 样品到探测器的距离 (cm) beam_center_x = 98 # 直束中心 X (像素, 1-based) beam_center_y = 243 # 直束中心 Y (像素, 1-based)
6. 参数参考
6.1 几何参数(来自校准)
| 代码中的符号 | 来源 | 单位 | 说明 |
|---|---|---|---|
L | detector_distance / 10 | cm | 样品到探测器的距离 |
beam_center_x | direct_beam_position[1] + 1 | 像素 (1-based) | 直束中心 X(快速维,列方向) |
beam_center_y | direct_beam_position[0] + 1 | 像素 (1-based) | 直束中心 Y(慢速维,行方向) |
pixel_size_cm | scan.get_detector_pixelsize() / 10 | cm | 像素大小(Pilatus: 172 µm = 0.0172 cm) |
energy | scan.get_motor_pos('energy') | eV | 束线能量 |
lam | hc / energy | Å | 波长(hc = 12398.4 eV·Å) |
6.2 衍生量
| 量 | 公式 | 说明 |
|---|---|---|
theta_v | -arctan((k - beam_center_y)·pixel_size / L) + delta | 2θ 的垂直分量(探测器 Y 方向) |
theta_h | arctan((n - beam_center_x)·pixel_size / (L / cos(theta_v - delta))) | 2θ 的水平分量(探测器 X 方向) |
theta_total | arccos(cos(theta_h)·cos(theta_v)) | 每个像素的总 2θ 角 |
q | 4π·sin(θ)/λ | 散射矢量模长(Å⁻¹) |
7. 输出文件
所有输出保存在自动创建的 pathsave 子文件夹中,路径为 {PATHSAVE}/{SAMPLE_NAME_1}_{scan_num:05d}/。
| 文件 | 格式 | 内容 |
|---|---|---|
scan{num}_integral_N{N}.dat | 文本(3 列) | Angle(deg) Q(Å⁻¹) Integrated_Intensity |
scan{num}_integral_N{N}.png | PNG 图片 | 一维衍射谱:Q(下轴)/ 2θ(上轴)vs 强度 |
scan{num}_stitched.png | PNG 图片 | 拼接后的探测器图像(带对比度拉伸) |
.dat 文件示例:
# Angle(deg) Q(A^-1) Integrated_Intensity 12.123 0.876 15234.0 12.156 0.879 14892.5 12.190 0.881 16781.2 ...
8. 常见问题排查
脚本已在拼接结果上应用 np.fliplr(),使角度从左到右按低→高排列。如果图像仍然反了,检查脚本中 fliplr 相关行(约 137‑138 行)是否存在且未被注释掉。
将 calibration.txt 中读出的值与硬编码的默认值(L = 31.0623、beam_center_x = 98、beam_center_y = 243)进行比较。校准得出的值可能有微小差异,这是正常的。如果差异很大,请重新运行校准。
calibration.txt。
脚本在 PATHSAVE/calibration.txt 查找校准文件。请确保先运行了校准步骤,或改用硬编码版本的 _no_calib 脚本。
在 # %% Inputs 单元中将 mon_normalize 设为 1。脚本通过 scan.get_scan_data("Monitor") 读取 Monitor 计数。请确认你的 .spec 文件中包含 "Monitor" 列。
# %% Spyder 单元标记。你可以按 Ctrl+Enter 逐个单元运行,逐步执行工作流程。config.py 必须先导入/运行以设置路径环境。