Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions docs/xray/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,13 @@ For Python A/B checks, pass `batch_rows=False` to
`cuphoton.xray.detector_artifacts.build_detector_artifacts_cupy` to force
the serial row loop. The default, `True`, batches eligible rows. The manifest
records this choice, and serial runs have distinct configuration and resume
identities. Frequency, amplitude, and FFT-frequency arrays match exactly in
the batch-versus-row regression cases; `fft_all` can differ by rounding from
the batched cuFFT plan (the normalized-trace tests use `atol=1e-15`).
identities. Batch-versus-row regression checks preserve array shapes, dtypes,
finite masks, zero padding, mode positions, fit status and FFT frequencies
exactly. Fitted frequencies, amplitudes and filtered amplitude sums can differ
by floating-point rounding, as can the batched cuFFT output. The normalized
trace fixtures use `rtol=0`, with `atol=5e-15` for fitted outputs and
`atol=1e-15` for `fft_all`; these bounds describe those fixtures rather than
arbitrary input scales.

`--fit-diagnostics summary` writes one status-aware record per detector row
within each processed tile, covering the tile's `tile_x_start` to
Expand Down
13 changes: 10 additions & 3 deletions tests/xray/test_detector_artifacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -1475,13 +1475,20 @@ def _assert_detector_outputs_match(
expected: dict[str, np.ndarray],
) -> None:
for name, values in expected.items():
if name == "fft_all":
# The batched cuFFT plan rounds differently from per-row FFTs.
assert actual[name].shape == values.shape
assert actual[name].dtype == values.dtype
if name in {"freq_all", "amp_all", "amp_all_sum_filtered", "fft_all"}:
np.testing.assert_array_equal(
np.isfinite(actual[name]), np.isfinite(values)
)
np.testing.assert_array_equal(actual[name] == 0, values == 0)
# Row and batched GPU arithmetic can round differently. Keep a
# fixed absolute error budget for these normalized fixtures.
np.testing.assert_allclose(
actual[name],
values,
rtol=0.0,
atol=1e-15,
atol=1e-15 if name == "fft_all" else 5e-15,
)
else:
np.testing.assert_array_equal(actual[name], values)
Expand Down
Loading