Ex12: Network 2

Multiple spike sources and synapse types including NMDA with Mg²⁺ block

Model: Network 2

Nine iafCells receiving input from three spike sources (periodic generator, spike arrays) via three synapse types: expOneSynapse, expTwoSynapse, and NMDA blockingPlasticSynapse with Mg²⁺ voltage-dependent block. Demonstrates weight and delay modulation.

Reference: NeuroML2 LEMS_NML2_Ex12_Net2.xml


1. Define Network in TVBO

from tvbo import SimulationExperiment

exp = SimulationExperiment.from_string("""
label: "NeuroML Ex12: Network 2"
dynamics:
  name: iafCell
  iri: neuroml:iafCell
network:
  dynamics:
    iaf1:
      name: iaf1
      iri: neuroml:iafCell
      parameters:
        leakReversal: {value: -60, unit: mV}
        thresh: {value: -35, unit: mV}
        reset: {value: -65, unit: mV}
        C: {value: 10, unit: pF}
        leakConductance: {value: 0.5, unit: nS}
    spiker:
      name: spiker
      iri: neuroml:spikeGenerator
      parameters:
        period: {value: 30, unit: ms}
    spikes2:
      name: spikes2
      iri: neuroml:spikeArray
      events:
        s:
          event_type: preset_time
          trigger_times: [50, 100, 130]
    spike100:
      name: spike100
      iri: neuroml:spikeArray
      events:
        s:
          event_type: preset_time
          trigger_times: [100]
    # NMDA synapse with Mg²⁺ voltage-dependent block (defined with full
    # composition tree — blockMechanism is a child dynamics)
    synNmda:
      name: synNmda
      iri: neuroml:blockingPlasticSynapse
      parameters:
        gbase: {value: 5, unit: nS}
        tauDecay: {value: 10, unit: ms}
        tauRise: {value: 1, unit: ms}
        erev: {value: 0, unit: mV}
      modes:
        blockMechanism:
          name: blockMechanism
          iri: neuroml:voltageConcDepBlockMechanism
          parameters:
            species: {description: mg}
            blockConcentration: {value: 1.2, unit: mmol_per_m3}
            scalingConc: {value: 1.9205441817997078, unit: mmol_per_m3}
            scalingVolt: {value: 16.129032258064516, unit: mV}
  nodes:
    # 9 post-synaptic cells
    - {id: 0, dynamics: iaf1}
    - {id: 1, dynamics: iaf1}
    - {id: 2, dynamics: iaf1}
    - {id: 3, dynamics: iaf1}
    - {id: 4, dynamics: iaf1}
    - {id: 5, dynamics: iaf1}
    - {id: 6, dynamics: iaf1}
    - {id: 7, dynamics: iaf1}
    - {id: 8, dynamics: iaf1}
    # Spike sources
    - {id: 100, dynamics: spike100}
    - {id: 101, dynamics: spikes2}
    - {id: 102, dynamics: spiker}
  edges:
    # spike100 → iaf[0..2]: expOneSynapse, varying weight/delay
    - {source: 100, target: 0, coupling: expOneSynapse, parameters: {gbase: {value: 0.1, unit: nS}, erev: {value: 0, unit: mV}, tauDecay: {value: 2, unit: ms}}}
    - {source: 100, target: 1, coupling: expOneSynapse, parameters: {gbase: {value: 0.1, unit: nS}, erev: {value: 0, unit: mV}, tauDecay: {value: 2, unit: ms}, weight: {value: 0.5}, delay: {value: 10, unit: ms}}}
    - {source: 100, target: 2, coupling: expOneSynapse, parameters: {gbase: {value: 0.1, unit: nS}, erev: {value: 0, unit: mV}, tauDecay: {value: 2, unit: ms}, weight: {value: 0.25}, delay: {value: 15, unit: ms}}}
    # spikes2 → iaf[3..5]: expTwoSynapse, varying weight/delay
    - {source: 101, target: 3, coupling: expTwoSynapse, parameters: {gbase: {value: 0.1, unit: nS}, erev: {value: 0, unit: mV}, tauDecay: {value: 2, unit: ms}, tauRise: {value: 0.05, unit: ms}}}
    - {source: 101, target: 4, coupling: expTwoSynapse, parameters: {gbase: {value: 0.1, unit: nS}, erev: {value: 0, unit: mV}, tauDecay: {value: 2, unit: ms}, tauRise: {value: 0.05, unit: ms}, weight: {value: 0.5}, delay: {value: 10, unit: ms}}}
    - {source: 101, target: 5, coupling: expTwoSynapse, parameters: {gbase: {value: 0.1, unit: nS}, erev: {value: 0, unit: mV}, tauDecay: {value: 2, unit: ms}, tauRise: {value: 0.05, unit: ms}, weight: {value: 0.25}, delay: {value: 15, unit: ms}}}
    # spiker → iaf[6..8]: NMDA synapse, varying weight/delay
    - {source: 102, target: 6, coupling: synNmda}
    - {source: 102, target: 7, coupling: synNmda, parameters: {weight: {value: 0.5}, delay: {value: 10, unit: ms}}}
    - {source: 102, target: 8, coupling: synNmda, parameters: {weight: {value: 0.25}, delay: {value: 15, unit: ms}}}
integration:
  method: euler
  step_size: 0.005
  duration: 300.0
  time_scale: ms
""")
print(f"Model: {exp.dynamics.name if exp.dynamics else 'network'}")
Model: iafCell

