feat(projection): distance-driven (DD3) projector replaces Siddon#17
Merged
Conversation
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
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 existingAK.foreachindex(sinogram)GPU pattern — race-free, no atomics.siddon_*call swapped todd_*(polychromatic ×3, photon_counting ×3, bhc/ir/utils/driver).siddon.jlis retained (unused) for reference + the DD-vs-Siddon comparison tests.Validation
🤖 Generated with Claude Code