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

Test docstring examples #350

Merged
merged 7 commits into from
May 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,13 @@ jobs:
run: python -V; pip -V
- name: Install depedencies and package
shell: bash
run: pip install -U -e .'[doc, tests]'
run: pip install -U -e .'[tests]'
- name: Install oldest supported version
if: ${{ matrix.OLDEST_SUPPORTED_VERSION }}
run: pip install ${{ matrix.DEPENDENCIES }}
- name: Run docstring tests
if: ${{ matrix.os == 'ubuntu-latest' }}
run: pytest --doctest-modules --ignore-glob=kikuchipy/*/tests
- name: Run tests
run: pytest --cov=kikuchipy --pyargs kikuchipy
- name: Generate line coverage
Expand Down
4 changes: 3 additions & 1 deletion doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ Contributors

Added
-----
- Unit testing of docstring examples.
(`#350 <https://github.com/pyxem/kikuchipy/pull/350>`_)
- Support for Python 3.9.
(`#348 <https://github.com/pyxem/kikuchipy/pull/348>)`_
(`#348 <https://github.com/pyxem/kikuchipy/pull/348>`_)
- Projection/pattern center calibration via the moving screen technique in a
kikuchipy.detectors.calibration module.
(`#322 <https://github.com/pyxem/kikuchipy/pull/322>`_)
Expand Down
5 changes: 5 additions & 0 deletions doc/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,11 @@ terminal. For an even nicer presentation, you can use ``coverage.py`` directly::
Then, you can open the created ``htmlcov/index.html`` in the browser and inspect
the coverage in more detail.

Docstring examples are tested
`with pytest <https://docs.pytest.org/en/stable/doctest.html>`_ as well::

$ pytest --doctest-modules --ignore-glob=kikuchipy/*/tests

Adding data to the data module
==============================

Expand Down
97 changes: 66 additions & 31 deletions kikuchipy/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,21 @@
from diffsims.crystallography import ReciprocalLatticePoint
from hyperspy import __version__ as hs_version
from hyperspy.misc.utils import DictionaryTreeBrowser
import matplotlib.pyplot as plt
import numpy as np
from orix.crystal_map import CrystalMap, Phase, PhaseList
from orix.quaternion.rotation import Rotation
from orix.vector import Vector3d, neo_euler
import pytest

from kikuchipy.detectors import EBSDDetector
from kikuchipy.generators import EBSDSimulationGenerator
import kikuchipy as kp
from kikuchipy.projections.ebsd_projections import (
detector2reciprocal_lattice,
detector2direct_lattice,
)
from kikuchipy.signals import EBSD
from kikuchipy.simulations.features import KikuchiBand, ZoneAxis


# ------------------------- Helper functions ------------------------- #


def assert_dictionary(dict1, dict2):
Expand Down Expand Up @@ -70,6 +71,38 @@ def assert_dictionary(dict1, dict2):
assert dict1[key] == dict2[key]


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


# ------------------------------ Setup ------------------------------ #


def pytest_sessionstart(session): # pragma: no cover
_ = kp.data.nickel_ebsd_large(allow_download=True)


# ----------------------------- Fixtures ----------------------------- #


