Skip to content

Commit f1be0d6

Browse files
committed
The RE comparison process has been updated.
1 parent 48417b2 commit f1be0d6

File tree

146 files changed

+2302
-11519
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

146 files changed

+2302
-11519
lines changed

NeuroML2/compare_MC/RE/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
`auto_compare.sh` provides the following modes:
2+
3+
- `--pas-nrn`
4+
NeuroML vs NEURON, passive (pas-only/leaky) cell.
5+
6+
- `--hh2-nrn`
7+
NeuroML vs NEURON, original mechanism (`HH2.mod``hh2ad`).
8+
9+
- `--hh2-cnexp-nrn`
10+
NeuroML vs NEURON, hh2 with cnexp mechanisms (`hh2_na_cnexp.mod` + `hh2_k_cnexp.mod`, `SUFFIX hh2_na/hh2_k`).
11+
12+
- `--hh2-hh2ad-vs-split`
13+
NEURON vs NEURON, direct comparison of `hh2ad` (HH2.mod) vs split `hh2_na+hh2_k` on the same cell.
14+
15+
Usage example (from this directory):
16+
17+
```bash
18+
chmod +x auto_compare.sh
19+
20+
./auto_compare.sh --pas-nrn
21+
./auto_compare.sh --hh2-nrn
22+
./auto_compare.sh --hh2-cnexp-nrn
23+
./auto_compare.sh --hh2-hh2ad-vs-split
24+
```
25+
26+
Notes:
27+
28+
- The NeuroML-based scripts (`run_nml_hh2.py`, `run_nml_leaky.py`, `omv_test.py`) will automatically set `NEURON_HOME` if it is not already defined, by locating `nrniv` on your `PATH`.
29+
30+
31+
In the mod folder, there are the original file HH2.mod, the files hh2_k.mod and hh2_na.mod exported from NeuroML, as well as the modified mod files mod/hh2_na_cnexp.mod and mod/hh2_k_cnexp.mod (the purpose is to demonstrate why the mod files exported from NeuroML cannot be recognized as cnexp format). By using nrnivmodl mod to check the C files, the differences can be observed.
32+
33+
Result: The difference in the leak channel is 0. After incorporating hh2ad, there is a significant numerical discrepancy during action potential generation. While the discrepancy for a single channel may be acceptable, when all ion channels are combined, it leads to the generation of an additional spike.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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="RE_hh2">
2+
<notes>NeuroML cell with only hh2_na/hh2_k and passive leak</notes>
3+
<include href="hh2_na.channel.nml"/>
4+
<include href="hh2_k.channel.nml"/>
5+
<include href="pas.channel.nml"/>
6+
7+
<cell id="RE_hh2_cell">
8+
<notes>Single-compartment soma</notes>
9+
<morphology id="morphology">
10+
<segment id="0" name="Seg0_soma">
11+
<proximal x="0.0" y="0.0" z="0.0" diameter="70.0"/>
12+
<distal x="0.0" y="64.86" z="0.0" diameter="70.0"/>
13+
</segment>
14+
</morphology>
15+
<biophysicalProperties id="biophys">
16+
<membraneProperties>
17+
<channelDensity id="pas_soma" ionChannel="pas" condDensity="5e-5 S_per_cm2" erev="-77.0 mV" ion="non_specific"/>
18+
<channelDensity ionChannel="hh2_k" id="hh2_k_soma" ion="k" erev="-95.0 mV" condDensity="0.01 S_per_cm2"/>
19+
<channelDensity ionChannel="hh2_na" id="hh2_na_soma" ion="na" erev="50.0 mV" condDensity="0.09 S_per_cm2"/>
20+
<spikeThresh value="5mV"/>
21+
<specificCapacitance value="1 uF_per_cm2"/>
22+
<initMembPotential value="-70mV"/>
23+
</membraneProperties>
24+
<intracellularProperties>
25+
<resistivity value="100 ohm_cm"/>
26+
</intracellularProperties>
27+
</biophysicalProperties>
28+
</cell>
29+
</neuroml>
30+

