5. Computing Metrics¶
Compute the main reference-free dose metrics and a reference-based geometry comparison using two real aligned studies.
In [1]:
Copied!
from dosemetrics.metrics import conformity, dvh, homogeneity
from dosemetrics.utils import (
compare_structure_geometry,
load_example_study,
plot_dose_slice,
plot_metric_values,
plot_subject_dvhs,
)
dose, structures = load_example_study("longitudinal/time_point_1")
_, later_structures = load_example_study("longitudinal/time_point_2")
ptv = structures["PTV"]
from dosemetrics.metrics import conformity, dvh, homogeneity
from dosemetrics.utils import (
compare_structure_geometry,
load_example_study,
plot_dose_slice,
plot_metric_values,
plot_subject_dvhs,
)
dose, structures = load_example_study("longitudinal/time_point_1")
_, later_structures = load_example_study("longitudinal/time_point_2")
ptv = structures["PTV"]
DVH metrics¶
In [2]:
Copied!
dose_bins, volume_percent = dvh.compute_dvh(dose, ptv, verbose=True)
statistics = dvh.compute_dose_statistics(dose, ptv, verbose=True)
plot_dose_slice(
dose,
structures=structures,
structure_names=["PTV", "Brainstem", "Chiasm"],
contour_colors={"PTV": "white", "Brainstem": "lime", "Chiasm": "cyan"},
cmap="turbo",
);
plot_subject_dvhs(
dose,
structures,
["PTV", "Brainstem", "Chiasm", "Eye_L", "Eye_R"],
color_by_type=False,
);
dose_bins, volume_percent = dvh.compute_dvh(dose, ptv, verbose=True)
statistics = dvh.compute_dose_statistics(dose, ptv, verbose=True)
plot_dose_slice(
dose,
structures=structures,
structure_names=["PTV", "Brainstem", "Chiasm"],
contour_colors={"PTV": "white", "Brainstem": "lime", "Chiasm": "cyan"},
cmap="turbo",
);
plot_subject_dvhs(
dose,
structures,
["PTV", "Brainstem", "Chiasm", "Eye_L", "Eye_R"],
color_by_type=False,
);
PTV DVH: 659 bins, 0.00-65.80 Gy, 0.0-100.0% volume PTV dose statistics (Gy) Mean 60.15 Minimum 48.60 Maximum 65.71 D98 56.57 D95 57.66 D50 60.25 D05 62.32 D02 62.81
Conformity and homogeneity¶
In [3]:
Copied!
prescription = 60.0
quality = {
"Coverage": conformity.compute_coverage(dose, ptv, prescription),
"Spillage": conformity.compute_spillage(dose, ptv, prescription),
"Paddick CI": conformity.compute_paddick_conformity_index(dose, ptv, prescription),
"Homogeneity index": homogeneity.compute_homogeneity_index(dose, ptv),
"Dose CV": homogeneity.compute_dose_homogeneity(dose, ptv),
}
plot_metric_values(quality, title="PTV conformity and homogeneity", ylim=(0, 1.1));
quality
prescription = 60.0
quality = {
"Coverage": conformity.compute_coverage(dose, ptv, prescription),
"Spillage": conformity.compute_spillage(dose, ptv, prescription),
"Paddick CI": conformity.compute_paddick_conformity_index(dose, ptv, prescription),
"Homogeneity index": homogeneity.compute_homogeneity_index(dose, ptv),
"Dose CV": homogeneity.compute_dose_homogeneity(dose, ptv),
}
plot_metric_values(quality, title="PTV conformity and homogeneity", ylim=(0, 1.1));
quality
Out[3]:
{'Coverage': 0.575361500716488,
'Spillage': 0.028841572910177006,
'Paddick CI': 0.5587671700438644,
'Homogeneity index': 0.10346541102749483,
'Dose CV': 0.024713383987545967}
Equivalent uniform dose¶
In [4]:
Copied!
eud = {
"PTV (a=-10)": dvh.compute_equivalent_uniform_dose(dose, ptv, -10),
"Brainstem (a=3)": dvh.compute_equivalent_uniform_dose(dose, structures["Brainstem"], 3),
"Chiasm (a=3)": dvh.compute_equivalent_uniform_dose(dose, structures["Chiasm"], 3),
}
plot_metric_values(eud, title="Equivalent uniform dose", ylabel="Dose (Gy)");
eud
eud = {
"PTV (a=-10)": dvh.compute_equivalent_uniform_dose(dose, ptv, -10),
"Brainstem (a=3)": dvh.compute_equivalent_uniform_dose(dose, structures["Brainstem"], 3),
"Chiasm (a=3)": dvh.compute_equivalent_uniform_dose(dose, structures["Chiasm"], 3),
}
plot_metric_values(eud, title="Equivalent uniform dose", ylabel="Dose (Gy)");
eud
Out[4]:
{'PTV (a=-10)': 59.922055573464604,
'Brainstem (a=3)': 23.07795524730258,
'Chiasm (a=3)': 44.2957090954421}
Reference-based geometric metrics¶
Here the later contours are evaluated against the first time point.
In [5]:
Copied!
compare_structure_geometry(
structures,
later_structures,
["PTV", "Brainstem", "Chiasm", "OpticNerve_L"],
).round(3)
compare_structure_geometry(
structures,
later_structures,
["PTV", "Brainstem", "Chiasm", "OpticNerve_L"],
).round(3)
Out[5]:
| Dice | Jaccard | Volume change (%) | |
|---|---|---|---|
| Structure | |||
| PTV | 0.823 | 0.699 | -13.941 |
| Brainstem | 0.801 | 0.669 | -1.967 |
| Chiasm | 0.012 | 0.006 | 5.063 |
| OpticNerve_L | 0.105 | 0.055 | 42.857 |