Analytical Phantoms - xcist/documentation GitHub Wiki

Analytic File Format

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.

⚠️ **GitHub.com Fallback** ⚠️