Description of problem
I have a simulation which takes a while to run. Even after parallelisation. Now I was wondering if there is a way to save the array exactly as to be saved in data and import and use later. What is the best way to do this ?
Plus :
Is there an efficient way to average the single neuron firing rate over n_sims. that is , neuron1 average the firing rate 1000 times . I could’nt setup the PopulationMonitor rate to do so. I realise maybe its is not the thing to use for single neurons.
Minimal code to reproduce problem
#imports
from brian2 import *
from IPython.display import clear_output
import numpy as np
import matplotlib.pyplot as plt
set_device('cpp_standalone', build_on_run=False)
prefs.devices.cpp_standalone.openmp_threads = 12
#define ovrlap AUB etc
n_ab = 0.33 # this percentage receives both sine and pulse
n_a = (1 - n_ab)/2 # only sine
n_b = (1 - n_ab)/2 # only pulse
########## neuron inputs #############
start_scope()
defaultclock.dt = 0.05*ms
duration = 2*second
Cm = 1*uF # /cm**2
gL = 0.1*msiemens
EL = -65*mV
ENa = 55*mV
EK = -90*mV
gNa = 35*msiemens
gK = 9*msiemens
# Synaptic variables
taue = 5*ms
taui = 10*ms
Ee = 0*mV
Ei = -80*mV
we = 15*uS # excitatory synaptic weight
wi = 67*uS # inhibitory synaptic weight
# Hodgkin-Huxley + synaptic + external currents
eqs = '''
dv/dt = (-gNa*m**3*h*(v-ENa) - gK*n**4*(v-EK) - gL*(v-EL)
+ Iamp0 + Iamp * sin(2*pi*Ifreq*t)
+ ge*(Ee-v) + gi*(Ei-v)) / Cm : volt
# gating vars
m = alpha_m/(alpha_m+beta_m) : 1
alpha_m = 0.1/mV*10*mV/exprel(-(v+35*mV)/(10*mV))/ms : Hz
beta_m = 4*exp(-(v+60*mV)/(18*mV))/ms : Hz
dh/dt = 5*(alpha_h*(1-h)-beta_h*h) : 1
alpha_h = 0.07*exp(-(v+58*mV)/(20*mV))/ms : Hz
beta_h = 1./(exp(-0.1/mV*(v+28*mV))+1)/ms : Hz
dn/dt = 5*(alpha_n*(1-n)-beta_n*n) : 1
alpha_n = 0.01/mV*10*mV/exprel(-(v+34*mV)/(10*mV))/ms : Hz
beta_n = 0.125*exp(-(v+44*mV)/(80*mV))/ms : Hz
# synaptic conductances
dge/dt = -ge*(1./taue) : siemens
dgi/dt = -gi*(1./taui) : siemens
# external input parameters
Iamp0 : amp # constant or pulsed current
Iamp : amp # sinusoidal amplitude
Ifreq : Hz # sinusoidal frequency
'''
# Neuron group
N = 100
group = NeuronGroup(N, eqs, threshold='v>-20*mV', refractory=3*ms,
method='rk4')
group.v = -70*mV
group.h = 1
######### noise goes everywhere ##########
# Noise input
rate = 20*Hz
Noise_in = PoissonGroup(N, rates=rate)
S = Synapses(Noise_in, group, on_pre='ge += we')
S.connect(j='i')
# Example: set input currents in n_a neurons
n_a_arr = np.zeros(N)
# first n_a percentage becomes 1
n_a = n_a * N # convert percentage to number of neurons
n_a_arr[:int(n_a)] = 1 # set first n_a neurons to 1
# sinusoidal input
n_b_arr = np.zeros(N)
#last n_b percentage becomes 1
n_b = n_b * N # convert percentage to number of neurons
n_b_arr[-int(n_b):] = 1 # set last n_b neurons to 1
n_ab_arr = n_a_arr + n_b_arr # overlap neurons
#make 0s as 1s and 1s as 0s
n_ab_arr[n_ab_arr == 0] = 1
n_ab_arr[n_ab_arr == 1] = 0
# Monitors
monitor = StateMonitor(group, 'v', record=True)
monitor_s = SpikeMonitor(group)
# syn_rate = PopulationRateMonitor(Noise_in)
# monitor_rate = PopulationRateMonitor(group)
# ge_monitor = StateMonitor(group, 'ge', record=True)
# input_monitor = SpikeMonitor(Noise_in)
n_sims = 1000
from tqdm import tqdm
for i in tqdm(range(n_sims)):
group.Iamp0 = 0*0.55*uA * (n_a_arr + n_ab_arr) # baseline or pulse amplitude
group.Iamp = 0*0.35*uA * (n_b_arr + n_ab_arr) # sinusoidal amplitude
group.Ifreq = 8*Hz # sinusoidal frequency
run(duration/5.0)
group.Iamp0 = 0.55*uA * (n_a_arr + n_ab_arr) # baseline or pulse amplitude
group.Iamp = 0.35*uA * (n_b_arr + n_ab_arr) # sinusoidal amplitude
group.Ifreq = 8*Hz # sinusoidal frequency
run(3*duration/5.0)
group.Iamp0 = 0*0.55*uA * (n_a_arr + n_ab_arr) # baseline or pulse amplitude
group.Iamp = 0*0.35*uA * (n_b_arr + n_ab_arr) # sinusoidal amplitude
group.Ifreq = 8*Hz # sinusoidal frequency
run(duration/5.0)
device.build()
clear_output(wait=False)
print('Whole sim completed')
#plot the raster plot for neuron group
plt.figure(figsize=(10, 6), dpi=150)
plt.plot(monitor_s.t/ms, monitor_s.i, 'k|', markersize= 3)
plt.xlabel('Time (ms)', fontsize=12)
plt.ylabel('Neuron index', fontsize=12)
plt.title('Raster plot of neuron spikes', fontsize=14)
plt.tight_layout()
plt.show()
#plot the raster plot for neuron group
plt.figure(figsize=(10, 6), dpi=150)
plt.plot(monitor_s.t/ms, monitor_s.i, 'k|', markersize= 3)
plt.xlabel('Time (ms)', fontsize=12)
plt.ylabel('Neuron index', fontsize=12)
plt.title('Raster plot of neuron spikes', fontsize=14)
plt.tight_layout()
plt.xlim(0, 4000)
plt.show()
What you have already tried
saving the brian2 object : have’nt tried anything yet.
For single neuron type firing rate average : I have tried chopping off the numpy array with time stamps. For example, unpacking the whole spike time and subtracting 2000, 4000, 6000 etc and pool them. But it is very messy.
Expected output (if relevant)
an array of Nxm , where N = 100 (number of neuron) x m = int(2000/dt) (number of time steps). Each row giving the Average firing rate for single neuron