Skip to content

Commit

Permalink
Merge pull request #774 from apdavison/brian-improvements
Browse files Browse the repository at this point in the history
Improvements to the pyNN.brian2 module
  • Loading branch information
apdavison committed Feb 4, 2023
2 parents ddfd58f + 7b8cebf commit 1b9694f
Show file tree
Hide file tree
Showing 10 changed files with 608 additions and 328 deletions.
9 changes: 6 additions & 3 deletions pyNN/brian2/populations.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@ def _get_parameters(self, *names):
`names` should be PyNN names
"""
def _get_component_parameters(component, names, component_label=None):
kwargs = {}
if component_label:
kwargs["suffix"] = component_label
if component.computed_parameters_include(names):
# need all parameters in order to calculate values
native_names = component.get_native_names()
native_names = component.get_native_names(**kwargs)
else:
native_names = component.get_native_names(*names, suffix=component_label)
native_names = component.get_native_names(*names, **kwargs)
native_parameter_space = self._get_native_parameters(*native_names)
if component_label:
ps = component.reverse_translate(native_parameter_space, suffix=component_label)
Expand Down Expand Up @@ -160,7 +163,7 @@ def _set_initial_value_array(self, variable, value):
D = self.celltype.state_variable_translations[variable]
pname = D['translated_name']
if callable(D['forward_transform']):
pval = D['forward_transform'](value) # (value)
pval = D['forward_transform'](**{variable: value})
else:
pval = eval(D['forward_transform'], globals(), {variable: value})
pval = pval.evaluate(simplify=False)
Expand Down
4 changes: 2 additions & 2 deletions pyNN/brian2/recording.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ def _get_all_signals(self, variable, ids, clear=False):
values = getattr(device, varname).T
else:
raise NotImplementedError # todo - construct a mask to get only the desired signals
translations = self.population.celltype.state_variable_translations
values = translations[variable]['reverse_transform'](values)
translations = self.population.celltype.state_variable_translations[variable]
values = translations['reverse_transform'](**{translations['translated_name']: values})
# because we use `when='end'`, need to add the value at the beginning of the run
tmp = np.empty((values.shape[0] + 1, values.shape[1]))
tmp[1:, :] = values
Expand Down
163 changes: 81 additions & 82 deletions pyNN/brian2/standardmodels/cells.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,43 +73,43 @@


leaky_iaf_translations = build_translations(
('v_rest', 'v_rest', lambda **p: p["v_rest"] * mV, lambda **p: p["v_rest"] / mV),
('v_reset', 'v_reset', lambda **p: p["v_reset"] * mV, lambda **p: p["v_reset"] / mV),
('cm', 'c_m', lambda **p: p["cm"] * nF, lambda **p: p["c_m"] / nF),
('tau_m', 'tau_m', lambda **p: p["tau_m"] * ms, lambda **p: p["tau_m"] / ms),
('tau_refrac', 'tau_refrac', lambda **p: p["tau_refrac"] * ms, lambda **p: p["tau_refrac"] / ms),
('v_thresh', 'v_thresh', lambda **p: p["v_thresh"] * mV, lambda **p: p["v_thresh"] / mV),
('i_offset', 'i_offset', lambda **p: p["i_offset"] * nA, lambda **p: p["i_offset"] / nA))
('v_rest', 'v_rest', mV),
('v_reset', 'v_reset', mV),
('cm', 'c_m', nF),
('tau_m', 'tau_m', ms),
('tau_refrac', 'tau_refrac', ms),
('v_thresh', 'v_thresh', mV),
('i_offset', 'i_offset', nA))

adexp_iaf_translations = build_translations(
('v_rest', 'v_rest', lambda **p: p["v_rest"] * mV, lambda **p: p["v_rest"] / mV),
('v_reset', 'v_reset', lambda **p: p["v_reset"] * mV, lambda **p: p["v_reset"] / mV),
('cm', 'c_m', lambda **p: p["cm"] * nF, lambda **p: p["c_m"] / nF),
('tau_m', 'tau_m', lambda **p: p["tau_m"] * ms, lambda **p: p["tau_m"] / ms),
('tau_refrac', 'tau_refrac', lambda **p: p["tau_refrac"] * ms, lambda **p: p["tau_refrac"] / ms),
('v_thresh', 'v_thresh', lambda **p: p["v_thresh"] * mV, lambda **p: p["v_thresh"] / mV),
('i_offset', 'i_offset', lambda **p: p["i_offset"] * nA, lambda **p: p["i_offset"] / nA),
('a', 'a', lambda **p: p["a"] * nS, lambda **p: p["a"] / nS),
('b', 'b', lambda **p: p["b"] * nA, lambda **p: p["b"] / nA),
('delta_T', 'delta_T', lambda **p: p["delta_T"] * mV, lambda **p: p["delta_T"] / mV),
('tau_w', 'tau_w', lambda **p: p["tau_w"] * ms, lambda **p: p["tau_w"] / ms),
('v_spike', 'v_spike', lambda **p: p["v_spike"] * mV, lambda **p: p["v_spike"] / mV))
('v_rest', 'v_rest', mV),
('v_reset', 'v_reset', mV),
('cm', 'c_m', nF),
('tau_m', 'tau_m', ms),
('tau_refrac', 'tau_refrac', ms),
('v_thresh', 'v_thresh', mV),
('i_offset', 'i_offset', nA),
('a', 'a', nS),
('b', 'b', nA),
('delta_T', 'delta_T', mV),
('tau_w', 'tau_w', ms),
('v_spike', 'v_spike', mV))

adapt_iaf_translations = build_translations(
('v_rest', 'v_rest', lambda **p: p["v_rest"] * mV, lambda **p: p["v_rest"] / mV),
('v_reset', 'v_reset', lambda **p: p["v_reset"] * mV, lambda **p: p["v_reset"] / mV),
('cm', 'c_m', lambda **p: p["cm"] * nF, lambda **p: p["c_m"] / nF),
('tau_m', 'tau_m', lambda **p: p["tau_m"] * ms, lambda **p: p["tau_m"] / ms),
('tau_refrac', 'tau_refrac', lambda **p: p["tau_refrac"] * ms, lambda **p: p["tau_refrac"] / ms),
('v_thresh', 'v_thresh', lambda **p: p["v_thresh"] * mV, lambda **p: p["v_thresh"] / mV),
('i_offset', 'i_offset', lambda **p: p["i_offset"] * nA, lambda **p: p["i_offset"] / nA),
('tau_sfa', 'tau_s', lambda **p: p["tau_sfa"] * ms, lambda **p: p["tau_s"] / ms),
('e_rev_sfa', 'E_s', lambda **p: p["e_rev_sfa"] * mV, lambda **p: p["E_s"] / mV),
('q_sfa', 'q_s', lambda **p: p["q_sfa"] * nS, lambda **p: p["q_s"] / nS),
('v_rest', 'v_rest', mV),
('v_reset', 'v_reset', mV),
('cm', 'c_m', nF),
('tau_m', 'tau_m', ms),
('tau_refrac', 'tau_refrac', ms),
('v_thresh', 'v_thresh', mV),
('i_offset', 'i_offset', nA),
('tau_sfa', 'tau_s', ms),
('e_rev_sfa', 'E_s', mV),
('q_sfa', 'q_s', nS),
# should we uS for consistency of PyNN unit system?
('tau_rr', 'tau_r', lambda **p: p["tau_rr"] * ms, lambda **p: p["tau_r"] / ms),
('e_rev_rr', 'E_r', lambda **p: p["e_rev_rr"] * mV, lambda **p: p["E_r"] / mV),
('q_rr', 'q_r', lambda **p: p["q_rr"] * nS, lambda **p: p["q_r"] / nS))
('tau_rr', 'tau_r', ms),
('e_rev_rr', 'E_r', mV),
('q_rr', 'q_r', nS))


class IF_curr_alpha(cells.IF_curr_alpha):
Expand Down Expand Up @@ -137,7 +137,7 @@ class IF_curr_delta(cells.IF_curr_delta):
eqs = leaky_iaf + voltage_step_synapses
translations = deepcopy(leaky_iaf_translations)
state_variable_translations = build_translations(
('v', 'v', lambda p: p * mV, lambda p: p / mV),
('v', 'v', mV),
)
post_synaptic_variables = {'excitatory': 'v', 'inhibitory': 'v'}
brian2_model = ThresholdNeuronGroup
Expand Down Expand Up @@ -169,10 +169,10 @@ class EIF_cond_exp_isfa_ista(cells.EIF_cond_exp_isfa_ista):
translations = deepcopy(adexp_iaf_translations)
translations.update(conductance_based_synapse_translations)
state_variable_translations = build_translations(
('v', 'v', lambda p: p * mV, lambda p: p / mV),
('w', 'w', lambda p: p * nA, lambda p: p / nA),
('gsyn_exc', 'ge', lambda p: p * uS, lambda p: p / uS),
('gsyn_inh', 'gi', lambda p: p * uS, lambda p: p / uS))
('v', 'v', mV),
('w', 'w', nA),
('gsyn_exc', 'ge', uS),
('gsyn_inh', 'gi', uS))

post_synaptic_variables = {'excitatory': 'ge', 'inhibitory': 'gi'}
brian2_model = AdaptiveNeuronGroup
Expand All @@ -184,10 +184,10 @@ class EIF_cond_alpha_isfa_ista(cells.EIF_cond_alpha_isfa_ista):
translations = deepcopy(adexp_iaf_translations)
translations.update(conductance_based_synapse_translations)
state_variable_translations = build_translations(
('v', 'v', lambda p: p * mV, lambda p: p / mV),
('w', 'w', lambda p: p * nA, lambda p: p / nA),
('gsyn_exc', 'ge', lambda p: p * uS, lambda p: p / uS),
('gsyn_inh', 'gi', lambda p: p * uS, lambda p: p / uS))
('v', 'v', mV),
('w', 'w', nA),
('gsyn_exc', 'ge', uS),
('gsyn_inh', 'gi', uS))
post_synaptic_variables = {'excitatory': 'ge', 'inhibitory': 'gi'}
brian2_model = AdaptiveNeuronGroup

Expand All @@ -196,7 +196,7 @@ class LIF(cells.LIF):
eqs = leaky_iaf
translations = deepcopy(leaky_iaf_translations)
state_variable_translations = build_translations(
('v', 'v', lambda p: p * mV, lambda p: p / mV),
('v', 'v', mV),
)
brian2_model = ThresholdNeuronGroup

Expand All @@ -205,8 +205,8 @@ class AdExp(cells.AdExp):
eqs = adexp_iaf
translations = deepcopy(adexp_iaf_translations)
state_variable_translations = build_translations(
('v', 'v', lambda p: p * mV, lambda p: p / mV),
('w', 'w', lambda p: p * nA, lambda p: p / nA)
('v', 'v', mV),
('w', 'w', nA)
)
brian2_model = AdaptiveNeuronGroup

Expand All @@ -216,12 +216,11 @@ class IF_cond_exp_gsfa_grr(cells.IF_cond_exp_gsfa_grr):
translations = deepcopy(adapt_iaf_translations)
translations.update(conductance_based_synapse_translations)
state_variable_translations = build_translations(
('v', 'v', lambda p: p * mV, lambda p: p / mV),
('g_s', 'g_s', lambda p: p * uS, lambda p: p / uS),
# todo: should be uS - needs changed for all back-ends
('g_r', 'g_r', lambda p: p * uS, lambda p: p / uS),
('gsyn_exc', 'ge', lambda p: p * uS, lambda p: p / uS),
('gsyn_inh', 'gi', lambda p: p * uS, lambda p: p / uS))
('v', 'v', mV),
('g_s', 'g_s', uS),
('g_r', 'g_r', uS),
('gsyn_exc', 'ge', uS),
('gsyn_inh', 'gi', uS))
post_synaptic_variables = {'excitatory': 'ge', 'inhibitory': 'gi'}
brian2_model = AdaptiveNeuronGroup2

Expand All @@ -230,30 +229,30 @@ class HH_cond_exp(cells.HH_cond_exp):
__doc__ = cells.HH_cond_exp.__doc__

translations = build_translations(
('gbar_Na', 'gbar_Na', lambda **p: p["gbar_Na"] * uS, lambda **p: p["gbar_Na"] / uS),
('gbar_K', 'gbar_K', lambda **p: p["gbar_K"] * uS, lambda **p: p["gbar_K"] / uS),
('g_leak', 'g_leak', lambda **p: p["g_leak"] * uS, lambda **p: p["g_leak"] / uS),
('cm', 'c_m', lambda **p: p["cm"] * nF, lambda **p: p["c_m"] / nF),
('v_offset', 'v_offset', lambda **p: p["v_offset"] * mV, lambda **p: p["v_offset"] / mV),
('e_rev_Na', 'e_rev_Na', lambda **p: p["e_rev_Na"] * mV, lambda **p: p["e_rev_Na"] / mV),
('e_rev_K', 'e_rev_K', lambda **p: p["e_rev_K"] * mV, lambda **p: p["e_rev_K"] / mV),
('e_rev_leak', 'e_rev_leak', lambda **p: p["e_rev_leak"] * mV, lambda **p: p["e_rev_leak"] / mV),
('e_rev_E', 'e_rev_e', lambda **p: p["e_rev_E"] * mV, lambda **p: p["e_rev_e"] / mV),
('e_rev_I', 'e_rev_i', lambda **p: p["e_rev_I"] * mV, lambda **p: p["e_rev_i"] / mV),
('tau_syn_E', 'tau_syn_e', lambda **p: p["tau_syn_E"] * ms, lambda **p: p["tau_syn_e"] / ms),
('tau_syn_I', 'tau_syn_i', lambda **p: p["tau_syn_I"] * ms, lambda **p: p["tau_syn_i"] / ms),
('i_offset', 'i_offset', lambda **p: p["i_offset"] * nA, lambda **p: p["i_offset"] / nA))
('gbar_Na', 'gbar_Na', uS),
('gbar_K', 'gbar_K', uS),
('g_leak', 'g_leak', uS),
('cm', 'c_m', nF),
('v_offset', 'v_offset', mV),
('e_rev_Na', 'e_rev_Na', mV),
('e_rev_K', 'e_rev_K', mV),
('e_rev_leak', 'e_rev_leak', mV),
('e_rev_E', 'e_rev_e', mV),
('e_rev_I', 'e_rev_i', mV),
('tau_syn_E', 'tau_syn_e', ms),
('tau_syn_I', 'tau_syn_i', ms),
('i_offset', 'i_offset', nA))
eqs = brian2.Equations('''
dv/dt = (g_leak*(e_rev_leak-v) - gbar_Na*(m*m*m)*h*(v-e_rev_Na) - gbar_K*(n*n*n*n)*(v-e_rev_K) + i_syn + i_offset + i_inj)/c_m : volt # noqa: E501
dm/dt = (alpham*(1-m)-betam*m) : 1
dn/dt = (alphan*(1-n)-betan*n) : 1
dh/dt = (alphah*(1-h)-betah*h) : 1
alpham = (0.32/mV)*(13*mV-v+v_offset)/(exp((13*mV-v+v_offset)/(4*mV))-1.)/ms : Hz
betam = (0.28/mV)*(v-v_offset-40*mV)/(exp((v-v_offset-40*mV)/(5*mV))-1)/ms : Hz
alphah = 0.128*exp((17*mV-v+v_offset)/(18*mV))/ms : Hz
betah = 4./(1+exp((40*mV-v+v_offset)/(5*mV)))/ms : Hz
alphah = 0.128*exp((17*mV-v+v_offset)/(18*mV))/ms : Hz
betah = 4./(1+exp((40*mV-v+v_offset)/(5*mV)))/ms : Hz
alphan = (0.032/mV)*(15*mV-v+v_offset)/(exp((15*mV-v+v_offset)/(5*mV))-1.)/ms : Hz
betan = .5*exp((10*mV-v+v_offset)/(40*mV))/ms : Hz
betan = .5*exp((10*mV-v+v_offset)/(40*mV))/ms : Hz
e_rev_Na : volt
e_rev_K : volt
e_rev_leak : volt
Expand All @@ -268,24 +267,24 @@ class HH_cond_exp(cells.HH_cond_exp):
recordable = ['spikes', 'v', 'gsyn_exc', 'gsyn_inh', 'm', 'n', 'h']
post_synaptic_variables = {'excitatory': 'ge', 'inhibitory': 'gi'}
state_variable_translations = build_translations(
('v', 'v', lambda p: p * mV, lambda p: p / mV),
('gsyn_exc', 'ge', lambda p: p * uS, lambda p: p / uS),
('gsyn_inh', 'gi', lambda p: p * uS, lambda p: p / uS),
('h', 'h', lambda p: p, lambda p: p),
('m', 'm', lambda p: p, lambda p: p),
('n', 'n', lambda p: p, lambda p: p))
('v', 'v', mV),
('gsyn_exc', 'ge', uS),
('gsyn_inh', 'gi', uS),
('h', 'h'),
('m', 'm'),
('n', 'n'))
brian2_model = BiophysicalNeuronGroup


class Izhikevich(cells.Izhikevich):
__doc__ = cells.Izhikevich.__doc__

translations = build_translations(
('a', 'a', lambda **p: p["a"] * (1 / ms), lambda **p: p["a"] / (1 / ms)),
('b', 'b', lambda **p: p["b"] * (1 / ms), lambda **p: p["b"] / (1 / ms)),
('c', 'v_reset', lambda **p: p["c"] * mV, lambda **p: p["v_reset"] / mV),
('d', 'd', lambda **p: p["d"] * (mV / ms), lambda **p: p["d"] / (mV / ms)),
('i_offset', 'i_offset', lambda **p: p["i_offset"] * nA, lambda **p: p["i_offset"] / nA))
('a', 'a', 1 / ms),
('b', 'b', 1 / ms),
('c', 'v_reset', mV),
('d', 'd', mV / ms),
('i_offset', 'i_offset', nA))
eqs = brian2.Equations('''
dv/dt = (0.04/ms/mV)*v*v + (5/ms)*v + 140*mV/ms - u + (i_offset + i_inj)/pF : volt (unless refractory) # noqa: E501
du/dt = a*(b*v-u) : volt/second (unless refractory)
Expand All @@ -298,18 +297,18 @@ class Izhikevich(cells.Izhikevich):
''')
post_synaptic_variables = {'excitatory': 'v', 'inhibitory': 'v'}
state_variable_translations = build_translations(
('v', 'v', lambda p: p * mV, lambda p: p / mV),
('u', 'u', lambda p: p * (mV / ms), lambda p: p / (mV / ms)))
('v', 'v', mV),
('u', 'u', mV / ms))
brian2_model = IzhikevichNeuronGroup


class SpikeSourcePoisson(cells.SpikeSourcePoisson):
__doc__ = cells.SpikeSourcePoisson.__doc__

translations = build_translations(
('rate', 'firing_rate', lambda **p: p["rate"] * Hz, lambda **p: p["firing_rate"] / Hz),
('start', 'start_time', lambda **p: p["start"] * ms, lambda **p: p["start_time"] / ms),
('duration', 'duration', lambda **p: p["duration"] * ms, lambda **p: p["duration"] / ms),
('rate', 'firing_rate', Hz),
('start', 'start_time', ms),
('duration', 'duration', ms),
)
eqs = None
brian2_model = PoissonGroup
Expand Down

0 comments on commit 1b9694f

Please sign in to comment.