JSBML lacks support for inline units

17 views
Skip to first unread message

Matthias König

unread,
Mar 2, 2018, 5:27:58 AM3/2/18
to jsbml-development
Hi all,
in libsbml it is possible to associate units with bare numbers. This is often necessary for full unit validation and simplifies things, because one does not need to define a parameter for a simple inline number in a math formula.
This is documented in the libsbml API

http://sbml.org/Software/libSBML/5.13.0/docs/cpp-api/_l3_parser_8cpp.html#a58e584e7c21801b34d79fed7a7c05ac8

The following lists the main differences in the formula syntax supported by the "Level 3" or L3 versions of the formula parsers and formatters, compared to what is supported by the Level 1-oriented SBML_parseFormula() and SBML_formulaToString():

  • Units may be asociated with bare numbers, using the following syntax:
    number unit
    The number may be in any form (an integer, real, or rational number), and the unit must conform to the syntax of an SBML identifier (technically, the type defined as SId in the SBML specifications). The whitespace between number and unit is optional.

I could not find any mentioning of this in the SBML specifcation, so it would probably be good to add this, especially because the inline units are written in the XML (so it should be part of the spec).

In libsbml the support for such inline units is very good, in JSBML the support is lacking so far making it difficult to generate models with full unit validation. Such math can be easily generated and is printing correctly, i.e., the following allows to generate such math and prints: "5 m"

import libsbml

doc = libsbml.SBMLDocument(3, 2)
model = doc.createModel()
model.id = "test_inline_unit"

ud = model.createUnitDefinition()
ud.setId("m")
u = model.createUnit()
u.setKind(libsbml.UNIT_KIND_METRE)
u.setExponent(1.0)
u.setScale(1)
u.setMultiplier(1.0)
ud.addUnit(u)

p = model.createParameter()
p.id = "p"
p.constant = False
p.units = "m"

rule = model.createAssignmentRule()
rule.variable = "p"
ast = libsbml.parseL3FormulaWithModel("5.0 m", model)
rule.setMath(ast)

formula = libsbml.formulaToL3String(ast)
print(formula)

libsbml.writeSBMLToFile(doc, "inline_units_py.xml")

 
JSBML can neither print the inline units, nor generate models with them:
The following prints "5", not like it should "5 m", the formula with inline unit cannot be parsed:

package org.cy3sbml.oven;

import org.sbml.jsbml.*;
import org.sbml.jsbml.text.parser.ParseException;

import javax.xml.stream.XMLStreamException;
import java.io.IOException;


public class InlineUnitsDropped {

public static void main(String[] args) throws IOException, XMLStreamException, ParseException {

// [1] To formula with inline units not working
SBMLDocument doc1 = JSBML.readSBML("/home/mkoenig/Desktop/inline_units_py.xml");
Model m1 = doc1.getModel();
AssignmentRule r1 = m1.getAssignmentRuleByVariable("p");
ASTNode a1 = r1.getMath();
String formula = JSBML.formulaToString(a1);
System.out.println(formula);


// [2] Parsing formulas with inline units not working
SBMLDocument doc = new SBMLDocument(3, 2);
Model model = doc.createModel();
model.setId("test_inline_unit");

UnitDefinition ud = model.createUnitDefinition();
ud.setId("m");
Unit u = new Unit();
u.setKind(Unit.Kind.METRE);
u.setExponent(1.0);
u.setScale(1);
u.setMultiplier(1.0);

ud.addUnit(u);


Parameter p = model.createParameter("p");
p.setConstant(false);
p.setUnits("m");

AssignmentRule rule = model.createAssignmentRule();
rule.setVariable("p");
ASTNode ast = JSBML.parseFormula("5.0 m");
rule.setMath(ast);

System.out.println(ast);

JSBML.writeSBML(doc, "/home/mkoenig/Desktop/inline_units.xml");
}
}

Resulting in

Exception in thread "main" org.sbml.jsbml.text.parser.ParseException: org.sbml.jsbml.text.parser.ParseException: Encountered " <STRING> "m "" at line 1, column 5.
Was expecting one of:
    <EOF>
    "+" ...
    "^" ...
    "-" ...
    "*" ...
    "/" ...
    "%" ...
    <COMPARISON> ...
    <BOOLEAN_LOGIC> ...
    <EOL> ...
   
    at org.sbml.jsbml.ASTNode.parseFormula(ASTNode.java:1106)
    at org.sbml.jsbml.JSBML.parseFormula(JSBML.java:368)
    at org.cy3sbml.oven.InlineUnitsDropped.main(InlineUnitsDropped.java:47)
Caused by: org.sbml.jsbml.text.parser.ParseException: Encountered " <STRING> "m "" at line 1, column 5.
Was expecting one of:
    <EOF>
    "+" ...
    "^" ...
    "-" ...
    "*" ...
    "/" ...
    "%" ...
    <COMPARISON> ...
    <BOOLEAN_LOGIC> ...
    <EOL> ...
   
    at org.sbml.jsbml.text.parser.FormulaParserLL3.generateParseException(FormulaParserLL3.java:1758)
    at org.sbml.jsbml.text.parser.FormulaParserLL3.jj_consume_token(FormulaParserLL3.java:1643)
    at org.sbml.jsbml.text.parser.FormulaParserLL3.expression(FormulaParserLL3.java:700)
    at org.sbml.jsbml.text.parser.FormulaParserLL3.parse(FormulaParserLL3.java:683)
    at org.sbml.jsbml.ASTNode.parseFormula(ASTNode.java:1103)
    ... 2 more


It would be great if JSBML could support inline units like libsbml. Also the inline units should be documented in the SBML specification.
Best Matthias




Matthias König

unread,
Mar 2, 2018, 5:30:42 AM3/2/18
to jsbml-development
Attached the minimal example SBML.
inline_units_py.xml

Nicolas Rodriguez

unread,
Mar 2, 2018, 10:47:42 AM3/2/18
to jsbml-de...@googlegroups.com

Hi Matthias,

Thanks for the request, I have added a pivotal story for it (https://www.pivotaltracker.com/story/show/155658888) but it won't have high priority. May be we can find a student to work on it at some point.

cheers,

Nico

--
You received this message because you are subscribed to the Google Groups "jsbml-development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jsbml-developm...@googlegroups.com.
To post to this group, send email to jsbml-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jsbml-development/46473917-6557-49e0-aca4-02f8c5938487%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Matthias König

unread,
Mar 2, 2018, 11:06:44 AM3/2/18
to jsbml-development
Hi Nicolas,
thanks. Sounds good.
Best Matthias

To unsubscribe from this group and stop receiving emails from it, send an email to jsbml-development+unsubscribe@googlegroups.com.
To post to this group, send email to jsbml-development@googlegroups.com.

--
You received this message because you are subscribed to a topic in the Google Groups "jsbml-development" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jsbml-development/NKvOu6Mukg0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jsbml-development+unsubscribe@googlegroups.com.
To post to this group, send email to jsbml-development@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jsbml-development/ad24c62f-0ada-d7cf-a2b3-f0f6d4750e9b%40ebi.ac.uk.

For more options, visit https://groups.google.com/d/optout.



--
Matthias König, PhD.
Junior Group Leader LiSyM - Systems Medicine of the Liver
Humboldt Universität zu Berlin, Institute of Biology, Institute for Theoretical Biology
  https://livermetabolism.com
koni...@googlemail.com
Reply all
Reply to author
Forward
0 new messages