Simulation
One function handles running the simulation: simulate.
SystemsOfSystems.simulate — Function
simulate(user_data; t, init_fcn, rates_fcn, updates_fcn, seed, options)Runs a simulation, returning a SimHistory containing its log, start and stop times, final model, and termination reason.
user_data: Can be anything used by theinit_fcnt: A collection of strictly increasing, finite times. The sim will step to exactly each given time, plus as many other steps as are required by the solver and models. At the very least, this must contain a start time and end time.init_fcn: Will be called with(t_start, user_data, seed), wheret_startis the first element of the abovetinput. This must return aModelDescription.rates_fcn: Will be called with(t, model)and is expected to return aRatesOutput.updates_fcn: Will be called with(t, model)and is expected to return anUpdatesOutput, ornothingwhen there are no updates, outputs, replacementt_next, or stop request.seed: A top-level seed (Int) to control all random number generation in the sim. Theinit_fcnreceives this as aBranchingSeed.options: SeeSimOptions.
Simulation Results
simulate returns one SimHistory. It contains the requested start time, the last completed simulation time, the final model, the log, and the reason the simulation stopped.
history = simulate(...)
history.t_start
history.t_stop
history.model
history.stopJulia's property destructuring is convenient when only part of the result is needed:
(; t_stop, model) = simulate(...)succeeded reports whether the simulation ended normally. Reaching the requested end time and a deliberate stop request both count as success; an exception or numerical solver failure does not.
if !succeeded(history)
@warn "Simulation failed" reason = history.stop
endSystemsOfSystems.SimHistory — Type
A container for simulation results, including fields for:
t_start: The simulation's start timet_stop: The last time completed by the simulationlog: The log containing the time series for each variable of each modelmodel: The final model constructed in the simstop: The normal stop or failure reason that ended the simulation
This type acts like a log itself, so for instance these do the same thing:
history["/models/plant"]["position"]
history.log["/models/plant"]["position"]The keys, values, and pairs functions also pass through to the underlying log.
SystemsOfSystems.succeeded — Function
succeeded(h::SimHistory)Returns true if the simulation ended without throwing an error or failing to converge on a solution.
Recorded Histories
SimHistory forwards the dictionary-like log interface, so users normally do not need to access its log field directly. These expressions are equivalent:
history["/vehicle/controller"]["command"]
history.log["/vehicle/controller"]["command"]Each model path returns a Logs.ModelHistory. Its constants, states, outputs, and submodels can be accessed by string or symbol. Logging policies may omit selected variables while preserving the model-history structure.
Logs.gather_all_time_series collects every recorded TimeSeries into one ordered dictionary. Its keys combine the model path and variable name, making it useful for searching, exporting, or passing a flat collection to another tool.
all_series = Logs.gather_all_time_series(history)
position = all_series["/vehicle:position"]SystemsOfSystems.Logs.ModelHistory — Type
ModelHistoryA container for the recorded history of one model.
The named-tuple fields contain the model's constants, state and output time series, and recursive submodel histories. path identifies the model, using / for the root.
A model logging policy may omit constants and time-series fields from these named tuples. Constants preserve their declaration form: raw constants remain raw values, while constants declared with VariableDescription retain that description and its metadata.
ModelHistory is mutable to give large, recursively parameterized histories reference semantics. Its fields are established during log construction and are not normally reassigned; samples are appended to the contained time series.
SystemsOfSystems.Logs.gather_all_time_series — Function
gather_all_time_series(history)Collects every TimeSeries below a ModelHistory, AbstractLog, or SimHistory into an ordered dictionary. Keys identify both the model and variable, such as "/aircraft/imu:angular_velocity".
Time-Series Utilities
SystemsOfSystems.select derives a new time series while preserving its timestamps and metadata. It is public but qualified because select is a common name in data-analysis packages.
speed = SystemsOfSystems.select(history["/"]["velocity"]; title = "Speed") do velocity
abs(velocity)
endplot_ts creates a new Makie figure. plot_ts! adds a time series to an existing figure or layout target. Either function requires a loaded Makie backend.
using CairoMakie
figure = Figure()
plot_ts!(figure[1, 1], history["/"]["position"])
figureSystemsOfSystems.TimeSeriesStuff.select — Function
select(f, ts::TimeSeries; kwargs)Applies f to each data element and returns the results as a new TimeSeries. Time and the associated metadata come from ts by default. A derived series representing a new signal can provide a new path and title.
Keyword arguments:
title: Title for the new time seriesdimensions: Dimensions for the transformed datapath: Complete signal path associated with the new time seriesdiscrete: Whether the new time series is discreteinterpolator: Interpolation policy for the new time seriesgroups: Dimension groups for the new time series
Example:
accelerometer_ts = SystemsOfSystems.select(measurements_ts) do measurement
measurement.accelerometer
endselect(ts::TimeSeries, dimension::AbstractString; kwargs)Selects the dimension with the given label as a new TimeSeries.
select(ts::TimeSeries, dimensions::AbstractVector{<:AbstractString}; kwargs)Selects the dimensions with the given labels as a new TimeSeries of tuples.
SystemsOfSystems.TimeSeriesStuff.plot_ts — Function
plot_ts(time_series; kwargs...)Creates a Makie figure containing one or more time series. A Makie backend such as GLMakie or CairoMakie must be loaded before calling this function.
plot_ts(ts::TimeSeries)Plots all of the dimensions of a single TimeSeries, returning the Makie.Figure. Any figure_kwargs will be passed to the Makie.Figure. If there is no content, nothing is returned.
plot_ts(tss::Vector{<:Pair{String, <:TimeSeries}}; skip_units_check = false)This combines multiple time series in a single plot. The input is a vector of string-time-series pairs, where the string becomes the legend label for the plot. This ignores plot groups; every dimension gets its own axis.
By default, this checks to make sure the units are consistent and errors if they are not. Set skip_units_check = true to skip the check.
If there is no content, nothing is returned.
Example:
plot_ts(
[
"truth" => truth_ts,
"measured" => measured_ts,
]
)plot_ts(tss::Vector, figure_kwargs = (;))This combines multiple time series in a single plot, stacked vertically. Any figure_kwargs will be passed to the Makie.Figure. If there is no content, nothing is returned.
Example:
plot_ts([truth_ts, measured_ts])plot_ts(tss::Matrix, figure_kwargs = (;))This combines multiple time series in a single plot, arranged in a matrix. Any figure_kwargs will be passed to the Makie.Figure. If there is no content, nothing is returned.
Example:
plot_ts(
[
ts1 ts2;
ts3 ts4;
]
)SystemsOfSystems.TimeSeriesStuff.plot_ts! — Function
plot_ts!(target, time_series; kwargs...)Adds one or more time series to an existing Makie figure or layout target. A Makie backend such as GLMakie or CairoMakie must be loaded before calling this function.
plot_ts!(f, ts::TimeSeries)Adds a TimeSeries to a given figure (or any "block" within a figure), f. All new axes are returned.
plot_ts!(f, tss::Vector{<:Pair{String, <:TimeSeries}}; skip_units_check = false)This combines multiple time series in a single plot in the given figure (or any "block"), f. The tss input is a vector of string-time-series pairs, where the string becomes the legend label for the plot. This ignores plot groups; every dimension gets its own axis.
By default, this checks to make sure the units are consistent and errors if they are not. Set skip_units_check = true to skip the check.
All new axes are returned.
See plot_ts(tss::Vector{<:Pair{String, <:TimeSeries}}) for more.
Stop Reasons
The history.stop field retains the specific reason the simulation ended. Normal stop reasons subtype AbstractStopReason, while exceptions and numerical failures subtype AbstractFailureReason. Most code can use succeeded(history) and only inspect the concrete reason when reporting or recovering from a failure.
SystemsOfSystems.AbstractTerminationReason — Type
The common supertype for every reason a simulation ceased running.
Normal stop requests and failures are deliberately separate categories. A model or hook request is part of the modeled lifecycle; a numerical or software failure means that lifecycle could not produce another valid sample.
SystemsOfSystems.AbstractStopReason — Type
A normal, successfully processed request to stop a simulation.
SystemsOfSystems.AbstractFailureReason — Type
A condition that prevented the simulation from producing another valid accepted sample.
SystemsOfSystems.ReachedEndTime — Type
The simulation successfully processed its requested final sample.
SystemsOfSystems.ModelRequestedStop — Type
The first model encountered in deterministic hierarchy order requested a normal stop.
SystemsOfSystems.HookRequestedStop — Type
The first hook encountered in configured order requested a normal stop.
SystemsOfSystems.EncounteredError — Type
User model code or simulation infrastructure raised an unexpected exception.
SystemsOfSystems.Solvers.SolverFailedToConverge — Type
The adaptive solver exhausted its allowed rejected attempts without satisfying tolerance.
SystemsOfSystems.Solvers.SolverStepSizeUnderflow — Type
The proposed floating-point step was too small to produce a later official rational time.
Reporting this explicitly is preferable to repeatedly accepting a zero-duration step, which would leave the simulation loop unable to make progress.
SystemsOfSystems.describe — Function
describe(reason::AbstractTerminationReason)Returns a concise, human-readable description of why a simulation stopped.