Ejemplo n.º 1
0
    def test_offset_back_to_rake(self):
        for strike, dip, rake in self.data:
            # Displace the line perpendicular to the plane...
            line = smath.sph2cart(*smath.rake(strike, dip, rake))
            norm = smath.sph2cart(*smath.pole(strike, dip))
            line = np.array(line) + 0.5 * np.array(norm)

            # Project the "displaced" line back onto the plane...
            lon, lat = smath.cart2sph(*line)
            plunge, bearing = smath.geographic2plunge_bearing(lon, lat)
            newrake = smath.project_onto_plane(strike, dip, plunge, bearing)
            assert np.allclose(rake, newrake)
Ejemplo n.º 2
0
    def test_offset_back_to_rake(self):
        for strike, dip, rake in self.data:
            # Displace the line perpendicular to the plane...
            line = smath.sph2cart(*smath.rake(strike, dip, rake))
            norm = smath.sph2cart(*smath.pole(strike, dip))
            line = np.array(line) + 0.5 * np.array(norm)

            # Project the "displaced" line back onto the plane...
            lon, lat = smath.cart2sph(*line)
            plunge, bearing = smath.geographic2plunge_bearing(lon, lat)
            newrake = smath.project_onto_plane(strike, dip, plunge, bearing)
            assert np.allclose(rake, newrake)
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
 def test_roundtrip(self):
     for strike in range(0, 370, 10):
         for dip in range(0, 100, 10):
             lon, lat = smath.pole(strike, dip)
             lon2, lat2 = smath.antipode(*smath.antipode(lon, lat))
             compare_lonlat(lon, lat, lon2, lat2)
Ejemplo n.º 5
0
 def test_geographic2pole(self):
     for (strike, dip) in self.strike_dip:
         lon, lat = smath.pole(strike, dip)
         assert np.allclose(smath.geographic2pole(lon, lat),
                            [[strike], [dip]])
Ejemplo n.º 6
0
 def test_roundtrip(self):
     for strike in range(0, 370, 10):
         for dip in range(0, 100, 10):
             lon, lat = smath.pole(strike, dip)
             lon2, lat2 = smath.antipode(*smath.antipode(lon, lat))
             compare_lonlat(lon, lat, lon2, lat2)
Ejemplo n.º 7
0
 def test_geographic2pole(self):
     for (strike, dip) in self.strike_dip:
         lon, lat = smath.pole(strike, dip)
         assert np.allclose(smath.geographic2pole(lon, lat),
                            [[strike], [dip]])
