NML2: Analog Synapses

Graded (continuous) synaptic transmission between FHN cells

NML2_AnalogSynapses.nml

Demonstrates graded synaptic transmission using <gradedSynapse> — the postsynaptic current is a continuous function of presynaptic voltage, without discrete spike events. Uses FitzHugh-Nagumo cells.

from pathlib import Path

nml_file = Path.home() / "work_data/toolboxes/NeuroML2/examples/NML2_AnalogSynapses.nml"
text = nml_file.read_text()

for line in text.split('\n'):
    stripped = line.strip()
    if any(tag in stripped for tag in ['<gradedSynapse', '<silentSynapse',
           '<fitzHugh', '<network', '<population', '<continuousProjection',
           '<continuousConnection']):
        print(stripped[:120])
<silentSynapse id="silent1"/>
<silentSynapse id="silent2"/>
<gradedSynapse id="gs2" conductance="5pS" delta="5mV" Vth="-55mV" k="0.025per_ms" erev="0mV"/>
<network id="net1">
<population id="iafPop1" component="iaf" size="1" />
<population id="iafPop2" component="iaf" size="1" />
<population id="iafPop3" component="iaf" size="1" />
<continuousProjection id ="testLinearGradedConn" presynapticPopulation="iafPop1" postsynapticPopulation="iafPop2">
<continuousConnection id="0" preCell="0" postCell="0" preComponent="silent1" postComponent="gs1"/>
<continuousProjection id ="testGradedConn" presynapticPopulation="iafPop1" postsynapticPopulation="iafPop3">
<continuousConnection id="0" preCell="0" postCell="0" preComponent="silent2" postComponent="gs2"/>

TVBO Representation: FHN Cell

from tvbo import SimulationExperiment

exp = SimulationExperiment.from_string("""
label: "NML2 AnalogSynapses: FHN Cell"
dynamics:
  name: FitzHughNagumo
  parameters:
    I: { value: 0.8 }
  state_variables:
    V:
      equation: { rhs: "V - V**3/3 - W + I" }
      initial_value: 0.0
      variable_of_interest: true
    W:
      equation: { rhs: "0.08*(V + 0.7 - 0.8*W)" }
      initial_value: 0.0
network:
  number_of_nodes: 1
integration:
  method: euler
  step_size: 0.01
  duration: 200.0
  time_scale: s
""")
xml = exp.render("lems")
print(xml[:800])

<Lems>

  <!-- Tell jLEMS/jNeuroML which component is the simulation entry point. -->
  <Target component="sim_NML2_AnalogSynapses__FHN_Cell"/>

  <!-- ════════════════════════════════════════════════════════════════
       Dimensions & Units (inline — no external includes needed)
       ════════════════════════════════════════════════════════════════ -->

  <!-- Dimensions -->
  <Dimension name="none"/>
  <Dimension name="time" t="1"/>
  <Dimension name="voltage" m="1" l="2" t="-3" i="-1"/>
  <Dimension name="per_time" t="-1"/>
  <Dimension name="conductance" m="-1" l="-2" t="3" i="2"/>
  <Dimension name="capacitance" m="-1" l="-2" t="4" i="2"/>
  <Dimension name="current" i="1"/>
  <Dimension name="resistance" m="1" l="2" t="-3" i="-2"/>
  <Dimension name="concentration" l="-3" n="1"/>

Run TVBO

import numpy as np
import matplotlib.pyplot as plt

result = exp.run("neuroml")
da = result.integration.data
t = da.coords['time'].values
vals = da.values

fig, ax = plt.subplots(figsize=(10, 4))
ax.plot(t, vals[:, 0], label='V')
ax.plot(t, vals[:, 1], label='W', alpha=0.7)
ax.set_xlabel("Time (s)")
ax.set_title("NML2 AnalogSynapses: FHN Cell via TVBO")
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()