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
12 changes: 7 additions & 5 deletions docs/open-items.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ coverage: `docs/parity.md`.

## Slower than Python at a typical size

- **Any-length FFT off the vDSP lengths (Bluestein)**: 2x to 7x slower than NumPy at 250² and 506²; numbers are right
(rtol 1e−7), only speed is open. Fix candidate: a mixed-radix plan for lengths that factor into 2, 3, 5 and 7, Bluestein
for the rest (#4).
- **Any-length FFT with a prime factor above 7 (Bluestein)**: lengths off vDSP that factor into 2, 3, 5 and 7 run a
mixed-radix FFT since #42 (250² 0.36 ms against NumPy 0.24 ms, 500² 1.58 ms against 1.52 ms); 506² (2 × 11 × 23) stays on
Bluestein, 1.6x slower than NumPy. Numbers are right (rtol 1e−7), only speed is open. Fix candidate: generic odd-radix
passes (#4).
- **Rows measured on a loaded machine**: `fft2+ifft2` at 192² to 512², multislice and frozen phonons at 192², the probe build
at 192² to 512² against abTEM float32. Re-measure in a quiet run before changing anything (#5).

## Work items

- **Detector and noise follow-ups from 0.4.0**: line profiles for segmented and
pixelated line scans, the azimuthal average, `LineScan` defaults, `integrate_disc(interpolate:)`, the DPC measurement of a
`SegmentedDetector`, tilt distributions (#9).
pixelated line scans, the azimuthal average, `LineScan` defaults, the "spline" method of `Images.interpolate`, tilt
distributions (#9). `integrate_disc(interpolate:)` and `Images.interpolate` (method "fft") are in; the DPC measurement of a
`SegmentedDetector` is under Polar measurements.
- **Potential API**: `CrystalPotential` (a unit potential repeated, frozen phonons per cell), its API undecided (#7).
- **Cells**: non-orthogonal and rotated cells, `periodic=False`, `orthogonalize_cell` in `AtomicStructure` (the kit keeps
its own structure type: `docs/adr/0001-standalone-structure-types.md`). Finite projection, the Kirkland, Peng and Ewald
Expand Down
11 changes: 6 additions & 5 deletions docs/parity.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ The coverage table of abTEM 1.0.10 (`References/python/abtem`, git `164e644`): i
the source in `site-packages/abtem` against SimulatoKit. Rewritten for 0.3.0 (the growing phase's kit audit); every row
has one state and one priority.

**Totals (128 rows): 37 present, 37 partial, 54 missing.** By priority: **study** 27 rows (11 present, 5 partial, 11 missing);
**useful** 79 (26, 32, 21); **not planned** 22 (all missing, each with its reason).
**Totals (129 rows): 38 present, 40 partial, 51 missing.** By priority: **study** 27 rows (12 present, 7 partial, 8 missing);
**useful** 80 (26, 33, 21); **not planned** 22 (all missing, each with its reason).

States:

Expand Down Expand Up @@ -40,7 +40,7 @@ detector, the Gaussian source size and Poisson noise on a scan.
| `core.energy.energy2mass` | | **missing**: planned: SimulatoCore (`ElectronBeam.mass` = the factor × mₑ) | useful |
| `Accelerator`, `HasAcceleratorMixin` (`energy`, `wavelength`, `sigma`, `lock_energy`, `match`, `check_match`) | `ElectronBeam(energy:)` | **partial**: energy, wavelength and σ; an undefined energy (None), `lock_energy` and `match` not offered; the energy must be finite and positive | useful |
| `core.constants.kappa` | `PhysicalConstants.kappa` | **present** (the same double) | useful |
| `Grid`, `HasGrid2DMixin` (`extent`, `gpts`, `sampling`, `reciprocal_space_sampling`, `endpoint`) | `Grid(nx:ny:extentX:extentY:)`, `Grid(extentX:extentY:samplingX:samplingY:)`, `.samplingX`/`Y`, `.reciprocalSamplingX`/`Y`, `.matches(_:)` | **partial**: any gpts ≥ 2 on both backends (0.3.0; vDSP where it has a length, Bluestein otherwise, pinned 90 x 75 against abTEM); `sampling=` gives ⌈extent / sampling⌉ points as abTEM; two dimensions, endpoint False only; the reciprocal sampling is abTEM's expression (bit-equal) | study |
| `Grid`, `HasGrid2DMixin` (`extent`, `gpts`, `sampling`, `reciprocal_space_sampling`, `endpoint`) | `Grid(nx:ny:extentX:extentY:)`, `Grid(extentX:extentY:samplingX:samplingY:)`, `.samplingX`/`Y`, `.reciprocalSamplingX`/`Y`, `.matches(_:)` | **partial**: any gpts ≥ 2 on both backends (0.3.0; vDSP where it has a length, a Stockham mixed-radix FFT for other lengths whose prime factors are 2, 3, 5 and 7, Bluestein otherwise; pinned 90 x 75 against abTEM; the mixed-radix path within 4e−16 of the largest term of NumPy `fft2` at 250² and 500², checked against a direct DFT); `sampling=` gives ⌈extent / sampling⌉ points as abTEM; two dimensions, endpoint False only; the reciprocal sampling is abTEM's expression (bit-equal) | study |
| `core.grid.spatial_frequencies`, NumPy `fftfreq` | `Grid.fftfreq`, `.frequenciesX`/`Y` | **present** (exact today, `SimulatoCoreTests`) | useful |
| `BaseWaves.angular_sampling`, `.cutoff_angles`, `.antialias_cutoff_gpts`, `.antialias_valid_gpts`, `.rectangle_cutoff_angles`, `.full_cutoff_angles`, `.cutoff_frequencies` | `DiffractionIntensity.angularSampling`, `.cutoffAngles`, `Antialias.cutoffPatternSize(on:)` | **partial**: angular sampling, cutoff angles and the odd cutoff size; the valid size only inside `PixelatedDetector(.valid)`; the rectangle and full cutoff angles and the cutoff frequencies not offered | useful |
| `abtem.config` (dask, device, precision, antialias settings), `abtem.axes` (axis metadata) | | **missing**: not planned: global configuration and ensemble-axis metadata belong to abTEM's lazy array objects; the kit takes explicit arguments | not planned |
Expand Down Expand Up @@ -184,10 +184,11 @@ detector, the Gaussian source size and Poisson noise on a scan.
| `DiffractionPatterns.center_of_mass(units)` | `CenterOfMassDetector(maxAngle:units:)` | **partial**: Σ P·α over the pixelated detector's crop in mrad or 1/Å, not divided by Σ P (as abTEM), pinned within 1e−5 of abTEM's complex64 result (0.3.0); a detector on the exit wave, not a method of a stored pattern; `integrated_center_of_mass` is `ScanMeasurement.integratedCenterOfMass` (next row) | study |
| `DiffractionPatterns.integrated_center_of_mass()` | `ScanMeasurement.integratedCenterOfMass(samplingX:samplingY:)` of a `CenterOfMassDetector` scan | **present**: abTEM's centre of mass through the kit 2e−16 (rtol 1e−7 default); the kit's own centre of mass 5e−8 (its COM is registered at 1e−5); no scaling beyond abTEM's (units of the COM times Å, minimum 0) | study |
| `Images.integrate_gradient` | `RealField.integratingGradient(x:y:)`, `ComplexField.integratedGradient(samplingX:samplingY:)` | **present** within assert_allclose float64 defaults (rtol 1e−7, atol 1e−12 of the max); measured 8e−16 of the maximum on even, odd, mixed, 2×3 and random (Nyquist) fields; planted potentials recovered to 1e−9 of their range | study |
| `integrate_disc` (`Images.integrate_disc`) | `RealField.integrateDisc(x:y:radius:mean:border:)` | **present** same tolerance; measured 2e−15 relative; `interpolate` not offered | study |
| `integrate_disc` (`Images.integrate_disc`) | `RealField.integrateDisc(x:y:radius:mean:border:interpolate:)` | **present** same tolerance; measured 2e−15 relative; `interpolate` resamples the image to that sampling first (`Images.interpolate`, method "fft"), pinned at rtol 1e−7 on three discs including one that wraps (`tools/pins/image-interpolate/pins.py`, held inline) | study |
| `Images.tile` | `RealField.tiled(repetitionsX:repetitionsY:)` | **present** exact | useful |
| `DiffractionPatterns.crop(max_angle, max_frequency, gpts)` | `Waves.diffractionPattern(maxAngle: .cutoff / .full)`, `PixelatedDetector(maxAngle:)` | **partial**: the crop is chosen when the pattern is made; not a method of a stored pattern | useful |
| `DiffractionPatterns.interpolate(sampling, gpts)`, `Images.interpolate(sampling, gpts, method, boundary, order, normalization, cval)` | | **missing**: planned: SimulatoCore | useful |
| `Images.interpolate(sampling, gpts, method, boundary, order, normalization, cval)` | `RealField.interpolated(rows:columns:normalization:)`, `.interpolated(samplingX:samplingY:normalization:)` | **partial**: method "fft" (crop or zero-pad in Fourier space, periodic), `normalization` "values" (scaled by new / old points) or "intensity"; a sampling gives ⌈extent / sampling⌉ points; pinned at rtol 1e−7 against abTEM in float64 on up, down and mixed resamplings of a planted 5 × 6 image (`tools/pins/image-interpolate/pins.py`, held inline); method "spline" (with `boundary`, `order`, `cval`) not offered; an axis of one point is refused (abTEM keeps its zero frequency) | useful |
| `DiffractionPatterns.interpolate(sampling, gpts)` | | **missing**: planned: SimulatoCore | useful |
| `DiffractionPatterns.gaussian_source_size(sigma)` | `ScanMeasurement.gaussianSourceSize(sigma:samplingX:samplingY:)` | **present**: scipy `gaussian_filter` over the two scan axes, mode wrap, radius ⌊4σ + ½⌋; pinned at rtol 1e−7 (float64) incl. a σ that wraps the scan (0.3.0) | study |
| `DiffractionPatterns.bandlimit`, `.block_direct`, `.tile_scan` | | **missing**: planned: SimulatoDetector | useful |
| `Images.crop(extent, offset, centered)` | | **missing**: planned: SimulatoCore | useful |
Expand Down
1 change: 1 addition & 0 deletions tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ git status --short Tests/ # no change to an *-arrays.bin: the fixtures reprodu
| `pins/potential-project-tile/pins.py` | none: prints the numbers `SimulatoMultisliceTests/PotentialProjectTileTests.swift` holds inline |
| `pins/polar/pins.py` | none: prints the numbers `SimulatoDetectorTests/PolarMeasurementTests.swift` holds inline |
| `pins/crystal-slices/pins.py` | none: prints the numbers `SimulatoMultisliceTests/CrystalSliceThicknessTests.swift` holds inline |
| `pins/image-interpolate/pins.py` | none: prints the numbers `SimulatoCoreTests/ImageInterpolationTests.swift` holds inline |

## Other tools

Expand Down
Loading