From 973194be2e9b945036dabef1ea3c4bdd11ff753f Mon Sep 17 00:00:00 2001 From: Paul Zeiger Date: Thu, 8 Oct 2026 17:09:47 +0000 Subject: [PATCH 1/2] Changelog entries for abTEM#556 Seven fixes from abTEM#556 that a user of v1.0.10 can hit, with the two changes in results (integrate_gradient offset, block_direct default radius) marked as behaviour changes. Co-Authored-By: Claude Sonnet 5.5 --- docs/abtem/changelog.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/abtem/changelog.md b/docs/abtem/changelog.md index 4559216f..345cfa4c 100644 --- a/docs/abtem/changelog.md +++ b/docs/abtem/changelog.md @@ -110,6 +110,34 @@ Bugfixes: - Warnings replace silent fallbacks: multi-GPU requested but declined (with the reason), a missing `if __name__ == "__main__"` guard, and a grid size that forces the Bluestein fallback (naming the next fast size) +- Changed results of `integrate_gradient` and `block_direct()`, and fixes to lazy `Waves.normalize()`, eager + `SMatrix.build()`, `GPAWPotential` with a trajectory and arithmetic on CuPy data + ([PR #556](https://github.com/abTEM/abTEM/pull/556)) + - **Behaviour change:** `Images.integrate_gradient` shifts every image of an ensemble so that its own + minimum is 0. An eager ensemble previously shared one constant, the minimum over the whole ensemble, and + a lazy result was shifted by the minimum of each dask block, so it depended on the chunking. Only the + offset of an ensemble member differs; a single image gives the same result. This applies to + `DiffractionPatterns.integrated_center_of_mass` as well + - **Behaviour change:** `DiffractionPatterns.block_direct()` without a `semiangle_cutoff` in the metadata + blocks only the zero-angle pixel: the default radius is half the smaller angular sampling. It was the + larger angular sampling, which also zeroed the neighbouring pixels (four, for similar samplings); for the + pattern of a single unit cell those are the first-order reflections. Patterns with a `semiangle_cutoff` + and calls with an explicit `radius` are unchanged. With `margin=True` and no `radius`, the margin (the + larger angular sampling) is added to the new, smaller radius, so fewer pixels are blocked than before + - Lazy `Waves.normalize()` raised `AttributeError`; it now gives the eager result for any chunking, + whether the waves are stored in real or reciprocal space + - Under `float64` the eager `SMatrix.build()` stored `complex64` plane waves; it now follows the configured + precision, as the lazy build does. The eager S-matrix, on the device or on the host, is `complex128` and + takes twice the memory it did; `float32` is unchanged + - Eager `SMatrix.build()` with `store_on_host=True` raised `AttributeError` on the CPU device + - A `GPAWPotential` of a single calculator with an `AtomsEnsemble` or `EnergyResolvedAtomsEnsemble` as + `frozen_phonons` raises a `ValueError` at construction. It was accepted, and then raised `TypeError` in + every build and multislice. One calculator takes `FrozenPhonons`; for a trajectory, pass one calculator + per frame + - Arithmetic between CuPy data and a host operand raised `TypeError`. `+`, `-`, `*`, `/` and `**`, + including the reflected forms, move a NumPy array, a dask array of NumPy chunks or an array object with + CPU data to the device. The result is on the device of the CuPy data, and lazy if either side is. The + in-place forms (`+=`, `-=`, `*=`, `/=`) accept a NumPy array or an eager CPU object Documentation: From 5a79856d0b728a80a7ab4412149187795b87bcf5 Mon Sep 17 00:00:00 2001 From: Paul Zeiger Date: Fri, 9 Oct 2026 06:33:05 +0000 Subject: [PATCH 2/2] Describe the CPU-GPU arithmetic error of abTEM#556 abTEM#556 now raises a TypeError naming copy_to_device for arithmetic between CPU and GPU data, in either operand order, instead of moving the host operand to the device. Co-Authored-By: Claude Opus 5.5 --- docs/abtem/changelog.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/abtem/changelog.md b/docs/abtem/changelog.md index 345cfa4c..134ac49f 100644 --- a/docs/abtem/changelog.md +++ b/docs/abtem/changelog.md @@ -111,7 +111,7 @@ Bugfixes: `if __name__ == "__main__"` guard, and a grid size that forces the Bluestein fallback (naming the next fast size) - Changed results of `integrate_gradient` and `block_direct()`, and fixes to lazy `Waves.normalize()`, eager - `SMatrix.build()`, `GPAWPotential` with a trajectory and arithmetic on CuPy data + `SMatrix.build()`, `GPAWPotential` with a trajectory and arithmetic between CPU and GPU data ([PR #556](https://github.com/abTEM/abTEM/pull/556)) - **Behaviour change:** `Images.integrate_gradient` shifts every image of an ensemble so that its own minimum is 0. An eager ensemble previously shared one constant, the minimum over the whole ensemble, and @@ -134,10 +134,11 @@ Bugfixes: `frozen_phonons` raises a `ValueError` at construction. It was accepted, and then raised `TypeError` in every build and multislice. One calculator takes `FrozenPhonons`; for a trajectory, pass one calculator per frame - - Arithmetic between CuPy data and a host operand raised `TypeError`. `+`, `-`, `*`, `/` and `**`, - including the reflected forms, move a NumPy array, a dask array of NumPy chunks or an array object with - CPU data to the device. The result is on the device of the CuPy data, and lazy if either side is. The - in-place forms (`+=`, `-=`, `*=`, `/=`) accept a NumPy array or an eager CPU object + - Arithmetic between CPU and GPU data (an array object with CuPy data and a NumPy array, a dask array of + NumPy chunks or an array object with CPU data, or the reverse) raises a `TypeError` that says to move + one operand with `copy_to_device`, in either operand order and for lazy data when the expression is + built. It raised CuPy's `TypeError` before, for lazy data only at compute time. NumPy scalars and Python + numbers are accepted as before Documentation: