Changelog#
The changes of each release, newest first. The changes of the next release go under a
heading ## Upcoming: <version>, which is renamed to the version when it is released.
1.0.11#
A bugfix release on top of 1.0.10 with fixes ported from dev; no features and no new defaults.
Plain potentials, plane-wave and probe multislice with default settings, ensembles of unweighted
parameters, zarr round trips and the configuration defaults are bit-identical to 1.0.10 at the
default float32 precision (checked on 66 scenarios).
Fixed: results that change#
Magnitudes are from small test systems and vary with the data.
4D-STEM and measurements
Centre of mass and iCOM are divided by the captured intensity (#417); an all-zero pattern gives NaN instead of 0.
Default diffraction patterns are unshifted: their coordinates,
azimuthal_average,bandlimitand centre of mass now agree with that (#463; azimuthal averages differ by up to 80 %).Radial bins are exactly
step_sizewide (#469; default ADF/HAADF move by 0.2 to 0.8 %,radial_binningby 13 to 33 %).A
FlexibleAnnularDetectorwithoutouterfollows the waves of each call, not the first ones it saw (#434).PolarMeasurements.integrateazimuthal limits (#459), rad/deg conversions (#458, off by 1e6),depth_profileandImages.coordinates(#461),interpolate_lineand2 / images(#470), periodic spline interpolation (#506).AnnularDetector(offset=...)is applied (#324);get_detector_regionreturns percent as a float (#283).block_direct=Trueblocks the whole bright-field disk instead of 1 mrad (#484);block_direct()without cutoff blocks only the zero-angle pixel (#556).Reciprocal-space waves measure like real-space ones (#565, #566); lazy
gaussian_source_sizeis periodic like the eager one (#485);integrate_gradienttakes the minimum per image (#556).Seeded Poisson and scan noise give another realisation for the same seed (#464, #475). Float32 stays float32 in transfer functions,
integrate_gradientandcenter_of_mass(#604).PixelatedDetector(reciprocal_space=False)has real-space axes,WavesDetector(gpts=...)declares the right shape, andblock_directno longer grows its metadata (#499).
PRISM
Aberrated
SMatrix.reduce/scanmatchProbe(#318; 17 to 75 %). An eager frozen-phonon reduce is averaged like the lazy one (#576), and eagerSMatrix.scan/reducereduce theCTFensemble axes (#466). PRISM no longer leaves its outer angle on the caller’s detector (#491).
Potentials and atoms
orthogonalize_cellfollowed byPotentialno longer drops atoms near cell faces (#345, #390, #555; wurtzite GaN lost 2 of 8 atoms, projected potential +33 %). Non-periodic cells keep displaced atoms (#460, #555).CrystalPotentialhonoursfirst_slice/last_slice(#269);GPAWPotential(repetitions=...)was wrong by about 100 % (#494);GPAWParametrizationappliescharge(#329).GPAW and Bloch slices are integrated centred on their slices, which shifts each slice by dz/2 (5 % for GPAW, 17 to 30 % for Bloch; whole-cell sums unchanged) (#574);
ChargeDensityPotentialslices are sampled at midpoints (#472).IAM magnetic fields change by ~1e-6 and their slices are labelled
ÅT,ŲT(#543);projection="finite"with sigmas for only some elements dropped the others (#480); the GPAW magneticreal_spaceprojection ignoredfirst_slice(#544);wrapped_crop_2doutside the cell (#389); eager multislice of potentials with two or more ensemble axes scrambled the results (#333).
Bloch waves
Non-centrosymmetric structures were computed for the negated structure (#379; wurtzite exit waves change by up to 1.27).
The symmetrising metric is applied consistently (#448): the eigendecomposition and matrix-exponential paths now agree to rounding. For Si at 100 keV, default intensities change by R = 1.5e-3 to 2.2e-3 on the zone axis and 3e-4 to 1.3e-3 at a 7° tilt (R = Σ|ΔI| / ΣI).
Eager rotation ensembles (#450), A/B/C centring (#487) and CuPy scattering matrices (#449).
HRTEM and CTF
set_aberrations('scherzer')C10 sign and ordering (#471);apply_ctfno longer writes the waves’ energy into the CTF (#489).
Core-loss
Continuum normalisation (#364), the (2l+1) double count (#368; L2,3 ÷3, M4,5 ÷5), site threshold and a spurious 1.02 factor (#468; K +3 to 4 %, L2,3 −22 to −27 %) and the vxc vacuum tail (−4 % at 3 eV). Single-channel frozen-phonon core loss was
num_configstimes too large or zero (#387).
Backscattering
Weighted distributions
Distribution weights are probabilities applied when the ensemble is reduced (#466). In 1.0.10 a STEM focal spread was effectively a top-hat, an HRTEM Gaussian spread had a standard deviation of σ/√2, and tilt and aperture weights were ignored. The peak of the reduced intensity of a 200 kV, 25 mrad probe with
gaussian(σ, num_samples=11)defocus is 1.76 times the 1.0.10 value at σ = 25 Å and 2.21 times at 50 Å. Frozen-phonon results are unchanged.New:
OrdinalAxis.weights/from_distributionandreduce_ensemble(axis=).gaussianweights sum to one;normalize='intensity'and'amplitude'are deprecated;.sum()/.mean()over a weighted axis warn; negative or wrong-length weights raiseValueError. Bloch rotation spreads and noise axes carry no weights, as before. Zarr files with a weighted axis cannot be read by 1.0.10.
Distributed computations
The client’s configuration reaches the workers of a
distributedclient, also forto_tiffandto_zarr(compute=False)(#346). Workers used to see only the YAML defaults, so for exampleprecision='float64'runs were computed infloat32. Distributed results obtained with a non-default configuration are worth repeating.
Other
FFTW
fftnover three axes transformed the wrong axes and strided input withoverwrite_x=Trueraised (#558); a lazyfft2_convolvehad the wrong shape for long kernels (#577).Waves.phase_shiftrelabelled reciprocal-space waves and widened complex64 (#550), as didtile(renormalize=True)(#414); 1Dinterpolatelost float64/complex dtypes (#427);bandlimitandblock_direct(radius=0)kept the direct beam on some grids (#506).StructureFactorArray.get_projected_potentialhonourssampling=and an integergptsandIndexedDiffractionPatterns.positions_dictis complete (#456).
Fixed: errors and crashes#
No longer raising:
Images.scan_noise,apply_ctfat a second energy,number - Images, lazygaussian_filterwith a constant boundary, lazynormalize, single-pointGridScan, noisy near-orthogonalPotentialcells, tilted eager Bloch exit waves with scalar thickness,IndexedDiffractionPatterns.sort(), core loss on 16 or 17 pixel grids,AnnularDetectorover aLineScanwith an extra ensemble axis, GPAW 26 calculators, frozen-phononGPAWPotential, ensemble backscattering, A/B/C centring, graphene repeated along c, and numba typing on some numba/numpy pairings.TransitionPotentialArray.filter_siteswithAtomsof several elements and a threshold no longer raisesIndexError; it returns the kept atoms of the element of the transition potential, asAtomsforAtomsinput and as positions for positions (#375).show(overlay=...)of an ensemble that has no base axes, such as the integrated core-loss measurements of the core-loss tutorial, gave more line labels than lines, and an ensemble of complex lines fewer. Matplotlib 3.11 raises an error for this (“label must be scalar or have the same length as the input data”); older versions took the whole list as the label. The lines are now labelled by the axes that are overlaid.excitations_weightsfails no longer on NumPy 2 (np.math). On CuPy 14.2 a lazy FFT in a dask worker thread no longer fails withCUFFT_EXEC_FAILED(seecupy.fft-cache-size).
Changed: behaviour#
abTEM reads
~/.config/abtemand$ABTEM_CONFIGas well as dask’s configuration files (#416); 1.0.10 ignored them. A leftovercupy.fft-cache-size: 0 MBthere now disables the cuFFT plan cache.cupy.fft-cache-size, ignored in 1.0.10, is read and defaults toauto(25 % of the device memory per thread);0 MBdisables the cache,-1removes the bound, and a plan larger than the bound runs uncached with a warning.LineScan.anglereports degrees (#470).SegmentedDetector(to_cpu=...)defaults toTrueas documented (#371). Explodedshow()grids use 0.25 between panels (#354).New errors instead of wrong results: backscattering with exit planes that do not start at the entrance plane or are not after every slice (#562, #499); a built
TransitionPotentialArrayat another energy or grid (#386);PixelatedDetector(resample='uniform')without reciprocal space (#499);transition_potential_scanwithexpansion_scope="full"(#506).Zarr arrays over 512 MiB use a multi-chunk layout and a failed write removes the partial file (#363, #369).
GPAWParametrizationfor Pm, Sm, Eu and Pu falls back to an unpolarised atom with a warning (#467). Importingabtemno longer fails ifcupyx.scipy.ndimagecannot be loaded (#381).
1.0.10#
Features:
Expanded real-space multislice with propagator- and fully-corrected algorithms, and backscattered waves (PR #236)
Related internal function name change: standard multislice is now properly called
FourierMultislice
Updated
BullseyeApertureto use smoothed aperture edges/corners (PR #266)Logarithmic scale display for
DiffractionPatternsand images (PR #303)Finite-projection integrals 7x faster on CPU (PR #309)
Documentation:
Expanded tutorial on real-space multislice
Depth-profile visualization of potentials in the walkthrough
Single-file Zarr zip storage, logarithmic display scaling, soft Bullseye apertures, anisotropic Debye-Waller factors and B-factor conversion helpers
All published notebooks verified to run with this release
Dependencies:
NumPy 2.0 or newer is now required (PR #245)
GitHub actions based on
uvand now cover more versions (including Python 3.14) (PR #308)New branching structure:
devfor development,mainfor releases (only via PRs fromdev)Support for Zarr 3
ZipStore(requiringzarr>=3.1)Added Zstandard compression of the arrays in the ZipStore at default level 4 (hat tip: quantEM) (PR #252)
Deprecated
[gpu]optional dependency (as just specifyingcupywill not install the correct CUDA version)Moved
testing,docs, anddevfrom optional dependencies to groupsNarrow Dask version exclusion to !=2025.12.*,!=2026.1.0,!=2026.1.1 (PR #285)
Declared
sympyas an optional dependency (core-lossextra), required for core-loss EELS form factors (PR #320)
Bugfixes:
Frozen-phonon ensemble handling (PR #267 & PR #292)
May also have resulted in incorrect behavior with
ensemble_mean = Falsefor e.g. defocus distributions
CrystalPotentialwith frozen phonons bugs (especially bad on – luckily rare – eager compute) (PR #306)Minor bugs, unsafe patterns, and dead code (PR #265)
Anisotropic Debye-Waller factors for Bloch waves (PR #271)
Added helper functions to convert between crystallographic B-factors and thermal sigmas
Added missing
.calculate_exit_wavesforBlochwaveEnsemble(PR #294)Silent atom drop when
z-position lands inSliceIndexedAtomsblind spot (PR #273)Early-exit bug in
orthogonalize_cell(PR #291)Fixed broken tutorial workflow for core-loss filtered imaging (PR #284)
Minor performance improvements for
transition_potential_scan(PR #286)
Bullseyeaperture:ring_widthandspoke_widthare now validated, rejecting values that previously produced a silently wrong (solid disk) aperture; docstring corrected to describe the actual fractional units introduced by the soft-edge redesign (PR #319)Unified the task-level progress bar config key on
diagnostics.task_progress(Bloch-wave code paths previously read a different, non-functional key) (PR #321)
1.0.9#
Dependencies:
Support for
scipy>=1.7andcupy>=12.Restricted Dask versions (
>=2022.12.1,!=2025.12.*,!=2026.1.*) to avoid an issue with Numba in the latest ones
1.0.8#
Starting the changelog with version 1.0.8.
Features:
Fully featured Bloch-wave simulations
Simple real-space multislice algorithm
Core-loss filtered imaging
Structured illumination (custom apertures and phase plates)
Documentation:
Updated and fixed example gallery
Appendix on convergence
Expanded tutorial on orthogonal periodic supercells
Bugfixes:
Numerous small bugfixes and improvements