Ex26: Connection Weights

Weighted chemical, electrical, continuous connections and weighted inputs

Model: Weighted Connections

Demonstrates all weight-bearing connection types in NeuroML2:

  • Chemical: <connection> (weight=1) and <connectionWD> (weight=0.5/2, delay=20/40ms)
  • Electrical: <electricalConnectionInstanceW> (weight=1/0.5/2)
  • Continuous: <continuousConnectionInstanceW> (weight=1/0.5/2)
  • Inputs: <inputList>/<inputW> (weight=1/0.5/2)

3 pre-synaptic HH cells receive weighted current injection; 9 post-synaptic HH cells receive synaptic input via different projection types.


1. Define Network in TVBO

from tvbo import SimulationExperiment

exp = SimulationExperiment.from_string("""
label: "NeuroML Ex26: Weights"
network:
  dynamics:
    hhcell:
      name: hhcell
      iri: neuroml:cell
      parameters:
        v0: { value: -65, unit: mV }
        specificCapacitance: { value: 1.0, unit: uF_per_cm2 }
        spikeThresh: { value: -20, unit: mV }
        diameter: { value: 17.841242 }
      components:
        passiveChan:
          name: passiveChan
          iri: neuroml:ionChannelHH
          parameters:
            conductance: { value: 10, unit: pS }
            condDensity: { value: 0.0003, unit: S_per_cm2 }
            erev: { value: -54.3, unit: mV }
            ion: non_specific
        naChan:
          name: naChan
          iri: neuroml:ionChannelHH
          parameters:
            conductance: { value: 10, unit: pS }
            condDensity: { value: 120.0, unit: mS_per_cm2 }
            erev: { value: 50.0, unit: mV }
            ion: na
            species: na
          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 }
        kChan:
          name: kChan
          iri: neuroml:ionChannelHH
          parameters:
            conductance: { value: 10, unit: pS }
            condDensity: { value: 36, unit: mS_per_cm2 }
            erev: { value: -77, unit: mV }
            ion: k
            species: k
          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 }
    pulseGen2:
      name: pulseGen2
      iri: neuroml:pulseGenerator
  nodes:
    # Pre-synaptic cells (3)
    - { id: 0, dynamics: hhcell }
    - { id: 1, dynamics: hhcell }
    - { id: 2, dynamics: hhcell }
    # Post-synaptic cells (9): chemical (0-2), electrical (3-5), continuous (6-8)
    - { id: 10, dynamics: hhcell }
    - { id: 11, dynamics: hhcell }
    - { id: 12, dynamics: hhcell }
    - { id: 13, dynamics: hhcell }
    - { id: 14, dynamics: hhcell }
    - { id: 15, dynamics: hhcell }
    - { id: 16, dynamics: hhcell }
    - { id: 17, dynamics: hhcell }
    - { id: 18, dynamics: hhcell }
    # Input nodes (one pulseGenerator, connected to 3 pre-cells with weights)
    - id: 100
      dynamics: pulseGen2
      parameters:
        delay: { value: 100, unit: ms }
        duration: { value: 100, unit: ms }
        amplitude: { value: 0.068, unit: nA }
  edges:
    # Weighted current inputs to pre-synaptic cells
    - { source: 100, target: 0, parameters: { weight: { value: 1 } } }
    - { source: 100, target: 1, parameters: { weight: { value: 0.5 } } }
    - { source: 100, target: 2, parameters: { weight: { value: 2 } } }
    # Chemical projections: pre[0] → post[10,11,12]
    - source: 0
      target: 10
      coupling: expOneSynapse
      parameters:
        gbase: { value: 0.2, unit: nS }
        erev: { value: 0, unit: mV }
        tauDecay: { value: 2, unit: ms }
    - source: 0
      target: 11
      coupling: expOneSynapse
      parameters:
        gbase: { value: 0.2, unit: nS }
        erev: { value: 0, unit: mV }
        tauDecay: { value: 2, unit: ms }
        weight: { value: 0.5 }
        delay: { value: 20, unit: ms }
    - source: 0
      target: 12
      coupling: expOneSynapse
      parameters:
        gbase: { value: 0.2, unit: nS }
        erev: { value: 0, unit: mV }
        tauDecay: { value: 2, unit: ms }
        weight: { value: 2 }
        delay: { value: 40, unit: ms }
    # Electrical projections (gap junctions): pre[0] → post[13,14,15]
    - source: 0
      target: 13
      coupling: gapJunction
      parameters:
        conductance: { value: 100, unit: pS }
        weight: { value: 1 }
    - source: 0
      target: 14
      coupling: gapJunction
      parameters:
        conductance: { value: 100, unit: pS }
        weight: { value: 0.5 }
    - source: 0
      target: 15
      coupling: gapJunction
      parameters:
        conductance: { value: 100, unit: pS }
        weight: { value: 2 }
    # Continuous projections (graded synapses): pre[0] → post[16,17,18]
    - source: 0
      target: 16
      coupling: gradedSynapse
      parameters:
        conductance: { value: 0.1, unit: nS }
        delta: { value: 5, unit: mV }
        Vth: { value: -35, unit: mV }
        k: { value: 0.025, unit: per_ms }
        erev: { value: 0, unit: mV }
        weight: { value: 1 }
    - source: 0
      target: 17
      coupling: gradedSynapse
      parameters:
        conductance: { value: 0.1, unit: nS }
        delta: { value: 5, unit: mV }
        Vth: { value: -35, unit: mV }
        k: { value: 0.025, unit: per_ms }
        erev: { value: 0, unit: mV }
        weight: { value: 0.5 }
    - source: 0
      target: 18
      coupling: gradedSynapse
      parameters:
        conductance: { value: 0.1, unit: nS }
        delta: { value: 5, unit: mV }
        Vth: { value: -35, unit: mV }
        k: { value: 0.025, unit: per_ms }
        erev: { value: 0, unit: mV }
        weight: { value: 2 }

integration:
  method: euler
  step_size: 0.005
  duration: 300.0
  time_scale: ms
""")
print(f"Network nodes: {len(exp.network.nodes)}")
print(f"Network edges: {len(exp.network.edges)}")
Network nodes: 13
Network edges: 12
* Owlready2 * Warning: ignoring cyclic subclass of/subproperty of, involving:
  http://uri.interlex.org/tgbugs/uris/readable/atlas/Space

