OpenMINDS Interoperability

Exporting TVBO simulations to OpenMINDS JSON-LD

Author

TVBO Team

Published

September 3, 2026

Overview

TVBO provides bidirectional interoperability with OpenMINDS, enabling:

  • Export simulation experiments to OpenMINDS-compatible JSON-LD
  • Import OpenMINDS JSON-LD back into TVBO objects
  • Integration with EBRAINS Knowledge Graph

Define a Simulation Experiment

The most readable way to define an experiment is using pure YAML with SimulationExperiment.from_string():

Code
import json
from tvbo.classes.experiment import SimulationExperiment
from IPython.display import Markdown
yaml_definition = """
id: 1
label: Three-Node Oscillator Network
description: >
  A simple 3-node network simulation using a damped harmonic oscillator model.
  Demonstrates round-trip conversion to/from OpenMINDS JSON-LD.

# Custom oscillator model (avoids ontology lookup)
dynamics:
  name: TEST_Oscillator
  label: Damped Harmonic Oscillator
  description: Simple 2D oscillator for testing
  system_type: continuous

  state_variables:
    x:
      name: x
      label: Position
      equation:
        lhs: d(x)/dt
        rhs: y
      domain: {lo: -10.0, hi: 10.0}
      variable_of_interest: true
      initial_value: 1.0

    y:
      name: y
      label: Velocity
      equation:
        lhs: d(y)/dt
        rhs: -omega**2 * x - gamma * y + k * c_in
      coupling_variable: true
      initial_value: 0.0

  parameters:
    omega:
      name: omega
      label: Angular frequency
      value: 1.0
      unit: rad/s
    gamma:
      name: gamma
      label: Damping coefficient
      value: 0.1
    k:
      name: k
      label: Coupling strength
      value: 0.05

  coupling_inputs:
    c_in:

# 3-node network with connectivity
network:
  number_of_nodes: 3
  nodes:
    - id: 0
      label: Region_A
    - id: 1
      label: Region_B
    - id: 2
      label: Region_C
  edges:
    - source: 0
      target: 1
      parameters:
        weight: {value: 0.5}
    - source: 1
      target: 0
      parameters:
        weight: {value: 0.5}
    - source: 1
      target: 2
      parameters:
        weight: {value: 0.3}
    - source: 2
      target: 1
      parameters:
        weight: {value: 0.3}
    - source: 0
      target: 2
      parameters:
        weight: {value: 0.2}
    - source: 2
      target: 0
      parameters:
        weight: {value: 0.2}
  coupling:
    Linear:
      label: Linear Diffusive Coupling

# Integration settings
integration:
  method: heun
  step_size: 0.1
  duration: 100.0
  time_scale: s
"""

# Step 1: Create experiment from YAML string
experiment = SimulationExperiment.from_string(yaml_definition)

Markdown(experiment.generate_report())

Three-Node Oscillator Network

A simple 3-node network simulation using a damped harmonic oscillator model. Demonstrates round-trip conversion to/from OpenMINDS JSON-LD.

Local Dynamics: Damped Harmonic Oscillator

Simple 2D oscillator for testing

system: continuous; autonomous: True; modes: 1; state variables: 2; parameters: 3.

State Equations

\[\dot{x} = y\] \[\dot{y} = c_{in} k - \gamma y - x \omega^{2}\]

State Variables

Variable Initial Value Equation Domain / Sampling Flags
\(x\) 1 differential (order 1) [-10, 10] recorded
\(y\) 0 differential (order 1) coupling, recorded

Parameters

Parameter Value Unit
\(\gamma\) 0.1
\(k\) 0.05
\(\omega\) 1 \(\frac{\mathrm{rad}}{\mathrm{s}}\)

Dimensional Check

Equation Dimensional check Detail
\(\dot{x}\) underdetermined x has no declared unit
\(\dot{y}\) underdetermined y has no declared unit

Coupling Inputs

Input Source Dimension Keys Description
c_in 1

Brain Network

Setting Value
Regions 3
Conduction velocity 3.0 mm_per_ms
Distance unit mm
Nodes 3 explicit nodes
Edges 6 explicit edges
Weights shape=3x3, dtype=float64

Coupling: Linear Diffusive Coupling

\[c = b + a \cdot \sum_{j=0}^{-1 + N} x_{j} \cdot {w}_{i,j}\]

Property Value
Delays enabled
Symmetry directed

Pre-synaptic: \(c_{\text{pre}} = x_{j}\)

Post-synaptic: \(c_{\text{post}} = b + a \cdot gx\)

Parameter Value Description
\(b\) 0 Shifts the base of the connection strength while maintaining the absolute difference between different values.
\(a\) 0.0039 Linear scaling factor of the coupled (delayed) input.

Numerical Integration

Setting Value
Method heun
Time step \(\Delta t = 0.1\) ms
Duration 100.0 ms
Absolute tolerance 1e-10
Relative tolerance 1e-10
Stages 2
Delayed state history True

Integration Update Expressions

