Source code for attitude.orientation.reconstructed

import numpy as N
import mplstereonet.stereonet_math as M

from ..geom import dot
from .base import BaseOrientation, hash_array
from ..coordinates.rotations import transform
from ..stereonet import plane_errors, normal_errors

[docs]class ErrorShell(object): """ Object representing a specific error level """ def __init__(self, axes, covariance): self.axes = axes self.covariance_matrix = covariance
[docs] def cartopy_girdle(self, **kw): from cartopy import crs, feature from shapely.geometry import Polygon cm = self.covariance_matrix sheets = {i: N.degrees(plane_errors(self.axes, cm, sheet=i, traditional_layout=False)) for i in ('upper','lower')} geom = Polygon(sheets['upper'], [sheets['lower']]) geometries = [geom] return feature.ShapelyFeature(geometries, crs.PlateCarree())
[docs] def cartopy_normal(self, **kw): from cartopy import crs, feature from shapely.geometry import Polygon cm = self.covariance_matrix upper = N.degrees(normal_errors(self.axes, cm, traditional_layout=False)) geom = Polygon(upper) geometries = [geom] return feature.ShapelyFeature(geometries, crs.PlateCarree())
[docs]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)
[docs] def strike_dip_rake(self): return self.__strike, self.__dip, self.__rake
[docs] def angular_errors(self): return self.__angular_errors
@property def hash(self): return hash_array(self.hyperbolic_axes*self.axes)