Important

This is a work in progress. Things are changing at a fast pace! It definitely contains bugs! Not suitable for medical use!

# Use case examples¶

rteval streamlines the extraction of useful radiotherapy plan parameters from DICOM data files (RTDOSE, RTPLAN, RTSTRUCT), such as point dose statistics, clinical dose constraints, arbitrary dose-volume data, contour coordinates, etc. It is easily scriptable and allows for the analysis of one’s department plans. Either on an individual plan basis or as a whole.

Its syntax is evolving and currently looks like this:

% ./rteval.py
Syntax: rteval.py load <RD file> <subcommand>
Available subcommands: ['anonymize', 'beams', 'by', 'cn', 'complexity', 'constraints',
'contour', 'diff', 'dv', 'dvh', 'pointds', 'prescription', 'structs', 'tags', 'vd', 'volume']
%


Each subcommand has its own syntax, e.g.:

% ./rteval.py load ./443-18/RD.dcm volume
Syntax: volume <structure 1> <structure 2> ...
{"volume": ""}
%


When a structure name is required, it may be given as a regular expression. E.g. To get a list of plan’s structure set:

% ./rteval.py load ./443-18/RD.dcm structs .*
{"structs": ["BODY", "Cochlea R PRV", "Cochlea R", "Cochlea L PRV", "Cochlea L",
"Brainstem PRV", "Brainstem", "Brain", "Area 51", "CTV 6996", "CTV 5445", "CTV 5940",
"CTV 6600", "CTV Nasal", "Lens R", "CTV Nasopharynx", "Esophagus", "Optic Chiasm PRV",
"Optic Nerv L", "Optic Nerv L PRV", "Optic Nerv R", "Optic Nerv R PRV", "Oral Cavity",
"Parotid L", "Parotid R", "PTV 5445", "oldPTV 5940", "oldPTV 6600", "PTV 6996",
"PTV LN L", "Eye L", "Eye R", "GTV N", "GTV T MRI inbra1", "GTV T MRI inbrai",
"GTV T PET", "CTV LN L", "CTV LN R", "CTV N", "Larynx", "Lens L", "Lens L PRV",
"Lens R PRV", "Optic Chiasm", "PTV LN R", "SMG L", "SMG R", "Spine", "Spine PRV",
"Trachea", "Bolus", "PTV 6600 New", "PTV 5445 New", "PTV 5940 New", "PTV 6303 New",
"PTV patch", "NS_NormalTissue", "Patch", "PTV 5940", "PTV 6600", "PTV 6303",
"PTV1-2", "PTV3-4", "PTV2-3", "PTV4-5"]}
%


To get a list of all structures containing the string “ctv”:

% ./rteval.py load ./443-18/RD.dcm structs ctv
{"structs": ["CTV 6996", "CTV 5445", "CTV 5940", "CTV 6600", "CTV Nasal",
"CTV Nasopharynx", "CTV LN L", "CTV LN R", "CTV N"]}
%


To get a list of all structures containing the string ‘parotid’ or the string ‘smg’:

% ./rteval.py load ./443-18/RD.dcm structs 'parotid|smg'
{"structs": ["Parotid L", "Parotid R", "SMG L", "SMG R"]}
%


Get the volume of some structures:

% ./rteval.py load ./443-18/RD.dcm volume 'parotid|trachea|esophagus|body'
{"volume": {"BODY": "12906.58", "esophagus": "13.11", "parotid_l": "35.22",
"parotid_r": "31.48", "trachea": "31.47"}}
%


## Dose constraints report for organs at risk¶

The following invocation will list all the organs at risk and the values of the respective constraints. The output is in JSON format and the structure names are fixed regardless of their original names in the structure set. This is done in order to facilitate subsequent statistical processing. Hence, Parotid R, R Parotid, Parotid Right, Right Parotid, Parotid_R, R_Parotid will all become parotid_r.

The nice thing about this feature is that it discovers automatically all known (to rteval) dose constraints:

% ./rteval.py load ./443-18/RD.dcm constraints
{"constraints": {"brainstem": {"Max": "50.36"}, "cochlea_l": {"Mean": "26.78"},
"cochlea_r": {"Mean": "32.67"}, "esophagus": {"V35": "62.57", "V50": "13.91",
"V70": "0.00", "Mean": "35.79"}, "eye_l": {"Mean": "18.31", "Max": "39.15"},
"eye_r": {"Mean": "20.53", "Max": "42.88"}, "larynx": {"Mean": "41.51"}, "lens_l":
{"Max": "11.10"}, "lens_r": {"Max": "11.58"}, "optic_chiasm": {"Max": "47.10"},
"optic_nerv_l": {"Max": "51.11"}, "optic_nerv_r": {"Max": "51.70"}, "oral_cavity":
{"Mean": "32.61"}, "parotid_l": {"Mean": "45.30"}, "parotid_r": {"Mean": "24.94"},
"smg_l": {"Mean": "64.44"}, "smg_r": {"Mean": "51.19"}, "spine": {"Max": "42.46"},
"trachea": {"Mean": "37.43"}}}
%


Or, in pretty print format:

