Skip to content

Commit

Permalink
Static pattern matching framework, orientation similarity map and cry…
Browse files Browse the repository at this point in the history
…stal map merging (#234)

* feat(SimilarityMetric): ZNCC, NDP and user defined metrics

Framework for calculating similarities between 2D gray-tone images of equal size.

* fix(SimilarityMetric): squeeze dimensions of similarity matrix

* fix(SimiliarityMetric): rechunk dask arrays after type conversion

* refactor(SimilarityMetric)

length of shape -> ndim, and removed unnecessary squeeze call.

* test(SimilarityMetric): Many to many ZNCC

Produce value of 1 with equal pattern and template

* refactor: removed metricscopes including ANY

* wip: tests cover most cases

* test: remove print statement

* refactor: indexation -> indexing

* Reformat docstrings, add Ole to credits, add indexing module to doc

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* refactor: renamed variables and made functions private

* refactor: underscore prefix

* refactor: underscore prefix

* Update docstring table, and more

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Add indexing module to kikuchipy/__init__.py

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Add static dictionary indexing note in changelog

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* fix: change standard shape of similarity matrix

Change data shape from (N,nm) to (nm,N) to correspond better with cdist in scipy and general logic.

* test: update tests to new output standard

* fix: _is_compatible to be working for all scopes

* Clarify parameters in docstrings, some minor syntax changes, repr

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Docstring explanation of _is_compatible()

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Return numpy where only numpy arrays are passed, test repr

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Improve return numpy/dask test

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* feat(template_match): Keep n largest metric results and template indices

* tests: simple tests covering all lines

* refactor: move code to give user more specific error

* refactor: removed comment

* feat: StaticDictionaryIndexing, OSM and xmap merging

Index patterns from preloaded sets of templates and produce CrystalMaps with Orientation Similarity Maps.

* wip: empty test files

* docs: template_match and slicing of templates

* fix: accept all scopes in template_match

* refactor: renamed variables and removed unnecessary code

* refactor: moved code to read metric str earlier

* docs: template slices and punctuation marks.

* fix: raise NotImplementedError

When compute=False and n_slices is not None.

* fix: allow user-defined footprint in OSM

* refactor+test: _merge -> merge_crystalmaps

* test: StaticDictionaryIndexing and OSM

* docs: StaticDictionaryIndexing

* fix: OSM bug

* refactor: template_match -> pattern_match

And more importantly: patterns->experimental, templates->simulated

* refactor(SimilarityMetric): patterns->experimental, templates->simulated

* docs: data -> patterns

* feat: EBSD.index method using StaticDictionaryIndexing

* fix: cyclic import and some documentation

* Remove setting of n_slices to None in static dictionary comp.

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* No longer raises ValueWarning instead of Error on merge equal phases

* Warns instead of raising error on merge equal phases

Updated commit summary.

* refactor: templates -> simulated

* refactor+test(EBSD): .index(...) -> .dictionary_indexing(...)

* test: fix to pass

* Intermediate commit before merging master into this branch

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Docstring changes, alternative merge_crystal_map [skip ci]

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Enable single scores per point, return comb. scores/indices

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Cont. testing crystal map merging, ensuring all tests pass

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* 100% coverage for xmap merging, some tests left

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Finish crystal map merge tests

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Touch up merge_crystal_maps docstring

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Changes to static dictionary indexing and OSM [skip ci]

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* MetricScope SOME_TO_MANY/ONE, 100% coverage

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Rename ZNCC->NCC, make ncc and ndp available from module

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Update changelog

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Add equation from Marquardt et al. (2017) to OSM docstring

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Print phase name and memory use % in indexing progressbar

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Clarify difference of keep_n variable in _pattern_matching funcs

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

* Dictionary indexing (DI) -> pattern matching, but keep DI references

Signed-off-by: Håkon Wiik Ånes <hwaanes@gmail.com>

Co-authored-by: Håkon Wiik Ånes <hwaanes@gmail.com>
  • Loading branch information
onatlandsmyr and hakonanes committed Nov 13, 2020
1 parent 8dc22a1 commit d1c799a
Show file tree
Hide file tree
Showing 20 changed files with 1,928 additions and 305 deletions.
18 changes: 18 additions & 0 deletions doc/bibliography.bib
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,21 @@ @phdthesis{lassen1994automated
title = {{Automated Determanation of Crystal Orientations from Electron Backscattering Patterns}},
year = {1994}
}
@article{chen2015dictionary,
author = {Chen, Yu H. and Park, Se Un and Wei, Dennis and Newstadt, Greg and Jackson, Michael A. and Simmons, Jeff P. and {De Graef}, Marc and Hero, Alfred O.},
doi = {10.1017/S1431927615000756},
issn = {14358115},
journal = {Microscopy and Microanalysis},
keywords = {EBSD, Von Mises-Fisher mixture distribution, dictionary matching, dynamical electron scattering, electron backscatter diffraction pattern, maximum likelihood orientation estimates},
number = {3},
pages = {739–752},
title = {{A Dictionary Approach to Electron Backscatter Diffraction Indexing}},
volume = {21},
year = {2015}
}
@book{goshtasby2012image,
author = {Goshtasby, A Ardeshir},
publisher = {Springer Science \& Business Media},
title = {{Image registration: Principles, tools and methods}},
year = {2012}
}
14 changes: 9 additions & 5 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@ Added
(`#236 <https://github.com/pyxem/kikuchipy/pull/236>`_,
`#237 <https://github.com/pyxem/kikuchipy/pull/237>`_,
`#243 <https://github.com/pyxem/kikuchipy/pull/243>`_)
- Indexing of EBSD patterns through matching of patterns with a static
dictionary of simulated patterns with known orientations.
- Pattern matching of EBSD patterns with a dictionary of pre-computed simulated
patterns with known crystal orientations, and related useful tools
(`#231 <https://github.com/pyxem/kikuchipy/pull/231>`_,
`#233 <https://github.com/pyxem/kikuchipy/pull/233>`_)
`#233 <https://github.com/pyxem/kikuchipy/pull/233>`_,
`#234 <https://github.com/pyxem/kikuchipy/pull/234>`_): (1) A framework for
creation of similarity metrics used in pattern matching, (2) computation of an
orientation similarity map from indexing results, and (3) creation of a multi
phase crystal map from single phase maps from pattern matching.
- EBSD.xmap property storing an orix CrystalMap object. So far only read from
a EMsoft simulated EBSD pattern file. Relevant documentation updated.
(`#226 <https://github.com/pyxem/kikuchipy/pull/226>`_)
Expand All @@ -55,8 +59,8 @@ Added

