This notebook re-uses material from Jupyter Book by Jean-Michel Létang: X-ray imaging: Physics, Instrumentation & Applications.
is not a replacement for Monte Carlo methods, it's a complement when a trade-off between speed and accuracy must met.
pip install gvxr
;Language | files | blank | comment | code |
---|---|---|---|---|
C/C++ Header | 88 | 5585 | 12720 | 38687 |
C++ | 117 | 11724 | 14024 | 33256 |
HTML | 50 | 592 | 474 | 13100 |
XML | 5 | 0 | 0 | 12121 |
... | ... | ... | ... | ... |
Language | files | blank | comment | code |
---|---|---|---|---|
... | ... | ... | ... | ... |
TeX | 17 | 986 | 747 | 5441 |
CMake | 69 | 1410 | 1448 | 4490 |
SWIG | 2 | 736 | 516 | 4010 |
Python | 31 | 1383 | 1232 | 3541 |
Markdown | 22 | 767 | 0 | 2155 |
GLSL | 56 | 1029 | 2961 | 2060 |
CSS | 3 | 307 | 80 | 1481 |
JavaScript | 24 | 105 | 210 | 1107 |
XSD | 2 | 101 | 10 | 1086 |
CSV | 7 | 1 | 0 | 379 |
make | 5 | 36 | 18 | 234 |
Windows Module Definition | 1 | 0 | 0 | 183 |
Text | 7 | 12 | 0 | 166 |
Bourne Shell | 17 | 51 | 67 | 128 |
... | ... | ... | ... | ... |
Language | files | blank | comment | code |
---|---|---|---|---|
... | ... | ... | ... | ... |
Java | 1 | 15 | 24 | 51 |
TOML | 1 | 4 | 2 | 44 |
Ruby | 1 | 17 | 26 | 41 |
C# | 1 | 12 | 23 | 39 |
MATLAB | 1 | 16 | 25 | 39 |
R | 1 | 14 | 26 | 35 |
Perl | 1 | 15 | 21 | 34 |
Tcl/Tk | 1 | 15 | 24 | 33 |
DOS Batch | 1 | 4 | 0 | 20 |
XSLT | 1 | 0 | 5 | 10 |
SUM: | 533 | 24937 | 34683 | 123971 |
The API is typically used to interact with a graphics processing unit (GPU), to achieve hardware-accelerated rendering.
In other words, takes polygon meshes as an input to produce 2D images.
View from Mount Jalla on the ESRF and ILL in Grenoble | Scanned object | CT slice |
---|---|---|
Vidal, Franck; Mitchell, Iwan; Letang, J.M. In: Precision Engineering, Vol. 74, 01.03.2022, p. 110-125. DOI: 10.1016/j.precisioneng.2021.10.014
X-ray tube principle: William Coolidge in 1913 | Old X-ray tube (glass wall chamber) |
---|---|
ESRF, Grenoble, France | Diamond Light Source, Didcot, UK |
---|---|
Source: Photograph by German Wikipedian Christian Hendrich, October 2004 | Copyright of Diamond Light Source Ltd |
For most X-rays imaging modalities, only directly transmitted photons are essential:
The linear attenuation coefficient $\mu$ appears in the Beer-Lambert Attenuation law which gives the number of directly transmitted photons $N_{out}$ (i.e. without interaction) in terms of the number of incident photons $N_{in}$: $$ N_{\mathrm{dt}}(E)=N_0(E)\exp(-\mu(E)X) $$ where $X$ is the thickness of the traversed material. This expression is only valid for photons which have the same energy $E$.
%matplotlib widget
import utilities
import ipywidgets as widgets
widgets.interact_manual(utilities.mu,material=widgets.Dropdown(options=[('Polyethylene','H2C'),('Water','H2O'),('Aluminium','Al'),('Copper','Cu'),('Yttrium','Y'),('Tin','Sn'),('Lead','Pb')],value="H2C",layout={'width': 'max-content'},description='Material:',style={'description_width': 'initial'}));
In the previous cell,
Run Interact
???
in the cell below with the corresponding valuemu_Cu = ??? # Linear attenuation of copper at 100 keV
N_0 = 500 # Number of incident photons
X_Cu = 1 # Thickness in cm
N_dt = N_0 * math.exp(-mu_Cu * X_Cu)
print("Out of", N_0, "photons, only", round(N_dt), "are transmitted")
X_H2O = None # Thickness in cm, it is unknown
mu_H2O = ??? # Linear attenuation of water at 100 keV
X_H2O = (-math.log(N_dt / 500)) / mu_H2O
print(round(X_H2O), "cm of water is needed to stop as many photons of 100 keV as", X_Cu,"cm of copper")
N_dt = N_0 * math.exp(-mu_H2O * X_H2O)
print("Out of", N_0, "photons, only", round(N_dt), "are transmitted")
Given $E$, $L_p$ and $\mu$, we can compute X-ray images.
Intersection sorting is actually not needed!
Lp=Σi - sng(V · Ni) x di
[^1]: In OpenGL a shader program is a small program that is usually run on a GPU in parallel for every pixel of an image.
[^2]: See DOI: 10.2312/LocalChapterEvents/TPCG/TPCG09/025-032 for more details.
pixel = E x Nout
pixel = E x Nin(E) e(-Σi μi Lp(i))
The Beer-Lambert law is broken down in several rendering passes:
μ is computed using Mass Attenuation Coefficients (μ/ρ) and material density (ρ).
Are the values used in gVirtualXRay accurate?
Are the Beer-Lambert law implementations accurate?
Are the simulated images accurate?
We simulate a test case twice:
GATE is an opensource software developed by an international collaboration. Its focus is on Monte Carlo simulation in medical imaging and radiotherapy. GATE makes use of the Geant4 libraries. Geant 4 is CERN's Monte Carlo simulation platform dedicated to particle physics in nuclear research. CERN is the European Organization for Nuclear Research.
Simulation parameters | Image computed with GATE (2 weeks of computations on supercomputer) | Image computed with gVirtualXRay (less than 1 sec. of computations on GPU) |
---|---|---|
Normalised cross-correlation (NCC) = 99.747%
Lungman phantom | 3D model of the phantom, source and detector |
---|---|
Normalised cross-correlation (NCC) = 98.92%
This research and/or training day would not have been possible without Jean Michel Létang, Jean Yves Buffière, Nicolas Freud, Nigel John, Tianci Wen, Iwan Mitchell, Jammie Pointon, Llion Evans, Ben Thorpes, David Fairbrother, ...