Phantoms used by OpenSkin have a small number of required properties.
The final output of processing a phantom for a given beam is a 2d array of doses. However, this array can represent a surface (or number of surfaces) in 3d space subject to the constraints below.
The phantom object must have a
height. These define the array used to hold the results and the dimensions of the output images.
A phantom must also have a
phantomMap which is an array of points in 3d space defining the skin points to be evaluated. The array must have
height as defined by the phantom. Points do not need to be contiguous.
In order to exclude radiation that has passed through the body the phantom also has a
normalMap which is an array (size
height) containing line segments defining the 3d vector into the skin surface for each point. Radiation from more than 90 degrees to this normal vector is excluded as shielded by the patient. As such concave surfaces will function incorrectly.
The simplest example is a flat phantom, representing the couch surface. This might have a
width of 50 and
height of 100 to cover the torso. Something like this:
phantomMap would then be an array of size 50x150. The first few entries in this array might be:
[ [0, 0, 0], [0, 1, 0], [0, 2, 0]... [ [0, 0, 0], [1, 1, 0], [2, 2, 0]...
representing evenly spaced points incrementing in x in rows and y in columns.
normalMap entry for the first cell
[0, 0, 0] might then be a segment from
[0, 0, -1] to
[0, 0, 0] assuming x-rays from below are of interest.
An alternative to a flat phantom is to build a surface in three dimensions. The currently implemented 3D phantom is a cuboid and two semi-cylinders, as below:
normalMap then take the form of a surface wrapped around the phantom. For dose maps this is then split at the chest and unpeeled into a 2D image.
height are still required but must reflect the size of the resulting 2D surface, not the width of the 3D patient.