Skip to content

Commit

Permalink
Merge pull request #349 from hakonanes/fix-346
Browse files Browse the repository at this point in the history
Fix scaling of region of interest coordinates in virtual backscatter electron imaging generator
  • Loading branch information
hakonanes committed Apr 29, 2021
2 parents bddf53b + 58ebd55 commit 676ac7c
Show file tree
Hide file tree
Showing 13 changed files with 122 additions and 49 deletions.
8 changes: 4 additions & 4 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
include kikuchipy/hyperspy_extension.yaml
include LICENSE
include MANIFEST.in
include pyproject.toml
include setup.cfg
include README.rst
include RELEASE.rst
include readthedocs.yml
include setup.py
include kikuchipy/hyperspy_extension.yaml

recursive-include doc Makefile make.bat
recursive-include doc *.rst *.py *.ipynb
recursive-include doc/_static *.png *.jpg *.svg *.gif *.sh
recursive-include doc Makefile make.bat *.rst *.py *.ipynb
recursive-include doc/_static *.png *.jpg *.svg *.gif
recursive-include kikuchipy/data *
6 changes: 6 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ Added
- Reading of NORDIF calibration patterns specified in a setting file into an
EBSD signal. (`#317 <https://github.com/pyxem/kikuchipy/pull/317>`_)

Fixed
-----
- Scaling of region of interest coordinates used in virtual backscatter electron
imaging to physical coordinates
(`#349 <https://github.com/pyxem/kikuchipy/pull/349>`_)

0.3.3 (2021-04-18)
==================