{
"constraints": {
"brainstem": {
"Max": "50.36"
},
"cochlea_l": {
"Mean": "26.78"
},
"cochlea_r": {
"Mean": "32.67"
},
"esophagus": {
"Mean": "35.79",
"V35": "62.57",
"V50": "13.91",
"V70": "0.00"
},
"eye_l": {
"Max": "39.15",
"Mean": "18.31"
},
...
}


## Use categorical variables to group results¶

In many cases one wants to group some measured quantity based on a categorical variable, e.g. measure homogeneity index or conformation number and group the results by the dosimetrist that did the planning or the physician that did the contouring/prescription. This is done by the by subcommand:

% ./rteval.py load ./443-18/RD.dcm by
Available by clauses: ['operator', 'patient', 'patientID', 'physician', 'plan',
'reviewer', 'studyDate', 'studyDay']
%


For instance, the following command will calculate the conformation number for the 95% isodose of the prescribed dose and attach to the results the reviewer and the physician:

% ./rteval.py load ./1010-16/RD.1.2.246.352.71.7.510151505849.233655.20160721142230.dcm \
> by reviewer physician cn auto
{"by": {"reviewer": "maria^papadopoulou", "physician": "kamperis^efstathios"},
"cn": {"95.0": "0.617"}}
%


The by subcommand is of great value when evaluating many plans at once.

## Batch process of plans¶

Since rteval is merely a Python script, applying it to a set of plans is straightforward. For instance, the following shell command will list the leaf aperture complexities for all arcs for all plans in the ~/plan-files directory:

% for f in ~/plan-files/*/RD*.dcm; do ./rteval.py load "$f" by patientID complexity; done {"by": {"patientID": "101-16"}, "complexity": {"arc1": "0.642", "arc2": "0.702"}}, {"by": {"patientID": "332-17"}, "complexity": {"arc1": "0.501", "arc2": "0.562"}}, {"by": {"patientID": "443-18"}, "complexity": {"arc1": "0.674", "arc2": "0.626"}}, {"by": {"patientID": "762-17"}, "complexity": {"arc1": "0.556", "arc2": "0.820"}}  ## Point dose statistics¶ To print point dose statistics for all structures along with a header for each column: % ./rteval.py load ./443-18/RD.dcm pointds header all Structure Min Max Mean D2 D98 body 00.00 76.19 17.54 65.39 00.21 brainstem_prv 18.67 55.11 34.44 50.46 21.10 brainstem 19.90 50.36 33.98 48.12 22.00 brain 00.69 63.80 13.75 47.82 00.96 cochlea_r_prv 28.06 44.25 33.64 41.46 28.91 cochlea_r 29.97 35.68 32.67 35.17 30.55 cochlea_l_prv 23.29 43.04 28.19 38.17 24.10 cochlea_l 24.99 29.93 26.78 29.10 25.23 ctv_6996 62.35 76.19 73.67 75.41 71.21 ctv_5445 04.34 76.19 61.73 74.60 49.92 ctv_5940 04.34 76.19 63.92 74.73 47.13 ctv_6600 57.18 76.19 72.67 75.39 62.07 esophagus 06.22 56.87 35.79 55.03 07.65 eye_l 08.95 39.15 18.31 32.73 09.40 eye_r 08.62 42.88 20.53 35.63 09.55 ...  ## Export DVH data¶ To export dose-volume data in (dose bin, volume) pairs you would invoke the dvh subcommand with the paired argument. The regular expression .* matches all the plan’s structures: % ./rteval.py load ./443-18/RD.dcm dvh paired '.*' > dvh.data %  These data could, then, be plotted with e.g. Mathematica: jd = Import["dvh.data", "JSON"]; organs = jd[[All, 2, All, 1]][[1]]; getDVH[organ_] := jd[[All, 2, organ, 2, 1(*dv*), 2]][[1]] ListPlot[ParallelTable[getDVH@k, {k, 1, Length@organs}], Joined -> True, InterpolationOrder -> 1, Frame -> {True, True, False, False}, FrameLabel -> {"Dose [Gy]", "% Volume"}, PlotLegends -> Table[organs[[k]], {k, 1, Length@organs}], PlotRangePadding -> {0, 0}]  Depending on the software you will be using to process the dvh data, it may be easier to export all dose bins separately from volume data. I.e., to export them as [d1, d2, d3, ...], [v1, v2, v3, ...] instead of [(d1, v1), (d2, v2), (d3, v3), ...]. If this is the case you’d use: % ./rteval.py load ./443-18/RD.dcm dvh '.*' > dvh.data %  And then plot them with R like: library(jsonlite) jd <- jsonlite::read_json('dvh.data', flatten=T) f <- function(organ) { df <- data.frame( unlist(jd$dvh[[organ]]$dose), unlist(jd$dvh[[organ]]\$vol)
);
names(df) <- c('dose', 'vol');
return(df)
}
par(mfrow=c(3,3))
for (i in 1:9) { plot(f(i), type='l', col='red', main=organs[[i]]) }


## Export contour coordinates¶

In order to export the coordinates of the points defining a structure, say mandible:

% ./rteval.py load ./332-17/RD.dcm contour Mandible > mandible.coords


Then you could do whatever you’d feel like with them, e.g. plot them in 3D space with Mathematica:

struct = Import["~/git-repos/rteval/rteval/mandible.coords", "JSON"]
struct = Flatten[struct[[All, 2, 1, 2]], 1]
Grid[Partition[#, 3] &@
(ListPointPlot3D[struct, PlotLabel -> #, Axes -> False,
AspectRatio -> Full, PlotStyle -> {Red}, Ticks -> None,
Boxed -> False, ViewPoint -> #] & /@
{Above, Front, Left, Right, {Left, Top}, {Right, Top}})]


## Compare two plans against each other¶

rteval enables the comparison of two plans. The syntax is the following:

% ./rteval.py load ./443-18/RD.dcm diff
Syntax: diff <filename> [pretty]
{"diff": ""}
%


So the if we’d like to compare plan 443-18/RD.dcm with 332-17/RD.dcm we’d write:

% ./rteval.py load ./443-18/RD.dcm diff ./332-17/RD.dcm pretty
Structure       Constr    V1     V2     dV     %
esophagus       V35     62.57  57.18  -5.39  -8.61
esophagus       V50     13.91  18.93   5.02  36.09
esophagus       V70      0.00   0.00   0.00   0.00
esophagus       Mean    35.79  34.49  -1.30  -3.63
larynx          Mean    41.51  41.18  -0.33  -0.79
parotid_l       Mean    45.30  24.41 -20.89 -46.11
parotid_r       Mean    24.94  23.99  -0.95  -3.81
spine           Max     42.46  41.37  -1.09  -2.57
trachea         Mean    37.43  33.56  -3.87 -10.34
%


The optional argument pretty determines whether the output shall be in plain text columnar format or in JSON format. The comparison includes only differences in dose constraints, but in the future it will contain virtually all metrics that rteval can calculate.

## Calculate and visualize the complexities of beam arcs¶

rteval can calculate the complexity of a plan for every beam and also it may report the individual “complexities” at each control point:

% ./rteval.py load ./443-18/RD.dcm complexity simple
{"complexity": {"simple": {"arc1": "0.674", "arc2": "0.626"}}},
% ./rteval.py load ./443-18/RD.dcm complexity simple verbose
{"complexity": {"simple": {"arc1": [0.00211, 0.00428, 0.0046, 0.00435, ...]}}}


Then, it’s easy to produce visually appealing plots, like:

json = Import["~/git-repos/rteval/rteval/arcs.json", "JSON"];
arc1 = json[[All, 2, 1, 2, 1, 2]]
arc2 = json[[All, 2, 1, 2, 2, 2]]
dat1 = Table[{2 k Pi/180, arc1[[k]]}, {k, 1, Length@arc1}];
dat2 = Table[{2 k Pi/180, arc2[[k]]}, {k, 1, Length@arc2}];
ListPlot[{arc1, arc2}, Joined -> True, InterpolationOrder -> 0,
Frame -> {True, True, False, False}, FrameLabel -> {"Theta(rads)", "Arc Complexity"},
PlotRange -> All, PlotLegends -> {"Arc1", "Arc2"}, ImageSize -> 600]


Or, a polar plot:

# Classes¶

## anonymize¶

class anonymize.DicomAnonymizer(dicomFilePath)

A class for anonymizing DICOM files.

assertAnonymization()

Confirms that the DICOM file was indeed anonymized.

doAnonymization()

Performs the anonymization of the respective DICOM file. The result is written to a new file named after the old one plus the suffix _anon.

listAnonymizableDicomTags()

Lists all DICOM tags that this anonymizer can erase.

## cbct¶

class cbct.CBCT(dicomFilePath)

A class for discovering Varian CBCT files and assembling them into the right series ordered by their z- coordinate. This is NOT a robust generic class. It serves the purposes of my PhD Thesis.

checkIfInOrder()

Prints a grid with the CBCT images of the ‘first’ (any, really) CBCT series.

scanDirectory()

Scan directory for Varian CBCT dicom files and assemble them into the respective series with correct z ordering.

## cmdprocessor¶

class cmd_processor.CmdProcessor(plan)

This is a class to process the commands that the user enters.

filterStructs(args)

It treats args a regular expression against which matches the structures of the structure set.

Parameters: args[0] – A regular expression matching structures, e.g. '.*' to match all structures in the structure set.

If args is empty, [] is returned.

processAnonymizeDicomFile()

Anonymizes the RD dicom file.

processBeams(args)
processBy(args)

Syntax: … by <clauses> E.g.

>>> ./rteval.py load rd.dcm cn 'PTV 6996' 95 by reviewer studydate


Will print the conformation number of structure PTV 6996 and will attach the reviewer of the plan and the date it was created to the result.

processCN(args)

Syntax: cn <structure regexp> <ref isodose 1> <ref isodose 2> ... Syntax: cn auto

processComplexity(args)

It will return the complexity scores for each beam in the plan.

Parameters: Metric – Which complexity metric to calculate. Verbose – If set, the complexity scores calculated at each control point will be returned. Differential – The difference of complexity between consecutive control points will be returned.
processConstraints(arg, isRegExp=True)

Given a regular expression matching structure(s) in the structure set, print their dose constraints.

Parameters: arg[0] – If isRegExp set to True, then this is to be interpreted as a regular expression matching structures, e.g. '.*' to match all structures in the structure set. If set to False then arg[0] is treated as a list of structure names.
E.g.
>>> p = plan.Plan('/path/to/rd_file')
>>> p.cmdProcessor.processConstraints('paro', isRegExp=True)
{'parotid_l': {'Mean': '45.30'}, 'parotid_r': {'Mean': '24.94'}}
>>> e.cmdProcessor.processConstraints(
['Parotid L', 'Parotid R', 'Spine'], isRegExp=False)
{'parotid_l': {'Mean': '45.30'}, 'parotid_r': {'Mean': '24.94'},
'spine': {'Max': '42.46'}}

processContour(args)

Given a regular expression matching structure(s) in the structure set, print the contour coordinates for every CT slice.

Parameters: args[0] – A regular expression matching structures, e.g. '.*' to match all structures in the structure set.
processDVHData(args)

Given a regular expression matching structure(s) in the structure set, print their dose-volume data.

Parameters: paired – If paired is set, the return object will be of the form [(d1, v1), (d2, v2), ...]. Otherwise, it will be of the form [(d1, d2, ...), (v1, v2, ...)].
processDoseVolume(args)

Given a regular expression matching structure(s) in the structure set, print the dose that covers at least <vol 1> <vol 2> ....

Parameters: args[0] – A regular expression matching structures, e.g. '.*' to match all structures in the structure set. args[1 – ]: The list of volume percentages.
E.g.:
>>> p = plan.Plan('/path/to/rd_file')
>>> p.cmdProcessor.processDoseVolume(['paro', 50])
{'Parotid L': {50: '42.57'}, 'Parotid R': {50: '18.50'}}

processDumpDose()

Print the dose distribution from the RD file.

processEAR(args)

Given a regular expression matching structure(s) in the structure set print the EARs (Excessive Absoulte Risk values) in Grays for the respective structure(s).

Parameters: args[0] – The mathematical model to use when estimating OED. Possible values include linear, exp and frac, for linear, exponential and exponential with fractionation model, respectively. args[1] – A regular expression matching structures, e.g. '.*' to match all structures in the structure set. args[2] – Age at exposure. args[3] – Age attained.
processListCT(args)

Print the UIDs of the CT files associated with this plan

Parameters: args[0] – If set to pretty, the result will be printed in columnar format, rather than in JSON.
processListMatchingRules()

Print the matching rules for structures. Example output: ‘spine matched by: cord spinal_canal spinal_cord spinalcanal spinalcord …’

processNTCP(args)

Given a regular expression matching structure(s) in the structure set, print their normal tissue complication probability (if applicable).

processOED(args)

Given a regular expression matching structure(s) in the structure set print the OEDs (Organ Equivalent Dose values) in Grays for the respective structure(s).

Parameters: args[0] – The mathematical model to use when estimating OED. Possible values include linear, exp and frac, for linear, exponential and exponential with fractionation model, respectively. args[1] – A regular expression matching structures, e.g. '.*' to match all structures in the structure set.
processOVH(args)

Given a regular expression matching structure(s) in the structure set and a structure representing the tumor volume, print the distance of every voxel of every structure to the tumor volume.

Parameters: args[0] – A regular expression matching structures, e.g. '.*' to match all structures in the structure set. args[1] – The structure representing the tumor, e.g. PTV 5940. args[2] – The grid size, e.g. 100 will create a 100x100x100 grid.
processPlanDiff(args)

Print the differences in constraints for two plans.

Parameters: args[0] – The second plan to be used in the comparison (the first is the one we have already loaded). args[1] – If set to pretty, the result will be printed in columnar format, rather than in JSON.
E.g.
>>> p = rteval.Plan('/path/to/rd_file')
>>> p.cmdProcessor.processPlanDiff(['/path/to/rd_file', 'pretty'])
Structure       Constr    V1     V2     dV     %
brainstem       Max     50.38  50.38   0.00   0.00
cochlea_l       Mean    26.78  26.78   0.00   0.00

processPointDoseStatistics(args)

Given a regular expression matching structure(s) in the structure set, print their point dose statistics (Min, Max, Mean, D2, D98).

Parameters: args[0] – A regular expression matching structures, e.g. '.*' to match all structures in the structure set.
E.g.
>>> p = rteval.Plan('/path/to/rd_file')
>>> p.cmdProcessor.processPointDoseStatistics(['spine'])
{'spine': {'Min': '2.50', 'Max': '42.46', 'Mean': '31.38',
'D2': '40.37', 'D98': '3.05'},
'Spine PRV': {'Min': '2.05', 'Max': '49.07', 'Mean': '31.22',
'D2': '44.82', 'D98': '2.54'}}

processPrescription()

Prints the prescription dose of the plan.

processSoftwareVersions()

Prints the Software Versions.

processStructures(arg)

Given a regular expression, print all matching structure(s) in the structure set.

Parameters: arg[0] – A regular expression matching structures, e.g. '.*' to match all structures in the structure set.
E.g.
>>> p = plan.Plan('/path/to/rd_file')
>>> p.cmdProcessor.processStructures(['paro'])
['Parotid L', 'Parotid R']

processTags(arg)

Prints DICOM tags in RTDOSE, RTPLAN or RTSTRUCT files.

Parameters: arg[0] – One of the values: rd, rp or rs.
processTotalMUs()

Print the total number of monitor units for all beams.

processVolumeDose(args)

Given a regular expression matching structure(s) in the structure set, print the volume that receives at least <isodose 1> <isodose 2> ....

Parameters: args[0] – A regular expression matching structures, e.g. '.*' to match all structures in the structure set. args[1 – ]: A list with isodoses.
E.g.:
>>> e = plan.Plan('/path/to/rd_file')
>>> e.cmdProcessor.processVolumeDose(['paro', 30, 50])
{'Parotid L': {30: '34.04', 50: '21.73'}, 'Parotid R': {30: '13.85', 50: '7.91'}}

processVolumeOfStructure(args)

Given a regular expression matching structure(s) in the structure set, print the volume of each one of them.

Parameters: args[0] – A regular expression matching structures, e.g. '.*' to match all structures in the structure set.
E.g.:
>>> e = plan.Plan('/path/to/rd_file')
>>> e.cmdProcessor.processVolumeOfStructure(['paro'])
{'parotid_l': '35.22', 'parotid_r': '31.48'}


## complexity¶

class complexity.Complexity(rtplan, beam)
calcArea(aleafs, bleafs)

Calculates the area defined by the leafs.

calcComplexity()

Calculates the complexity for this beam.

Returns: A tuple (x, y), where x is the total complexity for this beam and y is a list with the complexities of each individual CP.
calcComplexityAtCP(cp)

Calculates the complexity at the cp control point.

calcDifferentialComplexity()

Calculates the differential of complexity for this beam.

$\text{Differential} = \left|\text{Complexity}_{i+1} - \text{Complexity}_{i}\right|$

For all $$i$$.

Returns: A tuple (x, y), where x is the total differential complexity for this beam and y is a list with the differential complexities of each individual CP.
calcLeafEndPerimeter(aleafs, bleafs)

Calculates the perimeter of the area defined by the leafs.

calcLeafSidePerimeter(aleafs, bleafs)

Calculates the perimeter of the leaf sides only. I.e., it does not include the perimeter due to leafs width.

getComplexityMetric(metricName)
getJawLeafPos(cp)

Returns the leaf positions for the cp control point.

Note: [0x300a, 0x11c] is the Leaf/Jaw Positions attribute.

getLeafWidth(leaf)

Returns the leaf width for leaf.

In some linacs the leaf width is smaller at the center. E.g. in Varian Clinac DHX the collimator has 120 MLC (field size 40x40 cm), central 20 cm of field - 5mm leaf width, outer 20 cm of field - 10 mm leaf width.

getMonitorUnits()

Returns a list with the number of monitor units for every control point. E.g. [0, 2.45, 2.60, 2.60, 2.53, 1.63, 1.54, 1.20, …]

The MUs are calculated via the following formula: MU = meterset weight * beam meterset / final cumulative meterset weight

getNumberOfLeafs()

Returns the number of leafs.

In Varian Clinac DHX the collimator has 120 leafs.

getTotalMonitorUnits()

Returns the total number of Monitor Units for this beam.

## constraints¶

class constraints.Constraint(structure, differentialDVH)

A class for calculating the values of clinical constraints for organs at risk. The constraints are picked automatically, e.g. if the structure is Spinal Cord then automatically maximum point dose is returned. If the structure is Lung then automatically Mean dose, V5, V13, V20 and V30 are returned.

Which constraint is returned for every organ, is specified in the spec_constraints.py file.

Parameters: structure – The name of the structure, e.g. Spinal Cord. differentialDVH – The associated differential Dose-Volume Histogram.
calcEAR(model, prescribedDose, dosePerFraction, agex, agea)

Returns the EAR (Excess Absolute Risk) using model.

calcMaxDose()

Returns the max point dose reading it from the DVH DICOM data.

calcMeanDose()

Returns the mean dose reading it from the DVH DICOM data.

calcNTCP()

Returns the NTCP calculated via the LKB model.

calcOED(model, prescribedDose, dosePerFraction)

Returns the OED (Organ Equivalent Dose) using model.

calcV(constraints)

Returns Dose Volume constraints.

Constraints are given as V_D values, e.g., [20, 40, ...]. Corresponding to (V20, V40, ...). If a D value is given that exceeds the global Dmax then 0 is returned.

getStandardNameOfStructure(structure)

Returns the standard name for structure.

Given a structure name, e.g. Right Parotid, return its standard name, e.g. parotid_r. If none found, return the normalized version of the argument itself, i.e., right_parotid. This is useful for aggregating data for later statistical evaluation.

matchConstraint()

Returns a list with matched constraints.

matchOrganClass()

Returns the organ class for this structure.

## direval¶

class direval.DirectoryEvaluator(rootDirectory, fileTasks)

A class for traversing a directory hierarchy in order to discover RTDOSE dicom files. Once found, the files are processed with rteval in parallel.

The findWorker() method will find all RTDOSE dicom files under the root directory. For each one of them it will execute the rteval.main() method and it will pass whatever argument was given to us. E.g.:

./direval.py /temp constraints '.*'


Will look for RTDOSE dicom files under /temp and for each one of them it will call:

./rteval.py load <file> constraints '.*'

evalWorker()
findWorker(rlist)
startEval()
direval.main()

## dose_prescription¶

class dose_prescription.DosePrescription(plan, doseref=None)

A class for inferring dose prescription levels in plans with a simultaneous integrated boost (SIB).

Parameters: doseref – A list of predetermined dose levels, likely to be department specific, to which the inferred doses are rounded. If none given then assume [5280, 5445, 5940, 6600, 6996].
getMaxPrescribedDose()

This can be retrieved either by Target Prescription Dose if the prescription was done via a structure with Dose Reference Type TARGET or by Delivery Maximum Dose if the structure is of ORGAN_AT_RISK type. The search is done across all beams.

Returns: A tuple (x, y) with x being the maximum prescribed dose and y the structure from which this dose level was inferred.
inferSIBDoses()

Use heuristics to infer dose prescription levels in plans with a simultaneous integrated boost (SIB). It may return inaccurate results.

Returns: A list of (x, y) tuples with x being some PTV and y being the inferred dose level (rounded to the closest predetermined dose level).E.g.: >>> import rteval, dose_prescription as dp >>> p = plan.Plan('/path/to/rd_file') >>> print(dp.inferSIBDoses(e.plan)) [('PTV 5445', 5445), ('PTV1-2', 5445), ('PTV LN L', 5445), ('PTV LN R', 5445), ('PTV 5940', 5940), ('PTV3-4', 5940), ('PTV2-3', 5940), ('PTV 6600', 6600), ('PTV 6996', 6996)] 
plotdDVHPeaks()

Plot differential DVH along with the detected peaks corresponding to the dose levels (rounded to the closest predetermined dose level).

This method is meant to be used for debugging purposes.

## mydvh¶

class mydvh.DVH(differentialDVH, structure, prescribedDose)

This is a wrapper class around the Pydicom DVH class.

Parameters: differentialDVH – The Pydicom DVH object corresponding to a differential DVH. structure – The structure this DVH is associated with. prescribedDose – The maximum prescribed dose.
differentialDVH

The Pydicom DVH object.

structure

The name of the structure associated with this DVH.

absCumulative()

Returns the absolute cumulative DVH.

calcRelCumulative()

Calculates the relative cumulative DVH.

fastCalcAbsCumulative()

Calculates fast the absolute cumulative DVH.

getDVHData(paired=False)

Returns a dictionary with dose bin and volume data for the structure that is associated with this DVH.

The exact structure of the returned dictionary depends on the value of the parameter paired.

Parameters: paired – If set to True then (dose bin, volume) pairs are returned. If set to False then the resultant dictionary will have two nested dictionaries named dose and vol, each containing dose bin and volume data, respectively.

With paired=False:

>>> p = plan.Plan('/path/to/rd_file')
>>> p.plan.getDVHOf('Lens L').getDVHData(paired=False)
{'dose': [0.0, 0.01, 0.02, 0.03, 0.04, ...],
'vol': [100.0, 100.0, 100.0, 99.98, 99.1, ...]}


Same as before but with paired=True:

>>> p = plan.Plan('/path/to/rd_file')
>>> p.plan.getDVHOf('Lens L').getDVHData(paired=True)
{'dv': [(0.0, 100.0), (0.01, 100.0), (0.02, 100.0),
(0.03, 99.98), (0.04, 99.97), ...]}

getDicomDVH()

Returns the Pydicom differential DVH data object.

getDoseOfVolume(volPercentage)

Returns the minimum dose that covers volPercentage of the structure.

E.g., getDoseVolume(95) for ‘PTV’ structure will return the D95 of PTV, i.e. the minimum dose that covers 95% of the PTV volume.

getMaxDose(manual=False)

Returns the max dose for the structure that is associated with this DVH. Normally, the max dose should be available via Pydicom’s DVHMaximumDose. In case it isn’t, this function can be used to calculate it.

getMeanDose(manual=False)

Returns the mean dose for the structure that is associated with this DVH. Normally, the mean dose should be available via Pydicom’s DVHMeanDose. In case it isn’t, this function can be used to calculate it.

The formula that is used is the following:

$\text{Mean dose} = \frac{1}{\text{Total Volume}} (\mathrm{d}V_1 \mathrm{d}D_1 + \mathrm{d}V_2 \mathrm{d}D_2 + \ldots)$

for all dose bins, $$\mathrm{d}V$$, and their respective volume bins, $$\mathrm{d}V$$.

getMinDose(manual=False)

Returns the min dose for the structure that is associated with this DVH. Normally, the min dose should be available via Pydicom’s DVHMinimumDose. In case it isn’t, this function can be used to calculate it.

getTotalVolume()

Returns the total volume of structure.

getTotalVolume2()

Returns the total volume of structure.

getVolumeDose(isodose)

Returns the volume that is irradiated with at least isodose of the prescribed dose.

This is useful for the calculation of conformity index, i.e. CI = PTV / IRVol95.

relCumulative()

Returns the relative cumulative DVH.

## ntcp¶

class ntcp.lkb_model.LKBModel(dvh, parameters)

The Lyman Kutcher Burman (LKB) model is one of the most well known models for predicting Normal Tissue Complication Probability (NTCP) in a radiation treatment plan.

There are three parameters in the LKB model. TD50 represents the dose for a homogenous dose distribution to an organ at which 50% of patients are likely to experience a defined toxicity within 5 years. m is related to the standard deviation of TD50 and describes the steepness of the dose-response curve and n indicates the volume effect of the organ being assessed.

calcDeff(n)

Calculate effective dose Deff, i.e. the dose that, if given uniformly to the entire volume, will lead to the same NTCP as the actual non-uniform dose distribution.

Parameters: n – The model’s parameter n.

The model uses the following formula:

$D_\text{eff} = \sum_{i=1}^{N} (v_i D_i^n)^{1/n}$

Where $$v_i$$ is the fractional volume receiving $$D_i$$ dose summed over all $$N$$ voxels. In a differential DVH the y axis is $$\mathrm{d}V/\mathrm{d}D$$, therefore $$v_i = (\mathrm{d}V/\mathrm{d}D) \cdot \mathrm{d}D / V_\text{total}$$. X axis is $$\mathrm{d}D$$, therefore $$D_i = \sum_j \mathrm{d}D_j$$.

calcNTCP()

Calculate the NTCP via the following formula:

$\text{NTCP} = \frac{1}{2\pi}\int_{-\infty}^t \exp\left( -\frac{t^2}{2}\right)\mathrm{d}t$

Where:

$t = \frac{D_\text{eff} - \text{TD}_{50}}{m \text{TD}_{50}}$
class ntcp.ntcp_calculator.NTCPCalculator(dvh, model)

A class for calculating Normal Tissue Complication Probabilities (NTCPs).

Parameters: dvh – A differential DVH object. model – The mathematical model to use when estimating NTCP. Possible values currently only include LKB.
calcNTCP()

Do the actual calculation of NTCP.

## oed¶

class oed.oed_calculator.OEDCalculator(dvh, model)

A class for calculating Organ Equivalent Doses (OEDs).

Parameters: dvh – A differential DVH object. model – The mathematical model to use when estimating OED. Possible values include linear, exp and frac.
calcOED()

Do the actual calculation of OED.

oed.oed_calculator.calcMu(agex, agea, ge, ga)

Calculates the modifying function $$mu$$ that contains the population dependent variables.

The $$mu$$ function is defined as:

$\mu(agex, agea) = \exp\left( \gamma_e (agex-30) + \gamma_a \ln \left( \frac{agea}{70}\right) \right)$
Parameters: agex – Age at exposure agea – Age attained ge – Age modifying parameter ga – Age modifying parameter
class oed.linear_model.LinearModel(dvh, parameters)

A Linear model for calculating Organ Equivalent Doses (OEDs) in the context of predicting the risk of secondary (radiation-induced) cancers.

The model uses the following formula:

$\text{OED} = \sum_{i=1}^{N} v_i D_i$

Where $$v_i$$ is the fractional volume receiving $$D_i$$ dose summed over all $$N$$ voxels. In a differential DVH the y axis is $$\mathrm{d}V/\mathrm{d}D$$, therefore $$v_i = (\mathrm{d}V/\mathrm{d}D) \cdot \mathrm{d}D / V_\text{total}$$. X axis is $$\mathrm{d}D$$, therefore $$D_i = \sum_j \mathrm{d}D_j$$.

Parameters: dvh – The associated differential Dose-Volume Histogram. parameters – The model’s parameters.
calcOED()

Calculates the OED in Gray (Gy).

Returns: The value of OED.
class oed.exp_model.ExpModel(dvh, parameters)

An exponential model for calculating Organ Equivalent Doses (OEDs) in the context of predicting the risk of secondary (radiation-induced) cancers.

The model uses the following formula:

$\text{OED} = \sum_{i=1}^{N} v_i D_i \exp(-\alpha D_i)$

Where $$v_i$$ is the fractional volume receiving $$D_i$$ dose summed over all $$N$$ voxels. In a differential DVH the y axis is $$\mathrm{d}V/\mathrm{d}D$$, therefore $$v_i = (\mathrm{d}V/\mathrm{d}D) \cdot \mathrm{d}D / V_\text{total}$$. X axis is $$\mathrm{d}D$$, therefore $$D_i = \sum_j \mathrm{d}D_j$$.

Parameters: dvh – The associated differential Dose-Volume Histogram. parameters – The model’s parameters.
calcOED()

Calculates the OED in Gray (Gy).

Returns: A tuple of the form (x, y, z) where x is the calculated OED for a given alpha value, and y and z are the lower and upper bounds of OED corresponding to the lower and upper bounds of the alpha value.
doCalcOED(alpha)

Perform the actual OED calculation for a single alpha value.

Parameters: alpha – The model’s parameter alpha. The value of OED for this particular alpha value.
class oed.frac_model.FracModel(dvh, parameters)

An exponential model for calculating Organ Equivalent Doses (OEDs) in the context of predicting the risk of secondary (radiation-induced) cancers, that takes into account cell killing and fractionation effects. Reference: https://tbiomed.biomedcentral.com/articles/10.1186/1742-4682-8-27

The model uses the following formula:

$\text{RED}(D) = \frac{e^{-d D}}{a' R} \left( 1 -2R + R^2 e^{a' D} - (1-R^2) e^{-\frac{a'R}{1-R}D}\right)$

Where it assumed that the tissue is irradiated with a fractionated treatment schedule of equal dose fractions $$d$$ up to a dose $$D$$. The number of cells is reduced by cell killing which is proportional to $$a'$$ and is defined using the linear quadratic model:

$a' = a + \beta d = a + \beta \frac{D}{D_T} d_T$

Where $$D_T$$ and $$d_T$$ is the prescribed dose to the target volume with the corresponding fractionation dose, respectively. An $$a/\beta$$ ratio of 3 is assumed, with $$a=0.1$$ and $$\beta=0.033$$.

Parameters: dvh – The associated differential Dose-Volume Histogram. parameters – The model’s parameters.
RED(prescribedDose, dosePerFraction, R, D)
calcEAR(agex, agea, ge, ga)

Calculates the Excess Absolute Risk (EAR) for a whole organ.

Parameters: agex – Age at exposure. agea – Age attained. ge – Age modifying parameter. ga – Age modifying parameter.
calcOED()

Calculates the OED in Gray (Gy).

Returns: OED in Gray (Gy)
doCalcOED(prescribedDose, dosePerFraction, R)

Perform the actual OED calculation.

Parameters: prescribedDose – The prescribed total dose, e.g. 70 Gy. dosePerFraction – Dose per fraction, e.g. 2 Gy/fraction. R – Repopulation factor. Must be in [0, 1]. The value of OED.

## ovh¶

class ovh.OVH(coords, nsize)
Parameters: coords – the coordinates in R^3 of the structure that will participate in overlap histogram calculation, e.g. ‘Spine’ and ‘PTV 5940’. nsize – The size of the grid, e.g. nsize=100 will create a 100x100x100 grid.
calcdOVH(organ, target)

Calculates the differential overlap histogram between organ and target.

classmethod fromFilePath(filePath, nsize)

Load the vertex coordinates from a file.

Parameters: filePath – Path to the file with the vertex coordinates. nsize – The size of the grid, e.g. nsize=100 will create a 100x100x100 grid.
plotHist(dOVH)

Plots dOVH differential overlap histogram. This is used primarily for debugging purposes.

writeToFile(dOVH, organ)

Writes dOVH differential overlap histogram for organ in the disk. This is used primarily for debugging purposes.

## plan¶

class plan.Plan(rdFilePath)
cleanup(path_to_temp_dir)
getBeamSequence()

Returns the beam sequence of the plan

getComplexity(metricName, differential=False, verbose=False)

Returns the complexities for every beam in the plan. The beam names are normalized so that it is easier for post processing.

Parameters: metricName – Which complexity metric to calculate. It must be one of coa, em, efs, ltmean, mcs, mcsv, mfa, pi, sas. differential – Whether differential complexity will be computed. verbose – Whether to return the individual complexities for each control point of the beams. A list of tuples is returned. If verbose is False, then a tuple (x, y) is returned, with x being the (normalized) beam’s name and y the total complexity for the beam. If verbose is True, then a tuple (x, y, z) is returned, with z being a list with the complexities calculated at each control point.
getConformationNumber(structure, isodose)

Returns the conformation number for structure at the specified isodose level, as per the van’t Riet et al definition.

Parameters: structure – The name of the structure, e.g. PTV 5940. isodose – Isodose level given as a percentage, e.g. 95 corresponds to the 95% of prescribed dose. Conformation number ranging in [0.0, 1.0].
getDVHOf(structure)

Returns the Dose-Volume Histogram (DVH) of structure.

Parameters: structure – The name of the structure, e.g. PTV 5940. The DVH data object if it exists or None otherwise.
getDoseConstraints(structure)

Returns the dose constraints for structure (organ at risk).

Parameters: structure – The name of the structure, e.g. Lung. A list of [‘Structure’, ‘Constraint’, Numerical value]. E.g., [[‘lung’, ‘V5’, 45], [‘lung’, ‘V20’, 30], [‘lung’, ‘Mean’, 20], …].

Depending on the structure that is probed, the respective constraints are automatically calculated. E.g., if arg is Lung then V20 for lung will be returned, whereas if arg is Spinal Cord spine’s max point dose will be returned.

getDoseVolume(structure, volPercentage)

Returns the dose that covers at least volPercentage of structure.

Parameters: structure – The name of the structure, e.g. PTV 5940. volPercentage – Percentage of volume, e.g. 95 corresponds to the 95% the structure’s total volume.
>>> ./rteval.py load ./443-18/RD.dcm dv 'PTV 5445' 95
{"dv": {"PTV 5445": {"95.0": "52.45"}}}
>>> ./rteval.py load ./443-18/RD.dcm dv 'PTV 6600' 95
{"dv": {"PTV 6600": {"95.0": "63.71"}}}

getEAR(model, structure, agex, agea)

Returns the Excessive Absolute Risk for structure.

getInputFileName()
getInstitutionName()

Returns the Institution’s Name where where the equipment is located that is to be used for beam delivery.

getNTCP(structure)

Returns the normal tissue complication probability (if applicable).

getNumberOfBeams()

Returns the number of beams in the plan broken down by their type, i.e., static vs. dynamic.

Returns: A tuple where the first element is the number of static beams and the second element is the number of dynamic beams in the plan.
getNumberOfFractions()

Returns the number of fractions planned.

getOED(model, structure)

Returns the organ equivalent dose value (if applicable).

getOperatorName()

Returns the normalized name of the operator.

The username that was used while logged in (to TPS?).

getPatientID()

Returns the patient’s unique identification number.

getPatientName()

Returns the normalized patient’s name.

getPhysicianName()

Returns the normalized physician name.

getPlanLabel()

Returns the normalized RT plan label, e.g. plan1 or plan_nasopharynx.

getPointDoseStatistics(structure)

Returns a list of (statistic, value) for structure or an empty list if an error has occured.

Parameters: structure – The name of the structure, e.g. PTV 5940.

The statistics include Min point dose, Max point dose, Mean dose, D2 and D98.

getPrescribedDose()

Returns the plan’s prescribed dose.

Returns: A tuple (x, y) is returned, with x being the prescribed dose and y the structure that is attached to it.

In plans with a simultaneous integrated boost (SIB), returns the highest dose level. So if the patient is treated with 6996/212, 6600/200 and 5940/180 cGy, 6996 is returned. For extracting all doses, one needs to use DosePrescription.inferSIBDoses().

getReviewerName()

Returns the normalized username of the reviewer (e.g., medical physicist, dosimetrist).

getSoftwareVersions()

Returns the software versions.

getStructureSetFilePath()

Returns the path to the structure set associated with this plan.

getStudyDate()

Returns the date of the study in day/month/year format, e.g. 25-08-2018.

getStudyDay()

Returns the week day of the study date.

There’s also an RT plan date that, as it seems, is always past than study date. Unfortunately, neither results in a Saturday or Sunday (so can’t tell which one is the one we want, i.e., the day the dosimetry took place).

getTotalMUs()
getVolumeDose(structure, isodose)

Returns the volume of structure that is covered by at least isodose.

Parameters: structure – The name of the structure, e.g. PTV 5940. isodose – Isodose level given as a percentage, e.g. 95 corresponds to the 95% of prescribed dose.
getVolumeOf(structure)

Returns the geometrical volume of structure.

Parameters: structure – The name of the structure, e.g. Bowel bag. The geometrical volume of structure. If structure does not have a DVH, then zero is returned.

The volume is calculated by summing all dV’s from the differential DVH data.

>>> ./rteval.py load ./443-18/RD.dcm volume 'PTV 6600'
{"volume": {"PTV 6600": "289.41"}}
>>> ./rteval.py load ./443-18/RD.dcm vd 'PTV 6600' 1
{"vd": {"PTV 6600": {"1.0": "289.41"}}}


## plandiff¶

class plandiff.PlanDiff(plan1, plan2)

A class for calculating the differences between two plans.

Parameters: plan1 – the first plan plan2 – the second plan

E.g. of usage:

>>> p1 = plan.Plan('/path/to/rd_of_plan1')
>>> p2 = plan.Plan('/path/to/rd_of_plan2')
>>> rv = plandiff.PlanDiff(p1, p2).compare()

compare(isPretty=False)

It does the actual comparison between plan1 and plan2.

Returns: A dictionary with three nested dictionaries, each containing the organs at risk as keys and with the constraints of the 1st, the 2nd and their difference.
diffConstraints(constraints1, constraints2)

Calculate the difference between two dictionaries representing the dose constraints to the organs at risk (OAR) of the respective plan.

Parameters: constraints1 – A dictionary with the dose constraints of 1st plan’s OARs. constraints2 – A dictionary with the dose constraints of 2nd plan’s OARs. A dictionary with the common organs at risk and the dose differences of the respective constraints. For instance, if: constraints1 = {‘1’: {‘brainstem’: {‘Max’: ‘50.36’}}} and constraints2 = {‘2’: {‘brainstem’: {‘Max’: ‘52.55’}, then {‘brainstem’: {‘Max’: ‘-2.19’}} is returned.
plandiff.prettyPrint(diffDict)

Pretty print a dictionary as returned by PlanDiff.compare().

Parameters: diffDict – A dict of the form that PlanDiff.compare() returns.

E.g. of usage:

>>> p1 = plan.Plan('/path/to/rd_of_plan1')
>>> p2 = plan.Plan('/path/to/rd_of_plan2')
>>> rv = plandiff.PlanDiff(e1, e2).compare()
>>> prettyPrint(rv)
Structure       Constr    V1     V2     dV     %
esophagus       V35     62.57  57.18  -5.39  -8.61
esophagus       V50     13.91  18.93   5.02  36.09
esophagus       V70      0.00   0.00   0.00   0.00
esophagus       Mean    35.79  34.49  -1.30  -3.63
larynx          Mean    41.51  41.18  -0.33  -0.79
parotid_l       Mean    45.30  24.41 -20.89 -46.11
parotid_r       Mean    24.94  23.99  -0.95  -3.81
...


## spec_constraints¶

class spec_constraints.Bladder(structure, dvh)
getAbomb()
getAgeModifyingParameters()
getBetaEARofUK()
getLKBParameters()
getOEDParameters()
getR()
getV()

V65, V70, V75

class spec_constraints.Bone(structure, dvh)
getAgeModifyingParameters()
getOEDParameters()
getV()

V50

class spec_constraints.BrachialPlexus(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getLKBParameters()
getR()
getV()

Max dose

class spec_constraints.Brain(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getLKBParameters()
getR()
getV()

Max dose

class spec_constraints.Brainstem(structure, dvh)
getBetaEARofUK()
getLKBParameters()
getR()
getV()

Max dose

class spec_constraints.Breast(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getR()
class spec_constraints.Cervix(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
class spec_constraints.Cochlea(structure, dvh)
getV()

Mean dose

class spec_constraints.Esophageal(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getLKBParameters()
getR()
getV()

Mean dose and V35, V50, V70

class spec_constraints.Eye(structure, dvh)
getV()

Max and mean dose

class spec_constraints.FemoralHead(structure, dvh)
getAgeModifyingParameters()
getOEDParameters()
getV()

V10, V15, V25, V35, V40, V50, Max dose

class spec_constraints.Heart(structure, dvh)
getLKBParameters()
getV()

Mean dose and V25, V30

class spec_constraints.Kidney(structure, dvh)
getV()

Mean dose and V12, V20, V34, V28

class spec_constraints.LacrimalGland(structure, dvh)
getV()

Mean dose

class spec_constraints.LargeIntestine(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getR()
class spec_constraints.Larynx(structure, dvh)
getV()

Mean dose

class spec_constraints.Lens(structure, dvh)
getLKBParameters()
getV()

Max dose

class spec_constraints.Lips(structure, dvh)
getV()

Max dose

class spec_constraints.Liver(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getR()
class spec_constraints.Lung(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getOEDParameters()
getR()
getV()

Mean dose and V5, V13, V20, V30

class spec_constraints.Mandible(structure, dvh)
getLKBParameters()
getV()

Max dose

class spec_constraints.OpticChiasm(structure, dvh)
getLKBParameters()
getR()
getV()

Max dose

class spec_constraints.OralCavity(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getOEDParameters()
getR()
getV()

Mean dose

class spec_constraints.Parotid(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getLKBParameters()
getR()
getV()

Mean dose and V30

class spec_constraints.ParotidUnilateral(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getLKBParameters()
getR()
getV()

Mean dose

class spec_constraints.Prostate(structure, dvh)
getOEDParameters()
getV()

Mean dose

class spec_constraints.Rectum(structure, dvh)
getAbomb()
getAgeModifyingParameters()
getBetaEARofUK()
getLKBParameters()
getOEDParameters()
getR()
getV()

V50, V60, V65, V70, V75

class spec_constraints.Skin(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getOEDParameters()

OED parameters for secondary melanoma

class spec_constraints.SmallIntestine(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getR()
class spec_constraints.Spine(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getLKBParameters()
getR()
getV()

Max dose

class spec_constraints.Stomach(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getOEDParameters()
getR()
getV()

XXX: Not implemented yet (D100)

class spec_constraints.Submandibular(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getR()
getV()

Mean dose

class spec_constraints.Thyroid(structure, dvh)
getAgeModifyingParameters()
getBetaEARofUK()
getOEDParameters()
class spec_constraints.Trachea(structure, dvh)
getR()
getV()

Mean dose

## structure_set¶

class structure_set.StructureSet(rtss)
findStructureROIByName(structure)

Returns the ROI number of structure.

Parameters: structure – The name of the structure, e.g. PTV 5940. The ROI number of the structure or None if not found.
getContourDataAtIndex(structure, contourIndex)

Returns a list with the vertex coordinates for structure at contourIndex slice.

Parameters: structure – The name of the structure, e.g. PTV 5940. contourIndex – Takes values 0, 1, 2,..., N. It is the z-coord (long axis).
getContourVertices(structure, contourIndex)

Returns a list of the form [[x1, y1, z1], [x2, y2, z2], ….] for structure at contourIndex slice.

Parameters: structure – The name of the structure, e.g. PTV 5940. contourIndex – Takes values 0, 1, 2,..., N. It is the z-coord (long axis).
getNumberOfContours(structure)

Returns the number of contours for structure.

Parameters: structure – The name of the structure, e.g. PTV 5940.
getROIContourSequence(structure)

Returns the roi contour sequence for structure. This in turn may be used in getContourData() method.

Parameters: structure – The name of the structure, e.g. PTV 5940.
getStructures()

Returns a list of structures from current structure set, e.g., [‘Spine’, ‘Lung_Right’, PTV 5940’, …].

getUIDsOfCTImages()

Returns a list with the UIDs of the CT files associated with this plan

## voxelize¶

class voxelize.Voxelize(coords, nsize, minMax=None)
Parameters: coords – the coordinates in $$R^3$$ of the structure that we would like to voxelize. nsize – The size of the grid, e.g. nsize=100 will create a $$100 \times 100 \times 100$$ grid.
calcEuclideanDistanceTransform()

Calculates the Euclidean Distance Transformation.

doIt()

Performs the actual voxelization.

classmethod fromFilePath(filePath, nsize)

Load the vertex coordinates from a file.

Parameters: filePath – Path to the file with the vertex coordinates. nsize – The size of the grid, e.g. nsize=100 will create a $$100 \times 100 \times 100$$ grid.
getInteriorPoints()

Returns the interior points of the 3D structure. This is primarily used in the calculation of the EDT transformation, specifically to negate the value of EDT inside the 3D structure.

static getMinMax(coords)
plotContour(coords, z0)

Plot the contour for z=z0 in coords. This is meant for debugging purposes.

plotGrid()

Plot the 3D grid as a 3D scatter plot. This is meant for debugging purposes.

plotPoints3D(coords)

Plot the 3D grid from coords` as a 3D scatter plot. This is meant for debugging purposes.