Stricter checking before conversion by setLevelAndVersion()
LibSBML provides a facility to convert a SBML document between levels and versions of SBML. Unfortunately, the implementation in libSBML versions up through version 3 behaves in a way that makes it possible to introduce inconsistencies between the intended model and the internal representation of the model stored by libSBML.
Example of the issue
Consider the following code:
SBMLDocument *doc = new SBMLDocument(2, 4); Model * m = doc->createModel(); m->setSBOTerm(256); bool success = doc->setLevelAndVersion(1, 2);
The SBMLDocument will contain a model object whose
sboTerm attribute has been set. Calling
setLevelAndVersion() to convert the model to an SBML L1V2 model succeeds without generating an error. Writing out this model also produces a valid model, because the
sboTerm attribute will just be ignored (the libSBML output functions will check the SBML level and version and act appropriately). However, the in-memory representation of the model is invalid because it is a L1 model that has an
sboTerm (and SBML L1 does not define such an attribute).
Consider another example:
SBMLDocument *doc = new SBMLDocument(2, 4); Model * m = doc->createModel(); Compartment * c = m->createCompartment(); c->setId("c"); Parameter* p = m->createParameter(); p->setId("p"); p->setUnits("mole"); Parameter* p1 = m->createParameter(); p1->setId("p1"); AssignmentRule *ar = m->createAssignmentRule(); ar->setVariable("p1"); ar->setMath(SBML_parseFormula("p + c")); bool success = doc->setLevelAndVersion(2, 3);
The SBMLDocument contains a model with a compartment, two parameters and an assignment rule that assigns value to parameter
p1 using the formula "
p + c". Again, the conversion will be performed successfully. Note that
p represents a parameter with units of moles, and
c represents a compartment which by default has units of litres. In an L2V4 model, strict unit consistency is not required and thus, using the formula "
p + c" is permitted, even though the formula is nonsense because it mixes units. However, as an L2V3 model, this is invalid because SBML prior to L2V4 did require consistency in units of measurement. Despite this,
setLevelAndVersion() (in libSBML prior to version 4) allows the conversion. This demonstrates one way in which this method can convert a valid model into an invalid one.
In libSBML 4, the
setLevelAndVersion() function will be modified to help prevent the creation of invalid SBML and preserve the consistency of the internal represntation.
LibSBML-4 has added a further optional argument to the setLevelAndVersion function.
bool setLevelAndVersion(unsigned int level, unsigned int version, bool strict = false);
The default value, strict = false, means that the function performs exactly as it has done in previous versions of libSBML.
However, when the function is used with strict = true, there are more stringent restrictions applied to the conversion.
- A model is fully validated before a conversion is attempted. If the model fails validation, conversion is not attempted and the function returns false.
- The potential resulting model is validated and if it is invalid, the conversion is not performed and the function returns false.
- The usual checks are applied to determine whether conversion is possible. In cases where the target model may have lost some information contained in the source model (e.g. sboTerms) but would still be valid; the internal representation of the model is made consistent with the new level and version. In practical terms this means that converting a model with sboTerms to Level 1 will remove the sboTerms from the internal model and unless the user has saved them elsewhere the information will be lost.
In brief, with strict = true, only a valid model that will produce a valid model is converted and the internal representation is made consistent with the new level and version.
NOTE: The user can customise the validation that is applied using the setConsistencyChecks function. Only those validators that have been selected will be applied when determining the validity of both the source and the target model.