●  Open Source · MITv0.15 · Julia 1.12

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.

Open
Source
Gammex Model 472 phantom label mapXCAT chest reconstructed with FDK and with hybrid IRGammex 472 reconstructed with FBP and with hybrid IR at 200 mA and at 50 mA
02
Detector
families
05
Structs to
a scan
04
Clinical scanner
models
12
Worked
notebooks
§ 02  Quick start

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)
§ 03  What's inside

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.

Detectors

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.

EICTScannerPCCTScanner
Physics

Polychromatic 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.

SimOptionsCTProtocol
Projectors

One 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_paths
Reconstruction

FDK, 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_water
Spectral

VMI 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_basis
Denoising

SpectralHYPR

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_hypr
Dose

CTDIvol 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_dose
Phantoms

Calibration 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_recon
Portability

Written 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_workspace
§ 05  Where next

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.

If BasisSimulator.jl is useful in your work, please cite: Black D, Khodajou-Chokami H, Molloi S. BasisSimulator.jl: Open-source polychromatic CT simulation with a GPU-portable reconstruction stack. SoftwareX 2026;35:102910. doi:10.1016/j.softx.2026.102910