Skip to content

Commit d060070

Browse files
authored
Merge pull request #10 from openworm/development
First version of NML to main
2 parents c6df9c7 + 655ba56 commit d060070

15 files changed

Lines changed: 730 additions & 1 deletion

.github/workflows/omv-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
fail-fast: false
1818
matrix:
1919
python-version: [ 3.9, "3.11" ]
20-
engine: [ PyNEURON ]
20+
engine: [ PyNEURON, jNeuroML_validate ]
2121

2222
steps:
2323
- uses: actions/checkout@v4

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,12 @@
77
arm64
88
x86_64
99
/__pycache__
10+
.DS_Store
11+
/NeuroML/*.dat
12+
/NeuroML/report.*.txt
13+
/NeuroML/IClamp_AIY.json
14+
/NeuroML/Sim_IClamp_AIY.json
15+
/NeuroML/*.hoc
16+
/NeuroML/*_nrn.py
17+
/NeuroML/*.mod
1018
/AVAR_SIMULATION

NeuroML/.test.validate.omt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Script for running automated tests on OSB
2+
3+
# This test will validate all of the NeuroML 2 files in the current directory using: jnml -validate *.nml
4+
target: "*.cell.nml *.channel.nml *.net.nml"
5+
engine: jNeuroML_validate

NeuroML/AIY.cell.nml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<neuroml xmlns="http://www.neuroml.org/schema/neuroml2" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.1.xsd" id="AIY">
2+
<notes>A cell from Nicoletti et al. 2019</notes>
3+
<include href="leak.channel.nml"/>
4+
<cell id="AIY">
5+
<notes>AIY cell from Nicoletti et al. 2019</notes>
6+
<morphology id="morphology">
7+
<segment id="0" name="soma">
8+
<proximal x="0.0" y="0.0" z="0.0" diameter="4.579676669880742"/>
9+
<distal x="0.0" y="4.579676669880742" z="0.0" diameter="4.579676669880742"/>
10+
</segment>
11+
<segmentGroup id="soma_group" neuroLexId="GO:0043025">
12+
<notes>Default soma segment group for the cell</notes>
13+
<member segment="0"/>
14+
</segmentGroup>
15+
<segmentGroup id="all">
16+
<notes>Default segment group for all segments in the cell</notes>
17+
<member segment="0"/>
18+
</segmentGroup>
19+
</morphology>
20+
<biophysicalProperties id="biophys">
21+
<membraneProperties>
22+
<channelDensity id="leak_chans" ionChannel="leak" condDensity="0.00021247533768401888 S_per_cm2" erev="-89.57mV" ion="non_specific"/>
23+
<spikeThresh value="0mV"/>
24+
<specificCapacitance value="1.6 uF_per_cm2"/>
25+
<initMembPotential value="-65mV"/>
26+
</membraneProperties>
27+
<intracellularProperties>
28+
<resistivity value="0.1 kohm_cm"/>
29+
</intracellularProperties>
30+
</biophysicalProperties>
31+
</cell>
32+
</neuroml>

NeuroML/GenerateNeuroML.py

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
from neuroml import NeuroMLDocument
2+
from neuroml.utils import component_factory
3+
4+
from pyneuroml import pynml
5+
from pyneuroml.xppaut import parse_script
6+
from pprint import pprint
7+
8+
from neuroml import GateHHRates
9+
from neuroml import IncludeType
10+
import sympy
11+
from sympy.parsing.sympy_parser import parse_expr
12+
import math
13+
14+
15+
colors = {"AIY": "0.8 0 0"}
16+
cell_params = {}
17+
18+
cell = "AIY"
19+
cell_params[cell] = {"surf": 65.89e-8} # surface in cm^2 form neuromorpho AIYL
20+
21+
conductances = [ "leak",
22+
"slo1iso",
23+
"kqt1",
24+
"egl19",
25+
"slo1egl19",
26+
"nca",
27+
"irk",
28+
"eleak",
29+
"cm",
30+
]
31+
32+
g0 = [0.14, 1, 0.2, 0.1, 0.92, 0.06, 0.5, -89.57, 1.6]
33+
34+
35+
for a in zip(conductances, g0):
36+
print(f"Setting {a[0]} = {a[1]} for {cell}")
37+
cell_params[cell][a[0]] = a[1]
38+
39+
40+
def generate_nmllite(
41+
cell,
42+
duration=11000,
43+
config="IClamp",
44+
parameters=None,
45+
stim_delay=1000,
46+
stim_duration=5000,
47+
channels_to_include=[],
48+
):
49+
from neuromllite import Cell, InputSource
50+
51+
# from neuromllite.NetworkGenerator import *
52+
from neuromllite.utils import create_new_model
53+
54+
reference = "%s_%s" % (config, cell)
55+
56+
cell_id = "%s" % cell
57+
cell_nmll = Cell(id=cell_id, neuroml2_source_file="%s.cell.nml" % (cell))
58+
59+
################################################################################
60+
### Add some inputs
61+
62+
if "IClamp" in config:
63+
if not parameters:
64+
parameters = {}
65+
parameters["stim_amp"] = "30pA"
66+
parameters["stim_delay"] = "%sms" % stim_delay
67+
parameters["stim_duration"] = "%sms" % stim_duration
68+
69+
input_source = InputSource(
70+
id="iclamp_0",
71+
neuroml2_input="PulseGenerator",
72+
parameters={
73+
"amplitude": "stim_amp",
74+
"delay": "stim_delay",
75+
"duration": "stim_duration",
76+
},
77+
)
78+
79+
else:
80+
if not parameters:
81+
parameters = {}
82+
parameters["average_rate"] = "100 Hz"
83+
parameters["number_per_cell"] = "10"
84+
85+
input_source = InputSource(
86+
id="pfs0",
87+
neuroml2_input="PoissonFiringSynapse",
88+
parameters={
89+
"average_rate": "average_rate",
90+
"synapse": syn_exc.id,
91+
"spike_target": "./%s" % syn_exc.id,
92+
},
93+
)
94+
95+
sim, net = create_new_model(
96+
reference,
97+
duration,
98+
dt=0.025, # ms
99+
temperature=34, # degC
100+
default_region="Worm",
101+
parameters=parameters,
102+
cell_for_default_population=cell_nmll,
103+
color_for_default_population=colors[cell],
104+
input_for_default_population=input_source,
105+
)
106+
sim.record_variables = {"caConc": {"all": "*"}}
107+
for c in channels_to_include:
108+
not_on_rmd = ["kvs1", "kqt3", "egl2"]
109+
if c == "ca":
110+
c = "sk"
111+
112+
if c != "egl36" and cell != "AWCon" and not (c in not_on_rmd and cell == "RMD"):
113+
sim.record_variables["biophys/membraneProperties/%s_chans/gDensity" % c] = {
114+
"all": "*"
115+
}
116+
sim.record_variables["biophys/membraneProperties/%s_chans/iDensity" % c] = {
117+
"all": "*"
118+
}
119+
if (
120+
c != "leak"
121+
and c != "nca"
122+
and not (c == "egl36" and cell == "AWCon")
123+
and not (c in not_on_rmd and cell == "RMD")
124+
):
125+
sim.record_variables[
126+
"biophys/membraneProperties/%s_chans/%s/m/q" % (c, c)
127+
] = {"all": "*"}
128+
if (
129+
c != "leak"
130+
and c not in ["nca", "kir", "sk", "egl36", "kqt3", "egl2"]
131+
and not (c in not_on_rmd and cell == "RMD")
132+
):
133+
sim.record_variables[
134+
"biophys/membraneProperties/%s_chans/%s/h/q" % (c, c)
135+
] = {"all": "*"}
136+
137+
if cell == "AWCon" and c in ["kqt3"]:
138+
sim.record_variables[
139+
"biophys/membraneProperties/%s_chans/%s/s/q" % (c, c)
140+
] = {"all": "*"}
141+
sim.record_variables[
142+
"biophys/membraneProperties/%s_chans/%s/w/q" % (c, c)
143+
] = {"all": "*"}
144+
145+
sim.to_json_file()
146+
147+
return sim, net
148+
149+
150+
def create_cells(channels_to_include, duration=700, stim_delay=310, stim_duration=500):
151+
for cell_id in cell_params.keys():
152+
# Create the nml file and add the ion channels
153+
cell_doc = NeuroMLDocument(
154+
id=cell_id, notes="A cell from Nicoletti et al. 2019"
155+
)
156+
cell_fn = "%s.cell.nml" % cell_id
157+
158+
# Define a cell
159+
cell = cell_doc.add(
160+
"Cell", id=cell_id, notes="%s cell from Nicoletti et al. 2019" % cell_id
161+
)
162+
"""
163+
volume_um3 = xpps[cell_id]["parameters"]["vol"]
164+
diam = 1.7841242
165+
end_area = math.pi * diam * diam / 4
166+
length = volume_um3 / end_area
167+
surface_area_curved = length * math.pi * diam"""
168+
169+
surf = cell_params[cell_id]["surf"]
170+
# vol = 7.42e-12 # total volume
171+
L = math.sqrt(surf / math.pi)
172+
rsoma = L * 1e4
173+
174+
cell.add_segment(
175+
prox=[0, 0, 0, rsoma],
176+
dist=[0, rsoma, 0, rsoma],
177+
name="soma",
178+
parent=None,
179+
fraction_along=1.0,
180+
seg_type="soma",
181+
)
182+
183+
cell.add_membrane_property("SpikeThresh", value="0mV")
184+
185+
cell.set_specific_capacitance("%s uF_per_cm2" % (cell_params[cell_id]["cm"]))
186+
187+
cell.set_init_memb_potential("-65mV")
188+
189+
# This value is not really used as it's a single comp cell model
190+
cell.set_resistivity("0.1 kohm_cm")
191+
192+
193+
for channel_id in channels_to_include:
194+
195+
density_scaled = (cell_params[cell_id][channel_id]*1e-9)/(surf)
196+
197+
print(cell_params[cell_id])
198+
cell.add_channel_density(
199+
cell_doc,
200+
cd_id="%s_chans" % channel_id,
201+
cond_density="%s S_per_cm2" % density_scaled,
202+
erev="%smV" % cell_params[cell_id]["eleak"],
203+
ion="non_specific",
204+
ion_channel="%s" % channel_id,
205+
ion_chan_def_file="%s.channel.nml" % channel_id,
206+
)
207+
208+
"""
209+
cell_doc.includes.append(IncludeType(href="CaDynamics.nml"))
210+
# <species id="ca" ion="ca" concentrationModel="CaDynamics" initialConcentration="1e-4 mM" initialExtConcentration="2 mM"/>
211+
species = component_factory(
212+
"Species",
213+
id="ca",
214+
ion="ca",
215+
concentration_model="CaDynamics_%s" % cell_id,
216+
initial_concentration="5e-5 mM",
217+
initial_ext_concentration="2 mM",
218+
)
219+
220+
cell.biophysical_properties.intracellular_properties.add(species)"""
221+
222+
cell.info(show_contents=True)
223+
224+
cell_doc.validate(recursive=True)
225+
pynml.write_neuroml2_file(
226+
nml2_doc=cell_doc, nml2_file_name=cell_fn, validate=True
227+
)
228+
229+
sim, net = generate_nmllite(
230+
cell_id,
231+
duration=duration,
232+
config="IClamp",
233+
parameters=None,
234+
stim_delay=stim_delay,
235+
stim_duration=stim_duration,
236+
channels_to_include=channels_to_include,
237+
)
238+
239+
################################################################################
240+
### Run in some simulators
241+
242+
from neuromllite.NetworkGenerator import check_to_generate_or_run
243+
import sys
244+
245+
check_to_generate_or_run(sys.argv, sim)
246+
247+
248+
if __name__ == "__main__":
249+
create_cells(
250+
channels_to_include=["leak"],
251+
duration=11000,
252+
stim_delay=1000,
253+
stim_duration=5000,
254+
)

NeuroML/IClamp_AIY.net.nml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<neuroml xmlns="http://www.neuroml.org/schema/neuroml2" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.1.xsd" id="IClamp_AIY">
2+
<notes>Generated by NeuroMLlite v0.6.1
3+
Generated network: IClamp_AIY
4+
Generation seed: 1234
5+
NeuroMLlite parameters:
6+
stim_amp = 30pA
7+
stim_delay = 1000ms
8+
stim_duration = 5000ms</notes>
9+
<include href="AIY.cell.nml"/>
10+
<pulseGenerator id="iclamp_0" delay="1000ms" duration="5000ms" amplitude="30pA"/>
11+
<network id="IClamp_AIY" type="networkWithTemperature" temperature="34.0degC">
12+
<notes>A network model: IClamp_AIY</notes>
13+
<property tag="recommended_dt_ms" value="0.025"/>
14+
<property tag="recommended_duration_ms" value="11000.0"/>
15+
<population id="pop_AIY" component="AIY" size="1" type="populationList">
16+
<property tag="color" value="0.8 0 0"/>
17+
<property tag="region" value="Worm"/>
18+
<instance id="0">
19+
<location x="966.453535692138757" y="44.073259917535268" z="7.491470058587191"/>
20+
</instance>
21+
</population>
22+
<inputList id="Stim_iclamp_0" population="pop_AIY" component="iclamp_0">
23+
<input id="0" target="../pop_AIY/0/AIY" destination="synapses"/>
24+
</inputList>
25+
</network>
26+
</neuroml>

NeuroML/LEMS_Sim_IClamp_AIY.xml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<Lems>
2+
3+
<!--
4+
5+
This LEMS file has been automatically generated using PyNeuroML v1.3.13 (libNeuroML v0.6.6)
6+
7+
-->
8+
9+
<!-- Specify which component to run -->
10+
<Target component="Sim_IClamp_AIY" reportFile="report.Sim_IClamp_AIY.txt"/>
11+
12+
<!-- Include core NeuroML2 ComponentType definitions -->
13+
<Include file="Cells.xml"/>
14+
<Include file="Networks.xml"/>
15+
<Include file="Simulation.xml"/>
16+
17+
<Include file="PyNN.xml"/>
18+
<Include file="IClamp_AIY.net.nml"/>
19+
<Include file="AIY.cell.nml"/>
20+
21+
<Simulation id="Sim_IClamp_AIY" length="11000.0ms" step="0.025ms" target="IClamp_AIY" seed="12345"> <!-- Note seed: ensures same random numbers used every run -->
22+
<Display id="pop_AIY_0_biophys_membraneProperties_leak_chans_gDensity" title="Plots of pop_AIY_0_biophys_membraneProperties_leak_chans_gDensity" timeScale="1ms" xmin="-1100.0" xmax="12100.000000000002" ymin="-1" ymax="1">
23+
<Line id="pop_AIY_0_AIY_biophys_membraneProperties_leak_chans_gDensity" quantity="pop_AIY/0/AIY/biophys/membraneProperties/leak_chans/gDensity" scale="1" color="#d54f33" timeScale="1ms"/>
24+
</Display>
25+
26+
<Display id="pop_AIY_0_biophys_membraneProperties_leak_chans_iDensity" title="Plots of pop_AIY_0_biophys_membraneProperties_leak_chans_iDensity" timeScale="1ms" xmin="-1100.0" xmax="12100.000000000002" ymin="-1" ymax="1">
27+
<Line id="pop_AIY_0_AIY_biophys_membraneProperties_leak_chans_iDensity" quantity="pop_AIY/0/AIY/biophys/membraneProperties/leak_chans/iDensity" scale="1" color="#0534e4" timeScale="1ms"/>
28+
</Display>
29+
30+
<Display id="pop_AIY_0_caConc" title="Plots of pop_AIY_0_caConc" timeScale="1ms" xmin="-1100.0" xmax="12100.000000000002" ymin="-1" ymax="1">
31+
<Line id="pop_AIY_0_AIY_caConc" quantity="pop_AIY/0/AIY/caConc" scale="1" color="#98e752" timeScale="1ms"/>
32+
</Display>
33+
34+
<Display id="pop_AIY_v" title="Plots of pop_AIY_v" timeScale="1ms" xmin="-1100.0" xmax="12100.000000000002" ymin="-80" ymax="40">
35+
<Line id="pop_AIY_0_AIY_v" quantity="pop_AIY/0/AIY/v" scale="1mV" color="#bca074" timeScale="1ms"/>
36+
</Display>
37+
38+
<OutputFile id="Sim_IClamp_AIY_pop_AIY_v_dat" fileName="Sim_IClamp_AIY.pop_AIY.v.dat">
39+
<OutputColumn id="pop_AIY_0_AIY_v" quantity="pop_AIY/0/AIY/v"/>
40+
</OutputFile>
41+
42+
<OutputFile id="pop_AIY_0_biophys_membraneProperties_leak_chans_gDensity_dat" fileName="pop_AIY_0.biophys_membraneProperties_leak_chans_gDensity.dat">
43+
<OutputColumn id="pop_AIY_0_AIY_biophys_membraneProperties_leak_chans_gDensity" quantity="pop_AIY/0/AIY/biophys/membraneProperties/leak_chans/gDensity"/>
44+
</OutputFile>
45+
46+
<OutputFile id="pop_AIY_0_biophys_membraneProperties_leak_chans_iDensity_dat" fileName="pop_AIY_0.biophys_membraneProperties_leak_chans_iDensity.dat">
47+
<OutputColumn id="pop_AIY_0_AIY_biophys_membraneProperties_leak_chans_iDensity" quantity="pop_AIY/0/AIY/biophys/membraneProperties/leak_chans/iDensity"/>
48+
</OutputFile>
49+
50+
<OutputFile id="pop_AIY_0_caConc_dat" fileName="pop_AIY_0.caConc.dat">
51+
<OutputColumn id="pop_AIY_0_AIY_caConc" quantity="pop_AIY/0/AIY/caConc"/>
52+
</OutputFile>
53+
54+
</Simulation>
55+
56+
</Lems>

0 commit comments

Comments
 (0)