# 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/stereonet.py
# def quaternion(vector, angle):
# def ellipse(n=1000, adaptive=False):
# def sph2cart(lat,lon):
# def scale_errors(cov_axes, confidence_level=0.95):
# def normal_errors(axes, covariance_matrix, **kwargs):
# def test_ellipse():
# def plane_errors(axes, covariance_matrix, sheet='upper',**kwargs):
# def iterative_normal_errors(axes, covariance_matrix, **kwargs):
#     def sdot(a,b):
#     def step_func(a):
# def iterative_plane_errors(axes,covariance_matrix, **kwargs):
#     def sdot(a,b):
#     def step_func(a):
# def error_ellipse(axes, covariance_matrix, **kwargs):
# def error_coords(axes, covariance_matrix, **kwargs):
#     def _(half, level=1):
#     def __(level):
# 
# Path: attitude/display/stereonet.py
# def plot_patch(ax, vertices, codes, **kwargs):
#     # Make path plot in order with lines
#     # https://matplotlib.org/examples/pylab_examples/zorder_demo.html
#     defaults = dict(zorder=2)
#     defaults.update(kwargs)
# 
#     path = Path(vertices, codes)
#     patch = PathPatch(path, **defaults)
#     ax.add_patch(patch)


import numpy as N
import mplstereonet.stereonet_math as M
from matplotlib.path import Path
from ..orientation.reconstructed import ReconstructedPlane
from ..stereonet import ellipse, dot
from .stereonet import plot_patch
    # Not sure where this factor comes from but it
    # seems to make things work better
    c1 = 2
    axis_lengths = d[:2]
    f = N.linalg.norm(
        ell*axis_lengths,axis=1)

    e0 = -ell.T*d[2]*c1
    e = N.vstack((e0,f))

    _ = dot(e.T,axes).T

    lon,lat = M.cart2sph(-_[0],_[1],_[2])
    # This converts us into an upper-hemisphere
    # representation
    lon -= N.pi/2

    ell = list(zip(lon,lat))

    lonlat = N.array(ell)
    lonlat[:,1] = 90-N.degrees(lonlat[:,1])

    n = len(lonlat)
    codes = [Path.MOVETO]
    codes += [Path.LINETO]*(n-1)

    vertices = list(lonlat)
    plot_patch(ax, vertices, codes, **kwargs)

def uncertain_pole(ax, *args, **kwargs):

# 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/stereonet.py
# def quaternion(vector, angle):
# def ellipse(n=1000, adaptive=False):
# def sph2cart(lat,lon):
# def scale_errors(cov_axes, confidence_level=0.95):
# def normal_errors(axes, covariance_matrix, **kwargs):
# def test_ellipse():
# def plane_errors(axes, covariance_matrix, sheet='upper',**kwargs):
# def iterative_normal_errors(axes, covariance_matrix, **kwargs):
#     def sdot(a,b):
#     def step_func(a):
# def iterative_plane_errors(axes,covariance_matrix, **kwargs):
#     def sdot(a,b):
#     def step_func(a):
# def error_ellipse(axes, covariance_matrix, **kwargs):
# def error_coords(axes, covariance_matrix, **kwargs):
#     def _(half, level=1):
#     def __(level):
# 
# Path: attitude/display/stereonet.py
# def plot_patch(ax, vertices, codes, **kwargs):
#     # Make path plot in order with lines
#     # https://matplotlib.org/examples/pylab_examples/zorder_demo.html
#     defaults = dict(zorder=2)
#     defaults.update(kwargs)
# 
#     path = Path(vertices, codes)
#     patch = PathPatch(path, **defaults)
#     ax.add_patch(patch)


# Path: attitude/display/polar.py
import numpy as N
import mplstereonet.stereonet_math as M
from matplotlib.path import Path
from ..orientation.reconstructed import ReconstructedPlane
from ..stereonet import ellipse, dot
from .stereonet import plot_patch

    # Not sure where this factor comes from but it
    # seems to make things work better
    c1 = 2
    axis_lengths = d[:2]
    f = N.linalg.norm(
        ell*axis_lengths,axis=1)

    e0 = -ell.T*d[2]*c1
    e = N.vstack((e0,f))

    _ = dot(e.T,axes).T

    lon,lat = M.cart2sph(-_[0],_[1],_[2])
    # This converts us into an upper-hemisphere
    # representation
    lon -= N.pi/2

    ell = list(zip(lon,lat))

    lonlat = N.array(ell)
    lonlat[:,1] = 90-N.degrees(lonlat[:,1])

    n = len(lonlat)
    codes = [Path.MOVETO]
    codes += [Path.LINETO]*(n-1)

    vertices = list(lonlat)
    plot_patch(ax, vertices, codes, **kwargs)

def uncertain_pole(ax, *args, **kwargs):

    fit = ReconstructedPlane(*args)