2. Render LEMS XML

xml = exp.render("lems")
print(xml[:3000])
<Lems>
  <Target component="sim_NeuroML_Ex12__Network_2"/>

  <Include file="Cells.xml"/>
  <Include file="Networks.xml"/>
  <Include file="Inputs.xml"/>
  <Include file="Simulation.xml"/>

    <iafCell id="iaf1" C="10 pF" leakConductance="0.5 nS" leakReversal="-60 mV" reset="-65 mV" thresh="-35 mV"/>

    <spikeArray id="spike100">
        <spike id="0" time="100.0 ms"/>
    </spikeArray>

    <spikeArray id="spikes2">
        <spike id="0" time="50.0 ms"/>
        <spike id="1" time="100.0 ms"/>
        <spike id="2" time="130.0 ms"/>
    </spikeArray>

    <spikeGenerator id="spiker" period="30.0 ms"/>

    <expOneSynapse id="expOneSynapse" erev="0.0 mV" gbase="0.1 nS" tauDecay="2.0 ms"/>

    <expTwoSynapse id="expTwoSynapse" erev="0.0 mV" gbase="0.1 nS" tauDecay="2.0 ms" tauRise="0.05 ms"/>

    <blockingPlasticSynapse id="synNmda" erev="0 mV" gbase="5 nS" tauDecay="10 ms" tauRise="1 ms">
        <blockMechanism type="voltageConcDepBlockMechanism" blockConcentration="1.2 mM" scalingConc="1.9205441817997078 mM" scalingVolt="16.129032258064516 mV" species="mg"/>
    </blockingPlasticSynapse>

    <network id="net1">
        <population id="iaf1_pop" component="iaf1" size="9"/>
        <population id="spike100_pop" component="spike100" size="1"/>
        <population id="spikes2_pop" component="spikes2" size="1"/>
        <population id="spiker_pop" component="spiker" size="1"/>
        <synapticConnection from="spike100_pop[0]" to="iaf1_pop[0]" synapse="expOneSynapse" destination="synapses"/>
        <synapticConnectionWD from="spike100_pop[0]" to="iaf1_pop[1]" synapse="expOneSynapse" destination="synapses" weight="0.5" delay="10.0 ms"/>
        <synapticConnectionWD from="spike100_pop[0]" to="iaf1_pop[2]" synapse="expOneSynapse" destination="synapses" weight="0.25" delay="15.0 ms"/>
        <synapticConnection from="spikes2_pop[0]" to="iaf1_pop[3]" synapse="expTwoSynapse" destination="synapses"/>
        <synapticConnectionWD from="spikes2_pop[0]" to="iaf1_pop[4]" synapse="expTwoSynapse" destination="synapses" weight="0.5" delay="10.0 ms"/>
        <synapticConnectionWD from="spikes2_pop[0]" to="iaf1_pop[5]" synapse="expTwoSynapse" destination="synapses" weight="0.25" delay="15.0 ms"/>
        <synapticConnection from="spiker_pop[0]" to="iaf1_pop[6]" synapse="synNmda" destination="synapses"/>
        <synapticConnectionWD from="spiker_pop[0]" to="iaf1_pop[7]" synapse="synNmda" destination="synapses" weight="0.5" delay="10.0 ms"/>
        <synapticConnectionWD from="spiker_pop[0]" to="iaf1_pop[8]" synapse="synNmda" destination="synapses" weight="0.25" delay="15.0 ms"/>
    </network>

    <Simulation id="sim_NeuroML_Ex12__Network_2" length="300.0ms" step="0.005ms" target="net1">
        <OutputFile id="of0" fileName="results/iaf1.dat">
            <OutputColumn id="iaf1_pop_0_v" quantity="iaf1_pop[0]/v"/>
            <OutputColumn id="iaf1_pop_1_v" quantity="iaf1_pop[1]/v"/>
            <OutputColumn id="iaf1_pop_2_v" quantity="iaf1_pop[2]/v"/>

3. Run Reference

from tvbo.adapters.neuroml import run_lems_example

ref_outputs = run_lems_example("LEMS_NML2_Ex12_Net2.xml")
for name, arr in ref_outputs.items():
    print(f"  {name}: shape={arr.shape}")
  ex12.dat: shape=(60001, 10)

4. Run TVBO

result = exp.run("neuroml")
da = result.integration.data
print(f"TVBO: {da.dims}, shape={da.shape}")
TVBO: ('time', 'quantity'), shape=(60001, 9)

5. Compare & Plot

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