diff --git a/index.html b/index.html index 49473e7..0c1c64e 100644 --- a/index.html +++ b/index.html @@ -130,7 +130,7 @@
Version 5.1.1 — available now
+Version 5.2.0 — available now
Version 5.1.1 is available as a signed, notarized disk image. Open it and drag mac4DSTEM to your Applications folder — it launches without a security warning, and needs nothing else installed.
+Version 5.2.0 is available as a signed, notarized disk image. Open it and drag mac4DSTEM to your Applications folder — it launches without a security warning, and needs nothing else installed.
Sizes: quantification small 8 x 8, typical 256 x 256 (3 elements), large 1024 x 1024; thickness small 8 x 8, typical 64 x 64 (2048 channels), large 256 x 256. Large: not measured yet (large in the size list adds it).
| function | decision | why |
|---|---|---|
| quantification maps, all methods (the Python column converts to weight percent only; Swift returns both) | CPU only (parallel over pixels since 0.8.0) | 9 to 40 ms for 65 536 pixels; per pixel the work is 10 to 500 ns of arithmetic, so a Metal dispatch pays only above about 1e6 pixels; the break-even is not measured (the large size is not measured yet). Not a work item until a large-size run shows a slow large image |
| t/lambda log ratio, fixed threshold | CPU only; slower than Python on the typical size (0.49x), first in docs/parity.md (known limits) | single-threaded scalar passes against NumPy's vectorised axis sums |
| t/lambda log ratio, estimated threshold | CPU only | 5x faster than Python at the typical size (Python's per-pixel Savitzky-Golay search dominates) |
| EDX line fit, auto ID, EELS background fit, edge quantification | not benchmarked in 0.8.0 | need a Velox spectrum image or a planted EELS image on both sides; listed in docs/parity.md (known limits) |
Kit against py4DSTEM, same inputs, Float32 cubes, one run of tools/benchmarks on 2026-10-21. Harness: Tests/CuboVirtualTests/BenchmarkHarness.swift (Swift, built with swift test -c release, skipped unless CUBOKIT_BENCH_DIR is set) and tools/benchmarks/bench.py (the py4DSTEM side and the merge). Both read the same .npy cubes. Best of five after one warm-up; cells are best / median (spread = slowest - best) in milliseconds; "CPU vs py4DSTEM" is py4DSTEM's best divided by the kit CPU's best (above 1 the kit is faster). The cubes are held in memory (MemoryCube; DataCube(data=ndarray)). The Metal columns copy each tile to the GPU on every call; the _resident rows hold the cube in a ResidentCube (one Metal buffer) first.
Sizes (scan rows x columns x detector rows x columns): small 32x32x32x32 (1.0 M values), mid 64x64x32x32 (4.2 M), typical 100x100x64x64 (41.9 M, 168 MB). The large size (330x330x64x64, 1.8 GB) and the Bragg, strain, DPC, parallax and ptychography functions are not measured yet. The machine was shared during the run (load average 5 to 11 from other builds), so the spreads are wider than on a quiet Mac.
Re-run from a fresh clone of the kit, on a quiet Mac, one benchmark at a time (the typical cube is 168 MB on disk and in memory):
diff --git a/suite/index.html b/suite/index.html index f92f717..506f7de 100644 --- a/suite/index.html +++ b/suite/index.html @@ -40,10 +40,10 @@Beside the kits, MacEMUI 0.5.0 holds the apps' shared window, controls and Metal image view. It has no Python reference.
+Beside the kits, MacEMUI 0.5.1 holds the apps' shared window, controls and Metal image view. It has no Python reference.
"Parity: present of rows" counts the functions of the reference package that the kit has and has tested against it; each kit's docs/parity.md lists every function with its state and tolerance. See benchmarks and releases.
Apps: mac4DSTEM (4D-STEM) and macTEM (TEM images, spectroscopy and diffraction).
diff --git a/suite/releases.html b/suite/releases.html index cf80129..f54e797 100644 --- a/suite/releases.html +++ b/suite/releases.html @@ -40,9 +40,9 @@The apps: mac4DSTEM releases and macTEM releases on GitHub.
diff --git a/tools/check_site.py b/tools/check_site.py index eaddca2..181daf4 100644 --- a/tools/check_site.py +++ b/tools/check_site.py @@ -96,7 +96,12 @@ def check_releases(): for app, rel in APPS.items(): r = latest(app) ver = r["tag_name"].lstrip("v") - dmg = next(a for a in r["assets"] if a["name"] == f"{app}.dmg") + dmg = next((a for a in r["assets"] if a["name"] == f"{app}.dmg"), None) + if dmg is None: + errors.append(f"{rel}: the latest {app} release {r['tag_name']} has no {app}.dmg, so the page's " + f"releases/latest/download/{app}.dmg link is a 404: build it with tools/release.sh " + "on that tag and attach it") + continue size = f"{dmg['size'] / 1e6:.1f} MB" text = (ROOT / rel).read_text() for stated in sorted(set(re.findall(r"Version (\d+\.\d+\.\d+)", text))):