%matplotlib inline
import numpy as np
import pyxem as pxm
import hyperspy.api as hs
from pyxem.libraries.calibration_library import CalibrationDataLibrary
from pyxem.generators.calibration_generator import CalibrationGenerator

"""
Explanation: Calibrations
This notebook demonstrates how to calibrate real and reciprocal space coordinates of scanning electron diffraction data. Calibrations include correcting the diffraction pattern for lens distortions and determining the rotation between the scan and diffraction planes based on data acquired from reference standards.
This functionaility has been checked to run in pyxem-0.11.0 (May 2020). Bugs are always possible, do not trust the code blindly, and if you experience any issues please report them here: https://github.com/pyxem/pyxem-demos/issues
Contents

<a href='#ini'> Load Data & Initialize Generator</a>
<a href='#dis'> Determine Lens Distortions</a>
<a href='#cal'> Determine Real & Reciprocal Space Calibrations</a>
<a href='#rot'> Determin Real & Reciprocal Space Rotation</a> 

Import pyxem, required libraries and pyxem modules
End of explanation
"""


au_dpeg = hs.load('./data/03/au_xgrating_20cm.tif')
au_dpeg.plot(vmax=1)

"""
Explanation: Download and the data for this demo from here and put in directory with notebooks:
https://drive.google.com/drive/folders/1guzxUcHYNkB3CMClQ-Dhv9cCc1-N15Fj?usp=sharing
<a id='ini'></a>
1. Load Data & Initialize Generator
Load spatially averaged diffraction pattern from Au X-grating for distortion calibration
End of explanation
"""


au_im = hs.load('./data/03/au_xgrating_100kX.hspy')
au_im.plot()

"""
Explanation: Load a VDF image of Au X-grating for scan pixel calibration
End of explanation
"""


moo3_dpeg = hs.load('./data/03/moo3_20cm.tif')
moo3_dpeg.plot(vmax=1)

"""
Explanation: Load spatially averaged diffraction pattern from MoO3 standard for rotation calibration
End of explanation
"""


moo3_im = hs.load('./data/03/moo3_100kX.tif')
moo3_im.plot()

"""
Explanation: Load a VDF image of MoO3 standard for rotation calibration
End of explanation
"""


#Calibration Standard can only be gold for now
cal = CalibrationGenerator(diffraction_pattern=au_dpeg,
                           grating_image=au_im)

"""
Explanation: Initialise a CalibrationGenerator with the CalibrationDataLibrary
End of explanation
"""


cal.get_elliptical_distortion(mask_radius=10,
                              scale=100, amplitude=1000,
                              asymmetry=0.9,spread=2)

"""
Explanation: <a id='ids'></a>
2. Determine Lens Distortions
Lens distortions are assumed to be dominated by elliptical distortion due to the projector lens system. See, for example: https://www.sciencedirect.com/science/article/pii/S0304399105001087?via%3Dihub
Distortion correction is based on measuring the ellipticity of a ring pattern obtained from an Au X-grating calibration standard in scaninng mode.
Determine distortion correction matrix by ring fitting
End of explanation
"""


residuals = cal.get_distortion_residuals(mask_radius=10, spread=2)
residuals.plot(cmap='RdBu', vmax=0.04)

"""
Explanation: Obtain residuals before and after distortion correction and plot to inspect, the aim is for any differences to be small and circularly symmetric
End of explanation
"""


cal.plot_corrected_diffraction_pattern(vmax=0.1)

"""
Explanation: Plot distortion corrected diffraction pattern with adjustable reference circle for inspection
End of explanation
"""


cal.affine_matrix

"""
Explanation: Check the affine matrix, which may be applied to other data
End of explanation
"""


cal.ring_params

"""
Explanation: Inspect the ring fitting parameters
End of explanation
"""


cal.get_correction_matrix()

"""
Explanation: Calculate correction matrix and confirm that in this case it is equal to the affine matrix
End of explanation
"""


cal.get_diffraction_calibration(mask_length=30,
                                linewidth=5)

"""
Explanation: <a href='#cal'></a>
3. Determining Real & Reciprocal Space Scales
Determine the diffraction pattern calibration in reciprocal Angstroms per pixel
End of explanation
"""


cal.plot_calibrated_data(data_to_plot='au_x_grating_dp',
                         cmap='magma', vmax=0.1)

"""
Explanation: Plot the calibrated diffraction data to check it looks about right
End of explanation
"""


cal.grating_image.plot()
line = hs.roi.Line2DROI(x1=4.83957, y1=44.4148, x2=246.46, y2=119.159, linewidth=5.57199)
line.add_widget(cal.grating_image)

trace = line(cal.grating_image)
trace = trace.as_signal1D(spectral_axis=0)
trace.plot()

"""
Explanation: Plot the cross grating image data to define the line along which to take trace
End of explanation
"""


cal.get_navigation_calibration(line_roi=line, x1=40.,x2=232.,
                               n=3, xspace=500.)

"""
Explanation: Obtain the navigation calibration from the trace
End of explanation
"""