NeuroML2/compare_MC/RE/RE_netpy.py

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
import os
2+
# Force headless plotting for Matplotlib
3+
os.environ["MPLBACKEND"] = "Agg"
4+
import matplotlib
5+
matplotlib.use("Agg")
6+
# Ensure NEURON runs headless in non-GUI environments
7+
os.environ["NEURON_NO_GUI"] = "1"
8+
os.environ.pop("DISPLAY", None)
9+
print(f"[RE_netpy] Headless env: DISPLAY={os.environ.get('DISPLAY')}, NEURON_NO_GUI={os.environ.get('NEURON_NO_GUI')}, MPLBACKEND={os.environ.get('MPLBACKEND')}")
110
from netpyne import specs, sim
211
import pprint
312

@@ -12,8 +21,8 @@
1221
soma['ions']['na'] = {'e': 50.0, 'i': 10.0, 'o': 140.0}
1322
soma['mechs']['pas'] = {'g': 5e-5, 'e': -77}
1423
soma['mechs']['cadad'] = {'cainf': 0.00024, 'depth': 1, 'kd': 0.0, 'kt': 0.0, 'taur': 5}
15-
# soma['mechs']['kl'] = {'gmax': 3e-06}
16-
# soma['mechs']['itre'] = {"gmax": 0.002,"shift": 2.0}
24+
soma['mechs']['kl'] = {'gmax': 3e-06}
25+
soma['mechs']['itre'] = {"gmax": 0.002,"shift": 2.0}
1726
soma['mechs']['hh2ad'] = {"gkbar": 0.01,"gnabar": 0.09,"vtraub": -50.0}
1827

1928

@@ -25,7 +34,7 @@
2534

2635
netParams.popParams['RE'] = {'cellType': 'RE_HH_reduced', 'numCells': 1}
2736

28-
netParams.stimSourceParams['Input'] = {'type': 'IClamp', 'dur': 500, 'del': 200, 'amp': 0.3}
37+
netParams.stimSourceParams['Input'] = {'type': 'IClamp', 'dur': 500, 'del': 200, 'amp': 0.03}
2938
netParams.stimTargetParams['Input->RE'] = {'source': 'Input', 'sec': 'soma', 'loc': 0.5, 'conds': {'cellType': 'RE_HH_reduced'}}
3039
netParams.defaultThreshold = 5.0
3140
# Simulation options
@@ -34,28 +43,42 @@
3443
simConfig.recordCells = ['all']
3544
simConfig.hParams['celsius'] = 34
3645
simConfig.duration = 1000 # Duration of the simulation, in ms
37-
simConfig.dt = 0.001
46+
simConfig.dt = 0.025
3847
# Internal integration timestep to use
3948
simConfig.verbose = True # Show detailed messages
4049

4150

42-
simConfig.recordTraces = {'V_soma':{'sec':'soma','loc':0.5,'var':'v'},
51+
simConfig.recordTraces = {
52+
# Membrane
53+
'V_soma':{'sec':'soma','loc':0.5,'var':'v'},
54+
'cai':{'sec':'soma','loc':0.5,'var':'cai'},
55+
# HH Na/K (Traub hh2ad)
4356
'm_hh2_na':{'sec': 'soma', 'loc': 0.5, 'mech': 'hh2ad', 'var': 'm'},
4457
'h_hh2_na':{'sec': 'soma', 'loc': 0.5, 'mech': 'hh2ad', 'var': 'h'},
45-
'n_hh2_k':{'sec': 'soma', 'loc': 0.5, 'mech': 'hh2ad', 'var': 'n'},
58+
'n_hh2_k':{'sec': 'soma', 'loc': 0.5, 'mech': 'hh2ad', 'var': 'n'},
59+
# T type Ca channel (itre) from IT2.mod: states m,h; mechanism current 'i'
60+
'm_itre':{'sec': 'soma', 'loc': 0.5, 'mech': 'itre', 'var': 'm'},
61+
'h_itre':{'sec': 'soma', 'loc': 0.5, 'mech': 'itre', 'var': 'h'},
62+
'i_itre':{'sec': 'soma', 'loc': 0.5, 'mech': 'itre', 'var': 'i'},
63+
# Passive leak K channel current uses variable 'i' in kl.mod
64+
'i_kl':{'sec': 'soma', 'loc': 0.5, 'mech': 'kl', 'var': 'i'},
65+
# Total ionic currents for reference
4666
'ina':{'sec': 'soma', 'loc': 0.5, 'var': 'ina'},
47-
'ik':{'sec': 'soma', 'loc': 0.5, 'var': 'ik'}} # Dict with traces to record
67+
'ik':{'sec': 'soma', 'loc': 0.5, 'var': 'ik'},
68+
'ica':{'sec': 'soma', 'loc': 0.5, 'var': 'ica'}
69+
} # Dict with traces to record
4870

