Code
import json
from tvbo.classes.experiment import SimulationExperiment
from IPython.display import MarkdownExporting TVBO simulations to OpenMINDS JSON-LD
TVBO Team
September 3, 2026
TVBO provides bidirectional interoperability with OpenMINDS, enabling:
The most readable way to define an experiment is using pure YAML with SimulationExperiment.from_string():
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}\]
# 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
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]
---
title: "OpenMINDS Interoperability"
subtitle: "Exporting TVBO simulations to OpenMINDS JSON-LD"
author: "TVBO Team"
date: today
format:
html:
code-fold: false
code-tools: true
toc: true
toc-depth: 3
jupyter: python3
---
## Overview
TVBO provides bidirectional interoperability with [OpenMINDS](https://openminds.ebrains.eu/), 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()`:
```{python}
#| label: setup
#| code-fold: true
import json
from tvbo.classes.experiment import SimulationExperiment
from IPython.display import Markdown
```
```{python}
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())
```
```{python}
experiment.run().integration.plot()
```
## Export to OpenMINDS JSON-LD
```{python}
# 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])
```
## Import from OpenMINDS JSON-LD
```{python}
reconstructed = SimulationExperiment.from_openminds(jsonld)
reconstructed.run().integration.plot()
```
## Convert Back to YAML
```{python}
yaml_output = reconstructed.to_yaml()
print(yaml_output[:2000])
print("\n... [truncated]")
```