SBML.org — the global portal for all things SBML

Changes to libSBML's constructors

Overview

In libSBML versions up through version 3.x, when you create an object using the class constructor, libSBML uses default values for the SBML level and version. Those defaults values are the level and version of the most recently published SBML specification. If the objects are created independently using their constructors, they have no knowledge of any SBMLDocument that might have been created in the program. Once the component object is added to an SBMLDocument object, only then does it takes on the level and version of that SBMLDocument. Unfortunately, this can lead to unexpected inconsistencies and invalid SBML.

Example of the issue

Consider the following code fragment:

Compartment *c = new Compartment();
c->setSpatialDimensions(2);

Model *m = new Model();
m->setName("foo");
m->addCompartment(c);

SBMLDocument *doc = new SBMLDocument();
doc->setLevelAndVersion(1, 2);
doc->addModel(m);

It seems likely that the user is intending to create an SBML Level 1 Version 2 model. However, if the document were to be written out, the model name attribute would be empty! This is a consequence of the fact that at the point at which the model was created the default values for level and version were 2 and 4 respectively. The setName function on a Level 2 model acts on the internal name variable whereas the name attribute in a Level 1 model refers to the id variable.

In SBML Level 1 all compartments were 3-dimensional. However, the above code set the spatialDimensions variable to 2. Since the spatialDimensions attribute did not exist in Level 1 this value will not be written out, but the internal representation of the model will be a Level 1 model with a 2-dimensional compartment. This is not valid SBML.

Solution

LibSBML-4 provides constructors that allow the level, version and optionally a set of XML namespaces to be initialised. If the argument values taken together do not represent valid SBML then the contructor will throw an exception and the object will not be contructed.

API

A constructor creates the object as the existing constructors do but additionally sets the value of the internal variables mObjectLevel and mObjectVersion and optionally sets the mNamespaces variable.

Compartment::Compartment (unsigned int level, unsigned int version,
                          XMLNamespaces *xmlns) :
   SBase              ( -1       )
 , mSpatialDimensions ( 3        )
 , mSize              ( 1.0      )
 , mConstant          ( true     )
 , mIsSetSize         ( false    )
{
  mObjectLevel = level;
  mObjectVersion = version;
  if (xmlns) setNamespaces(xmlns);

  if (!isValidLevelVersionNamespaceCombination())
    throw OurSBMLConstructorException();
}

Once the object has been added to an SBMLDocument, the level, version and namespaces for that document override those used to create the object. However, the ability to set these values when the object is created will facilitate the creation of valid SBML.

Alternative API

Having implemented these constructors, it was pointed out that in fact the arguments amounted to a duplication of information. With the exception of SBML Level 1 it is aways possible to infer the level and version from the SBML namespace. It was therefore suggested that the arguments to the new constructors be reduced to merely the set of XMLNamespaces. However, this would limit the ability to construct SBML Level 1 Version 1 objects. Thus, a new class, SBMLNamespaces, has been developed. This class stores the level, version and a set of XMLNamespaces and is contructed using the level and version.

class LIBSBML_EXTERN SBMLNamespaces
{
public:

  SBMLNamespaces(unsigned int level = SBML_DEFAULT_LEVEL, 
                 unsigned int version = SBML_DEFAULT_VERSION);
  
  ~SBMLNamespaces();

  static std::string getSBMLNamespaceURI(unsigned int level,
                                         unsigned int version);
  
  unsigned int getLevel();

  unsigned int getVersion();

  XMLNamespaces * getNamespaces();

protected:  

  unsigned int    mLevel;
  unsigned int    mVersion;
  XMLNamespaces * mNamespaces;
};


As libSBML develops support for SBML Level 3 it is anticipated that an additional argument specifying SBML packages will be included.


Constructors for SBML objects can now be constructed from an SBMLNamespaces instance.

Compartment::Compartment (SBMLNamespaces *sbmlns) :
   SBase ("", "", -1)
 , mSpatialDimensions( 3        )
 , mSize             ( 1.0      )
 , mConstant         ( true     )
 , mIsSetSize        ( false    )
{
  mObjectLevel = sbmlns->getLevel();
  mObjectVersion = sbmlns->getVersion();
  setNamespaces(sbmlns->getNamespaces());
}

The new SBMLNamespaces class and corresponding constructors will be available in libSBML-3.4.0. The existing constructors in libSBML-4-beta will be replaced by these new constructors.

Retrieved from "http://sbml.org/SBML_Projects/libSBML/Development/Changes_to_libSBML%27s_constructors"

This page was last modified 21:11, 26 May 2009.



Please use our issue tracking system for any questions or suggestions about this website. This page was last modified 21:11, 26 May 2009.