Analytical Phantoms - xcist/documentation GitHub Wiki

CatSim was originally developed to simulate the following analytic objects: cylinders, ellipsoids, boxes, and clipping planes. Subsequently, the capability to simulate other analytic objects has been added including hyperboloids of one plane, hyperboloids of two planes, cones, and tori (see figure to the right). However, the FORBILD phantom model does not support all these objects. For this and other reasons, we developed a new phantom format that’s based on Matlab syntax. We use the extension .ppm
for the new (Matlab-based) format.
This syntax supports phantom files that contain one of two classes of shapes: analytic and polygonal.
For analytic phantoms, use cfg.callback_projector = 'C_Projector_Analytic';
For polygonal phantoms, use cfg.callback_projector = 'C_Projector_Polygon';
Files in the .ppm file syntax are read in by executing them as Matlab scripts. At the end of execution, it is expected that each object in the phantom will be stored in a structure called object
, and a list of the materials will be stored in a cell array called materialList
. The object structure contains various fields as described below.
These fields are relevant to analytic and polygonal phantoms:
object.material |
filename that describes the material or an index into the materialList (for example, if the materialList contains ‘water’ , and ‘bone’ , one could use the number 2 instead of the string ‘bone’ . |
object.density |
A density relative to the default density of the material. |
These fields are relevant only to polygonal phantoms:
object.vertices |
The vertices of the polygon |
object.tri_inds |
The indices of the vertices of each triangular face. Faces with more than three vertices should be subdivided into triangles. |
These fields are relevant only to analytic phantoms:
object.center |
The center of the object |
object.half_axes |
The size of the object along 3 object axes |
object.euler_angs |
Three rotation angles that are applied sequentially (about z, y, and z axes respectively) in order to rotate the object to the desired orientation |
object.type |
can be any of the following: Ellipsoid, Cylinder, Torus, Cone, Hyperboloid2, Hyperboloid1, VesselSeg, Box
|
object.axial_lims |
Simple way to establish two basic clipping planes for cones and hyperboloids |
object.shape |
Used only for the torus object to define the thickness relative to the radius of curvature |
object.clip |
A set of clipping planes specified as a vector and a distance |
object.name |
object name (optional... used in PhantaSee) |
object.color
|
optional... used only in PhantaSee |
object.group |
optional... used only in PhantaSee |
object.transparency |
optional... used only in PhantaSee |
There are many ways to structure the phantom description file since it is executed within Matlab. The most straightforward (and verbose) way to specify a given object is to set each parameter of each object on a separate line. For example:
object{1}.center = [0.000000 0.000000 0.000000];
object{1}.half_axes = [108.000000 108.000000 17.500000];
object{1}.euler_angs = [0.000000 0.000000 0.000000];
object{1}.density = 1.000000;
object{1}.type = 'Cylinder';
object{1}.material = 'water';
object{1}.axial_lims = [0.000000 0.000000];
object{1}.shape = 0.000000;
object{1}.clip = [];
object{1}.color = [1.000000 0.000000 0.000000];
object{1}.group = 0;
object{1}.transparancy = 0.000000;
Note that this can be problematic if you have a phantom of 100 objects and you want to add an object at the beginning of the list such that the former object 1 becomes object 2, the former object 2 becomes object 3 and so on. It is better, therefore, to use the function
AddObject()
to add the objects into the phantom as in the example .ppm
file. Note also that most parameters have default values (the half_axes parameter does not), so there is no need to specify a parameter if you are happy with the default. There is a default header for .ppm
files as follows:obj=[];object=[];
update = '[obj,object]=AddObject(obj,object,materialList);'
If this header is included, you can specify an object in a variable called obj and then evaluate the update step to add it to the phantom (which is stored in object).
Furthermore, loops can be used to add many objects (e.g. resolution bars) with a small amount of code.