Beispiel #1
0
 def test_fit_pole_noisy(self):
     np.random.seed(1)
     for strike in range(0, 370, 10):
         for dip in range(0, 100, 10):
             lon, lat = mplstereonet.pole(strike, dip)
             lon = lon + np.radians(np.random.normal(0, 1, 100))
             lat = lat + np.radians(np.random.normal(0, 1, 100))
             s_noisy, d_noisy = mplstereonet.geographic2pole(lon, lat)
             s, d = mplstereonet.fit_pole(s_noisy, d_noisy)
             ang_dist = self.cos_distance(strike, dip, s, d)
             assert ang_dist < 2 or (180 - ang_dist) < 2
Beispiel #2
0
 def test_fit_pole_noisy(self):
     np.random.seed(1)
     for strike in range(0, 370, 10):
         for dip in range(0, 100, 10):
             lon, lat = mplstereonet.pole(strike, dip)
             lon = lon + np.radians(np.random.normal(0, 1, 100))
             lat = lat + np.radians(np.random.normal(0, 1, 100))
             s_noisy, d_noisy = mplstereonet.geographic2pole(lon, lat)
             s, d = mplstereonet.fit_pole(s_noisy, d_noisy)
             ang_dist = self.cos_distance(strike, dip, s, d)
             assert ang_dist < 2 or (180 - ang_dist) < 2
Beispiel #3
0
 def test_fit_pole(self):
     np.random.seed(1)
     for strike in range(0, 370, 10):
         for dip in range(0, 100, 10):
             s, d = mplstereonet.fit_pole([strike], [dip])
             self.compare_strikedip(strike, dip, s, d)