Changed
-------
- The EBSDMasterPattern gets unsettable phase, hemisphere and projection
properties. (`#246 <https://github.com/pyxem/kikuchipy/pull/246>`_)
- The EBSDMasterPattern gets phase, hemisphere and projection properties.
(`#246 <https://github.com/pyxem/kikuchipy/pull/246>`_)
- EMsoft EBSD master pattern plugin can read a single energy pattern. Parameter
`energy_range` changed to `energy`.
(`240 <https://github.com/pyxem/kikuchipy/pull/240>`_)
Expand Down
28 changes: 17 additions & 11 deletions doc/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -224,22 +224,22 @@ indexing
.. currentmodule:: kikuchipy.indexing

.. autosummary::
pattern_matching
StaticPatternMatching
orientation_similarity_map
merge_crystal_maps
similarity_metrics

pattern_matching
----------------

.. currentmodule:: kikuchipy.indexing.pattern_matching

.. autosummary::
pattern_match

.. automodule:: kikuchipy.indexing.pattern_matching
.. autoclass:: StaticPatternMatching
:members:
:undoc-members:
:show-inheritance:

.. automethod:: __init__
.. automethod:: __call__

.. autofunction:: orientation_similarity_map
.. autofunction:: merge_crystal_maps

similarity_metrics
------------------

Expand All @@ -248,16 +248,21 @@ similarity_metrics
.. autosummary::
make_similarity_metric
MetricScope
ncc
ndp

.. automodule:: kikuchipy.indexing.similarity_metrics
:members:
:undoc-members:
:show-inheritance:

.. autofunction:: ncc
.. autofunction:: ndp

....

io
==
===

.. automodule:: kikuchipy.io

Expand Down Expand Up @@ -457,6 +462,7 @@ All methods listed here are also available to
.. autosummary::
adaptive_histogram_equalization
average_neighbour_patterns
match_patterns
fft_filter
get_decomposition_model
get_dynamic_background
Expand Down
63 changes: 60 additions & 3 deletions kikuchipy/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@
import gc
import os
import tempfile
from typing import Tuple

