Summary
vo-all stripe removal, applied to the full-row range of a densely-absorbing sample, produces a reconstruction where every in-FOV voxel is a single constant (~2.4e-4) and every out-of-FOV voxel is 0 — no sample structure visible. Bug is independent of --vo-all-la-size (tested 51, 61, 201, all produce the same collapse). Row subsets of the same dataset reconstruct correctly. Switching to --remove-stripe-method fw on the same command produces a correct reconstr
uction.
Steps to reproduce
Dataset: cast_LM10_FS0_s2_5x_Cu2_118.h5 (2-BM, 1801 projections, 2426×3232 detector, transmission ratio ~0.26 — heavily absorbing).
tomocupy recon_steps \
--file-name <raw.h5> \
--rotation-axis-auto auto --rotation-axis-method vo \
--reconstruction-type full \
--propagation-distance 200 --fbp-filter shepp \
--pixel-size 1.4 --energy 30 \
--retrieve-phase-method paganin --retrieve-phase-alpha 0.001 \
--remove-stripe-method vo-all \
--flat-linear True
Expected behavior
Normal Paganin-processed reconstruction with values in the ±0.05 range and visible sample structure (like the fw output confirms is possible on this dataset).
Actual behavior
/exchange/data has correct shape (2426, 3232, 3232) float32, correct file size, no crash, no warnings in the log. But the numerical content is:
- In-FOV voxels: all ≈ 2.3929265e-4 (44,743 distinct values in a 5×10⁻⁷ range around this constant — essentially a plateau)
- Out-of-FOV voxels: exactly 0
- No sample structure visible; renders as a uniform white disk
Bisect showing row-range dependence
Same command with different --start-row / --end-row:
| range |
rows |
outcome |
mid-slice max |
| 0..1213 |
1213 |
OK |
0.0144 |
| 1213..2426 |
1213 |
BROKEN |
2.4e-4 |
| 600..1800 |
1200 |
BROKEN |
2.4e-4 |
| 1213..1500 |
287 |
BROKEN |
4.4e-4 (different constant) |
| 1500..1800 |
300 |
BROKEN |
2.4e-4 |
| 1800..2426 |
626 |
BROKEN |
2.4e-4 |
| 1400..1500 |
100 |
OK |
0.0026 |
Rows 1500..1800 have raw row-mean 138–172 vs the volume median of 410 — those rows are heavily attenuated (sample dominates the FOV). This appears to be the trigger content for vo-all's collapse.
Independence from --vo-all-la-size
Tested with --vo-all-la-size 51 (below default 61) and with 201 (user's original). Both produce the same collapsed constant. Bug is not in the filter-window sizing; it's in vo-all's core estimation logic on this input class.
Fix / workaround
Switch to --remove-stripe-method fw. Same command otherwise. Produces a correct full-volume reconstruction (values −0.038 to +0.053, sample structure visible).
Suspected root cause
vo-all's stripe estimation likely uses a global reduction across z-rows. When the batch includes rows where the sample dominates the FOV (dim raw signal), the estimator produces a corrupt "stripe" pattern that's actually the sample profile itself. That correction, when applied globally to all rows in the batch, cancels out the reconstruction, collapsing all in-FOV voxels to a constant. Row subsets that avoid the problematic z-band reconstruct fine.
Would need to inspect remove_stripe._rs_large3 / _rs_dead3 and their handling of very low mean row-intensity to confirm.
Environment
- tomocupy 1.1.0 installed from
decarlof/tomocupy fork main branch (which is upstream + a few decarlof-specific fixes; no vo-all-related fork changes)
- cupy 12.3, CUDA 12.1 (system)
- Linux, tomo4 at APS 2-BM
- HDF5_USE_FILE_LOCKING=FALSE (NFS output dir; unrelated to this bug)
Summary
vo-allstripe removal, applied to the full-row range of a densely-absorbing sample, produces a reconstruction where every in-FOV voxel is a single constant (~2.4e-4) and every out-of-FOV voxel is 0 — no sample structure visible. Bug is independent of--vo-all-la-size(tested 51, 61, 201, all produce the same collapse). Row subsets of the same dataset reconstruct correctly. Switching to--remove-stripe-method fwon the same command produces a correct reconstruction.
Steps to reproduce
Dataset:
cast_LM10_FS0_s2_5x_Cu2_118.h5(2-BM, 1801 projections, 2426×3232 detector, transmission ratio ~0.26 — heavily absorbing).Expected behavior
Normal Paganin-processed reconstruction with values in the ±0.05 range and visible sample structure (like the
fwoutput confirms is possible on this dataset).Actual behavior
/exchange/datahas correct shape (2426, 3232, 3232) float32, correct file size, no crash, no warnings in the log. But the numerical content is:Bisect showing row-range dependence
Same command with different
--start-row/--end-row:Rows 1500..1800 have raw row-mean 138–172 vs the volume median of 410 — those rows are heavily attenuated (sample dominates the FOV). This appears to be the trigger content for vo-all's collapse.
Independence from
--vo-all-la-sizeTested with
--vo-all-la-size 51(below default 61) and with201(user's original). Both produce the same collapsed constant. Bug is not in the filter-window sizing; it's in vo-all's core estimation logic on this input class.Fix / workaround
Switch to
--remove-stripe-method fw. Same command otherwise. Produces a correct full-volume reconstruction (values −0.038 to +0.053, sample structure visible).Suspected root cause
vo-all's stripe estimation likely uses a global reduction across z-rows. When the batch includes rows where the sample dominates the FOV (dim raw signal), the estimator produces a corrupt "stripe" pattern that's actually the sample profile itself. That correction, when applied globally to all rows in the batch, cancels out the reconstruction, collapsing all in-FOV voxels to a constant. Row subsets that avoid the problematic z-band reconstruct fine.Would need to inspect
remove_stripe._rs_large3/_rs_dead3and their handling of very low mean row-intensity to confirm.Environment
decarlof/tomocupyfork main branch (which is upstream + a few decarlof-specific fixes; no vo-all-related fork changes)