使用diompyler-core来读取剂量统计信息的方法
from dicompylercore import dicomparser, dvh, dvhcalc
rs_file = r"D:\code\temp\RS.dcm"
rd_file = r"d:\code\temp\RD_PI-V-25F.dcm"
rtss = dicomparser.DicomParser(rs_file)
rtdose = dicomparser.DicomParser(rd_file)
structures = rtss.GetStructures()
参考这个使用dicompyler-core,直接从RTStruct和RTDose文件中,读取ROI剂量统计信息的文章:
DVH参数计算(1)
GitHub - dicompyler/dicompyler-core: A library of core radiation therapy modules for DICOM RT used by dicompyler
Github上面的简单介绍:
A library of core radiation therapy modules for DICOM / DICOM RT used by dicompyler. This package includes:
-
dicomparser: parse DICOM objects in an easy-to-use manner -
dvh: Pythonic access to dose volume histogram (DVH) data -
dvhcalc: Independent DVH calculation using DICOM RT Dose & RT Structure Set -
dose: Pythonic access to RT Dose data including dose summation
不知道为啥dicompyler-0.4.2以后就没更新了,现在RTplan协议貌似改了,一打开plan就奔溃,另外如果有中文目录也会崩溃。
首先是安装dicompyler-core,这里用conda虚拟环境
conda create -name dicompyler
conda activate dicompyler
# 安装依赖包
conda install numpy pydicom matplotlib pillow shapely scikit-image scipy
# jupyter虚拟环境
conda install ipykernel
python -m ipykernel install --user --name dicompyler
在这一段的时候报错:
calcdvh = dvh.DVH.from_dicom_dvh(rtdose.ds, 10)
# Error
AttributeError: 'FileDataset' object has no attribute 'DVHSequence'
参考这个链接,是因为RTdose文件里面没有包含DVHSequence信息,建议使用dvhcalc重新计算
'FileDataset' object has no attribute 'DVHSequence' · Issue #219 · dicompyler/dicompyler-core · GitHub
计算dvh的方法:
from dicompylercore import dicomparser, dvhcalc
rs_file = r"D:\code\temp\RS.dcm"
rd_file = r"d:\code\temp\RD_PI-V-25F.dcm"
rtss = dicomparser.DicomParser(rs_file)
structures = rtss.GetStructures()
structure = list(structures.values())
for stuc in structures:
print(f"id: {stuc:^3}, name: {structures[stuc]['name']}")
# 创建一个空字典来保存每个结构的DVH
dvh_dict = {}
# 遍历structures字典的键
for structure_id in structures:
# 获取结构名称
structure_name = structures[structure_id]['name']
print(f"Parsering dvh for {structure_name}")
# 使用get_dvh计算DVH并保存到dvh_dict中
dvh_dict[structure_name] = dvhcalc.get_dvh(rs_file, rd_file, structure_id)
# 此时,dvh_dict包含了所有结构的DVH,使用结构名称作为键
print(dvh_dict.keys())
#dict_keys(['Mark', 'b-ptv', 'i-ptv', 'r-ptv', 'nt', 'Ring', 'Spinal cord', 'PTV', 'Rectum', 'Bladder', 'Sigmoid', 'Bone marrow', 'Bowel bag', 'Femur_R', 'Femur_L', 'External', 'CTV'])
查看bladder的剂量统计信息
dvh_dict['Bladder']
DVH(cumulative, 4817 bins: [0.0:48.17] Gy, volume: 139.8125 cm3, name: 'Bladder', rx_dose: 0 Gy)
dvh_dict['Bladder'].describe()
Structure: Bladder
-----
DVH Type: cumulative, abs dose: Gy, abs volume: cm3
Volume: 139.81 cm3
Max Dose: 48.17 Gy
Min Dose: 20.25 Gy
Mean Dose: 42.11 Gy
D100: 20.24 Gy
D98: 26.66 Gy
D95: 29.62 Gy
D2cc: 47.78 Gy
这里文件中得到的是cumulative dvh, absolute dose, absolute volume 的
获取剂量统计信息的方法:
# max, min, mean
dvh_dict['Bladder'].volume
dvh_dict['Bladder'].max
dvh_dict['Bladder'].mean
# absolute dose for absolue volume
dvh_dict['Bladder'].D2cc
dvh_dict['Bladder'].D10cc
dvh_dict['Bladder'].statistic('D0.3cc').value
# relative volume for absolute dose
# 返回DVHValue类,使用.value得到值,.units得到单位
dvh_dict['Bladder'].relative_volume.statistic('V40Gy')
# dvh.DVHValue(69.89271345552079, '%')
如果出现不同的结构名称,在不建议修改原始的RTstruct文件的情况下,可以考虑使用映射来统一不同的结构名称,修改后的代码如下:
from dicompylercore import dicomparser, dvhcalc
rs_file = r"D:\code\temp\RS.dcm"
rd_file = r"d:\code\temp\RD_PI-V-25F.dcm"
rtss = dicomparser.DicomParser(rs_file)
structures = rtss.GetStructures()
structure = list(structures.values())
for stuc in structures:
print(f"id: {stuc:^3}, name: {structures[stuc]['name']}")
name_mapping = {
'Rectum_1': 'Rectum',
'Rectum_v2': 'Rectum',
'Lung-left_variant': 'Lung Left',
# 更多可能的名称变体和它们的标准名称
}
def get_standard_name(original_name):
return name_mapping.get(original_name, original_name)
# 创建一个空字典来保存每个结构的DVH
dvh_dict = {}
# 遍历structures字典的键
for structure_id in structures:
# 获取结构名称
original_name = structures[structure_id]['name']
standard_name = get_standard_name(original_name)
print(f"Parsering dvh for {standard_name}")
# 使用get_dvh计算DVH并保存到dvh_dict中
dvh_dict[standard_name] = dvhcalc.get_dvh(rs_file, rd_file, structure_id)
# 此时,dvh_dict包含了所有结构的DVH,使用结构名称作为键
print("Done !!!!")
最后是找到的参考文档,似乎是readthedocs这个网站自动生成的。
dicompyler-core Documentation
Documentation
Be sure to check out the latest release for the user manual PDF, which is geared towards the user interface. For power-users, dvha.readthedocs.io contains detailed documentation for backend tools (e.g., if you want to perform queries with python commands).
另外,还有个
DVH Analysis的软件
GitHub - cutright/DVH-Analytics: A DICOM Database Application for Radiation Oncology
也可以批量分析RT dose
导入数据库,
计算DVH
Query 导出CSV
计算EUD,TCP和NTCP