from diffpy.structure import Atom, Lattice, Structure
from diffsims.crystallography import ReciprocalLatticePoint
import numpy as np
from orix.crystal_map import Phase
from orix.crystal_map import CrystalMap, Phase, PhaseList
from orix.quaternion.rotation import Rotation
from orix.vector import Vector3d, neo_euler
import pytest
Expand All @@ -40,8 +41,8 @@

@pytest.fixture
def dummy_signal():
"""Dummy signal of shape <3, 3|3, 3>. If this is changed, all tests
using this signal will fail since they compare the output from
"""Dummy signal of shape <(3, 3)|(3, 3)>. If this is changed, all
tests using this signal will fail since they compare the output from
methods using this signal (as input) to hard-coded outputs.
"""
# fmt: off
Expand Down Expand Up @@ -292,3 +293,59 @@ def nickel_zone_axes(nickel_kikuchi_band, nickel_rotations, pc1):
in_pattern=uvw_in_pattern,
gnomonic_radius=detector.r_max,
)


@pytest.fixture
def rotations():
return Rotation([(2, 4, 6, 8), (-1, -3, -5, -7)])


@pytest.fixture
def get_single_phase_xmap(rotations):
def _get_single_phase_xmap(
nav_shape,
rotations_per_point=5,
prop_names=["scores", "simulation_indices"],
name="a",
phase_id=0,
):
d, map_size = _get_spatial_array_dicts(nav_shape)
rot_idx = np.random.choice(
np.arange(rotations.size), map_size * rotations_per_point
)
data_shape = (map_size,)
if rotations_per_point > 1:
data_shape += (rotations_per_point,)
d["rotations"] = rotations[rot_idx].reshape(*data_shape)
d["phase_id"] = np.ones(map_size) * phase_id
d["phase_list"] = PhaseList(Phase(name=name))
# Scores and simulation indices
d["prop"] = {
prop_names[0]: np.ones(data_shape, dtype=np.float32),
prop_names[1]: np.arange(np.prod(data_shape)).reshape(data_shape),
}
return CrystalMap(**d)

return _get_single_phase_xmap


def _get_spatial_array_dicts(
nav_shape: Tuple[int, int], step_sizes: Tuple[int, int] = (1.5, 1)
) -> Tuple[dict, int]:
ny, nx = nav_shape
dy, dx = step_sizes
d = {"x": None, "y": None, "z": None}
map_size = 1
if nx > 1:
if ny > 1:
d["x"] = np.tile(np.arange(nx) * dx, ny)
else:
d["x"] = np.arange(nx) * dx
map_size *= nx
if ny > 1:
if nx > 1:
d["y"] = np.sort(np.tile(np.arange(ny) * dy, nx))
else:
d["y"] = np.arange(ny) * dy
map_size *= ny
return d, map_size
4 changes: 2 additions & 2 deletions kikuchipy/generators/virtual_bse_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ def get_rgb_image(
See Also
--------
kikuchipy.signals.EBSD.plot_virtual_bse_intensity,
kikuchipy.signals.EBSD.get_virtual_bse_intensity,
~kikuchipy.signals.EBSD.plot_virtual_bse_intensity
~kikuchipy.signals.EBSD.get_virtual_bse_intensity
Notes
-----
Expand Down
23 changes: 15 additions & 8 deletions kikuchipy/indexing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,23 @@
# You should have received a copy of the GNU General Public License
# along with kikuchipy. If not, see <http://www.gnu.org/licenses/>.

"""Indexing of EBSD patterns."""
"""Tools for indexing of EBSD patterns by comparison to simulated
patterns.
from kikuchipy.indexing.similarity_metrics import (
make_similarity_metric,
MetricScope,
The EBSD method :meth:`~kikuchipy.signals.EBSD.match_patterns` uses
these tools for pattern matching.
"""

from kikuchipy.indexing._merge_crystal_maps import merge_crystal_maps
from kikuchipy.indexing.orientation_similarity_map import (
orientation_similarity_map,
)
from kikuchipy.indexing.pattern_matching import pattern_match
from kikuchipy.indexing import similarity_metrics
from kikuchipy.indexing._static_pattern_matching import StaticPatternMatching

__all__ = [
"make_similarity_metric",
"MetricScope",
"pattern_match",
"merge_crystal_maps",
"orientation_similarity_map",
"similarity_metrics",
"StaticPatternMatching",
]

0 comments on commit d1c799a

Please sign in to comment.