Repository navigation
Add orientation and phase mapping, Bloch-wave dynamical diffraction, calibration, strain and DDF - #297
Open
cophus wants to merge 35 commits into
Open
Add orientation and phase mapping, Bloch-wave dynamical diffraction, calibration, strain and DDF#297cophus wants to merge 35 commits into
cophus wants to merge 35 commits into
Conversation
Some corrections to the new DDF and clustering routines. "noise" was renamed to "unclustered". An additional function added to put grain labels into a vector. The dbscan was rewritten with help from Claude to eliminate some inefficiencies that made it slow on CPU. An updated ipynb will be sent to accompany this PR.
Brings in the torch Vector (electronmicroscopy#272), spectroscopy, em-database and the widget package removal. - pyproject.toml, quantem/__init__.py: keep both sides (ase, spglib, em-database; diffraction and spectroscopy). - file_readers.py: keep acom's 3D-as-4D reading, add dev's _print_available_datasets and read_3d_spectroscopy, restore the scan_length/scan_axis/transpose_scan_axes parameters an earlier merge dropped from the signature, and remove conflict markers committed in the read_4dstem docstring. - widget/: follow dev's removal except the diffraction widget (diffsim) and the files it needs to build; restore the widget .gitignore rules. - uv.lock regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Read Vector data with .numpy().astype(np.float64) instead of .array and flatten(), which now return tensors. This keeps the old writable float64 arrays, so consumers mixing peaks with float64 tensors also work for float32 Vectors, and torch.as_tensor no longer warns about read-only input. - Detected peaks stay float64 (dtype=torch.float64); Vectors derived from other Vectors (calibrated peaks, residual peaks, masked copies) keep the source dtype. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
float32 holds peak positions to ~3e-5 px, well below detection precision, and every read casts to float64 before computing, so the float64 storage only doubled memory and file size. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pdates from Ian MacLaren Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Port aperture_array_generator, aperture_array_subtract, DDFimage, pointlist_to_array (rphi), DDF_radial_image and DDFradialazimuthimage from py4DSTEM into digital_dark_field.py as aperture_array, aperture_array_subtract, aperture_ddf_image, add_polar_fields, polar_mask and radial_ddf_image, all reading peaks from a Vector. Add ddf_image(peaks, mask) and plot_apertures. Fix assign_grain_labels and plot_cluster_scatter from PR electronmicroscopy#286 for the torch-backed Vector. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
What problem this PR addresses
This PR adds automated crystal orientation mapping (ACOM) and phase mapping of 4D-STEM data to
quantem.diffraction, along with the crystallography, calibration, disk detection and dynamical diffraction code these methods depend on. It also includes the digital dark field (DDF) analysis from Ian MacLaren (PR #286), and a reverse Monte Carlo (RMC) fit of diffuse scattering. The full test suite (1061 tests) passes in about 2 minutes.Tutorial notebooks:
diffraction_simulation.ipynb
ACOM_orientation_phase_strain_Ti.ipynb
ACOM_dynamical_refinement_Ti.ipynb
The new modules in
quantem.diffractionare:crystal.py:Crystalwraps anase.Atomscell from a CIF file, finds the space group and Laue class with spglib, and computes kinematical structure factors from the Lobato and Van Dyck electron scattering factors. We use the absorptive Weickenmeier-Kohl factors (wk_scattering_factors.py) for Bloch-wave calculations. Apseudo_symmetry_tollets the matching use a higher pseudo-symmetry than the exact space group.rotations.py: quaternions in torch, scalar first, rotating crystal to lab coordinates, with the zone axis pointing toward the source.disk_detection.py,bragg_vectors.py,strain.py: template matching disk detection,BraggVectorson the torch-backedVector, lattice fitting andStrainMap.calibration.py: origins, scan rotation from the curl of the centre of mass, pixel size, and elliptic distortion.calibrate()runs these steps and returns aDiffractionCalibration, which can be applied to peaks, rebinned, saved and reloaded.illumination.py: excitation error envelopes for convergent beams and precession, and relrod factors.orientation.py:OrientationMapmatches every measured pattern against a library of simulated zone axis patterns using a sparse polar correlation (cosine similarity from 0 to 1), then refines each orientation by least squares on the paired peaks. Reliability is the margin between the best and second-best match outside a 15 degree exclusion ball. Overlapping grains are matched by deflation (num_matches,suppress_matched,match_residual).phase.pyandcrystal_map.py:PhaseMapassigns the phase at each position by non-negative least squares over candidate subsets, with a complexity penalty and a null hypothesis for vacuum and amorphous regions.CrystalMapruns this workflow for several crystals and provides masks, phase fractions, and orientation, pole figure, correlation and match plots.bloch.py: Bloch-wave dynamical diffraction in torch, including thickness refinement, CBED, LACBED and Kossel patterns, Kossel reference patterns, andrefine_dynamical, which refines tilt, thickness and in-plane strain at every position against the measured Bragg intensities.digital_dark_field.py: virtual apertures, polar and radial DDF images, and clustering of Bragg peaks into grain maps, ported from Ian MacLaren's py4DSTEM functions.reverse_monte_carlo.py:ReverseMonteCarlofits a supercell with chemical order and static displacements to the diffuse scattering measured along several zone axes.We also made the following changes to shared core code:
read_4dstemreads 3D stacks as 4D data, and resolves the RosettaSciIO plugin from a plugin name or file extension. Extensions shared by several plugins (such as.h5) now raise an error listing the plugins.Polar4dstem,Dataset4dstem.polar_transform,Dataset4dstem.from_file,show_virtual_imagesandshow_virtual_detectors.AutoSerializesavestorch.deviceandase.Atoms(including partial occupancy), and the newBundlesaves several objects in one file.Vectorpeaks incore/utils/clustering.py.show_2dcolorbars useset_powerlimits((-3, 4)), so values from 1e-3 to 1e4 are printed without a shared exponent. This changes the appearance of existing colorbars.ase>=3.23andspglib>=2.5.What should the reviewer(s) do
Please review and merge. Three points need attention from the reviewers:
PR Adding various strain mapping algorithms #284 (strain) added the same five disk detection and strain files independently. We merged the newer Adding various strain mapping algorithms #284 versions into this branch, keeping the
g1/g2names, the detector-to-scan rotation (q_to_r_rotation_ccw_deg,q_transpose), GPU caching and the CPU template average from Adding various strain mapping algorithms #284, and the correlation options and origin calibration from this branch. Two choices differ from Adding various strain mapping algorithms #284. Disk detection keepssubtract_mean=False, because the ACOM detection thresholds assume a positive template. Shear and rotation follow the corrected sign convention of Adding various strain mapping algorithms #284, soe_rcandphifromOrientationMap.calculate_strainchange sign relative to earlier versions of this branch. Adding various strain mapping algorithms #284 can be rebased onto this PR with mostly formatting conflicts.PR DDF and clustering updates #286 (DDF) is merged here, and the DDF function
fit_latticeis renamed torefine_lattice_vectorsto avoid a clash withBraggVectors.fit_lattice.The diffraction simulator widget developed on this branch has moved to the
quantem.widgetrepository, so this PR contains no widget code.This PR introduces a public-facing change (e.g., figures, CLI input/output, API).
Generated with Claude Code