示例#1
0
def custom_violin_stats(data, weights):
    # Get weighted median and mean (using weighted module for median)
    median = weighted.quantile_1D(data, weights, 0.5)
    pcent_16 = weighted.quantile_1D(data, weights, 0.16)
    pcent_84 = weighted.quantile_1D(data, weights, 0.84)
    mean, sumw = np.ma.average(data, weights=list(weights), returned=True)

    # Use matplotlib violin_stats, which expects a function that takes in data and coords
    # which we get from closure above
    results = violin_stats(data, vdensity_with_weights(weights))

    # Update result dictionary with our updated info
    results[0][u"mean"] = mean
    results[0][u"median"] = median
    results[0][u"pcent_16"] = pcent_16
    results[0][u"pcent_84"] = pcent_84

    # No need to do this, since it should be populated from violin_stats
    # results[0][u"min"] =  np.min(data)
    # results[0][u"max"] =  np.max(data)

    return results
示例#2
0
def weighted_quantiles(data, labels, weights, return_quantiles=False):
    num_categories = len(labels)
    breaks = linspace(0, 1, num_categories + 1)
    quantiles = [
        weighted.quantile_1D(data, weights, mybreak) for mybreak in breaks[1:]
    ]
    ret = zeros(len(data))
    for i in range(0, len(quantiles) - 1):
        lower = quantiles[i]
        upper = quantiles[i + 1]
        ret[and_(data >= lower, data < upper)] = labels[i]

    if return_quantiles:
        return ret + 1, quantiles
    else:
        return ret + 1
def custom_violin_stats(data, weights):
    """Taken from https://colab.research.google.com/drive/1cSnJGKJEqbllkPbF2z0cnfdwT40sUKKR#scrollTo=RIcLIr5XJRmx"""
    # Get weighted median and mean (using weighted module for median)
    median = weighted.quantile_1D(data, weights, 0.5)
    mean, sumw = np.ma.average(data, weights=list(weights), returned=True)

    # Use matplotlib violin_stats, which expects a function that takes in data and coords
    # which we get from closure above
    results = violin_stats(data, vdensity_with_weights(weights))

    # Update result dictionary with our updated info
    results[0][u"mean"] = mean
    results[0][u"median"] = median

    # No need to do this, since it should be populated from violin_stats
    # results[0][u"min"] =  np.min(data)
    # results[0][u"max"] =  np.max(data)

    return results
示例#4
0
 def test_weighted_median_1D_unsorted(self):
     # Median of the unsorted array
     self.assertEqual(quantile_1D(self.a1Du, self.a1Du_w, 0.5), 30)
     self.assertEqual(quantile_1D(self.a1Du, np.ones_like(self.a1Du), 0.5), 27.5)
