SBML.org — the global portal for all things SBML

Changed API for setXYZ() methods

Contents

Overview

Using libSBML it is currently possible to create an internal representation of an SBML model that is invalid SBML. Values can be assigned to attributes on SBML components using set functions. Currently there are very few checks on the values being assigned. The set functions will change to verify the attribute value, prior to assigning value to a variable. In order to allow users to monitor the effect, the return type of these functions will change from void to int; where the return value will be drawn from an enumeration of values indicating success or failure of the function.

Once objects have been created, they can be added to other objects to construct a model. The add functions will also change to verify that the object being added is appropriate; returning a value to indicate success/failure.

Example of the issue

Consider the following code:

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

  Model * model = doc->createModel();

  Compartment * c = model->createCompartment();
  c->setSpatialDimensions(2);

  Species * s = new Species();
  s->setSpeciesType("gg");

  m->addSpecies(s);

A Level 1 Version 2 document has been created with a model, a compartment and a species. However the internal representation of the model is completely invalid SBML.

  1. Compartment c has the spatialDimensions variable set to 2; despite the fact that in SBML L1V2 all compartments are 3-dimensional.
  2. Compartment c does not have the required name attribute set.
  3. Species s has the speciesType variable set; despite the fact that speciesType was not an attribute on an L1V2 Species.
  4. Species s does not have the required name, compartment and initialAmount attributes set.

Solution

Functions will determine the requested action is appropriate and return a value to indicate to the user whether the action was taken.

Set function API

The set functions will determine whether the function is appropriate for the given SBML Level/Version and check that the value to be assigned is a valid value for the particular attribute.

For example the 'setSpatialDimensions' function on the Compartment class will change to:

int
Compartment::setSpatialDimensions(unsigned int value)
{
  if (getLevel() < 2)
  {
    // spatialDimensions must always be 3 in a level 1 compartment
    mSpatialDimensions = 3; // maintain internal consistency
    return LIBSBML_UNEXPECTED_ATTRIBUTE;
  }
  else if (value < 0 || value > 3)
  {
    return LIBSBML_INVALID_ATTRIBUTE_VALUE;
  }
  else
  {
    mSpatialDimensions = value;
    return LIBSBML_OPERATION_SUCCESS;
  }
}

The code works as follows:

  • if the compartment is Level 1
    • assign mSpatialDimensions to 3 to preserve consistency of the internal representation of the model
    • return failure indicating that the spatialDimensions attribute is not expected for a Level 1 model
  • if the value to be assigned is not 0, 1, 2 or 3
    • return failure indicating that the value given was not valid for the spatialDimensions attribute
  • otherwise
    • assign mSpatialDimensions to the value given
    • return success

Add function API

Currently components are added to other components without any checks on the level/version of the individual objects. This code will change to only permit components with matching level/version values to be added to each other. In addition further checks will be made to ensure that any required attributes and elements have been set for the object to be added and that an object (of this type) with an identical id does not already exist.

For example, the 'addCompartment' function on the Model class will change to

int
Model::addCompartment (const Compartment* c)
{
  if (c == NULL)
  {
    return LIBSBML_OPERATION_FAILED;
  }
  else if (!(c->hasRequiredAttributes())
        || !(c->hasRequiredElements()))
  {
    return LIBSBML_INVALID_OBJECT;
  }
  else if (getLevel() != c->getLevel())
  {
    return LIBSBML_LEVEL_MISMATCH;
  }
  else if (getVersion() != c->getVersion())
  {
    return LIBSBML_VERSION_MISMATCH;
  }
  else if (getCompartment(c->getId()) != NULL)
  {
    // compartment with this id already exists 
    return LIBSBML_DUPLICATE_OBJECT_ID;
  }
  else
  {
    mCompartments.append(c);

    return LIBSBML_OPERATION_SUCCESS;
  }
}

The code considers the following;

  • if the argument supplied is NULL pointer
    • return failure indicating that the function was not performed
  • if the required attributes and elements have not been set on the argument Compartment object
    • return failure indicating the object is not valid
  • if the SBML Level of the Model object does not match the SBML Level of the argument Compartment object
    • return failure indicating a mismatch of SBML Level
  • if the SBML Version of the Model object does not match the SBML Version of the argument Compartment object
    • return failure indicating a mismatch of SBML Version
  • if a compartment with an identical id already exists within the model
    • return failure indicating a duplicate id
  • otherwise
    • add the argument Compartment to the Model
    • return success

Enumeration of return values

Name Value Description
LIBSBML_OPERATION_SUCCESS 0 The function was performed successfully.
LIBSBML_INDEX_EXCEEDS_SIZE -1 The function attempted to access a child object with an index that exceeds the size of the parent object.
LIBSBML_UNEXPECTED_ATTRIBUTE -2 The attribute being accessed is not applicable to the parent object.
LIBSBML_OPERATION_FAILED -3 The function was not successful.
LIBSBML_INVALID_ATTRIBUTE_VALUE -4 The argument value is not appropriate for this attribute.
LIBSBML_INVALID_OBJECT -5 The object passed as an argument is not valid i.e. it does not have all the required attributes/elements.
LIBSBML_DUPLICATE_OBJECT_ID -6 The parent object already contains a child object of this type with the same id value.
LIBSBML_LEVEL_MISMATCH -7 The SBML Level of the argument does not match the SBML Level of the parent object.
LIBSBML_VERSION_MISMATCH -8 The SBML Version of the argument does not match the SBML Version of the parent object.
LIBSBML_INVALID_XML_OPERATION -9 The function is invalid for the current XML object.

Functions affected

The following functions will all change. In libSBML-3 these functions all returned void. In libSBML-4 they will validate the action to be taken and return an integer indicating success or failure:

  • addXXX
  • appendXXX
  • clearXXX
  • freeXXX
  • insertXXX
  • prependXXX
  • removeXXX
  • replaceXXX
  • setXXX
  • swapXXX
  • unsetXXX

where XXX indicates an attribute or component name.

Retrieved from "http://sbml.org/SBML_Projects/libSBML/Development/Changed_API_for_setXYZ%28%29_methods"

This page was last modified 16:03, 16 March 2009.



Please use our issue tracking system for any questions or suggestions about this website. This page was last modified 16:03, 16 March 2009.