4971

50-
simConfig.recordStep = 0.001 # Step size in ms to save data (eg. V traces, LFP, etc)
51-
simConfig.filename = 'RE_reduced_hh2' # Set file output name
72+
simConfig.recordStep = 0.025 # Match integration step for high‑res alignment
73+
simConfig.filename = 'RE_full_data' # Set file output name
5274
simConfig.savePickle = False # Save params, network and sim output to pickle file
5375
simConfig.saveDataInclude = ['simData']
54-
simConfig.saveJson = True
55-
simConfig.analysis['plotTraces'] = {'include': [0], 'saveFig': True} # Plot recorded traces for this list of cells
56-
simConfig.analysis['plotRaster'] = {'saveFig': True} # Plot a raster
76+
# 以 NetPyNE 默认方式保存 JSON(兼容不同版本)
77+
simConfig.saveJson = True
78+
# Disable built-in plotting during headless runs to avoid DISPLAY issues
79+
simConfig.analysis = {}
5780

5881
# Create network and run simulation
5982
sim.createSimulateAnalyze(netParams = netParams, simConfig = simConfig)
6083

61-
#import pylab; pylab.show() # this line is only necessary in certain systems where figures appear empty
84+
#import pylab; pylab.show() # this line is only necessary in certain systems where figures appear empty

NeuroML2/compare_MC/RE/RE_reduced_cell.nml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@
2828
</morphology>
2929
<biophysicalProperties id="biophys">
3030
<membraneProperties>
31+
<channelDensityNernst id="itre_soma" ionChannel="itre" condDensity="0.002 S_per_cm2" ion="ca"/>
3132

3233
<channelDensity ionChannel="pas" id="pas_soma" ion="non_specific" erev="-77.0 mV" condDensity="5e-5 S_per_cm2"/>
33-
34+
<channelDensity ionChannel="kl" id="kl_soma" ion="k" erev="-95.0 mV" condDensity="3e-06 S_per_cm2"/>
3435
<channelDensity ionChannel="hh2_k" id="hh2_k_soma" ion="k" erev="-95.0 mV" condDensity="0.01 S_per_cm2"/>
35-
3636
<channelDensity ionChannel="hh2_na" id="hh2_na_soma" ion="na" erev="50.0 mV" condDensity="0.09 S_per_cm2"/>
37-
37+
3838
<spikeThresh value="5mV"/>
3939
<specificCapacitance value="1 uF_per_cm2"/>
4040
<initMembPotential value="-70mV"/>

NeuroML2/compare_MC/RE/RE_reduced_cellParams.json

