# Issues with creating a neuron population inside a custom function

**URL:** <https://brian.discourse.group/t/issues-with-creating-a-neuron-population-inside-a-custom-function/1259>\
**Category:** Support\
**Created:** [18 July 2024 14:42 UTC](https://brian.discourse.group/t/issues-with-creating-a-neuron-population-inside-a-custom-function/1259 "2024-07-18T14:42:26Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![rebeccanclarke](https://avatars.discourse-cdn.com/v4/letter/r/ac8455/32.png) [@rebeccanclarke](https://brian.discourse.group/u/rebeccanclarke)\
**Post date:** [18 July 2024 14:42 UTC](https://brian.discourse.group/t/issues-with-creating-a-neuron-population-inside-a-custom-function/1259/1 "2024-07-18T14:42:26Z")

</div>

# Description of problem

My overall goal is to create a network of multiple neuron groups, each representing different neuron types within different brain regions. Therefore, I am creating custom functions inside which I am creating the neuron groups. However, I am having issues transferring variables through my own function into the NeuronGroup() function, and when I run the group I keep getting errors like '‘The identifier “tau” could not be resolved.’, even though I am sure I am defining the variables correctly.

Sometimes it will throw this error for one variable, and after re-starting everything it might throw the error for a different variable (it doesn’t seem to be consistent).

Is this something that can be done (or maybe should not be done and hence why it doesn’t work)?

Apologies if this has already been answered somewhere, I am fairly new to this!

# Minimal code to reproduce problem

### Simplified example

```
from brian2 import *

variables={'N':1, 'tau':10*ms, 'tau_2':10*ms}

def create_neuron_population(variables):
    # Parameters
    start_scope()
    
    N = variables['N']
    tau = variables['tau']
    tau_2 = variables['tau_2']
    eqs = '''
    dv/dt = (1.1-v)/tau : 1
    du/dt = (1.1 - u)/tau_2 : 1
    '''
    
    # Create a neuron group
    G = NeuronGroup(N, eqs, threshold='v>1', reset='v=0', method='exact')
    
    # Initial condition
    G.v = 'rand()'
    G.u = 0
    
    return G

G = create_neuron_population(variables)

spike_monitor = SpikeMonitor(G)
state_monitor = StateMonitor(G, 'v', record=True)

run(100*ms)

```

# What you have aready tried

Taking all the same functionality outside the custom function removes any errors.

---

<div class="post-metadata">

**Author:** ![mstimberg](https://yyz2.discourse-cdn.com/free1/user_avatar/brian.discourse.group/mstimberg/32/11_2.png) [@mstimberg](https://brian.discourse.group/u/mstimberg)\
**Post date:** [18 July 2024 15:33 UTC](https://brian.discourse.group/t/issues-with-creating-a-neuron-population-inside-a-custom-function/1259/2 "2024-07-18T15:33:44Z")

</div>

Hi @rebeccanclarke. This is a quite common issue, and we clearly need to document it better – most of our examples/tutorials/etc. are based on simple “flat” scripts where this issue does not appear. You can find some details here: [Namespaces — Brian 2 2.7.1 documentation](https://brian2.readthedocs.io/en/stable/advanced/namespaces.html)  
But shortly: the variables need to be accessible where you call the run function, not where you define the group. So your example would work if `N`, `tau`, and `tau_2` would be defined before `run`, not in the function. If you have the constants already in a dictionary, then the cleanest solution would be to not define them as normal Python variables at all, but instead use the `namespace` mechanism. If the constants are shared across groups, then you would provide this dictionary to the `run` function:

```python
run(100*ms, namespace=variables)

```

This would work in your above example, but I guess in your real use case, different neuron types have different values for e.g. `tau`. In that case, you can give the `namespace` argument to `NeuronGroup` itself. I.e., in your example above:

```python
G = NeuronGroup(N, eqs, threshold='v>1', reset='v=0', method='exact', namespace=variables)

```

(without needing to “unpack” the dictionary into variables before).

Both mechanisms can also be combined, i.e. each `NeuronGroup` has a few parameters that are specific to that group, while some parameters might be shared across all groups.

Finally, please note that for efficiency reasons, you should ideally only create separate `NeuronGroup`s if they need different _equations_, not just different _parameters_.

E.g. instead of

```python
   eqs = '''
    dv/dt = (1.1-v)/tau : 1
    du/dt = (1.1 - u)/tau_2 : 1
    '''
    G1 = NeuronGroup(N1, eqs, threshold='v>1', reset='v=0', method='exact', namespace={'tau': 10*ms, 'tau_2': 5*ms})
    G2 = NeuronGroup(N2, eqs, threshold='v>1', reset='v=0', method='exact', namespace={'tau': 20*ms, 'tau_2': 10*ms})

```

you could write:

```python
   eqs = '''
    dv/dt = (1.1-v)/tau : 1
    du/dt = (1.1 - u)/tau_2 : 1
    tau : second (constant)
    tau_2 : second (constant)
    '''
    G = NeuronGroup(N1 + N2, eqs, threshold='v>1', reset='v=0', method='exact')
    G1 = G[:N1]
    G1.tau = 10*ms
    G1.tau_2 = 5*ms
    G2 = G[N1:]
    G2.tau = 20*ms
    G2.tau_2 = 10*ms

```

Of course this won’t change anything noticeable in a simple example, but if you have a complex network, then each separate `NeuronGroup` also requires that you use separate `Synapses`, so the total number of objects that need to be generated quickly explodes.

Hope that helps a bit!

---

<div class="post-metadata">

**Author:** ![rebeccanclarke](https://avatars.discourse-cdn.com/v4/letter/r/ac8455/32.png) [@rebeccanclarke](https://brian.discourse.group/u/rebeccanclarke)\
**Post date:** [18 July 2024 16:01 UTC](https://brian.discourse.group/t/issues-with-creating-a-neuron-population-inside-a-custom-function/1259/3 "2024-07-18T16:01:12Z")

</div>

Thank you @mstimberg that is so helpful!

I was planning on using separate neuron groups for different regions because I am including different receptor types for each group. So although the basic equations are the same, the synaptic current being added to dv/dt is slightly different for each one.

Thanks again, and for the speedy response!
