From b9e0c36e86b7420c8e494197ffa9ca60697693a2 Mon Sep 17 00:00:00 2001
From: Erlendos12 <99336047+Erlendos12@users.noreply.github.com>
Date: Wed, 29 Mar 2023 19:27:27 +0200
Subject: [PATCH 1/2] Add doc for hough indexing with multiple phases
---
.../hough_indexing_multiple_phases.ipynb | 883 ++++++++++++++++++
kikuchipy/data/__init__.py | 2 +
kikuchipy/data/_data.py | 43 +
kikuchipy/data/_registry.py | 2 +
kikuchipy/data/tests/test_data.py | 9 +
5 files changed, 939 insertions(+)
create mode 100644 doc/tutorials/hough_indexing_multiple_phases.ipynb
diff --git a/doc/tutorials/hough_indexing_multiple_phases.ipynb b/doc/tutorials/hough_indexing_multiple_phases.ipynb
new file mode 100644
index 00000000..a1468d0d
--- /dev/null
+++ b/doc/tutorials/hough_indexing_multiple_phases.ipynb
@@ -0,0 +1,883 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "8b9b51ab-7a89-437f-80b6-080030a6233b",
+ "metadata": {
+ "nbsphinx": "hidden"
+ },
+ "source": [
+ "This notebook is part of the `kikuchipy` documentation https://kikuchipy.org.\n",
+ "Links to the documentation won't work from the notebook."
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "48f0168b-a986-4467-a59d-6e0af1301df9",
+ "metadata": {},
+ "source": [
+ "# Hough indexing with multiple phases\n",
+ "\n",
+ "In this tutorial, we will perform Hough indexing (HI) on a dataset containing both FCC and BCC structured phases using [PyEBSDIndex](https://pyebsdindex.readthedocs.io). We will also refine orientations before merging crystal maps from each phase. A 32 MB dataset of super duplex stainless steel, containing austenite and ferrite, will be used.\n",
+ "\n",
+ "
\n",
+ "\n",
+ "Note\n",
+ "\n",
+ "PyEBSDIndex is an optional dependency of kikuchipy, and can be installed with both `pip` and `conda` (from `conda-forge`).\n",
+ "To install PyEBSDIndex, see their [installation instructions](https://pyebsdindex.readthedocs.io/en/latest/installation.html).\n",
+ "\n",
+ "PyEBSDIndex supports indexing face centered and body centered cubic (FCC and BCC) materials.\n",
+ "\n",
+ "
\n",
+ "\n",
+ "Let's import necessary libraries"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "386299e8-8698-4efa-a913-440baf6d389e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Exchange inline for notebook or qt5 (from pyqt) for interactive plotting\n",
+ "%matplotlib inline\n",
+ "\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "\n",
+ "from diffsims.crystallography import ReciprocalLatticeVector\n",
+ "import kikuchipy as kp\n",
+ "from orix import plot\n",
+ "from orix.crystal_map import PhaseList\n",
+ "from orix.vector import Vector3d\n",
+ "\n",
+ "\n",
+ "plt.rcParams.update(\n",
+ " {\"font.size\": 15, \"lines.markersize\": 15, \"scatter.edgecolors\": \"k\"}\n",
+ ")"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "3167fc89-7080-4ed7-a146-3b098875e08e",
+ "metadata": {},
+ "source": [
+ "Load a dataset of (60, 60) SDSS EBSD patterns of (48, 48) pixels with a step size of 1.0 μm"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "f91c0b61-37ce-4666-aeb1-e665ca3a0e8b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = kp.data.sdss_ebsd(allow_download=True)\n",
+ "s"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "086b69bb-712d-414b-81b0-5e955c4bcaf6",
+ "metadata": {},
+ "source": [
+ "## Pre-indexing maps\n",
+ "\n",
+ "First, we produce two indexing independent maps showing microstructural features: a [virtual backscatter electron (VBSE) image](virtual_backscatter_electron_imaging.ipynb) and an [image quality (IQ) map](feature_maps.ipynb#Image-quality).\n",
+ "The former uses the BSE yield on the detector to give a qualitative orientation contrast, so is done on raw unprocessed patterns.\n",
+ "The latter assumes that the sharper the Kikuchi bands, the higher the image quality, so is done on processed patterns."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "cd9f52d8-1e0b-43d2-bd32-085cea15b19c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vbse_imager = kp.imaging.VirtualBSEImager(s)\n",
+ "print(vbse_imager.grid_shape)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9d67599a-f11e-4d48-87bd-3959ebe9a420",
+ "metadata": {},
+ "source": [
+ "Get the VBSE image by coloring the three center grid tiles red, green and blue"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5ff2bde2-acc2-4b1c-88a5-df96119cb090",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "maps_vbse_rgb = vbse_imager.get_rgb_image(r=(2, 1), g=(2, 2), b=(2, 3))\n",
+ "maps_vbse_rgb"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1b85b14b-b91b-45ad-a39b-bb5c9d782e56",
+ "metadata": {},
+ "source": [
+ "Plot the VBSE image"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "aa72ad12-fdd3-4d1b-a80a-3f7eb883061b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "maps_vbse_rgb.plot()"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "bad0046f-ab46-4478-8703-2dc09f3990f5",
+ "metadata": {},
+ "source": [
+ "Enhance the Kikuchi bands by removing the static and dynamic background (see the [pattern processing tutorial](pattern_processing.ipynb) for details)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "748b330c-0681-43ac-925b-951ebcd402ae",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s.remove_static_background()\n",
+ "s.remove_dynamic_background()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "2d4459e4-6923-47bc-8a00-7c31a6b685cd",
+ "metadata": {},
+ "source": [
+ "Get the IQ map"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "dec9bad2-c017-45c9-ab91-32db09c3a0b8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "maps_iq = s.get_image_quality()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ba216058-097a-44e7-85d1-20e30464c679",
+ "metadata": {},
+ "source": [
+ "Plot the IQ map (using the [CrystalMap.plot()](https://orix.readthedocs.io/en/stable/reference/generated/orix.crystal_map.CrystalMap.plot.html) method of the [EBSD.xmap](../reference/generated/kikuchipy.signals.EBSD.xmap.rst) attribute)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "480d83ad-361a-40f9-97a2-1437b5d76dd2",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s.xmap.plot(\n",
+ " maps_iq.ravel(), # Must be 1D\n",
+ " cmap=\"gray\",\n",
+ " colorbar=True,\n",
+ " colorbar_label=\"Image quality $Q$\",\n",
+ " remove_padding=True,\n",
+ ")"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "81023608-d459-490c-805c-a93b59594bf3",
+ "metadata": {},
+ "source": [
+ "We recognize the grain boundaries from the VBSE image."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "784d523f-238b-4065-abea-314159a50de9",
+ "metadata": {},
+ "source": [
+ "## Calibrate detector-sample geometry\n",
+ "\n",
+ "We need to know the position of the sample with respect to the detector, the so-called projection/pattern center (PC) (see the [reference frames tutorial](reference_frames.ipynb) for all conventions).\n",
+ "We do this by optimizing an initial guess of the PC obtained from similar experiments on the same microscope.\n",
+ "\n",
+ "We will keep all detector-sample geometry parameters conveniently in an [EBSDDetector](../reference/generated/kikuchipy.detectors.EBSDDetector.rst)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "3085ad18-b7bd-4fce-95fa-e3a9a8c3ea9a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sig_shape = s.axes_manager.signal_shape[::-1] # (Rows, columns)\n",
+ "det = kp.detectors.EBSDDetector(sig_shape, sample_tilt=70)\n",
+ "\n",
+ "det"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "602ee407-2f25-4021-9f18-f299f587cfd2",
+ "metadata": {},
+ "source": [
+ "Extract patterns from the full dataset spread out evenly in a map grid"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "e007ff94-019d-498a-a6b7-4820bf60147d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "grid_shape = (4, 4)\n",
+ "s_grid, idx = s.extract_grid(grid_shape, return_indices=True)\n",
+ "s_grid"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "10c679b7-0b31-4afe-9152-40a2cd2f85d3",
+ "metadata": {},
+ "source": [
+ "Plot the pattern grid on the IQ map"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bf54b0aa-bd42-4200-bc8d-a36558757d07",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "nav_shape = s.axes_manager.navigation_shape[::-1]\n",
+ "\n",
+ "kp.draw.plot_pattern_positions_in_map(\n",
+ " rc=idx.reshape(2, -1).T, # Shape (n patterns, 2)\n",
+ " roi_shape=nav_shape, # Or maps_iq.shape\n",
+ " roi_image=maps_iq,\n",
+ ")"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "b9b740e5-c178-4236-8bcc-415e85bd9948",
+ "metadata": {},
+ "source": [
+ "We will optimize one PC per pattern in this grid using [EBSD.hough_indexing_optimize_pc()](../reference/generated/kikuchipy.signals.EBSD.hough_indexing_optimize_pc.rst), which calls the `PyEBSDIndex` function\n",
+ "[pcopt.optimize()](https://pyebsdindex.readthedocs.io/en/stable/reference/generated/pyebsdindex.pcopt.optimize.html) internally.\n",
+ "Hough indexing with `PyEBSDIndex` is centered around the use of an [EBSDIndexer](https://pyebsdindex.readthedocs.io/en/stable/reference/generated/pyebsdindex.ebsd_index.EBSDIndexer.html).\n",
+ "The indexer stores the phase and detector information as well as the indexing parameters, like the resolution of the Hough transform and the number of bands to use for orientation determination.\n",
+ "Here, we obtain this indexer by combining a [PhaseList](https://orix.readthedocs.io/en/stable/reference/generated/orix.crystal_map.PhaseList.html) with an `EBSDDetector` via [EBSDDetector.get_indexer()](../reference/generated/kikuchipy.detectors.EBSDDetector.get_indexer.rst). We will download and use the master patterns for austenite and ferrite to define the phases, and use the master patterns later to do orientation refinement."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ab80ae0d-01df-48df-a8d6-acbe89f31aa2",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mp_austenite = kp.data.ebsd_master_pattern(\n",
+ " \"austenite\",\n",
+ " energy=20, # kV\n",
+ " projection=\"lambert\",\n",
+ " hemisphere=\"upper\",\n",
+ " allow_download=True,\n",
+ ")\n",
+ "mp_ferrite = kp.data.ebsd_master_pattern(\n",
+ " \"ferrite\",\n",
+ " energy=20, # kV\n",
+ " projection=\"lambert\",\n",
+ " hemisphere=\"upper\",\n",
+ " allow_download=True,\n",
+ ")\n",
+ "\n",
+ "phase_list = PhaseList()\n",
+ "phase_list.add(mp_austenite.phase)\n",
+ "phase_list.add(mp_ferrite.phase)\n",
+ "phase_list"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "071b1dfb-1a23-4f11-9a16-d3f5df3a5418",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "indexer = det.get_indexer(phase_list)\n",
+ "\n",
+ "print(indexer.vendor)\n",
+ "print(indexer.sampleTilt)\n",
+ "print(indexer.camElev)\n",
+ "print(indexer.PC)\n",
+ "print(indexer.phaselist)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "50b66e56-df61-4252-bc07-2bf8c37405a3",
+ "metadata": {},
+ "source": [
+ "Optimize PCs for each grid pattern using the Nelder-Mead optimization algorithm from SciPy.\n",
+ "(We will \"overwrite\" the existing detector variable.)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7e737efa-229d-462a-aef5-851032b29b54",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "det = s_grid.hough_indexing_optimize_pc(\n",
+ " pc0=[0.50, 0.35, 0.52], # Initial guess based on previous experiments\n",
+ " indexer=indexer,\n",
+ " batch=True,\n",
+ ")\n",
+ "\n",
+ "# Print mean and standard deviation\n",
+ "print(det.pc_flattened.mean(axis=0))\n",
+ "print(det.pc_flattened.std(0))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ef2b49ce-3194-413c-b564-f223f0cccd13",
+ "metadata": {},
+ "source": [
+ "Plot the PCs"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "edb85679-0358-4300-ac23-a738e52732ab",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "det.plot_pc(\"scatter\", s=50, annotate=True)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "7928b35d-a315-4d75-8322-a98fe847bc45",
+ "metadata": {},
+ "source": [
+ "The values do not order nicely in the grid they were extracted from...\n",
+ "This is not that surprising though, seeing that they are only (48, 48) pixels wide!\n",
+ "Fortunately, the spread is not great, so we will can use the mean PC for indexing."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "96991049-7742-4851-817c-6e7c308b50cc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "det.pc = det.pc_average"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "8c6cc769-8ee2-499e-a9be-46f4c8d15dc6",
+ "metadata": {},
+ "source": [
+ "We can check the position of the mean PC on the detector before using it."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7eb88c8b-0018-4ae6-a3d9-fd7014b9765d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "det.plot(pattern=s_grid.inav[0, 0].data)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "a0692f45-3059-46d0-a5c8-df2b0fadbd2e",
+ "metadata": {},
+ "source": [
+ "## Perform indexing\n",
+ "\n",
+ "With this PC calibration, we can index all patterns.\n",
+ "We will get a new indexer from the detector with the average PC as determined from the optimization above."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "54710226-9623-4261-9100-e27239be3978",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "indexer = det.get_indexer(phase_list)\n",
+ "indexer.PC"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "59ac5e5b-5e59-4c5b-9b0b-b3cd035e92e6",
+ "metadata": {},
+ "source": [
+ "Now we are ready to index our patterns using [EBSD.hough_indexing()](../reference/generated/kikuchipy.signals.EBSD.hough_indexing.rst).\n",
+ "After indexing is done, we will also plot the Hough transform of the first pattern with the nine detected bands used in indexing highlighted (by passing `verbose=2` on top `PyEBSDIndex`).\n",
+ "Although we passed the phase list to create the indexer with `EBSDDetector.get_indexer()` above, we need to pass it to `EBSD.hough_indexing()` to describe the phases correctly in the returned [CrystalMap](https://orix.readthedocs.io/en/stable/reference/generated/orix.crystal_map.CrystalMap.html). We also pass `return_index_data=True` so the index data is avaiable later when doing orientation refinement. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "1830c550-c4e7-4a62-9fc3-8c9772726497",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "xmap, data = s.hough_indexing(\n",
+ " phase_list=phase_list, indexer=indexer, verbose=2, return_index_data=True\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bc302021-c9ee-470d-ad48-90ddf1207643",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "xmap"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "580af2ff-5f5f-43e4-9628-7ce8475e6e9c",
+ "metadata": {},
+ "source": [
+ "## Validate indexing results"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "faa4d916-ef3e-44db-b9d9-bae4d6a131aa",
+ "metadata": {},
+ "source": [
+ "Plot quality metrics"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "42eb10aa-f94a-4f73-8b27-ece7a9366b6f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "aspect_ratio = xmap.shape[1] / xmap.shape[0]\n",
+ "figsize = (8 * aspect_ratio, 4.5 * aspect_ratio)\n",
+ "\n",
+ "fig, ax = plt.subplots(nrows=2, ncols=2, figsize=figsize)\n",
+ "for a, to_plot in zip(ax.ravel(), [\"pq\", \"cm\", \"fit\", \"nmatch\"]):\n",
+ " im = a.imshow(xmap.get_map_data(to_plot))\n",
+ " fig.colorbar(im, ax=a, label=to_plot)\n",
+ " a.axis(\"off\")\n",
+ "fig.subplots_adjust(wspace=0, hspace=0.05)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "d31d51e9-db59-4643-90f1-33db6da7ac72",
+ "metadata": {},
+ "source": [
+ "The pattern quality (PQ) and confidence metric (CM) maps show little variation across the sample.\n",
+ "The most important map here is the pattern fit (also known as the mean angular error/deviation), which shows the average angular deviation between the positions of each detected band to the closest theoretical band: this is below an OK fit of 1.5$^{\\circ}$ across most of the map, but some values reach closer to 2.0$^{\\circ}$. \n",
+ "The final map (*nmatch*) shows that most of the nine detected bands in each pattern were indexed within a pattern fit of 3$^{\\circ}$.\n",
+ "See the [PyEBSDIndex Hough indexing tutorial](https://pyebsdindex.readthedocs.io/en/latest/tutorials/ebsd_index_demo.html) for a complete explanation of all the indexing result parameters.\n",
+ "\n",
+ "Phases can be plotted with"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "731a204f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "xmap.plot(remove_padding=True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "89d4bdcb",
+ "metadata": {},
+ "source": [
+ "Create a color key to color orientations with"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "18eb8100-cc02-455d-9bd3-6e864589dfb1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "v_ipf = Vector3d.xvector()\n",
+ "sym = xmap.phases[0].point_group\n",
+ "\n",
+ "ckey = plot.IPFColorKeyTSL(sym, v_ipf)\n",
+ "ckey"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "77451774-c1fc-40e6-a94c-fcd626a20695",
+ "metadata": {},
+ "source": [
+ "Orientations are given a color based on which crystal direction $\\left$ points in a certain sample direction, producing the so-called inverse pole figure (IPF) map.\n",
+ "Let's plot the IPF-X map with the CM map overlayed"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "dac157a4-3b96-49f8-a5eb-f3987c9af076",
+ "metadata": {
+ "nbsphinx-thumbnail": {
+ "tooltip": "Hough indexing using PyEBSDIndex"
+ },
+ "tags": [
+ "nbsphinx-thumbnail"
+ ]
+ },
+ "outputs": [],
+ "source": [
+ "rgb_x = ckey.orientation2color(xmap.rotations)\n",
+ "fig = xmap.plot(rgb_x, overlay=\"cm\", remove_padding=True, return_figure=True)\n",
+ "\n",
+ "# Place color key in bottom right corner, coordinates are [left, bottom, width, height]\n",
+ "ax_ckey = fig.add_axes([0.63, 0.08, 0.2, 0.2], projection=\"ipf\", symmetry=sym)\n",
+ "ax_ckey.plot_ipf_color_key(show_title=False)\n",
+ "ax_ckey.patch.set_facecolor(\"None\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f252e330-0405-4b06-a422-e50291d6509f",
+ "metadata": {},
+ "source": [
+ "Let's also plot the three maps side by side"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "99d5f1ff-4919-40b8-aea2-d2e7b8a72d8b",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "directions = Vector3d(((1, 0, 0), (0, 1, 0), (0, 0, 1)))\n",
+ "n = directions.size\n",
+ "\n",
+ "figsize = (4 * n * aspect_ratio, n * aspect_ratio)\n",
+ "fig, ax = plt.subplots(ncols=n, figsize=figsize)\n",
+ "for i, title in zip(range(n), [\"X\", \"Y\", \"Z\"]):\n",
+ " ckey.direction = directions[i]\n",
+ " rgb = ckey.orientation2color(xmap.rotations)\n",
+ " ax[i].imshow(rgb.reshape(xmap.shape + (3,)))\n",
+ " ax[i].set_title(f\"IPF-{title}\")\n",
+ " ax[i].axis(\"off\")\n",
+ "fig.subplots_adjust(wspace=0.02)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "4a700d96-3b7c-4a8f-a170-118664de8fb7",
+ "metadata": {},
+ "source": [
+ "The orientation maps show grains as we would expect from the VBSE image and IQ map obtained before indexing.\n",
+ "\n",
+ "As a final verification, we'll plot geometrical simulations on top of the experimental patterns (see the [geometrical simulations tutorial](geometrical_ebsd_simulations.ipynb) for details)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "3abfc6c2-761d-4fac-856a-a76973f287b2",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "rlv = ReciprocalLatticeVector(\n",
+ " phase=xmap.phases[0], hkl=[[1, 1, 1], [2, 0, 0], [2, 2, 0], [3, 1, 1]]\n",
+ ")\n",
+ "rlv = rlv.symmetrise()\n",
+ "simulator = kp.simulations.KikuchiPatternSimulator(rlv)\n",
+ "sim = simulator.on_detector(det, xmap.rotations.reshape(*xmap.shape))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b166a003-07b0-4567-a82a-374f178e44b1",
+ "metadata": {},
+ "source": [
+ "Add markers to EBSD signal"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2d692d56-8e94-4b8c-bfe0-e2faba5431ce",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "markers = sim.as_markers()\n",
+ "s.add_marker(markers, plot_marker=False, permanent=True)\n",
+ "\n",
+ "# To remove existing markers\n",
+ "# del s.metadata.Markers"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "e81634c2-eaa7-4c75-967a-bd6a02ed1fcc",
+ "metadata": {},
+ "source": [
+ "Navigate patterns with simulations in IPF-X map (see the [visualization tutorial](visualizing_patterns.ipynb) for details)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bc8f8eb5-9309-4f3d-aeb0-1b4acbf83cdd",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "maps_nav_rgb = kp.draw.get_rgb_navigator(rgb_x.reshape(xmap.shape + (3,)))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a93e4267-ec14-40d3-b7f3-492c90d1743a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s.plot(maps_nav_rgb)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "a338d588-f626-4b44-95c6-df44ab4f5d1e",
+ "metadata": {},
+ "source": [
+ "## Orientation refinement\n",
+ "\n",
+ "We can refine the orientation results using dynamical simulations. First we need to create seperate crystal maps, one for each phase, by passing the id of the phase to [xmap_from_hough_indexing_data()](../reference/generated/kikuchipy.indexing.xmap_from_hough_indexing_data.rst)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "1af501c8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "xmap_austenite = kp.indexing.xmap_from_hough_indexing_data(\n",
+ " data=data,\n",
+ " phase_list=phase_list,\n",
+ " data_index=0, # Phase ID for austenite in phase_list\n",
+ " navigation_shape=nav_shape,\n",
+ " step_sizes=(1.0, 1.0),\n",
+ " scan_unit=\"um\",\n",
+ ")\n",
+ "xmap_ferrite = kp.indexing.xmap_from_hough_indexing_data(\n",
+ " data=data,\n",
+ " phase_list=phase_list,\n",
+ " data_index=1, # Phase ID for ferrite in phase_list\n",
+ " navigation_shape=nav_shape,\n",
+ " step_sizes=(1.0, 1.0),\n",
+ " scan_unit=\"um\",\n",
+ ")\n",
+ "print(xmap_austenite, \"\\n\")\n",
+ "print(xmap_ferrite)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "82be0679",
+ "metadata": {},
+ "source": [
+ "Looking at the phases present in the crystal maps, we can see that some orientations are `not_indexed`. We have to mask out these orientations as they cannot be refined. For example, we can create the masks like this"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "16302867",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "nav_mask_austenite = ~(xmap_austenite.phase_id == xmap.phases.id_from_name(\"austenite\"))\n",
+ "nav_mask_austenite = nav_mask_austenite.reshape(xmap.shape)\n",
+ "\n",
+ "nav_mask_ferrite = ~(xmap_ferrite.phase_id == xmap.phases.id_from_name(\"ferrite\"))\n",
+ "nav_mask_ferrite = nav_mask_ferrite.reshape(xmap.shape)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "a774405b",
+ "metadata": {},
+ "source": [
+ "We refine each crystal map using [EBSD.refine_orientation()](../reference/generated/kikuchipy.signals.EBSD.refine_orientation.rst) before merging the results."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8f02c856",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(\"Refining orientations for austenite\")\n",
+ "refined_xmap_austenite = s.refine_orientation(\n",
+ " xmap=xmap_austenite,\n",
+ " detector=det,\n",
+ " master_pattern=mp_austenite,\n",
+ " energy=20, # kV\n",
+ " navigation_mask=nav_mask_austenite,\n",
+ " trust_region=[1, 1, 1],\n",
+ " # The following are default values\n",
+ " method=\"minimize\",\n",
+ " method_kwargs=dict(method=\"Nelder-Mead\", tol=1e-4),\n",
+ " compute=True,\n",
+ ")\n",
+ "\n",
+ "print(\"Refining orientations for ferrite\")\n",
+ "refined_xmap_ferrite = s.refine_orientation(\n",
+ " xmap=xmap_ferrite,\n",
+ " detector=det,\n",
+ " master_pattern=mp_ferrite,\n",
+ " energy=20, # kV\n",
+ " navigation_mask=nav_mask_ferrite,\n",
+ " trust_region=[1, 1, 1],\n",
+ " # The following are default values\n",
+ " method=\"minimize\",\n",
+ " method_kwargs=dict(method=\"Nelder-Mead\", tol=1e-4),\n",
+ " compute=True,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "refined_xmap = kp.indexing.merge_crystal_maps([refined_xmap_austenite, refined_xmap_ferrite])"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "dabc1ce1",
+ "metadata": {},
+ "source": [
+ "We can compare the unrefined and refined phase and IPF maps."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "0f5dbeb2",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "maps = [\n",
+ " xmap,\n",
+ " refined_xmap,\n",
+ "]\n",
+ "fig, ax = plt.subplots(\n",
+ " nrows=2, ncols=2, figsize=(8, 8), subplot_kw=dict(projection=\"plot_map\")\n",
+ ")\n",
+ "for row in range(2):\n",
+ " for col, map in zip(range(2), maps):\n",
+ " cell = ax[row, col]\n",
+ " cell.set_title(\"Unrefined\" if col == 0 else \"Refined\")\n",
+ " cell.axis(\"off\")\n",
+ " if row == 1:\n",
+ " ckey.direction = Vector3d((1, 0, 0))\n",
+ " rgb = ckey.orientation2color(map.rotations)\n",
+ " cell.imshow(rgb.reshape(map.shape + (3,)))\n",
+ " else:\n",
+ " cell.plot_map(map)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "58806a48",
+ "metadata": {},
+ "source": [
+ "Despite the low resolution patterns, orientation refinement has cleaned up some of the miss-indexed phases and orientations, and gives an overall \"cleaner\" crystal map."
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.10"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/kikuchipy/data/__init__.py b/kikuchipy/data/__init__.py
index 7c81b528..0fed78bf 100644
--- a/kikuchipy/data/__init__.py
+++ b/kikuchipy/data/__init__.py
@@ -43,6 +43,7 @@
"silicon_ebsd_moving_screen_in",
"silicon_ebsd_moving_screen_out10mm",
"silicon_ebsd_moving_screen_out5mm",
+ "sdss_ebsd",
]
@@ -63,6 +64,7 @@ def __getattr__(name):
"silicon_ebsd_moving_screen_in": "_data",
"silicon_ebsd_moving_screen_out10mm": "_data",
"silicon_ebsd_moving_screen_out5mm": "_data",
+ "sdss_ebsd": "_data",
}
if name in __all__:
import importlib
diff --git a/kikuchipy/data/_data.py b/kikuchipy/data/_data.py
index 77eb8a22..35292b68 100644
--- a/kikuchipy/data/_data.py
+++ b/kikuchipy/data/_data.py
@@ -120,6 +120,49 @@ def nickel_ebsd_large(
file_path = NiEBSDLarge.fetch_file_path(allow_download, show_progressbar)
return load(file_path, **kwargs)
+def sdss_ebsd(
+ allow_download: bool = False, show_progressbar: Optional[bool] = None, **kwargs
+) -> EBSD:
+ """3600 EBSD patterns in a (60, 60) navigation shape of (48, 48)
+ pixels from super duplex stainless steel, acquired on a NORDIF NICE detector.
+
+ Parameters
+ ----------
+ allow_download
+ Whether to allow downloading the dataset from the internet to
+ the local cache with the pooch Python package. Default is
+ ``False``.
+ show_progressbar
+ Whether to show a progressbar when downloading. If not given,
+ the value of
+ :obj:`hyperspy.api.preferences.General.show_progressbar` is
+ used.
+ **kwargs
+ Keyword arguments passed to :func:`~kikuchipy.load`.
+
+ Returns
+ -------
+ ebsd_signal
+ EBSD signal.
+
+ Notes
+ -----
+ The dataset is hosted in the GitHub repository
+ https://github.com/pyxem/kikuchipy-data.
+
+ The dataset carries a CC BY 4.0 license.
+
+ Examples
+ --------
+ >>> import kikuchipy as kp
+ >>> s = kp.data.sdss_ebsd(allow_download=True)
+ >>> s
+
+ >>> s.plot()
+ """
+ SdssEBSD = Dataset("sdss_ebsd/patterns.h5")
+ file_path = SdssEBSD.fetch_file_path(allow_download, show_progressbar)
+ return load(file_path, **kwargs)
def ni_gain(
number: int = 1,
diff --git a/kikuchipy/data/_registry.py b/kikuchipy/data/_registry.py
index 68c68676..9f995b46 100644
--- a/kikuchipy/data/_registry.py
+++ b/kikuchipy/data/_registry.py
@@ -29,6 +29,7 @@
"silicon_ebsd_moving_screen/si_in.h5": "md5:d8561736f6174e6520a45c3be19eb23a",
"silicon_ebsd_moving_screen/si_out5mm.h5": "md5:77dd01cc2cae6c1c5af6708260c94cab",
"silicon_ebsd_moving_screen/si_out10mm.h5": "md5:0b4ece1533f380a42b9b81cfd0dd202c",
+ "sdss_ebsd/patterns.h5": "md5:1051caae473ab061f28bad6399d8d0a3",
# From Zenodo
"ebsd_si_wafer.zip": "md5:444ec4188ba8c8bda5948c2bf4f9a672",
"si_wafer/Pattern.dat": "md5:58952a93c3ecacff22955f1ad7c61246",
@@ -76,6 +77,7 @@
_registry_urls = {
# From GitHub
"nickel_ebsd_large/patterns.h5": KP_DATA_REPO_URL + "bcab8f7a4ffdb86a97f14e2327a4813d3156a85e/nickel_ebsd_large/patterns_v2.h5",
+ "sdss_ebsd/patterns.h5": KP_DATA_REPO_URL + "bcab8f7a4ffdb86a97f14e2327a4813d3156a85e/sdss_ebsd/patterns.h5",
"silicon_ebsd_moving_screen/si_in.h5": KP_DATA_REPO_URL + "bcab8f7a4ffdb86a97f14e2327a4813d3156a85e/silicon_ebsd_moving_screen/si_in.h5",
"silicon_ebsd_moving_screen/si_out5mm.h5": KP_DATA_REPO_URL + "bcab8f7a4ffdb86a97f14e2327a4813d3156a85e/silicon_ebsd_moving_screen/si_out5mm.h5",
"silicon_ebsd_moving_screen/si_out10mm.h5": KP_DATA_REPO_URL + "bcab8f7a4ffdb86a97f14e2327a4813d3156a85e/silicon_ebsd_moving_screen/si_out10mm.h5",
diff --git a/kikuchipy/data/tests/test_data.py b/kikuchipy/data/tests/test_data.py
index 6419e750..43aa4d69 100644
--- a/kikuchipy/data/tests/test_data.py
+++ b/kikuchipy/data/tests/test_data.py
@@ -117,6 +117,14 @@ def test_load_ni_ebsd_large_allow_download(self):
assert s.data.shape == (55, 75, 60, 60)
assert np.issubdtype(s.data.dtype, np.uint8)
+ def test_load_sdss_ebsd_allow_download(self):
+ """Download from external."""
+ s = kp.data.sdss_ebsd(lazy=True, allow_download=True)
+
+ assert isinstance(s, kp.signals.LazyEBSD)
+ assert s.data.shape == (60, 60, 48, 48)
+ assert np.issubdtype(s.data.dtype, np.uint8)
+
# TODO: Remove test after 0.8 is released
def test_load_si_ebsd_moving_screen_in(self):
"""Download external Si pattern."""
@@ -298,6 +306,7 @@ def test_dataset_availability(self):
"""
datasets = [
"nickel_ebsd_large/patterns.h5",
+ "sdss_ebsd_large/patterns.h5",
"silicon_ebsd_moving_screen/si_in.h5",
"silicon_ebsd_moving_screen/si_out5mm.h5",
"silicon_ebsd_moving_screen/si_out10mm.h5",
From bd5878c4d59b0e8c9f7dbb5d1cf90faded8590c4 Mon Sep 17 00:00:00 2001
From: Erlendos12 <99336047+Erlendos12@users.noreply.github.com>
Date: Wed, 29 Mar 2023 19:34:05 +0200
Subject: [PATCH 2/2] Format with black
---
.../hough_indexing_multiple_phases.ipynb | 66 ++++++++++---------
1 file changed, 34 insertions(+), 32 deletions(-)
diff --git a/doc/tutorials/hough_indexing_multiple_phases.ipynb b/doc/tutorials/hough_indexing_multiple_phases.ipynb
index a1468d0d..02549c6c 100644
--- a/doc/tutorials/hough_indexing_multiple_phases.ipynb
+++ b/doc/tutorials/hough_indexing_multiple_phases.ipynb
@@ -77,7 +77,7 @@
"outputs": [],
"source": [
"s = kp.data.sdss_ebsd(allow_download=True)\n",
- "s"
+ "s\n"
]
},
{
@@ -100,7 +100,7 @@
"outputs": [],
"source": [
"vbse_imager = kp.imaging.VirtualBSEImager(s)\n",
- "print(vbse_imager.grid_shape)"
+ "print(vbse_imager.grid_shape)\n"
]
},
{
@@ -119,7 +119,7 @@
"outputs": [],
"source": [
"maps_vbse_rgb = vbse_imager.get_rgb_image(r=(2, 1), g=(2, 2), b=(2, 3))\n",
- "maps_vbse_rgb"
+ "maps_vbse_rgb\n"
]
},
{
@@ -137,7 +137,7 @@
"metadata": {},
"outputs": [],
"source": [
- "maps_vbse_rgb.plot()"
+ "maps_vbse_rgb.plot()\n"
]
},
{
@@ -157,7 +157,7 @@
"outputs": [],
"source": [
"s.remove_static_background()\n",
- "s.remove_dynamic_background()"
+ "s.remove_dynamic_background()\n"
]
},
{
@@ -175,7 +175,7 @@
"metadata": {},
"outputs": [],
"source": [
- "maps_iq = s.get_image_quality()"
+ "maps_iq = s.get_image_quality()\n"
]
},
{
@@ -199,7 +199,7 @@
" colorbar=True,\n",
" colorbar_label=\"Image quality $Q$\",\n",
" remove_padding=True,\n",
- ")"
+ ")\n"
]
},
{
@@ -234,7 +234,7 @@
"sig_shape = s.axes_manager.signal_shape[::-1] # (Rows, columns)\n",
"det = kp.detectors.EBSDDetector(sig_shape, sample_tilt=70)\n",
"\n",
- "det"
+ "det\n"
]
},
{
@@ -254,7 +254,7 @@
"source": [
"grid_shape = (4, 4)\n",
"s_grid, idx = s.extract_grid(grid_shape, return_indices=True)\n",
- "s_grid"
+ "s_grid\n"
]
},
{
@@ -278,7 +278,7 @@
" rc=idx.reshape(2, -1).T, # Shape (n patterns, 2)\n",
" roi_shape=nav_shape, # Or maps_iq.shape\n",
" roi_image=maps_iq,\n",
- ")"
+ ")\n"
]
},
{
@@ -335,7 +335,7 @@
"print(indexer.sampleTilt)\n",
"print(indexer.camElev)\n",
"print(indexer.PC)\n",
- "print(indexer.phaselist)"
+ "print(indexer.phaselist)\n"
]
},
{
@@ -362,7 +362,7 @@
"\n",
"# Print mean and standard deviation\n",
"print(det.pc_flattened.mean(axis=0))\n",
- "print(det.pc_flattened.std(0))"
+ "print(det.pc_flattened.std(0))\n"
]
},
{
@@ -380,7 +380,7 @@
"metadata": {},
"outputs": [],
"source": [
- "det.plot_pc(\"scatter\", s=50, annotate=True)"
+ "det.plot_pc(\"scatter\", s=50, annotate=True)\n"
]
},
{
@@ -401,7 +401,7 @@
"metadata": {},
"outputs": [],
"source": [
- "det.pc = det.pc_average"
+ "det.pc = det.pc_average\n"
]
},
{
@@ -420,7 +420,7 @@
"metadata": {},
"outputs": [],
"source": [
- "det.plot(pattern=s_grid.inav[0, 0].data)"
+ "det.plot(pattern=s_grid.inav[0, 0].data)\n"
]
},
{
@@ -443,7 +443,7 @@
"outputs": [],
"source": [
"indexer = det.get_indexer(phase_list)\n",
- "indexer.PC"
+ "indexer.PC\n"
]
},
{
@@ -466,7 +466,7 @@
"source": [
"xmap, data = s.hough_indexing(\n",
" phase_list=phase_list, indexer=indexer, verbose=2, return_index_data=True\n",
- ")"
+ ")\n"
]
},
{
@@ -476,7 +476,7 @@
"metadata": {},
"outputs": [],
"source": [
- "xmap"
+ "xmap\n"
]
},
{
@@ -510,7 +510,7 @@
" im = a.imshow(xmap.get_map_data(to_plot))\n",
" fig.colorbar(im, ax=a, label=to_plot)\n",
" a.axis(\"off\")\n",
- "fig.subplots_adjust(wspace=0, hspace=0.05)"
+ "fig.subplots_adjust(wspace=0, hspace=0.05)\n"
]
},
{
@@ -534,7 +534,7 @@
"metadata": {},
"outputs": [],
"source": [
- "xmap.plot(remove_padding=True)"
+ "xmap.plot(remove_padding=True)\n"
]
},
{
@@ -556,7 +556,7 @@
"sym = xmap.phases[0].point_group\n",
"\n",
"ckey = plot.IPFColorKeyTSL(sym, v_ipf)\n",
- "ckey"
+ "ckey\n"
]
},
{
@@ -588,7 +588,7 @@
"# Place color key in bottom right corner, coordinates are [left, bottom, width, height]\n",
"ax_ckey = fig.add_axes([0.63, 0.08, 0.2, 0.2], projection=\"ipf\", symmetry=sym)\n",
"ax_ckey.plot_ipf_color_key(show_title=False)\n",
- "ax_ckey.patch.set_facecolor(\"None\")"
+ "ax_ckey.patch.set_facecolor(\"None\")\n"
]
},
{
@@ -619,7 +619,7 @@
" ax[i].imshow(rgb.reshape(xmap.shape + (3,)))\n",
" ax[i].set_title(f\"IPF-{title}\")\n",
" ax[i].axis(\"off\")\n",
- "fig.subplots_adjust(wspace=0.02)"
+ "fig.subplots_adjust(wspace=0.02)\n"
]
},
{
@@ -645,7 +645,7 @@
")\n",
"rlv = rlv.symmetrise()\n",
"simulator = kp.simulations.KikuchiPatternSimulator(rlv)\n",
- "sim = simulator.on_detector(det, xmap.rotations.reshape(*xmap.shape))"
+ "sim = simulator.on_detector(det, xmap.rotations.reshape(*xmap.shape))\n"
]
},
{
@@ -667,7 +667,7 @@
"s.add_marker(markers, plot_marker=False, permanent=True)\n",
"\n",
"# To remove existing markers\n",
- "# del s.metadata.Markers"
+ "# del s.metadata.Markers\n"
]
},
{
@@ -685,7 +685,7 @@
"metadata": {},
"outputs": [],
"source": [
- "maps_nav_rgb = kp.draw.get_rgb_navigator(rgb_x.reshape(xmap.shape + (3,)))"
+ "maps_nav_rgb = kp.draw.get_rgb_navigator(rgb_x.reshape(xmap.shape + (3,)))\n"
]
},
{
@@ -695,7 +695,7 @@
"metadata": {},
"outputs": [],
"source": [
- "s.plot(maps_nav_rgb)"
+ "s.plot(maps_nav_rgb)\n"
]
},
{
@@ -733,7 +733,7 @@
" scan_unit=\"um\",\n",
")\n",
"print(xmap_austenite, \"\\n\")\n",
- "print(xmap_ferrite)"
+ "print(xmap_ferrite)\n"
]
},
{
@@ -756,7 +756,7 @@
"nav_mask_austenite = nav_mask_austenite.reshape(xmap.shape)\n",
"\n",
"nav_mask_ferrite = ~(xmap_ferrite.phase_id == xmap.phases.id_from_name(\"ferrite\"))\n",
- "nav_mask_ferrite = nav_mask_ferrite.reshape(xmap.shape)"
+ "nav_mask_ferrite = nav_mask_ferrite.reshape(xmap.shape)\n"
]
},
{
@@ -801,7 +801,7 @@
" method=\"minimize\",\n",
" method_kwargs=dict(method=\"Nelder-Mead\", tol=1e-4),\n",
" compute=True,\n",
- ")"
+ ")\n"
]
},
{
@@ -810,7 +810,9 @@
"metadata": {},
"outputs": [],
"source": [
- "refined_xmap = kp.indexing.merge_crystal_maps([refined_xmap_austenite, refined_xmap_ferrite])"
+ "refined_xmap = kp.indexing.merge_crystal_maps(\n",
+ " [refined_xmap_austenite, refined_xmap_ferrite]\n",
+ ")"
]
},
{
@@ -846,7 +848,7 @@
" rgb = ckey.orientation2color(map.rotations)\n",
" cell.imshow(rgb.reshape(map.shape + (3,)))\n",
" else:\n",
- " cell.plot_map(map)"
+ " cell.plot_map(map)\n"
]
},
{