Recent posts
#21
Geometry, Material & Navigation / Creating geometry components i...
Last post by mwj12 - Dec 02, 2025, 08:59 PMMy Python script generates a multitude of navigators, detectors, etc... in list form using a loop, something like,
Here, the details of build_meshed_navigator() are not really important. It is my own function which constructs a meshed navigator with GGEMSMeshedPhantom and populates its members to certain specifications. The result is a list of navigators, held in the list 'meshed'.
But in all the documentation examples, the components are all created as explicit top-level variables, and GGEMS v1.3 doesn't seem to be able to recognize GGEMS objects when they are encapsulated in lists or other containers. My simulation output thus contains all zeros, as if no sources or other components are present. Is there a way to get GGEMS v1.3 to recognize arrays of navigators and other components, built using loops?
Code Select
meshed = []
for Md in as_list(cfg.get("meshedNavigators")):
meshed.append(build_meshed_navigator(Md, matlabBase))
Here, the details of build_meshed_navigator() are not really important. It is my own function which constructs a meshed navigator with GGEMSMeshedPhantom and populates its members to certain specifications. The result is a list of navigators, held in the list 'meshed'.
But in all the documentation examples, the components are all created as explicit top-level variables, and GGEMS v1.3 doesn't seem to be able to recognize GGEMS objects when they are encapsulated in lists or other containers. My simulation output thus contains all zeros, as if no sources or other components are present. Is there a way to get GGEMS v1.3 to recognize arrays of navigators and other components, built using loops?
#22
Output Data / CBCT simulation output except...
Last post by zhenguo - Dec 01, 2025, 01:18 PMHello, I am a beginner with GGEMS. When using example 7_Mesh.py, I modified the original STL phantom code as follows:
Original code for STEP 5: Phantoms and systems
# Loading phantom in GGEMS
mesh_phantom = GGEMSMeshedPhantom('phantom_mesh')
mesh_phantom.set_phantom('data/Stanford_Bunny.stl')
mesh_phantom.set_rotation(90.0, 90.0, 0.0, 'deg')
mesh_phantom.set_position(0.0, 0.0, 0.0, 'mm')
mesh_phantom.set_mesh_octree_depth(4)
mesh_phantom.set_visible(True)
mesh_phantom.set_material('Water')
mesh_phantom.set_material_color('Water', color_name='white') # Uncomment for automatic color
Modified code:
# Loading phantom in GGEMS
mesh_phantom = GGEMSMeshedPhantom('Centrifuge_tube')
mesh_phantom.set_phantom('data/Centrifuge_tube.STL')
mesh_phantom.set_rotation(0.0, 0.0, 0.0, 'deg')
mesh_phantom.set_position(-11.25, -50.0, -11.25, 'mm')
mesh_phantom.set_mesh_octree_depth(4)
mesh_phantom.set_visible(True)
mesh_phantom.set_material('Bakelite')
mesh_phantom.set_material_color('Bakelite', color_name='white') # Uncomment for automatic color
mesh_phantom1 = GGEMSMeshedPhantom('Cylindrical_soil')
mesh_phantom1.set_phantom('data/Cylindrical_soil.STL')
mesh_phantom1.set_rotation(0.0, 0.0, 0.0, 'deg')
mesh_phantom1.set_position(-6, -10.0, -6, 'mm')
mesh_phantom1.set_mesh_octree_depth(4)
mesh_phantom1.set_visible(True)
mesh_phantom1.set_material('Lead')
mesh_phantom1.set_material_color('Lead', color_name='blue') # Uncomment for automatic color
The STL file of the centrifuge tube phantom is a cylindrical ring with a height of 100 mm, an outer radius of 11.25 mm, and an inner radius of 10.5 mm; the cylindrical soil phantom is a cylinder with a radius of 6 mm and a height of 20 mm. The geometric centers of both phantoms are at the coordinate origin, and there is no overlap between them at all—the cylindrical ring encloses the cylinder.
After running the code, I found that the generated projection.raw image only shows the projection of the centrifuge tube sample, with no information about the cylindrical soil reflected. However, if I change mesh_phantom1.set_position(-6, -10.0, -6, 'mm') to mesh_phantom1.set_position(-100, -10.0, -6, 'mm') (at which point the cylindrical ring and the cylinder no longer have an enclosing or overlapping relationship), the information of the soil cylinder will appear in the projection.raw file generated after running the code.
What causes this issue and how can it be resolved? I would be extremely grateful for your answer. Best regards!
Original code for STEP 5: Phantoms and systems
# Loading phantom in GGEMS
mesh_phantom = GGEMSMeshedPhantom('phantom_mesh')
mesh_phantom.set_phantom('data/Stanford_Bunny.stl')
mesh_phantom.set_rotation(90.0, 90.0, 0.0, 'deg')
mesh_phantom.set_position(0.0, 0.0, 0.0, 'mm')
mesh_phantom.set_mesh_octree_depth(4)
mesh_phantom.set_visible(True)
mesh_phantom.set_material('Water')
mesh_phantom.set_material_color('Water', color_name='white') # Uncomment for automatic color
Modified code:
# Loading phantom in GGEMS
mesh_phantom = GGEMSMeshedPhantom('Centrifuge_tube')
mesh_phantom.set_phantom('data/Centrifuge_tube.STL')
mesh_phantom.set_rotation(0.0, 0.0, 0.0, 'deg')
mesh_phantom.set_position(-11.25, -50.0, -11.25, 'mm')
mesh_phantom.set_mesh_octree_depth(4)
mesh_phantom.set_visible(True)
mesh_phantom.set_material('Bakelite')
mesh_phantom.set_material_color('Bakelite', color_name='white') # Uncomment for automatic color
mesh_phantom1 = GGEMSMeshedPhantom('Cylindrical_soil')
mesh_phantom1.set_phantom('data/Cylindrical_soil.STL')
mesh_phantom1.set_rotation(0.0, 0.0, 0.0, 'deg')
mesh_phantom1.set_position(-6, -10.0, -6, 'mm')
mesh_phantom1.set_mesh_octree_depth(4)
mesh_phantom1.set_visible(True)
mesh_phantom1.set_material('Lead')
mesh_phantom1.set_material_color('Lead', color_name='blue') # Uncomment for automatic color
The STL file of the centrifuge tube phantom is a cylindrical ring with a height of 100 mm, an outer radius of 11.25 mm, and an inner radius of 10.5 mm; the cylindrical soil phantom is a cylinder with a radius of 6 mm and a height of 20 mm. The geometric centers of both phantoms are at the coordinate origin, and there is no overlap between them at all—the cylindrical ring encloses the cylinder.
After running the code, I found that the generated projection.raw image only shows the projection of the centrifuge tube sample, with no information about the cylindrical soil reflected. However, if I change mesh_phantom1.set_position(-6, -10.0, -6, 'mm') to mesh_phantom1.set_position(-100, -10.0, -6, 'mm') (at which point the cylindrical ring and the cylinder no longer have an enclosing or overlapping relationship), the information of the soil cylinder will appear in the projection.raw file generated after running the code.
What causes this issue and how can it be resolved? I would be extremely grateful for your answer. Best regards!
#23
Geometry, Material & Navigation / Re: The meaning of source_isoc...
Last post by mwj12 - Nov 29, 2025, 04:11 AMThanks!
#24
Geometry, Material & Navigation / Re: Angular rotation conventio...
Last post by mwj12 - Nov 29, 2025, 04:11 AMGreat, thanks!
#25
Geometry, Material & Navigation / Re: The meaning of source_isoc...
Last post by didier.benoit - Nov 28, 2025, 07:40 PMIn version 1.3:
GGEMSXRaySource = independent source, with its own position/orientation.
GGEMSCTSystem = CT system geometry description (isocentre → source → detector distances).
The CT system assumes a specific scanning geometry (as in a real CT gantry), and these distances are internal parameters used for projections and detector placement.
This is why you can create several GGEMSXRaySource and several GGEMSCTSystem objects independently:
the CT system does not track or reference a specific GGEMSXRaySource.
If several sources exist, the CT system geometry stays the same and is not "linked" to one of them.
It simply defines its own source position relative to its isocentre internally.
GGEMSXRaySource = independent source, with its own position/orientation.
GGEMSCTSystem = CT system geometry description (isocentre → source → detector distances).
The CT system assumes a specific scanning geometry (as in a real CT gantry), and these distances are internal parameters used for projections and detector placement.
This is why you can create several GGEMSXRaySource and several GGEMSCTSystem objects independently:
the CT system does not track or reference a specific GGEMSXRaySource.
If several sources exist, the CT system geometry stays the same and is not "linked" to one of them.
It simply defines its own source position relative to its isocentre internally.
#26
Geometry, Material & Navigation / Re: Angular rotation conventio...
Last post by didier.benoit - Nov 28, 2025, 07:32 PMIn GGEMS 1.3, the three angles (rx, ry, rz) are applied as extrinsic rotations about the global X, Y and Z axes, in this order (X → Y → Z).
Internally the code composes the rotation matrix as Rz * Ry * Rx, which, with the convention used in GGEMS (column vectors, active rotations), corresponds to a rotation first about X, then about Y, then about Z.
In GGEMS v2, the whole transformation system (rotations and translations) will be redesigned and much more thoroughly documented, with explicit conventions on Euler angles, rotation order, and possibly quaternions.
Internally the code composes the rotation matrix as Rz * Ry * Rx, which, with the convention used in GGEMS (column vectors, active rotations), corresponds to a rotation first about X, then about Y, then about Z.
In GGEMS v2, the whole transformation system (rotations and translations) will be redesigned and much more thoroughly documented, with explicit conventions on Euler angles, rotation order, and possibly quaternions.
#27
Geometry, Material & Navigation / The meaning of source_isocente...
Last post by mwj12 - Nov 26, 2025, 04:50 AMIn the doc examples, it appears that CT x-ray sources and CT detectors are independent elements, created respectively with GGEMSXRaySource and GGEMSCTSystem. For example, In visualization.py, it is shown how you can have two GGEMSXRaySource and two GGEMSCTSystem components in the same simulation, none belonging to the other.
How is it then that each GGEMSCTSystem object has geometry parameters source_isocenter_distance and source_detector_distance which seem to be tied to a particular x-ray source? In particular, when we use code like the following to set these parameters, which x-ray source are the distances set relative to if there happens to be more than one source?
How is it then that each GGEMSCTSystem object has geometry parameters source_isocenter_distance and source_detector_distance which seem to be tied to a particular x-ray source? In particular, when we use code like the following to set these parameters, which x-ray source are the distances set relative to if there happens to be more than one source?
Code Select
cbct_system = GGEMSCTSystem('detector')
cbct_system.set_ct_type('flat')
cbct_system.set_source_detector_distance(1500.5, 'mm')
cbct_system.set_source_isocenter_distance(900.0, 'mm')
#28
Geometry, Material & Navigation / Angular rotation conventions
Last post by mwj12 - Nov 20, 2025, 01:17 PMWhen specifying the angular pose of an element, e.g.,
Code Select
phantom.set_rotation(30.0, 40.0, 50.0, 'deg')
I assume this specifies a sequence of rotations about the X, Y, and Z axes, but in what order? And are these intrinsic or extrinsic rotations? #29
Output Data / Re: CBCT simulation output (en...
Last post by mwj12 - Nov 19, 2025, 05:47 PM OK. In any case, I think I found a simpler workaround. If you modify the spectrum.dat file so that fraction of photons in each row of the table is weighted by the photon energy, it should give you the same mean signal (scatter and primary?) as an energy-integrating detector. It won't give the same noise statistics, but for my present purposes, that's okay.
#30
Output Data / Re: CBCT simulation output (en...
Last post by didier.benoit - Nov 19, 2025, 11:31 AMYou can already add the number of source you want in GGEMS and set the number of particles.
You have a exemple with to source here https://doc.ggems.fr/v1.3/example_6.html, you can see the macro file in 'ggems/examples/6_Visualization'. I don't have the commands that ChatGPT wrote you, but you can implement and adapt to you case.
You have a exemple with to source here https://doc.ggems.fr/v1.3/example_6.html, you can see the macro file in 'ggems/examples/6_Visualization'. I don't have the commands that ChatGPT wrote you, but you can implement and adapt to you case.