@pytest.fixture
def dummy_signal():
"""Dummy signal of shape <(3, 3)|(3, 3)>. If this is changed, all
Expand All @@ -87,7 +120,7 @@ def dummy_signal():
dtype=np.uint8
).reshape((3, 3, 3, 3))
# fmt: on
return EBSD(dummy_array)
return kp.signals.EBSD(dummy_array)


@pytest.fixture
Expand Down Expand Up @@ -146,7 +179,7 @@ def pc1():
@pytest.fixture(params=[(1,)])
def detector(request, pc1):
"""A NORDIF UF1100 EBSD detector with a TSL PC."""
return EBSDDetector(
return kp.detectors.EBSDDetector(
shape=(60, 60),
binning=8,
px_size=70,
Expand Down Expand Up @@ -214,7 +247,7 @@ def nickel_ebsd_simulation_generator(
"""Generator for EBSD simulations of Kikuchi bands for the Nickel
data set referenced above.
"""
return EBSDSimulationGenerator(
return kp.generators.EBSDSimulationGenerator(
detector=detector, phase=nickel_phase, rotations=nickel_rotations,
)

Expand All @@ -228,7 +261,7 @@ def nickel_kikuchi_band(nickel_rlp, nickel_rotations, pc1):

nav_shape = (5, 5)

detector = EBSDDetector(
detector = kp.detectors.EBSDDetector(
shape=(60, 60),
binning=8,
px_size=70,
Expand Down Expand Up @@ -262,7 +295,7 @@ def nickel_kikuchi_band(nickel_rlp, nickel_rotations, pc1):
hkl_detector[is_in_some_pattern], source=0, destination=nav_dim
)

return KikuchiBand(
return kp.simulations.features.KikuchiBand(
phase=phase,
hkl=hkl,
hkl_detector=hkl_detector,
Expand All @@ -279,7 +312,7 @@ def nickel_zone_axes(nickel_kikuchi_band, nickel_rotations, pc1):

nav_shape = (5, 5)

detector = EBSDDetector(
detector = kp.detectors.EBSDDetector(
shape=(60, 60),
binning=8,
px_size=70,
Expand Down Expand Up @@ -315,7 +348,7 @@ def nickel_zone_axes(nickel_kikuchi_band, nickel_rotations, pc1):
uvw_detector[is_in_some_pattern], source=0, destination=nav_dim
)

return ZoneAxis(
return kp.simulations.features.ZoneAxis(
phase=phase,
uvw=uvw,
uvw_detector=uvw_detector,
Expand Down Expand Up @@ -358,23 +391,25 @@ def _get_single_phase_xmap(
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
# ---------------------- pytest doctest-modules ---------------------- #


@pytest.fixture(autouse=True)
def doctest_setup_teardown(request):
# Setup
plt.ioff() # Interactive plotting off
temporary_directory = tempfile.TemporaryDirectory()
original_directory = os.getcwd()
os.chdir(temporary_directory.name)
yield

# Teardown
os.chdir(original_directory)
temporary_directory.cleanup()
plt.close("all")


@pytest.fixture(autouse=True)
def import_to_namespace(doctest_namespace):
DIR_PATH = os.path.dirname(__file__)
doctest_namespace["DATA_DIR"] = os.path.join(DIR_PATH, "data/kikuchipy")
17 changes: 7 additions & 10 deletions kikuchipy/detectors/ebsd_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,25 +87,25 @@ def __init__(

Examples
--------
>>> import numpy as np
>>> from kikuchipy.detectors import EBSDDetector
>>> det = EBSDDetector(
... shape=(60, 60),
... pc=np.ones((149, 200)) * [0.421, 0.779, 0.505],
... pc=np.ones((149, 200, 3)) * (0.421, 0.779, 0.505),
... convention="tsl",
... px_size=70,
... binning=8,
... tilt=5,
... sample_tilt=70,
... )
>>> det
EBSDDetector (60, 60), px_size 70 um, binning 8, tilt 0, pc
(0.421, 0.221, 0.505)
EBSDDetector (60, 60), px_size 70 um, binning 8, tilt 5, pc (0.421, 0.221, 0.505)
>>> det.navigation_shape # (nrows, ncols)
(149, 200)
>>> det.bounds
array([ 0, 60, 0, 60])
>>> det.gnomonic_bounds
array([-0.83366337, 1.14653465, -1.54257426, 0.43762376])
array([ 0, 59, 0, 59])
>>> det.gnomonic_bounds[0, 0]
array([-0.83366337, 1.14653465, -0.83366337, 1.14653465])
>>> det.plot()
"""
self.shape = shape
Expand Down Expand Up @@ -527,11 +527,8 @@ def plot(
>>> from kikuchipy.detectors import EBSDDetector
>>> det = EBSDDetector(
... shape=(60, 60),
... pc=np.ones((149, 200)) * [0.421, 0.779, 0.505],
... pc=np.ones((149, 200, 3)) * (0.421, 0.779, 0.505),
... convention="tsl",
... pixel_size=70,
... binning=8,
... tilt=5,
... sample_tilt=70,
... )
>>> det.plot()
Expand Down
34 changes: 22 additions & 12 deletions kikuchipy/filters/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ class Window(np.ndarray):

Examples
--------
>>> import kikuchipy as kp
>>> import numpy as np
>>> import kikuchipy as kp

The following passed parameters are the default

Expand Down Expand Up @@ -95,19 +95,19 @@ class Window(np.ndarray):
>>> w = kp.filters.Window(np.arange(6).reshape(3, 2))
>>> w
Window (3, 2) custom
[[0, 1]
[2, 3]
[4, 5]]
[[0 1]
[2 3]
[4 5]]

To create a Gaussian window with a standard deviation of 2, obtained
from :func:`scipy.signal.windows.gaussian`

>>> w = kp.filters.Window(window="gaussian", std=2)
>>> w
Window (3, 3) gaussian
[[0.77880078, 0.8824969 , 0.77880078]
[0.8824969 , 1. , 0.8824969 ]
[0.77880078, 0.8824969 , 0.77880078]]
[[0.7788 0.8825 0.7788]
[0.8825 1. 0.8825]
[0.7788 0.8825 0.7788]]

See Also
--------
Expand Down Expand Up @@ -326,8 +326,11 @@ def plot(
showing element values and x/y ticks, can be produced and
written to file

>>> import kikuchipy as kp
>>> w = kp.filters.Window()
>>> figure, image, colorbar = w.plot(
... cmap="inferno", grid=True, show_values=True)
... cmap="inferno", grid=True, show_values=True
... )
>>> figure.savefig('my_kernel.png')
"""
if not self.is_valid():
Expand Down Expand Up @@ -437,6 +440,7 @@ def modified_hann(Nx: int) -> np.ndarray:

Examples
--------
>>> import numpy as np
>>> import kikuchipy as kp
>>> w1 = kp.filters.modified_hann(Nx=30)
>>> w2 = kp.filters.Window("modified_hann", shape=(30,))
Expand Down Expand Up @@ -490,11 +494,14 @@ def lowpass_fft_filter(

Examples
--------
>>> import numpy as np
>>> import kikuchipy as kp
>>> w1 = kp.filters.Window(
... "lowpass", cutoff=30, cutoff_width=15, shape=(96, 96))
... "lowpass", cutoff=30, cutoff_width=15, shape=(96, 96)
... )
>>> w2 = kp.filters.lowpass_fft_filter(
shape=(96, 96), cutoff=30, cutoff_width=15)
... shape=(96, 96), cutoff=30, cutoff_width=15
... )
>>> np.allclose(w1, w2)
True
"""
Expand Down Expand Up @@ -554,11 +561,14 @@ def highpass_fft_filter(

Examples
--------
>>> import numpy as np
>>> import kikuchipy as kp
>>> w1 = kp.filters.Window(
... "highpass", cutoff=1, cutoff_width=0.5, shape=(96, 96))
... "highpass", cutoff=1, cutoff_width=0.5, shape=(96, 96)
... )
>>> w2 = kp.filters.highpass_fft_filter(
... shape=(96, 96), cutoff=1, cutoff_width=0.5)
... shape=(96, 96), cutoff=1, cutoff_width=0.5
... )
>>> np.allclose(w1, w2)
True
"""
Expand Down
Loading