Ex3: HH Network with Synapses

Network of HH cells connected by expOneSynapse, expTwoSynapse, and alphaSynapse

Model: HH Network

This example connects a pre-synaptic HH cell to three post-synaptic passive cells via different synapse types (expOneSynapse, expTwoSynapse, alphaSynapse).

Cell types use standard NeuroML types (pointCellCondBased) with hierarchical components: composition trees. Synapses use standard NeuroML synapse types on network edges. The simulated traces match the reference jNeuroML simulation to correlation r ≈ 1; the emitted XML is equivalent, not byte-identical, to the canonical NeuroML file.


1. Define Network in TVBO

from tvbo import SimulationExperiment

exp = SimulationExperiment.from_string("""
label: "NeuroML Ex3: HH Network"
dynamics:
  name: hhcell_1
  iri: neuroml:pointCellCondBased
  parameters:
    C:      { value: 10, unit: pF }
    v0:     { value: -65, unit: mV }
    thresh: { value: 20, unit: mV }
  components:
    passive:
      name: passive
      iri: neuroml:ionChannelPassive
      parameters:
        conductance: { value: 10, unit: pS }
        number:      { value: 300 }
        erev:        { value: -54.3, unit: mV }
    na:
      name: na
      iri: neuroml:ionChannelHH
      parameters:
        conductance: { value: 10, unit: pS }
        number:      { value: 120000 }
        erev:        { value: 50, unit: mV }
      components:
        m:
          name: m
          iri: neuroml:gateHHrates
          parameters: { instances: { value: 3 } }
          components:
            forwardRate:
              name: forwardRate
              iri: neuroml:HHExpLinearRate
              parameters:
                rate:     { value: 1, unit: per_ms }
                midpoint: { value: -40, unit: mV }
                scale:    { value: 10, unit: mV }
            reverseRate:
              name: reverseRate
              iri: neuroml:HHExpRate
              parameters:
                rate:     { value: 4, unit: per_ms }
                midpoint: { value: -65, unit: mV }
                scale:    { value: -18, unit: mV }
        h:
          name: h
          iri: neuroml:gateHHrates
          parameters: { instances: { value: 1 } }
          components:
            forwardRate:
              name: forwardRate
              iri: neuroml:HHExpRate
              parameters:
                rate:     { value: 0.07, unit: per_ms }
                midpoint: { value: -65, unit: mV }
                scale:    { value: -20, unit: mV }
            reverseRate:
              name: reverseRate
              iri: neuroml:HHSigmoidRate
              parameters:
                rate:     { value: 1, unit: per_ms }
                midpoint: { value: -35, unit: mV }
                scale:    { value: 10, unit: mV }
    k:
      name: k
      iri: neuroml:ionChannelHH
      parameters:
        conductance: { value: 10, unit: pS }
        number:      { value: 36000 }
        erev:        { value: -77, unit: mV }
      components:
        n:
          name: n
          iri: neuroml:gateHHrates
          parameters: { instances: { value: 4 } }
          components:
            forwardRate:
              name: forwardRate
              iri: neuroml:HHExpLinearRate
              parameters:
                rate:     { value: 0.1, unit: per_ms }
                midpoint: { value: -55, unit: mV }
                scale:    { value: 10, unit: mV }
            reverseRate:
              name: reverseRate
              iri: neuroml:HHExpRate
              parameters:
                rate:     { value: 0.125, unit: per_ms }
                midpoint: { value: -65, unit: mV }
                scale:    { value: -80, unit: mV }

network:
  number_of_nodes: 5
  dynamics:
    hhcell_1:
      name: hhcell_1
      iri: neuroml:pointCellCondBased
      parameters:
        C:      { value: 10, unit: pF }
        v0:     { value: -65, unit: mV }
        thresh: { value: 20, unit: mV }
      components:
        passive:
          name: passive
          iri: neuroml:ionChannelPassive
          parameters:
            conductance: { value: 10, unit: pS }
            number:      { value: 300 }
            erev:        { value: -54.3, unit: mV }
        na:
          name: na
          iri: neuroml:ionChannelHH
          parameters:
            conductance: { value: 10, unit: pS }
            number:      { value: 120000 }
            erev:        { value: 50, unit: mV }
          components:
            m:
              name: m
              iri: neuroml:gateHHrates
              parameters: { instances: { value: 3 } }
              components:
                forwardRate:
                  name: forwardRate
                  iri: neuroml:HHExpLinearRate
                  parameters:
                    rate:     { value: 1, unit: per_ms }
                    midpoint: { value: -40, unit: mV }
                    scale:    { value: 10, unit: mV }
                reverseRate:
                  name: reverseRate
                  iri: neuroml:HHExpRate
                  parameters:
                    rate:     { value: 4, unit: per_ms }
                    midpoint: { value: -65, unit: mV }
                    scale:    { value: -18, unit: mV }
            h:
              name: h
              iri: neuroml:gateHHrates
              parameters: { instances: { value: 1 } }
              components:
                forwardRate:
                  name: forwardRate
                  iri: neuroml:HHExpRate
                  parameters:
                    rate:     { value: 0.07, unit: per_ms }
                    midpoint: { value: -65, unit: mV }
                    scale:    { value: -20, unit: mV }
                reverseRate:
                  name: reverseRate
                  iri: neuroml:HHSigmoidRate
                  parameters:
                    rate:     { value: 1, unit: per_ms }
                    midpoint: { value: -35, unit: mV }
                    scale:    { value: 10, unit: mV }
        k:
          name: k
          iri: neuroml:ionChannelHH
          parameters:
            conductance: { value: 10, unit: pS }
            number:      { value: 36000 }
            erev:        { value: -77, unit: mV }
          components:
            n:
              name: n
              iri: neuroml:gateHHrates
              parameters: { instances: { value: 4 } }
              components:
                forwardRate:
                  name: forwardRate
                  iri: neuroml:HHExpLinearRate
                  parameters:
                    rate:     { value: 0.1, unit: per_ms }
                    midpoint: { value: -55, unit: mV }
                    scale:    { value: 10, unit: mV }
                reverseRate:
                  name: reverseRate
                  iri: neuroml:HHExpRate
                  parameters:
                    rate:     { value: 0.125, unit: per_ms }
                    midpoint: { value: -65, unit: mV }
                    scale:    { value: -80, unit: mV }
    hhcell_2:
      name: hhcell_2
      iri: neuroml:pointCellCondBased
      parameters:
        C:      { value: 10, unit: pF }
        v0:     { value: -55, unit: mV }
        thresh: { value: 20, unit: mV }
      components:
        leak:
          name: leak
          iri: neuroml:ionChannelPassive
          parameters:
            conductance: { value: 10, unit: pS }
            number:      { value: 300 }
            erev:        { value: -54.3, unit: mV }
  nodes:
    - id: 0
      dynamics: hhcell_1
      record: false
    - id: 1
      dynamics: hhcell_2
    - id: 2
      dynamics: hhcell_2
    - id: 3
      dynamics: hhcell_2
    - id: 100
      dynamics: pulseGenerator
      parameters:
        delay:     { value: 25, unit: ms }
        duration:  { value: 50, unit: ms }
        amplitude: { value: 0.065, unit: nA }
  edges:
    - source: 100
      target: 0
    - source: 0
      target: 1
      coupling: expOneSynapse
      parameters:
        gbase:    { value: 0.5, unit: nS }
        erev:     { value: 0, unit: mV }
        tauDecay: { value: 3, unit: ms }
    - source: 0
      target: 2
      coupling: expTwoSynapse
      parameters:
        gbase:    { value: 0.5, unit: nS }
        erev:     { value: 0, unit: mV }
        tauRise:  { value: 1, unit: ms }
        tauDecay: { value: 2, unit: ms }
    - source: 0
      target: 3
      coupling: alphaSynapse
      parameters:
        gbase: { value: 0.5, unit: nS }
        erev:  { value: 0, unit: mV }
        tau:   { value: 2, unit: ms }

integration:
  method: euler
  step_size: 0.005
  duration: 100.0
  time_scale: ms
""")
print(f"Model: {exp.dynamics.name if exp.dynamics else 'network'}")
print(f"Network nodes: {len(exp.network.nodes)}")
Model: hhcell_1
Network nodes: 5

