Skip to content

Commit

Permalink
Merge pull request pyxem#1090 from CSSFrancis/BugFixOrientation
Browse files Browse the repository at this point in the history
Bug Fix Orientation
  • Loading branch information
CSSFrancis authored Jun 10, 2024
2 parents 9fadd91 + 2383f4d commit b1aa171
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 25 deletions.
1 change: 1 addition & 0 deletions examples/orientation_mapping/mulit_phase_orientation.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
reciprocal_radius=2,
with_direct_beam=False,
)
polar_multi = polar_multi**0.5 # gamma correction
orientation_map = polar_multi.get_orientation(sim)


Expand Down
1 change: 1 addition & 0 deletions examples/orientation_mapping/on_zone_orientation.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
# This should be fairly good at finding the orientation of the grains on each side of the tilt boundary.
# The rotation is stored in the rotation column of the orientation map or .isg[2,0] if you want to use the
# rotation as a navigator or plot it directly.
polar_si_tilt = polar_si_tilt**0.5 # gamma correction

orientation_map = polar_si_tilt.get_orientation(sim)
orientation_map.plot_over_signal(simulated_si_tilt)
2 changes: 1 addition & 1 deletion examples/orientation_mapping/single_phase_orientation.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
# there?" rather than "Is the Bragg vector the right intensity?" patially because the intensity of the Bragg vector might have
# many different effects.


polar_si = polar_si**0.5 # gamma correction.
orientation_map = polar_si.get_orientation(sim)
orientation_map.plot_over_signal(simulated_si, vmax="96th")

Expand Down
28 changes: 18 additions & 10 deletions pyxem/signals/indexation_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ def vectors_to_intensity(vectors, scale=1):
return (vectors.intensity / np.max(vectors.intensity)) * scale


def vectors_to_text(vectors):
def vectors_to_text(vectors, fast=True):
"""
Convert a set of diffraction vectors to text. For use with the map function
and making text markers.
Expand All @@ -201,9 +201,12 @@ def add_bar(i: int) -> str:
return f"{i}"

out = []
for hkl in vectors.hkl:
for hkl in vectors.origional_hkl:
h, k, l = np.round(hkl).astype(np.int16)
out.append(f"({add_bar(h)} {add_bar(k)} {add_bar(l)})")
if fast:
out.append(f"{h} {k} {l}")
else:
out.append(f"({add_bar(h)} {add_bar(k)} {add_bar(l)})")
return out


Expand Down Expand Up @@ -234,6 +237,7 @@ def extract_vectors_from_orientation_map(result, all_vectors, n_best_index=0):
# Copy manually, as deepcopy adds a lot of overhead with the phase
intensity = vectors.intensity
vectors = DiffractingVector(vectors.phase, xyz=vectors.data.copy())
hkl = vectors.hkl
# Flip y, as discussed in https://github.com/pyxem/pyxem/issues/925
vectors.y = -vectors.y

Expand All @@ -244,6 +248,7 @@ def extract_vectors_from_orientation_map(result, all_vectors, n_best_index=0):
vectors = DiffractingVector(
vectors.phase, xyz=vectors.data.copy(), intensity=intensity
)
vectors.origional_hkl = hkl

# Mirror if necessary.
# Mirroring, in this case, means casting (r, theta) to (r, -theta).
Expand Down Expand Up @@ -323,7 +328,11 @@ def to_rotation(self, flatten=False):
raise ValueError(
"Cannot create rotation from lazy signal. Please compute the signal first."
)
all_rotations = Rotation.stack(self.simulation.rotations).flatten()
if isinstance(self.simulation.rotations, (list, np.ndarray)):
quats = np.vstack([r.data for r in self.simulation.rotations])
all_rotations = Rotation(data=quats)
else:
all_rotations = self.simulation.rotations
rotations = self.map(
rotation_from_orientation_map,
rots=all_rotations.data,
Expand Down Expand Up @@ -527,6 +536,7 @@ def to_markers(
text_kwargs: dict = None,
include_intensity: bool = False,
intesity_scale: float = 1,
fast: bool = True,
**kwargs,
) -> Sequence[hs.plot.markers.Markers]:
"""Convert the orientation map to a set of markers for plotting.
Expand All @@ -549,6 +559,8 @@ def to_markers(
having a larger marker size.
lazy_output: bool
If True, the output will be a lazy signal. If None, the output will be lazy if the input is lazy.
fast: bool
If True the annotations will print as -h rather than \\bar{h}
Returns
-------
Expand Down Expand Up @@ -607,18 +619,14 @@ def to_markers(
ragged=True,
output_dtype=object,
output_signal_size=(),
fast=fast,
)
# New signal for offset coordinates, as using inplace=True shifts the point markers too
text_coords = coords.map(
lambda x: x + annotation_shift,
inplace=False,
lazy_output=True,
)
text_coords = coords.map(
lambda x: x + annotation_shift,
inplace=False,
lazy_output=True,
)
text_markers = hs.plot.markers.Texts.from_signal(
text_coords, texts=texts.data.T, color=text_color, **text_kwargs
)
Expand Down Expand Up @@ -831,7 +839,7 @@ def get_ipf_annotation_markers(self, offset: float = 0.85, scale: float = 0.2):
offset_transform="display",
offsets=[[0, 0]],
)
return polygon_sector, texts, mesh
return polygon_sector, mesh, texts

