DynMSR

An R toolkit for systems-biology and systems-pharmacology models in Heta, SBML, and DynMS formats.

Heta project GitHub issues GitHub license Autotests Downloads

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 ─────────────────────────────────────────┘

Main features

Installation

Install the released version from CRAN:

install.packages("DynMSR")

To install the development version from GitHub:

# install.packages("devtools")
# devtools::install_github("hetalang/DynMSR")
install.packages("DynMSR", repos = c('https://hetalang.r-universe.dev', 'https://cloud.r-project.org'))

Heta project quick start

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)

SBML quick start

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)

DynMS quick start

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)

Backends

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.

mrgsolve

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.

Reproducibility reports

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 SBML L2V5 DynMS simulation
sbmlteam/sbml-test-suite SBML L3V1 → Heta → DynMSR/mrgsolve SBML L3V1 DynMS simulation

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.

Development

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.R

Heta 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.

Related projects