2. Render LEMS XML

xml = exp.render("lems")
print(xml[:3000])

<Lems>

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

  <!-- ════════════════════════════════════════════════════════════════
       Standard NeuroML2 type includes for network mode.
       Provides all standard dimensions, units, synapse types, input
       types, network infrastructure, and simulation types.
       ════════════════════════════════════════════════════════════════ -->
  <Include file="Cells.xml"/>
  <Include file="Networks.xml"/>
  <Include file="Simulation.xml"/>

  <!-- ════════════════════════════════════════════════════════════════
       Dynamics ComponentType & Component instances
       ════════════════════════════════════════════════════════════════ -->


  <!-- ── ComponentType: hhcell_1 ── -->
  <ComponentType name="hhcell_1" extends="baseCellMembPot">
    <Parameter name="C" dimension="capacitance"/>
    <Parameter name="thresh" dimension="voltage"/>
    <Parameter name="v0" dimension="voltage"/>
    <Constant name="SEC" dimension="time" value="1ms"/>
    <!-- Dynamically attached synapses/inputs from network connections -->
    <Attachments name="synapses" type="basePointCurrent"/>

    <Dynamics>
      <!-- ── Flat dynamics ── -->
      <OnStart>
      </OnStart>
    </Dynamics>
  </ComponentType>

  <Component id="hhcell_1_inst" type="hhcell_1" C="10 pF" thresh="20 mV" v0="-65 mV"/>

  <!-- ── ComponentType: hhcell_2 ── -->
  <ComponentType name="hhcell_2" extends="baseCellMembPot">
    <Parameter name="C" dimension="capacitance"/>
    <Parameter name="thresh" dimension="voltage"/>
    <Parameter name="v0" dimension="voltage"/>
    <Constant name="SEC" dimension="time" value="1ms"/>
    <!-- Dynamically attached synapses/inputs from network connections -->
    <Attachments name="synapses" type="basePointCurrent"/>

    <Dynamics>
      <!-- ── Flat dynamics ── -->
      <OnStart>
      </OnStart>
    </Dynamics>
  </ComponentType>

  <Component id="hhcell_2_inst" type="hhcell_2" C="10 pF" thresh="20 mV" v0="-55 mV"/>


  <!-- ════════════════════════════════════════════════════════════════
       Built-in/named synapse definitions (no custom ODE dynamics)
       ════════════════════════════════════════════════════════════════ -->
  <!-- Synapse: expOneSynapse (expOneSynapse) -->
  <expOneSynapse id="expOneSynapse" erev="0 mV" gbase="0.5 nS" tauDecay="3 ms"/>
  <!-- Synapse: expTwoSynapse (expTwoSynapse) -->
  <expTwoSynapse id="expTwoSynapse" erev="0 mV" gbase="0.5 nS" tauDecay="2 ms" tauRise="1 ms"/>
  <!-- Synapse: alphaSynapse (alphaSynapse) -->
  <alphaSynapse id="alphaSynapse" erev="0 mV" gbase="0.5 nS" tau="2 ms"/>

  <!-- ════════════════════════════════════════════════════════════════
       Input Sources (pulseGenerator, spikeGenerator, spikeArray, etc.)
       ════════════════════════════════════════════════════════════════ -->
  <pulseGenerator id="pulseGenerator" amplitude="0.065 nA" delay="25 ms" duration="50 ms"/>

  

