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:

_images/template.png

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.

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();