DECT Z-eff 双能CT分解 插件用户手册
DECT Z-eff (Dual-Energy CT Decomposition) - User Manual
Dragonfly Prototype Apps · DECT Z-eff...
版本 Version 1.0 · 2026-07-04
第一部分 中文手册
目录
1. 简介
2. 适用场景
3. 安装与启用
4. 运行环境与首次配置
5. 界面说明
5.1 左侧:Beginner demo(新手演示,无需数据)
5.2 右侧:Energy volumes(能量体数据)
5.3 右侧:Calibration(参考材料 → ROI 标定)
5.4 右侧:DECT compute venv(计算环境)
5.5 右侧:运行按钮与日志
6. 使用步骤
6.1 第一次使用:跑内置演示
6.2 处理自己的双能数据
7. 参数说明
8. 输出结果
9. 常见问题与故障排除
10. 注意事项与已知限制
11. 参考资料
1. 简介
DECT Z-eff 是 Dragonfly 的一个 Prototype Apps 插件,用于对双能 CT(Dual-Energy CT,DECT)数据做材质分解。选择一个低能量体数据和一个高能量体数据,在已知参考材料(如石英、方解石、盐水)上勾画 ROI 用于标定,设定两个有效能量(keV)后运行,插件即在场景中生成两个新的 Channel:
- Z_eff — 有效原子序数图:反映每个体素的等效原子序数,例如盐水/水约 7.4、石英约 11.8、方解石约 15.7、黄铁矿约 21.6,可用于矿物/材质判别;
- Rho_e — 相对电子密度图:以水为 1.0 的相对电子密度,反映密度信息。
算法内核分两步:先做线性 PV→μ 标定——把每个能量段的原始灰度值(PV)通过参考材料 ROI 的平均灰度与其理论线性衰减系数 μ(cm⁻¹)做线性拟合;再做经典的 Alvarez–Macovski 双基分解——把 μ(E) 建模为光电效应项 a_pe·E⁻³ 与康普顿散射项 a_kn·f_KN(E)(Klein–Nishina 近似)之和,对每个体素求解 2×2 线性方程组,由系数比值 (a_pe/a_kn)^(1/3.6) 映射得到 Z_eff,由 a_kn 归一化得到 Rho_e。Z_eff 与 Rho_e 的标尺会自动依据内置参考材料表(水、石英、方解石、白云石、黄铁矿、铝、空气)进行标定,运行日志中会报告每个能量段标定拟合的质量(R²)。
标定所需的理论衰减系数来自开源 X 射线物理数据库 xraydb(如已安装 xraylib 则优先使用)。这些计算依赖(numpy、scipy、xraydb,均为经 pip 从 PyPI 安装的开源 Python 库)安装在一个独立的 Python 虚拟环境(venv)中,绝不写入 Dragonfly 自带的 Python,因此不会影响 Dragonfly 本体的稳定性。
插件还内置新手演示:一键生成已知矿物组成的合成双能体模并跑通完整的“标定 → 分解”流程,无需准备任何数据即可体验和验证插件。
2. 适用场景
- 数字岩石物理 / 岩石物理学:在岩心双能显微 CT 扫描中识别矿物(石英、方解石、白云石、黄铁矿等)并定量分析成分;
- 材料科学:需要区分灰度相近但元素组成不同的相时,Z_eff 提供超越简单灰度的判别维度;
- 工业 CT:只要对同一样品有两个不同(有效)能量的扫描数据,即可使用本插件做材质分解;
- 教学与方法验证:内置合成体模演示可用于理解双能 CT 分解原理(低能下光电效应强烈拉开高原子序数相,高能下差异收敛为密度主导)。
输入要求:两个同尺寸的 Dragonfly Channel(低能与高能各一个),以及至少一个画在已知参考材料内部的 ROI 或 MultiROI(建议两个以上,见第 6、7 节)。
3. 安装与启用
本插件通过 Prototype Labs & Apps Full Package(完整安装包)分发和安装:
1. 把安装包 zip 解压到任意较短路径(如 C:\PL\,避免过深的目录导致 Windows 路径超长);
2. 双击 Install_FullPackage.bat;
3. 在弹出的安装对话框中,于 Prototype Apps 列表里勾选 DECT Z-eff...(注意:所有插件默认不勾选,必须手动勾选本插件);
4. 点击 Install,等待控制台完成;
5. 完全退出并重启 Dragonfly(菜单只在 Dragonfly 启动时扫描一次)。
重启后,菜单项出现在 Prototype Apps ▸ DECT Z-eff...(位于 Reconstruction & Imaging 分组)。点击后打开一个名为 DECT Z-eff 的浮动窗口(可移动、可停靠)。
以后随时可以在 Developer ▸ Prototype Labs... ▸ Menu Item Manager 中修改启用状态:底部 “Prototype Apps (Full Package)” 列表里每个应用一个勾选框,勾选=部署菜单项,取消=移除菜单项,改动后重启 Dragonfly 生效。停用从不删除插件已搭建的计算环境,重新启用后立即可用。也可以随时重跑安装器(上次的选择即为默认值)。
安装均写入当前用户目录(%LOCALAPPDATA%),不需要管理员权限。卸载用 Uninstall_FullPackage.bat:它移除菜单项与插件代码,但保留 venv 等插件环境(结束时会列出路径,需要磁盘空间时可手动删除)。
4. 运行环境与首次配置
DECT 的标定需要 xraydb(或 xraylib)提供理论衰减系数,这些库不在 Dragonfly 自带 Python 中、也不允许装入其中。因此计算运行在一个独立的原生 Windows venv 里,插件与它之间通过文件(config.json / status.json / *.npy)通信。首次使用前需构建一次该环境:
运行随插件分发的 setup_dect_venv.bat(或等价的 PowerShell 脚本):
setup_dect_venv.bat
:: 或者:
powershell -ExecutionPolicy Bypass -File setup_dect_venv.ps1
:: 可选参数:
:: -BasePython C:\path\python.exe 指定基础解释器
:: -Force 强制重建 venv
脚本会依次完成:
1. 自动寻找一个 Python 3.9–3.12 基础解释器(通过 py 启动器或 PATH 中的 python;拒绝使用 Dragonfly 自带的解释器);
2. 在 %LOCALAPPDATA%\DECT_Zeff\venv 创建虚拟环境;
3. pip 安装 numpy + scipy + xraydb(下载量约 100 MB,需联网一次);
4. 尝试安装可选的 xraylib(有预编译 wheel 才装得上;装不上也没关系,运行时使用 xraydb);
5. 做导入冒烟测试,确认 numpy/scipy/xraydb 可用;
6. 写入配置文件 %LOCALAPPDATA%\DECT_Zeff\config.json(记录 venv 的 python 路径和作业根目录),并创建默认作业目录 C:\DECT_ZeffJobs。
配置写好后,插件面板会自动检测:打开面板时读取 %LOCALAPPDATA%\DECT_Zeff\config.json 自动填充 “venv python” 与 “Job root”;也可点击面板中的 Setup / Detect venv 按钮手动触发检测(该按钮只做检测与填充,不负责建环境)。
- 需要联网:仅首次建环境时(pip 下载);日常运行完全离线。
- 不需要 GPU:计算为 numpy 向量化 CPU 运算。
- 不需要 WSL:venv 是原生 Windows 环境。
失败时的替代方案:若脚本报 “no suitable Python 3.9-3.12 found”,请先从 python.org 安装一个 3.9–3.12 版本的 Python 再重跑,或用 -BasePython 显式指定解释器。也可以完全手动:自己创建一个 venv、pip install numpy scipy xraydb,然后把该 venv 的 ...\Scripts\python.exe 完整路径粘贴到面板的 “venv python” 输入框即可。
5. 界面说明
面板整体为左右分栏(可拖动分隔条):左侧是新手演示区,右侧是正式数据的配置区 + 运行按钮 + 日志。顶部有一行功能简介和一个 ◀ Hide demo 按钮——点击可隐藏/显示左侧演示区(隐藏后按钮变为 Show demo ▶)。
5.1 左侧:Beginner demo(新手演示,无需数据)
- Phantom 下拉框:选择合成体模,共 3 种——
Sandstone (quartz + brine pores)(石英基质 + 含水孔隙)、Carbonate with pyrite (calcite + FeS2)(方解石基质 + 黄铁矿结核)、Mixed lithology (4 materials)(水、石英、方解石、黄铁矿并存);下方灰色文字随选择显示该体模的一句话说明; - Resolution (voxels/axis) 数字框:体模每轴体素数,范围 16–160,默认 64;
- “How to read it” 说明文字:提示 Z_eff / Rho_e 的参考读数,并说明演示固定在 40 / 100 keV(内置 μ 表就是按这两个能量制表的);
- Also import the synthetic low/high volumes 复选框(默认勾选):把合成的低/高能输入体也导入为 Channel,便于对照查看;
- Generate phantom + Run demo 按钮(绿色):一键生成体模、写出标定 ROI、调用 venv 完成标定与分解,并把结果导回 Dragonfly。
5.2 右侧:Energy volumes(能量体数据)
- Refresh objects 按钮:扫描当前 Dragonfly 会话中的对象,把所有 Channel 填入两个下拉框、把所有 ROI/MultiROI 填入标定行的 ROI 下拉框(打开面板后应先点它);
- Low-energy Channel / High-energy Channel 下拉框:分别选择低能与高能体数据(显示名称和尺寸;两者必须不同、且尺寸一致);
- Low energy (keV) / High energy (keV) 输入框:两次扫描的有效能量,默认 40 / 100(会记住上次运行的数值)。
5.3 右侧:Calibration(参考材料 → ROI 标定)
把每种参考材料对应到一个画在该物相内部的 ROI / MultiROI。每个 ROI 的平均灰度与该材料的理论衰减系数(来自 xraydb)拟合,用于把 PV 换算为 μ。两对及以上给出真正的线性拟合(含截距和 R²);只有一对时直线被强制过原点。
- + Add material 按钮:新增一行标定对(面板打开时默认已有一行);
- Clear all 按钮:清空所有标定行(并留下一行空行);
- 每行内容:材料下拉框(可选 Water、Quartz、Calcite、Dolomite、Pyrite、Aluminum、Air)→ ROI 下拉框(列出场景中的 ROI/MultiROI 及其尺寸)→ X 删除按钮(红色)。
5.4 右侧:DECT compute venv(计算环境)
- venv python 输入框:计算 venv 的 python.exe 完整路径;留空则自动检测(占位提示
auto-detected; or paste ...\DECT_Zeff\venv\Scripts\python.exe); - Job root (Windows) 输入框:作业根目录,默认 C:\DECT_ZeffJobs,每次运行在其下新建一个带时间戳的作业文件夹;
- Setup / Detect venv 按钮:重新检测 venv(读配置文件、探测默认安装位置),检测结果打印到日志。
5.5 右侧:运行按钮与日志
- Run DECT decomposition 按钮(蓝色):用右侧配置对真实数据运行标定 + 分解;
- Open Output Folder 按钮:在资源管理器中打开最近一次作业的输出文件夹(若尚未运行则打开作业根目录);
- 日志区(只读文本框):显示进度百分比、标定质量(每能量段的 n、R²、slope/intercept)、Z_eff / Rho_e 的标定模式与标尺、结果值域统计、新建 Channel 名称和输出目录;出错时显示错误信息与堆栈。
运行期间两个运行按钮会被禁用;计算在后台线程 + 独立子进程中进行,不会卡住 Dragonfly 界面。关闭面板会请求取消正在运行的作业。
6. 使用步骤
6.1 第一次使用:跑内置演示
1. 确认已按第 4 节建好 venv(面板日志出现 Using DECT venv: ... 即为就绪;否则点 Setup / Detect venv);
2. 在左侧选择一个 Phantom(例如 Carbonate with pyrite),保持分辨率 64;
3. 点击 Generate phantom + Run demo;
4. 观察日志:生成体模 → 导入合成低/高能 Channel(若勾选)→ 标定(R² 应接近 1)→ Alvarez–Macovski 分解 → 导回结果;
5. 在 Dragonfly 数据列表中查看新 Channel:Demo_DECT Z-eff (40/100 keV) 与 Demo_DECT Rho-e rel-water (40/100 keV)。切片浏览 Z_eff:黄铁矿(约 21.6)明显高于方解石(约 15.7)和水(约 7.4)。
6.2 处理自己的双能数据
输入要求:低能、高能两个 Channel 已载入 Dragonfly,且体素网格尺寸完全一致;已在体数据中的已知参考材料区域各画好一个 ROI(或 MultiROI),ROI 必须与低能 Channel 同网格、且非空。
1. 点击 Refresh objects,日志显示找到的 Channel / ROI 数量;
2. 在 Low-energy Channel / High-energy Channel 中分别选择低、高能体数据(顺序不要选反);
3. 填写 Low energy (keV) 与 High energy (keV)(两次扫描的有效能量);
4. 在标定区为每种参考材料添加一行:选材料(如 Quartz)→ 选对应 ROI;建议至少两对(例如孔隙水 + 石英基质),必要时点 + Add material 增加;
5. 点击 Run DECT decomposition;
6. 等待日志走到 100%:检查两条 Calib low/high 的 R²(越接近 1 说明标定越可信)以及 Z_eff / Rho_e 的值域统计;
7. 在场景中查看新生成的 DECT Z-eff (低/高 keV) 和 DECT Rho-e rel-water (低/高 keV) 两个 Channel;需要检查中间文件时点 Open Output Folder。
若某个 ROI 与体数据尺寸不一致或为空,日志会给出 [Warn] 并跳过该标定对;如果全部标定对都被跳过,运行会失败并提示检查 ROI。
7. 参数说明
参数 | 默认值 | 说明 |
Phantom(演示) | Sandstone (quartz + brine pores) | 演示体模类型,共 3 种:Sandstone / Carbonate with pyrite / Mixed lithology(4 材料) |
Resolution (voxels/axis)(演示) | 64 | 体模每轴体素数,范围 16–160;越大越精细、耗时越长 |
Also import the synthetic low/high volumes(演示) | 勾选 | 把合成低/高能输入体也导入为 Channel(名如 Demo_sandstone_low_40keV,单位 PV) |
Low-energy Channel | (空,需 Refresh 后选择) | 低能量体数据;与高能体尺寸必须一致 |
High-energy Channel | (空,需 Refresh 后选择) | 高能量体数据;不能与低能选择同一个对象 |
Low energy (keV) | 40 | 低能扫描的有效能量;参与基函数 E⁻³ 与 Klein–Nishina 项的计算,也用于查询理论 μ |
High energy (keV) | 100 | 高能扫描的有效能量;两能量过近会导致方程组病态 |
Material(标定行) | Water | 参考材料,7 选 1:Water / Quartz / Calcite / Dolomite / Pyrite / Aluminum / Air |
ROI(标定行) | (空) | 画在该材料内部的 ROI 或 MultiROI;须与体数据同网格且非空 |
venv python | (自动检测) | 计算 venv 的 python.exe;通常为 %LOCALAPPDATA%\DECT_Zeff\venv\Scripts\python.exe |
Job root (Windows) | C:\DECT_ZeffJobs | 作业根目录;每次运行新建 dect_<时间戳>(演示为 dect_demo_<体模>_<时间戳>)子目录 |
内置参考材料表(标定与自动标尺均使用;来自插件的材料数据库):
材料 | 化学式 | 密度 g/cm³ | 参考 Z_eff |
Water(水/盐水) | H2O | 1.0 | 7.42 |
Quartz(石英) | SiO2 | 2.65 | 11.8 |
Calcite(方解石) | CaCO3 | 2.71 | 15.7 |
Dolomite(白云石) | CaMg(CO3)2 | 2.85 | 13.0 |
Pyrite(黄铁矿) | FeS2 | 5.01 | 21.6 |
Aluminum(铝) | Al | 2.70 | 13.0 |
Air(空气) | N0.78O0.21Ar0.01 | 0.0012 | 7.6 |
另有两个固定开启的内部选项:Z_eff 与 Rho_e 的自动标尺(auto-calibrate)。Z_eff 标尺由参考材料表过原点拟合得到(日志 zeff_mode: Calibrated (Physical));Rho_e 标尺按水归一(日志 rhoe_mode: Relative to Water,水 ≈ 1.0)。
8. 输出结果
Dragonfly 场景中的新对象(几何信息——体素间距与原点——继承自低能 Channel):
DECT Z-eff (40/100 keV)—— Z_eff 图 Channel,数据单位标注为Z (atomic number)(括号中为实际使用的两个能量);DECT Rho-e rel-water (40/100 keV)—— 相对电子密度图 Channel,单位标注rel. e- density;- 演示运行时上述名称带
Demo_前缀;若勾选了导入输入体,还会得到Demo_<体模>_low_40keV与Demo_<体模>_high_100keV两个输入 Channel(单位 PV)。
两个结果 Channel 与普通 Channel 一样使用:在 2D 切片中配合合适的窗宽/LUT 浏览,或做后续阈值分割、统计。Z_eff 图中不满足求解条件的体素(康普顿系数过小或光电系数非正,例如空气背景)被置 0。
作业文件夹(C:\DECT_ZeffJobs\dect_<时间戳>\,点 Open Output Folder 直达)内含:
low.npy/high.npy:导出的低/高能体数据(float32);mask_<材料>.npy:每个标定 ROI 的二值掩膜;config.json:本次运行的完整配置;status.json:进度/状态(供面板轮询);z_eff.npy/rho_e.npy:结果图原始数组;dect_result.json:结果摘要——所用物理库(xraydb/xraylib)、每能量段标定的 n/R²/slope/intercept、Z_eff 与 Rho_e 的模式和标尺、结果 min/max/mean 统计、耗时。
日志中的质量指标:Calib low/high: n=.. R^2=.. mu=..*PV+.. 给出标定拟合质量;Z_eff mode / Rho_e mode 给出标尺来源;随后是各结果的取值范围和均值。R² 明显偏低说明 ROI 不纯、材料选错或能量填错。
9. 常见问题与故障排除
问 1:菜单里找不到 Prototype Apps ▸ DECT Z-eff...?
答:本插件在完整安装包中默认不勾选。重跑 Install_FullPackage.bat 勾选它,或在 Developer ▸ Prototype Labs... ▸ Menu Item Manager 中勾选,然后完全重启 Dragonfly(菜单只在启动时扫描)。
问 2:日志提示 “No DECT venv found” 或 “ERROR: DECT venv not set”?
答:计算环境还没建好。按第 4 节运行 setup_dect_venv.bat(联网一次,约 100 MB);或者手动建 venv 装 numpy/scipy/xraydb 后,把其 ...\Scripts\python.exe 粘贴到 “venv python” 输入框,再点 Setup / Detect venv 确认。
问 3:报错 “neither xraylib nor xraydb is installed in this venv”?
答:venv 存在但物理库缺失(例如手动建的环境漏装)。重跑 setup_dect_venv.ps1(必要时加 -Force 重建),它会安装 xraydb 并做导入冒烟测试。
问 4:标定 R² 很低,或 Z_eff 数值明显不合理?
答:依次检查——① ROI 是否画在纯净单一物相内部(避开边界和伪影);② 材料下拉框选择是否与 ROI 实际物相一致;③ 低/高能 Channel 是否选反;④ 两个有效能量是否填对(它们既进入基函数又决定理论 μ 查询);⑤ 标定对是否太少——只有一对时直线被强制过原点、无 R² 可言,建议至少两对且 Z_eff 跨度要大(如水 + 石英)。
问 5:日志出现 “[Warn] ROI for X shape ... mismatches volume ...; skipping”?
答:该 ROI 与低能体数据不在同一体素网格上(尺寸不同),已被跳过。请在与低能 Channel 相同几何的视图上重新勾画 ROI;MultiROI 亦须同网格。全部标定对被跳过时运行会失败。
问 6:setup 脚本报 “no suitable Python 3.9-3.12 found”?
答:机器上没有可用的标准 Python(脚本刻意拒绝 Dragonfly 自带解释器)。从 python.org 安装 3.9–3.12 任一版本后重跑,或用 -BasePython C:\path\python.exe 显式指定。
问 7:运行到一半想取消?
答:关闭面板会向作业发出取消请求(日志报 cancelled)。已写入作业文件夹的中间文件不会自动删除,可手动清理 C:\DECT_ZeffJobs。
10. 注意事项与已知限制
- 低、高能两个体数据必须尺寸完全一致;插件不做配准或重采样,若两次扫描存在位移需先自行对齐;
- 标定假设 PV 与线性衰减系数呈线性关系(每个能量段一条直线);重建中的强烈非线性(如未校正的束硬化)会降低精度;
- 能量输入的是有效(等效单能)能量:实际 X 射线源是多能谱,用单一 keV 近似必然有偏差,可通过调整能量值与增加标定材料来改善;
- 只支持两个能量的双基分解(2×2 求解);两能量必须拉开差距,过近会导致矩阵病态甚至报 “singular matrix”;
- 只有一对标定材料时直线强制过原点(无截距、无 R²);若该 ROI 平均灰度非正则无法拟合,将退回恒等标定并在日志标记 degenerate;
- Z_eff 的经验指数固定为 1/3.6;Z_eff 与 Rho_e 均截断为非负,无法求解的体素置 0;
- 参考材料仅限内置 7 种(见第 7 节表格);其他材料暂不能直接用于标定;
- 演示体模固定在 40 / 100 keV 运行(其内置 μ 表按此制表),演示时面板中填写的能量会被忽略;
- 计算为 CPU 运算,内存中会同时存在体数据的多份 float32 副本,特大体数据请注意内存;
- 面板会把能量、venv 路径、作业根目录记忆到
%LOCALAPPDATA%\DECT_Zeff\config.json,下次打开自动恢复。
11. 参考资料
- Alvarez–Macovski 双基分解:把 μ(E) 分解为光电效应(E⁻³)与康普顿散射(Klein–Nishina)两个基函数,是双能 CT 材质分解的经典方法(本插件的求解内核);
- xraydb:纯 Python 的 X 射线性质数据库(PyPI 包
xraydb),提供标定所需的理论质量/线性衰减系数; - xraylib:另一个 X 射线物理库(PyPI 包
xraylib,可选安装),可用时优先于 xraydb; - numpy / scipy:数值计算与线性回归(
scipy.stats.linregress)所用的开源库; - 插件自带 README(随插件源码分发)含架构图与物理说明,供高级用户参考。
Part II English Manual
Contents
1. Overview
2. Use cases
3. Installation and enabling
4. Runtime environment and first-time configuration
5. User interface
5.1 Left: Beginner demo (no data needed)
5.2 Right: Energy volumes
5.3 Right: Calibration (reference Material -> ROI)
5.4 Right: DECT compute venv
5.5 Right: run buttons and log
6. Step-by-step workflows
6.1 First run: the built-in demo
6.2 Processing your own dual-energy data
7. Parameter reference
8. Outputs
9. FAQ and troubleshooting
10. Notes and known limitations
11. References
1. Overview
DECT Z-eff is a Dragonfly Prototype Apps plugin for material decomposition of dual-energy CT (DECT) data. Select a low-energy and a high-energy volume, mark ROIs on known reference materials (e.g. quartz, calcite, brine) for calibration, set the two effective energies (keV) and run - two new Channels are published into the scene:
- Z_eff - Effective Atomic Number map: the equivalent atomic number per voxel, e.g. brine/water ~7.4, quartz ~11.8, calcite ~15.7, pyrite ~21.6 - a strong discriminator for minerals/materials;
- Rho_e - Relative Electron Density map: electron density relative to water (water ~1.0), carrying the density information.
The computation runs in two stages. First a linear PV to mu calibration per energy band: the mean grayscale (PV) of each reference-material ROI is fit against that material's theoretical linear attenuation coefficient mu (cm⁻¹). Then the classic Alvarez-Macovski two-basis decomposition: mu(E) is modelled as a photoelectric term a_pe·E⁻³ plus a Compton term a_kn·f_KN(E) (Klein-Nishina approximation); a 2x2 linear system is inverted per voxel, the coefficient ratio (a_pe/a_kn)^(1/3.6) maps to Z_eff and a_kn (normalized to water) gives Rho_e. Both output scales are auto-calibrated against a built-in reference-material table (water, quartz, calcite, dolomite, pyrite, aluminum, air), and the calibration quality (R² per band) is reported in the log.
The theoretical attenuation coefficients come from the open-source X-ray physics database xraydb (with xraylib preferred when installed). These compute dependencies (numpy, scipy, xraydb - all open-source Python packages installed from PyPI) live in an isolated Python virtual environment (venv) and are never installed into Dragonfly's embedded Python, so the plugin cannot destabilize Dragonfly itself.
A built-in beginner demo generates a synthetic dual-energy phantom of known minerals and runs the full calibrate-then-decompose pipeline, so you can try and validate the plugin without preparing any data.
2. Use cases
- Digital rock physics / petrophysics: identifying minerals (quartz, calcite, dolomite, pyrite, ...) and quantifying composition in dual-energy micro-CT scans of rock cores;
- Materials science: when phases with similar grayscale but different elemental composition must be separated, Z_eff adds a discrimination axis beyond simple grayscale;
- Industrial CT: whenever two scans of the same sample at different (effective) energies are available;
- Teaching and method validation: the synthetic-phantom demo illustrates the DECT principle (at low energy the photoelectric effect strongly separates high-Z phases; at high energy the spread collapses toward density-driven Compton contrast).
Input requirements: two Dragonfly Channels of identical size (one low-energy, one high-energy), plus at least one ROI or MultiROI drawn inside a known reference material (two or more recommended - see sections 6 and 7).
3. Installation and enabling
The plugin is distributed and installed via the Prototype Labs & Apps Full Package:
1. Unzip the package to a short path (e.g. C:\PL\; avoid deep folders that can hit the Windows path-length limit);
2. Double-click Install_FullPackage.bat;
3. In the installer dialog, tick DECT Z-eff... in the Prototype Apps list (note: all plugins are unticked by default - you must tick this one);
4. Click Install and wait for the console to finish;
5. Quit Dragonfly completely and restart it (menus are only discovered at startup).
After the restart the menu entry appears under Prototype Apps ▸ DECT Z-eff... (in the Reconstruction & Imaging group). Clicking it opens a floating, movable/dockable window titled DECT Z-eff.
You can change your choices later at any time in Developer ▸ Prototype Labs... ▸ Menu Item Manager: the "Prototype Apps (Full Package)" list at the bottom has one checkbox per app - tick = deploy, untick = remove the menu entry; restart Dragonfly to apply. Disabling never deletes a plugin's compute environment, so re-enabling is instant. Alternatively, re-run the installer - it remembers your previous choices as defaults.
Everything installs per-user (%LOCALAPPDATA%); no admin rights are needed. To uninstall, use Uninstall_FullPackage.bat: it removes menu items and plugin code but keeps the venv and other environments (their paths are listed at the end for manual deletion if you want the disk space back).
4. Runtime environment and first-time configuration
Calibration needs xraydb (or xraylib) for theoretical attenuation coefficients; these libraries are not in Dragonfly's embedded Python and must not be pip-installed into it. The compute therefore runs in a separate native Windows venv; the plugin talks to it through files (config.json / status.json / *.npy). Before first use, build that environment once:
Run setup_dect_venv.bat (or the equivalent PowerShell script) shipped with the plugin:
setup_dect_venv.bat
:: or:
powershell -ExecutionPolicy Bypass -File setup_dect_venv.ps1
:: optional switches:
:: -BasePython C:\path\python.exe use a specific base interpreter
:: -Force rebuild the venv from scratch
The script performs, in order:
1. Locate a Python 3.9-3.12 base interpreter (via the py launcher or python on PATH; it refuses Dragonfly's own interpreter);
2. Create the venv at %LOCALAPPDATA%\DECT_Zeff\venv;
3. pip-install numpy + scipy + xraydb (download roughly 100 MB; internet needed once);
4. Try the optional xraylib (installs only if a prebuilt wheel is available; if not, the runner simply uses xraydb);
5. Run an import smoke test to confirm numpy/scipy/xraydb work;
6. Write %LOCALAPPDATA%\DECT_Zeff\config.json (venv python path + job root) and create the default job folder C:\DECT_ZeffJobs.
Once the config exists, the panel auto-detects it: on opening it reads %LOCALAPPDATA%\DECT_Zeff\config.json and pre-fills "venv python" and "Job root". You can also click the Setup / Detect venv button to re-run detection (this button only detects and fills the fields - it does not build the environment).
- Internet: needed once, for the initial pip download; normal operation is fully offline.
- GPU: not required - the compute is vectorized numpy on the CPU.
- WSL: not required - the venv is a native Windows environment.
If setup fails: on "no suitable Python 3.9-3.12 found", install a Python 3.9-3.12 from python.org and re-run, or pass -BasePython explicitly. Fully manual alternative: create your own venv, pip install numpy scipy xraydb, then paste that venv's ...\Scripts\python.exe path into the panel's "venv python" field.
5. User interface
The panel is split left/right (draggable splitter): the left side is the beginner demo, the right side holds the configuration for your own data plus the run buttons and the log. At the top there is a one-line description and a ◀ Hide demo button that hides/shows the left side (it turns into Show demo ▶ when hidden).
5.1 Left: Beginner demo (no data needed)
- Phantom dropdown: three synthetic phantoms -
Sandstone (quartz + brine pores),Carbonate with pyrite (calcite + FeS2),Mixed lithology (4 materials); a gray one-line description updates below as you switch; - Resolution (voxels/axis) spinbox: voxels per axis, range 16-160, default 64;
- "How to read it" text: reference readings for Z_eff / Rho_e, and a note that the demo always runs at 40 / 100 keV (its built-in mu table is tabulated at those energies);
- Also import the synthetic low/high volumes checkbox (checked by default): also imports the synthetic input volumes as Channels for side-by-side inspection;
- Generate phantom + Run demo button (green): one click builds the phantom, writes the calibration ROIs, runs calibration + decomposition in the venv and imports the results back.
5.2 Right: Energy volumes
- Refresh objects button: scans the current Dragonfly session and fills the two Channel dropdowns and the ROI dropdowns of the calibration rows (click it first after opening the panel);
- Low-energy Channel / High-energy Channel dropdowns: pick the two volumes (shown with name and shape; they must be different objects with identical shapes);
- Low energy (keV) / High energy (keV) fields: the effective energies of the two scans, defaults 40 / 100 (the last used values are remembered).
5.3 Right: Calibration (reference Material -> ROI)
Map each reference material to an ROI / MultiROI drawn inside that phase. The mean intensity per ROI is fit against the material's theoretical attenuation (from xraydb) to convert PV to mu. Two or more pairs give a real linear fit (with intercept and R²); a single pair forces the line through the origin.
- + Add material button: adds a calibration row (one empty row exists when the panel opens);
- Clear all button: removes all rows (and leaves one fresh empty row);
- Each row: material dropdown (Water, Quartz, Calcite, Dolomite, Pyrite, Aluminum, Air) -> ROI dropdown (lists the session's ROIs/MultiROIs with their shapes) -> red X button to delete the row.
5.4 Right: DECT compute venv
- venv python field: full path of the compute venv's python.exe; leave empty for auto-detection (placeholder:
auto-detected; or paste ...\DECT_Zeff\venv\Scripts\python.exe); - Job root (Windows) field: job root folder, default C:\DECT_ZeffJobs; every run creates a timestamped job subfolder there;
- Setup / Detect venv button: re-detects the venv (reads the config file, probes the default install location) and reports the result in the log.
5.5 Right: run buttons and log
- Run DECT decomposition button (blue): runs calibration + decomposition on your own data using the right-hand configuration;
- Open Output Folder button: opens the most recent job folder in Explorer (or the job root if nothing has run yet);
- Log (read-only text box): progress percentages, calibration quality per band (n, R², slope/intercept), Z_eff / Rho_e calibration mode and scale, result value ranges, the names of the new Channels and the output folder; on failure, the error message and traceback.
Both run buttons are disabled while a job is running; the compute runs in a background thread plus a separate subprocess, so the Dragonfly UI stays responsive. Closing the panel requests cancellation of a running job.
6. Step-by-step workflows
6.1 First run: the built-in demo
1. Make sure the venv is built (section 4); the log line Using DECT venv: ... confirms it (otherwise click Setup / Detect venv);
2. Pick a Phantom on the left (e.g. Carbonate with pyrite), keep the resolution at 64;
3. Click Generate phantom + Run demo;
4. Watch the log: phantom generation -> import of the synthetic low/high Channels (if ticked) -> calibration (R² should be close to 1) -> Alvarez-Macovski decomposition -> import of the results;
5. Inspect the new Channels in Dragonfly's data list: Demo_DECT Z-eff (40/100 keV) and Demo_DECT Rho-e rel-water (40/100 keV). Browsing Z_eff slices, pyrite (~21.6) stands far above calcite (~15.7) and water (~7.4).
6.2 Processing your own dual-energy data
Input requirements: the low- and high-energy Channels are loaded in Dragonfly with exactly matching voxel grids, and one ROI (or MultiROI) has been drawn inside each known reference material; each ROI must be on the same grid as the low-energy Channel and must not be empty.
1. Click Refresh objects; the log reports how many Channels / ROIs were found;
2. Select the Low-energy Channel and High-energy Channel (do not swap them);
3. Enter the Low energy (keV) and High energy (keV) (the effective energies of the two scans);
4. Add one calibration row per reference material: pick the material (e.g. Quartz) -> pick its ROI; at least two pairs are recommended (e.g. pore brine + quartz matrix); click + Add material for more rows;
5. Click Run DECT decomposition;
6. Wait for the log to reach 100%: check the R² of the Calib low/high lines (the closer to 1, the more trustworthy the calibration) and the Z_eff / Rho_e value-range statistics;
7. Inspect the new DECT Z-eff (low/high keV) and DECT Rho-e rel-water (low/high keV) Channels in the scene; click Open Output Folder to examine the intermediate files.
If an ROI's shape does not match the volumes, or the ROI is empty, the log prints a [Warn] and skips that pair; if all pairs are skipped the run fails with a message asking you to check the ROIs.
7. Parameter reference
Parameter | Default | Description |
Phantom (demo) | Sandstone (quartz + brine pores) | Synthetic phantom type; 3 choices: Sandstone / Carbonate with pyrite / Mixed lithology (4 materials) |
Resolution (voxels/axis) (demo) | 64 | Voxels per axis, range 16-160; larger = finer but slower |
Also import the synthetic low/high volumes (demo) | checked | Also imports the synthetic input volumes as Channels (e.g. Demo_sandstone_low_40keV, unit PV) |
Low-energy Channel | (empty; pick after Refresh) | The low-energy volume; must match the high-energy volume's shape |
High-energy Channel | (empty; pick after Refresh) | The high-energy volume; must be a different object than the low-energy one |
Low energy (keV) | 40 | Effective energy of the low-energy scan; enters the E⁻³ and Klein-Nishina basis terms and the theoretical-mu lookup |
High energy (keV) | 100 | Effective energy of the high-energy scan; energies too close together make the system ill-conditioned |
Material (calibration row) | Water | Reference material, one of 7: Water / Quartz / Calcite / Dolomite / Pyrite / Aluminum / Air |
ROI (calibration row) | (empty) | ROI or MultiROI drawn inside that material; must share the volume grid and be non-empty |
venv python | (auto-detected) | python.exe of the compute venv; normally %LOCALAPPDATA%\DECT_Zeff\venv\Scripts\python.exe |
Job root (Windows) | C:\DECT_ZeffJobs | Job root; each run creates a dect_<timestamp> subfolder (dect_demo_<phantom>_<timestamp> for demos) |
Built-in reference-material table (used both for calibration and for the automatic output scales; from the plugin's material database):
Material | Formula | Density g/cm³ | Reference Z_eff |
Water (water/brine) | H2O | 1.0 | 7.42 |
Quartz | SiO2 | 2.65 | 11.8 |
Calcite | CaCO3 | 2.71 | 15.7 |
Dolomite | CaMg(CO3)2 | 2.85 | 13.0 |
Pyrite | FeS2 | 5.01 | 21.6 |
Aluminum | Al | 2.70 | 13.0 |
Air | N0.78O0.21Ar0.01 | 0.0012 | 7.6 |
Two internal options are always on: the automatic scaling of Z_eff and Rho_e. The Z_eff scale is fit through the origin against the reference table (log: zeff_mode: Calibrated (Physical)); the Rho_e scale normalizes to water (log: rhoe_mode: Relative to Water, water ~1.0).
8. Outputs
New objects in the Dragonfly scene (the geometry - voxel spacing and origin - is inherited from the low-energy Channel):
DECT Z-eff (40/100 keV)- the Z_eff map Channel, data unit labelledZ (atomic number)(the numbers in parentheses are the energies actually used);DECT Rho-e rel-water (40/100 keV)- the relative electron density Channel, unit labelledrel. e- density;- Demo runs prefix these names with
Demo_; with the import-inputs checkbox ticked you also getDemo_<phantom>_low_40keVandDemo_<phantom>_high_100keVinput Channels (unit PV).
Both result Channels behave like any Channel: browse them in 2D slices with a suitable window/LUT, or use them for further thresholding and statistics. In the Z_eff map, voxels where the solve is invalid (Compton coefficient too small or non-positive photoelectric coefficient, e.g. air background) are set to 0.
Job folder (C:\DECT_ZeffJobs\dect_<timestamp>\, reachable via Open Output Folder) contains:
low.npy/high.npy: the exported low/high energy volumes (float32);mask_<Material>.npy: the binary mask of each calibration ROI;config.json: the full run configuration;status.json: progress/state (polled by the panel);z_eff.npy/rho_e.npy: the raw result arrays;dect_result.json: the result summary - physics backend used (xraydb/xraylib), per-band calibration n/R²/slope/intercept, Z_eff and Rho_e modes and scales, min/max/mean statistics of the results, and the runtime in seconds.
Quality indicators in the log: Calib low/high: n=.. R^2=.. mu=..*PV+.. gives the calibration fit quality; Z_eff mode / Rho_e mode show where the scales come from; value ranges and means of the results follow. A clearly low R² indicates impure ROIs, a wrong material choice, or wrong energies.
9. FAQ and troubleshooting
Q1: The menu entry Prototype Apps ▸ DECT Z-eff... is missing.
A: The plugin is unticked by default in the Full Package installer. Re-run Install_FullPackage.bat and tick it, or tick it in Developer ▸ Prototype Labs... ▸ Menu Item Manager, then fully restart Dragonfly (menus are only discovered at startup).
Q2: The log says "No DECT venv found" or "ERROR: DECT venv not set".
A: The compute environment has not been built yet. Run setup_dect_venv.bat as in section 4 (one-time internet download of roughly 100 MB); or build a venv yourself with numpy/scipy/xraydb, paste its ...\Scripts\python.exe into the "venv python" field, and click Setup / Detect venv to confirm.
Q3: Error "neither xraylib nor xraydb is installed in this venv".
A: The venv exists but the physics library is missing (e.g. a hand-built environment). Re-run setup_dect_venv.ps1 (add -Force to rebuild if needed); it installs xraydb and runs an import smoke test.
Q4: The calibration R² is low, or the Z_eff values look wrong.
A: Check in order - (1) each ROI lies inside a pure single phase (away from boundaries and artifacts); (2) the material selected in the dropdown matches the ROI's actual phase; (3) the low/high Channels are not swapped; (4) the two effective energies are correct (they enter both the basis functions and the theoretical-mu lookup); (5) enough calibration pairs - with a single pair the line is forced through the origin and no R² exists; use at least two pairs spanning a wide Z_eff range (e.g. water + quartz).
Q5: The log shows "[Warn] ROI for X shape ... mismatches volume ...; skipping".
A: That ROI is not on the same voxel grid as the low-energy volume (different shape) and was skipped. Redraw the ROI on a view with the same geometry as the low-energy Channel; MultiROIs must also share the grid. If every pair is skipped, the run fails.
Q6: The setup script fails with "no suitable Python 3.9-3.12 found".
A: No standard Python is available (the script deliberately refuses Dragonfly's own interpreter). Install any Python 3.9-3.12 from python.org and re-run, or pass -BasePython C:\path\python.exe explicitly.
Q7: How do I cancel a running job?
A: Closing the panel requests cancellation (the log reports cancelled). Intermediate files already written to the job folder are not deleted automatically; clean up C:\DECT_ZeffJobs manually if desired.
10. Notes and known limitations
- The low- and high-energy volumes must have exactly the same shape; the plugin performs no registration or resampling - align the scans beforehand if they are shifted;
- Calibration assumes PV is linearly related to the linear attenuation coefficient (one straight line per band); strong reconstruction non-linearities (e.g. uncorrected beam hardening) reduce accuracy;
- The energies are effective (equivalent monochromatic) energies: real X-ray sources are polychromatic, so a single-keV approximation carries an inherent bias - tune the energy values and add calibration materials to improve results;
- Only two energies are supported (a 2x2 two-basis solve); the energies must be well separated - values too close make the matrix ill-conditioned and can raise a "singular matrix" error;
- With a single calibration pair the line is forced through the origin (no intercept, no R²); if that ROI's mean PV is non-positive the fit is impossible and the identity calibration is kept, flagged degenerate in the QA output;
- The empirical Z_eff exponent is fixed at 1/3.6; both Z_eff and Rho_e are clipped to non-negative values, and unsolvable voxels are set to 0;
- Only the 7 built-in reference materials (see the table in section 7) can be used for calibration;
- The demo always runs at 40 / 100 keV (its built-in mu table is tabulated there); energies typed in the panel are ignored during a demo run;
- The compute is CPU-based, and several float32 copies of the volume coexist in memory - mind your RAM for very large volumes;
- The panel remembers the energies, venv path and job root in
%LOCALAPPDATA%\DECT_Zeff\config.jsonand restores them next time.
11. References
- Alvarez-Macovski two-basis decomposition: modelling mu(E) as a photoelectric (E⁻³) plus a Compton (Klein-Nishina) basis - the classic dual-energy CT decomposition method used by this plugin's solver;
- xraydb: a pure-Python X-ray properties database (PyPI package
xraydb), providing the theoretical attenuation coefficients used in calibration; - xraylib: an alternative X-ray physics library (PyPI package
xraylib, optional), preferred over xraydb when available; - numpy / scipy: the open-source libraries used for the numerics and the linear regression (
scipy.stats.linregress); - The plugin's bundled README (shipped with the plugin source) contains the architecture diagram and physics notes for advanced users.