xraymclib

xraymclib (Diagnostic X-ray Monte Carlo) is a radiation dose scoring library for diagnostic photon energies written in C++. The main goal for this library is to provide an accurate physics model to describe and model x-ray sources and estimate radiation doses by the Monte-Carlo method.

If you are looking for an application with graphical user interface to perform simulations, OpenXrayMC uses this library as Monte Carlo engine and also allows for import CT images and phantoms as scoring volumes.

Example of usage

A brief example on how to use xraymclib to simulate a pencilbeam of 60 keV onto a cylindar of aluminum is shown below.

  1#include "xraymc/beams/pencilbeam.hpp"
  2#include "xraymc/material/material.hpp"
  3#include "xraymc/transport.hpp"
  4#include "xraymc/world/visualization/visualizeworld.hpp"
  5#include "xraymc/world/world.hpp"
  6#include "xraymc/world/worlditems/depthdose.hpp"
  7#include "xraymc/world/worlditems/enclosedroom.hpp"
  8
  9#include <algorithm>
 10#include <iostream>
 11#include <thread>
 12
 13void example()
 14{
 15    // Create a thin aluminium cylinder and print depth dose
 16    std::cout << "Example Pencilbeam\nTransport of monoenergetic photons in a thin long aluminium cylinder\n";
 17
 18    // Start creating a depthscore cylinder
 19    constexpr int N_ATOMIC_SHELLS = 5; // Number of atomic shells to consider binding energies for (5 is more than sufficient).
 20    constexpr int LOW_ENERGY_CORRECTION = 1; /* 0: No binding energy correction, 1: Livermore correction, 2; impulse approx. correction*/
 21
 22    using Cylinder = xraymc::DepthDose<N_ATOMIC_SHELLS, LOW_ENERGY_CORRECTION>;
 23    using Room = xraymc::EnclosedRoom<N_ATOMIC_SHELLS, LOW_ENERGY_CORRECTION>;
 24
 25    // Create a world that can consist of one or more depthdose objects
 26    xraymc::World<Cylinder, Room> world;
 27    // Reserve number of items in world.
 28    world.reserveNumberOfItems(2);
 29
 30    // Adding a depthdose object
 31    auto& cylinder = world.template addItem<Cylinder>({ 1 /* cm radius */, 10 /* cm lenght */ }, "Cylinder");
 32
 33    // Set material and density
 34    auto aluminium = xraymc::Material<N_ATOMIC_SHELLS>::byZ(13).value();
 35    cylinder.setMaterial(aluminium, 2.27 /* g/cm3 */);
 36
 37    // Optional set cylinder material to water
 38    // auto water = xraymc::Material<N_ATOMIC_SHELLS>::byChemicalFormula("H2O").value();
 39    // cylinder.setMaterial(water, 1.0);
 40
 41    // Adding room with walls of concrete
 42    auto& room = world.template addItem<Room>({ 2 /*cm wall thickness*/, 200 /*cm inner walls sizes*/ }, "Room");
 43    auto concrete = xraymc::Material<N_ATOMIC_SHELLS>::byNistName("Concrete, Ordinary").value();
 44    auto concrete_density = xraymc::NISTMaterials::density("Concrete, Ordinary");
 45    room.setMaterial(concrete, concrete_density);
 46    //    Example for constructing other materials
 47    //    auto water = xraymc::Material<N_ATOMIC_SHELLS>::byChemicalFormula("H2O").value();
 48
 49    std::cout << "with radius " << cylinder.radius() << " cm and height " << cylinder.length() << " cm\n";
 50
 51    // Building world
 52    world.build();
 53
 54    // Define a radiation source
 55    xraymc::PencilBeam<> beam({ 0, 0, -10 } /* position */, { 0, 0, 1 } /* direction */);
 56    beam.setNumberOfExposures(64); // number of jobs
 57    beam.setNumberOfParticlesPerExposure(1000000); // histories per job
 58    beam.setEnergy(60.0);
 59
 60    // Run simulation
 61    auto nThreads = std::max(std::thread::hardware_concurrency(), std::uint32_t { 1 });
 62    auto time_elapsed = xraymc::Transport::runConsole(world, beam, nThreads, true);
 63
 64    // Get max dose and print some values
 65    std::cout << "Depth dose in cylinder for " << beam.numberOfParticles() << " photons of " << beam.energy() << " keV\n";
 66    std::cout << "Material: mass. att. coeff: " << aluminium.attenuationValues(beam.energy()).sum() << ", density: " << cylinder.density() << std::endl;
 67    std::cout << "Simulation time: " << time_elapsed << std::endl;
 68    std::cout << "Depth [cm], Dose per Air Kerma [mGy/mGy], Uncertainty [%], #Events\n";
 69    double max_dose = 0;
 70    for (std::size_t i = 0; i < cylinder.resolution(); ++i) {
 71        auto dose_val = cylinder.doseScored(i).dose();
 72        max_dose = std::max(max_dose, dose_val);
 73        std::cout << (cylinder.length() * (i + 0.5)) / cylinder.resolution() << ", ";
 74        std::cout << cylinder.doseScored(i).dose() << ", ";
 75        std::cout << cylinder.doseScored(i).relativeUncertainty() * 100 << ", ";
 76        std::cout << cylinder.doseScored(i).numberOfEvents() << std::endl;
 77    }
 78
 79    // Generate some images
 80    xraymc::VisualizeWorld viz(world);
 81    auto buffer = viz.template createBuffer<double>(1024, 1024);
 82    viz.setDistance(60);
 83    viz.setAzimuthalAngleDeg(90);
 84    viz.setPolarAngleDeg(30);
 85    viz.suggestFOV(4); // zoom = 2
 86    viz.setColorOfItem<std::uint8_t>(world.getItemPointerFromName("Cylinder"), { 255, 192, 203 }); // making it pink
 87    viz.generate(world, buffer);
 88    viz.savePNG("cylinder.png", buffer);
 89
 90    viz.setColorByValueMinMax(0.0, max_dose); // color by dose value
 91    viz.addColorByValueItem(world.getItemPointerFromName("Cylinder"));
 92    viz.generate(world, buffer);
 93    viz.savePNG("cylinder_dose.png", buffer);
 94}
 95
 96int main(int argc, char* argv[])
 97{
 98    example();
 99    return EXIT_SUCCESS;
100}

The example can be built by CMake with the following CMakeLists.txt file.

 1# testing to see if xraymclib target is defined. If it's not we will download 
 2# xraymclib at configure time.
 3IF( NOT TARGET libxraymc)
 4	include(FetchContent)
 5	## Adding xraymclib package
 6	FetchContent_Declare(
 7		libxraymc
 8		GIT_REPOSITORY https://github.com/medicalphysics/xraymclib.git
 9		GIT_TAG master
10		)
11	FetchContent_MakeAvailable(libxraymc)
12ENDIF()
13
14#Define an executable
15add_executable(pencilbeam pencilbeam.cpp)
16
17#Linking to xraymclib
18target_link_libraries(pencilbeam PRIVATE libxraymc)
19
20#Adding interaction binary data to example 
21#This cmake function vil copy physicslist.bin to executable folder
22xraymclib_add_physics_list(pencilbeam)
23
24install(TARGETS pencilbeam
25	RUNTIME DESTINATION examples)

See complete examples at:

C++ API

Other