Skip to content

Commit f19c519

Browse files
committed
Updated notebook using new package
1 parent 58863db commit f19c519

File tree

2 files changed

+239
-354
lines changed

2 files changed

+239
-354
lines changed

Tutorial.ipynb

Lines changed: 186 additions & 308 deletions
Large diffs are not rendered by default.

ex_wavelet.py

Lines changed: 53 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
This example shows creating and modification of wavelet bases for fluence map compression using portpy
44
55
"""
6+
# import sys
7+
# sys.path.append('..')
68
import portpy.photon as pp
79
from low_dim_rt import LowDimRT
810
import numpy as np
@@ -13,7 +15,7 @@
1315
def ex_wavelet():
1416
# specify the patient data location
1517
# you first need to download the patient database from the link provided in the PortPy GitHub page
16-
data_dir = r'F:\Research\Data_newformat\Python-PORT\data'
18+
data_dir = r'.\data'
1719
# pick a patient from the existing patient list to get detailed info about the patient data (e.g., beams_dict, structures, ...)
1820
patient_id = 'Lung_Patient_2'
1921
# create my_plan object for the planner beams_dict and select among the beams which are 30 degrees apart
@@ -34,70 +36,75 @@ def ex_wavelet():
3436
'max_dose_gy': rind_max_dose[4]}]
3537
my_plan.add_rinds(rind_params=rind_params)
3638

37-
# create cvxpy problem using the clinical criteria
38-
prob = pp.CvxPyProb(my_plan, opt_params={'smoothness_weight': 10})
39-
40-
# run imrt fluence map optimization using cvxpy and one of the supported solvers and save the optimal solution in sol
41-
# CVXPy supports several opensource (ECOS, OSQP, SCS) and commercial solvers (e.g., MOSEK, GUROBI, CPLEX)
42-
# For optimization problems with non-linear objective and/or constraints, MOSEK often performs well
43-
# For mixed integer programs, GUROBI/CPLEX are good choices
44-
# If you have .edu email address, you can get free academic license for commercial solvers
45-
# we recommend the commercial solver MOSEK as your solver for the problems in this example,
46-
# however, if you don't have a license, you can try opensource/free solver SCS or ECOS
47-
# see https://www.cvxpy.org/tutorial/advanced/index.html for more info about CVXPy solvers
48-
# To set up mosek solver, you can get mosek license file using edu account and place the license file in directory C:\Users\username\mosek
49-
prob.solve(solver='MOSEK', verbose=True)
50-
sol = prob.get_sol()
39+
# With no quadratic smoothness
40+
prob = pp.CvxPyProb(my_plan, smoothness_weight=0)
41+
prob.solve(solver='MOSEK', verbose=False)
42+
sol_no_quad_no_wav = prob.get_sol()
5143

52-
# run IMRT fluence map optimization using a low dimensional subspace for fluence map compression
53-
prob = pp.CvxPyProb(my_plan, opt_params={'smoothness_weight': 10})
5444
# creating the wavelet incomplete basis representing a low dimensional subspace for dimension reduction
5545
wavelet_basis = LowDimRT.get_low_dim_basis(my_plan.inf_matrix, 'wavelet')
5646
# Smoothness Constraint
5747
y = cp.Variable(wavelet_basis.shape[1])
5848
prob.constraints += [wavelet_basis @ y == prob.x]
5949
prob.solve(solver='MOSEK', verbose=False)
60-
sol_low_dim = prob.get_sol()
50+
sol_no_quad_with_wav = prob.get_sol()
51+
52+
# create cvxpy problem using the clinical criteria
53+
prob = pp.CvxPyProb(my_plan, smoothness_weight=10)
54+
# run IMRT fluence map optimization using a low dimensional subspace for fluence map compression
55+
prob.solve(solver='MOSEK', verbose=False)
56+
sol_quad_no_wav = prob.get_sol()
6157

62-
# With no quadratic smoothness
63-
prob = pp.CvxPyProb(my_plan, opt_params={'smoothness_weight': 0})
64-
# creating the wavelet incomplete basis representing a low dimensional subspace for dimension reduction
65-
wavelet_basis = LowDimRT.get_low_dim_basis(my_plan.inf_matrix, 'wavelet')
6658
# Smoothness Constraint
6759
y = cp.Variable(wavelet_basis.shape[1])
6860
prob.constraints += [wavelet_basis @ y == prob.x]
6961
prob.solve(solver='MOSEK', verbose=False)
70-
sol_low_dim_only = prob.get_sol()
62+
sol_quad_with_wav = prob.get_sol()
63+
64+
pp.save_plan(my_plan, plan_name='my_plan', path=r'C:\temp')
65+
pp.save_optimal_sol(sol_no_quad_no_wav, sol_name='sol_no_quad_no_wav', path=r'C:\temp')
66+
pp.save_optimal_sol(sol_no_quad_with_wav, sol_name='sol_no_quad_with_wav', path=r'C:\temp')
67+
pp.save_optimal_sol(sol_quad_no_wav, sol_name='sol_quad_no_wav', path=r'C:\temp')
68+
pp.save_optimal_sol(sol_quad_with_wav, sol_name='sol_quad_with_wav', path=r'C:\temp')
69+
70+
# my_plan = pp.load_plan(plan_name='my_plan', path=r'C:\temp')
71+
# sol_no_quad_no_wav = pp.load_optimal_sol(sol_name='sol_no_quad_no_wav', path=r'C:\temp')
72+
# sol_no_quad_with_wav = pp.load_optimal_sol(sol_name='sol_no_quad_with_wav', path=r'C:\temp')
73+
# sol_quad_no_wav = pp.load_optimal_sol(sol_name='sol_quad_no_wav', path=r'C:\temp')
74+
# sol_quad_with_wav = pp.load_optimal_sol(sol_name='sol_quad_with_wav', path=r'C:\temp')
7175

7276
# plot fluence 3D and 2D
73-
fig, ax = plt.subplots(1, 3, figsize=(12, 12), subplot_kw={'projection': '3d'})
74-
pp.Visualize.plot_fluence_3d(sol=sol, beam_id=0, ax=ax[0])
75-
pp.Visualize.plot_fluence_3d(sol=sol_low_dim, beam_id=0, ax=ax[1])
76-
pp.Visualize.plot_fluence_3d(sol=sol_low_dim_only, beam_id=0, ax=ax[2])
77-
plt.show()
77+
fig, ax = plt.subplots(1, 2, figsize=(18, 6), subplot_kw={'projection': '3d'})
78+
fig.suptitle('Without Quadratic smoothness')
79+
pp.Visualize.plot_fluence_3d(sol=sol_no_quad_no_wav, beam_id=37, ax=ax[0], title='Without Wavelet')
80+
pp.Visualize.plot_fluence_3d(sol=sol_no_quad_with_wav, beam_id=37, ax=ax[1], title='With Wavelet')
7881

79-
fig, ax = plt.subplots(1, 3, figsize=(12, 12))
80-
pp.Visualize.plot_fluence_2d(sol=sol, beam_id=0, ax=ax[0])
81-
pp.Visualize.plot_fluence_2d(sol=sol_low_dim, beam_id=0, ax=ax[1])
82-
pp.Visualize.plot_fluence_2d(sol=sol_low_dim_only, beam_id=0, ax=ax[2])
82+
fig, ax = plt.subplots(1, 2, figsize=(18, 6), subplot_kw={'projection': '3d'})
83+
fig.suptitle('With Quadratic smoothness')
84+
pp.Visualize.plot_fluence_3d(sol=sol_quad_no_wav, beam_id=37, ax=ax[0], title='Without Wavelet')
85+
pp.Visualize.plot_fluence_3d(sol=sol_quad_with_wav, beam_id=37, ax=ax[1], title='With Wavelet')
8386
plt.show()
87+
8488
# plot DVH for the structures in the given list. Default dose_1d is in Gy and volume is in relative scale(%).
85-
structs = ['PTV', 'ESOPHAGUS', 'HEART', 'CORD']
86-
fig, ax = plt.subplots(figsize=(12, 12))
87-
ax = pp.Visualize.plot_dvh(my_plan, sol=sol, structs=structs, ax=ax)
88-
ax = pp.Visualize.plot_dvh(my_plan, sol=sol_low_dim, structs=structs, ax=ax)
89-
pp.Visualize.plot_dvh(my_plan, sol=sol_low_dim_only, structs=structs, ax=ax)
90-
plt.show()
91-
# plot 2d axial slice for the given solution and display the structures contours on the slice
92-
fig, ax = plt.subplots(1, 3, figsize=(12, 12))
93-
pp.Visualize.plot_2d_dose(my_plan, sol=sol, slice_num=40, structs=['PTV'], ax=ax[0])
94-
pp.Visualize.plot_2d_dose(my_plan, sol=sol_low_dim, slice_num=40, structs=['PTV'], ax=ax[1])
95-
pp.Visualize.plot_2d_dose(my_plan, sol=sol_low_dim_only, slice_num=40, structs=['PTV'], ax=ax[2])
89+
structs = ['PTV', 'ESOPHAGUS', 'HEART', 'CORD', 'LUNG_L', 'LUNG_R']
90+
fig, ax = plt.subplots(1, 2, figsize=(20, 8))
91+
ax0 = pp.Visualize.plot_dvh(my_plan, sol=sol_no_quad_no_wav, structs=structs, style='solid', ax=ax[0])
92+
ax0 = pp.Visualize.plot_dvh(my_plan, sol=sol_no_quad_with_wav, structs=structs, style='dashed', ax=ax0)
93+
fig.suptitle('DVH comparison')
94+
ax0.set_title('Without Quadratic smoothness \n solid: Without Wavelet, Dash: With Wavelet')
95+
# plt.show()
96+
# print('\n\n')
97+
98+
# fig, ax = plt.subplots(figsize=(12, 8))
99+
ax1 = pp.Visualize.plot_dvh(my_plan, sol=sol_quad_no_wav, structs=structs, style='solid', ax=ax[1])
100+
ax1 = pp.Visualize.plot_dvh(my_plan, sol=sol_quad_with_wav, structs=structs, style='dashed', ax=ax1)
101+
ax1.set_title('With Quadratic smoothness \n solid: Without Wavelet, Dash: With Wavelet')
96102
plt.show()
103+
97104
# visualize plan metrics based upon clinical criteria
98-
pp.Visualize.plan_metrics(my_plan, sol=sol)
99-
pp.Visualize.plan_metrics(my_plan, sol=sol_low_dim)
100-
pp.Visualize.plan_metrics(my_plan, sol=sol_low_dim_only)
105+
pp.Visualize.plan_metrics(my_plan,
106+
sol=[sol_no_quad_no_wav, sol_no_quad_with_wav, sol_quad_no_wav, sol_quad_with_wav],
107+
sol_names=['no_quad_no_wav', 'no_quad_with_wav', 'quad_no_wav', 'quad_with_wav'])
101108

102109

103110
if __name__ == "__main__":

0 commit comments

Comments
 (0)