Ex27: Multi-Synapses

AMPA + NMDA synapses, individually and as doubleSynapse composite

Model: Multi-Synapses

Five iafCells receiving spikes: cells get AMPA-only, NMDA-only, both separately, and a doubleSynapse (AMPA+NMDA composite) with delay. Demonstrates doubleSynapse which references two child synapses by name.

Reference: NeuroML2 LEMS_NML2_Ex27_MultiSynapses.xml


1. Define Network in TVBO

from tvbo import SimulationExperiment

exp = SimulationExperiment.from_string("""
label: "NeuroML Ex27: Multi-Synapses"
dynamics:
  name: iafCell
  iri: neuroml:iafCell
network:
  dynamics:
    iaf:
      name: iaf
      iri: neuroml:iafCell
      parameters:
        leakReversal: {value: -70, unit: mV}
        thresh: {value: -55, unit: mV}
        reset: {value: -70, unit: mV}
        C: {value: 0.2, unit: nF}
        leakConductance: {value: 10, unit: nS}
    spks:
      name: spks
      iri: neuroml:spikeArray
      events:
        s:
          event_type: preset_time
          trigger_times: [50, 200, 350, 360]
    # AMPA: fast excitatory synapse
    AMPA:
      name: AMPA
      iri: neuroml:expTwoSynapse
      parameters:
        gbase: {value: 1, unit: nS}
        erev: {value: 0, unit: mV}
        tauRise: {value: 1, unit: ms}
        tauDecay: {value: 2, unit: ms}
    # NMDA: slow excitatory synapse with Mg2+ block
    NMDA:
      name: NMDA
      iri: neuroml:blockingPlasticSynapse
      parameters:
        gbase: {value: 4, unit: nS}
        erev: {value: 0, unit: mV}
        tauRise: {value: 2, unit: ms}
        tauDecay: {value: 20, unit: ms}
      modes:
        blockMechanism:
          name: blockMechanism
          iri: neuroml:voltageConcDepBlockMechanism
          parameters:
            species: {description: mg}
            blockConcentration: {value: 1.2, unit: mmol_per_m3}
            scalingConc: {value: 1.920544, unit: mmol_per_m3}
            scalingVolt: {value: 16.129, unit: mV}
    # doubleSynapse: composite of AMPA + NMDA
    AMPA_NMDA:
      name: AMPA_NMDA
      iri: neuroml:doubleSynapse
      parameters:
        synapse1: {description: AMPA}
        synapse1Path: {description: ./AMPA}
        synapse2: {description: NMDA}
        synapse2Path: {description: ./NMDA}
  nodes:
    - {id: 0, dynamics: iaf}
    - {id: 1, dynamics: iaf}
    - {id: 2, dynamics: iaf}
    - {id: 3, dynamics: iaf}
    - {id: 4, dynamics: iaf}
    - {id: 100, dynamics: spks}
  edges:
    # Cell 0: AMPA only
    - {source: 100, target: 0, coupling: AMPA, parameters: {weight: {value: 0.5}, delay: {value: 0, unit: ms}}}
    # Cell 1: NMDA only
    - {source: 100, target: 1, coupling: NMDA, parameters: {weight: {value: 0.5}, delay: {value: 0, unit: ms}}}
    # Cell 2: AMPA + NMDA separately
    - {source: 100, target: 2, coupling: AMPA, parameters: {weight: {value: 0.5}, delay: {value: 0, unit: ms}}}
    - {source: 100, target: 2, coupling: NMDA, parameters: {weight: {value: 0.5}, delay: {value: 0, unit: ms}}}
    # Cell 3: doubleSynapse (AMPA+NMDA composite) with 5ms delay
    - {source: 100, target: 3, coupling: AMPA_NMDA, parameters: {weight: {value: 0.5}, delay: {value: 5, unit: ms}}}
integration:
  method: euler
  step_size: 0.001
  duration: 600.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_Ex27__Multi_Synapses"/>

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

    <iafCell id="iaf" C="0.2 nF" leakConductance="10 nS" leakReversal="-70 mV" reset="-70 mV" thresh="-55 mV"/>

    <spikeArray id="spks">
        <spike id="0" time="50.0 ms"/>
        <spike id="1" time="200.0 ms"/>
        <spike id="2" time="350.0 ms"/>
        <spike id="3" time="360.0 ms"/>
    </spikeArray>

    <expTwoSynapse id="AMPA" erev="0 mV" gbase="1 nS" tauDecay="2 ms" tauRise="1 ms"/>

    <blockingPlasticSynapse id="NMDA" erev="0 mV" gbase="4 nS" tauDecay="20 ms" tauRise="2 ms">
        <blockMechanism type="voltageConcDepBlockMechanism" blockConcentration="1.2 mM" scalingConc="1.920544 mM" scalingVolt="16.129 mV" species="mg"/>
    </blockingPlasticSynapse>

    <doubleSynapse id="AMPA_NMDA" synapse1="AMPA" synapse1Path="./AMPA" synapse2="NMDA" synapse2Path="./NMDA"/>

    <network id="net1">
        <population id="iaf_pop" component="iaf" size="5"/>
        <population id="spks_pop" component="spks" size="1"/>
        <synapticConnectionWD from="spks_pop[0]" to="iaf_pop[0]" synapse="AMPA" destination="synapses" weight="0.5" delay="0.0 ms"/>
        <synapticConnectionWD from="spks_pop[0]" to="iaf_pop[1]" synapse="NMDA" destination="synapses" weight="0.5" delay="0.0 ms"/>
        <synapticConnectionWD from="spks_pop[0]" to="iaf_pop[2]" synapse="AMPA" destination="synapses" weight="0.5" delay="0.0 ms"/>
        <synapticConnectionWD from="spks_pop[0]" to="iaf_pop[2]" synapse="NMDA" destination="synapses" weight="0.5" delay="0.0 ms"/>
        <synapticConnectionWD from="spks_pop[0]" to="iaf_pop[3]" synapse="AMPA_NMDA" destination="synapses" weight="0.5" delay="5.0 ms"/>
    </network>

    <Simulation id="sim_NeuroML_Ex27__Multi_Synapses" length="600.0ms" step="0.001ms" target="net1">
        <OutputFile id="of0" fileName="results/iaf.dat">
            <OutputColumn id="iaf_pop_0_v" quantity="iaf_pop[0]/v"/>
            <OutputColumn id="iaf_pop_1_v" quantity="iaf_pop[1]/v"/>
            <OutputColumn id="iaf_pop_2_v" quantity="iaf_pop[2]/v"/>
            <OutputColumn id="iaf_pop_3_v" quantity="iaf_pop[3]/v"/>
            <OutputColumn id="iaf_pop_4_v" quantity="iaf_pop[4]/v"/>
        </OutputFile>
    </Simulation>

</Lems>

3. Run Reference

from tvbo.adapters.neuroml import run_lems_example

ref_outputs = run_lems_example("LEMS_NML2_Ex27_MultiSynapses.xml")
for name, arr in ref_outputs.items():
    print(f"  {name}: shape={arr.shape}")
  ex27_v.dat: shape=(600001, 5)

4. Run TVBO

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

5. Compare & Plot

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