Skip to content

Commit

Permalink
Merge 57cc359 into 734466f
Browse files Browse the repository at this point in the history
  • Loading branch information
pc494 committed Feb 17, 2018
2 parents 734466f + 57cc359 commit c3fbd9c
Show file tree
Hide file tree
Showing 9 changed files with 273 additions and 292 deletions.
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
language: python
python:
- "3.5"
- "3.6"

sudo: false

before_install:
- "pip install sphinx hyperspy pymatgen Cython transforms3d lxml"
- "pip install sphinx hyperspy pymatgen Cython transforms3d lxml ipywidgets"
- "pip install sphinx_bootstrap_theme"
- "pip install pytest pytest-cov"
- "pip install coveralls"
Expand Down
6 changes: 2 additions & 4 deletions pyxem/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
# along with pyXem. If not, see <http://www.gnu.org/licenses/>.

import numpy as np
from scipy.interpolate import RectBivariateSpline


def correlate(image, pattern_dictionary):
"""The correlation between a diffraction pattern and a simulation.
Expand Down Expand Up @@ -57,6 +55,6 @@ def correlate(image, pattern_dictionary):
pixel_coordinates = pattern_dictionary['pixel_coords']
pattern_normalization = pattern_dictionary['pattern_norm']

image_intensities = image[pixel_coordinates[:, 0], pixel_coordinates[:, 1]]
image_intensities = image[pixel_coordinates[:, 1], pixel_coordinates[:, 0]]

return np.dot(image_intensities,pattern_intensities)/pattern_normalization
return np.dot(image_intensities,pattern_intensities)/pattern_normalization
4 changes: 2 additions & 2 deletions pyxem/utils/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def generate_marker_inputs_from_peaks(peaks):
pad = np.array(list(itertools.zip_longest(*np.concatenate(peaks.data),fillvalue=[np.nan,np.nan])))
pad = pad.reshape((max_peak_len),peaks.data.shape[0],peaks.data.shape[1],2)
xy_cords = np.transpose(pad,[3,0,1,2]) #move the x,y pairs to the front
x = xy_cords[1]
y = xy_cords[0]
x = xy_cords[0]
y = xy_cords[1]

return x,y
41 changes: 41 additions & 0 deletions tests/Orientation_mapping/OM_fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
# Copyright 2018 The pyXem developers
#
# This file is part of pyXem.
#
# pyXem 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.
#
# pyXem 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 pyXem. If not, see <http://www.gnu.org/licenses/>.

import pymatgen as pmg
import numpy as np

half_side_length = 72

def create_GaAs():
Ga = pmg.Element("Ga")
As = pmg.Element("As")
lattice = pmg.Lattice.cubic(5.6535)
return pmg.Structure.from_spacegroup("F23",lattice, [Ga,As], [[0, 0, 0],[0.25,0.25,0.25]])

def create_twin_angles():
" Returns a list contains two sep by rotation of 20"
twin_angles_1 = [0,0,0]
twin_angles_2 = np.add(twin_angles_1,[20,0,0])
return [twin_angles_1,twin_angles_2]

def build_linear_grid_in_euler(alpha_max,beta_max,gamma_max,resolution):
a = np.arange(0,alpha_max,step=resolution)
b = np.arange(0,beta_max,step=resolution)
c = np.arange(0,gamma_max,step=resolution)
from itertools import product
return list(product(a,b,c))
81 changes: 81 additions & 0 deletions tests/Orientation_mapping/test_OM_twins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# -*- coding: utf-8 -*-
# Copyright 2018 The pyXem developers
#
# This file is part of pyXem.
#
# pyXem 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.
#
# pyXem 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 pyXem. If not, see <http://www.gnu.org/licenses/>.

import numpy as np
import pytest
import pyxem as pxm

from pyxem.signals.diffraction_simulation import DiffractionSimulation
from pyxem.generators.indexation_generator import IndexationGenerator
from transforms3d.euler import euler2axangle
from pymatgen.transformations.standard_transformations import RotationTransformation
from OM_fixtures import create_GaAs,create_twin_angles,half_side_length, build_linear_grid_in_euler
from pyxem.utils.sim_utils import peaks_from_best_template
from pyxem.utils.plot import generate_marker_inputs_from_peaks
import hyperspy.api as hs

structure = create_GaAs()
edc = pxm.DiffractionGenerator(300, 5e-2)

dps = []
for orientation in create_twin_angles()*2:
axis, angle = euler2axangle(orientation[0], orientation[1],orientation[2], 'rzxz')
rotation = RotationTransformation(axis, angle,angle_in_radians=True)
rotated_structure = rotation.apply_transformation(structure)
data = edc.calculate_ed_data(rotated_structure,
reciprocal_radius=0.9, #avoiding a reflection issue
with_direct_beam=False)
dps.append(data.as_signal(2*half_side_length,0.025,1).data)

dp = pxm.ElectronDiffraction([dps[0:2],dps[2:]])
dp.set_calibration(1/half_side_length)

diff_gen = pxm.DiffractionLibraryGenerator(edc)
rot_list = build_linear_grid_in_euler(20,5,5,1)
struc_lib = dict()
struc_lib["A"] = (structure,rot_list)
library = diff_gen.get_diffraction_library(struc_lib,
calibration=1/half_side_length,
reciprocal_radius=0.6,
half_shape=(half_side_length,half_side_length),
representation='euler',
with_direct_beam=False)

indexer = IndexationGenerator(dp,library)
match_results = indexer.correlate()

def test_match_results():
assert np.all(match_results.inav[0,0].data[0,1:4] == np.array([0,0,0]))
assert match_results.inav[1,1].data[0,2] == 0 #no rotation in z for the twinning

# Visualization Code

peaks = match_results.map(peaks_from_best_template,
phase=["A"],library=library,inplace=False)

def test_peak_from_best_template():
# Will fail if top line of test_match_results failed
assert peaks.inav[0,0] == library["A"][(0,0,0)]['Sim'].coordinates[:,:2]

mmx,mmy = generate_marker_inputs_from_peaks(peaks)
dp.plot(cmap='viridis')
for mx,my in zip(mmx,mmy):
## THERE IS A GOTCHA HERE DUE TO WEAK REFLECTION
m = hs.markers.point(x=mx,y=my,color='red',marker='x') #see visual test
dp.add_marker(m,plot_marker=True,permanent=True)

92 changes: 92 additions & 0 deletions tests/Orientation_mapping/test_orientation_mapping.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# -*- coding: utf-8 -*-
# Copyright 2018 The pyXem developers
#
# This file is part of pyXem.
#
# pyXem 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.
#
# pyXem 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 pyXem. If not, see <http://www.gnu.org/licenses/>.

import numpy as np
import pytest
import pyxem as pxm
from pyxem.signals.diffraction_simulation import DiffractionSimulation
from pyxem.generators.indexation_generator import IndexationGenerator

# This test suite is aimed at checking the basic functionality of the Omapping process, obviously to have a succesful OM process
# many other components will also need to be correct

dps, dp_sim_list = [],[]

# Create 4 random diffraction simulations
half_side_length = 72
for alpha in [0,1,2,3]:
coords = (np.random.rand(5,2)-0.5)*2 #zero mean, range from -1 to +1
dp_sim = DiffractionSimulation(coordinates=coords,
intensities=np.ones_like(coords[:,0]),
calibration=1/half_side_length)
dp_sim_list.append(dp_sim) #stores the simulations
dps.append(dp_sim.as_signal(2*half_side_length,0.075,1).data) #stores a numpy array of pattern

dp = pxm.ElectronDiffraction([dps[0:2],dps[2:]]) #now from a 2x2 array of patterns


library = dict()
half_shape = (half_side_length,half_side_length)
library["Phase"] = {}

def create_library_entry(library,rotation,DiffractionSimulation):
library["Phase"][rotation] = {}
p = DiffractionSimulation #for concision
library["Phase"][rotation]['Sim'] = p
library["Phase"][rotation]['intensities'] = p.intensities
library["Phase"][rotation]['pixel_coords'] = (p.calibrated_coordinates[:,:2]+half_shape).astype(int)
library["Phase"][rotation]['pattern_norm'] = np.sqrt(np.dot(p.intensities,p.intensities))
return library


for alpha in np.arange(0,10,1):
rotation = (alpha,0,0)
if rotation[0] < 4:
library = create_library_entry(library,rotation,dp_sim_list[rotation[0]])
else:
local_cords = np.random.rand(5,2)
pat = DiffractionSimulation(coordinates=local_cords,intensities=np.ones_like(local_cords[:,0]))
library = create_library_entry(library,rotation,pat)

indexer = IndexationGenerator(dp,library)
match_results = indexer.correlate()

def test_match_results():
# Note the random number generator may give a different assertion failure
# This should always work regardless of the RNG.
assert match_results.inav[0,0].data[0][1] == 0
assert match_results.inav[1,0].data[0][1] == 1
assert match_results.inav[0,1].data[0][1] == 2
assert match_results.inav[1,1].data[0][1] == 3


# Visualization Code

from pyxem.utils.sim_utils import peaks_from_best_template
from pyxem.utils.plot import generate_marker_inputs_from_peaks
import hyperspy.api as hs

peaks = match_results.map(peaks_from_best_template,
phase=["Phase"],library=library,inplace=False)
mmx,mmy = generate_marker_inputs_from_peaks(peaks)
dp.set_calibration(2/144)
dp.plot(cmap='viridis')
for mx,my in zip(mmx,mmy):
m = hs.markers.point(x=mx,y=my,color='red',marker='x')
dp.add_marker(m,plot_marker=True,permanent=True)

Loading

0 comments on commit c3fbd9c

Please sign in to comment.