Source code for attitude.orientation.base

from __future__ import division, print_function
import numpy as N
from ..geom.util import dot
from ..error.ellipse import ellipse
from hashlib import sha1

[docs]def hash_array(a): return sha1(a.data.tobytes()).hexdigest()[:8]
[docs]def rotation(angle): """Rotation about the Z axis (in the XY plane)""" return N.array([[N.cos(angle),-N.sin(angle),0], [N.sin(angle), N.cos(angle),0], [0 , 0 ,1]])
[docs]def ellipse(center,covariance_matrix,level=1, n=1000): """Returns error ellipse in slope-azimuth space""" # singular value decomposition U, s, rotation_matrix = N.linalg.svd(covariance_matrix) # semi-axes (largest first) saxes = N.sqrt(s)*level ## If the _area_ of a 2s ellipse is twice that of a 1s ellipse # If the _axes_ are supposed to be twice as long, then it should be N.sqrt(s)*width u = N.linspace(0, 2*N.pi, n) data = N.column_stack((saxes[0]*N.cos(u), saxes[1]*N.sin(u))) # rotate data return N.dot(data, rotation_matrix)+ center
[docs]class BaseOrientation(object): """ Abstract class to define common methods used by other orientation classes (e.g. reconstructed orientations, pca orientations) """ disabled = False
[docs] def dip_direction(self, uncertainties=False): s,d = self.strike_dip() s+=90 if uncertainties: return (s,d),self.errors() return (s,d)
[docs] def gradient(self, uncertainties=False): return self.azimuth,self.slope
[docs] def errors(self): return tuple(N.degrees(i) for i in self.standard_errors()[:2])
@property def rotated_covariance(self): r = rotation(self.azimuth) return dot(r.T,self.covariance_matrix,r)
[docs] def standard_errors(self): return N.sqrt(N.diagonal(self.rotated_covariance))
def _ellipse(self,level): return ellipse( tuple(self.coefficients[:2]), self.covariance_matrix[:2,:2], level=level)
[docs] def error_ellipse(self, spherical=True, vector=False, level=1): e = self._ellipse(level) if spherical: slope = N.arctan(-e[:,0]) azimuth = self.azimuth + N.arctan2(-e[:,1],-e[:,0]) if vector: azimuth = azimuth + N.pi/2 return (N.pi+azimuth,N.pi/2-slope) return (e[:,1],e[:,0])
@property def principal_axes(self): return self.singular_values*self.axes @property def hash(self): return hash_array(self.principal_axes) @property def center(self): return None @property def centered_array(self): return None
[docs] def to_mapping(self,**values): """ Create a JSON-serializable representation of the plane that is usable with the javascript frontend """ strike, dip, rake = self.strike_dip_rake() min, max = self.angular_errors() try: disabled = self.disabled except AttributeError: disabled = False mapping = dict( uid=self.hash, axes=self.axes.tolist(), hyperbolic_axes=self.hyperbolic_axes.tolist(), max_angular_error=max, min_angular_error=min, strike=strike, dip=dip, rake=rake, disabled=disabled) # Add in user-provided-values, overwriting if # necessary for k,v in values.items(): mapping[k] = v return mapping