Skip to content

feat(projection): distance-driven (DD3) projector replaces Siddon#17

Merged
Dale-Black merged 2 commits into
mainfrom
dd-raytracing
Jun 18, 2026
Merged

feat(projection): distance-driven (DD3) projector replaces Siddon#17
Dale-Black merged 2 commits into
mainfrom
dd-raytracing

Conversation

@Dale-Black

Copy link
Copy Markdown
Member

Summary

Replaces the Siddon ray-driven forward projector with a from-scratch Julia port of CatSim/XCIST's distance-driven (DD3) projector (De Man & Basu 2004), as a true drop-in. DD is the projector now — no kwarg/switch — and every downstream consumer (EICT poly, PCCT spectral, BHC, IR, FDK) works unchanged.

This is a non-breaking, drop-in change (no public API/signature changes), so it should cut a minor release (0.4.0 → 0.5.0).

What changed

  • New src/projection/dd.jl: dd_forward_project!/dd_forward_project (mono), dd_fused_poly_project! (EICT), dd_fused_spectral_project! (PCCT). DD3's image-stationary scatter kernel is reformulated as an output-stationary gather (one thread per sinogram cell) to keep the existing AK.foreachindex(sinogram) GPU pattern — race-free, no atomics.
  • Every internal siddon_* call swapped to dd_* (polychromatic ×3, photon_counting ×3, bhc/ir/utils/driver). siddon.jl is retained (unused) for reference + the DD-vs-Siddon comparison tests.
  • Docs gallery (nb01–04, nb07) regenerated against DD.

Validation

  • vs Siddon: mean |Δrel| ≈ 0.3%, central-ray exact, exact linearity, zero→zero; max ~2% is expected footprint-vs-chord edge difference.
  • Metal GPU bit-exact vs CPU.
  • Test suite green (2705/2705).
  • Docs notebooks (nb01–04, nb07) visually identical DD-vs-Siddon — VMI rod accuracy and FBP/recon image quality preserved.
  • Independently validated downstream on a realistic GE Revolution Apex head phantom (basis-brain-perfusion): correct HU + iodine enhancement.

🤖 Generated with Claude Code

Dale-Black and others added 2 commits June 18, 2026 12:01
…the pipeline

Port CatSim/XCIST's distance-driven 3D projector (gecatsim
DD3Proj_roi_notrans_mm) to Julia/AcceleratedKernels.jl as the forward
projector, reformulated output-stationary (gather) so it dispatches one
thread per sinogram cell via AK.foreachindex — same pattern as Siddon, no
atomics, portable to Metal/CUDA/ROCm/CPU.

New src/projection/dd.jl exposes drop-in replacements with identical
signatures to the Siddon entry points:
  dd_forward_project! / dd_forward_project
  dd_fused_poly_project!      (EI polychromatic; reuses Siddon's @generated
                               NTuple energy/Beer-Lambert helpers)
  dd_fused_spectral_project!  (PCCT tiled spectral)

A shared _dd_cell_setup maps each detector cell onto the iso-plane; _dd_bounds
bounds the contributing voxel range by inverse projection so per-cell work is
O(n_rows x footprint), comparable to a Siddon ray walk.

The internal pipeline now calls dd_* directly everywhere it called siddon_*
(polychromatic EI fused/tiled/sequential, photon_counting PCCT spectral+mono,
BHC sinogram + image-domain, IR ray-sums, OS-PWLS subset forward). No notebook
or downstream API changed. siddon.jl is retained for reference/benchmark and
the DD-vs-Siddon regression tests.

Validation (test/projection.jl, 28/28; full suite 2705/2705):
  - DD vs Siddon line integrals: mean 0.3% / median 0 / max <2% (footprint vs
    chord edge diff, expected), exact on the central ray, linear in mu.
  - fused poly / spectral vs Siddon fused: bin means identical to 4 dp.
  - Metal bit-exact vs CPU (mono 0.0, poly 4.8e-7, spectral 1.1e-8).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Re-ran nb01-04 and nb07 against the new distance-driven (DD3) projector and
refreshed their docs/assets PNGs, so the gallery reflects DD output (visually
identical to the Siddon baseline, no quantitative regression). nb03 also drops
its SVD sinogram denoise to passthrough (SVD_SIGMA_PX 0.0).

Ignore PlutoSpace/pluto-collab *.pluto-cache.toml cell-output caches (tens of
MB, regenerated every run).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Dale-Black Dale-Black merged commit eb60159 into main Jun 18, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant