粉末衍射数据拼接 & 积分

pyCXIM — 配置 · 校准 · 拼接与积分

目录

  1. 工作流程总览
  2. 数据目录结构
  3. 第一步 — 配置 config.py
  4. 第二步 — 运行校准
  5. 第三步 — 拼接与圆环积分
  6. 参数参考
  7. 输出文件
  8. 常见问题排查

1. 工作流程总览

本流程用于处理在 HEPS ID05 线站使用面探测器采集的粉末衍射数据。原始数据由 del scan 组成,即探测器以递增的 del 角度采集一系列二维衍射图像。

三步工作流程:

  1. 配置 — 在 config.py 中设置实验参数(路径、样品名、探测器类型)。
  2. 校准 — 运行 HEPS_ID05_calibration.py,确定探测器距离、Beam Center 等几何参数,生成 calibration.txt
  3. 拼接与积分 — 运行 HEPS_ID05_stitch_integrate.py,自动读取校准参数,将所有帧按角度重叠拼接成一张大图,在指定 范围内执行圆环积分(粉末积分),输出一维衍射谱。
💡 提示: 另备有 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_DATE202606实验日期(年月)
BEAMTIME_IDPLT-26-02091-ID05-01实验申请编号
PROJECT_NAMEZhengZhong项目/用户名(spec 初始化)
SAMPLE_NAMESample1样品标识(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_1SAMPLE_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 中保存的参数

参数名所属章节说明
beamlineGeneral Information线站名称(如 id05_6c
direct_beam_positionDetector calibration[Y_center, X_center],0-based 像素坐标
detector_distanceDetector calibration样品到探测器的距离,单位为 mm
pixelsizeDetector calibration像素大小,mm(Pilatus: 0.172)
detector_rotationDetector calibration探测器旋转角度(度)
💡 提示: 校准完成后可以打开 calibration.txt 检查数值是否合理。

5. 第三步 — 拼接与圆环积分

主处理脚本为 scripts/Powder_Diff/HEPS_ID05_stitch_integrate.py。它自动从 calibration.txt 读取校准参数。

5.1 调整处理参数

打开脚本,修改 # %% Inputs 单元中的参数:

参数名示例值说明
scan_num44粉末衍射数据的目标扫描号
image_x_range[10, 185]X(探测器列)像素范围,1-based
image_y_band3每个匹配角度像素周围的半带宽(±行数)
mon_normalize0Monitor 归一化。0=关闭,1=开启
delta_startNone起始 2θ 角度(度)。None=从数据自动获取
delta_endNone结束 2θ 角度(度)。None=从数据自动获取
N30每度的插值点数(网格密度)
stitch_cmap"jet"拼接图像显示所用的色图
stitch_vmin0显示下限百分位(0=关闭)
stitch_vmax99显示上限百分位

5.2 脚本执行流程

  1. 读取扫描信息 — 通过 HEPSTifImporter 加载 .spec 文件、TIF 图像和元数据。
  2. 加载校准参数 — 从 calibration.txt 读取 direct_beam_positiondetector_distance
  3. 获取能量 — 从扫描电机位置读取束线能量,计算波长 λ。
  4. 逐帧角度计算 — 对每一帧,根据探测器几何计算每个像素的 2θ 角。
  5. 拼接 — 寻找相邻帧之间的角度重叠区域,在重叠处归一化强度,然后将非重叠部分拼接起来。结果是一张完整的大图。
  6. 圆环积分 — 对目标角度网格中的每个角度,在拼接图像中寻找匹配像素,在 ±image_y_band 行内求和强度,得到一维谱。
  7. 输出 — 保存一维谱(.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 几何参数(来自校准)

代码中的符号来源单位说明
Ldetector_distance / 10cm样品到探测器的距离
beam_center_xdirect_beam_position[1] + 1像素 (1-based)直束中心 X(快速维,列方向)
beam_center_ydirect_beam_position[0] + 1像素 (1-based)直束中心 Y(慢速维,行方向)
pixel_size_cmscan.get_detector_pixelsize() / 10cm像素大小(Pilatus: 172 µm = 0.0172 cm)
energyscan.get_motor_pos('energy')eV束线能量
lamhc / energyÅ波长(hc = 12398.4 eV·Å)

6.2 衍生量

公式说明
theta_v-arctan((k - beam_center_y)·pixel_size / L) + delta2θ 的垂直分量(探测器 Y 方向)
theta_harctan((n - beam_center_x)·pixel_size / (L / cos(theta_v - delta)))2θ 的水平分量(探测器 X 方向)
theta_totalarccos(cos(theta_h)·cos(theta_v))每个像素的总 2θ 角
q4π·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}.pngPNG 图片一维衍射谱:Q(下轴)/ 2θ(上轴)vs 强度
scan{num}_stitched.pngPNG 图片拼接后的探测器图像(带对比度拉伸)

.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.0623beam_center_x = 98beam_center_y = 243)进行比较。校准得出的值可能有微小差异,这是正常的。如果差异很大,请重新运行校准。

🔴 找不到 calibration.txt

脚本在 PATHSAVE/calibration.txt 查找校准文件。请确保先运行了校准步骤,或改用硬编码版本的 _no_calib 脚本。

🔴 Monitor 归一化不生效。

# %% Inputs 单元中将 mon_normalize 设为 1。脚本通过 scan.get_scan_data("Monitor") 读取 Monitor 计数。请确认你的 .spec 文件中包含 "Monitor" 列。

💡 通用提示: 所有脚本均使用 # %% Spyder 单元标记。你可以按 Ctrl+Enter 逐个单元运行,逐步执行工作流程。config.py 必须先导入/运行以设置路径环境。