Beispiel #4
0
    def plotMultiPlanes(self, structures, **kwds):
        #get the dataset
        dataset = kwds.get("data", [self.dataDict])

        #split into structure types
        structure_data = [self.filterByName(regx) for regx in structures]

        #get drawing kwds
        symbols = kwds.get("symbols", ['.'] * len(structure_data))
        cols = kwds.get("colours", ['k'] * len(structure_data))
        contours = kwds.get("contours", ["None"] * len(structure_data))
        cmaps = kwds.get("cmap", ["Blues"] * len(structure_data))
        size = kwds.get("marker_size", [6] * len(structure_data))
        alphas = kwds.get("alphas", [0.75] * len(structure_data))
        values = kwds.get("values", None)
        showCMaps = kwds.get("showCMaps", True)
        mean = kwds.get("mean", [False] * len(structure_data))
        models = kwds.get("models", [None] * len(structure_data))
        outlier_thresh = kwds.get("outlier_thresh",
                                  [None] * len(structure_data))

        #length of all arrays should match
        assert len(structure_data) == len(
            symbols), "Error - symbols array is the incorrect length."
        assert len(structure_data) == len(
            cols), "Error - symbols cols is the incorrect length."
        assert len(structure_data) == len(
            contours), "Error - contours array is the incorrect length."
        assert len(structure_data) == len(
            cmaps), "Error - cmaps array is the incorrect length."
        assert len(structure_data) == len(
            size), "Error - size array is the incorrect length."
        assert len(structure_data) == len(
            alphas), "Error - alphas array is the incorrect length."
        assert len(structure_data) == len(
            mean), "Error - mean array is the incorrect length."
        assert len(structure_data) == len(
            models), "Error - models array is the incorrect length."
        assert len(structure_data) == len(
            outlier_thresh
        ), "Error - outlier_thresh array is the incorrect length."
        if values != None:
            assert len(structure_data) == len(values)

        #init plot
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='stereonet')
        cax = []
        #plot each structure type
        for i, data in enumerate(structure_data):
            #init orientations lists
            strikes = []
            dips = []
            x = []
            y = []
            #loop through data finding plane objects
            for o in data:
                planes = self.filterByKey('PLANE', data=o)
                for p in planes:
                    strikes += [
                        float(p['DipDir']) - 90
                    ]  #n.b. we use this to avoid ambiguity in strike direction (though Compass uses british RHR)
                    dips += [float(p['Dip'])]
                    x += [float(p['Cx'])]
                    y += [float(p['Cy'])]

            strikes = np.array(strikes)
            dips = np.array(dips)
            x = np.array(x)
            y = np.array(y)

            #outlier detection?
            out_mask = np.array([True] *
                                len(strikes))  #default is all outliers
            if models[i] != None and outlier_thresh[
                    i] != None:  #do we have enough info to determine outliers?
                print("\tComputing outliers for threshold %d" %
                      outlier_thresh[i])
                strike_pred = models[i].predict(np.stack(
                    [x, y]).T)  #generate predicted values given the model
                diff = models[i].loss(
                    strikes, strike_pred
                )  #calculate the difference between predicted and observed
                out_mask = diff > outlier_thresh[
                    i]  #define outliers (boolean array)

            in_mask = np.logical_not(out_mask)  #calculate inliers

            #plot poles
            #ax.pole(strikes[out_mask], dips[out_mask], symbols[i], markersize=size[i], color=cols[i], alpha=alphas[i])
            #ax.pole(strikes[in_mask], dips[in_mask], '^', markersize=size[i], color=cols[i], alpha=alphas[i])
            ax.pole(strikes,
                    dips,
                    symbols[i],
                    markersize=size[i],
                    color=cols[i],
                    alpha=alphas[i])

            #plot model?
            if models[i] != None and outlier_thresh[i] != None:
                #calculate centroid of inlier points
                cx = np.mean(x[in_mask])
                cy = np.mean(y[in_mask])

                #calculate expected strike given this point
                strike_pred = models[i].predict(np.stack([[cx], [cy]]).T)[0]

                #plot domain
                ax.plane(
                    strike_pred - outlier_thresh[i] + 90, 90, '--', c='gray'
                )  #n.b. + 90 as we are mapping the domain of poles not the actual planes!
                ax.plane(strike_pred + outlier_thresh[i] + 90,
                         90,
                         '--',
                         c='gray')

                #plot radial line
                ax.plane(strike_pred, 90, '-', c='gray')

            #plot contours?
            if contours[i] == "Line":
                if (values == None):
                    cax.append(
                        ax.density_contour(strikes,
                                           dips,
                                           measurement='poles',
                                           cmap=cmaps[i],
                                           sigma=2))
                else:
                    cax.append(
                        ax.density_contour(strikes,
                                           dips,
                                           levels=values[i],
                                           measurement='poles',
                                           cmap=cmaps[i],
                                           sigma=2))
                if showCMaps:
                    fig.colorbar(cax[-1])
            if contours[i] == "Filled":
                if (values == None):
                    cax.append(
                        ax.density_contourf(strikes,
                                            dips,
                                            measurement='poles',
                                            cmap=cmaps[i],
                                            sigma=2))
                else:
                    cax.append(
                        ax.density_contourf(strikes,
                                            dips,
                                            levels=values[i],
                                            measurement='poles',
                                            cmap=cmaps[i],
                                            sigma=2))
                if showCMaps:
                    fig.colorbar(cax[-1])

            #plot n-observations
            xloc = 0.95
            yloc = -0.04 + 0.032 * i
            ax.text(xloc,
                    yloc,
                    "n=%d" % len(strikes),
                    color=cols[i],
                    transform=ax.transAxes,
                    ha='left',
                    va='center')

            #calculate mean?
            if mean[i] == True:
                if len(strikes) > 0:
                    strike, dip = mplstereonet.fit_pole(strikes,
                                                        dips,
                                                        measurement='poles')
                    ax.plane(strike, dip, cols[i])

        #plot outcrop orientation to give indication of uncertainty/outcrop bias
        if (kwds.get("show_outcrop", False)):
            #list to store normals in
            normals = [[], [], []]  #[x-coords, y-coords, z-coords]

            #loop through trace datasets
            for o in dataset:
                traces = self.filterByKey('TRACE', data=o)
                for t in traces:

                    #does this trace have normals?
                    if t['POINTS']['@normals'] == "True":
                        #extract normal coords
                        normals[0] += list(
                            map(float, t['POINTS']['nx'].split(",")))
                        normals[1] += list(
                            map(float, t['POINTS']['ny'].split(",")))
                        normals[2] += list(
                            map(float, t['POINTS']['nz'].split(",")))

            #plot normals as contours
            plunge, bearing = mplstereonet.vector2plunge_bearing(
                normals[0], normals[1], normals[2])
            cax = ax.density_contour(plunge,
                                     bearing,
                                     measurement='lines',
                                     cmap="winter")
            fig.colorbar(cax)

        #draw grid
        ax.set_xticks([x / (2 * np.pi) for x in range(-180, 180, 45)])
        ax.set_yticks([x / (2 * np.pi) for x in range(-180, 180, 45)])
        ax.grid()

        return fig, ax, cax
Beispiel #5
0
 def test_fit_pole(self):
     np.random.seed(1)
     for strike in range(0, 370, 10):
         for dip in range(0, 100, 10):
             s, d = mplstereonet.fit_pole([strike], [dip])
             self.compare_strikedip(strike, dip, s, d)