# Path: attitude/orientation/reconstructed.py
# class ReconstructedPlane(ErrorShell, BaseOrientation):
#     """
#     This class represents a plane with errors on two axes.
#     This error is presumably the result of some statistical
#     process, and is a single confidence interval or shell
#     derived from this result.
#     """
#     def __init__(self, strike, dip, rake, *angular_errors, **kwargs):
#         _trans_arr = N.array([-1, -1, 1])
#         def vec(latlon):
#             lat, lon = latlon
#             _ = M.sph2cart(lat, lon)
#             val = N.array(_).flatten()
#             val = N.roll(val,-1)
#             return val * _trans_arr
# 
#         normal_error = kwargs.pop('normal_error',1)
# 
#         self.__strike = strike
#         self.__dip = dip
#         self.__angular_errors = angular_errors
#         self.__rake = rake
# 
#         errors = N.radians(angular_errors)/2
#         pole = M.pole(strike, dip)
# 
#         # Uncertain why we have to do this to get a normal vector
#         # but it has something to do with the stereonet coordinate
#         # system relative to the normal
#         self.normal = vec(pole)
#         ll = M.rake(strike, dip, rake)
#         max_angle = vec(ll)
#         min_angle = N.cross(self.normal, max_angle)
# 
#         # These axes have the correct length but need to be
#         # rotated into the correct reference frame.
#         ax = N.vstack((min_angle, max_angle, self.normal))
# 
#         # Apply right-hand rule
#         #ax[0:],ax[1:]
# 
#         #T = N.eye(3)
#         #T[:-1,:-1] = rotate_2D(N.radians(rake))
# 
#         T = transform(ax[0],max_angle)
#         self.axes = ax
#         if self.axes[-1,-1] < 0:
#             self.axes *= -1
# 
#         lengths = normal_error/N.tan(errors[::-1])
#         self.hyperbolic_axes = N.array(list(lengths)+[normal_error])
#         self.covariance_matrix = N.diag(self.hyperbolic_axes)
# 
#     def strike_dip_rake(self):
#         return self.__strike, self.__dip, self.__rake
# 
#     def angular_errors(self):
#         return self.__angular_errors
# 
#     @property
#     def hash(self):
#         return hash_array(self.hyperbolic_axes*self.axes)
# 
# Path: attitude/orientation/pca.py
# def random_pca(scattered=True):
#     if scattered:
#         arr,coeffs = scattered_plane()
#     else:
#         arr, coeffs = random_plane()
#     arr = N.array(arr).transpose()
#     return PCAOrientation(arr)
# 
# Path: attitude/geom/util.py
# def angle(v1,v2, cos=False):
#     """
#     Find the angle between two vectors.
# 
#     :param cos: If True, the cosine of the
#     angle will be returned. False by default.
#     """
#     n = (norm(v1)*norm(v2))
#     _ = dot(v1,v2)/n
#     return _ if cos else N.arccos(_)


import numpy as N
import pytest
from .reconstructed import ReconstructedPlane
from .pca import random_pca
from ..geom.util import angle
from numpy.testing import assert_array_almost_equal


def test_rake_angle():
    """
    Test that we can reconstruct rake angle
    """
    fit = random_pca()
    ang = fit._rake()
    ang2 = angle(fit.axes[0], fit.dip_dr)
    assert N.allclose(ang, ang2)


def test_reconstructed_plane():
    """
    Test the reconstruction of a fitted plane from orientation
    of the plane expressed in spherical coordinates
    """

# Path: attitude/orientation/reconstructed.py
# class ReconstructedPlane(ErrorShell, BaseOrientation):
#     """
#     This class represents a plane with errors on two axes.
#     This error is presumably the result of some statistical
#     process, and is a single confidence interval or shell
#     derived from this result.
#     """
#     def __init__(self, strike, dip, rake, *angular_errors, **kwargs):
#         _trans_arr = N.array([-1, -1, 1])
#         def vec(latlon):
#             lat, lon = latlon
#             _ = M.sph2cart(lat, lon)
#             val = N.array(_).flatten()
#             val = N.roll(val,-1)
#             return val * _trans_arr
# 
#         normal_error = kwargs.pop('normal_error',1)
# 
#         self.__strike = strike
#         self.__dip = dip
#         self.__angular_errors = angular_errors
#         self.__rake = rake
# 
#         errors = N.radians(angular_errors)/2
#         pole = M.pole(strike, dip)
# 
#         # Uncertain why we have to do this to get a normal vector
#         # but it has something to do with the stereonet coordinate
#         # system relative to the normal
#         self.normal = vec(pole)
#         ll = M.rake(strike, dip, rake)
#         max_angle = vec(ll)
#         min_angle = N.cross(self.normal, max_angle)
# 
#         # These axes have the correct length but need to be
#         # rotated into the correct reference frame.
#         ax = N.vstack((min_angle, max_angle, self.normal))
# 
#         # Apply right-hand rule
#         #ax[0:],ax[1:]
# 
#         #T = N.eye(3)
#         #T[:-1,:-1] = rotate_2D(N.radians(rake))
# 
#         T = transform(ax[0],max_angle)
#         self.axes = ax
#         if self.axes[-1,-1] < 0:
#             self.axes *= -1
# 
#         lengths = normal_error/N.tan(errors[::-1])
#         self.hyperbolic_axes = N.array(list(lengths)+[normal_error])
#         self.covariance_matrix = N.diag(self.hyperbolic_axes)
# 
#     def strike_dip_rake(self):
#         return self.__strike, self.__dip, self.__rake
# 
#     def angular_errors(self):
#         return self.__angular_errors
# 
#     @property
#     def hash(self):
#         return hash_array(self.hyperbolic_axes*self.axes)
# 
# Path: attitude/orientation/pca.py
# def random_pca(scattered=True):
#     if scattered:
#         arr,coeffs = scattered_plane()
#     else:
#         arr, coeffs = random_plane()
#     arr = N.array(arr).transpose()
#     return PCAOrientation(arr)
# 
# Path: attitude/geom/util.py
# def angle(v1,v2, cos=False):
#     """
#     Find the angle between two vectors.
# 
#     :param cos: If True, the cosine of the
#     angle will be returned. False by default.
#     """
#     n = (norm(v1)*norm(v2))
#     _ = dot(v1,v2)/n
#     return _ if cos else N.arccos(_)


# Path: attitude/orientation/test_reconstructed.py
import numpy as N
import pytest
from .reconstructed import ReconstructedPlane
from .pca import random_pca
from ..geom.util import angle
from numpy.testing import assert_array_almost_equal



def test_rake_angle():
    """
    Test that we can reconstruct rake angle
    """
    fit = random_pca()
    ang = fit._rake()
    ang2 = angle(fit.axes[0], fit.dip_dr)
    assert N.allclose(ang, ang2)


def test_reconstructed_plane():
    """
    Test the reconstruction of a fitted plane from orientation
    of the plane expressed in spherical coordinates
    """

    fit = random_pca()