\[X_{1} = X + noise + dX_{0} \cdot dt + dt \cdot stimulus\] \[dX = \frac{dt \cdot \left(dX_{0} + dX_{1}\right)}{2}\]

experiment.run().integration.plot()
INFO [tvbo.run] [+0s] STEP 1: Running simulation...
INFO [tvbo.run] [+0s]   Simulation period: 100.0 s, dt: 0.1 s
INFO [tvbo.run] [+0s]   Simulation complete.
INFO [tvbo.run] [+0s] Experiment complete.

Export to OpenMINDS JSON-LD

# Step 2: Convert to OpenMINDS JSON-LD
jsonld = experiment.to_openminds(base_id="https://example.org/simulations")


print("JSON-LD preview:")
print(json.dumps(jsonld, indent=2, default=str)[:1500])
JSON-LD preview:
{
  "@context": {
    "@vocab": "https://openminds.ebrains.eu/vocab/",
    "tvbo": "https://w3id.org/tvbo/",
    "sands": "https://openminds.ebrains.eu/sands/",
    "core": "https://openminds.ebrains.eu/core/",
    "computation": "https://openminds.ebrains.eu/computation/"
  },
  "@type": "tvbo:SimulationExperiment",
  "id": 1,
  "model": "TEST_Oscillator",
  "references": [],
  "description": "A simple 3-node network simulation using a damped harmonic oscillator model. Demonstrates round-trip conversion to/from OpenMINDS JSON-LD.\n",
  "additional_equations": [],
  "label": "Three-Node Oscillator Network",
  "dynamics": {
    "name": "TEST_Oscillator",
    "label": "Damped Harmonic Oscillator",
    "parameters": {
      "gamma": {
        "@type": "tvbo:Parameter",
        "name": "gamma",
        "label": "Damping coefficient",
        "value": 0.1,
        "grounding": [],
        "explored_values": [],
        "element_domains": []
      },
      "k": {
        "@type": "tvbo:Parameter",
        "name": "k",
        "label": "Coupling strength",
        "value": 0.05,
        "grounding": [],
        "explored_values": [],
        "element_domains": []
      },
      "omega": {
        "@type": "tvbo:Parameter",
        "name": "omega",
        "label": "Angular frequency",
        "value": 1.0,
        "unit": "rad_per_s",
        "grounding": [],
        "explored_values": [],
        "element_domains": []
      }
    },
    "description": "Simple 2D oscillator for test

Import from OpenMINDS JSON-LD

reconstructed = SimulationExperiment.from_openminds(jsonld)
reconstructed.run().integration.plot()
INFO [tvbo.run] [+0s] STEP 1: Running simulation...
INFO [tvbo.run] [+0s]   Simulation period: 100.0 ms, dt: 0.1 ms
INFO [tvbo.run] [+0s]   Simulation complete.
INFO [tvbo.run] [+0s] Experiment complete.

Convert Back to YAML

yaml_output = reconstructed.to_yaml()
print(yaml_output[:2000])
print("\n... [truncated]")
id: 1
model: TEST_Oscillator
part: main
description: 'A simple 3-node network simulation using a damped harmonic oscillator
  model. Demonstrates round-trip conversion to/from OpenMINDS JSON-LD.

  '
label: Three-Node Oscillator Network
dynamics:
  name: TEST_Oscillator
  label: Damped Harmonic Oscillator
  parameters:
    gamma:
      name: gamma
      label: Damping coefficient
      value: 0.1
    k:
      name: k
      label: Coupling strength
      value: 0.05
    omega:
      name: omega
      label: Angular frequency
      value: 1.0
      unit: rad_per_s
  description: Simple 2D oscillator for testing
  coupling_inputs:
    c_in:
      name: c_in
      dimension: 1
      local: false
  state_variables:
    x:
      name: x
      label: Position
      domain:
        enforce: none
        lo: -10.0
        hi: 10.0
        log_scale: false
      equation:
        lhs: d(x)/dt
        rhs: y
        latex: false
      record: true
      variable_of_interest: true
      coupling_variable: false
      equation_type: differential
      equation_order: 1
      initial_value: 1.0
    y:
      name: y
      label: Velocity
      equation:
        lhs: d(y)/dt
        rhs: -omega**2 * x - gamma * y + k * c_in
        latex: false
      record: true
      variable_of_interest: true
      coupling_variable: true
      equation_type: differential
      equation_order: 1
      initial_value: 0.0
  number_of_modes: 1
  system_type: continuous
  autonomous: true
  cse: false
  compile: false
integration:
  method: heun
  abs_tol: 1.0e-10
  rel_tol: 1.0e-10
  step_size: 0.1
  duration: 100.0
  transient_time: 0.0
  block_size: 1000
  noise_draw: fused
  scipy_ode_base: false
  number_of_stages: 2
  intermediate_expressions:
    X1:
      name: X1
      equation:
        lhs: X1
        rhs: X + dX0 * dt + noise + stimulus * dt
        latex: false
      record: false
  update_expression:
    name: dX
    equation:
      lhs: X_{t+1}
      rhs: (dX0 + dX1) * (dt / 2)
      l

... [truncated]