3. Run Reference

from tvbo.adapters.neuroml import run_lems_example

ref_outputs = run_lems_example("LEMS_NML2_Ex3_Net.xml")
for name, arr in ref_outputs.items():
    print(f"  {name}: shape={arr.shape}")
  ex3_v.dat: shape=(20001, 4)

4. Run TVBO

result = exp.run("neuroml")
da = result.integration.data
print(f"TVBO: {da.dims}, shape={da.shape}")
pyNeuroML >>> 19:11:22 - INFO - Loading LEMS file: tvbo_lems_sim.xml and running with jNeuroML
pyNeuroML >>> 19:11:22 - INFO - Executing: (java -Xmx400M  -Djava.awt.headless=true -jar  "/Users/leonmartin_bih/tools/tvbo/.venv/lib/python3.12/site-packages/pyneuroml/utils/./../lib/jNeuroML-0.14.0-jar-with-dependencies.jar"  tvbo_lems_sim.xml  -nogui -I '') in directory: /var/folders/ym/9kw1g21j1nd7kwfn8c0z3st40000gn/T/tmp71gn2yp3
pyNeuroML >>> 19:11:23 - INFO - Command completed successfully!
TVBO: ('time', 'quantity'), shape=(20001, 3)

5. Compare & Plot

from tvbo.adapters.neuroml import plot_lems_comparison
plot_lems_comparison("LEMS_NML2_Ex3_Net.xml", ref_outputs, result.integration.data, title_prefix="Ex3")