def find_excitability_region(P, El, Gl, Cm, pp=low_rate_fluct_domain, discret=40, print_domain=False):
    """
    P are the coefficients of the firing rate response fit
    the other parameters set the default boundaries of
    the numerical evaluation of the relevant firing rate domain

    here all in SI units
    """
    sV0 = np.linspace(pp["sV_min"], pp["sV_max"], discret)
    TvN0 = np.linspace(pp["Ts_ratio"] + 1.0 / pp["muG_max"], pp["Ts_ratio"] + 1.0 / pp["muG_min"], discret)
    muV0 = np.linspace(pp["muV_min"], pp["muV_max"], 5 * discret)  # high discret
    muV, sV, TvN = np.meshgrid(muV0, sV0, TvN0)

    Vthre = final_threshold_func(P, muV, sV, TvN, Gl, El)
    Fout = erfc_func(muV, sV, TvN, Vthre, Gl, Cm)

    dmuV, dsV, dTvN = derivatives_template(P, muV, sV, TvN, Gl * np.ones(muV.shape), El, Gl, Cm)

    ok = (Fout < pp["max_Fout"]) & (Fout > pp["min_Fout"]) & (dmuV > 0) & (dsV > 0)  # desired conditions

    if print_domain:
        print "muV domain :", round(1e3 * muV[ok].min()), round(1e3 * muV[ok].max())
        print "sV domain :", round(1e3 * sV[ok].min()), round(1e3 * sV[ok].max())
        print "TvN domain :", round(1e2 * TvN[ok].min()), round(1e2 * TvN[ok].max())

    return Fout[ok], Vthre[ok], muV[ok], sV[ok], TvN[ok]
def get_mean_encoding_power(P, El, Gl, Cm, pp=low_rate_fluct_domain, discret=20, with_rescaling=False):
    """
    returns the mean excitability as well as the mean encoding coeffs in:
    mV, Hz/mV, Hz/mV and Hz/%
    """
    Fout, Vthre, muV, sV, TvN = find_excitability_region(P, El, Gl, Cm, pp=pp, discret=discret)
    dmuV, dsV, dTvN = derivatives_template(P, muV, sV, TvN, Gl * np.ones(muV.shape), El, Gl, Cm)

    return 1e3 * Vthre.mean(), dmuV.mean() * 1e-3, dsV.mean() * 1e-3, 1e-2 * dTvN.mean()
def get_mean_encoding_power(P, El, Gl, Cm,\
                            pp = low_rate_fluct_domain,
                            discret=20, with_rescaling=False):
    """
    returns the mean excitability as well as the mean encoding coeffs in:
    mV, Hz/mV, Hz/mV and Hz/%
    """
    Fout, Vthre, muV, sV, TvN = find_excitability_region(P, El, Gl, Cm,\
                                    pp=pp, discret=discret)
    dmuV, dsV, dTvN = derivatives_template(\
            P, muV, sV, TvN, Gl*np.ones(muV.shape), El, Gl, Cm)

    return 1e3 * Vthre.mean(), dmuV.mean() * 1e-3, dsV.mean(
    ) * 1e-3, 1e-2 * dTvN.mean()
def find_excitability_region(P, El, Gl, Cm,\
                             pp = low_rate_fluct_domain,
                             discret=40,\
                             print_domain=False):
    """
    P are the coefficients of the firing rate response fit
    the other parameters set the default boundaries of
    the numerical evaluation of the relevant firing rate domain

    here all in SI units
    """
    sV0 = np.linspace(pp['sV_min'], pp['sV_max'], discret)
    TvN0 = np.linspace(pp['Ts_ratio'] + 1. / pp['muG_max'],
                       pp['Ts_ratio'] + 1. / pp['muG_min'], discret)
    muV0 = np.linspace(pp['muV_min'], pp['muV_max'],
                       5 * discret)  # high discret
    muV, sV, TvN = np.meshgrid(muV0, sV0, TvN0)

    Vthre = final_threshold_func(P, muV, sV, TvN, Gl)
    Fout = erfc_func(muV, sV, TvN, Vthre, Gl, Cm)

    dmuV, dsV, dTvN = derivatives_template(\
            P, muV, sV, TvN, Gl*np.ones(muV.shape), El, Gl, Cm)

    ok = (Fout < pp['max_Fout']) & (Fout > pp['min_Fout']) & (dmuV > 0) & (
        dsV > 0)  # desired conditions

    if print_domain:
        print('muV domain :', round(1e3 * muV[ok].min()),
              round(1e3 * muV[ok].max()))
        print('sV domain :', round(1e3 * sV[ok].min()),
              round(1e3 * sV[ok].max()))
        print('TvN domain :', round(1e2 * TvN[ok].min()),
              round(1e2 * TvN[ok].max()))

    return Fout[ok], Vthre[ok], muV[ok], sV[ok], TvN[ok]