Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

address Scott’s feedback on the basal ganglia tutorial #498

Merged
merged 3 commits into from
Dec 6, 2024

Conversation

gabrevaya
Copy link
Contributor

Addressing Scott’s feedback on the basal ganglia tutorial.

1

It seems the Striatum_*_Adam() functions are doing all the heavy computational lifting here. Can we more explicitly explain what those are doing, and how they relate to the NB ecosystem (eg “We previously showed how to build circuits out of single neuron blox and networks out of neural mass blox. Here we show how entire model components(?) can be described in a single blox.” or something like that?).

Below the image at the beginning of the tutorial, I added:

# In previous tutorials, we explored building neural circuits from individual neuron bloxs and creating networks using neural mass bloxs. Here, we'll demonstrate how Neuroblox enables modeling of complex brain structures using specialized composite bloxs that encapsulate entire neural populations. These composite bloxs represent distinct neuronal populations within the basal ganglia, each containing multiple Hodgkin-Huxley neurons with their characteristic properties and intrinsic connectivity patterns.

2

This tutorial appears to use a different plotting interface from most other tutorials—plot(), meanfield(), etc. instead of the the *_timeseries() and lines!() approach. I’m guessing these are a higher-level interface that abstracts away some of the lower-level calls in other tutorials? If so, we should make that explicit here (eg “Previously we have used low-level NB functions to measure model-simulated data and plot it. Now we introduce higher-level functions that abstract both of these steps into a single function call…”). And if that is not the case, then we should align the plotting interface across tutorials.

@harisorgn, what do you suggest for this?

I used

plot(sol, idxs=1, axis = (xlabel = "Time (ms)", ylabel = "Membrane potential (mV)"))

over something like what is used in the "Bottom-up construction of a neural assembly" tutorial:

v = voltage_timeseries(nn1, sol)
fig = Figure();
ax = Axis(fig[1,1]; xlabel = "time (ms)", ylabel = "Voltage (mv)")
cl = get_neuron_color(nn1) #specify color based on neuron type (excitatory/inhibitory)
lines!(ax, sol.t, v, color=cl)
fig ## to display the figure

just because it was much more concise and simple. But Scott is right that we need to use coherent plotting functions across tutorials. What do you suggest? I think Helmut had suggested including a new plot recipe for plotting variables of individual neurons (such as voltage). In that case, we could use it for these plots.

3

All the detect_spikes() and mean_firing_rate() feel like a bit of a red herring here. They add a bunch of code and apparent complexity, but it seems the only actual use is to generate the mean firing rates in the plot titles(?), where the rate differences are pretty obvious to the eye. Can we consider either removing these or being a bit more intentional about why they’re in there (eg “Here we’ll show you how to detect spikes in continuous data and measure mean firing rates in NB”)?

After #496 is merged, this would be simplified, eg. changing

# Detect spikes and compute firing rates
spikes_msn = detect_spikes(msn, ens_sol[1], threshold = -35)
t, fr_msn = mean_firing_rate(spikes_msn, ens_sol[1])
spikes_fsi = detect_spikes(fsi, ens_sol[1], threshold = -25)
t, fr_fsi = mean_firing_rate(spikes_fsi, ens_sol[1])

to

# Computing firing rates for comparison
fr_msn = firing_rate(msn, ens_sol[1], threshold=-35, transient=200)
fr_fsi = firing_rate(fsi, ens_sol[1], threshold=-35, transient=200)

I think after this simplification, it would be OK to include the firing rates calculations, right? I'll change # Computing firing rates for comparison to # Compute firing rates for comparison in order to maintain consistency.

4

Plot looks different from docs – peak at ~800 ms vs ~1900 ms

This seems to be due to some difference in the randomness. Even though I set a random seed for reproducibility at the beginning of the tutorial, something (perhaps running it with a different number of threads) could be affecting this. In any case, since the qualitative results are maintained, I think this should be acceptable.

5

In the text, can we make explicit the connection to the code, and why we want to do this, eg “We can also run multiple simulations in parallel using EnsembleProblem()…. This allows us to evaluate model outputs with multiple realizations of random physiological noise” (or something like that)?

Change:

# We can leverage parallel computing using `EnsembleProblem()` to run multiple simulations simultaneously. This allows us to evaluate model outputs with multiple realizations of random physiological noise while utilizing all available computational threads (default) or processes.

6

“Their inhibition onto MSNs suppresses the low beta-band activity seen in isolated MSN populations”. Is this referring to the peak at 12 Hz in the Cell 8/9 plots? If so, we should mention that peak in the text around those plots to orient users to it.

Bellow the last MSN power spectrum plot, I added:

# Note the peak at ~12 Hz in the MSN population's activity, representing an emergent beta-band oscillation characteristic of this circuit. We'll explore how this rhythm is altered by FSI inhibition next.

Other

Besides the changes in this PR, when #495 is merged, the power spectrum calls will be also much cleaner, without having to specify alpha, beta and gamma labels positions.

@harisorgn
Copy link
Member

What do you suggest? I think Helmut had suggested including a new plot recipe for plotting variables of individual neurons (such as voltage). In that case, we could use it for these plots.

We have state_timeseries for this. I don't think a recipe is currently needed unless a specific state of a specific supertype of bloxs needs a specific plot etc. I'd say use voltage_timeseries like Anand did on the bottom-up tutorial. These timeseries getter functions are part of our API so it's good to use them in tutorials. About the axis object, I prefer defining it separately and then using the mutating function lines!(ax, ...) . I think this is an easier transition to layouts, when you have multiple axis objects.

@gabrevaya gabrevaya merged commit 6854ace into master Dec 6, 2024
6 checks passed
@gabrevaya gabrevaya deleted the basal_ganglia_tutorial_scott_feedback branch December 6, 2024 19:30
david-hofmann pushed a commit that referenced this pull request Jan 2, 2025
* address Scott’s feedback on the basal ganglia tutorial
* change voltage plotting method
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants