Repository navigation
Replace the py4DSTEM TEM diffraction component with the quantEM browser simulator - #550
Merged
Merged
Conversation
TEMDiffractionComponent now shows DiffractionSim from the quantem.diffsim package. The server converts the structure to CIF text of its conventional standard cell, and the browser computes the reflections, structure factors and Bloch wave intensities, so the component no longer imports py4DSTEM or NumPy. The temdiff extra installs quantem.diffsim>=0.1, and the example app switches between Si, SrTiO3 and GaN. Fixes materialsproject#547. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test checks the settings that TEMDiffractionComponent sends to the simulator and the bundle route, and skips when quantem.diffsim is not installed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
|
@cophus Thanks for the contribution! Merged! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #547.
The TEM diffraction tab of the Materials Project website has failed since the site moved to NumPy 2, because every py4DSTEM release on PyPI, up to 0.14.18, builds its
Crystalwithdtype="float_", which NumPy 2.0 removed. py4DSTEM 0.14.18 also requires scikit-learn<1.5, and the newest allowed version (1.4.2) has no Python 3.13 wheels and cannot be built from source there, so thetemdiffextra blocks the move to Python 3.13.This PR replaces the component with DiffractionSim, the electron diffraction simulator from quantEM, packaged as
quantem.diffsimon PyPI (electronmicroscopy/quantem.widget#245). The package has no runtime dependencies and ships one ES module (1.16 MB) with a few Python helpers. Every calculation runs in the browser, including the reflection list, the structure factors from the Lobato and Van Dyck scattering factors (Acta Cryst. A 70, 636 (2014)), and the Bloch wave intensities with the absorptive Weickenmeier and Kohl scattering factors and a Debye-Waller factor (Acta Cryst. A 47, 590 (1991)). The server only converts the structure to CIF text of its conventional standard cell, which is also the cell that py4DSTEM'sCrystal.from_pymatgen_structureuses by default, so zone axes refer to the same lattice as before.The simulator shows the crystal and its diffraction pattern side by side, with nanobeam, convergent beam electron diffraction (CBED) and Kikuchi modes, kinematical or Bloch wave intensities, and controls for orientation, thickness, convergence semiangle, precession and beam energy. It opens along [001] at 200 keV in nanobeam mode, which matches the beam direction and voltage defaults of the current tab. The current tab defaults to kinematical intensities, while the simulator starts with Bloch wave intensities for a 400 Å thick crystal. The simulator hides its structure menu when a structure is passed in, and shows a "Powered by quantEM" link to the quantEM documentation in its lower right corner.
Changes
crystal_toolkit/components/diffraction_tem.py:TEMDiffractionComponent.layout()returnsquantem.diffsim.dash.layout(self.id("quantem-diffsim")), which holds adcc.Storefor the settings and thehtml.Divthat the simulator draws into.generate_callbackscallsquantem.diffsim.dash.register(app), which serves the bundle from the app's Flask server at_quantem_diffsim/diffraction-sim-0.1.0.js(underroutes_pathname_prefix, versioned and cached for one year) and adds one clientside callback that draws the simulator. A single server callback sendsquantem.diffsim.settings(structure, zone_axis=[0, 0, 1], mode="nanobeam", energy_keV=200)whenever the structure store changes. When quantem.diffsim is not installed, the component shows a message in place of the simulator, as it did for py4DSTEM. These changes reduce the file from 397 to 74 lines.TEMDiffractionCalculatorand its plotly figure are removed, along with the py4DSTEM and NumPy imports. Nothing else in Crystal Toolkit imports the calculator, and code that calls it directly, as the snippet in [Bug]: TEM diffraction pattern with py4DSTEM #547 does, will need to use py4DSTEM itself.pyproject.toml:temdiff = ["quantem.diffsim>=0.1"]replacespy4DSTEM>=0.13.11.crystal_toolkit/apps/examples/diffraction_tem.py: a dropdown switches between Si, SrTiO3 and wurtzite GaN, so that the example also tests redrawing.tests/test_diffraction_tem.py: the test checks the settings sent for Si (zone axis, mode, energy, formula and space group in the CIF), thePreventUpdatefor an empty structure store, and the bundle route, and is skipped when quantem.diffsim is not installed.Dependencies
temdiff = ["quantem.diffsim>=0.1"]resolves from PyPI, andpip install -e ".[temdiff]"installs quantem.diffsim 0.1.0, which has no dependencies.requirements/still pinpy4dstem==0.14.18. We left them for the automated dependency upgrade to regenerate. Until then CI installs py4DSTEM, which is no longer imported, and does not install quantem.diffsim, so the new test is skipped.Testing
pip install -e ".[temdiff]"on this branch installs the PyPI wheel into site-packages, with no local copy,tests/test_diffraction_tem.pypasses, and the example app draws Si, SrTiO3 and GaN with no console errors.temdiffextra,pytest testsgives 16 passed, and ruff 0.14.10 check and format pass on the changed files.import crystal_toolkit.componentsworks,TEMDiffractionComponent().layout()returns the message, and the new test is skipped.pip install quantem.diffsimfrom PyPI installs no other package and writes a working standalone page.tests/test_utils.pyfail, becauseCACHE_TYPE"simple" incrystal_toolkit/core/plugin.pyno longer resolves to a cache backend. This PR does not touch that file. Thefix-flask-caching-cache-typesbranch addresses this, and we ran the example app and the tests with flask-caching 2.3.1.Checklist
Written by Colin Ophus and Claude (Claude Code).