Note
This page corresponds to a Jupyter notebook you can
try out yourself.
(The original version is here.)
Simulation Tutorial¶
This notebook shows how to estimate the delay and amplitude response between primary brain regions for a given neuron. In general, the delay within a compartment tends to be isopotential meaning a region to region response matrix is a reasonable characterization of the output response of a neuron.
The electrical simulation uses a simple linear passive model using a network of resistors and capacitors based on a skeleton representation of the neuron. Users can specify specific membrane resistance and capacitance values and cytoplasm resitance.
Note: You must install some additional dependencies before using simulation functions:
conda install -c conda-forge ngspice umap-learn scikit-learn matplotlib
Setup neuron model¶
create neuprint client using the public hemibrain dataset
build a neuron spice model for a given body id
[1]:
from neuprint import Client
TOKEN = "" # <--- Paste your token here
# (or define NEUPRINT_APPLICATION CREDENTIALS in your environment)
client = Client("neuprint.janelia.org", "hemibrain:v1.2.1", TOKEN)
[2]:
# simulate a PEG neuron (same type as in hemibrain paper)
from neuprint import NeuronModel
nm = NeuronModel(449438847)
Estimate neuron timing¶
Run simulation for the given neuron¶
Specify the number of inputs per brain region (randomly selected) which will be tested. A current is injected at each input site one at a time and delay and amplitude response is measured.
[3]:
res = nm.simulate(2)
Examine the response results¶
compute_region_delay_matrix reports the delay between regions where the row index is the input brain region and the column names represent the output region. A delay (ms) and amplitude (mV) are returned. They are averages over all the response for a given region input-output pair.
Note: the results to synapses that are not in brain regions (“none”) are shown for completeness. But those output responses are not necessarily co-located and cannot be treated as an ROI.
[4]:
delay, amp = res.compute_region_delay_matrix()
[5]:
# delay matrix in ms
delay
[5]:
EB | LAL(R) | PB | none | |
---|---|---|---|---|
CRE(R) | 2.074233 | 0.427321 | 3.208169 | 2.539196 |
EB | 1.258467 | 2.456816 | 3.166434 | 2.483917 |
FB | 1.657618 | 2.120017 | 1.880404 | 1.058834 |
LAL(R) | 2.356702 | 0.329966 | 3.474082 | 2.809558 |
PB | 3.143595 | 3.550282 | 0.437841 | 0.713781 |
none | 2.590528 | 3.010865 | 0.676969 | 0.154951 |
[6]:
# amplitude in mV
amp
[6]:
EB | LAL(R) | PB | none | |
---|---|---|---|---|
CRE(R) | 0.153407 | 0.489385 | 0.122230 | 0.134334 |
EB | 0.181624 | 0.143877 | 0.121702 | 0.134000 |
FB | 0.160437 | 0.149854 | 0.149690 | 0.167537 |
LAL(R) | 0.146963 | 0.749892 | 0.117411 | 0.128987 |
PB | 0.123022 | 0.116236 | 0.416325 | 0.261497 |
none | 0.134309 | 0.126698 | 0.283109 | 0.311731 |
Plot response from one brain region to others¶
Each dot represents the response from each input from the specified input region (LAL(R) here) to every output in the neuron (each output brain region is indicated).
[7]:
res.plot_response_from_region("LAL(R)")
[7]:
Decompose neuron connections by electrical domain¶
Use simple linear passive delay progragation through the neuron to determine distinct domains for representing the neuron. The decomposition can be used to derive ROIs using electrical delay.
Simulate the delay ‘distances’ between parts of the neuron¶
This function checks propagation delays throughout the neuron based on the number of specified points. The points are randomly chosen even between inputs and outputs. In principle, any points could be chosen.
[8]:
res = nm.estimate_intra_neuron_delay(num_points=100)
Show delay propogation closeness between simulated points¶
This plot should show whether there are distinct electrical domains for the neuron. The primary ROI labels are provided to show how well the points correspond to the annotated regions.
[9]:
res.plot_neuron_domains()
[9]:
Partition the neuron into different domains based on simulated points¶
Cluster the simulated points and map a partition id to each synapse in the neuron. The function returns input and output connections broken down by these domain ids.
[10]:
summary, detailed_io, plot = res.estimate_neuron_domains(3, plot=True)
[11]:
# input / output table broken down by domain id from partitioning
summary
[11]:
io | partner | weight | domain_id | rois | |
---|---|---|---|---|---|
0 | output | 696682163 | 147 | 0 | [EB] |
1 | output | 974300015 | 97 | 1 | [PB, none] |
2 | output | 858587718 | 88 | 0 | [EB] |
3 | output | 858587718 | 72 | 2 | [LAL(R)] |
4 | output | 1228692168 | 66 | 0 | [EB] |
... | ... | ... | ... | ... | ... |
720 | input | 5813057963 | 1 | 0 | [EB] |
721 | input | 5813062805 | 1 | 0 | [CRE(R)] |
722 | input | 5813061383 | 1 | 1 | [PB] |
723 | input | 5813070465 | 1 | 0 | [EB] |
724 | input | 5813080269 | 1 | 0 | [EB] |
725 rows × 5 columns
[12]:
# domain id for each x,y,z location
detailed_io
[12]:
type | x | y | z | roi | partner | domain_id | |
---|---|---|---|---|---|---|---|
0 | post | 21510 | 26069 | 20648 | EB | 387364605 | 0 |
1 | post | 23679 | 24857 | 20538 | EB | 387364605 | 0 |
2 | post | 22135 | 26177 | 20494 | EB | 387364605 | 0 |
3 | post | 21613 | 25974 | 20679 | EB | 387364605 | 0 |
4 | post | 23870 | 23196 | 20455 | EB | 387364605 | 0 |
... | ... | ... | ... | ... | ... | ... | ... |
7092 | pre | 23030 | 24895 | 20167 | EB | 1002507131 | 0 |
7093 | pre | 23621 | 24908 | 20429 | EB | 1002507131 | 0 |
7094 | pre | 22615 | 24507 | 19708 | EB | 1002507131 | 0 |
7095 | pre | 22992 | 24888 | 20123 | EB | 1002507131 | 0 |
7096 | pre | 23278 | 24606 | 20178 | EB | 1002507131 | 0 |
7097 rows × 7 columns
[13]:
plot
[13]: