Ejemplo n.º 1
0
def find_fixed_point(NRN1, NRN2, NTWK, Ne=8000, Ni=2000, exc_aff=0., verbose=False):

    # we start from the first order prediction !!!
    X0 = find_fixed_point_first_order(NRN1, NRN2, NTWK,\
                                      Ne=Ne, Ni=Ni, exc_aff=exc_aff,\
                                      verbose=verbose)
    X0 = [X0[0], X0[1], .5, .5, .5]
    
    TF1, TF2 = load_transfer_functions(NRN1, NRN2, NTWK)
    t = np.arange(200)*1e-4              # time

    ### SECOND ORDER ###
    # def dX_dt_scalar(X, t=0):
    #     return build_up_differential_operator(TF1, TF2,\
    #                                           Ne=Ne, Ni=Ni)(X, exc_aff=exc_aff)
    # X = odeint(dX_dt_scalar, X0, t)         # we don't need infodict here

    # simple euler
    X = X0
    for i in range(len(t)-1):
        X = X + (t[1]-t[0])*build_up_differential_operator(TF1, TF2,Ne=Ne, Ni=Ni)(X, exc_aff=exc_aff)
        last_X = X

    print('Make sure that those two values are similar !!')
    print(X)
    print(last_X)
    
    if verbose:
        print(X)
    if verbose:
        print('first order prediction: ',X[-1])
    
    # return X[-1][0], X[-1][1], np.sqrt(X[-1][2]), np.sqrt(X[-1][3]), np.sqrt(X[-1][4])
    return X[0], X[1], np.sqrt(X[2]), np.sqrt(X[3]), np.sqrt(X[4])
Ejemplo n.º 2
0
def find_fixed_point_first_order(NRN1, NRN2, NTWK,\
                                 Ne=8000, Ni=2000, exc_aff=0.,\
                                 verbose=False):

    TF1, TF2 = load_transfer_functions(NRN1, NRN2, NTWK)
    
    t = np.arange(2000)*1e-4              # time
    
    ### FIRST ORDER ###
    def dX_dt_scalar(X, t=0):
        return build_up_differential_operator_first_order(TF1, TF2, T=5e-3)(X, exc_aff=exc_aff)
    X0 = [1, 10] # need inhibition stronger than excitation
    X = odeint(dX_dt_scalar, X0, t)         # we don't need infodict here
    if verbose:
        print('first order prediction: ', X[-1])
    return X[-1][0], X[-1][1] 
