Code
from tvbo import Dynamics
from tvbo.classes.experiment import SimulationExperiment
import tempfile
import osDeclarative definition of simulation outputs in TVBO
The output attribute in TVBO model specifications defines which variables are included in simulation results. This is a declarative approach that explicitly specifies what the user wants to observe from the simulation.
The output field is a list of string references to either:
# Example: Output both state and derived variables
state_variables:
x:
equation:
rhs: a * x
y:
equation:
rhs: b * y
derived_variables:
x_squared:
equation:
rhs: x**2
signal:
equation:
rhs: x + y
output:
- x # State variable (integrated)
- x_squared # Derived variable (computed post-integration)
- signal # Another derived variableDuring simulation:
x, y) are integrated using the numerical schemeThis means derived variables in output are computed outside the integration loop, from the full time series of state variables.
Let’s create and run a simple experiment to demonstrate the output format.
We’ll create a damped harmonic oscillator with both state variables and derived outputs:
yaml_content = """
name: DampedOscillator
description: "Simple damped harmonic oscillator with derived output"
parameters:
omega:
value: 1.0
description: "Natural frequency"
gamma:
value: 0.1
description: "Damping coefficient"
state_variables:
x:
description: "Position"
equation:
rhs: v
initial_value: 1.0
v:
description: "Velocity"
equation:
rhs: -omega**2 * x - gamma * v
initial_value: 0.0
derived_variables:
energy:
description: "Total energy (kinetic + potential)"
equation:
rhs: 0.5 * v**2 + 0.5 * omega**2 * x**2
output:
- x # Position (state variable)
- v # Velocity (state variable)
- energy # Total energy (derived variable)
"""
# Save to temp file and load
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
f.write(yaml_content)
temp_path = f.name
model = Dynamics.from_file(temp_path)
print(f"Model: {model.name}")
print(f"State variables: {list(model.state_variables.keys())}")
print(f"Derived variables: {list(model.derived_variables.keys())}")
print(f"Output: {model.output}")Model: DampedOscillator
State variables: ['x', 'v']
Derived variables: ['energy']
Output: ['x', 'v', 'energy']
exp = SimulationExperiment(dynamics=model)
# Run the simulation using JAX backend
res = exp.run('jax')
print(f"Result type: {type(res).__name__}")
print(f"Result shape: {res.data.shape}")
print(f"Time points: {len(res.time)}")Result type: ExperimentResult
Result shape: (81920, 3, 1, 1)
Time points: 81920
The result contains exactly what was specified in output:
output is the declarative specification - it defines exactly what appears in resultsoutput is empty, all state variables are returned (backwards compatibility)| Variable Type | In Integration? | In Output |
|---|---|---|
State variable in output |
✅ Integrated | ✅ Indexed from trace |
Derived variable in output |
❌ Not integrated | ✅ Computed from trace |
State variable NOT in output |
✅ Integrated | ❌ Not in result |