def bias_eff(k, Pk, OmegaM, z, M1, M2, author, bins=100):

    M = np.logspace(np.log10(M1), np.log10(M2), bins + 1)  #bins in mass
    M_middle = 10**(0.5 * (np.log10(M[1:]) + np.log10(M[:-1]))
                    )  #center of the bin
    deltaM = M[1:] - M[:-1]  #size of the bin

    if author == 'SMT01':
        dndM = MFL.ST_mass_function(k, Pk, OmegaM, None, None, None,
                                    M_middle)[1]

    if author == 'Tinker':
        dndM = MFL.Tinker_mass_function(k, Pk, OmegaM, z, None, None, None,
                                        M_middle)[1]

    b = np.empty(bins, dtype=np.float64)
    for i in range(bins):
        b[i] = bias(k, Pk, OmegaM, M_middle[i], author)

    bias_eff = np.sum(dndM * deltaM * b) / np.sum(dndM * deltaM)

    return bias_eff
M_max = 1e16  #Msun/h
bins = 200

#From Crighton et al. 2015
Omega_HI = 4e-4 * (1.0 + z)**0.60

#define the bins in mass
M = np.logspace(np.log10(M_min), np.log10(M_max), bins + 1)

#read the matter power spectrum
if do_CDM: [k, Pk] = BL.CDM_Pk(f_Pk_DM, f_transfer, Omega_CDM, Omega_B)
else: [k, Pk] = BL.DM_Pk(f_Pk_DM)

#compute/read the halo mass function
if not (os.path.exists(f_MF)):
    dndM = MFL.ST_mass_function(k, Pk, OmegaM, None, None, None, M)[1]
    np.savetxt(f_MF, np.transpose([M, dndM]))
else:
    M_MF, dndM = np.loadtxt(f_MF, unpack=True)
    if np.any(M_MF != M):
        print 'error!!\nbins in mass function are different'
        sys.exit()

#compute/read the halo bias
if not (os.path.exists(f_bias)):
    b = np.empty(bins + 1, dtype=np.float64)
    for i, mass in enumerate(M):
        b[i] = BL.bias(k, Pk, OmegaM, mass, 'SMT01')
    np.savetxt(f_bias, np.transpose([M, b]))
else:
    M_b, b = np.loadtxt(f_bias, unpack=True)