Ejemplo n.º 3
0
def Euler_method_for_ring_model(NRN1, NRN2, NTWK, RING, STIM, BIN=5e-3,\
                                custom_ring_params={}, custom_stim_params={}):
    """
    Given two afferent rate input excitatory and inhibitory respectively
    this function computes the prediction of a first order rate model
    (e.g. Wilson and Cowan in the 70s, or 1st order of El Boustani and
    Destexhe 2009) by implementing a simple Euler method
    IN A 2D GRID WITH LATERAL CONNECTIVITY
    the number of laterally connected units is 'connected_neighbors'
    there is an exponential decay of the strength 'decay_connect'
    ----------------------------------------------------------------
    the core of the formalism is the transfer function, see Zerlaut et al. 2015
    it can also be Kuhn et al. 2004 or Amit & Brunel 1997
    -----------------------------------------------------------------
    nu_0 is the starting value value of the recurrent network activity
    it should be the fixed point of the network dynamics
    -----------------------------------------------------------------
    t is the discretization used to solve the euler method
    BIN is the initial sampling bin that should correspond to the
    markovian time scale where the formalism holds (~5ms)
    
    conduction_velocity=0e-3, in ms per pixel !!!
    """

    print('----- loading parameters [...]')
    M = get_connectivity_and_synapses_matrix(NTWK, SI_units=True)
    ext_drive = M[0, 0]['ext_drive']
    params = get_neuron_params(NRN2, SI_units=True)
    reformat_syn_parameters(params, M)
    afferent_exc_fraction = M[0, 0]['afferent_exc_fraction']

    print('----- ## we look for the fixed point [...]')
    try:
        fe0, fi0, muV0 = np.load("fixed_point_data_TO_BE_REMOVED.npy")
        print(
            "/!\\ STORED FIXED POINT DATA LOADED, check if not a different config /!\\"
        )
    except IOError:
        fe0, fi0 = find_fixed_point_first_order(NRN1,
                                                NRN2,
                                                NTWK,
                                                exc_aff=ext_drive)
        muV0, _, _, _ = get_fluct_regime_vars(fe0 + ext_drive, fi0,
                                              *pseq_params(params))
        np.save('fixed_point_data_TO_BE_REMOVED.npy', [fe0, fi0, muV0])

    print('----- ## we load the transfer functions [...]')
    TF1, TF2 = load_transfer_functions(NRN1, NRN2, NTWK)

    print('----- ## ring initialisation [...]')
    X, Xn_exc, Xn_inh, exc_connected_neighbors, exc_decay_connect, inh_connected_neighbors,\
        inh_decay_connect, conduction_velocity = ring.pseq_ring_params(RING, custom=custom_ring_params)

    print('----- ## stimulation initialisation [...]')
    t, Fe_aff = stim.get_stimulation(X, STIM, custom=custom_stim_params)
    Fi_aff = 0 * Fe_aff  # no afferent inhibition yet

    print('----- ## model initialisation [...]')
    Fe, Fi, muVn = 0 * Fe_aff + fe0, 0 * Fe_aff + fi0, 0 * Fe_aff + muV0

    print('----- starting the temporal loop [...]')
    dt = t[1] - t[0]

    # constructing the Euler method for the activity rate
    for i_t in range(len(t) - 1):  # loop over time

        for i_x in range(len(X)):  # loop over pixels

            # afferent excitation + exc DRIVE
            fe = (1 - afferent_exc_fraction) * Fe_aff[
                i_t, i_x] + ext_drive  # common both to exc and inh
            fe_pure_exc = (2 * afferent_exc_fraction -
                           1) * Fe_aff[i_t, i_x]  # only for excitatory pop
            fi = 0  #  0 for now.. !

            # EXC --- we add the recurrent activity and the lateral interactions
            for i_xn in Xn_exc:  # loop over neighboring excitatory pixels
                # calculus of the weight
                exc_weight = ring.gaussian_connectivity(
                    i_xn, 0., exc_decay_connect)
                # then we have folded boundary conditions (else they donot
                # have all the same number of active neighbors !!)
                i_xC = (i_x + i_xn) % (len(X))

                if i_t > int(abs(i_xn) / conduction_velocity / dt):
                    it_delayed = i_t - int(
                        abs(i_xn) / conduction_velocity / dt)
                else:
                    it_delayed = 0

                fe += exc_weight * Fe[it_delayed, i_xC]

            # INH --- we add the recurrent activity and the lateral interactions
            for i_xn in Xn_inh:  # loop over neighboring inhibitory pixels
                # calculus of the weight
                inh_weight = ring.gaussian_connectivity(
                    i_xn, 0., inh_decay_connect)
                # then we have folded boundary conditions (else they donot
                # have all the same number of active neighbors !!)
                i_xC = (i_x + i_xn) % (len(X))

                if i_t > int(abs(i_xn) / conduction_velocity / dt):
                    it_delayed = i_t - int(
                        abs(i_xn) / conduction_velocity / dt)
                else:
                    it_delayed = 0

                fi += inh_weight * Fi[it_delayed, i_xC]

            ## NOTE THAT NO NEED TO SCALE : fi*= gei*pconnec*Ntot and fe *= (1-gei)*pconnec*Ntot
            ## THIS IS DONE IN THE TRANSFER FUNCTIONS !!!!

            # now we can guess the rate model output
            muVn[i_t + 1,
                 i_x], _, _, _ = get_fluct_regime_vars(fe, fi,
                                                       *pseq_params(params))
            Fe[i_t + 1,
               i_x] = Fe[i_t, i_x] + dt / BIN * (TF1(fe + fe_pure_exc, fi) -
                                                 Fe[i_t, i_x])
            Fi[i_t + 1,
               i_x] = Fi[i_t, i_x] + dt / BIN * (TF2(fe, fi) - Fi[i_t, i_x])

    print('----- temporal loop over !')

    return t, X, Fe_aff, Fe, Fi, np.abs((muVn - muV0) / muV0)
Ejemplo n.º 4
0
from scipy.integrate import odeint
from single_cell_models.cell_library import get_neuron_params
from synapses_and_connectivity.syn_and_connec_library import get_connectivity_and_synapses_matrix
from transfer_functions.tf_simulation import reformat_syn_parameters
import matplotlib.pylab as plt

from scipy.optimize import fsolve
from scipy.optimize import minimize
import math

NTWK = 'CONFIG1'

NRN1 = 'HH_RS'
NRN2 = 'HH_RS'

TF1, TF2 = load_transfer_functions(NRN1, NRN2, NTWK)

M = get_connectivity_and_synapses_matrix(NTWK, SI_units=True)
params = get_neuron_params(NRN1, SI_units=True)
reformat_syn_parameters(params, M)
paramsinh = get_neuron_params(NRN2, SI_units=True)
reformat_syn_parameters(paramsinh, M)

Qe, Te, Ee = params['Qe'], params['Te'], params['Ee']
Qi, Ti, Ei = params['Qi'], params['Ti'], params['Ei']
Gl, Cm, El = params['Gl'], params['Cm'], params['El']
pconnec, Ntot, gei, ext_drive = params['pconnec'], params['Ntot'], params[
    'gei'], M[0, 0]['ext_drive']

N = 100
freqs = np.linspace(3, 7, N)
Ejemplo n.º 5
0
def draw_phase_space(args, T=5e-3):

    TF1, TF2 = load_transfer_functions(args.NRN1, args.NRN2, args.NTWK)

    ## now we compute the dynamical system
    ## X = [nu_e,nu_i]
    # T*d(nu_e)/dt = TF1(nu_e,nu_i) - n_e
    # T*d(nu_i)/dt = TF2(nu_e,nu_i) - n_i

    def dX_dt_scalar(X, t=0):
        return build_up_differential_operator_first_order(TF1, TF2, T=5e-3)(
            X, exc_aff=args.ext_drive)

    def dX_dt_mesh(IN, t=0):
        [x, y] = IN
        DFx = 0 * x
        DFy = 0 * y
        for inh in range(x.shape[0]):
            for exc in range(x.shape[1]):
                fe = x[inh][exc]
                fi = y[inh][exc]
                DFx[inh, exc] = (TF1(fe + args.ext_drive, fi) - fe) / T
                DFy[inh, exc] = (TF2(fe + args.ext_drive, fi) - fi) / T
        return DFx, DFy

    t = np.linspace(0, .04, 1e5)  # time

    # values  = np.array([[3,9],[4,9.5],[7.5,7],[5.5,4],[4,4]])
    values = np.array([[2, 14], [6, 12], [1, 1], [5.5, 4], [10, 3]])
    vcolors = plt.cm.gist_heat(np.linspace(
        0, .8, len(values)))  # colors for each trajectory

    ff1 = plt.figure(figsize=(5, 4))
    f1 = plt.subplot(111)

    ff2 = plt.figure(figsize=(5, 4))
    f2 = plt.subplot(111)

    # X_f0 = np.array([4.,4.])
    # X_f1 = np.array([10.,10.]) # fixed points values

    #-------------------------------------------------------
    # plot trajectories
    for v, col in zip(range(len(values)), vcolors):
        X0 = values[v]  # starting point
        X = integrate.odeint(dX_dt_scalar, X0,
                             t)  # we don't need infodict here
        l1 = f1.plot(1e3 * t,
                     X[:, 0],
                     '--',
                     lw=2,
                     color=col,
                     label='excitation')
        l2 = f1.plot(1e3 * t, X[:, 1], '-', lw=2, color=col)
        f2.plot(X[:, 0],
                X[:, 1],
                lw=2,
                color=col,
                label='X0=(%.f, %.f)' % (X0[0], X0[1]))
    f1.legend(('exc. pop.', 'inh. pop.'), prop={'size': 'x-small'})

    set_plot(f1, xlabel="time (ms)", ylabel="frequency (Hz)")

    ###### ============ VECTOR FIELD  ============= #######

    #-------------------------------------------------------
    # define a grid and compute direction at each point
    ymax = args.max_Fi
    ymin = 0
    xmax = args.max_Fe
    xmin = 0
    nb_points = 20

    x = np.linspace(xmin, xmax, nb_points)
    y = np.linspace(ymin, ymax, nb_points)

    X1, Y1 = np.meshgrid(x, y)  # create a grid
    DX1, DY1 = dX_dt_mesh([X1, Y1])  # compute growth rate on the gridt
    M = (np.hypot(DX1, DY1))  # Norm of the growth rate
    M[M == 0] = 1.  # Avoid zero division errors
    M /= 1e3  # TO BE CHECKED -> Hz/ms
    DX1 /= M  # Normalize each arrows
    DY1 /= M

    #-------------------------------------------------------
    # Drow direction fields, using matplotlib 's quiver function
    # I choose to plot normalized arrows and to use colors to give information on
    # the growth speed
    Q = plt.quiver(X1, Y1, DX1, DY1, M, pivot='mid', cmap=plt.cm.jet)
    cb = plt.colorbar(Q, cmap=plt.cm.jet, shrink=.5)
    cb.set_label('absolute speed (Hz/ms)')
    cb.set_ticks([0, 10, 20])
    #cb.set_ticklabels([0,int(M.max()/2000),int(M.max()/1000)])
    plt.plot([X[-1, 0]], [X[-1, 1]], 'ko', ms=10)
    plt.plot([X[-1, 0], X[-1, 0]], [0, X[-1, 1]], 'k--', lw=4, alpha=.4)
    plt.plot([0, X[-1, 0]], [X[-1, 1], X[-1, 1]], 'k--', lw=4, alpha=.4)

    set_plot(f2, xlabel='exc. pop. freq. (Hz)', ylabel='inh. pop. freq. (Hz)',\
             xlim=[xmin, xmax], ylim=[ymin, ymax])
    # plt.legend(loc='best')
    # plt.grid()
    # now fixed point
    print 'Fe=', X[-1, 0]
    print 'Fi=', X[-1, 1]

    plt.tight_layout()

    # ff2.savefig('figures/phase_space_with_fs.pdf', format='pdf')
    # ff1.savefig('figures/traject_with_fs.pdf', format='pdf')
    # ff2.savefig('figures/phase_space.pdf', format='pdf')
    # ff1.savefig('figures/traject.pdf', format='pdf')

    plt.show()