# Class vs direct?

**URL:** <https://brian.discourse.group/t/class-vs-direct/1350>\
**Category:** Support\
**Tags:** network\
**Created:** [12 December 2024 15:20 UTC](https://brian.discourse.group/t/class-vs-direct/1350 "2024-12-12T15:20:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Thanh-Binh](https://yyz2.discourse-cdn.com/free1/user_avatar/brian.discourse.group/thanh-binh/32/809_2.png) [@Thanh-Binh](https://brian.discourse.group/u/Thanh-Binh)\
**Post date:** [12 December 2024 15:20 UTC](https://brian.discourse.group/t/class-vs-direct/1350/1 "2024-12-12T15:20:29Z")

</div>

# Description of problem

Dear all,  
I am new on Brian, and want to implement my network in a class and test it, but it provides no results.  
Did I do something wrong here?

Thanks for your time and help.  
BR Binh

# Minimal code to reproduce problem

```python
class myNeuronClass :
    def __init__ (self):
        eqsM = '''
	    dv/dt = (g+1)/(1*ms): 1 (unless refractory)
	    g : 1
	    '''
        self.G = NeuronGroup(1, eqsM, threshold='v>5', reset='v=0; g = 0', refractory=5*ms, method='Euler')
        # we send spikes at time 2, and 32ms to the neuron group G for changing the value of its variable "g" to 2 and 4 accordingly
        nlayers = 2
        self.clocks = []
        self.clock_synapses = []
        for l in range(nlayers):
	        spike_times = np.array([l*30+2])*ms
	        indices = np.array([0]*len(spike_times))
	        clock = SpikeGeneratorGroup(1, indices, spike_times)
	        self.clocks.append(clock)
	        clock_synapse = Synapses(clock, self.G, on_pre='g =' + str((l+1)*2))
	        clock_synapse.connect()
	        self.clock_synapses.append(clock_synapse)

def main():
	start_scope()

	duration = 100*ms
	net = myNeuronClass()
	
	M = StateMonitor(net.G, 'v', record=True)
	P = StateMonitor(net.G, 'g', record=True)

	run(duration)
	
	subplot(211)
	plot(M.t/ms, M.v[0])
	ylabel('v')
	subplot(212)
	plot(P.t/ms, P.g[0])
	xlabel('Time (ms)')
	ylabel('g')
	show()

```

# What you have already tried

I want to monitor the value “g” and “v”, but they seem to be empty.  
Without using class, it works well.

# Expected output (if relevant)

For v: I should see a saw-tooth signal over time  
For g: it should be 0 until t= 2, then 2 until t=32, and after that 4

# Actual output (if relevant)

empty output

# Full traceback of error (if relevant)

---

<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:** [12 December 2024 21:21 UTC](https://brian.discourse.group/t/class-vs-direct/1350/2 "2024-12-12T21:21:36Z")

</div>

Hi @Thanh-Binh – welcome to the Brian community 😊  
The issue you are facing is unfortunately quite common, we do not document the “structured program” use case very well, i.e. constructing things in classes and functions as opposed to “flat scripts” as in most of our examples and tutorials.

In your code, the `main` function calls `run(...)`. At this point, Brian will look for “Brian objects” in the current scope and run them. In your case, it will only find the two `StateMonitor`s. There is a way to make it work with custom classes, but in cases like this, I would rather recommend to explicitly construct a `Network` object containing everything needed (see [Running a simulation — Brian 2 2.7.1 documentation](https://brian2.readthedocs.io/en/stable/user/running.html#networks)). In your example, you could for example replace your `run` call by:

```python
network = Network(collect()) # include the monitors
network.add(net.G) # add the NeuronGroup
network.add(net.clocks) # add the SpikeGeneratorGroups
network.add(net.clock_synapses) # add the Synapses
network.run(duration)

```

(The first line with the `collect` will basically do what the `run(...)` call did previously, i.e. collect everything “visible” in the current scope, in your case the two monitors.)  
Another option would be to create and store the `Network` object as part of the class, or have a general `.objects` attribute containing _all_ the objects that need to be added to the network so that the `main` function is more independent of the internals of your class.

Hope that gets you going!

PS: I edited your post to display the code more nicely. You can use triple backticks like this for code blocks:

````python
```
# Python code
print("Hello, world!)
```

````

PPS: A very minor thing, but you can use a single `StateMonitor` for both variables:

```python
M = StateMonitor(net.G, ['v', 'g'], record=True)

```

---

<div class="post-metadata">

**Author:** ![Thanh-Binh](https://yyz2.discourse-cdn.com/free1/user_avatar/brian.discourse.group/thanh-binh/32/809_2.png) [@Thanh-Binh](https://brian.discourse.group/u/Thanh-Binh)\
**Post date:** [12 December 2024 22:04 UTC](https://brian.discourse.group/t/class-vs-direct/1350/3 "2024-12-12T22:04:00Z")

</div>

@mstimberg thanks for your comments!  
Even in the Case I put all in a flatt script in main()  
I found the code

```
    nlayers = 2
    self.clocks = []
    self.clock_synapses = []
    for l in range(nlayers):
        spike_times = np.array([l*30+2])*ms
        indices = np.array([0]*len(spike_times))
        clock = SpikeGeneratorGroup(1, indices, spike_times)
        self.clocks.append(clock)
        clock_synapse = Synapses(clock, self.G, on_pre='g =' + str((l+1)*2))
        clock_synapse.connect()
        self.clock_synapses.append(clock_synapse)

```

does not work correctly. Clocks emit only 1 spike at 32ms. No Spike is emitted by the 1st Spike time at 2ms !  
Why?

Thanks

---

<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:** [12 December 2024 22:33 UTC](https://brian.discourse.group/t/class-vs-direct/1350/4 "2024-12-12T22:33:38Z")

</div>

Hi again. This is the issue that is briefly discussed in the link I sent earlier : the `run` call does not “see” the objects that are stored in containers like lists, it only automatically collects objects that are directly stored in variables in the current scope. After the loop, the `clock` and `clock_synapse` variables contain the values from the second iteration and are automatically included in the network. The objects from the first iteration are only in `self.clocks` and `self.clock_synapses`, and Brian will therefore ignore them.

---

<div class="post-metadata">

**Author:** ![Thanh-Binh](https://yyz2.discourse-cdn.com/free1/user_avatar/brian.discourse.group/thanh-binh/32/809_2.png) [@Thanh-Binh](https://brian.discourse.group/u/Thanh-Binh)\
**Post date:** [13 December 2024 07:43 UTC](https://brian.discourse.group/t/class-vs-direct/1350/5 "2024-12-13T07:43:21Z")

</div>

@mstimberg thank you very much. I understood this concept.
