diff --git a/tests/common.py b/tests/common.py new file mode 100644 index 000000000..553920551 --- /dev/null +++ b/tests/common.py @@ -0,0 +1,42 @@ +import math + +import numpy as np + +import hexrd.constants as ct + + +def convert_axis_angle_to_rmat(axis, angle): + # Copied from: https://github.com/ovillellas/xrd-transforms/blob/b94f8b2d7839d883829d00a2adc5bec9c80e0116/test_xrd_transforms/common.py#L59 # noqa + # This is based on + # https://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/ + + angle = float(angle) + axis = np.array(axis, dtype=float) + assert axis.shape == (3,) + + if abs(angle) < ct.epsf: + return ct.identity_3x3 + + axis_norm = np.linalg.norm(axis) + if axis_norm < ct.epsf: + raise ValueError("axis is zero") + + axis /= axis_norm + + m = np.empty((3, 3), dtype=float) + + c = math.cos(angle) + s = math.sin(angle) + t = 1.0 - c + + m[0, 0] = c + axis[0]*axis[0]*t + m[0, 1] = axis[0]*axis[1]*t - axis[2]*s + m[0, 2] = axis[0]*axis[2]*t + axis[1]*s + m[1, 0] = axis[0]*axis[1]*t + axis[2]*s + m[1, 1] = c + axis[1]*axis[1]*t + m[1, 2] = axis[1]*axis[2]*t - axis[0]*s + m[2, 0] = axis[0]*axis[2]*t - axis[1]*s + m[2, 1] = axis[1]*axis[2]*t + axis[0]*s + m[2, 2] = c + axis[2]*axis[2]*t + + return m diff --git a/tests/conftest.py b/tests/conftest.py index d83985516..14a274012 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,3 +10,13 @@ def example_repo_path(): repo_path = os.environ['HEXRD_EXAMPLE_REPO_PATH'] return Path(repo_path) + + +@pytest.fixture +def test_dir(): + return Path(__file__).resolve().parent + + +@pytest.fixture +def test_data_dir(test_dir): + return test_dir / 'data' diff --git a/tests/data/gvec_to_xy.json b/tests/data/gvec_to_xy.json new file mode 100644 index 000000000..495af9393 --- /dev/null +++ b/tests/data/gvec_to_xy.json @@ -0,0 +1,78 @@ +[ + { + "input": { + "gvec_c": [ 0.57735027, 0.57735028, 0.57735027], + "rmat_d": [[1.0, 0.0, 0.0], + [0.0, 1.0, 0.0], + [0.0, 0.0, 1.0]], + "rmat_s": [[ 0.77029942, 0.0 , 0.63768237], + [ 0.0 , 1.0 , -0.0 ], + [-0.63768237, 0.0 , 0.77029942]], + "rmat_c": [[ 0.91734473, -0.08166131, 0.38962815], + [ 0.31547749, 0.74606417, -0.58639766], + [-0.24280159, 0.66084771, 0.71016033]], + "tvec_d": [ 0.0 , 1.5 , -5.0 ], + "tvec_s": [ 0.0 , 0.0 , 0.0 ], + "tvec_c": [-0.25, -0.25, -0.25] + }, + "output": [ 0.13349048, -1.61131393] + }, + { + "input": { + "gvec_c": [[ 0.57735027, 0.57735028, 0.57735027], + [ 0.57735027, -0.57735027, 0.57735028], + [ 0.57735028, 0.57735027, -0.57735027]], + "rmat_d": [[1.0, 0.0, 0.0], + [0.0, 1.0, 0.0], + [0.0, 0.0, 1.0]], + "rmat_s": [[ 0.77029942, 0.0 , 0.63768237], + [ 0.0 , 1.0 , -0.0 ], + [-0.63768237, 0.0 , 0.77029942]], + "rmat_c": [[ 0.91734473, -0.08166131, 0.38962815], + [ 0.31547749, 0.74606417, -0.58639766], + [-0.24280159, 0.66084771, 0.71016033]], + "tvec_d": [ 0.0 , 1.5 , -5.0 ], + "tvec_s": [ 0.0 , 0.0 , 0.0 ], + "tvec_c": [-0.25, -0.25, -0.25] + }, + "output": [[ 0.13349048, -1.61131393], + [-11.66778585, 10.41129093], + [ -0.67291173, -5.11162229]] + }, + { + "input": { + "gvec_c": [[ 0.57735027, 0.57735028, 0.57735027], + [ 0.57735027, -0.57735027, 0.57735028], + [ 0.57735027, -0.57735028, -0.57735026], + [ 0.57735028, 0.57735027, -0.57735027]], + "rmat_d": [[1.0, 0.0, 0.0], + [0.0, 1.0, 0.0], + [0.0, 0.0, 1.0]], + "rmat_s": [[[ 0.77029942, 0.0 , 0.63768237], + [ 0.0 , 1.0 , -0.0 ], + [-0.63768237, 0.0 , 0.77029942]], + + [[ 0.97986016, 0.0 , -0.19968493], + [-0.0 , 1.0 , -0.0 ], + [ 0.19968493, 0.0 , 0.97986016]], + + [[ 0.30523954, 0.0 , -0.9522756 ], + [-0.0 , 1.0 , -0.0 ], + [ 0.9522756 , 0.0 , 0.30523954]], + + [[ 0.73506994, 0.0 , -0.67799129], + [-0.0 , 1.0 , -0.0 ], + [ 0.67799129, 0.0 , 0.73506994]]], + "rmat_c": [[ 0.91734473, -0.08166131, 0.38962815], + [ 0.31547749, 0.74606417, -0.58639766], + [-0.24280159, 0.66084771, 0.71016033]], + "tvec_d": [ 0.0 , 1.5 , -5.0 ], + "tvec_s": [ 0.0 , 0.0 , 0.0 ], + "tvec_c": [-0.25, -0.25, -0.25] + }, + "output": [[ 0.13349048, -1.61131393], + [ 0.19186549, -2.03119741], + [ 0.63614123, -1.70709656], + [ 0.12934705, -1.29999638]] + } +] diff --git a/tests/test_inverse_distortion.py b/tests/test_inverse_distortion.py index dd1fb8427..9029d1bfa 100644 --- a/tests/test_inverse_distortion.py +++ b/tests/test_inverse_distortion.py @@ -1,12 +1,8 @@ -import os import json import numpy as np from hexrd.extensions import inverse_distortion - -test_dir = os.path.dirname(os.path.abspath(__file__)) - RHO_MAX = 204.8 params = [ -2.277777438488093e-05, @@ -33,11 +29,8 @@ def test_large_input(): assert xy_out.shape == xy_in.shape -def test_logged_data(): - with open( - os.path.join(test_dir, 'data', 'inverse_distortion_in_out.json'), - encoding='utf-8' - ) as f: +def test_logged_data(test_data_dir): + with open(test_data_dir / 'inverse_distortion_in_out.json') as f: example_data = json.load(f) for example in example_data: diff --git a/tests/test_transforms.py b/tests/test_transforms.py new file mode 100644 index 000000000..79417834a --- /dev/null +++ b/tests/test_transforms.py @@ -0,0 +1,38 @@ +import copy +import json + +import numpy as np + +from hexrd.transforms.xfcapi import gvec_to_xy + +from common import convert_axis_angle_to_rmat + + +def test_gvec_to_xy(test_data_dir): + with open(test_data_dir / 'gvec_to_xy.json') as rf: + test_data = json.load(rf) + + for entry in test_data: + kwargs = entry['input'] + expected = entry['output'] + + kwargs = {k: np.asarray(v) for k, v in kwargs.items()} + result = gvec_to_xy(**kwargs) + assert np.allclose(result, expected) + + # Verify that we get the correct answer with a rotation. + rot = convert_axis_angle_to_rmat(np.r_[0.5, 0.2, 0.6], 1.0) + + rotated_kwargs = copy.deepcopy(kwargs) + rotated_kwargs['beam_vec'] = np.r_[0.0, 0.0, -1.0] + + # The following are not rotated: + # gvec_c are relative to the crystal frame + # rMat_c is in sample frame + # tvec_c is relative to sample frame + to_rotate = ['rmat_d', 'rmat_s', 'tvec_d', 'tvec_s', 'beam_vec'] + for k in to_rotate: + rotated_kwargs[k] = rot @ rotated_kwargs[k] + + result = gvec_to_xy(**rotated_kwargs) + assert np.allclose(result, expected)