示例#5
0
    def analyzeResults(self):
        self.matched = []  # for paired comparisons
        for i, f in enumerate(self.pickles):
            s = f.split(os.sep)[-1]
            if not (fnmatch.filter(itertools.chain.from_iterable(self.matched),
                                   "*" + s)):
                self.matched.append(fnmatch.filter(self.pickles, "*" + s))
            plotname = f.replace('.pkl', '.xplt')
            print("\n... Analyzing results for {:s}".format(plotname))

            results = febio.FebPlt(plotname)
            stress = np.zeros((len(self.data[f]['elements']), 3, 3), float)
            strain = np.copy(stress)
            #material element volumes
            mvolumes = np.zeros(len(self.data[f]['elements']), float)
            #spatial element volumes
            svolumes = np.copy(mvolumes)
            nnodes = len(list(results.NodeData.keys()))
            displacement = np.zeros((nnodes, 3))
            for j, n in enumerate(self.data[f]['nodes']):
                tmp = results.NodeData[j + 1]['displacement'][-1, :]
                displacement[j, :] = [tmp[0], tmp[1], tmp[2]]
            pstress = []
            pstressdir = []
            pstrain = []
            pstraindir = []
            for j, e in enumerate(self.data[f]['elements']):
                tmp = results.ElementData[j + 1]['stress'][-1, :]
                stress[j, :, :] = [[tmp[0], tmp[3], tmp[5]],
                                   [tmp[3], tmp[1], tmp[4]],
                                   [tmp[5], tmp[4], tmp[2]]]
                #material coordinates
                X = np.zeros((4, 3), float)
                #spatial coordinates
                x = np.zeros((4, 3), float)
                for k in range(4):
                    X[k, :] = self.data[f]['nodes'][e[k] - 1]
                    x[k, :] = (X[k, :] +
                               results.NodeData[e[k]]['displacement'][-1, :])
                #set up tangent space
                W = np.zeros((6, 3), float)
                w = np.zeros((6, 3), float)
                for k, c in enumerate([(0, 1), (0, 2), (0, 3), (1, 3), (2, 3),
                                       (1, 2)]):
                    W[k, :] = X[c[1], :] - X[c[0], :]
                    w[k, :] = x[c[1], :] - x[c[0], :]
                dX = np.zeros((6, 6), float)
                ds = np.zeros((6, 1), float)
                for k in range(6):
                    for l in range(3):
                        dX[k, l] = 2 * W[k, l]**2
                    dX[k, 3] = 4 * W[k, 0] * W[k, 1]
                    dX[k, 4] = 4 * W[k, 1] * W[k, 2]
                    dX[k, 5] = 4 * W[k, 0] * W[k, 2]
                    ds[k, 0] = (np.linalg.norm(w[k, :])**2 -
                                np.linalg.norm(W[k, :])**2)
                #solve for strain
                E = np.linalg.solve(dX, ds)
                #get volumes
                mvolumes[j] = old_div(
                    np.abs(np.dot(W[0, :], np.cross(W[1, :], W[2, :]))), 6.0)
                svolumes[j] = old_div(
                    np.abs(np.dot(w[0, :], np.cross(w[1, :], w[2, :]))), 6.0)
                strain[j, :, :] = [[E[0], E[3], E[5]], [E[3], E[1], E[4]],
                                   [E[5], E[4], E[2]]]
                #eigenvalues and eigenvectors of stress and strain tensors
                #eigenvectors are normalized
                eigstrain, eigstraindir = np.linalg.eigh(strain[j, :, :])
                order = np.argsort(eigstrain)
                eigstrain = eigstrain[order]
                eigstraindir /= np.linalg.norm(eigstraindir,
                                               axis=0,
                                               keepdims=True)
                eigstraindir = eigstraindir[:, order]
                pstrain.append(eigstrain)
                pstraindir.append(eigstraindir)
                eigstress, eigstressdir = np.linalg.eigh(stress[j, :, :])
                order = np.argsort(eigstress)
                eigstress = eigstress[order]
                eigstressdir /= np.linalg.norm(eigstressdir,
                                               axis=0,
                                               keepdims=True)
                eigstressdir = eigstressdir[:, order]
                pstress.append(eigstress)
                pstressdir.append(eigstressdir)
            pstress = np.array(pstress)
            pstressdir = np.array(pstressdir)
            pstrain = np.array(pstrain)
            pstraindir = np.array(pstraindir)
            #save reference volumes
            self.volumes.update({f: mvolumes})
            self.results['Effective Strain (von Mises)'].update({
                f:
                np.sqrt(
                    old_div(((pstrain[:, 2] - pstrain[:, 1])**2 +
                             (pstrain[:, 1] - pstrain[:, 0])**2 +
                             (pstrain[:, 2] - pstrain[:, 0])**2), 2.0))
            })
            self.results['Maximum Compressive Strain'].update(
                {f: np.outer(pstrain[:, 0], [1, 1, 1]) * pstraindir[:, :, 0]})
            self.results['Maximum Tensile Strain'].update(
                {f: np.outer(pstrain[:, 2], [1, 1, 1]) * pstraindir[:, :, 2]})
            self.results['Maximum Shear Strain'].update(
                {f: 0.5 * (pstrain[:, 2] - pstrain[:, 0])})
            self.results['Volumetric Strain'].update(
                {f: old_div(svolumes, mvolumes) - 1.0})

            self.results['Effective Stress (von Mises)'].update({
                f:
                np.sqrt(
                    old_div(((pstress[:, 2] - pstress[:, 1])**2 +
                             (pstress[:, 1] - pstress[:, 0])**2 +
                             (pstress[:, 2] - pstress[:, 0])**2), 2.0))
            })
            self.results['Maximum Compressive Stress'].update(
                {f: np.outer(pstress[:, 0], [1, 1, 1]) * pstressdir[:, :, 0]})
            self.results['Maximum Tensile Stress'].update(
                {f: np.outer(pstress[:, 2], [1, 1, 1]) * pstressdir[:, :, 2]})
            self.results['Maximum Shear Stress'].update(
                {f: 0.5 * (pstress[:, 2] - pstress[:, 0])})
            self.results['Pressure'].update(
                {f: old_div(np.sum(pstress, axis=1), 3.0)})

            self.results['Displacement'].update({f: displacement})

        for i, k in enumerate(self.outputs.keys()):
            if self.outputs[k].get():
                for m in self.matched:
                    weights = old_div(self.volumes[m[0]],
                                      np.sum(self.volumes[m[0]]))
                    for j, f in enumerate(m):
                        if len(self.results[k][f].shape) > 1:
                            dat = np.ravel(
                                np.linalg.norm(self.results[k][f], axis=1))
                        else:
                            dat = np.ravel(self.results[k][f])
                        if self.analysis['Generate Histograms'].get():
                            IQR = np.subtract(*np.percentile(dat, [75, 25]))
                            nbins = (int(
                                old_div(
                                    np.ptp(dat),
                                    (2 * IQR * dat.size**(old_div(-1., 3.))))))
                            h = histogram(dat, numbins=nbins, weights=weights)
                            bins = np.linspace(h[1],
                                               h[1] + h[2] * nbins,
                                               nbins,
                                               endpoint=False)
                            self.histograms[k][f] = {
                                'bins': bins,
                                'heights': h[0],
                                'width': h[2]
                            }
                        if self.analysis['Tukey Boxplots'].get():
                            quantiles = np.zeros(3, float)
                            for n, q in enumerate([0.25, 0.5, 0.75]):
                                quantiles[n] = quantile_1D(dat, weights, q)
                            self.boxwhiskers[k][f] = {
                                'quantiles': quantiles,
                                'data': dat
                            }
                    if self.analysis['Calculate Differences'].get():
                        for c in itertools.combinations(m, 2):
                            if len(self.results[k][c[0]].shape) > 1:
                                dat1 = np.ravel(
                                    np.linalg.norm(self.results[k][c[0]],
                                                   axis=1))
                                dat2 = np.ravel(
                                    np.linalg.norm(self.results[k][c[1]],
                                                   axis=1))
                            else:
                                dat1 = np.ravel(self.results[k][c[0]])
                                dat2 = np.ravel(self.results[k][c[1]])
                            difference = dat2 - dat1
                            wrms = np.sqrt(
                                np.average(difference**2, weights=weights))
                            self.differences[k][c[1] + "MINUS" + c[0]] = {
                                'difference': difference,
                                'weighted RMS': wrms
                            }
        self.saveResults()
        print("... ... Analysis Complete")