def to_ipf_colormap(
self,
Expand Down
27 changes: 17 additions & 10 deletions pyxem/signals/polar_diffraction2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,6 @@ def get_orientation(
n_keep=None,
frac_keep=0.1,
n_best=1,
gamma=0.5,
normalize_templates=True,
**kwargs,
):
Expand All @@ -337,26 +336,33 @@ def get_orientation(
n_best : int
The number of best matching orientations to keep.
normalize_templates : bool
Normalize the templates to the same intensity.
gamma : float
The gamma correction applied to the diffraction patterns. The default
value is 0.5 which takes the square root of the diffraction patterns to
increase the intensity of the low intensity reflections and decrease the
intensity of the high intensity reflections. In most cases gamma<1 is a
good starting point. See :cite:`pyxemorientationmapping2022` for more information.
Normalize the templates to the same intensity..
kwargs : dict
Any additional options for the :meth:`~hyperspy.signal.BaseSignal.map` function.
Returns
-------
orientation : BaseSignal
A signal with the orientation at each navigation position.
Notes
-----
A gamma correction is often applied to the diffraction patterns. A good value
to start with is thethe square root (gamma=0.5) of the diffraction patterns to
increase the intensity of the low intensity reflections and decrease the
intensity of the high intensity reflections. This can be applied via:
>>> s_gamma = s**0.5
In most cases gamma<1 See :cite:`pyxemorientationmapping2022` for more information.
Additionally, subtracting a small value can sometimes be helpful as it penalizes
diffraction patterns which do not have the full compliment of simulated diffraction
vectors.
References
----------
.. bibliography::
"""
if gamma != 1:
self.data = self.data**gamma
(
r_templates,
theta_templates,
Expand Down Expand Up @@ -384,6 +390,7 @@ def get_orientation(
transpose=True,
output_signal_size=(n_best, 4),
output_dtype=float,
**kwargs,
)

# Translate in-plane rotation from index to degrees
Expand Down
18 changes: 14 additions & 4 deletions pyxem/tests/signals/test_indexation_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ def simple_multi_rot_orientation_result(self):
reciprocal_radius=2,
with_direct_beam=True,
)
orientations = polar.get_orientation(sims, alpha=1) # in this case we
polar = polar**0.5
orientations = polar.get_orientation(sims)
return orientations, r, s

@pytest.fixture(scope="class")
Expand All @@ -242,7 +243,7 @@ def multi_phase_orientation_result(self):

generator = SimulationGenerator(200, minimum_intensity=0.05)
rotations = get_sample_reduced_fundamental(
resolution=1, point_group=phase.point_group
resolution=2, point_group=phase.point_group
)
rotations2 = get_sample_reduced_fundamental(
resolution=1, point_group=phase2.point_group
Expand Down Expand Up @@ -294,14 +295,23 @@ def test_to_crystal_map_multi_phase(self, multi_phase_orientation_result):
assert np.all(crystal_map.phase_id < 2)

@pytest.mark.parametrize("annotate", [True, False])
@pytest.mark.parametrize("fast", [True, False])
@pytest.mark.parametrize("lazy_output", [True, False])
@pytest.mark.parametrize("add_intensity", [True, False])
def test_to_markers(
self, simple_multi_rot_orientation_result, annotate, lazy_output, add_intensity
self,
simple_multi_rot_orientation_result,
annotate,
lazy_output,
add_intensity,
fast,
):
orientations, rotations, s = simple_multi_rot_orientation_result
markers = orientations.to_markers(
lazy_output=lazy_output, annotate=annotate, include_intensity=add_intensity
lazy_output=lazy_output,
annotate=annotate,
include_intensity=add_intensity,
fast=fast,
)
assert isinstance(markers[0], hs.plot.markers.Markers)

Expand Down

0 comments on commit b1aa171

Please sign in to comment.