From a180da1dd5962055ef47332ef750b59aadb47a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Tcho=C5=84?= Date: Wed, 15 Apr 2026 17:41:00 +0200 Subject: [PATCH] Fix diffraction (#1) * Simple but slow fix to allow observing diffraction mode again * Tried to introduce some optimizations but couldn't, current version is good-enough --- .../simulation/crystal.py | 33 ++++++++++++------- .../simulation/stage.py | 2 +- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/instamatic-tem-emulator/simulation/crystal.py b/src/instamatic-tem-emulator/simulation/crystal.py index 64f5c56..0fc052e 100644 --- a/src/instamatic-tem-emulator/simulation/crystal.py +++ b/src/instamatic-tem-emulator/simulation/crystal.py @@ -4,7 +4,6 @@ import numpy as np from diffpy import structure as diffpy -from diffsims.crystallography._diffracting_vector import DiffractingVector from diffsims.generators.simulation_generator import Simulation2D, SimulationGenerator from orix.crystal_map import Phase from orix.quaternion import Rotation @@ -65,11 +64,6 @@ def __init__( lattice=self.lattice, ) self.phase = Phase(space_group=space_group, structure=self.structure) - # self.recip = DiffractingVector.from_min_dspacing( - # self.phase, - # min_dspacing=1, - # include_zero_vector=False, - # ) raises exception to use ReciprocalLatticeVector instead - version 0.7.0 issue? self.recip = Vector3D.from_min_dspacing( self.phase, min_dspacing=1, @@ -161,7 +155,7 @@ def reciprocal_space_lattice(self, d_min: float) -> np.ndarray: vecs = self.lattice.reciprocal().cartesian(hkls) return vecs - def diffraction_pattern_mask( + def diffraction_pattern( self, shape: tuple[int, int], d_min: float, @@ -201,10 +195,27 @@ def diffraction_pattern_mask( max_excitation_error = excitation_error rotation = Rotation.from_matrix(rotation_matrix) - from diffsims.generators.simulation_generator import ( - Vector3d, - get_intersection_with_ewalds_sphere, - ) + try: + from diffsims.generators.simulation_generator import ( + Vector3d, + get_intersection_with_ewalds_sphere, + ) + except ImportError: + sim = gen.calculate_diffraction2d( + phase=self.phase, + rotation=rotation, + reciprocal_radius=1 / d_min, + with_direct_beam=False, + max_excitation_error=max_excitation_error, + ) + pattern = sim.get_diffraction_pattern( + shape=shape, + sigma=1, + calibration=1 / d_min / (shape[0] / 2), + ) + return pattern * intensity_scale + + # code below only works with https://github.com/pyxem/diffsims/pull/232 optical_axis = rotation * Vector3d.zvector() # Calculate the reciprocal lattice vectors that intersect the Ewald sphere. diff --git a/src/instamatic-tem-emulator/simulation/stage.py b/src/instamatic-tem-emulator/simulation/stage.py index 9a9bd73..b8aa2eb 100644 --- a/src/instamatic-tem-emulator/simulation/stage.py +++ b/src/instamatic-tem-emulator/simulation/stage.py @@ -270,7 +270,7 @@ def get_diffraction_pattern( # Crystal is completely on the grid continue - reflections += self.crystals[sample.crystal_index].diffraction_pattern_mask( + reflections += self.crystals[sample.crystal_index].diffraction_pattern( shape, d_min=d_min, rotation_matrix=self.rotation_matrix @ sample.rotation_matrix,