2. Render LEMS XML

xml = exp.render("lems")
print(xml[:2000])
<Lems>

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

  <!-- ════════════════════════════════════════════════════════════════
       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 ── -->
  <ComponentType name="hhcell" extends="baseCellMembPot">
    <Parameter name="diameter" dimension="none"/>
    <Parameter name="specificCapacitance" dimension="none"/>
    <Parameter name="spikeThresh" 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_inst" type="hhcell" diameter="17.841242" specificCapacitance="1.0" spikeThresh="-20 mV" v0="-65 mV"/>


  <!-- ════════════════════════════════════════════════════════════════
       Built-in/named synapse definitions (no custom ODE dynamics)
       ════════════════════════════════════════════════════════════════ -->
  <!-- Synapse: expOneSynapse (expOneSynapse) -->
  <expOneSynapse id="expOneSynapse" erev="0 mV" gbase="0.2 nS" tauDecay="2 ms"/>
  <!-- Synapse: gapJunction (gapJunction) -->
  <gapJunction id="gapJunction" conductance="100 pS"/>
  <!-- Synapse: gradedSynapse (g

3. Run Reference

from tvbo.adapters.neuroml import run_lems_example

ref_outputs = run_lems_example("LEMS_NML2_Ex26_Weights.xml")
for name, arr in ref_outputs.items():
    print(f"  {name}: shape={arr.shape}")
  ex26.dat: shape=(60001, 10)
  ex26_pre.dat: shape=(60001, 4)

4. Run TVBO

result = exp.run("neuroml")
da = result.integration.data
print(f"TVBO: {da.dims}, shape={da.shape}")
pyNeuroML >>> 13:06:52 - INFO - Loading LEMS file: tvbo_lems_sim.xml and running with jNeuroML
pyNeuroML >>> 13:06:52 - 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/tmpm0zmilc1
pyNeuroML >>> 13:06:58 - INFO - Command completed successfully!
TVBO: ('time', 'quantity'), shape=(60001, 12)

5. Compare & Plot

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