Examples¶
Code snippets demonstrating PyTRiP capabilities.
Example 00 - Cube arithmetic¶
This example demonstrates simple arithmetic on dose- and LET-cubes. Two dose cubes from two fields are summed to generate a new total dose cube.
The two LET-cubes from the two fields are combined to calculate the total dose-averaged LET in the resulting treatment plan. All data are saved to disk.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | """
Simple example of how to do arithmetic on Cube objects in PyTRiP.
"""
import pytrip as pt
# sum two dose cubes, write result:
print("Two half boxes: out.dos")
d1 = pt.DosCube()
d2 = pt.DosCube()
d1.read("box052000.dos")
d2.read("box053000.dos")
d = (d1 + d2)
d.write("out.dos")
# print minium and maximum value found in cubes
print(d1.cube.min(), d1.cube.max())
print(d2.cube.min(), d2.cube.max())
# calculate new dose average LET cube
l1 = pt.LETCube()
l2 = pt.LETCube()
l1.read("box052000.dosemlet.dos")
l2.read("box053000.dosemlet.dos")
l = ((d1 * l1) + (d2 * l2)) / (d1 + d2)
l.write("out.dosemlet.dos")
|
Example 01 - Handling structures¶
This example shows how one can select a region inside a CTX data cube using a VDX file, and perform some manipulation of it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | """
This example shows how to use contours to select volume of interests inside a CTX cube. The VOI is then manipulated.
"""
import pytrip as pt
# first define some paths and other important parameters
ctx_path = "/home/bassler/Projects/CTdata/TST000/TST000000.ctx"
vdx_path = "/home/bassler/Projects/CTdata/TST000/TST000000.vdx"
my_target_voi = "GTV"
# load CT cube
my_ctx = pt.CtxCube()
my_ctx.read(ctx_path)
# load VOIs
my_vdx = pt.VdxCube(my_ctx) # my_vdx is the object which will hold all volumes of interest and the meta information
my_vdx.read(vdx_path) # load the .vdx file
print(my_vdx.get_voi_names()) # show us all VOIs found in the .vdx file
# Select the requested VOI from the VdxCube object
target_voi = my_vdx.get_voi_by_name(my_target_voi)
# get_voi_cube() returns a DosCube() object, where all voxels inside the VOI holds the value 1000, and 0 elsewhere.
voi_cube = target_voi.get_voi_cube()
# Based on the retrieved DosCube() we calculate a three dimensional mask object,
# which assigns True to all voxels inside the Voi, and False elsewhere.
mask = (voi_cube.cube == 1000)
# "The mask object and the CTX cube have same dimensions (they are infact inherited from the same top level class).
# Therefore we can apply the mask cube to the ctx cube and work with the values.
# For instance we can set all HUs to zero within the Voi:
my_ctx.cube[mask] = 0
# or add 100 to all HUs of the voxels inside the mask:
# my_ctx.cube[mask] += 100
# save masked CT to the file in current directory
masked_ctx = "masked.ctx"
my_ctx.write(masked_ctx)
|
Working with dose cubes is fully analogous to the CTX cubes.
Example 02 - TRiP execution¶
In this example, we demonstrate how to actually perform a treatment plan using TRiP98. Most of the lines concern with the setup of TRiP.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | """
This example demonstrates how to load a CT cube in Voxelplan format, and the associated contours.
Then a plan is prepared and optimized using TRiP98.
"""
import os
import logging
import pytrip as pt
import pytrip.tripexecuter as pte
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO) # give some output on what is going on.
# Fist we specify the directory where all our files are:
wdir = "/home/bassler/test"
# In TRiP, the patient "TST000" would typically carry the filename "TST000000"
patient_name = "TST000000"
# so we can construc the paths to the CTX and VDX files like this:
ctx_path = os.path.join(wdir, patient_name + ".ctx")
vdx_path = os.path.join(wdir, patient_name + ".vdx")
# Next we load the CT cube:
c = pt.CtxCube()
c.read(ctx_path)
# And load the contours
v = pt.VdxCube(c)
v.read(vdx_path)
# we may print all contours found in the Vdx file, if we want to
print(v.get_voi_names())
# Ok, we have the Contours and the CT cube ready. Next we must prepare a plan.
# We may choose any basename for the patient. All output files will be named using
# this basename.
plan = pte.Plan(basename=patient_name)
# We need to specify where the kernel files can be found. The location may depend on the ion we
# wnat to treat with. This example is for carbon ions:
plan.ddd_dir = "/home/bassler/TRiP98/base/DATA/DDD/12C/RF3MM/*"
plan.spc_dir = "/home/bassler/TRiP98/base/DATA/SPC/12C/RF3MM/*"
plan.sis_path = "/home/bassler/TRiP98/base/DATA/SIS/12C.sis"
plan.hlut_path = "/home/bassler/TRiP98/base/DATA/HLUT/19990218.hlut"
plan.dedx_path = "/home/bassler/TRiP98/base/DATA/DEDX/20040607.dedx"
plan.working_dir = "/home/bassler/test/" # working dir must exist.
# Set the plan target to the voi called "CTV"
plan.voi_target = v.get_voi_by_name('CTV')
# some optional parameters (if not set, they will all be zero by default)
plan.rifi = 3.0 # 3 mm ripple filter. (This is only for documentaiton, it will not affect the dose optimization.)
plan.bolus = 0.0 # No bolus is applied here. Set this to some value, if you are to optimize very shallow tumours.
plan.offh2o = 1.873 # Some offset mimicing the monitoring ionization chambers and exit window of the beam nozzle.
# Next we need to specify at least one field, and add that field to the plan.
field = pte.Field()
field.basename = patient_name # This name will be used for output filenames, if any field specific output is saved.
field.gantry = 10.0 # degrees
field.couch = 90.0 # degrees
field.fwhm = 4.0 # spot size in [mm]
field.projectile = 'C'
print(field) # We can print all parameters of this field, for checking.
plan.fields.append(field) # attach field to plan. You may attach multiple fields.
# Next, set the flags for what output should be generated, when the plan has completed.
plan.want_phys_dose = True # We want a physical dose cube, "TST000000.dos"
plan.want_bio_dose = False # No biological cube (Dose * RBE)
plan.want_dlet = True # We want to have the dose-averaged LET cube
plan.want_rst = False # Print the raster scan files (.rst) for all fields.
# print(plan) # this will print all plan parameters
te = pte.Execute(c, v) # get the executer object, based on the given Ctx and Vdx cube.
# in the case that TRiP98 is not installed locally, you may have to enable remote execution:
# te.remote = True
# te.servername = "titan.phys.au.dk"
# te.username = "bassler"
# te.password = "xxxxxxxx" # you can set a password, but this is strongly discouraged. Better to exchange SSH keys!
# te.remote_base_dir = "/home/bassler/test"
# depending on the remote .bashrc_profile setup, it may be needed to specify the full path
# for the remote TRiP installation. On some systems the $PATH is set, so this line can be omitted,
# or shortened to just "TRiP98"
# te.trip_bin_path = "/opt/aptg/TRiP98/bin/TRiP98"
te.execute(plan) # this will run TRiP
# te.execute(plan, False) # set to False, if TRiP98 should not be executed. Good for testing.
# requested results can be found in
# plan.dosecubes[]
# and
# plan.letcubes[]
# and they are also saved to working_dir
|