Make a GGEMS Project
GGEMS is designed as a library, and can be called using either python or C++. The performance are the same.
Template
GGEMS (C++ or python) macros are writting following this template:
Python
Warning
Check your PYTHONPATH environment variable is set correctly.
Using GGEMS with python is very simple. In a folder storing your project write a python file importing GGEMS.
from ggems import *
Verbosity level is defined in the range [0;3]. For a silent GGEMS execution, the level is set to 0, otherwise 3 for lot of informations.
GGEMSVerbosity(0)
Necessary singletons should be called.
opencl_manager = GGEMSOpenCLManager()
opengl_manager = GGEMSOpenGLManager()
materials_database_manager = GGEMSMaterialsDatabaseManager()
processes_manager = GGEMSProcessesManager()
range_cuts_manager = GGEMSRangeCutsManager()
volume_creator_manager = GGEMSVolumeCreatorManager()
An OpenCL device could be selected.
opencl_manager.set_device_index(0)
A material database has to be loaded in GGEMS. A material file is provided in GGEMS in ‘data’ folder. This file can be copy and paste in your project, and a new material can be added inside it.
materials_database_manager.set_materials('materials.txt')
Photon physical processes are activated using the process name, the particle name and the associated phantom name (or ‘all’ for all defined phantoms).
processes_manager.add_process('Compton', 'gamma', 'all')
processes_manager.add_process('Photoelectric', 'gamma', 'all')
processes_manager.add_process('Rayleigh', 'gamma', 'all')
Physical tables can be customized by changing the number of bins and the energy range. The following values are the default values.
processes_manager.set_cross_section_table_number_of_bins(220)
processes_manager.set_cross_section_table_energy_min(1.0, 'keV')
processes_manager.set_cross_section_table_energy_max(10.0, 'MeV')
Range cuts are defined in distance, particle type has to be specified and cuts are associated to a phantom (or ‘all’ for all defined phantoms). The distance is converted in energy during the initialization step. During the simulation, if energy particle is below to a cut, the particle is killed and the energy is locally deposited.
range_cuts_manager.set_cut('gamma', 0.1, 'mm', 'all')
GGEMS can be launched using the GGEMS python class. All verboses can be set to ‘True’ or ‘False’. In ‘tracking_verbose’, the second parameters is the index of particle to track. The method ‘initialize’ intializes all objects in GGEMS, and the simulation starts with the method ‘run’.
ggems = GGEMS()
ggems.opencl_verbose(True)
ggems.material_database_verbose(True)
ggems.navigator_verbose(True)
ggems.source_verbose(True)
ggems.memory_verbose(True)
ggems.process_verbose(True)
ggems.range_cuts_verbose(True)
ggems.random_verbose(True)
ggems.profiling_verbose(True)
ggems.tracking_verbose(True, 0)
ggems.initialize(seed) #using a custom seed
# ggems.initialize()
ggems.run()
The last step, exit GGEMS properly by cleaning OpenCL:
ggems.delete()
opencl_manager.clean()
exit()
C++
Warning
Check your PATH (on Windows) and LD_LIBRARY_PATH (on Linux) environment variables are set correctly.
Warning
For better compatibility we recommend to compile your GGEMS applications in C++ with the same compiler as the one used to compile the GGEMS library.
First method (recommended method)
In C++, the easiest way to compile your own code is to create your application in the ‘example’ directory of GGEMS, and declare your application in the CMAKE of GGEMS. To do this, edit the ‘GGEMS/examples/CMakeLists.txt’ file:
# ...
ADD_SUBDIRECTORY(5_World_Tracking)
# ...
ADD_SUBDIRECTORY(MY_PROJECT)
# ...
In the previous example, we considered that you created a folder named ‘MY_PROJECT’ in GGEMS example directory.
From this step, you can take inspiration from other GGEMS examples by adding (optional) ‘src’ and ‘include’ directories if you need to implement new classes. Here is a complete sample CMakeLists.txt file:
PROJECT(MY_PROJECT)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
FILE(GLOB my_source ${PROJECT_SOURCE_DIR}/src/*.cc)
ADD_EXECUTABLE(my_project main.cc ${my_source})
TARGET_LINK_LIBRARIES(my_project ggems)
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION ggems/examples)
INSTALL(TARGETS my_project DESTINATION ggems/examples/MY_PROJECT)
Your application will be compiled together with the GGEMS library.
Second method
Create a project folder (named ‘my_project’ for instance), then create two other folders ‘include’ and ‘src’ if custom C++ classes are written. Create two files: ‘main.cc’ and ‘CMakeLists.txt’. At this stage, the folder structure is:
<my_project>
|-- include\
|-- src\
|-- main.cc
|-- CMakeLists.txt
A CMakeLists.txt file is required to build a C++ executable for GGEMS. An example is given on Windows using Visual C++.
CMAKE_MINIMUM_REQUIRED(VERSION 3.13 FATAL_ERROR)
SET(ENV{CC} "cl")
SET(ENV{CXX} "cl")
PROJECT(MYPROJECT LANGUAGES CXX)
# Finding CUDA and OpenCL
FIND_PACKAGE(CUDA REQUIRED)
SET(OpenCL_ROOT "${CUDA_TOOLKIT_ROOT_DIR}")
FIND_PACKAGE(OpenCL REQUIRED)
IF(${OpenCL_VERSION_STRING} VERSION_GREATER "1.2")
ADD_DEFINITIONS(-DCL_USE_DEPRECATED_OPENCL_1_2_APIS)
ENDIF()
# If OpenGL visualization if necessary
OPTION(OPENGL_VISUALIZATION "Using OpenGL for visualization" OFF)
IF(OPENGL_VISUALIZATION)
ADD_DEFINITIONS(-DOPENGL_VISUALIZATION)
FIND_PACKAGE(GLFW3 REQUIRED)
FIND_PACKAGE(OpenGL REQUIRED)
SET(GLEW_USE_STATIC_LIBS TRUE) # Using GLEW in static, important for Python!!!
FIND_PACKAGE(GLEW REQUIRED)
FIND_PACKAGE(glm REQUIRED)
GET_FILENAME_COMPONENT(GLM_INCLUDE_DIR ${glm_DIR}/../../../include ABSOLUTE)
ENDIF()
# Giving path to GGEMS headers and to GGEMS librarie
SET(GGEMS_INCLUDE_DIRS "" CACHE PATH "Path to the GGEMS include directory")
SET(GGEMS_LIBRARY "" CACHE FILEPATH "Path to GGEMS library (.lib or .so)")
# Forcing release mode
SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release" FORCE)
SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release")
# Compiling using c++17
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Ox /std:c++17")
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include ${GGEMS_INCLUDE_DIRS})
FILE(GLOB source ${PROJECT_SOURCE_DIR}/src/*.cc)
ADD_EXECUTABLE(my_project main.cc ${source})
IF(OPENGL_VISUALIZATION)
TARGET_LINK_LIBRARIES(my_project OpenCL::OpenCL ${GGEMS_LIBRARY} ${GLFW3_LIBRARY} OpenGL::GL OpenGL::GLU GLEW::glew_s glm::glm)
ELSE()
TARGET_LINK_LIBRARIES(my_project OpenCL::OpenCL ${GGEMS_LIBRARY})
ENDIF()
In main.cc file, GGEMS files are included:
#include <GGEMS/global/GGEMS.hh>
#include <GGEMS/global/GGEMSOpenCLManager.hh>
#include <GGEMS/graphics/GGEMSOpenGLManager.hh>
// ...
For silent GGEMS execution, the level is set to 0, otherwize 3 for maximum informations.
GGcout.SetVerbosity(0);
GGcerr.SetVerbosity(0);
GGwarn.SetVerbosity(0);
Necessary singletons should be called.
GGEMSOpenCLManager& opencl_manager = GGEMSOpenCLManager::GetInstance();
GGEMSMaterialsDatabaseManager& material_manager = GGEMSMaterialsDatabaseManager::GetInstance();
GGEMSVolumeCreatorManager& volume_creator_manager = GGEMSVolumeCreatorManager::GetInstance();
GGEMSProcessesManager& processes_manager = GGEMSProcessesManager::GetInstance();
GGEMSRangeCutsManager& range_cuts_manager = GGEMSRangeCutsManager::GetInstance();
An OpenCL device could be selected:
opencl_manager.DeviceToActivate(0);
A material database has to be loaded in GGEMS. A material file is provided in GGEMS in ‘data’ folder. This file can be copy and paste in your project, and a new material can be added inside it.
material_manager.SetMaterialsDatabase("materials.txt");
Photon physical processes are activated using the process name, the particle name and the associated phantom name (or ‘all’ for all defined phantoms).
processes_manager.AddProcess("Compton", "gamma", "all");
processes_manager.AddProcess("Photoelectric", "gamma", "all");
processes_manager.AddProcess("Rayleigh", "gamma", "all");
Physical tables can be customized by changing the number of bins and the energy range. The following values are the default values.
processes_manager.SetCrossSectionTableNumberOfBins(220);
processes_manager.SetCrossSectionTableMinimumEnergy(1.0f, "keV");
processes_manager.SetCrossSectionTableMaximumEnergy(1.0f, "MeV");
Range cuts are defined in distance, particle type has to be specified and cuts are associated to a phantom (or ‘all’ for all defined phantoms). The distance is converted in energy during the initialization step. During the simulation, if energy particle is below to a cut, the particle is killed and the energy is locally deposited.
range_cuts_manager.SetLengthCut("all", "gamma", 0.1f, "mm");
GGEMS can be launched using the GGEMS python class. All verboses can be set to ‘True’ or ‘False’. In ‘tracking_verbose’, the second parameters is the index of particle to track. The method ‘initialize’ intializes all objects in GGEMS, and the simulation starts with the method ‘run’.
GGEMS ggems;
ggems.SetOpenCLVerbose(true);
ggems.SetMaterialDatabaseVerbose(true);
ggems.SetNavigatorVerbose(true);
ggems.SetSourceVerbose(true);
ggems.SetMemoryRAMVerbose(true);
ggems.SetProcessVerbose(true);
ggems.SetRangeCutsVerbose(true);
ggems.SetRandomVerbose(true);
ggems.SetProfilingVerbose(true);
ggems.SetTrackingVerbose(true, 0);
ggems.Initialize(seed); // using a custom seed
// ggems.Initialize();
ggems.Run();
The last step, exit GGEMS properly by cleaning OpenCL:
GGEMSOpenCLManager::GetInstance().Clean();