Polychromatic CT, end-to-end, on any GPU.
BasisSimulator.jl simulates energy-integrating and photon-counting CT scanners from the source spectrum to the detector counts, and reconstructs what they measure: FDK, helical WFBP, hybrid IR, and virtual monoenergetic images from dual-kVp, dual-source and photon-counting data, with the dose of every scan. One source tree runs on CUDA, Metal, ROCm, oneAPI and the CPU.
Source



families
a scan
models
notebooks
Phantom → sinogram → image,
in five structs.
A phantom, a scanner, a protocol, the physics and the output grid. The workspace allocates once and is reused on every call; the dose report comes with the scan.
import BasisSimulator as BS, GPUSelect
to_gpu = GPUSelect.Storage() # CuArray, MtlArray, ROCArray, oneArray, or Array
cpu = BS.create_gammex_472(n_voxels = 256, n_slices = 4, z_cm = 1.0)
phantom = BS.Phantom(to_gpu(cpu.mask), cpu.materials, cpu.voxel_size, cpu.origin, cpu.extent)
scanner = BS.EICTScanner(source_to_isocenter = 625.6, source_to_detector = 1100.0,
detector_rows = 32, detector_cols = 834,
detector_row_size = 0.625, detector_col_size = 0.6)
protocol = BS.CTProtocol(kVp = 120, mA = 200.0, views = 500, collimation_mm = 5.0)
sim_opts = BS.SimOptions()
rec_opts = BS.ReconOptions(matrix_size = (512, 512, 4), fov_cm = 35.0, z_cm = 0.5)
ws = BS.create_workspace(scanner, protocol, sim_opts, rec_opts, phantom)
dose = BS.simulate!(ws, phantom, protocol, sim_opts).dose # CTDIvol, DLP
bhc = BS.calibrate_bhc_water(sim_opts, protocol; scanner, geom = ws.geom)
sino = to_gpu(BS.apply_bhc_water(ws.sinogram, bhc))
fdk = BS.create_fdk_recon_workspace(sino, ws.geom, rec_opts.matrix_size)
hu = BS.to_hounsfield(Array(BS.reconstruct!(fdk, sino, ws.geom)); μ_water = bhc.μ_water_ref)Simulation, reconstruction,
spectral imaging.
Every effect a clinical acquisition applies is modelled where the scanner applies it, and every reconstruction reads the same geometry the simulation wrote.
Energy-integrating and photon-counting
Scintillators weighted by Monte Carlo efficiency tables for GE Gemstone and the Siemens Force and Definition Flash UFC crystals. CdTe, CZT or Si counting through a Monte Carlo detector response, with charge sharing, K-fluorescence, Monte Carlo pile-up and model-based pile-up and scatter correction.
EICTScannerPCCTScannerPolychromatic from the spectrum up
IPEM tungsten spectra, flat and added filters (Al, Ti, Sn, Cu), CatSim bowties, heel effect, focal-spot blur, fill factor, lag and scatter, then quantum and electronic noise drawn in the counts, before the log.
SimOptionsCTProtocolOne volume walk, the whole spectrum
The distance-driven :dd_fast projector integrates every energy in a single pass over arc or flat detectors with the quarter-detector offset; Siddon is kept for comparison. Path lengths can be cached and reused across tube voltages.
:dd_fastmaterial_pathsFDK, helical WFBP, hybrid IR
Cone-beam FDK, rebinned WFBP chosen automatically when the protocol has a pitch, and hybrid iterative reconstruction with one strength dial from 0 (FBP) to 100. Water beam hardening is calibrated from the detected spectrum itself.
reconstruct!calibrate_bhc_waterVMI from any spectral acquisition
Photon-counting bins, rapid kVp switching and dual-source pairs all go through one n-channel profile-likelihood water–iodine decomposition (or Cong's estimator), per-basis reconstruction, ACNR and virtual monoenergetic synthesis in HU.
vmi_pipelinespectral_basisSpectralHYPR
Generalized HYPR-LR in two places: on the counts of each detector row before the decomposition, and on the reconstructed basis pair. Also T-LBF for photon counting and ACNR.
SpectralHYPRhypr_lrimage_hyprCTDIvol and DLP of every scan
Monte Carlo of the simulated beam in the 16 and 32 cm CTDI phantoms: CTDI100 at the centre and periphery, CTDIw, CTDIvol and DLP, attached to every simulate! result.
result.dosecompute_doseCalibration phantoms and anatomy
Gammex 472, XCAT anatomies downloaded on demand, any label map with any XrayAttenuation material, and affine maps between the phantom, world and reconstruction grids for ground-truth overlays.
create_gammex_472load_xcat_male_chestresample_to_reconWritten once, for every backend
Kernels are written against AcceleratedKernels.jl; GPUSelect picks the device. Workspaces allocate every buffer once, so repeated scans do not allocate.
GPUSelect.Storagecreate_workspaceFigures the examples
draw themselves.
Each figure below is written by an example notebook when it runs. Open one to read the code that made it.

An XCAT chest with a material per organ, FDK beside hybrid IR at strength 60.

Dual-source 80/Sn140 kV virtual monoenergetic images on the SOMATOM Definition Flash.

30 cm of coverage: a 20 mm helix at pitch 1.0 against three 16 cm-beam axial stations 10 cm apart.

Monte Carlo detector efficiency: two UFC crystals and the Gemstone garnet.

Beam hardening and photon starvation from a user-defined titanium implant.

The same scan through CatSim/XCIST and through BasisSimulator on CPU and GPU.
Read, run,
build on it.
The walkthrough runs on a laptop in minutes; the notebooks are the full studies; the scanner page has the hardware parameter sets to copy.
Install, the five structs, FDK and HIR, dose, photon counting and VMI.
Twelve Pluto notebooks with their code, prose and figures.
GE Apex Elite, Siemens NAEOTOM Alpha, Force and Definition Flash.
Every exported function and type, from the docstrings.