Commit b6478411 authored by Magnus Nord's avatar Magnus Nord
Browse files

Update structural analysis notebook

Use better, rechunked, dataset
parent 6545fe63
Pipeline #120967208 passed with stage
in 24 minutes and 32 seconds
......@@ -17,7 +17,8 @@
"* https://doi.org/10.1103/PhysRevMaterials.3.063605\n",
"\n",
"Dataset and scripts used in processing the data for the paper:\n",
"* Zenodo DOI: https://dx.doi.org/10.5281/zenodo.3476746"
"* Zenodo DOI: https://dx.doi.org/10.5281/zenodo.3476746\n",
"* The actual dataset used here, which is a rechunked version of the dataset used in the paper: https://zenodo.org/record/3687144. The original dataset had suboptimal chunking, which lead to very slow data processing"
]
},
{
......@@ -74,14 +75,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Downloading the data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"One note about this dataset: the chunking used in the file is not optimal, meaning that most of the processing functions will be fairly slow. It is possible to rechunk the data array, but due to the chunking in the HDF5 file itself being the way it is, this won't help much."
"### Downloading the data from Zenodo"
]
},
{
......@@ -95,9 +89,9 @@
"outputs": [],
"source": [
"import os.path\n",
"if not os.path.exists('datasets/m004_LSMO_LFO_STO_medipix.emd'):\n",
"if not os.path.exists('m004_LSMO_LFO_STO_medipix_rechunked.hspy'):\n",
" import urllib.request\n",
" urllib.request.urlretrieve('https://zenodo.org/record/3476746/files/m004_LSMO_LFO_STO_medipix.hdf5', 'datasets/m004_LSMO_LFO_STO_medipix.emd')"
" urllib.request.urlretrieve('https://zenodo.org/record/3687144/files/m004_LSMO_LFO_STO_medipix_rechunked.hspy', 'm004_LSMO_LFO_STO_medipix_rechunked.hspy')"
]
},
{
......@@ -113,14 +107,14 @@
"metadata": {},
"outputs": [],
"source": [
"s = ps.load_ps_signal(\"datasets/m004_LSMO_LFO_STO_medipix.emd\", lazy=True)"
"s = ps.load_ps_signal(\"m004_LSMO_LFO_STO_medipix_rechunked.hspy\", lazy=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This returns a `LazyPixelatedSTEM` class, which is inherits HyperSpy's `Signal2D`. So all functions which work in `Signal2D`, also works here:"
"This returns a `LazyPixelatedSTEM` class, which is inherits HyperSpy's `Signal2D`. So all functions which work in `Signal2D`, also works here."
]
},
{
......@@ -178,6 +172,22 @@
"s_adf.plot()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This signal can be used as a navigator for the original dataset"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"s.plot(navigator=s_adf)"
]
},
{
"cell_type": "markdown",
"metadata": {},
......@@ -216,7 +226,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Radial integration"
"### Radial averaging"
]
},
{
......@@ -264,7 +274,7 @@
"metadata": {},
"outputs": [],
"source": [
"s_radial = s.radial_integration(centre_x=s_com.inav[0].data, centre_y=s_com.inav[1].data)"
"s_radial = s.radial_average(centre_x=s_com.inav[0].data, centre_y=s_com.inav[1].data)"
]
},
{
......@@ -314,6 +324,33 @@
"source": [
"s_radial.T.plot()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Move the navigator to around 50 on the x-axis, to see the intensity distribution of the HOLZ ring.\n",
"\n",
"This can also be extracted by slicing the radial signal."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"s_holz = s_radial.isig[48:52].mean(-1).T"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"s_holz.plot()"
]
}
],
"metadata": {
......
%% Cell type:markdown id: tags:
# Basic structural analysis of 4D-STEM data
This notebook shows how to use the `pixstem` library to analyse 4D scanning transmission electron microscopy (STEM) data. Here, we're looking at a dataset from a perovskite oxide thin film sample.
More documentation for the data processing routines in pixStem is found at https://pixstem.org
Journal article about the dataset:
* **Three-dimensional subnanoscale imaging of unit cell doubling due to octahedral tilting and cation modulation in strained perovskite thin films**
* Magnus Nord, Andrew Ross, Damien McGrouther, Juri Barthel, Magnus Moreau, Ingrid Hallsteinsen, Thomas Tybell, and Ian MacLaren
* Phys. Rev. Materials 3, 063605 – Published 14 June 2019
* https://doi.org/10.1103/PhysRevMaterials.3.063605
Dataset and scripts used in processing the data for the paper:
* Zenodo DOI: https://dx.doi.org/10.5281/zenodo.3476746
* The actual dataset used here, which is a rechunked version of the dataset used in the paper: https://zenodo.org/record/3687144. The original dataset had suboptimal chunking, which lead to very slow data processing
%% Cell type:markdown id: tags:
## Importing libraries
%% Cell type:markdown id: tags:
The first step is setting the plotting toolkit
%% Cell type:code id: tags:nbval-skip
``` python
%matplotlib qt5
```
%% Cell type:markdown id: tags:
Then import the library itself
%% Cell type:code id: tags:
``` python
import pixstem.api as ps
```
%% Cell type:markdown id: tags:
## Working with fast pixelated detector STEM data
%% Cell type:markdown id: tags:
### Downloading the data
%% Cell type:markdown id: tags:
One note about this dataset: the chunking used in the file is not optimal, meaning that most of the processing functions will be fairly slow. It is possible to rechunk the data array, but due to the chunking in the HDF5 file itself being the way it is, this won't help much.
### Downloading the data from Zenodo
%% Cell type:code id: tags:nbval-skip
``` python
import os.path
if not os.path.exists('datasets/m004_LSMO_LFO_STO_medipix.emd'):
if not os.path.exists('m004_LSMO_LFO_STO_medipix_rechunked.hspy'):
import urllib.request
urllib.request.urlretrieve('https://zenodo.org/record/3476746/files/m004_LSMO_LFO_STO_medipix.hdf5', 'datasets/m004_LSMO_LFO_STO_medipix.emd')
urllib.request.urlretrieve('https://zenodo.org/record/3687144/files/m004_LSMO_LFO_STO_medipix_rechunked.hspy', 'm004_LSMO_LFO_STO_medipix_rechunked.hspy')
```
%% Cell type:markdown id: tags:
### Loading data
%% Cell type:code id: tags:
``` python
s = ps.load_ps_signal("datasets/m004_LSMO_LFO_STO_medipix.emd", lazy=True)
s = ps.load_ps_signal("m004_LSMO_LFO_STO_medipix_rechunked.hspy", lazy=True)
```
%% Cell type:markdown id: tags:
This returns a `LazyPixelatedSTEM` class, which is inherits HyperSpy's `Signal2D`. So all functions which work in `Signal2D`, also works here:
This returns a `LazyPixelatedSTEM` class, which is inherits HyperSpy's `Signal2D`. So all functions which work in `Signal2D`, also works here.
%% Cell type:markdown id: tags:
### Plotting
%% Cell type:markdown id: tags:
Plotting the signal directly will be very slow, as the navigation figure has to be generated. A quicker way is using `navigator='slider'`, where the navigation figure is not made.
%% Cell type:code id: tags:
``` python
s.plot(navigator='slider')
```
%% Cell type:markdown id: tags:
### Virtual detectors
%% Cell type:markdown id: tags:
The `virtual_annular_dark_field` is used to construct a images from the `PixelatedSTEM` class, with the input being `(x, y, r_outer, r_inner)`
%% Cell type:code id: tags:
``` python
s_adf = s.virtual_annular_dark_field(128, 128, 70, 128)
```
%% Cell type:code id: tags:
``` python
s_adf.plot()
```
%% Cell type:markdown id: tags:
This signal can be used as a navigator for the original dataset
%% Cell type:code id: tags:
``` python
s.plot(navigator=s_adf)
```
%% Cell type:markdown id: tags:
There is also a virtual bright field method. Passing no parameters to the method gives a sum of the diffraction dimensions:
%% Cell type:code id: tags:
``` python
s_bf = s.virtual_bright_field()
s_bf.plot()
```
%% Cell type:markdown id: tags:
A mask can be applied in the form of (x, y, r):
%% Cell type:code id: tags:
``` python
s_bf = s.virtual_bright_field(128, 128, 30)
s_bf.plot()
```
%% Cell type:markdown id: tags:
### Radial integration
### Radial averaging
%% Cell type:markdown id: tags:
A common task is getting the intensity as a function of scattering angle. This is done using radial integration, which firstly requires finding the center of the electron beam. Here we use the `center_of_mass` function.
%% Cell type:code id: tags:
``` python
s_com = s.center_of_mass(threshold=1.)
```
%% Cell type:markdown id: tags:
This returns a `DPCSignal2D` class, which will be explored more later. What we need to know is that is it basically a HyperSpy `Signal2D` class, where the x-beam shifts are in the first navigation index (`s.inav[0]`), while the y-shifts are in the second navigation index (`s.inav[1]`).
%% Cell type:code id: tags:
``` python
s_com.plot()
```
%% Cell type:markdown id: tags:
To do the radial integration itself, use the `radial_integration` method, which requires the `centre_x` and `centre_y` arguments to be specified.
%% Cell type:code id: tags:
``` python
s_radial = s.radial_integration(centre_x=s_com.inav[0].data, centre_y=s_com.inav[1].data)
s_radial = s.radial_average(centre_x=s_com.inav[0].data, centre_y=s_com.inav[1].data)
```
%% Cell type:markdown id: tags:
This returns a new signal, where the signal dimensions has been reduced from 2 to 1 dimensions. This is especially useful when working with large datasets, where this operation can drastically reduce the data size, making it possible to load the full data into memory.
%% Cell type:code id: tags:
``` python
s_radial
```
%% Cell type:markdown id: tags:
Plotting it shows the electron scattering for each probe position:
%% Cell type:code id: tags:
``` python
s_radial.plot()
```
%% Cell type:markdown id: tags:
To rather visualize the data as function of scattering angle (essentially virtual annular dark field), we can transpose the data using `s_radial.T`. This "flips" the signal and navigation axes:
%% Cell type:code id: tags:
``` python
s_radial.T.plot()
```
%% Cell type:markdown id: tags:
Move the navigator to around 50 on the x-axis, to see the intensity distribution of the HOLZ ring.
This can also be extracted by slicing the radial signal.
%% Cell type:code id: tags:
``` python
s_holz = s_radial.isig[48:52].mean(-1).T
```
%% Cell type:code id: tags:
``` python
s_holz.plot()
```
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment