10. Reference application
10.1. Transport modules coding in XML geometry file
Type name |
Transport class |
Description |
---|---|---|
cylinder |
mcTransportCylinder |
Solid cylinder |
cone |
mcTransportCone |
Solid cone |
prism |
mcTransportPrism |
Solid prism |
wedge |
mcTransportWedge |
Solid rectangle cylinder |
ring |
mcTransportRing |
Solid ring |
conicalring |
mcTransportConicalRing |
Solid ring with focused edges |
conicalhole |
mcTransportConicalHole |
Solid ring with hole and all edges focused |
rectanglering |
mcTransportRectangleRing |
Solid rectangle ring |
jaw_pair |
mcTransportJawPairRounded |
Pair of solid prism, representing collimator jaws |
jaw_pair_focused |
mcTransportJawPairFocused |
Pair of solid prism with focused internal edges, representing collimator jaws |
rectanglepolygonsidehole |
mcTransportRectanglePolygonSideHole |
Solid prism with rectangle hole which internal edge is defined by arbitrary polygon |
mlc |
mcTransportMLC |
MLC modelling module |
gridcylinder |
mcTransportCylinderStack |
Stack of nested cylinders with space between them |
planefilter |
mcTransportPlaneFilter |
Transparent infinite plane used for hosting objects like scoring |
etrap |
mcETransportTrap |
An other infinite plane, which kills particles after processing in scoring |
rectangletrap |
mcTransportRectangleTrap |
Rectangular trap, which kills particles except those that go through the internal hole or onside the transport |
spheretrap |
mcTransportSphereTrap |
Spherical trap that kills particle after scoring |
axial_splitter |
mcTransportAxialSymmetricSplitter |
Splits particles in cylindrical symmetric cases with eventual rotation around Z axis and preserving total weight |
simple_splitter |
mcTransportSimpleSplitter |
Generates copies of particles while keeping total weight |
slab |
mcTransportSlab |
Simple infinite slab |
ptlasvegas |
mcPTLasVegas |
Las Vegas phantom for testing portal imaging systems in radiation therapy units |
esphere |
mcETransportSphere |
Solid sphere |
e_convex_polygon_circle |
mcETransportConvexPolygonCircle |
Cylindrically symmetric solid object formed by polygon rotation around Z axis |
Next is an example of code, which parses geometry configuration file and creates network of transport objects.
if (_wcsicmp(geomType.c_str(), L"ptlasvegas") == 0)
{
t = new mcPTLasVegas(origin, normal, xaxis);
}
else if (_wcsicmp(geomType.c_str(), L"esphere") == 0)
{
t = new mcETransportSphere(origin, normal, xaxis, radius);
}
else if (_wcsicmp(geomType.c_str(), L"e_convex_polygon_circle") == 0)
{
t = new mcETransportConvexPolygonCircle(origin, normal, xaxis, poly_z, poly_x);
}
10.1.1. Module “cylinder”
Class: |
mcTransportCylinder |
Description: |
Cylinder object |
Example: |
10.1.2. Module “rectanglepolygonsidehole”
Class: |
mcTransportRectanglePolygonSideHole |
Description: |
Cylindrically symmetric object with shaped by polygon hole |
Example: |
10.2. Composite transport modules coding in XML geometry file
Type name |
Transport class |
Description |
---|---|---|
group |
mcTransport |
Embedding other transport as regions |
embedding |
mcTransport |
Embedding nested transport modules |
embedded_group |
mcTransportEmbeddedGroup |
Group of transport modules with arbitrary order |
linear_chain |
mcTransportLinearChain |
Z ordered chain of transports that pass particles to neighbors |
10.2.1. Module “group”
Class: |
mcTransport |
Description: |
Not a real object. It is a special construction to group other object. Group is treated by shower as a single object. I.e. it looks like a module in z-ordered chain of modules. |
Example: |
<!--CyberKnife primary collimator with aluminum filter layer-->
<module type="group" name="PRI_1">
<position unit="cm" x="0" y="0" z="-78.5" />
<normal x="0" y="0" z="1" />
<xaxis x="1" y="0" z="0" />
<module type="ring" name="PRI_1W" medium="W700ICRU" density="1">
<Color r="0" g="0.5" b="0" t="0.5" />
<position unit="cm" x="0" y="0" z="0" />
<normal x="0" y="0" z="1" />
<xaxis x="1" y="0" z="0" />
<size unit="cm" r0="0.24" r1="8.25" height="3.1"/>
</module>
<module type="cylinder" name="PRI_1A" medium="AL700ICRU" density="1">
<Color r="1" g="1" b="1" t="0.5" />
<position unit="cm" x="0" y="0" z="0" />
<normal x="0" y="0" z="1" />
<xaxis x="1" y="0" z="0" />
<size unit="cm" radius="0.24" height="0.85"/>
</module>
</module>
|
Next is a parser code fragment, that demonstrates how content of “group” module description is interpreted. Grouping is implemented through the concept of Regions.
else if (_wcsicmp(geomType.c_str(), L"group") == 0)
{
t = new mcTransport(origin, normal, xaxis);
// Search and parse embedded modules
for (auto node : geometry.Nodes)
{
if (_wcsicmp(node.Name.c_str(), L"module") == 0)
{
mcTransport* region = GeometryParser::ParseTransport(node, media, nThreads);
region->setDefaultScore(nThreads);
t->addRegion(region);
}
}
}
In this code example variable t represents transport module which will be inserted in to the current transport chain. Nested modules will be simulated as regular modules, but under the multiregion transport t roof.
Note
Nested modules coordinate system is defined relatively to the parent module.
In this particular module “group” example two modules are nested to parent module. Their registration in parent as regions means, that after each event of exiting from nested module particles will be tested on possibility of hitting any other region. If so, transport will be delegated to the nearest hitting region. Otherwise particle will exit parent module.
10.2.2. Module “embedding”
Class: |
Can be any transport class, that implements nested transport |
Description: |
Nested set of transport modules. The most external one represents the whole module from the point of view of consuming linear chain of transports. |
Example: |
<?xml version="1.0" encoding="utf-8"?>
<!-- Faddegon experiment geometry with spherical detector -->
<accelerator>
<!--
Objects are sequence of nested objects.
First one is experimental unit as whole (wich can be inserted in other chains).
All its childs are nested as a Russian dole.
First child is most internal object (target in this case).
All child coordinates are defined relatively to the parent.
-->
<module type="embedding" name="ExperimentalUnit">
<position unit="cm" x="0" y="0" z="0" />
<normal x="0" y="0" z="1" />
<xaxis x="1" y="0" z="0" />
<!--Target-->
<!-- Pb (9.13 g/cm2 thick, 17.95 g/cm2 radius RHO= 1.1340E+01 -->
<module type="cylinder" name="Target" medium="PB700ICRU" density="1">
<Color r="1" g="1" b="1" t="0" />
<position unit="cm" x="0" y="0" z="0" />
<normal x="0" y="0" z="1" />
<xaxis x="1" y="0" z="0" />
<size unit="cm" radius="1.58" height="0.805"/>
</module>
<!-- Assume transport in Vacuum (i.e. next will be detector) -->
<!--Spherical detector is requred to atach scoring-->
<module type="spheretrap" name="Detector" medium="H2O700ICRU" density="1">
<Color r="1.0" g="0.5" b="0.5" t="0.8" />
<position unit="cm" x="0" y="0" z="0" />
<normal x="0" y="0" z="1" />
<xaxis x="1" y="0" z="0" />
<size unit="cm" radius="100.0"/>
</module>
</module>
</accelerator>
|
XML configuration file contains nested transports of “embedding” module in the order of internal transports first.
Next is a parser code fragment, that demonstrates how content of “embedding” module description is interpreted. Grouping is implemented through the concept of nested transports, which means russian doll type construction, i.e. nested transport is completely covered by parent transport. Each transport may have only one reference to embedded transport.
else if (_wcsicmp(geomType.c_str(), L"embedding") == 0)
{
// Temporal transport needed for group coordinate system
mcTransport ttmp(origin, normal, xaxis);
mcTransport* eprev = nullptr;
// Search and parse nested transports
for (auto node : geometry.Nodes)
{
if (_wcsicmp(node.Name.c_str(), L"module") == 0)
{
mcTransport* eobj = GeometryParser::ParseTransport(node, media, nThreads);
if (eobj == nullptr)
throw exception("Embedding group should contain only embedding objects");
// Transfer coordinate system from group to world
eobj->MoveToCoordinateSystem(ttmp.MT2W());
eobj->setDefaultScore(nThreads);
if (eprev != nullptr)
{
eprev->setExternalTransport(eobj);
eobj->setInternalTransport(eprev);
}
eprev = eobj;
}
}
t = eprev;
skipInit = true;
}
In this code example variable t represents transport module which will be inserted in to the current transport chain. Nested modules will be simulated by moving particles between internal / external transport until particle leave the most external transport.
Note
Nested modules coordinate system is defined relatively to the parent module.
In this particular module “embedding” example there are two modules. Оne (Target) is inside the other (spherical detector). In contrast to linear chain of transports ordered by increasing Z position nested transport is implemented by setting references in each transport “embedding” module references to external and internal ones. Registration transports in a such a way is provided by setExternalTransport() / setInternalTransport() functions.
10.2.3. Module “embedded_group”
Class: |
mcTransportEmbeddedGroup |
Description: |
Special class with overridden transport, which at transport inside itself detects nearest transport from internal collection which can be hit by particles and pass transport to it. If no internal transport can be hit, particle exits from this module. |
Example: |
<!--
Group of modules consisting of target and
shielding elements and primary collimator hole
-->
<module type="embedded_group" name="ShieldInternalGroup">
<position unit="cm" x="0" y="0" z="0" />
<normal x="0" y="0" z="1" />
<xaxis x="1" y="0" z="0" />
<!--Accelerator part-->
<module type="embedding" name="Accelerator">
<position unit="cm" x="0" y="0" z="0" />
<normal x="0" y="0" z="1" />
<xaxis x="1" y="0" z="0" />
<!--......................-->
</module>
<!--Primary collimator hole-->
<module type="e_convex_polygon_circle" name="PriCollAir"
medium="AIR700ICRU" density="1">
<Color r="0.2" g="0.2" b="1.0" t="0.8" />
<position unit="cm" x="0" y="0" z="0" />
<normal x="0" y="0" z="1" />
<xaxis x="1" y="0" z="0" />
<polygon>
<point z="1.801" x="0.65"/>
<point z="9.799" x="2.6"/>
</polygon>
</module>
</module>
|
XML configuration file contains nested transports of “embedded_group” module in the order of internal transports first.
Next is a parser code fragment, that demonstrates how content of “embedded_group” module description is interpreted. Grouping is implemented through the concept of internal collection of transport modules, which can be hit by the particles in any order.
else if (_wcsicmp(geomType.c_str(), L"embedded_group") == 0)
{
t = new mcTransportEmbeddedGroup(origin, normal, xaxis);
// Search and parse nested transports
for (auto node : geometry.Nodes)
{
if (_wcsicmp(node.Name.c_str(), L"module") == 0)
{
mcTransport* eobj = GeometryParser::ParseTransport(node, media, nThreads);
if (eobj == nullptr)
throw exception("embedded_group internal module parse error");
// Transfer coordinate system from group to world
eobj->MoveToCoordinateSystem(t->MT2W());
((mcTransportEmbeddedGroup*)t)->addTransport(eobj);
}
}
}
In this code example variable t represents transport module which will be inserted in to the current transport chain.
Note
Nested modules coordinate system is defined relatively to the parent module.
In this particular module “embedded_group” example demonstrates how primary collimator hole can be implemented inside the whole shield side by side with electron accelerator inside the same shied object.
10.2.4. Module “linear_chain”
Class: |
mcTransportLinearChain |
Description: |
Special class with overridden transport, which at transport inside itself detects nearest transport from internal collection which can be hit by particles and pass transport to it. If no internal transport can be hit, particle exits from this module. |
Example: |
<module type="linear_chain" name="RadiationHead">
<position unit="cm" x="0" y="0" z="0" />
<normal x="0" y="0" z="1" />
<xaxis x="1" y="0" z="0" />
<module type="embedding" name="ShieldGroup">
<position unit="cm" x="0" y="0" z="0" />
<normal x="0" y="0" z="1" />
<xaxis x="1" y="0" z="0" />
<!--......................-->
</module>
<!--Flattening filter-->
<module type="cone" name="Flattenig Filter" medium="W700ICRU" density="1">
<Color r="0.7" g="0.7" b="0.7" t="0.2" />
<position unit="cm" x="0" y="0" z="11" />
<normal x="0" y="0" z="-1" />
<xaxis x="-1" y="0" z="0" />
<size unit="cm" radius="2.4" height="1.0"/>
</module>
<!--Ionization chamber-->
<module type="cylinder" name="IonChamber" medium="AIR700ICRU" density="1">
<Color r="1.0" g="0.5" b="0.0" t="0.7" />
<position unit="cm" x="0" y="0" z="11.5" />
<normal x="0" y="0" z="1" />
<xaxis x="1" y="0" z="0" />
<size unit="cm" radius="6.0" height="2"/>
</module>
<!--......................-->
</module>
|
XML configuration file contains nested transports of “linear_chain” module in the order of internal transports first.
Next is a parser code fragment, that demonstrates how content of “linear_chain” module description is interpreted. Grouping is implemented through the concept of internal linear Z ordered chain of transport modules.
else if (_wcsicmp(geomType.c_str(), L"linear_chain") == 0)
{
t = new mcTransportLinearChain(origin, normal, xaxis);
for (auto node : geometry.Nodes)
{
if (_wcsicmp(node.Name.c_str(), L"module") == 0)
{
mcTransport* eobj = GeometryParser::ParseTransport(node, media, nThreads);
if (eobj == nullptr)
throw exception("Embedding group should contain only embedding objects");
eobj->MoveToCoordinateSystem(t->MT2W());
((mcTransportLinearChain*)t)->addTransport(eobj);
}
}
((mcTransportLinearChain*)t)->completeInit();
}
In this code example variable t represents transport module which will be inserted in to the current transport chain.
Note
Nested modules coordinate system is defined relatively to the parent module.
In this particular module “linear_chain” example demonstrates implementation accelerator head collimating structures sequence, where elements can be separated by planes, orthogonal to Z axis.