Lines changed: 0 additions & 75 deletions
This file was deleted.
-102 KB
Binary file not shown.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
usage() {
5+
cat <<'USAGE'
6+
Usage: ./auto_compare.sh [--pas-nrn | --hh2-nrn | --hh2-cnexp-nrn | --hh2-hh2ad-vs-split] [--help]
7+
8+
Options:
9+
--pas-nrn Run passive (pas) NEURON (Python) vs NeuroML comparison
10+
--hh2-nrn Run hh2 (Traub Na/K, HH2.mod) NEURON (Python) vs NeuroML comparison
11+
--hh2-cnexp-nrn Run hh2 (Na/K split cnexp: hh2_na_cnexp/hh2_k_cnexp) NEURON (Python) vs NeuroML comparison
12+
--hh2-hh2ad-vs-split Run NEURON hh2ad (HH2.mod) vs split hh2_na+hh2_k comparison
13+
-h, --help Show this help
14+
USAGE
15+
}
16+
17+
run_hh2_nrn() {
18+
echo "[NRN-HH2 1/4] Compile mechanisms from mod/ (HH2.mod -> hh2ad)"
19+
rm -rf x86_64 || true
20+
nrnivmodl mod
21+
22+
echo "[NRN-HH2 2/4] Running pure NEURON (Python) hh2 (dt=0.025 ms)"
23+
python3 run_neuron_hh2.py
24+
25+
echo "[NRN-HH2 3/4] Running NeuroML hh2 (dt=0.025 ms)"
26+
python3 run_nml_hh2.py
27+
28+
echo "[NRN-HH2 4/4] Comparing traces (high-res, step-aligned)"
29+
python3 compare_neuron_nml_hh2.py
30+
31+
echo "[NRN-HH2] Done. See compare_out/hh2_neuron_vs_nml for outputs."
32+
}
33+
34+
run_hh2_cnexp_nrn() {
35+
echo "[NRN-HH2-CNEXP 1/4] Compile mechanisms from mod/ (hh2_na_cnexp.mod, hh2_k_cnexp.mod, HH2.mod)"
36+
rm -rf x86_64 || true
37+
nrnivmodl mod
38+
39+
echo "[NRN-HH2-CNEXP 2/4] Running pure NEURON (Python) hh2 cnexp split (dt=0.025 ms)"
40+
python3 run_neuron_hh2_cnexp.py
41+
42+
echo "[NRN-HH2-CNEXP 3/4] Running NeuroML hh2 (dt=0.025 ms)"
43+
python3 run_nml_hh2.py
44+
45+
echo "[NRN-HH2-CNEXP 4/4] Comparing traces (high-res, step-aligned)"
46+
python3 compare_neuron_nml_hh2_cnexp.py
47+
48+
echo "[NRN-HH2-CNEXP] Done. See compare_out/hh2_cnexp_neuron_vs_nml for outputs."
49+
}
50+
51+
run_pas_nrn() {
52+
echo "[NRN-PAS 1/3] Running pure NEURON (Python) passive (dt=0.025 ms)"
53+
python3 run_neuron_pas.py
54+
55+
echo "[NRN-PAS 2/3] Running NeuroML leaky (dt=0.025 ms)"
56+
python3 run_nml_leaky.py
57+
58+
echo "[NRN-PAS 3/3] Comparing traces (high-res, step-aligned)"
59+
python3 compare_neuron_nml_pas.py
60+
61+
echo "[NRN-PAS] Done. See compare_out/leaky_neuron_vs_nml for outputs."
62+
}
63+
64+
run_hh2_hh2ad_vs_split() {
65+
echo "[RE hh2 hh2ad vs (hh2_na+hh2_k) 1/4] Compiling NEURON mechanisms (mod/hh2_na.mod, mod/hh2_k.mod, HH2.mod, pas_nml2.mod, etc.)"
66+
rm -rf x86_64 || true
67+
nrnivmodl mod
68+
69+
echo "[RE hh2 hh2ad vs (hh2_na+hh2_k) 2/4] Running NEURON hh2ad (HH2.mod, dt=0.025 ms)"
70+
python3 run_neuron_hh2.py
71+
72+
echo "[RE hh2 hh2ad vs (hh2_na+hh2_k) 3/4] Running NEURON split hh2 (hh2_na+hh2_k, dt=0.025 ms)"
73+
python3 run_neuron_hh2_split.py
74+
75+
echo "[RE hh2 hh2ad vs (hh2_na+hh2_k) 4/4] Comparing mechanisms and generating plots"
76+
python3 compare_neuron_hh2_hh2ad_vs_split.py
77+
78+
echo "[RE hh2 hh2ad vs (hh2_na+hh2_k)] Done. See compare_out/hh2_hh2ad_vs_split_neuron for results."
79+
}
80+
81+
main() {
82+
case "${1-}" in
83+
--pas-nrn)
84+
run_pas_nrn
85+
;;
86+
--hh2-nrn)
87+
run_hh2_nrn
88+
;;
89+
--hh2-cnexp-nrn)
90+
run_hh2_cnexp_nrn
91+
;;
92+
--hh2-hh2ad-vs-split)
93+
run_hh2_hh2ad_vs_split
94+
;;
95+
-h|--help|"")
96+
usage
97+
;;
98+
*)
99+
echo "Unknown option: $1" >&2
100+
usage
101+
exit 1
102+
;;
103+
esac
104+
}
105+
106+
main "$@"
-1010 KB
Binary file not shown.
-1.01 MB
Binary file not shown.
-56.7 KB
Binary file not shown.

0 commit comments

Comments
 (0)