Skip to content

FDK: do not apply Wang detector-offset weights on short scans (Python… - #778

Open
yliu88au wants to merge 1 commit into
CERN:masterfrom
liu005:fix/wang-short-scan-gate
Open

yliu88au wants to merge 1 commit into
CERN:masterfrom
liu005:fix/wang-short-scan-gate

Conversation

@yliu88au

@yliu88au yliu88au commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

What is wrong. Wang's displaced-detector weighting assumes a full circular scan: it ramps one side of the detector down and relies on the opposing (beta + pi) views to bring the ray coverage back to uniform. On a short scan those opposing views do not exist, so the ramp survives into the reconstruction as a one-sided shading (a "teardrop"). Both bindings switch the weights on whenever offDetector is non-zero, with no check of the scan arc - and a sub-pixel calibrated offset is enough to trigger it, so a short scan with a calibrated geometry was silently shaded.

Fix. FDK skips the Wang weights when the angles do not cover a full circle. The test is the one MATLAB's FDK.m already uses to decide Parker weighting (max - min < 2*pi - 1.5*max(step) on the in-plane angle), so a full circle sampled with endpoint=False still gets the weights and the two bindings agree.

  • Python: is_short_scan(angles) in single_pass_algorithms.py (accepts (n,) or (n, 3)), used by FDK; a verbose message says when the weights were skipped.
  • MATLAB: the same condition in FDK.m with a warning.

Full scans are unchanged: the weights are applied exactly as before.

Example (Python/demos/d26_ShortScanWangWeights.py): a uniform cylinder (mu = 0.02), 200-degree scan, 64^3. Left/right interior ratio of the reconstruction:

case left/right ratio
centred detector 1.002
0.1 mm offset, Wang applied (before) 1.171
0.1 mm offset, Wang skipped (after) 1.002

d26

A MATLAB twin of the demo, MATLAB/Demos/d26_ShortScanWangWeights.m, reproduces the old behaviour by applying redundancy_weighting by hand and then calls the default FDK; I could not run MATLAB here, so it is untested - please try it if you can.

Tests (Python/tests/test_fdk_short_scan_wang.py): seven pure-NumPy classification cases (full circle with and without endpoint, 200 degrees, half circle, Euler triplets, descending angles, single angle) and one GPU reconstruction test asserting the offset short scan matches the centred one to 5 %.

Not in this PR. Python's FDK still calls filtering(..., parker=False) (the # TODO: Fix parker in filtering.py), so Python short scans get no Parker weights where MATLAB applies them by default. With parkerweight fixed in #767 that parity is a separate, small follow-up.
PR_class2_d26_short_scan_wang

… + MATLAB)

Wang's displaced-detector weights assume a full circle: they ramp one side of
the detector down and rely on the opposing (beta + pi) views to bring the
coverage back to uniform. On a short scan those views do not exist, so the
ramp survives into the reconstruction as a one-sided shading, and any
non-zero offDetector - a sub-pixel calibrated value is enough - switched the
weights on with no check of the scan arc.

Python: is_short_scan(angles) (the test FDK.m already uses for the Parker
default: max - min < 2*pi - 1.5*max(step), so endpoint=False full circles are
not short); FDK skips the weights and says so when verbose. MATLAB: the same
condition in FDK.m with a warning. Full scans unchanged.

Demo d26 (Python; MATLAB twin untested here): uniform cylinder, 200-degree
scan, 0.1 mm offset - left/right interior ratio 1.171 with the weights,
1.002 without, 1.002 for the centred reference. Tests: 7 pure-NumPy
classification cases + 1 GPU reconstruction test.
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