Ejemplo n.º 8
0
def stereoplot(
    Dip,
    DipDirection,
    FrictionAngle,
    figsize,
):
    """ 
    
    Plot histograms with best fit probability density functions
    
    :param list Dip: list containing Dip angles
    
    :param list DipDirection: list containing Dip Directions
    
    :param tuple(float,float) figsize: figure size width,height
    
    """
    # Figure settings
    plt.rcParams.update({'font.size': 12})
    matplotlib.style.use('seaborn-whitegrid')
    fig = plt.figure(figsize=figsize, dpi=100, facecolor='w', edgecolor='k')
    ax = fig.add_subplot(111, projection='stereonet')

    # Convert dip to strike
    strikes = [dipdir2strike(x) for x in DipDirection]

    colours = ['r', 'g', 'b']
    i = 0
    # Set what the pole markers look like
    for x, y in zip(strikes, Dip):
        ax.pole(x,
                y,
                color=colours[i],
                marker='D',
                markersize=10,
                alpha=1,
                zorder=5)
        ax.plane(x, y, color=colours[i], linewidth=2)
        ax.rake(x,
                y,
                90,
                color=colours[i],
                marker='o',
                markersize=10,
                alpha=1,
                zorder=5)
        i = i + 1

    # Plane intersections
    plunge, bearing = plane_intersection([strikes[0], strikes[0], strikes[1]],
                                         [Dip[0], Dip[0], Dip[1]],
                                         [strikes[1], strikes[2], strikes[2]],
                                         [Dip[1], Dip[2], Dip[2]])
    plunge = [x for x in plunge]
    bearing = [x for x in bearing]
    ax.line(plunge, bearing, color='k', marker='o', markersize='10')

    # Convert plane intersections as poles (strike/dip)
    int_strike, int_dip = plunge_bearing2pole(plunge, bearing)
    int_strike = [x for x in int_strike]
    int_dip = [x - 0.001 for x in int_dip]
    joint_strikes = [x + 180 for x in strikes]
    joint_dips = [90 - x for x in Dip]
    point_strikes = joint_strikes + int_strike
    point_dips = joint_dips + int_dip
    real_dips = Dip + plunge

    # Wedge Shaded area
    intersects = [[0, 1], [0, 2], [1, 2]]
    j_inside_strikes = []
    j_inside_dips = []
    for joint, intersect in enumerate(intersects):
        j_plane = plane(strikes[joint], Dip[joint])
        j_plane = np.vstack((j_plane[0].T, j_plane[1].T))

        j_plane_poles = geographic2pole(j_plane[0], j_plane[1])

        int1 = int_strike[intersect[0]]
        int2 = int_strike[intersect[1]]
        int_diff = int1 - int2

        if int_diff >= -180 and int_diff < 0 or int_diff > 180:
            ints_ordered = [int1, int2]
        elif int_diff <= 180 and int_diff > 0 or int_diff < -180:
            ints_ordered = [int2, int1]

        j_inside_strike = []
        j_inside_dip = []

        for i, x in enumerate(j_plane_poles[0]):
            if ang_between(x, ints_ordered[0], ints_ordered[1]):
                j_inside_strike.append(j_plane_poles[0][i])
                j_inside_dip.append(j_plane_poles[1][i])

        j_inside_strikes.append(j_inside_strike)
        j_inside_dips.append(j_inside_dip)

        #ax.pole(j_inside_strike, j_inside_dip, color=colours[joint])

    j_inside_strikes = j_inside_strikes[0] + j_inside_strikes[
        1] + j_inside_strikes[2]
    j_inside_dips = j_inside_dips[0] + j_inside_dips[1] + j_inside_dips[2]

    # Friction circle
    ax.cone(90,
            0,
            90 - FrictionAngle,
            alpha=0.1,
            color='r',
            zorder=1,
            bidirectional=False)

    # Stereonet overlay settings
    ax.set_azimuth_ticks([0, 90, 180, 270], labels=['N', 'E', 'S', 'W'])
    ax.grid(True, kind='polar')
    plt.tight_layout()

    # Shaded Area
    shaded_area = pole(j_inside_strikes, j_inside_dips)
    shaded_area_x = [x for x in shaded_area[0]]
    shaded_area_y = [x for x in shaded_area[1]]
    shaded_area_stack = np.vstack((shaded_area_x, shaded_area_y)).T

    edges = alpha_shape(shaded_area_stack, alpha=1, only_outer=True)
    edges_joined = stitch_boundaries(edges)
    edges_joined_x = []
    edges_joined_y = []

    for i, j in edges_joined[0]:
        edges_joined_x.append(shaded_area_x[i])
        edges_joined_y.append(shaded_area_y[i])
    polygon = np.vstack((edges_joined_x, edges_joined_y)).T

    ax.fill(edges_joined_x, edges_joined_y, 'k', alpha=0.3)

    Joints = ['1', '2', '3', '1/2', '1/3', '2/3']

    Stability = "Stable"
    Mode = 'N/A'

    if point_inside_polygon(0, 0, polygon):
        Stability = 'Unstable'
        Mode = 'Falling'
    else:
        poles_ext = pole(point_strikes, [d + 1 for d in point_dips])
        poles_ext = np.vstack((poles_ext[0], poles_ext[1])).T
        max_slide = 0
        for i in range(0, 6):
            if point_inside_polygon(
                    poles_ext[i][0], poles_ext[i][1], polygon
            ) and real_dips[i] >= FrictionAngle and real_dips[i] > max_slide:
                Stability = 'Unstable'
                max_slide = real_dips[i]
                Mode = "Sliding on Joint {0}".format(Joints[i])

    # Table in top plot
    table_data = [["Friction Angle", "{0}°".format(FrictionAngle)],
                  ["Joints", "Dip / Dip Direction"],
                  [
                      "1", "{0}°/{1:0=3d}°".format(int(round(Dip[0])),
                                                   int(round(DipDirection[0])))
                  ],
                  [
                      "2", "{0}°/{1:0=3d}°".format(int(round(Dip[1])),
                                                   int(round(DipDirection[1])))
                  ],
                  [
                      "3", "{0}°/{1:0=3d}°".format(int(round(Dip[2])),
                                                   int(round(DipDirection[2])))
                  ], ["Intersections", "Trend / Plunge"],
                  [
                      "1/2", "{0}°/{1:0=3d}°".format(int(round(plunge[0])),
                                                     int(round(bearing[0])))
                  ],
                  [
                      "1/3", "{0}°/{1:0=3d}°".format(int(round(plunge[1])),
                                                     int(round(bearing[1])))
                  ],
                  [
                      "2/3", "{0}°/{1:0=3d}°".format(int(round(plunge[2])),
                                                     int(round(bearing[2])))
                  ], ["Stability", Stability], ["Mode", Mode]]

    table = ax.table(cellText=table_data,
                     bbox=[1.1, 0.3, 0.4, 0.35],
                     cellLoc='center',
                     loc='right',
                     colWidths=[0.2, 0.2
                                ])  # , loc='top right')#, colWidths = [0.4]*2)
    for (row, col), cell in table.get_celld().items():
        if (row == 0 or row == 1 or row == 5 or row == 9 or row == 10):
            cell.set_text_props(fontproperties=FontProperties(weight='bold'))
        if (row == 2):
            cell.set_text_props(color='r')
        if (row == 3):
            cell.set_text_props(color='g')
        if (row == 4):
            cell.set_text_props(color='b')

    return fig, ax