def getMeans2D(energy_x, energy_y, z, lim):
    ind = np.invert(np.isnan(z))
    z = z[ind]
    energy_x = energy_x[ind]
    energy_y = energy_y[ind]
    neighborhood = neighbors.NearestNeighbors(n_neighbors=250)
    neighborhood.fit(np.transpose(np.matrix([energy_x, energy_y])))
    step = 0.5
    ener_x = np.arange(0, lim + step, step)
    ener_y = np.arange(0, lim + step, step)
    sigma_gaussianfit = []
    mean_gaussianfit = []

    for y in ener_y:
        line_mean = []
        line_sigma = []
        for x in ener_x:
            if x + y < lim:
                dist, ind = neighborhood.kneighbors(X=[[x, y]])
                z_ind = z[ind]
                params = gaussian_fit(z_ind, binwidth=0.1, reducedChi2Max=10)
                if math.isnan(params[0]):
                    line_mean.append(np.mean(z_ind))
                    line_sigma.append(np.sqrt(np.std(z_ind)))
                else:
                    line_mean.append(params[1])
                    line_sigma.append(params[0])
            else:
                line_mean.append(math.nan)
                line_sigma.append(math.nan)
        mean_gaussianfit.append(line_mean)
        sigma_gaussianfit.append(line_sigma)
    return mean_gaussianfit, sigma_gaussianfit
def getMeans(energy_x, y):
    ind = np.invert(np.isnan(y))
    y = y[ind]
    energy_x = energy_x[ind]

    neighborhood = neighbors.NearestNeighbors(n_neighbors=1000)
    neighborhood.fit(np.transpose(np.matrix(energy_x)))
    step = 0.1
    ener = np.arange(min(energy_x), max(energy_x), step)
    sigma_gaussianfit = []
    mean_gaussianfit = []
    means = []
    energy = []
    reducedChi2 = []
    for e in ener:
        dist, ind = neighborhood.kneighbors(X=e)
        y_ind = y[ind][np.invert(np.isnan(y[ind]))]
        params, reduced = gaussian_fit(y_ind,
                                       binwidth=0.1,
                                       giveReducedChi2=True,
                                       reducedChi2Max=10)
        if not (math.isnan(params[1])):
            means.append(np.mean(y_ind))
            sigma_gaussianfit.append(params[0])
            mean_gaussianfit.append(params[1])
            energy.append(e)
            reducedChi2.append(reduced)
    return energy, means, mean_gaussianfit, sigma_gaussianfit, reducedChi2