Expand Down
15 changes: 12 additions & 3 deletions doc/virtual_backscatter_electron_imaging.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,22 @@
"s"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We create a rectangular ROI by specifying the upper left and lower right\n",
"coordinates of the rectangle in units of the detector pixel size (scale of `dx`\n",
"and `dy` in the signal axes manager)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"roi = hs.roi.RectangularROI(left=0, top=0, right=10, bottom=10)\n",
"roi"
"s.axes_manager"
]
},
{
Expand All @@ -69,6 +77,7 @@
"metadata": {},
"outputs": [],
"source": [
"roi = hs.roi.RectangularROI(left=0, top=0, right=10, bottom=10)\n",
"s.plot_virtual_bse_intensity(roi)"
]
},
Expand Down Expand Up @@ -400,7 +409,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.6"
"version": "3.8.8"
}
},
"nbformat": 4,
Expand Down
8 changes: 6 additions & 2 deletions kikuchipy/data/bruker/create_bruker_h5ebsd_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,12 @@
# Header
ebsd_header = ebsd.create_group("Header")
ebsd_header.create_dataset("CameraTilt", dtype=float, data=0)
ebsd_header.create_dataset("DetectorFullHeightMicrons", dtype=np.int32, data=sy)
ebsd_header.create_dataset("DetectorFullWidthMicrons", dtype=np.int32, data=sx)
ebsd_header.create_dataset(
"DetectorFullHeightMicrons", dtype=np.int32, data=23700
)
ebsd_header.create_dataset(
"DetectorFullWidthMicrons", dtype=np.int32, data=31600
)
grid_type = ebsd_header.create_dataset("Grid Type", shape=(1,), dtype="|S9")
grid_type[()] = b"isometric"
ebsd_header.create_dataset("KV", dtype=float, data=20)
Expand Down
Binary file modified kikuchipy/data/bruker/patterns.h5
Binary file not shown.
Binary file modified kikuchipy/data/bruker/patterns_roi.h5
Binary file not shown.
Binary file modified kikuchipy/data/bruker/patterns_roi_nonrectangular.h5
Binary file not shown.
33 changes: 17 additions & 16 deletions kikuchipy/generators/virtual_bse_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ def get_images_from_grid(
images[row, col] = self.signal.get_virtual_bse_intensity(roi).data

vbse_images = VirtualBSEImage(images)
# TODO: Transfer signal's detector axes to new navigation axes with
# proper binning
# TODO: Transfer signal's detector axes to new navigation axes
# with proper binning
vbse_images.axes_manager = _transfer_navigation_axes_to_signal_axes(
new_axes=vbse_images.axes_manager, old_axes=self.signal.axes_manager
)
Expand All @@ -243,15 +243,16 @@ def roi_from_grid(self, index: Union[Tuple, List[Tuple]]) -> RectangularROI:
"""
rows = self.grid_rows
cols = self.grid_cols
dc, dr = [i.scale for i in self.signal.axes_manager.signal_axes]

if isinstance(index, tuple):
index = (index,)
index = np.array(index)

min_col = cols[min(index[:, 1])]
max_col = cols[max(index[:, 1])] + cols[1]
min_row = rows[min(index[:, 0])]
max_row = rows[max(index[:, 0])] + rows[1]
min_col = cols[min(index[:, 1])] * dc
max_col = (cols[max(index[:, 1])] + cols[1]) * dc
min_row = rows[min(index[:, 0])] * dr
max_row = (rows[max(index[:, 0])] + rows[1]) * dr

return RectangularROI(
left=min_col, top=min_row, right=max_col, bottom=max_row,
Expand Down Expand Up @@ -289,9 +290,9 @@ def plot_grid(
pattern : kikuchipy.signals.EBSD
A single pattern with the markers added.
"""
# Get detector scales
# Get detector scales (column, row)
axes_manager = self.signal.axes_manager
dx, dy = [i.scale for i in axes_manager.signal_axes]
dc, dr = [i.scale for i in axes_manager.signal_axes]

rows = self.grid_rows
cols = self.grid_cols
Expand All @@ -303,17 +304,17 @@ def plot_grid(
for row, col in np.ndindex(self.grid_shape):
markers.append(
Text(
x=cols[col],
y=rows[row] + (0.1 * rows[1]),
x=cols[col] * dc,
y=(rows[row] + (0.1 * rows[1])) * dr,
text=f"{row,col}",
color=color,
)
)

# Set lines
kwargs.setdefault("color", "w")
markers += [HorizontalLine((i - 0.5) * dy, **kwargs) for i in rows]
markers += [VerticalLine((j - 0.5) * dx, **kwargs) for j in cols]
markers += [HorizontalLine((i - 0.5) * dr, **kwargs) for i in rows]
markers += [VerticalLine((j - 0.5) * dc, **kwargs) for j in cols]

# Color RGB tiles
if rgb_channels is not None:
Expand All @@ -325,10 +326,10 @@ def plot_grid(
roi = self.roi_from_grid((row, col))
markers += [
Rectangle(
x1=(roi.left - 0.5) * dx,
y1=(roi.top - 0.5) * dx,
x2=(roi.right - 0.5) * dy,
y2=(roi.bottom - 0.5) * dy,
x1=(roi.left - 0.5) * dc,
y1=(roi.top - 0.5) * dc,
x2=(roi.right - 0.5) * dr,
y2=(roi.bottom - 0.5) * dr,
**kwargs,
)
]
Expand Down
17 changes: 17 additions & 0 deletions kikuchipy/indexing/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
# Copyright 2019-2021 The kikuchipy developers
#
# This file is part of kikuchipy.
#
# kikuchipy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# kikuchipy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with kikuchipy. If not, see <http://www.gnu.org/licenses/>.
51 changes: 30 additions & 21 deletions kikuchipy/io/plugins/h5ebsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -749,21 +749,21 @@ def brukerheader2dicts(
# Get region of interest (ROI, only rectangular shape supported)
try:
sd = hdf5group2dict(group=scan_group["EBSD/SEM"])
iy = sd["IY"][()]
ix = sd["IX"][()]
ir = sd["IY"][()]
ic = sd["IX"][()]
roi = True
except KeyError:
roi = False
ny = hd["NROWS"]
nx = hd["NCOLS"]
nr = hd["NROWS"]
nc = hd["NCOLS"]
if roi:
ny_roi, nx_roi, is_rectangular = _bruker_roi_is_rectangular(iy, ix)
nr_roi, nc_roi, is_rectangular = _bruker_roi_is_rectangular(ir, ic)
if is_rectangular:
ny = ny_roi
nx = nx_roi
nr = nr_roi
nc = nc_roi
# Get indices of patterns in the 2D map
idx = np.array([iy - np.min(iy), ix - np.min(ix)])
scan_size["indices"] = np.ravel_multi_index(idx, (ny, nx)).argsort()
idx = np.array([ir - np.min(ir), ic - np.min(ic)])
scan_size["indices"] = np.ravel_multi_index(idx, (nr, nc)).argsort()
else:
raise ValueError(
"Only a rectangular region of interest is supported"
Expand All @@ -772,8 +772,8 @@ def brukerheader2dicts(
# Populate scan size dictionary
scan_size.set_item("sx", hd["PatternWidth"])
scan_size.set_item("sy", hd["PatternHeight"])
scan_size.set_item("nx", nx)
scan_size.set_item("ny", ny)
scan_size.set_item("nx", nc)
scan_size.set_item("ny", nr)
scan_size.set_item("step_x", hd["XSTEP"])
scan_size.set_item("step_y", hd["YSTEP"])
scan_size.set_item(
Expand All @@ -783,18 +783,27 @@ def brukerheader2dicts(
return md, omd, scan_size


def _bruker_roi_is_rectangular(iy, ix):
iy_unique, iy_unique_counts = np.unique(iy, return_counts=True)
ix_unique, ix_unique_counts = np.unique(ix, return_counts=True)
def _bruker_roi_is_rectangular(ir, ic):
ir_unique, ir_unique_counts = np.unique(ir, return_counts=True)
ic_unique, ic_unique_counts = np.unique(ic, return_counts=True)
is_rectangular = (
np.all(np.diff(np.sort(iy_unique)) == 1)
and np.all(np.diff(np.sort(ix_unique)) == 1)
and np.unique(iy_unique_counts).size == 1
and np.unique(ix_unique_counts).size == 1
np.all(np.diff(np.sort(ir_unique)) == 1)
and np.all(np.diff(np.sort(ic_unique)) == 1)
and np.unique(ir_unique_counts).size == 1
and np.unique(ic_unique_counts).size == 1
)
iy2 = np.max(iy) - np.min(iy) + 1
ix2 = np.max(ix) - np.min(ix) + 1
return iy2, ix2, is_rectangular
ir2 = np.max(ir) - np.min(ir) + 1
ic2 = np.max(ic) - np.min(ic) + 1
return ir2, ic2, is_rectangular


# (n rows, n columns). Source: internet
BRUKER_DETECTOR_MODEL_RESOLUTION = dict(
eflash_fs=(480, 640),
eflash_hd=(1200, 1600),
eflash_hr=(1200, 1600),
eflash_xs=(540, 720),
)


def file_writer(
Expand Down
17 changes: 17 additions & 0 deletions kikuchipy/pattern/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
# Copyright 2019-2021 The kikuchipy developers
#
# This file is part of kikuchipy.
#
# kikuchipy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# kikuchipy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with kikuchipy. If not, see <http://www.gnu.org/licenses/>.
4 changes: 2 additions & 2 deletions kikuchipy/signals/ebsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -1430,7 +1430,7 @@ def plot_virtual_bse_intensity(

# Create the interactive signal
interactive(
f=sliced_signal.sum,
f=sliced_signal.nansum,
axis=sliced_signal.axes_manager.signal_axes,
event=roi.events.changed,
recompute_out_event=None,
Expand All @@ -1442,7 +1442,7 @@ def plot_virtual_bse_intensity(

@staticmethod
def _get_sum_signal(signal, out_signal_axes: Optional[List] = None):
out = signal.sum(signal.axes_manager.signal_axes)
out = signal.nansum(signal.axes_manager.signal_axes)
if out_signal_axes is None:
out_signal_axes = list(
np.arange(min(signal.axes_manager.navigation_dimension, 2))
Expand Down
12 changes: 11 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Note that Black does not support setup.cfg

[tool:pytest]
addopts = -ra

Expand All @@ -11,4 +13,12 @@ relative_files = True
[coverage:report]
precision = 2

# Note that Black does not support setup.cfg
[manifix]
known_excludes =
.*
.*/**
.git/**
**/*.pyc
doc/build*
htmlcov/**
*.code-workspace

0 comments on commit 676ac7c

Please sign in to comment.