An R toolkit for systems-biology and systems-pharmacology models in Heta, SBML, and DynMS formats.
DynMSR helps you take a Heta project, an SBML model,
or a DynMS JSON file and run it from R. It provides one convenient
interface between these model formats and simulation backends: load a
model, select it, and build it for simulation. DynMS (Dynamic Model
Specification) is a lightweight, portable intermediate representation
for dynamical simulation models. DynMS files are read directly; Heta
projects and SBML files are converted to DynMS with
heta-compiler first.
Heta project ── heta-compiler ──> DynMS JSON ───────┐
SBML file ───── heta-compiler ──> DynMS JSON ───────┼──> DynMSR ──> R backend
DynMS JSON ─────────────────────────────────────────┘
heta-compiler and DynMS.heta-compiler and DynMS.Install the released version from CRAN:
install.packages("DynMSR")To install the development version from GitHub:
# install.packages("devtools")
devtools::install_github("hetalang/DynMSR")DynMSR can also build a Heta project. This workflow, as well as
sbml_load(), requires a compatible
heta-compiler installation. DynMSR works with
heta-compiler starting from version
0.12.2.
Install the compiler by following the official
Heta installation instructions. Then create an empty directory, such
as heta-quick-start, and save this file as
heta-quick-start/index.heta:
comp1 @Compartment .= 1;
A @Species { compartment: comp1 } .= 10;
B @Species { compartment: comp1 } .= 0;
r1 @Reaction { actors: A => 2B } := k1 * A * comp1;
k1 @Const = 1.2e-1;
The model describes a reaction in which one unit of A
produces two units of B.
library(DynMSR)
# heta_check()
platform <- heta_load("path/to/heta-quick-start")
model <- get_model(platform, 1)
# install.packages("mrgsolve")
require(mrgsolve)
mrgsolve_model <- build_mrgsolve(model)
result <- mrgsim(mrgsolve_model, end = 100, delta = 1)
plot(result)With heta-compiler installed as above, create a file
named sbml-quick-start.xml with this SBML Level 2 Version 5
model. Like the Heta example, it describes the reaction
A → 2B.
<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level2/version5" level="2" version="5">
<model id="simple_conversion">
<listOfCompartments>
<compartment id="comp1" size="1"/>
</listOfCompartments>
<listOfSpecies>
<species id="A" compartment="comp1" initialAmount="10"/>
<species id="B" compartment="comp1" initialAmount="0"/>
</listOfSpecies>
<listOfParameters>
<parameter id="k1" value="0.12"/>
</listOfParameters>
<listOfReactions>
<reaction id="r1" reversible="false">
<listOfReactants>
<speciesReference species="A"/>
</listOfReactants>
<listOfProducts>
<speciesReference species="B" stoichiometry="2"/>
</listOfProducts>
<kineticLaw>
<math xmlns="http://www.w3.org/1998/Math/MathML"><apply><times/><ci>k1</ci><ci>A</ci></apply></math>
</kineticLaw>
</reaction>
</listOfReactions>
</model>
</sbml>Load and simulate the model from R:
library(DynMSR)
platform <- sbml_load("path/to/sbml-quick-start.xml")
model <- get_model(platform, 1)
require(mrgsolve)
mrgsolve_model <- build_mrgsolve(model)
result <- mrgsim(mrgsolve_model, end = 100, delta = 1)
plot(result)Use dynms_lib() to start with a bundled DynMS JSON
document. Replace its call with a path to your own DynMS JSON document
when needed.
library(DynMSR)
# Load the DynMS JSON file as a platform
platform <- dynms_load(dynms_lib("repeated-dose"))
# Select the first model in the platform
model <- get_model(platform, 1)
# Build a compiled mrgsolve model object
mrgsolve_model <- build_mrgsolve(model)
# Run a simulation with the mrgsolve model
library(mrgsolve)
res <- mrgsim(mrgsolve_model)DynMSR treats mrgsolve and deSolve (planned) as backend targets in its architecture: the same loaded DynMS model is intended to support either backend without changing the core loader or validator. The mrgsolve backend is available now. The deSolve backend is planned, but is not yet implemented and cannot currently be used for code generation or simulation.
The mrgsolve backend does not use root finding for DynMS state-event
triggers. The current exporter evaluates such conditions in
$ODE; mrgsolve may call that block at internal trial times
rather than only at output records. Consequently, the generated state
update can occur at an output record before or after the true threshold
crossing. This limitation does not apply to DynMS time events, whose
scheduled times are passed directly to mrgsolve.
For a closer step-based approximation, use a smaller output interval:
res <- mrgsolve::mrgsim(mrgsolve_model, delta = 0.01)Reducing delta and limiting hmax can
sometimes make the approximation closer, but neither reproduces the
exact root-crossing time nor guarantees which side of the threshold an
event will be placed. A robust step-based implementation would evaluate
and latch state-event conditions in $TABLE, where they run
on the output grid, rather than in $ODE.
This section presents automated DynMS simulation checks for the
main branch. Each selected SBML Semantic Test Suite case is
converted with Heta, loaded by DynMSR, simulated with mrgsolve, and
compared with its reference time course.
| Test set | Simulation check | Latest main |
|---|---|---|
| sbmlteam/sbml-test-suite | SBML L2V5 → Heta → DynMSR/mrgsolve | |
| sbmlteam/sbml-test-suite | SBML L3V1 → Heta → DynMSR/mrgsolve |
The compiler compatibility rule and installation URL are stored in
inst/config/heta-compiler.json. Heta integration tests run
only in CI jobs that install the optional compiler.
Run the local test suite with:
Rscript -e "pkgload::load_all('.'); testthat::test_dir('tests/testthat')"Heta integration tests are disabled by default. They require
heta-compiler and can be enabled with:
Rscript -e "Sys.setenv(DYNMSR_RUN_HETA_INTEGRATION = 'true'); pkgload::load_all('.'); testthat::test_dir('tests/testthat')"Regenerate roxygen2 documentation, including NAMESPACE
and man/*.Rd, with:
Rscript -e "roxygen2::roxygenise()"Bundled DynMS JSON Schemas are stored in inst/schema/.
Supported versions, schema paths, and upstream sources are listed in
inst/config/dynms.json. Schema validation selects the local
schema using the document’s dynms version.
To refresh all configured local schemas during development:
Rscript tools/update-dynms-schema.RHeta is an optional DynMS producer; it is not required to read or
validate DynMS JSON files. The compiler compatibility rule is defined in
inst/config/heta-compiler.json.
This is a manual developer step. Package installation, examples, and tests use the bundled local schema and do not download files from the internet.