示例#6
0
 def test_weighted_median_1D_unsorted(self):
     # Median of the unsorted array
     self.assertEqual(quantile_1D(self.a1Du, self.a1Du_w, 0.5), 30)
     self.assertEqual(quantile_1D(self.a1Du, np.ones_like(self.a1Du), 0.5),
                      27.5)
示例#7
0
    def analyzeResults(self):
        self.matched = [] # for paired comparisons
        for i, f in enumerate(self.pickles):
            s = f.split(os.sep)[-1]
            if not(fnmatch.filter(
                    itertools.chain.from_iterable(self.matched), "*" + s)):
                self.matched.append(fnmatch.filter(self.pickles, "*" + s))
            plotname = f.replace('.pkl', '.xplt')
            print("\n... Analyzing results for {:s}".format(plotname))

            results = febio.FebPlt(plotname)
            stress = np.zeros((len(self.data[f]['elements']), 3, 3), float)
            strain = np.copy(stress)
            #material element volumes
            mvolumes = np.zeros(len(self.data[f]['elements']), float)
            #spatial element volumes
            svolumes = np.copy(mvolumes)
            nnodes = len(list(results.NodeData.keys()))
            displacement = np.zeros((nnodes, 3))
            for j, n in enumerate(self.data[f]['nodes']):
                tmp = results.NodeData[j + 1]['displacement'][-1, :]
                displacement[j, :] = [tmp[0], tmp[1], tmp[2]]
            pstress = []
            pstressdir = []
            pstrain = []
            pstraindir = []
            for j, e in enumerate(self.data[f]['elements']):
                tmp = results.ElementData[j + 1]['stress'][-1, :]
                stress[j, :, :] = [[tmp[0], tmp[3], tmp[5]],
                                   [tmp[3], tmp[1], tmp[4]],
                                   [tmp[5], tmp[4], tmp[2]]]
                #material coordinates
                X = np.zeros((4, 3), float)
                #spatial coordinates
                x = np.zeros((4, 3), float)
                for k in range(4):
                    X[k, :] = self.data[f]['nodes'][e[k] - 1]
                    x[k, :] = (X[k, :] +
                               results.NodeData[e[k]]['displacement'][-1, :])
                #set up tangent space
                W = np.zeros((6, 3), float)
                w = np.zeros((6, 3), float)
                for k, c in enumerate(
                        [(0, 1), (0, 2), (0, 3), (1, 3), (2, 3), (1, 2)]):
                    W[k, :] = X[c[1], :] - X[c[0], :]
                    w[k, :] = x[c[1], :] - x[c[0], :]
                dX = np.zeros((6, 6), float)
                ds = np.zeros((6, 1), float)
                for k in range(6):
                    for l in range(3):
                        dX[k, l] = 2 * W[k, l] ** 2
                    dX[k, 3] = 4 * W[k, 0] * W[k, 1]
                    dX[k, 4] = 4 * W[k, 1] * W[k, 2]
                    dX[k, 5] = 4 * W[k, 0] * W[k, 2]
                    ds[k, 0] = (np.linalg.norm(w[k, :]) ** 2 -
                                np.linalg.norm(W[k, :]) ** 2)
                #solve for strain
                E = np.linalg.solve(dX, ds)
                #get volumes
                mvolumes[j] = old_div(np.abs(
                    np.dot(W[0, :], np.cross(W[1, :], W[2, :]))), 6.0)
                svolumes[j] = old_div(np.abs(
                    np.dot(w[0, :], np.cross(w[1, :], w[2, :]))), 6.0)
                strain[j, :, :] = [[E[0], E[3], E[5]],
                                   [E[3], E[1], E[4]],
                                   [E[5], E[4], E[2]]]
                #eigenvalues and eigenvectors of stress and strain tensors
                #eigenvectors are normalized
                eigstrain, eigstraindir = np.linalg.eigh(strain[j, :, :])
                order = np.argsort(eigstrain)
                eigstrain = eigstrain[order]
                eigstraindir /= np.linalg.norm(eigstraindir, axis=0, keepdims=True)
                eigstraindir = eigstraindir[:, order]
                pstrain.append(eigstrain)
                pstraindir.append(eigstraindir)
                eigstress, eigstressdir = np.linalg.eigh(stress[j, :, :])
                order = np.argsort(eigstress)
                eigstress = eigstress[order]
                eigstressdir /= np.linalg.norm(eigstressdir, axis=0, keepdims=True)
                eigstressdir = eigstressdir[:, order]
                pstress.append(eigstress)
                pstressdir.append(eigstressdir)
            pstress = np.array(pstress)
            pstressdir = np.array(pstressdir)
            pstrain = np.array(pstrain)
            pstraindir = np.array(pstraindir)
            #save reference volumes
            self.volumes.update({f: mvolumes})
            self.results['Effective Strain (von Mises)'].update(
                {f: np.sqrt(old_div(((pstrain[:, 2] - pstrain[:, 1]) ** 2 +
                             (pstrain[:, 1] - pstrain[:, 0]) ** 2 +
                             (pstrain[:, 2] - pstrain[:, 0]) ** 2),
                            2.0))})
            self.results['Maximum Compressive Strain'].update(
                {f: np.outer(pstrain[:, 0], [1 , 1, 1]) * pstraindir[:, :, 0]})
            self.results['Maximum Tensile Strain'].update(
                {f: np.outer(pstrain[:, 2], [1, 1, 1]) * pstraindir[:, :, 2]})
            self.results['Maximum Shear Strain'].update(
                {f: 0.5 * (pstrain[:, 2] - pstrain[:, 0])})
            self.results['Volumetric Strain'].update(
                {f: old_div(svolumes, mvolumes) - 1.0})

            self.results['Effective Stress (von Mises)'].update(
                {f: np.sqrt(old_div(((pstress[:, 2] - pstress[:, 1]) ** 2 +
                             (pstress[:, 1] - pstress[:, 0]) ** 2 +
                             (pstress[:, 2] - pstress[:, 0]) ** 2), 2.0))})
            self.results['Maximum Compressive Stress'].update(
                {f: np.outer(pstress[:, 0], [1 , 1, 1]) * pstressdir[:, :, 0]})
            self.results['Maximum Tensile Stress'].update(
                {f: np.outer(pstress[:, 2], [1, 1, 1]) * pstressdir[:, :, 2]})
            self.results['Maximum Shear Stress'].update(
                {f: 0.5 * (pstress[:, 2] - pstress[:, 0])})
            self.results['Pressure'].update(
                {f: old_div(np.sum(pstress, axis=1), 3.0)})

            self.results['Displacement'].update({f: displacement})

        for i, k in enumerate(self.outputs.keys()):
            if self.outputs[k].get():
                for m in self.matched:
                    weights = old_div(self.volumes[m[0]], np.sum(self.volumes[m[0]]))
                    for j, f in enumerate(m):
                        if len(self.results[k][f].shape) > 1:
                            dat = np.ravel(np.linalg.norm(self.results[k][f], axis=1))
                        else:
                            dat = np.ravel(self.results[k][f])
                        if self.analysis['Generate Histograms'].get():
                            IQR = np.subtract(*np.percentile(dat, [75, 25]))
                            nbins = (int(old_div(np.ptp(dat),
                                         (2 * IQR * dat.size ** (old_div(-1., 3.))))))
                            h = histogram(dat, numbins=nbins, weights=weights)
                            bins = np.linspace(h[1], h[1] + h[2] * nbins,
                                               nbins, endpoint=False)
                            self.histograms[k][f] = {'bins': bins,
                                                     'heights': h[0],
                                                     'width': h[2]}
                        if self.analysis['Tukey Boxplots'].get():
                            quantiles = np.zeros(3, float)
                            for n, q in enumerate([0.25, 0.5, 0.75]):
                                quantiles[n] = quantile_1D(dat, weights, q)
                            self.boxwhiskers[k][f] = {'quantiles': quantiles,
                                                      'data': dat}
                    if self.analysis['Calculate Differences'].get():
                        for c in itertools.combinations(m, 2):
                            if len(self.results[k][c[0]].shape) > 1:
                                dat1 = np.ravel(np.linalg.norm(self.results[k][c[0]], axis=1))
                                dat2 = np.ravel(np.linalg.norm(self.results[k][c[1]], axis=1))
                            else:
                                dat1 = np.ravel(self.results[k][c[0]])
                                dat2 = np.ravel(self.results[k][c[1]])
                            difference = dat2 - dat1
                            wrms = np.sqrt(np.average(difference ** 2,
                                                      weights=weights))
                            self.differences[k][c[1] + "MINUS" + c[0]] = {
                                'difference': difference, 'weighted RMS': wrms}
        self.saveResults()
        print("... ... Analysis Complete")