Model Structure¶
A Model is a tree of Pydantic models. ModelBuilder creates it, Model.to_json
writes it, and the Rust engine reads the same tree from JSON
(crates/commol-core/src/types/). Most users never build these types by hand;
read this page to understand model files or to work on Commol.
A model has a header, a process written once, a structure that lays the
process out, and an engine that runs it. The process (bins, accumulators,
stratifications, transitions) is the same for every kind of model; the
structure changes between kinds and is tagged in JSON by kind, and by
variant for a narrower form of a structure. The one kind is aggregate:
amounts per compartment.
Model name, description, version, step_unit, origin
├── parameters: [Parameter] (a value may be a SeriesValue)
├── engine: ModelEngine
│ ├── type: "DifferenceEquations", "DifferentialEquations",
│ │ "StochasticEvents" or "StochasticSteps"
│ └── settings: ODESolver | StochasticEventsSettings | StochasticStepsSettings | None
│ (settings of that engine; None: its defaults)
├── process: Process
│ ├── bins: [Bin]
│ ├── accumulators: [Accumulator]
│ ├── stratifications: [Stratification]
│ │ └── conditions: [StratificationCondition]
│ └── transitions: [Transition] (impulse_at, impulse_every for impulses)
│ └── stratified_rates: [StratifiedRate]
│ └── conditions: [StratificationCondition]
└── structure: Aggregate (kind: "aggregate", variant: None)
├── bin_amounts: {bin: amount | None} (in the unit of the bin)
├── stratification_fractions: {stratification: {category: fraction}}
├── compartment_amounts: {compartment: amount}
└── neighbors: Complete | Groups | None
In JSON the structure is an object with its kind, its variant and the
fields of its class:
{
"name": "Model",
"parameters": [],
"engine": {"type": "DifferenceEquations", "settings": null},
"process": {"bins": [], "accumulators": [], "stratifications": [], "transitions": []},
"structure": {
"kind": "aggregate",
"variant": null,
"bin_amounts": {"A": 990.0, "B": 10.0},
"stratification_fractions": {},
"compartment_amounts": {},
"neighbors": null
},
"step_unit": null,
"origin": null
}
Model, Process, ModelStructure, Aggregate, Complete and Groups are
documented in Model API. The engine must run the kind of the
structure: a model whose engine runs another kind is rejected when it is made,
with an error that names the engine, both kinds and the engines of the kind of
the model. A variant keeps the kind, the fields and the engines of its
structure, and loads back as its own class
(Design decisions).
Bins and accumulators¶
Bin ¶
Bases: BaseModel
Defines a single bin (base category) of the process of a model.
A bin represents a fundamental category before stratification. The combination of a bin with all stratifications produces the actual compartments.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
Identifier of the bin. |
name |
str
|
A descriptive, human-readable name for the bin. |
unit |
str | None
|
The unit of measurement for this bin. If None, the bin will use the model-level bin_unit when specified. |
Source code in commol/context/bin.py
Accumulator ¶
Bases: BaseModel
A cumulative event counter tracked as output but not as part of the state.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
Identifier of the accumulator, and the name of its output before the stratifications expand it. |
name |
str
|
A descriptive, human-readable name for the accumulator. |
Source code in commol/context/bin.py
Stratifications¶
Stratification ¶
Bases: BaseModel
Defines a categorical subdivision of the compartments.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
Identifier of the stratification. |
categories |
list[str]
|
List of the different stratification groups identifiers. |
description |
str | None
|
A human-readable description of the stratification. |
conditions |
list[StratificationCondition] | None
|
When set, this stratification only expands compartments whose already-applied stratification categories satisfy ALL conditions. Compartments that do not satisfy the conditions are kept without appending this stratification's categories. May only reference stratifications declared before this one. |
Source code in commol/context/stratification.py
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | |
Methods:¶
validate_categories_length ¶
Enforces that categories are not empty.
Source code in commol/context/stratification.py
validate_categories_uniqueness ¶
Enforces that categories are not repeated.
Source code in commol/context/stratification.py
validate_conditions_have_categories ¶
Enforces that stratification expansion conditions filter by category.
Source code in commol/context/stratification.py
StratificationCondition ¶
Bases: BaseModel
Specifies a category within a stratification for rate matching.
When to is set, the matched category in the source compartment is
replaced with the to category in the target compartment name. This
enables cross-category transitions within the same bin (e.g., from g1
to g2).
Attributes:
| Name | Type | Description |
|---|---|---|
stratification |
str
|
The ID of the stratification (e.g., "group", "type") |
category |
str
|
The category within that stratification (e.g., "g1", "t1") |
to |
str | None
|
Target category override. When set, the target compartment will use this category instead of the source compartment's category for this stratification. |
Source code in commol/context/stratification_condition.py
Parameters¶
Parameter ¶
Bases: BaseModel
Defines a global model parameter.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
The identifier of the parameter. |
value |
float | str | SeriesValue | None
|
Value of the parameter. Can be:
- float: A numerical constant value
- str: A mathematical formula that can reference other parameters,
special variables (total, total_ |
description |
str | None
|
A human-readable description of the parameter. |
unit |
str | None
|
The unit of the parameter (e.g., "1/day", "dimensionless", "item"). If None, the parameter has no unit specified. |
Source code in commol/context/parameter.py
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | |
Methods:¶
validate_value
classmethod
¶
validate_value(value: float | str | SeriesValue | None) -> float | str | SeriesValue | None
Validate the parameter value.
Source code in commol/context/parameter.py
validate_formula ¶
Check a formula value as a rate is checked: the security check and the check of the language of formulas.
Source code in commol/context/parameter.py
is_calibrated ¶
Check if the parameter has a value (is calibrated).
Returns:
| Type | Description |
|---|---|
bool
|
True if the parameter has a value, False if it needs calibration. |
with_value ¶
with_value(value: ParameterUpdate) -> Parameter
This parameter with another value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
ParameterUpdate
|
The new value, as |
required |
Returns:
| Type | Description |
|---|---|
Parameter
|
A new parameter with the same id, description and unit. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in commol/context/parameter.py
The value of a series parameter, SeriesValue, is documented in
Model API.
Transitions¶
Transition ¶
Bases: BaseModel
Defines a rule for system evolution.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
Id of the transition. |
source |
list[str]
|
The origin compartments. |
target |
list[str]
|
The destination compartments. |
accumulators |
list[str]
|
Ids of the accumulators that add up the flow of this transition. |
rate |
str | None
|
Default mathematical formula, parameter name, or constant value for the flow. Used when no stratified rate matches. Numeric values are automatically converted to strings during validation. Operators: +, -, *, /, % (modulo), ^ or ** (power) Functions: sin, cos, tan, exp, ln, sqrt, abs, min, max, if, etc. Constants: pi, e Note: Both ^ and ** are supported for exponentiation (** is converted to ^). Examples: - "k1" (parameter reference) - "0.5" (constant, can also be passed as float 0.5) - "k1 * A * B / total" (mathematical formula) - "0.3 * sin(2 * pi * t / 365)" (formula that changes along the axis) - "2^10" or "2**10" (power: both syntaxes work) |
stratified_rates |
list[StratifiedRate] | None
|
Stratification-specific rates. Each rate applies to compartments that match all specified stratification conditions. |
per_compartment |
bool | None
|
When True, the id of each source and target bin in a rate reads the compartment of each flow; any other bin keeps its total. A transition between categories ignores it. |
impulse_at |
list[float] | None
|
Positions on the axis where the transition is an impulse: at each one, the rate is a fraction (proportional) or an amount (absolute) moved at once. Between them the transition moves nothing. |
impulse_every |
tuple[float, float] | None
|
|
Source code in commol/context/transition.py
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | |
Attributes¶
is_impulse
property
¶
Whether the transition is an impulse rather than a continuous flow.
Methods:¶
validate_impulse ¶
Check the impulse with the rule of the engine (check_impulse of
crates/commol-model/src/values.rs): one of impulse_at and
impulse_every, at least one position on the axis, a positive period
and an offset that is not negative.
Source code in commol/context/transition.py
validate_rate
classmethod
¶
Convert numeric rates to strings and perform security and syntax validation.
Source code in commol/context/transition.py
StratifiedRate ¶
Bases: BaseModel
Defines a rate for specific stratification categories.
Attributes:
| Name | Type | Description |
|---|---|---|
conditions |
list[StratificationCondition]
|
List of stratification-category pairs that must match |
rate |
str
|
Rate expression for compartments matching these conditions |
absolute |
bool | None
|
True: the flow is the rate, not multiplied by the source amount.
False: the flow is the rate times the source amount. None: the rate
is absolute when it reads a compartment, a bin total or a
|
Source code in commol/context/transition.py
Methods:¶
validate_not_empty
classmethod
¶
validate_not_empty(v: list[StratificationCondition]) -> list[StratificationCondition]
Ensure at least one stratification condition is specified.
Source code in commol/context/transition.py
validate_unique_stratifications ¶
Ensure no duplicate stratification IDs.
Source code in commol/context/transition.py
validate_rate
classmethod
¶
Perform security and syntax validation on the rate expression.
Engine¶
The engine's list of engines (crates/commol-core/src/types/engine.rs)
validates the settings: settings of another engine raise an error that names
both. ODESolver is documented in Simulation API.
ModelEngine ¶
Bases: BaseModel
The engine that runs a model, and its settings.
Attributes:
| Name | Type | Description |
|---|---|---|
type |
str
|
Name of an engine of the engine's list, such as
|
settings |
EngineSettings | None
|
Settings of that engine; None uses its defaults.
|
Source code in commol/context/engine.py
Methods:¶
settings_of_the_engine
classmethod
¶
settings_of_the_engine(value: EngineSettings | Mapping[str, JsonValue] | None, info: ValidationInfo) -> EngineSettings | Mapping[str, JsonValue] | None
Read settings given as a mapping with the class of their engine.
Source code in commol/context/engine.py
check_settings ¶
Ask the engine's list whether it has the engine and the settings.
Source code in commol/context/engine.py
Initial conditions¶
Aggregate holds the fields and methods of InitialConditions, and checks
them against the process when the model is built.
InitialConditions ¶
Bases: BaseModel
How much starts where: the amount of each bin and the split of it.
Every amount is in the unit of its bin, so bins of different units, such
as a count and a concentration, start without a total over them.
Aggregate holds these fields and their methods; the checks against the
bins and the stratifications of the process are in
Aggregate.check_model.
Attributes:
| Name | Type | Description |
|---|---|---|
bin_amounts |
dict[str, float | None]
|
The amount of each bin at the start, by bin id, in the unit of the bin; finite and not negative. None leaves an amount for calibration. |
stratification_fractions |
dict[str, dict[str, float]]
|
The fraction of each category, by stratification id and category: the split of the amount of every bin the stratification applies to; each from 0 to 1, and a sum of 1 within 1e-6. A conditional stratification splits only the group its conditions select. |
compartment_amounts |
dict[str, float]
|
Amounts of single expanded compartments, by compartment name, applied after the expansion. |
Source code in commol/context/initial_conditions.py
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 | |
Methods:¶
reject_fractions_of_a_total
classmethod
¶
Name the field of amounts that replaces a field of fractions.
A total over bins of different units has no meaning, so the initial
state is stated as amounts, and a structure with total,
bin_fractions or compartment_fractions is rejected with the
field to use.
Source code in commol/context/initial_conditions.py
validate_bin_amounts
classmethod
¶
Check every bin amount with the rule of the engine.
Source code in commol/context/initial_conditions.py
validate_stratification_fractions
classmethod
¶
validate_stratification_fractions(value: dict[str, dict[str, float]]) -> dict[str, dict[str, float]]
Check the fractions of every stratification with the rule of the engine.
Source code in commol/context/initial_conditions.py
validate_compartment_amounts
classmethod
¶
Check every compartment amount with the rule of the engine.
Source code in commol/context/initial_conditions.py
get_uncalibrated_bins ¶
Get list of bin IDs that have uncalibrated amounts (value = None).
Returns:
| Type | Description |
|---|---|
list[str]
|
List of bin IDs with uncalibrated initial conditions. |
Source code in commol/context/initial_conditions.py
get_categories_with_fractions ¶
Get the categories that have a declared initial fraction.
Returns:
| Type | Description |
|---|---|
set[str]
|
Category names collected from |
Source code in commol/context/initial_conditions.py
resolve_category ¶
Resolve a category id to its stratification and its bare name.
A qualified id (group:g1) names the stratification. A bare name
must be declared by exactly one stratification.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
category
|
str
|
A bare or qualified category id. |
required |
Returns:
| Type | Description |
|---|---|
tuple[str, str]
|
The stratification id and the bare category name. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the category is not found or a bare name is ambiguous. |
Source code in commol/context/initial_conditions.py
category_id ¶
Shortest id that names a category without ambiguity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
stratification
|
str
|
Id of the stratification that declares the category. |
required |
category
|
str
|
Bare category name. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The bare name, or |
Source code in commol/context/initial_conditions.py
get_category_fraction ¶
Get the fraction of a category within the group it subdivides.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
category
|
str
|
A category id, bare or qualified ( |
required |
Returns:
| Type | Description |
|---|---|
float
|
The declared fraction, relative to the group the category's stratification applies to rather than to the whole model. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the category is not found or a bare name is ambiguous. |
Source code in commol/context/initial_conditions.py
update_stratification_fractions ¶
Update stratification category fractions by category name.
Categories belonging to several stratifications may be given in one
call. A category name declared by more than one stratification must be
qualified with its stratification, as in group:g1. Within each
stratification, at most one category may be omitted; the omitted
category receives the rest of 1, or 0 when the given values pass 1.
The fractions of every stratification are checked with the rule of the
engine before any of them changes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fractions
|
Mapping[str, float]
|
Dictionary mapping category names, bare or qualified, to their new fraction values. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a category is not found or is ambiguous, or a stratification has more than one category omitted; with the message of the engine, if a fraction is not from 0 to 1 or the fractions of a stratification do not sum to 1 within 1e-6. |
Source code in commol/context/initial_conditions.py
update_bin_amounts ¶
Update bin amounts by bin ID.
Every amount is checked before any bin changes, so a rejected call leaves the initial conditions unchanged. The bins of one unit keep no sum: to move an amount between bins, update every bin involved.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
amounts
|
Mapping[str, float | None]
|
Dictionary mapping bin IDs to their new amount, in the unit of the bin. None marks a bin that needs calibration. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a bin ID is not found in the initial conditions, or, with the message of the engine, an amount is not finite or is negative. |