Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to have spot centers off pixel centers #235

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

viljarjf
Copy link

Description of the change

Previously, Simulation2d.get_diffraction_pattern rounded coordinates down to nearest pixel in the output pattern, before adding a gaussian blur.
This PR implements a more manual gaussian blurring, evaluating the gaussian without assuming integer spot coordinates instead of using convolution.
This gives more accurate spot positions, which is important when using these patterns in external analysis tools.
It is slower, but using numba made it only around 20% slower (as opposed to 800% slower without).

Progress of the PR

Minimal example of the bug fix or new feature

# Setup
from diffpy.structure import Structure, Atom, Lattice
from orix.crystal_map import Phase
from diffsims.generators.simulation_generator import SimulationGenerator

l = Lattice(10, 10, 10, 90, 90, 90)
a = [Atom("Au", (0, 0, 0))]
s = Structure(a, l)

p = Phase(structure=s, space_group=1)

gen = SimulationGenerator()
sim = gen.calculate_diffraction2d(p)

Performance analysis:

%%timeit
sim.get_diffraction_pattern(shape=(100,100), sigma=1, fast=True)

205 µs ± 4.61 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

%%timeit
sim.get_diffraction_pattern(shape=(100,100), sigma=1, fast=False)

250 µs ± 2.8 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

New is around 25% slower.

Qualitative difference in resulting plots:

from matplotlib import pyplot as plt
plt.figure()
plt.subplot(1, 2, 1)
kwargs = dict(
    shape=(10, 10), 
    sigma=1, 
    normalize=False,
    fast_clip_threshold=0.1,
    calibration=0.001, # Very small calibration = only direct beam
)
fast = sim.get_diffraction_pattern(fast=True, **kwargs)
plt.imshow(fast, vmax=20)
plt.subplot(1, 2, 2)
slow = sim.get_diffraction_pattern(fast=False, **kwargs)
plt.imshow(slow, vmax=20)

image

In the example above, since the shape is 10x10, the center is not at a pixel coordinate, but at (4.5, 4.5). This is rounded to (5, 5) in the fast (current) mode.

Note that there is a bug where the direct beam is added twice to the simulations. For the fast mode, this is fine, as the intensity of each spot is set rather than summed (before blurring). For the new, however, the direct beam is twice as intense as it should. This is fixed in #232.

For reviewers

  • The PR title is short, concise, and will make sense 1 year later.
  • New functions are imported in corresponding __init__.py.
  • New features, API changes, and deprecations are mentioned in the
    unreleased section in CHANGELOG.rst.
  • Contributor(s) are listed correctly in credits in diffsims/release_info.py and
    in .zenodo.json.

@viljarjf viljarjf mentioned this pull request Jan 27, 2025
13 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant