- Notifications
You must be signed in to change notification settings - Fork3
Neuron++ is a library which wraps NEURON (http://www.neuron.yale.edu) with easy to use Python objects.
License
ziemowit-s/neuronpp
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Neuron++ is a wrapper for NEURON (http://www.neuron.yale.edu) with easy to use Python objects.The key intention behind this framework was to perform tedious tasks in few lines of code withthe object-oriented paradigm.
NEURON allows to create simulations of Biological Neural Networks. The Neuron++ framework wasdesigned to match the simplicity of libraries such as Keras library for Artificial Neural Networks.With Neuron++ you can easily create group of cells, stack them together as populations,then stimulate them with external input and collect readouts to perform any task.
Use for fast prototyping of neural models in NEURON simulator, using Python interface withthe object-oriented paradigm (OOP)
Precisely define single cell models and connect them together to create a network
Auto-compilation of all MOD files on the fly
Auto-load SWC/ASC or HOC morphology for each cell
Upload HOC defined models and adapt them to your needs
Define in vitro experimental protocols (eg. STDP paradigms)
Manage synaptic signaling
Debug synapses and point processes RANGE values in real time with interactivestimulation from the keyboard
Create predefined dendritic spines and synapses with ease
Define populations of neurons and connect them together
Provide helpful exception messages and guidelines of how to use NEURON functions with Neuron++wrapper without errors
This is the Alpha version.
- Python >= 3.5 (recommended is Python 3.8)
- Install requirements.txt:
pip install -r requirements.txt
- If not Linux - go to the instruction:https://github.com/ziemowit-s/neuron_get_started
- recommended NEURON version is 7.8.2. Please do not use NEURON version 8.* Neuron++ won't remove correctly NEURON elements. It will be fixed in the future
https://github.com/ziemowit-s/neuronpp
- Locally:
python setup.py bdist_wheel
- Through pip and GitHub:
pip install git+https://github.com/ziemowit-s//neuronpp
- Bear in mind that if you install the library through the pip you will have access to all featuresof NEURON++, however additionally provided cell models from other publications (listed below) willnot work correctly, unless you download the 'commons/' folder from the GitHub repository and changepaths in 'examples/' indicating the 'commons/'.
So if you want to work with those predefined models it is recommended to clone the repository fromGitHub rather than install through pip.
This repository contains the basic cell objects:
Cell
classHocCell
- the experimental `HOC class which loads HOC based cell model.
The repository also contains some predefined cell models from ModelDB (https://senselab.med.yale.edu/modeldb)
- All of those models are located in the cells/ folder.
- If you want to create your own model it is recommended to use:
Cell
HocCell
- if you want to reuse existing HOC model
The list of predefined cell models:
- Ebner et al. 2019,https://doi.org/10.1016/j.celrep.2019.11.068
- Custom implementation of Ebner et. al 2019 with ACh/DA modulation
- Combe et al. 2018,https://doi.org/10.1523/JNEUROSCI.0449-18.2018
- Graham et al. 2014,https://doi.org/10.1162/NECO_a_00640
- Hay et al. 2011,https://doi.org/10.1371/journal.pcbi.1002107
MOD files of all of those models are located in the commons/mods/ folder.Combe 2018 model and Graham 2014 model additionally have HOC files located in thecommons/hocmodels/ folder.
Cell()
object has acompile_path
param which allows to specify paths which contain MOD files.
You don't need to compile files externally, if you provided appropriate pathways itwill be done automatically before each run.
All examples are located in the examples/ folder
Please bear in mind that due to substantial updates some examples may not work as described here inthe README, also some additional features have been added which are not listed here. We will updatereadme soon.
- create a cell:
cell=Cell(name="mycell")
- load SWCor ASC morphology:
cell.load_morpho(filepath='commons/morphologies/asc/cell2.asc')
- load HOC-based cell (and HOC-based morphology) model to the
Cell
object:- allows to work with most modelDB single cell models
- it will auto load all sections and point processes for further usage and/or filtering
- This is an experimental feature, so currently works ONLY with HOC models which define asingle cell
cell=HocCell(name="mycell")cell.load_hoc("your_cell_model.hoc")
- if the HOC cell model is defined as a Template - just specify the
cell_template_name
param:
cell=HocCell(name="mycell")cell.load_hoc("Ebner2019_minimum_load/load_model.hoc",hoc_template_name="L5PCtemplate")
- create and connect sections:
cell.add_seg("soma",diam=20,l=20,nseg=10)cell.add_seg("dend",diam=2,l=100,nseg=10)cell.connect_secs(child="dend",parent="soma")
- add NEURON mechanisms (default or MOD-based):
cell.insert("pas")cell.insert("hh")
- define simulation and run:
sim=Simulation(init_v=-65,warmup=20)sim.run(runtime=500)
- add IClamp:
sections=cell.filter_secs("soma")soma=sections[0]ic=IClamp(segment=soma(0.5))ic.debug(delay=100,dur=10,amp=0.1)
You can obtain any part of the cell by string or regular expression filtering
- filter section of the cell by string:
# Assuming you have sections dend[0]...dend[100] it will return all of themsections=cell.filter_secs(name="dend")
- filter by string separated by coma:
# Each coma function as OR between stringssections=cell.filter_secs(name="apic[1],apic[50]")
- filter section of the cell by regular expression:
# Assuming you have sections dend[0]...dend[100] and apic[0]...apic[100] it will return all of themsections=cell.filter_secs(name="regex:(apic)|(basal)")
- return synapses of type 'ExpSyn' located in all heads sections (of the dendritic spines)
cell.filter_synapses(mod_name="ExpSyn",name="head")
- custom function-based filtering:
- pass function to the
obj_filter
param.eg. (lambda expression) returns sections which name contains 'apic' or theirdistance > 1000 um from the soma:
- pass function to the
soma=cell.filter_secs("soma")cell.filter_secs(obj_filter=lambdao:'apic'ino.nameorh.distance(soma(0.5),o(0.5))>1000)
- field-based filtering with custom function.eg. (lambda expression) returns sections which parent's name contains less than 10 characters
cell.filter_secs(parent=lambdao:len(o.parent.name)<10)
All filter functions available in default cell objectCell
:
- filter_secs - obtain sections
- filter_point_processes - obtain point processes
- filter_netcons - obtain netcons
- filter_synapses - obtain single synapse, which is a point_process and netcon wrapper
- filter_synaptic_group - obtain a group of synapses which is many single synapses grouped together
If you definesource
param - it will stimulate synapse based on the stimulation from the source.Ifsource
is None - there will be no source and no netcon, however you can add those later oruse such synapse for theExperiment
.
- add single synapse:
cell=Cell(name="cell")soma=cell.filter_secs(name="soma")cell.add_sypanse(source=None,mod_name="Syn4P",seg=soma(0.5),netcon_weight=0.01,delay=1)
- add many spines to the provided sections:
cell=Cell(name="cell")dendrites=cell.filter_secs(name="dend")cell.add_randuniform_spines(spine_number=10,head_nseg=10,neck_nseg=10,secs=dendrites)
- add many synapses with spines (1 synapse/spine) in a single function to the provided sections:
cell=Cell(name="cell")dendrites=cell.filter_secs(name="dend")syns=cell.add_random_synapses_with_spine(source=None,secs=dendrites,mod="ExpSyn",netcon_weight=0.01,delay=1,number=10)
- define NetStim (or VecStim) and pass it to synapses as a source while creating:
netstim=NetStimCell(name="netst")stim=netstim.add_netstim(start=300,number=5,interval=10)cell=Cell(name="cell")soma=cell.filter_secs(name="soma")cell.add_sypanse(source=stim,seg=soma(0.5),mod_name="ExpSyn",netcon_weight=0.01,delay=1)
- send external input to the synapse by calling synaptic event:
- every synapse can be stimulated by making event, however a good practice is to definesource=None for such synapses.
cell=Cell(name="cell")soma=cell.filter_secs(name="soma")syns=cell.add_sypanse(source=None,seg=soma(0.5),mod_name="ExpSyn",netcon_weight=0.01,delay=1)sim=Simulation(init_v=-55,warmup=20)syns[0].make_event(10)syns[0].make_event(20)sim.run(runtime=100)
- Add another source to the previously created synapse:
synapse.add_netcon(source=None,weight=0.035,threshold=15,delay=2)
- make spike detector for the cell:
cell.make_spike_detector()sim=RunSim(init_v=-65)sim.run(runtime=500)cell.plot_spikes()
- record variables from sections and point_processes:
# record section's voltagesoma=cell.filter_secs(name="soma")rec_v=Record(soma(0.5),variables="v")# record synaptic (point_process) wariables (weight 'w')point_processes=cell.filter_point_processes(mod_name="Syn4P",name="dend")rec_syn=Record(point_processes,variables="w")sim=Simulation(init_v=-65,warmup=20,with_neuron_gui=True)sim.run(runtime=500)
- make plots and export recorded variables to CSV:
rec_v.plot()rec_syn.plot()plt.show()rec_v.to_csv("vrec.csv")
- make shape plot of the cell in NEURON GUI:
# show 'cai' propagation in range 0-0.01 uMmake_shape_plot(variable="cai",min_val=0,max_val=0.01)# show 'v' propagation in range -70-40 mVmake_shape_plot(variable="v",min_val=-70,max_val=40)
- define experimetal protocols, eg. STDP protocol:
soma=cell.filter_secs("soma")syn=cell.filter_synapses(tag="my_synapse")experiment=Experiment(iti=40)experiment.add_epsp(num=3,synapse=syn,init=20,interval=20,weight=0.02)experiment.add_iclamp(num=3,segment=soma(0.5),init=60,interval=20,dur=3,amp=1.6)experiment.build()
Create a population of many neurons of the same type and connect them between populations:
Create a template cell function:
defcell_function():cell=Cell(name="cell")morpho_path=os.path.join(path,"..","commons/morphologies/swc/my.swc")cell.load_morpho(filepath=morpho_path)cell.insert("pas")cell.insert("hh")cell.make_spike_detector(seg=cell.filter_secs("soma")(0.5))returncell
- Create stimulation:
# Create NetStimnetstim=NetStimCell("stim").add_netstim(start=21,number=100,interval=2)# Define weight distribution for both: NetStim->population1 and population1->population2weight_dist=NormalTruncatedDist(mean=0.1,std=0.2)
- Define population 1:
pop1=Population("pop_1")pop1.add_cells(num=3,cell_function=cell_function)# create 10 synapses on population 2 per NetStim object (single NetStim here)connector=pop1.connect(syn_num_per_cell_source=10)connector.set_source(netstim)# choose all dendrites as potential targets for synaptic choicetargets= [d(0.5)forcinpop1.cellsfordinc.filter_secs("dend")]connector.set_target(targets)# Make synapsesyn_adder=connector.add_synapse("Exp2Syn")syn_adder.add_netcon(weight=weight_dist)# change tau1 and tau2 for Exp2Syn synapsessyn_adder.add_point_process_params(tau1=0.1,tau2=2)
- Build connections and define that you want to record from the population
- By default
record()
method make records of: voltage variable in soma(0.5)
- By default
connector.build()pop1.record()
- Create population 2:
pop2=Population("pop_2")pop2.add_cells(num=3,cell_function=cell_function)
- Define connections between pop1 and pop2 where weights will be chosenfrom the Normal Truncated Distribution:
# create 5 synapses per single cell in population 1connector=pop2.connect(syn_num_per_cell_source=5)source= [c.filter_secs("soma")(0.5)forcinpop1.cells]connector.set_source(source)# choose all dendrites as potential targets for synaptic choicetargets= [d(0.5)forcinpop2.cellsfordinc.filter_secs("dend")]connector.set_target(targets)# Make synapsesyn_adder=connector.add_synapse("Exp2Syn")syn_adder.add_netcon(weight=weight_dist)# change tau1 and tau2 for Exp2Syn synapsessyn_adder.add_point_process_params(tau1=0.1,tau2=2)
- Build connections and define that you want to record from the population
- By default
record()
method make records of: voltage variable in soma(0.5)
connector.build()pop2.record()
- Ryn simulation and plot activities:
sim=Simulation(init_v=-70,warmup=20)foriinrange(1000):sim.run(runtime=1)pop1.plot(animate=True)pop2.plot(animate=True)
- Create (experimental) interactive graph of connected populations which allows you to see andmove nodes in the web browser:
show_connectivity_graph(pop1.cells+pop2.cells)
Debug any cell and synapse on interactive plot.
- By pressing a key defined as
stim_key
param (default is w) you can stimulate synapsesprovided to the Debugger - It allows to easily plot synaptic weight (defined as MOD's RANGE variable) to see howthe plasticity behaves in real time
fromneuronpp.cells.cellimportCellfromneuronpp.utils.synaptic_debuggerimportSynapticDebugger# Prepare cellcell=Cell("cell")soma=cell.add_sec("soma",diam=20,l=20,nseg=100)cell.insert("pas")cell.insert("hh")syn1=cell.add_synapse(source=None,netcon_weight=0.002,seg=soma(0.1),mod_name="Exp2Syn")syn2=cell.add_synapse(source=None,netcon_weight=0.002,seg=soma(0.9),mod_name="Exp2Syn")syn3=cell.add_synapse(source=None,netcon_weight=0.002,seg=soma(0.5),mod_name="Exp2Syn")# Debugdebug=SynapticDebugger(init_v=-70,warmup=10,delay_between_steps=15)debug.add_syn(syn1,key_press='1',plot=True,syn_variables='i')debug.add_syn(syn2,key_press='2')debug.add_syn(syn3,key_press='3')debug.add_seg(soma(0.5))debug.debug_interactive()
Example of Ebner et al. 2019 model of synaptic weight (variable w) changing based on synaptic stimulation on demandby pressing key "w" on the keyboard:
- variable w: weight on the synapse.
- variable v: voltage on the soma.
- Pressing "w" on the keyboard produce a synaptic event.
About
Neuron++ is a library which wraps NEURON (http://www.neuron.yale.edu) with easy to use Python objects.