def test_ConductanceMinimization(self): """Solve for NMDA conductances with constrained firing rates""" system = no_subpopulation() constraints = [ MFConstraint( "%s-%s" % (p.name, "gNMDA"), partial(lambda x: x.inputs[0][IP.GM], p), partial(lambda x, val: x.inputs[0].__setitem__(IP.GM, val), p), partial(lambda x: x.rate - x.rate_prediction, p), 0. * nsiemens, 500. * nsiemens) for p in system.populations ] + [ MFConstraint("%s-%s" % (p.name, "v_mean"), partial(lambda x: x.v_mean, p), partial(lambda x, val: setattr(x, "v_mean", val), p), partial(lambda x: x.v_mean - x.v_mean_prediction, p), -80. * mV, -50. * mV) for p in system.populations ] state = MFState(constraints, bounds_check=True) solver = MFSolver(state, solver='hybr') solver.run() for p in system.populations: assert p.rate_prediction.has_same_dimensions(p.rate) np.testing.assert_almost_equal(np.array(p.rate_prediction), np.array(p.rate))
def test_ConductanceMinimizationRatio(self): """Solve for NMDA & Gaba conductances with constrained firing rates & EI fixed ratio""" system = no_subpopulation() ratio = 4. def e_setter(p, val): p.inputs[0].__setitem__(IP.GM, val) p.inputs[1].__setitem__(IP.GM, ratio * val) constraints = [ MFConstraint("%s-%s" % (print(p.inputs), "gNMDA"), partial(lambda x: x.inputs[0][IP.GM], p), partial(e_setter, p), partial(lambda x: x.rate - x.rate_prediction, p), 0. * nsiemens, 500. * nsiemens) for p in system.populations ] + [ MFConstraint("%s-%s" % (p.name, "v_mean"), partial(lambda x: x.v_mean, p), partial(lambda x, val: setattr(x, "v_mean", val), p), partial(lambda x: x.v_mean - x.v_mean_prediction, p), -80. * mV, 50. * mV) for p in system.populations ] state = MFState(constraints) solver = MFSolver(state, maxiter=1) solver.run() for p in system.populations: assert p.rate_prediction.has_same_dimensions(p.rate) np.testing.assert_almost_equal(np.array(p.rate_prediction), np.array(p.rate))
def test_GradientMinimization_RatesVoltages(self): """Solve for firing rates & voltages with specialized subclass""" system = no_subpopulation() solver = MFSolver.rates_voltages(system, solver="mse", maxiter=1) sol1 = solver.run() solver = MFSolver.rates_voltages(system, solver="gradient", maxiter=1) sol2 = solver.run() np.testing.assert_array_almost_equal(sol1.state, sol2.state, 5)
def test_MFSolver_RatesVoltages(self): """Solve for firing rates & voltages with specialized subclass""" solver = MFSolver.rates_voltages(self.system) r1 = solver.run() # take old implementation and compare state = self.test_MFState() solver = MFSolver(state) r2 = solver.run() for key in [c.name for c in r1.constraints]: assert r1[key] == r2[key]
def test_simulation_theory(self): reset_brian2() t = 1000 * ms dt = 0.01 * ms defaultclock.dt = dt pop = MFLinearPopulation( 100, { PP.GM: 25. * nS, PP.CM: 0.5 * nF, PP.VL: -70. * mV, PP.VTHR: -50. * mV, PP.VRES: -55. * mV, PP.TAU_RP: 2. * ms }) pop.rate = 1 * Hz noise = MFStaticInput(1000, 1 * Hz, pop, { IP.GM: 2 * nS, IP.VREV: 0 * volt, IP.TAU: 2. * ms, }) rec = MFLinearInput(pop, pop, { IP.GM: 0.973 / 100 * nS, IP.VREV: -70 * volt, IP.TAU: 10. * ms, }) system = MFSystem(pop) solver = MFSolver.rates_voltages(system, solver='mse', maxiter=1) sol = solver.run() theory = sol.state[0] rate = PopulationRateMonitor(pop.brian2) net = system.collect_brian2_network(rate) net.run(t) #brian2_introspect(net, globals()) stable_t = int(t / dt * 0.1) isolated = np.array(rate.rate)[stable_t:-stable_t] print(isolated.mean()) if False: plt.plot(rate.t / ms, rate.smooth_rate(width=25 * ms) / Hz) plt.plot(np.ones(10000) * isolated.mean(), label='simulation mean') plt.plot(np.ones(10000) * theory, label='theory mean') plt.ylabel('Population rate (Hz) per 100') plt.xlabel('Simulation time (ms)') plt.title('Poisson noise 5 Hz per 1000') plt.legend() plt.show()
def test_MFSolver(self): """Solve for firing rates & voltages with explicit function""" up, down, inter = self.system.populations up.rate = 1 * Hz down.rate = 4 * Hz inter.rate = 12 * Hz solver = MFSolver.rates_voltages(self.system, solver='simplex', maxiter=1) sol = solver.run() print(sol)
def test_simulation_theory(self): reset_brian2() t = 3000 * ms dt = 0.01 * ms n = 100 poisson = MFPoissonPopulation(n, n * 10 * Hz) pop = MFLinearPopulation( n, { PP.GM: 10 * nsiemens, PP.VL: 0 * mV, PP.CM: 5 * nfarad, PP.VTHR: 0 * mV, PP.VRES: 0 * mV, PP.TAU_RP: 15 * ms }) syn = MFLinearNMDAInput( poisson, pop, { IP.GM: 10 * nsiemens, IP.VREV: 0 * mV, IP.TAU: 20 * ms, IP.TAU_NMDA: 30 * ms, IP.BETA: 1, IP.GAMMA: 1, }) system = MFSystem(pop, poisson) solver = MFSolver.rates_voltages(system, solver='mse') solver.run() theory = syn.g_dyn() / syn.origin.n m = StateMonitor(syn.brian2, syn.post_variable_name, record=range(100)) defaultclock.dt = dt net = system.collect_brian2_network(m) net.run(t) stable_t = int(t / dt * 0.1) simulation = m.__getattr__(syn.post_variable_name)[:, stable_t:] simulation_mean = np.mean(simulation) print(simulation) assert np.isclose(theory, simulation_mean, rtol=0.5, atol=0.5)
def with_rate(rate): reset_brian2() pop = MFLinearPopulation(n_pop, { PP.GM: 25. * nS, PP.CM: 0.5 * nF, PP.VL: -70. * mV, PP.VTHR: -50. * mV, PP.VRES: -55. * mV, PP.TAU_RP: 2. * ms }) pop.rate = 10 * Hz MFStaticInput(n_noise, rate * Hz, pop, { IP.GM: 2.08 * nS, IP.VREV: 0 * volt, IP.TAU: 1.5 * ms, }) system = MFSystem(pop) rate = PopulationRateMonitor(pop.brian2) net = system.collect_brian2_network(rate) net.run(t) margin = round(0.5 * second / defaultclock.dt) stable = rate.smooth_rate(width=20 * ms)[margin:-margin] mean_simu = np.mean(stable) std_simu = np.reshape(stable, (samples, -1)).mean(axis=1).std() / np.sqrt(samples) * 1.96 print(std_simu) solver = MFSolver.rates_voltages(system, solver='simplex', maxiter=1) sol = solver.run() mean_theo = sol.state[0] return [mean_theo, mean_simu, std_simu]
def for_rate(rate): reset_brian2() pop = MFLinearPopulation( n_pop, { PP.GM: 25. * nS, PP.CM: 0.5 * nF, PP.VL: -70. * mV, PP.VTHR: -50. * mV, PP.VRES: -55. * mV, PP.TAU_RP: 2. * ms }) pop.rate = 1 * Hz MFStaticInput(n_noise, rate * Hz, pop, { IP.GM: 2 * nS, IP.VREV: 0 * volt, IP.TAU: 2. * ms, }) t = 500 * ms dt = 0.1 * ms system = MFSystem(pop) rate = PopulationRateMonitor(pop.brian2) net = system.collect_brian2_network(rate) net.run(t) stable_t = int(t / dt * 0.1) isolated = np.array(rate.rate)[stable_t:-stable_t] sim = np.mean(isolated) solver = MFSolver.rates_voltages(system, solver='simplex', maxiter=1) sol = solver.run() return [sol.state[0], sim]
def for_rate(rate): pop = MFLinearPopulation(100, { PP.GM: 25. * nS, PP.CM: 0.5 * nF, PP.VL: -70. * mV, PP.VTHR: -50. * mV, PP.VRES: -55. * mV, PP.TAU_RP: 2. * ms }) pop.rate = 10 * Hz noise = MFStaticInput(1000, rate * Hz, pop, { IP.GM: 2 * nS, IP.VREV: 0 * volt, IP.TAU: 2. * ms, }) pop.add_noise(noise) system = MFSystem(pop) solver = MFSolver.rates_voltages(system, solver='mse', maxiter=1) print(solver.state) sol = solver.run() return sol.state[0]
def test_MFSolver(self): """Solve for firing rates & voltages with explicit function""" state = self.test_MFState() solver = MFSolver(state) solver.run()
def test_simulation_theory(self): reset_brian2() t = 3000 * ms dt = 0.01 * ms n = 100 alpha = 0.5 poisson = MFPoissonPopulation(n, n * 10 * Hz) pop = MFLinearPopulation( n, { PP.GM: 10 * nsiemens, PP.VL: 0 * mV, PP.CM: 5 * nfarad, PP.VTHR: 0 * mV, PP.VRES: 0 * mV, PP.TAU_RP: 15 * ms }) syn = MFLinear3TSInput( poisson, pop, { IP.GM: 10 * nsiemens, IP.VREV: 0 * mvolt, IP.TAU: 0 * ms, IP.TAU_RISE: 2 * ms, IP.TAU_D1: 20 * ms, IP.TAU_D2: 30 * ms, IP.ALPHA: alpha }) system = MFSystem(pop, poisson) solver = MFSolver.rates_voltages(system, solver='mse') solver.run() theory = syn.g_dyn() / syn.origin.n print(syn.brian2) m1 = StateMonitor(syn.brian2, syn.post_variable_name[0], record=range(100)) m2 = StateMonitor(syn.brian2, syn.post_variable_name[1], record=range(100)) m3 = StateMonitor(syn.brian2, syn.post_variable_name[2], record=range(100)) m4 = StateMonitor(syn.brian2, syn.post_variable_name[3], record=range(100)) defaultclock.dt = dt net = system.collect_brian2_network(m1, m2, m3, m4) net.run(t) stable_t = int(t / dt * 0.1) simulation_1 = m1.__getattr__(syn.post_variable_name[0])[:, stable_t:] simulation_mean_1 = np.mean(simulation_1) simulation_2 = m2.__getattr__(syn.post_variable_name[1])[:, stable_t:] simulation_mean_2 = np.mean(simulation_2) simulation_3 = m3.__getattr__(syn.post_variable_name[2])[:, stable_t:] simulation_mean_3 = np.mean(simulation_3) simulation_4 = m4.__getattr__(syn.post_variable_name[3])[:, stable_t:] simulation_mean_4 = np.mean(simulation_4) simulation_mean = alpha * simulation_mean_1 + ( 1 - alpha) * simulation_mean_2 + -alpha * simulation_mean_3 - ( 1 - alpha) * simulation_mean_4 assert np.isclose(theory, simulation_mean, rtol=0.5, atol=0.5)
rm_E_sel = modelling.brian2_rate_monitors(pop_e_sel) rm_E = modelling.brian2_rate_monitors(pop_e) rm_I = modelling.brian2_rate_monitors(pop_i) all_rm = rm_E + rm_I + rm_E_sel # simulate, can be long >120s system = MFSystem(pop_e, *pop_e_sel, pop_i, name="Brunel Wang 2001") pop_e.rate = 1 * Hz pop_i.rate = 9 * Hz for p in pop_e_sel: p.rate = 1 * Hz pop_e_sel[0].rate = 30 * Hz solver = MFSolver.rates_voltages(system, solver='simplex', maxiter=1) #sol = solver.run() #print(sol) #system.graph().view(cleanup=True) # at 1s, select population 1 C_selection = int(f * C_ext) rate_selection = 50 * Hz stimuli1 = TimedArray(np.r_[np.zeros(40), np.ones(2), np.zeros(1000)], dt=25 * ms) input1 = PoissonInput(pop_e_sel[0].brian2, 's_noise_E_sel_0', C_selection, rate_selection, 'stimuli1(t)')