Skip to content

Commit 1b9694f

Browse files
authored
Merge pull request #774 from apdavison/brian-improvements
Improvements to the pyNN.brian2 module
2 parents ddfd58f + 7b8cebf commit 1b9694f

File tree

10 files changed

+608
-328
lines changed

10 files changed

+608
-328
lines changed

pyNN/brian2/populations.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@ def _get_parameters(self, *names):
2727
`names` should be PyNN names
2828
"""
2929
def _get_component_parameters(component, names, component_label=None):
30+
kwargs = {}
31+
if component_label:
32+
kwargs["suffix"] = component_label
3033
if component.computed_parameters_include(names):
3134
# need all parameters in order to calculate values
32-
native_names = component.get_native_names()
35+
native_names = component.get_native_names(**kwargs)
3336
else:
34-
native_names = component.get_native_names(*names, suffix=component_label)
37+
native_names = component.get_native_names(*names, **kwargs)
3538
native_parameter_space = self._get_native_parameters(*native_names)
3639
if component_label:
3740
ps = component.reverse_translate(native_parameter_space, suffix=component_label)
@@ -160,7 +163,7 @@ def _set_initial_value_array(self, variable, value):
160163
D = self.celltype.state_variable_translations[variable]
161164
pname = D['translated_name']
162165
if callable(D['forward_transform']):
163-
pval = D['forward_transform'](value) # (value)
166+
pval = D['forward_transform'](**{variable: value})
164167
else:
165168
pval = eval(D['forward_transform'], globals(), {variable: value})
166169
pval = pval.evaluate(simplify=False)

pyNN/brian2/recording.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ def _get_all_signals(self, variable, ids, clear=False):
8787
values = getattr(device, varname).T
8888
else:
8989
raise NotImplementedError # todo - construct a mask to get only the desired signals
90-
translations = self.population.celltype.state_variable_translations
91-
values = translations[variable]['reverse_transform'](values)
90+
translations = self.population.celltype.state_variable_translations[variable]
91+
values = translations['reverse_transform'](**{translations['translated_name']: values})
9292
# because we use `when='end'`, need to add the value at the beginning of the run
9393
tmp = np.empty((values.shape[0] + 1, values.shape[1]))
9494
tmp[1:, :] = values

pyNN/brian2/standardmodels/cells.py

Lines changed: 81 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -73,43 +73,43 @@
7373

7474

7575
leaky_iaf_translations = build_translations(
76-
('v_rest', 'v_rest', lambda **p: p["v_rest"] * mV, lambda **p: p["v_rest"] / mV),
77-
('v_reset', 'v_reset', lambda **p: p["v_reset"] * mV, lambda **p: p["v_reset"] / mV),
78-
('cm', 'c_m', lambda **p: p["cm"] * nF, lambda **p: p["c_m"] / nF),
79-
('tau_m', 'tau_m', lambda **p: p["tau_m"] * ms, lambda **p: p["tau_m"] / ms),
80-
('tau_refrac', 'tau_refrac', lambda **p: p["tau_refrac"] * ms, lambda **p: p["tau_refrac"] / ms),
81-
('v_thresh', 'v_thresh', lambda **p: p["v_thresh"] * mV, lambda **p: p["v_thresh"] / mV),
82-
('i_offset', 'i_offset', lambda **p: p["i_offset"] * nA, lambda **p: p["i_offset"] / nA))
76+
('v_rest', 'v_rest', mV),
77+
('v_reset', 'v_reset', mV),
78+
('cm', 'c_m', nF),
79+
('tau_m', 'tau_m', ms),
80+
('tau_refrac', 'tau_refrac', ms),
81+
('v_thresh', 'v_thresh', mV),
82+
('i_offset', 'i_offset', nA))
8383

8484
adexp_iaf_translations = build_translations(
85-
('v_rest', 'v_rest', lambda **p: p["v_rest"] * mV, lambda **p: p["v_rest"] / mV),
86-
('v_reset', 'v_reset', lambda **p: p["v_reset"] * mV, lambda **p: p["v_reset"] / mV),
87-
('cm', 'c_m', lambda **p: p["cm"] * nF, lambda **p: p["c_m"] / nF),
88-
('tau_m', 'tau_m', lambda **p: p["tau_m"] * ms, lambda **p: p["tau_m"] / ms),
89-
('tau_refrac', 'tau_refrac', lambda **p: p["tau_refrac"] * ms, lambda **p: p["tau_refrac"] / ms),
90-
('v_thresh', 'v_thresh', lambda **p: p["v_thresh"] * mV, lambda **p: p["v_thresh"] / mV),
91-
('i_offset', 'i_offset', lambda **p: p["i_offset"] * nA, lambda **p: p["i_offset"] / nA),
92-
('a', 'a', lambda **p: p["a"] * nS, lambda **p: p["a"] / nS),
93-
('b', 'b', lambda **p: p["b"] * nA, lambda **p: p["b"] / nA),
94-
('delta_T', 'delta_T', lambda **p: p["delta_T"] * mV, lambda **p: p["delta_T"] / mV),
95-
('tau_w', 'tau_w', lambda **p: p["tau_w"] * ms, lambda **p: p["tau_w"] / ms),
96-
('v_spike', 'v_spike', lambda **p: p["v_spike"] * mV, lambda **p: p["v_spike"] / mV))
85+
('v_rest', 'v_rest', mV),
86+
('v_reset', 'v_reset', mV),
87+
('cm', 'c_m', nF),
88+
('tau_m', 'tau_m', ms),
89+
('tau_refrac', 'tau_refrac', ms),
90+
('v_thresh', 'v_thresh', mV),
91+
('i_offset', 'i_offset', nA),
92+
('a', 'a', nS),
93+
('b', 'b', nA),
94+
('delta_T', 'delta_T', mV),
95+
('tau_w', 'tau_w', ms),
96+
('v_spike', 'v_spike', mV))
9797

9898
adapt_iaf_translations = build_translations(
99-
('v_rest', 'v_rest', lambda **p: p["v_rest"] * mV, lambda **p: p["v_rest"] / mV),
100-
('v_reset', 'v_reset', lambda **p: p["v_reset"] * mV, lambda **p: p["v_reset"] / mV),
101-
('cm', 'c_m', lambda **p: p["cm"] * nF, lambda **p: p["c_m"] / nF),
102-
('tau_m', 'tau_m', lambda **p: p["tau_m"] * ms, lambda **p: p["tau_m"] / ms),
103-
('tau_refrac', 'tau_refrac', lambda **p: p["tau_refrac"] * ms, lambda **p: p["tau_refrac"] / ms),
104-
('v_thresh', 'v_thresh', lambda **p: p["v_thresh"] * mV, lambda **p: p["v_thresh"] / mV),
105-
('i_offset', 'i_offset', lambda **p: p["i_offset"] * nA, lambda **p: p["i_offset"] / nA),
106-
('tau_sfa', 'tau_s', lambda **p: p["tau_sfa"] * ms, lambda **p: p["tau_s"] / ms),
107-
('e_rev_sfa', 'E_s', lambda **p: p["e_rev_sfa"] * mV, lambda **p: p["E_s"] / mV),
108-
('q_sfa', 'q_s', lambda **p: p["q_sfa"] * nS, lambda **p: p["q_s"] / nS),
99+
('v_rest', 'v_rest', mV),
100+
('v_reset', 'v_reset', mV),
101+
('cm', 'c_m', nF),
102+
('tau_m', 'tau_m', ms),
103+
('tau_refrac', 'tau_refrac', ms),
104+
('v_thresh', 'v_thresh', mV),
105+
('i_offset', 'i_offset', nA),
106+
('tau_sfa', 'tau_s', ms),
107+
('e_rev_sfa', 'E_s', mV),
108+
('q_sfa', 'q_s', nS),
109109
# should we uS for consistency of PyNN unit system?
110-
('tau_rr', 'tau_r', lambda **p: p["tau_rr"] * ms, lambda **p: p["tau_r"] / ms),
111-
('e_rev_rr', 'E_r', lambda **p: p["e_rev_rr"] * mV, lambda **p: p["E_r"] / mV),
112-
('q_rr', 'q_r', lambda **p: p["q_rr"] * nS, lambda **p: p["q_r"] / nS))
110+
('tau_rr', 'tau_r', ms),
111+
('e_rev_rr', 'E_r', mV),
112+
('q_rr', 'q_r', nS))
113113

114114

115115
class IF_curr_alpha(cells.IF_curr_alpha):
@@ -137,7 +137,7 @@ class IF_curr_delta(cells.IF_curr_delta):
137137
eqs = leaky_iaf + voltage_step_synapses
138138
translations = deepcopy(leaky_iaf_translations)
139139
state_variable_translations = build_translations(
140-
('v', 'v', lambda p: p * mV, lambda p: p / mV),
140+
('v', 'v', mV),
141141
)
142142
post_synaptic_variables = {'excitatory': 'v', 'inhibitory': 'v'}
143143
brian2_model = ThresholdNeuronGroup
@@ -169,10 +169,10 @@ class EIF_cond_exp_isfa_ista(cells.EIF_cond_exp_isfa_ista):
169169
translations = deepcopy(adexp_iaf_translations)
170170
translations.update(conductance_based_synapse_translations)
171171
state_variable_translations = build_translations(
172-
('v', 'v', lambda p: p * mV, lambda p: p / mV),
173-
('w', 'w', lambda p: p * nA, lambda p: p / nA),
174-
('gsyn_exc', 'ge', lambda p: p * uS, lambda p: p / uS),
175-
('gsyn_inh', 'gi', lambda p: p * uS, lambda p: p / uS))
172+
('v', 'v', mV),
173+
('w', 'w', nA),
174+
('gsyn_exc', 'ge', uS),
175+
('gsyn_inh', 'gi', uS))
176176

177177
post_synaptic_variables = {'excitatory': 'ge', 'inhibitory': 'gi'}
178178
brian2_model = AdaptiveNeuronGroup
@@ -184,10 +184,10 @@ class EIF_cond_alpha_isfa_ista(cells.EIF_cond_alpha_isfa_ista):
184184
translations = deepcopy(adexp_iaf_translations)
185185
translations.update(conductance_based_synapse_translations)
186186
state_variable_translations = build_translations(
187-
('v', 'v', lambda p: p * mV, lambda p: p / mV),
188-
('w', 'w', lambda p: p * nA, lambda p: p / nA),
189-
('gsyn_exc', 'ge', lambda p: p * uS, lambda p: p / uS),
190-
('gsyn_inh', 'gi', lambda p: p * uS, lambda p: p / uS))
187+
('v', 'v', mV),
188+
('w', 'w', nA),
189+
('gsyn_exc', 'ge', uS),
190+
('gsyn_inh', 'gi', uS))
191191
post_synaptic_variables = {'excitatory': 'ge', 'inhibitory': 'gi'}
192192
brian2_model = AdaptiveNeuronGroup
193193

@@ -196,7 +196,7 @@ class LIF(cells.LIF):
196196
eqs = leaky_iaf
197197
translations = deepcopy(leaky_iaf_translations)
198198
state_variable_translations = build_translations(
199-
('v', 'v', lambda p: p * mV, lambda p: p / mV),
199+
('v', 'v', mV),
200200
)
201201
brian2_model = ThresholdNeuronGroup
202202

@@ -205,8 +205,8 @@ class AdExp(cells.AdExp):
205205
eqs = adexp_iaf
206206
translations = deepcopy(adexp_iaf_translations)
207207
state_variable_translations = build_translations(
208-
('v', 'v', lambda p: p * mV, lambda p: p / mV),
209-
('w', 'w', lambda p: p * nA, lambda p: p / nA)
208+
('v', 'v', mV),
209+
('w', 'w', nA)
210210
)
211211
brian2_model = AdaptiveNeuronGroup
212212

@@ -216,12 +216,11 @@ class IF_cond_exp_gsfa_grr(cells.IF_cond_exp_gsfa_grr):
216216
translations = deepcopy(adapt_iaf_translations)
217217
translations.update(conductance_based_synapse_translations)
218218
state_variable_translations = build_translations(
219-
('v', 'v', lambda p: p * mV, lambda p: p / mV),
220-
('g_s', 'g_s', lambda p: p * uS, lambda p: p / uS),
221-
# todo: should be uS - needs changed for all back-ends
222-
('g_r', 'g_r', lambda p: p * uS, lambda p: p / uS),
223-
('gsyn_exc', 'ge', lambda p: p * uS, lambda p: p / uS),
224-
('gsyn_inh', 'gi', lambda p: p * uS, lambda p: p / uS))
219+
('v', 'v', mV),
220+
('g_s', 'g_s', uS),
221+
('g_r', 'g_r', uS),
222+
('gsyn_exc', 'ge', uS),
223+
('gsyn_inh', 'gi', uS))
225224
post_synaptic_variables = {'excitatory': 'ge', 'inhibitory': 'gi'}
226225
brian2_model = AdaptiveNeuronGroup2
227226

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

232231
translations = build_translations(
233-
('gbar_Na', 'gbar_Na', lambda **p: p["gbar_Na"] * uS, lambda **p: p["gbar_Na"] / uS),
234-
('gbar_K', 'gbar_K', lambda **p: p["gbar_K"] * uS, lambda **p: p["gbar_K"] / uS),
235-
('g_leak', 'g_leak', lambda **p: p["g_leak"] * uS, lambda **p: p["g_leak"] / uS),
236-
('cm', 'c_m', lambda **p: p["cm"] * nF, lambda **p: p["c_m"] / nF),
237-
('v_offset', 'v_offset', lambda **p: p["v_offset"] * mV, lambda **p: p["v_offset"] / mV),
238-
('e_rev_Na', 'e_rev_Na', lambda **p: p["e_rev_Na"] * mV, lambda **p: p["e_rev_Na"] / mV),
239-
('e_rev_K', 'e_rev_K', lambda **p: p["e_rev_K"] * mV, lambda **p: p["e_rev_K"] / mV),
240-
('e_rev_leak', 'e_rev_leak', lambda **p: p["e_rev_leak"] * mV, lambda **p: p["e_rev_leak"] / mV),
241-
('e_rev_E', 'e_rev_e', lambda **p: p["e_rev_E"] * mV, lambda **p: p["e_rev_e"] / mV),
242-
('e_rev_I', 'e_rev_i', lambda **p: p["e_rev_I"] * mV, lambda **p: p["e_rev_i"] / mV),
243-
('tau_syn_E', 'tau_syn_e', lambda **p: p["tau_syn_E"] * ms, lambda **p: p["tau_syn_e"] / ms),
244-
('tau_syn_I', 'tau_syn_i', lambda **p: p["tau_syn_I"] * ms, lambda **p: p["tau_syn_i"] / ms),
245-
('i_offset', 'i_offset', lambda **p: p["i_offset"] * nA, lambda **p: p["i_offset"] / nA))
232+
('gbar_Na', 'gbar_Na', uS),
233+
('gbar_K', 'gbar_K', uS),
234+
('g_leak', 'g_leak', uS),
235+
('cm', 'c_m', nF),
236+
('v_offset', 'v_offset', mV),
237+
('e_rev_Na', 'e_rev_Na', mV),
238+
('e_rev_K', 'e_rev_K', mV),
239+
('e_rev_leak', 'e_rev_leak', mV),
240+
('e_rev_E', 'e_rev_e', mV),
241+
('e_rev_I', 'e_rev_i', mV),
242+
('tau_syn_E', 'tau_syn_e', ms),
243+
('tau_syn_I', 'tau_syn_i', ms),
244+
('i_offset', 'i_offset', nA))
246245
eqs = brian2.Equations('''
247246
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
248247
dm/dt = (alpham*(1-m)-betam*m) : 1
249248
dn/dt = (alphan*(1-n)-betan*n) : 1
250249
dh/dt = (alphah*(1-h)-betah*h) : 1
251250
alpham = (0.32/mV)*(13*mV-v+v_offset)/(exp((13*mV-v+v_offset)/(4*mV))-1.)/ms : Hz
252251
betam = (0.28/mV)*(v-v_offset-40*mV)/(exp((v-v_offset-40*mV)/(5*mV))-1)/ms : Hz
253-
alphah = 0.128*exp((17*mV-v+v_offset)/(18*mV))/ms : Hz
254-
betah = 4./(1+exp((40*mV-v+v_offset)/(5*mV)))/ms : Hz
252+
alphah = 0.128*exp((17*mV-v+v_offset)/(18*mV))/ms : Hz
253+
betah = 4./(1+exp((40*mV-v+v_offset)/(5*mV)))/ms : Hz
255254
alphan = (0.032/mV)*(15*mV-v+v_offset)/(exp((15*mV-v+v_offset)/(5*mV))-1.)/ms : Hz
256-
betan = .5*exp((10*mV-v+v_offset)/(40*mV))/ms : Hz
255+
betan = .5*exp((10*mV-v+v_offset)/(40*mV))/ms : Hz
257256
e_rev_Na : volt
258257
e_rev_K : volt
259258
e_rev_leak : volt
@@ -268,24 +267,24 @@ class HH_cond_exp(cells.HH_cond_exp):
268267
recordable = ['spikes', 'v', 'gsyn_exc', 'gsyn_inh', 'm', 'n', 'h']
269268
post_synaptic_variables = {'excitatory': 'ge', 'inhibitory': 'gi'}
270269
state_variable_translations = build_translations(
271-
('v', 'v', lambda p: p * mV, lambda p: p / mV),
272-
('gsyn_exc', 'ge', lambda p: p * uS, lambda p: p / uS),
273-
('gsyn_inh', 'gi', lambda p: p * uS, lambda p: p / uS),
274-
('h', 'h', lambda p: p, lambda p: p),
275-
('m', 'm', lambda p: p, lambda p: p),
276-
('n', 'n', lambda p: p, lambda p: p))
270+
('v', 'v', mV),
271+
('gsyn_exc', 'ge', uS),
272+
('gsyn_inh', 'gi', uS),
273+
('h', 'h'),
274+
('m', 'm'),
275+
('n', 'n'))
277276
brian2_model = BiophysicalNeuronGroup
278277

279278

280279
class Izhikevich(cells.Izhikevich):
281280
__doc__ = cells.Izhikevich.__doc__
282281

283282
translations = build_translations(
284-
('a', 'a', lambda **p: p["a"] * (1 / ms), lambda **p: p["a"] / (1 / ms)),
285-
('b', 'b', lambda **p: p["b"] * (1 / ms), lambda **p: p["b"] / (1 / ms)),
286-
('c', 'v_reset', lambda **p: p["c"] * mV, lambda **p: p["v_reset"] / mV),
287-
('d', 'd', lambda **p: p["d"] * (mV / ms), lambda **p: p["d"] / (mV / ms)),
288-
('i_offset', 'i_offset', lambda **p: p["i_offset"] * nA, lambda **p: p["i_offset"] / nA))
283+
('a', 'a', 1 / ms),
284+
('b', 'b', 1 / ms),
285+
('c', 'v_reset', mV),
286+
('d', 'd', mV / ms),
287+
('i_offset', 'i_offset', nA))
289288
eqs = brian2.Equations('''
290289
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
291290
du/dt = a*(b*v-u) : volt/second (unless refractory)
@@ -298,18 +297,18 @@ class Izhikevich(cells.Izhikevich):
298297
''')
299298
post_synaptic_variables = {'excitatory': 'v', 'inhibitory': 'v'}
300299
state_variable_translations = build_translations(
301-
('v', 'v', lambda p: p * mV, lambda p: p / mV),
302-
('u', 'u', lambda p: p * (mV / ms), lambda p: p / (mV / ms)))
300+
('v', 'v', mV),
301+
('u', 'u', mV / ms))
303302
brian2_model = IzhikevichNeuronGroup
304303

305304

306305
class SpikeSourcePoisson(cells.SpikeSourcePoisson):
307306
__doc__ = cells.SpikeSourcePoisson.__doc__
308307

309308
translations = build_translations(
310-
('rate', 'firing_rate', lambda **p: p["rate"] * Hz, lambda **p: p["firing_rate"] / Hz),
311-
('start', 'start_time', lambda **p: p["start"] * ms, lambda **p: p["start_time"] / ms),
312-
('duration', 'duration', lambda **p: p["duration"] * ms, lambda **p: p["duration"] / ms),
309+
('rate', 'firing_rate', Hz),
310+
('start', 'start_time', ms),
311+
('duration', 'duration', ms),
313312
)
314313
eqs = None
315314
brian2_model = PoissonGroup

0 commit comments

Comments
 (0)