Heta is an open format and its rules can be elaborated by software tools in different ways. Nevertheless formulating the Heta specification we keep in mind the following steps.
-
Parsing. Heta modules are translated to the collection of components.
Parsing starts from single index file (it can have any name), then other files are added recursively based on
#include
actions. Each file represents one module.The errors which happen at the stage will be of types:
FileSystemError
,ParsingError
. -
Modules integration. Collection of Heta modules are combined into a single structure Q-array which is sequence of actions for platform container. The modules must not have circular references.
The errors which happen at the stage will be of type
ModuleError
. -
Translation. The Q-array is translated sequentially to create the elements of Heta container. Generally it is a key-value pairs. The properties must satisfy the requirements for its classes. See the structure of Heta container below.
The errors which happen at the stage will be of types:
QError
,ValidationError
. -
Binding. Binding Heta components are based on internal cross references. Checking references. Checking required properties.
The errors which happen at the stage will be of types:
BindingError
. -
Testing circular references. In general case some of references (like
assignments
in@Record
orunits
in#defineUnit
) may be circular which is not allowed. On this step the compiler searches them and throws an error if found. -
Checking units consistency (optional). Testing if left and right part of assignments has the same calculated unit.
-
Checking units terms. Checking the units requirement for specific components: @Compartment is volume or square, or length, etc.
-
Other steps. The next steps depend on a tool used? analysis, export etc.
The errors which happen at the stage will be of types:
ExportError
.
- namespaceStorage (key/value dictionary)
- namespace (key/value dictionary)
- components
- namespace (key/value dictionary)
- unitDefStorage (key/value dictionary)
- unit definition
Structures in example are shown in Heta and JSON notation.
Structure 1. Heta language code
file: index.heta
s1 @Species { compartment: comp0 };
#include {source: ./addon.heta, type: heta};
file: addon.heta
s1 'Species number one';
Structure 2. Collection of modules
{
"Y:/platform/src/index.heta" : [
{
"action": "upsert",
"class": "Species",
"id": "s1",
"compartment": "comp0"
},
{
"action": "include",
"source": "Y:/platform/src/addon.heta",
"type": "heta"
}
],
"Y:/platform/src/addon.heta" : [
{
"action": "upsert",
"id": "s1",
"title": "Species number one"
}
]
}
Structure 3. Q-array
[
{
"action": "upsert",
"class": "Species",
"id": "s1",
"compartment": "comp0"
},
{
"action": "upsert",
"id": "s1",
"title": "Species number one"
},
{
"action": "export",
"format": "SBML",
"filepath": "sbml"
}
]
Structure 4. Heta container
{
"namespaceStorage": {
"nameless": {
"s1": {"class": "Species", "compartment": "comp0", "title": "Species number one"}
}
},
"unitDefStorage": {},
"exportStorage": {
"some_random_id": {"class": "SBMLExport", "filepath": "sbml"}
}
}
Structure 5. Heta container (bound)
{
"namespaceStorage": {
"nameless": {
"s1": {
"class": "Species",
"compartment": "comp0",
"title": "Species number one",
"compartmentObj": {...} // direct reference to the compartment comp0
}
}
},
"unitDefStorage": {
},
"exportStorage": {
"some_random_id": {
"class": "SBMLExport",
"filepath": "sbml"
}
}
}
Output formats.
file: sbml.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<sbml
xmlns = "http://www.sbml.org/sbml/level2/version4"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
level="2" version="4">
...
<listOfSpecies>
<species
id = "s1"
metaid = "nameless::s1"
compartment = "comp0"
name = "Species number one"
boundaryCondition = "false"
constant = "false",
hasOnlySubstanceUnits = "false"
/>
</listOfSpecies>
</sbml>