What is Heta?
Heta is an open-source modeling language and toolchain for building, organizing, and transforming quantitative models used in systems pharmacology, systems biology, and related fields. https://hetalang.github.io
- Heta language — a language for defining models.
- Heta compiler — a tool for converting models.
- HetaSimulator.jl — a simulation framework in Julia.
Model example
/* A simple model with two species A and B,
one reaction r1, and a time event sw1 */
comp1 @Compartment .= 1;
A @Species {compartment: comp1} .= 2;
B @Species {compartment: comp1} .= 0;
r1 @Reaction {actors: A => 2B} := k1*A*comp1;
k1 @Const = 1.2e-1;
dose1 @Const = 1;
sw1 @TimeSwitcher {start: 12, period: 24};
A [sw1]= A + dose1 / comp1;Base classes
@Const defines fixed values
k1 @Const {units: 1/second} = 1.2e-1;@Record defines values which may vary over time.
p1 @Record {
units: 1/second, // optional
boundary: false, // default - false
output: true // default - false
} := x * y;@Process defines income and outcome of records.
p1 @Process {
actors: in => out,
units: 1/second, // optional
output: true // default - false
} := k1 * in;@Compartment defines physical volumes.
comp1 @Compartment {
units: liter, // optional
boundary: true, // default - false
output: true // default - false
} .= 1;@Species defines concentrations or amounts.
Aamt @Species {
compartment: comp1,
units: mole, // optional
isAmount: true, // default - false
boundary: false, // default - false
output: true // default - false
} .= 10;@Reaction defines chemical reactions.
r1 @Reaction {
actors: A <=> 2B,
units: mole/second, // optional
modifiers: [C, D], // default - []
output: true // default - false
} := k1 * A * C * D * comp1;actors define stoichiometry of a Process or Reaction:
A => 2B + C | irreversible reaction |
=> A | source (production) |
A => | sink (degradation) |
A <=> B | reversible reaction |
Annotations
Comments
// This is a single-line comment
/* This is a
multi-line comment */Semantic annotations
'''Here you can write the component notes'''
A @Species 'Title for component A' {
compartment: comp1,
tags: [tag1, tag2, tag3], // user-defined tags
aux: {key1: value1, key2: value2} // user-defined meta
} .= 10;Mathematical expressions
Math expressions can be used in Record, Process, Compartment, Species, Reaction assignment and Switcher trigger properties.
Assignments
= | assign a value, for Const only |
.= | initial assignment, evaluated at time 0 only, for Record, Compartment, Species |
:= | rule assignment, evaluated at each time step, for Record, Process, Compartment, Species, Reaction |
[sw1]= | assignment when switcher sw1 is active, for Record, Compartment, Species |
Numbers and operators
1, 1.2e-1, 1E-1 | numbers |
pi, e | mathematical constants |
Infinity, -Infinity, NaN | special values |
+, -, *, /, ^ | basic math operators |
true, false | boolean values |
and, or, xor, not | boolean operators |
==, !=, <, >, <=, >= | comparison operators |
x > 5 ? 1 : 0 | Ternary operator |
Functions
exp(x), pow(x, n), sqrt(x), nthRoot(x, n) |
ln(x), log(x), logbase(x, base), log10(x), log2(x) |
abs(x), ceil(x), floor(x), sign(x), factorial(n) |
max(x, y), max(x, y, z), min(x, y), min(x, y, z) |
cos(x), cot(x), csc(x), sec(x), sin(x), tan(x) |
acos(x), acot(x), acsc(x), asec(x), asin(x), atan(x) |
User-defined functions
#defineFunction myFunc {
arguments: [x, y],
math: "x^2 + y^2"
};Switchers
A Switcher can update Record, Compartment, or Species when used with [<switcher id>]= assignment operator.
A [sw1]= A + dose1 / comp1;
Bamt [sw2]= Bamt + dose2;@TimeSwitcher is triggered at specific time points.
sw1 @TimeSwitcher {
start: 10,
period: 6, // default - 0, no repeat
stop: 10, // default - 0, no stop
active: false // default - true
};@CSwitcher triggers when a value crosses zero (from - to +).
sw2 @CSwitcher {
trigger: x - 5,
active: false // default - true
};@DSwitcher triggers when conditions are met during solution.
sw1 @DSwitcher {
trigger: x > 5,
active: false // default - true
};Units
Units expression
Used in the units property to set units of Const, Record, Process, Compartment, Species, Reaction, TimeScale, and #defineUnit.
second | simple units expression |
1/liter/second*mole^2 | complex units expression |
(1e-9 mole)^2/(60 second)*metre | complex units with prefixes |
Core Units
| dimensionless, mole, litre, second, kilogram, item, joule, metre, watt, volt, gram, kelvin, year, day, hour, minute, avogadro, hertz |
| katal, ampere, newton, becquerel, candela, coulomb, farad, gray, henry, lumen, lux, ohm, pascal, radian, siemens, sievert, steradian, tesla, weber |
User-defined units
#defineUnit uM {
units: (1e-6 mole)/liter
};Heta modules
What is a module?
Modules are files containing model components and can be included in a Heta project. Every project must include at least one module. Other modules can be included in the main module or in other modules.
my-project/
|-- src/
|-- index.heta
|-- mod1.heta
|-- mod2.csv
|-- mod3.xlsx
|-- mod4.json
|-- mod5.yml
|-- mod6.xmlTypes of modules
Modules are included using the include statement (or alternatively with #include action).
/* index.heta */
include mod1.heta; // Heta
include mod2.csv type table; // Table
include mod3.xlsx type table with {sheet: 0, omitRows: 0};
include mod3.xlsx type table with {sheet: 1, omitRows: 0};
include mod4.json type json; // JSON
include mod5.yml type yaml; // YAML
include mod6.xml type sbml; // SBMLTable modules
- Use
heta initto generate template table. - Same structure as Heta code, but in a tabular format.
- First line is a header with property names.
- Support various formats: CSV, TSV, Excel, etc.
| id | class | actors | assignmnents.ode_ |
|---|---|---|---|
| r1 | Reaction | A => B | k1 * A * comp1 |
| r2 | Reaction | B => C | k2 * B * comp1 |
| r3 | Reaction | C => A | k3 * C * comp1 |
Heta-compiler
Typical workflow
Heta-compiler runs from console: bash, cmd, PowerShell, etc.
- Install heta-compiler and verify with
heta -v. heta init— initialize project with default files.- Edit src/index.heta, include modules, add components.
- Edit platform.yml to set build options and export formats.
heta build— compile model and export to formats.- Repeat steps 3-5 until model is ready.
Compile with options
Build options override settings from platform.yml (if they exist) for current build.
Run from console in project directory:
heta build -h | Show build options |
heta build --source=src/model.heta | Compile from file |
heta build --export=SBML,Dot,Simbio | Export to formats |
heta build --units-check | Check units consistency |
Export formats
Can be used with --export= build option or platform.yml export.
SBML | Systems Biology Markup Language L2/L3 |
Simbio | MATLAB SimBiology format |
Mrgsolve | Model code for the R package mrgsolve |
DBSolve | Model format for DBSolve simulation software |
Julia | Julia code for HetaSimulator.jl |
Matlab | MATLAB code representation of the model |
Table | Heta table representation of model components (CSV/TSV/Excel) |
XLSX | Spreadsheet representation of the model |
JSON | Heta JSON structured model format |
YAML | Heta YAML structured model format |
Dot | Graphviz Dot file for model structure visualization |
Summary | Human-readable text summary of the model |
Compiled files are saved to the dist/ directory.
Other
qsp-units.heta in heta-compiler
heta init provides pre-defined units, which can be then loaded in index.heta.
include qsp-units.heta;| UL (unitless), percent, cell, kcell |
| fmole, pmole, nmole, umole, mmole, fM, pM, nM, uM, mM, M, kM |
| fL, pL, nL, uL, mL, dL, L, fg, pg, ng, ug, mg, g, kg, fm, pm, nm, um, mm, cm, m |
| fs, ps, ns, us, ms, s, h, week |
| kat, cal, kcal |
platform.yml
File storing build options and metadata of the project.
{
builderVersion: ^0.10.0,
id: my-project,
notes: My project description,
version: v1.2.0,
license: MIT,
options: {
unitsCheck: true
},
importModule: {source: src/index.heta},
export: [
{format: JSON, omit: [], useUnitsExpr: false},
#{format: YAML, omit: [], useUnitsExpr: false},
#{format: DBSolve, powTransform: keep, version: 26},
{format: SBML, version: L2V4},
{format: Dot},
]
}Piecewise function in heta-compiler
Return val1 if cond1 is true, val2 if cond2 is true, and so on. If no conditions are true, return otherwise value.
| piecewise(val1, cond1, val2, cond2, ..., otherwise) |
Main actions
#insert k1 @Const = 1; | Insert component into platform |
#update k1 = 1.1; | Update component properties |
#upsert k1 @Const = 2; | Insert or update component depending on @Class presence |
k1 @Const = 2; | Same as #upsert but shorter syntax |
#delete k1; | Delete component from platform |
#include {source: module.xlsx, type: table, sheet: 0}; | Include module into platform, works as include statement |
#defineUnit uM {units: (1e-6 mole)/liter}; | Define user's unit |
#defineFunction sq {arguments: [x, y], math: "x^2 + y^2"}; | Define user function |