Loading [MathJax]/extensions/tex2jax.js
libSBML C++ API  5.20.4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
createExampleSBML.cpp

Lengthy example of creating SBML models presented in the SBML specification.

Lengthy example of creating SBML models presented in the SBML specification.

/**
* @file createExampleSBML.cpp
* @brief Creates example SBML models presented in the SBML specification.
* @author Akiya Jouraku
* @author Michael Hucka
* @author Sarah Keating
*
* <!--------------------------------------------------------------------------
* This sample program is distributed under a different license than the rest
* of libSBML. This program uses the open-source MIT license, as follows:
*
* Copyright (c) 2013-2018 by the California Institute of Technology
* (California, USA), the European Bioinformatics Institute (EMBL-EBI, UK)
* and the University of Heidelberg (Germany), with support from the National
* Institutes of Health (USA) under grant R01GM070923. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Neither the name of the California Institute of Technology (Caltech), nor
* of the European Bioinformatics Institute (EMBL-EBI), nor of the University
* of Heidelberg, nor the names of any contributors, may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* ------------------------------------------------------------------------ -->
*/
#include <iostream>
#include <sbml/SBMLTypes.h>
using namespace std;
LIBSBML_CPP_NAMESPACE_USE
//
// Functions for creating the Example SBML documents.
//
SBMLDocument* createExampleEnzymaticReaction(); /* 7.1 */
SBMLDocument* createExampleInvolvingUnits(); /* 7.2 */
SBMLDocument* createExampleInvolvingFunctionDefinitions(); /* 7.8 */
//
// Helper functions for validating and writing the SBML documents created.
//
bool validateExampleSBML(SBMLDocument *sbmlDoc);
bool writeExampleSBML(const SBMLDocument *sbmlDoc, const string& filename);
//
// These variables are used in writeExampleSBML when writing an SBML
// document. They are handed to libSBML functions in order to include
// the program information into comments within the SBML file.
//
const static string ProgramName = "createExampleModels";
const static string ProgramVersion = "1.0.0";
//
// The SBML Level and Version of the example SBML models.
//
const static unsigned int Level = 2;
const static unsigned int Version = 4;
//===============================================================================
//
// Main routine
//
// Creates SBML models represented in "Example models expressed in XML using
// SBML" in Section 7 of the SBML Level 2 Version 4 specification(*).
//
// (*) The specification document is available at the following URL:
// http://sbml.org/Documents/Specifications
//
//===============================================================================
//
int
main (int argc, char *argv[])
{
SBMLDocument* sbmlDoc = 0;
bool SBMLok = false;
try
{
//-------------------------------------------------
// 7.1 A Simple example application of SBML
//-------------------------------------------------
sbmlDoc = createExampleEnzymaticReaction();
SBMLok = validateExampleSBML(sbmlDoc);
if (SBMLok) writeExampleSBML(sbmlDoc, "enzymaticreaction.xml");
delete sbmlDoc;
if (!SBMLok) return 1;
//-------------------------------------------------
// 7.2 Example involving units
//-------------------------------------------------
sbmlDoc = createExampleInvolvingUnits();
SBMLok = validateExampleSBML(sbmlDoc);
if (SBMLok) writeExampleSBML(sbmlDoc, "units.xml");
delete sbmlDoc;
if (!SBMLok) return 1;
//-------------------------------------------------
// 7.8 Example involving function definitions
//-------------------------------------------------
sbmlDoc = createExampleInvolvingFunctionDefinitions();
SBMLok = validateExampleSBML(sbmlDoc);
if (SBMLok) writeExampleSBML(sbmlDoc, "functiondef.xml");
delete sbmlDoc;
if (!SBMLok) return 1;
}
catch (std::bad_alloc& e)
{
cerr << e.what() << ": Unable to allocate memory." << endl;
return 1;
}
catch (...)
{
cerr << "Unexpected exceptional condition encountered." << endl;
return 1;
}
// A 0 return status is the standard Unix/Linux way to say "all ok".
return 0;
}
//===============================================================================
//
//
// Functions for creating the Example SBML documents.
//
//
//===============================================================================
/**
*
* Creates an SBML model represented in "7.1 A Simple example application of SBML"
* in the SBML Level 2 Version 4 Specification.
*
*/
SBMLDocument* createExampleEnzymaticReaction()
{
const unsigned int level = Level;
const unsigned int version = Version;
//---------------------------------------------------------------------------
//
// Creates an SBMLDocument object
//
//---------------------------------------------------------------------------
SBMLDocument* sbmlDoc = new SBMLDocument(level,version);
//---------------------------------------------------------------------------
//
// Creates a Model object inside the SBMLDocument object.
//
//---------------------------------------------------------------------------
Model* model = sbmlDoc->createModel();
model->setId("EnzymaticReaction");
//---------------------------------------------------------------------------
//
// Creates UnitDefinition objects inside the Model object.
//
//---------------------------------------------------------------------------
// Temporary pointers (reused more than once below).
UnitDefinition* unitdef;
Unit* unit;
//---------------------------------------------------------------------------
// (UnitDefinition1) Creates an UnitDefinition object ("per_second")
//---------------------------------------------------------------------------
unitdef = model->createUnitDefinition();
unitdef->setId("per_second");
// Creates an Unit inside the UnitDefinition object
unit = unitdef->createUnit();
unit->setExponent(-1);
//--------------------------------------------------------------------------------
// (UnitDefinition2) Creates an UnitDefinition object ("litre_per_mole_per_second")
//--------------------------------------------------------------------------------
// Note that we can reuse the pointers 'unitdef' and 'unit' because the
// actual UnitDefinition object (along with the Unit objects within it)
// is already attached to the Model object.
unitdef = model->createUnitDefinition();
unitdef->setId("litre_per_mole_per_second");
// Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second")
unit = unitdef->createUnit();
unit->setExponent(-1);
// Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second")
unit = unitdef->createUnit();
unit->setExponent(1);
// Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second")
unit = unitdef->createUnit();
unit->setExponent(-1);
//---------------------------------------------------------------------------
//
// Creates a Compartment object inside the Model object.
//
//---------------------------------------------------------------------------
Compartment* comp;
const string compName = "cytosol";
// Creates a Compartment object ("cytosol")
comp = model->createCompartment();
comp->setId(compName);
// Sets the "size" attribute of the Compartment object.
//
// We are not setting the units on the compartment size explicitly, so
// the units of this Compartment object will be the default SBML units of
// volume, which are liters.
//
comp->setSize(1e-14);
//---------------------------------------------------------------------------
//
// Creates Species objects inside the Model object.
//
//---------------------------------------------------------------------------
// Temporary pointer (reused more than once below).
Species *sp;
//---------------------------------------------------------------------------
// (Species1) Creates a Species object ("ES")
//---------------------------------------------------------------------------
// Create the Species objects inside the Model object.
sp = model->createSpecies();
sp->setId("ES");
sp->setName("ES");
// Sets the "compartment" attribute of the Species object to identify the
// compartment in which the Species object is located.
sp->setCompartment(compName);
// Sets the "initialAmount" attribute of the Species object.
//
// In SBML, the units of a Species object's initial quantity are
// determined by two attributes, "substanceUnits" and
// "hasOnlySubstanceUnits", and the "spatialDimensions" attribute
// of the Compartment object ("cytosol") in which the species
// object is located. Here, we are using the default values for
// "substanceUnits" (which is "mole") and "hasOnlySubstanceUnits"
// (which is "false"). The compartment in which the species is
// located uses volume units of liters, so the units of these
// species (when the species appear in numerical formulas in the
// model) will be moles/liters.
//
//---------------------------------------------------------------------------
// (Species2) Creates a Species object ("P")
//---------------------------------------------------------------------------
sp = model->createSpecies();
sp->setCompartment(compName);
sp->setId("P");
sp->setName("P");
//---------------------------------------------------------------------------
// (Species3) Creates a Species object ("S")
//---------------------------------------------------------------------------
sp = model->createSpecies();
sp->setCompartment(compName);
sp->setId("S");
sp->setName("S");
sp->setInitialAmount(1e-20);
//---------------------------------------------------------------------------
// (Species4) Creates a Species object ("E")
//---------------------------------------------------------------------------
sp = model->createSpecies();
sp->setCompartment(compName);
sp->setId("E");
sp->setName("E");
sp->setInitialAmount(5e-21);
//---------------------------------------------------------------------------
//
// Creates Reaction objects inside the Model object.
//
//---------------------------------------------------------------------------
// Temporary pointers.
Reaction* reaction;
//---------------------------------------------------------------------------
// (Reaction1) Creates a Reaction object ("veq").
//---------------------------------------------------------------------------
reaction = model->createReaction();
reaction->setId("veq");
// (Reactant1) Creates a Reactant object that references Species "E"
// in the model. The object will be created within the reaction in the
// SBML <listOfReactants>.
spr = reaction->createReactant();
spr->setSpecies("E");
// (Reactant2) Creates a Reactant object that references Species "S"
// in the model.
spr = reaction->createReactant();
spr->setSpecies("S");
//---------------------------------------------------------------------------
// (Product1) Creates a Product object that references Species "ES" in
// the model.
//---------------------------------------------------------------------------
spr = reaction->createProduct();
spr->setSpecies("ES");
//---------------------------------------------------------------------------
// Creates a KineticLaw object inside the Reaction object ("veq").
//---------------------------------------------------------------------------
kl = reaction->createKineticLaw();
//---------------------------------------------------------------------------
// Creates an ASTNode object which represents the following math of the
// KineticLaw.
//
// <math xmlns="http://www.w3.org/1998/Math/MathML">
// <apply>
// <times/>
// <ci> cytosol </ci>
// <apply>
// <minus/>
// <apply>
// <times/>
// <ci> kon </ci>
// <ci> E </ci>
// <ci> S </ci>
// </apply>
// <apply>
// <times/>
// <ci> koff </ci>
// <ci> ES </ci>
// </apply>
// </apply>
// </apply>
// </math>
//
//---------------------------------------------------------------------------
//------------------------------------------
//
// create nodes representing the variables
//
//------------------------------------------
ASTNode* astCytosol = new ASTNode(AST_NAME);
astCytosol->setName("cytosol");
ASTNode* astKon = new ASTNode(AST_NAME);
astKon->setName("kon");
ASTNode* astKoff = new ASTNode(AST_NAME);
astKoff->setName("koff");
ASTNode* astE = new ASTNode(AST_NAME);
astE->setName("E");
ASTNode* astS = new ASTNode(AST_NAME);
astS->setName("S");
ASTNode* astES = new ASTNode(AST_NAME);
astES->setName("ES");
//--------------------------------------------
//
// create node representing
// <apply>
// <times/>
// <ci> koff </ci>
// <ci> ES </ci>
// </apply>
//
//--------------------------------------------
ASTNode *astTimes1 = new ASTNode(AST_TIMES);
astTimes1->addChild(astKoff);
astTimes1->addChild(astES);
//--------------------------------------------
//
// create node representing
// <apply>
// <times/>
// <ci> kon </ci>
// <ci> E </ci>
// <ci> S </ci>
// </apply>
//
//
// (NOTES)
//
// Since there is a restriction with an ASTNode of "<times/>" operation
// such that the ASTNode is a binary class and thus only two operands can
// be directly added, the following code in this comment block is invalid
// because the code directly adds three <ci> ASTNodes to <times/> ASTNode.
//
// ASTNode *astTimes = new ASTNode(AST_TIMES);
// astTimes->addChild(astKon);
// astTimes->addChild(astE);
// astTimes->addChild(astS);
//
// The following valid code after this comment block creates the ASTNode
// as a binary tree.
//
// Please see "Converting between ASTs and text strings" described
// at http://sbml.org/Software/libSBML/docs/cpp-api/class_a_s_t_node.html
// for the detailed information.
//
//--------------------------------------------
ASTNode *astTimes2 = new ASTNode(AST_TIMES);
astTimes2->addChild(astE);
astTimes2->addChild(astS);
ASTNode *astTimes = new ASTNode(AST_TIMES);
astTimes->addChild(astKon);
astTimes->addChild(astTimes2);
//--------------------------------------------
//
// create node representing
// <apply>
// <minus/>
// <apply>
// <times/>
// <ci> kon </ci>
// <ci> E </ci>
// <ci> S </ci>
// </apply>
// <apply>
// <times/>
// <ci> koff </ci>
// <ci> ES </ci>
// </apply>
// </apply>
//
//--------------------------------------------
ASTNode *astMinus = new ASTNode(AST_MINUS);
astMinus->addChild(astTimes);
astMinus->addChild(astTimes1);
//--------------------------------------------
//
// create node representing
// <apply>
// <times/>
// <ci> cytosol </ci>
// <apply>
// <minus/>
// <apply>
// <times/>
// <ci> kon </ci>
// <ci> E </ci>
// <ci> S </ci>
// </apply>
// <apply>
// <times/>
// <ci> koff </ci>
// <ci> ES </ci>
// </apply>
// </apply>
// </apply>
//
//--------------------------------------------
ASTNode* astMath = new ASTNode(AST_TIMES);
astMath->addChild(astCytosol);
astMath->addChild(astMinus);
//---------------------------------------------
//
// set the Math element
//
//------------------------------------------------
kl->setMath(astMath);
// KineticLaw::setMath(const ASTNode*) sets the math of the KineticLaw object
// to a copy of the given ASTNode, and thus basically the caller should delete
// the original ASTNode object if the caller has the ownership of the object to
// avoid memory leak.
delete astMath;
//---------------------------------------------------------------------------
// Creates local Parameter objects inside the KineticLaw object.
//---------------------------------------------------------------------------
// Creates a Parameter ("kon")
Parameter* para = kl->createParameter();
para->setId("kon");
para->setValue(1000000);
para->setUnits("litre_per_mole_per_second");
// Creates a Parameter ("koff")
para = kl->createParameter();
para->setId("koff");
para->setValue(0.2);
para->setUnits("per_second");
//---------------------------------------------------------------------------
// (Reaction2) Creates a Reaction object ("vcat") .
//---------------------------------------------------------------------------
reaction = model->createReaction();
reaction->setId("vcat");
reaction->setReversible(false);
//---------------------------------------------------------------------------
// Creates Reactant objects inside the Reaction object ("vcat").
//---------------------------------------------------------------------------
// (Reactant1) Creates a Reactant object that references Species "ES" in the
// model.
spr = reaction->createReactant();
spr->setSpecies("ES");
//---------------------------------------------------------------------------
// Creates a Product object inside the Reaction object ("vcat").
//---------------------------------------------------------------------------
// (Product1) Creates a Product object that references Species "E" in the model.
spr = reaction->createProduct();
spr->setSpecies("E");
// (Product2) Creates a Product object that references Species "P" in the model.
spr = reaction->createProduct();
spr->setSpecies("P");
//---------------------------------------------------------------------------
// Creates a KineticLaw object inside the Reaction object ("vcat").
//---------------------------------------------------------------------------
kl = reaction->createKineticLaw();
//---------------------------------------------------------------------------
// Sets a math (ASTNode object) to the KineticLaw object.
//---------------------------------------------------------------------------
// To create mathematical expressions, one would typically construct
// an ASTNode tree as the above example code which creates a math of another
// KineticLaw object. Here, to save some space and illustrate another approach
// of doing it, we will write out the formula in MathML form and then use a
// libSBML convenience function to create the ASTNode tree for us.
// (This is a bit dangerous; it's very easy to make mistakes when writing MathML
// by hand, so in a real program, we would not really want to do it this way.)
string mathXMLString = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
" <apply>"
" <times/>"
" <ci> cytosol </ci>"
" <ci> kcat </ci>"
" <ci> ES </ci>"
" </apply>"
"</math>";
astMath = readMathMLFromString(mathXMLString.c_str());
kl->setMath(astMath);
delete astMath;
//---------------------------------------------------------------------------
// Creates local Parameter objects inside the KineticLaw object.
//---------------------------------------------------------------------------
// Creates a Parameter ("kcat")
para = kl->createParameter();
para->setId("kcat");
para->setValue(0.1);
para->setUnits("per_second");
// Returns the created SBMLDocument object.
// The returned object must be explicitly deleted by the caller,
// otherwise a memory leak will happen.
return sbmlDoc;
}
/**
*
* Creates an SBML model represented in "7.2 Example involving units"
* in the SBML Level 2 Version 4 Specification.
*
*/
SBMLDocument* createExampleInvolvingUnits()
{
const unsigned int level = Level;
const unsigned int version = Version;
//---------------------------------------------------------------------------
//
// Creates an SBMLDocument object
//
//---------------------------------------------------------------------------
SBMLDocument* sbmlDoc = new SBMLDocument(level,version);
// Adds the namespace for XHTML to the SBMLDocument object. We need this
// because we will add notes to the model. (By default, the SBML document
// created by SBMLDocument only declares the SBML XML namespace.)
sbmlDoc->getNamespaces()->add("http://www.w3.org/1999/xhtml", "xhtml");
//---------------------------------------------------------------------------
//
// Creates a Model object inside the SBMLDocument object.
//
//---------------------------------------------------------------------------
Model* model = sbmlDoc->createModel();
model->setId("unitsExample");
//---------------------------------------------------------------------------
//
// Creates UnitDefinition objects inside the Model object.
//
//---------------------------------------------------------------------------
// Temporary pointers (reused more than once below).
UnitDefinition* unitdef;
Unit *unit;
//---------------------------------------------------------------------------
// (UnitDefinition1) Creates an UnitDefinition object ("substance").
//
// This has the effect of redefining the default unit of subtance for the
// whole model.
//---------------------------------------------------------------------------
unitdef = model->createUnitDefinition();
unitdef->setId("substance");
// Creates an Unit inside the UnitDefinition object
unit = unitdef->createUnit();
unit->setScale(-3);
//--------------------------------------------------------------------------------
// (UnitDefinition2) Creates an UnitDefinition object ("mmls")
//--------------------------------------------------------------------------------
// Note that we can reuse the pointers 'unitdef' and 'unit' because the
// actual UnitDefinition object (along with the Unit objects within it)
// is already attached to the Model object.
unitdef = model->createUnitDefinition();
unitdef->setId("mmls");
// Creates an Unit inside the UnitDefinition object ("mmls")
unit = unitdef->createUnit();
unit->setScale(-3);
// Creates an Unit inside the UnitDefinition object ("mmls")
unit = unitdef->createUnit();
unit->setExponent(-1);
// Creates an Unit inside the UnitDefinition object ("mmls")
unit = unitdef->createUnit();
unit->setExponent(-1);
//--------------------------------------------------------------------------------
// (UnitDefinition3) Creates an UnitDefinition object ("mml")
//--------------------------------------------------------------------------------
unitdef = model->createUnitDefinition();
unitdef->setId("mml");
// Creates an Unit inside the UnitDefinition object ("mml")
unit = unitdef->createUnit();
unit->setScale(-3);
// Creates an Unit inside the UnitDefinition object ("mml")
unit = unitdef->createUnit();
unit->setExponent(-1);
//---------------------------------------------------------------------------
//
// Creates a Compartment object inside the Model object.
//
//---------------------------------------------------------------------------
Compartment* comp;
const string compName = "cell";
// Creates a Compartment object ("cell")
comp = model->createCompartment();
comp->setId(compName);
// Sets the "size" attribute of the Compartment object.
//
// The units of this Compartment object is the default SBML
// units of volume (litre), and thus we don't have to explicitly invoke
// setUnits("litre") function to set the default units.
//
comp->setSize(1);
//---------------------------------------------------------------------------
//
// Creates Species objects inside the Model object.
//
//---------------------------------------------------------------------------
// Temporary pointer (reused more than once below).
Species *sp;
//---------------------------------------------------------------------------
// (Species1) Creates a Species object ("x0")
//---------------------------------------------------------------------------
sp = model->createSpecies();
sp->setId("x0");
// Sets the "compartment" attribute of the Species object to identify the
// compartnet in which the Species object located.
sp->setCompartment(compName);
// Sets the "initialConcentration" attribute of the Species object.
//
// The units of this Species object is determined by two attributes of this
// Species object ("substanceUnits" and "hasOnlySubstanceUnits") and the
// "spatialDimensions" attribute of the Compartment object ("cytosol") in which
// this species object is located.
// Since the default values are used for "substanceUnits" (substance (mole))
// and "hasOnlySubstanceUnits" (false) and the value of "spatialDimension" (3)
// is greater than 0, the units of this Species object is moles/liters .
//
//---------------------------------------------------------------------------
// (Species2) Creates a Species object ("x1")
//---------------------------------------------------------------------------
sp = model->createSpecies();
sp->setId("x1");
sp->setCompartment(compName);
//---------------------------------------------------------------------------
// (Species3) Creates a Species object ("s1")
//---------------------------------------------------------------------------
sp = model->createSpecies();
sp->setCompartment(compName);
sp->setId("s1");
//---------------------------------------------------------------------------
// (Species4) Creates a Species object ("s2")
//---------------------------------------------------------------------------
sp = model->createSpecies();
sp->setCompartment(compName);
sp->setId("s2");
//---------------------------------------------------------------------------
//
// Creates global Parameter objects inside the Model object.
//
//---------------------------------------------------------------------------
Parameter* para;
// Creates a Parameter ("vm")
para = model->createParameter();
para->setId("vm");
para->setValue(2);
para->setUnits("mmls");
// Creates a Parameter ("km")
para = model->createParameter();
para->setId("km");
para->setValue(2);
para->setUnits("mml");
//---------------------------------------------------------------------------
//
// Creates Reaction objects inside the Model object.
//
//---------------------------------------------------------------------------
// Temporary pointers.
Reaction* reaction;
//---------------------------------------------------------------------------
// (Reaction1) Creates a Reaction object ("v1").
//---------------------------------------------------------------------------
reaction = model->createReaction();
reaction->setId("v1");
//---------------------------------------------------------------------------
// Creates Reactant objects inside the Reaction object ("v1").
//---------------------------------------------------------------------------
// (Reactant1) Creates a Reactant object that references Species "x0"
// in the model.
spr = reaction->createReactant();
spr->setSpecies("x0");
//---------------------------------------------------------------------------
// Creates a Product object inside the Reaction object ("v1").
//---------------------------------------------------------------------------
// Creates a Product object that references Species "s1" in the model.
spr = reaction->createProduct();
spr->setSpecies("s1");
//---------------------------------------------------------------------------
// Creates a KineticLaw object inside the Reaction object ("v1").
//---------------------------------------------------------------------------
kl = reaction->createKineticLaw();
// Creates a <notes> element in the KineticLaw object.
// Here we illustrate how to do it using a literal string. This requires
// known the required syntax of XHTML and the requirements for SBML <notes>
// elements. Later below, we show how to create notes using objects instead
// of strings.
string notesString = "<xhtml:p> ((vm * s1)/(km + s1)) * cell </xhtml:p>";
kl->setNotes(notesString);
//---------------------------------------------------------------------------
// Creates an ASTNode object which represents the following KineticLaw object.
//
// <math xmlns=\"http://www.w3.org/1998/Math/MathML\">
// <apply>
// <times/>
// <apply>
// <divide/>
// <apply>
// <times/>
// <ci> vm </ci>
// <ci> s1 </ci>
// </apply>
// <apply>
// <plus/>
// <ci> km </ci>
// <ci> s1 </ci>
// </apply>
// </apply>
// <ci> cell </ci>
// </apply>
// </math>
//---------------------------------------------------------------------------
//
// In the following code, ASTNode objects, which construct an ASTNode tree
// of the above math, are created and added in the order of preorder traversal
// of the tree (i.e. the order corresponds to the nested structure of the above
// MathML elements), and thus the following code maybe a bit more efficient but
// maybe a bit difficult to read.
//
ASTNode* astMath = new ASTNode(AST_TIMES);
astMath->addChild(new ASTNode(AST_DIVIDE));
ASTNode* astDivide = astMath->getLeftChild();
astDivide->addChild(new ASTNode(AST_TIMES));
ASTNode* astTimes = astDivide->getLeftChild();
astTimes->addChild(new ASTNode(AST_NAME));
astTimes->getLeftChild()->setName("vm");
astTimes->addChild(new ASTNode(AST_NAME));
astTimes->getRightChild()->setName("s1");
astDivide->addChild(new ASTNode(AST_PLUS));
ASTNode* astPlus = astDivide->getRightChild();
astPlus->addChild(new ASTNode(AST_NAME));
astPlus->getLeftChild()->setName("km");
astPlus->addChild(new ASTNode(AST_NAME));
astPlus->getRightChild()->setName("s1");
astMath->addChild(new ASTNode(AST_NAME));
astMath->getRightChild()->setName("cell");
//---------------------------------------------
//
// set the Math element
//
//------------------------------------------------
kl->setMath(astMath);
delete astMath;
//---------------------------------------------------------------------------
// (Reaction2) Creates a Reaction object ("v2").
//---------------------------------------------------------------------------
reaction = model->createReaction();
reaction->setId("v2");
//---------------------------------------------------------------------------
// Creates Reactant objects inside the Reaction object ("v2").
//---------------------------------------------------------------------------
// (Reactant2) Creates a Reactant object that references Species "s1"
// in the model.
spr = reaction->createReactant();
spr->setSpecies("s1");
//---------------------------------------------------------------------------
// Creates a Product object inside the Reaction object ("v2").
//---------------------------------------------------------------------------
// Creates a Product object that references Species "s2" in the model.
spr = reaction->createProduct();
spr->setSpecies("s2");
//---------------------------------------------------------------------------
// Creates a KineticLaw object inside the Reaction object ("v2").
//---------------------------------------------------------------------------
kl = reaction->createKineticLaw();
// Sets a notes (by XMLNode) to the KineticLaw object.
//
// The following code is an alternative to using setNotes(const string&).
// The equivalent code would be like this:
//
// notesString = "<xhtml:p>((vm * s2)/(km + s2))*cell</xhtml:p>";
// kl->setNotes(notesString);
// Creates an XMLNode of start element (<xhtml:p>) without attributes.
XMLNode notesXMLNode(XMLTriple("p", "", "xhtml"), XMLAttributes());
// Adds a text element to the start element.
notesXMLNode.addChild(XMLNode(" ((vm * s2)/(km + s2)) * cell "));
// Adds it to the kineticLaw object.
kl->setNotes(&notesXMLNode);
//---------------------------------------------------------------------------
// Sets a math (ASTNode object) to the KineticLaw object.
//---------------------------------------------------------------------------
// To create mathematical expressions, one would typically construct
// an ASTNode tree as the above example code which creates a math of another
// KineticLaw object. Here, to save some space and illustrate another approach
// of doing it, we will write out the formula in MathML form and then use a
// libSBML convenience function to create the ASTNode tree for us.
// (This is a bit dangerous; it's very easy to make mistakes when writing MathML
// by hand, so in a real program, we would not really want to do it this way.)
string mathXMLString = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
" <apply>"
" <times/>"
" <apply>"
" <divide/>"
" <apply>"
" <times/>"
" <ci> vm </ci>"
" <ci> s2 </ci>"
" </apply>"
" <apply>"
" <plus/>"
" <ci> km </ci>"
" <ci> s2 </ci>"
" </apply>"
" </apply>"
" <ci> cell </ci>"
" </apply>"
"</math>";
astMath = readMathMLFromString(mathXMLString.c_str());
kl->setMath(astMath);
delete astMath;
//---------------------------------------------------------------------------
// (Reaction3) Creates a Reaction object ("v3").
//---------------------------------------------------------------------------
reaction = model->createReaction();
reaction->setId("v3");
//---------------------------------------------------------------------------
// Creates Reactant objects inside the Reaction object ("v3").
//---------------------------------------------------------------------------
// (Reactant2) Creates a Reactant object that references Species "s2"
// in the model.
spr = reaction->createReactant();
spr->setSpecies("s2");
//---------------------------------------------------------------------------
// Creates a Product object inside the Reaction object ("v3").
//---------------------------------------------------------------------------
// Creates a Product object that references Species "x1" in the model.
spr = reaction->createProduct();
spr->setSpecies("x1");
//---------------------------------------------------------------------------
// Creates a KineticLaw object inside the Reaction object ("v3").
//---------------------------------------------------------------------------
kl = reaction->createKineticLaw();
// Sets a notes (by string) to the KineticLaw object.
notesString = "<xhtml:p> ((vm * x1)/(km + x1)) * cell </xhtml:p>";
kl->setNotes(notesString);
//---------------------------------------------------------------------------
// Sets a math (ASTNode object) to the KineticLaw object.
//---------------------------------------------------------------------------
mathXMLString = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
" <apply>"
" <times/>"
" <apply>"
" <divide/>"
" <apply>"
" <times/>"
" <ci> vm </ci>"
" <ci> x1 </ci>"
" </apply>"
" <apply>"
" <plus/>"
" <ci> km </ci>"
" <ci> x1 </ci>"
" </apply>"
" </apply>"
" <ci> cell </ci>"
" </apply>"
"</math>";
astMath = readMathMLFromString(mathXMLString.c_str());
kl->setMath(astMath);
delete astMath;
// Returns the created SBMLDocument object.
// The returned object must be explicitly deleted by the caller,
// otherwise memory leak will happen.
return sbmlDoc;
}
/**
*
* Creates an SBML model represented in "7.8 Example involving function definitions"
* in the SBML Level 2 Version 4 Specification.
*
*/
SBMLDocument* createExampleInvolvingFunctionDefinitions()
{
const unsigned int level = Level;
const unsigned int version = Version;
//---------------------------------------------------------------------------
//
// Creates an SBMLDocument object
//
//---------------------------------------------------------------------------
SBMLDocument* sbmlDoc = new SBMLDocument(level,version);
//---------------------------------------------------------------------------
//
// Creates a Model object inside the SBMLDocument object.
//
//---------------------------------------------------------------------------
Model* model = sbmlDoc->createModel();
model->setId("functionExample");
//---------------------------------------------------------------------------
//
// Creates a FunctionDefinition object inside the Model object.
//
//---------------------------------------------------------------------------
FunctionDefinition* fdef = model->createFunctionDefinition();
fdef->setId("f");
// Sets a math (ASTNode object) to the FunctionDefinition object.
string mathXMLString = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
" <lambda>"
" <bvar>"
" <ci> x </ci>"
" </bvar>"
" <apply>"
" <times/>"
" <ci> x </ci>"
" <cn> 2 </cn>"
" </apply>"
" </lambda>"
"</math>";
ASTNode* astMath = readMathMLFromString(mathXMLString.c_str());
fdef->setMath(astMath);
delete astMath;
//---------------------------------------------------------------------------
//
// Creates a Compartment object inside the Model object.
//
//---------------------------------------------------------------------------
Compartment* comp;
const string compName = "compartmentOne";
// Creates a Compartment object ("compartmentOne")
comp = model->createCompartment();
comp->setId(compName);
// Sets the "size" attribute of the Compartment object.
//
// The units of this Compartment object is the default SBML
// units of volume (litre), and thus we don't have to explicitly invoke
// setUnits("litre") function to set the default units.
//
comp->setSize(1);
//---------------------------------------------------------------------------
//
// Creates Species objects inside the Model object.
//
//---------------------------------------------------------------------------
Species* sp;
//---------------------------------------------------------------------------
// (Species1) Creates a Species object ("S1")
//---------------------------------------------------------------------------
sp = model->createSpecies();
sp->setId("S1");
// Sets the "compartment" attribute of the Species object to identify the
// compartnet in which the Species object located.
sp->setCompartment(compName);
// Sets the "initialConcentration" attribute of the Species object.
//
// The units of this Species object is determined by two attributes of this
// Species object ("substanceUnits" and "hasOnlySubstanceUnits") and the
// "spatialDimension" attribute of the Compartment object ("cytosol") in which
// this species object located.
// Since the default values are used for "substanceUnits" (substance (mole))
// and "hasOnlySubstanceUnits" (false) and the value of "spatialDimension" (3)
// is greater than 0, the units of this Species object is mole/litre .
//
//---------------------------------------------------------------------------
// (Species2) Creates a Species object ("S2")
//---------------------------------------------------------------------------
sp = model->createSpecies();
sp->setId("S2");
sp->setCompartment(compName);
//---------------------------------------------------------------------------
//
// Creates a global Parameter object inside the Model object.
//
//---------------------------------------------------------------------------
Parameter* para;
// Creates a Parameter ("t")
para = model->createParameter();
para->setId("t");
para->setValue(1);
para->setUnits("second");
//---------------------------------------------------------------------------
//
// Creates Reaction objects inside the Model object.
//
//---------------------------------------------------------------------------
// Temporary pointers.
Reaction* reaction;
//---------------------------------------------------------------------------
// (Reaction1) Creates a Reaction object ("reaction_1").
//---------------------------------------------------------------------------
reaction = model->createReaction();
reaction->setId("reaction_1");
reaction->setReversible(false);
//---------------------------------------------------------------------------
// Creates Reactant objects inside the Reaction object ("reaction_1").
//---------------------------------------------------------------------------
// (Reactant1) Creates a Reactant object that references Species "S1"
// in the model.
spr = reaction->createReactant();
spr->setSpecies("S1");
//---------------------------------------------------------------------------
// Creates a Product object inside the Reaction object ("reaction_1").
//---------------------------------------------------------------------------
// Creates a Product object that references Species "S2" in the model.
spr = reaction->createProduct();
spr->setSpecies("S2");
//---------------------------------------------------------------------------
// Creates a KineticLaw object inside the Reaction object ("reaction_1").
//---------------------------------------------------------------------------
kl = reaction->createKineticLaw();
//---------------------------------------------------------------------------
// Sets a math (ASTNode object) to the KineticLaw object.
//---------------------------------------------------------------------------
mathXMLString = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
" <apply>"
" <divide/>"
" <apply>"
" <times/>"
" <apply>"
" <ci> f </ci>"
" <ci> S1 </ci>"
" </apply>"
" <ci> compartmentOne </ci>"
" </apply>"
" <ci> t </ci>"
" </apply>"
"</math>";
astMath = readMathMLFromString(mathXMLString.c_str());
kl->setMath(astMath);
delete astMath;
// Returns the created SBMLDocument object.
// The returned object must be explicitly deleted by the caller,
// otherwise memory leak will happen.
return sbmlDoc;
}
//===============================================================================
//
//
// Helper functions for writing/validating the given SBML documents.
//
//
//===============================================================================
/**
*
* Validates the given SBMLDocument.
*
* This function is based on validateSBML.cpp implemented by
* Sarah Keating, Ben Bornstein, and Michael Hucka.
*
*/
bool validateExampleSBML (SBMLDocument* sbmlDoc)
{
if (!sbmlDoc)
{
cerr << "validateExampleSBML: given a null SBML Document" << endl;
return false;
}
string consistencyMessages;
string validationMessages;
bool noProblems = true;
unsigned int numCheckFailures = 0;
unsigned int numConsistencyErrors = 0;
unsigned int numConsistencyWarnings = 0;
unsigned int numValidationErrors = 0;
unsigned int numValidationWarnings = 0;
// LibSBML 3.3 is lenient when generating models from scratch using the
// API for creating objects. Once the whole model is done and before it
// gets written out, it's important to check that the whole model is in
// fact complete, consistent and valid.
numCheckFailures = sbmlDoc->checkInternalConsistency();
if ( numCheckFailures > 0 )
{
noProblems = false;
for (unsigned int i = 0; i < numCheckFailures; i++)
{
const SBMLError* sbmlErr = sbmlDoc->getError(i);
if ( sbmlErr->isFatal() || sbmlErr->isError() )
{
++numConsistencyErrors;
}
else
{
++numConsistencyWarnings;
}
}
ostringstream oss;
sbmlDoc->printErrors(oss);
consistencyMessages = oss.str();
}
// If the internal checks fail, it makes little sense to attempt
// further validation, because the model may be too compromised to
// be properly interpreted.
if (numConsistencyErrors > 0)
{
consistencyMessages += "Further validation aborted.";
}
else
{
numCheckFailures = sbmlDoc->checkConsistency();
if ( numCheckFailures > 0 )
{
noProblems = false;
for (unsigned int i = 0; i < numCheckFailures; i++)
{
const SBMLError* sbmlErr = sbmlDoc->getError(i);
if ( sbmlErr->isFatal() || sbmlErr->isError() )
{
++numValidationErrors;
}
else
{
++numValidationWarnings;
}
}
ostringstream oss;
sbmlDoc->printErrors(oss);
validationMessages = oss.str();
}
}
if (noProblems)
return true;
else
{
if (numConsistencyErrors > 0)
{
cout << "ERROR: encountered " << numConsistencyErrors
<< " consistency error" << (numConsistencyErrors == 1 ? "" : "s")
<< " in model '" << sbmlDoc->getModel()->getId() << "'." << endl;
}
if (numConsistencyWarnings > 0)
{
cout << "Notice: encountered " << numConsistencyWarnings
<< " consistency warning" << (numConsistencyWarnings == 1 ? "" : "s")
<< " in model '" << sbmlDoc->getModel()->getId() << "'." << endl;
}
cout << endl << consistencyMessages;
if (numValidationErrors > 0)
{
cout << "ERROR: encountered " << numValidationErrors
<< " validation error" << (numValidationErrors == 1 ? "" : "s")
<< " in model '" << sbmlDoc->getModel()->getId() << "'." << endl;
}
if (numValidationWarnings > 0)
{
cout << "Notice: encountered " << numValidationWarnings
<< " validation warning" << (numValidationWarnings == 1 ? "" : "s")
<< " in model '" << sbmlDoc->getModel()->getId() << "'." << endl;
}
cout << endl << validationMessages;
return (numConsistencyErrors == 0 && numValidationErrors == 0);
}
}
/**
*
* Writes the given SBMLDocument to the given file.
*
*/
bool writeExampleSBML(const SBMLDocument* sbmlDoc, const string& filename)
{
SBMLWriter sbmlWriter;
bool result = sbmlWriter.writeSBML(sbmlDoc, filename);
if (result)
{
cout << "Wrote file \"" << filename << "\"" << endl;
return true;
}
else
{
cerr << "Failed to write \"" << filename << "\"" << endl;
return false;
}
}
@ AST_MINUS
Definition ASTNodeType.h:85
@ AST_DIVIDE
Definition ASTNodeType.h:87
@ AST_TIMES
Definition ASTNodeType.h:86
@ AST_NAME
Definition ASTNodeType.h:95
@ AST_PLUS
Definition ASTNodeType.h:84
ASTNode_t * readMathMLFromString(const char *xml)
Definition MathML.cpp:2273
Include all SBML types in a single header file.
@ UNIT_KIND_LITRE
Definition UnitKind.h:80
@ UNIT_KIND_MOLE
Definition UnitKind.h:85
@ UNIT_KIND_SECOND
Definition UnitKind.h:90
Definition ASTNode.h:221
ASTNode * getLeftChild() const
Returns the left child of this node.
Definition ASTNode.cpp:1031
int setName(const char *name)
Sets the value of this ASTNode to the given name.
Definition ASTNode.cpp:2088
ASTNode * getRightChild() const
Returns the right child of this node.
Definition ASTNode.cpp:1045
int addChild(ASTNode *disownedChild, bool inRead=false)
Adds the given node as a child of this ASTNode.
Definition ASTNode.cpp:846
Definition Compartment.h:490
virtual int setId(const std::string &sid)
Sets the value of the "id" attribute of this Compartment object.
Definition Compartment.cpp:479
int setSize(double value)
Sets the "size" attribute (or "volume" in SBML Level&#160;1) of this Compartment object.
Definition Compartment.cpp:603
Definition FunctionDefinition.h:150
virtual int setMath(const ASTNode *math)
Sets the "math" subelement of this FunctionDefinition to the Abstract Syntax Tree given in math.
Definition FunctionDefinition.cpp:272
virtual int setId(const std::string &sid)
Sets the value of the "id" attribute of this FunctionDefinition.
Definition FunctionDefinition.cpp:225
Definition KineticLaw.h:203
virtual int setMath(const ASTNode *math)
Sets the mathematical expression of this KineticLaw instance to a copy of the given ASTNode.
Definition KineticLaw.cpp:392
Parameter * createParameter()
Creates a new Parameter object, adds it to this KineticLaw's list of parameters, and returns the Para...
Definition KineticLaw.cpp:613
Definition Parameter.h:202
int setUnits(const std::string &units)
Sets the "units" attribute of this Parameter to a copy of the given units identifier units.
Definition Parameter.cpp:394
int setValue(double value)
Sets the "value" attribute of this Parameter to the given double value and marks the attribute as set...
Definition Parameter.cpp:382
virtual int setId(const std::string &sid)
Sets the value of the "id" attribute of this Parameter.
Definition Parameter.cpp:335
Definition Reaction.h:224
SpeciesReference * createReactant()
Creates a new SpeciesReference, adds it to this Reaction's list of reactants, and returns it.
Definition Reaction.cpp:954
int setReversible(bool value)
Sets the value of the "reversible" attribute of this Reaction.
Definition Reaction.cpp:599
virtual int setId(const std::string &sid)
Sets the value of the "id" attribute of this Reaction.
Definition Reaction.cpp:517
SpeciesReference * createProduct()
Creates a new SpeciesReference, adds it to this Reaction's list of products, and returns it.
Definition Reaction.cpp:983
KineticLaw * createKineticLaw()
Creates a new KineticLaw object, installs it as this Reaction's "kineticLaw" subelement,...
Definition Reaction.cpp:1041
Definition SBMLDocument.h:351
Model * createModel(const std::string sid="")
Creates a new Model inside this SBMLDocument, and returns a pointer to it.
Definition SBMLDocument.cpp:627
unsigned int checkConsistency()
Performs consistency checking and validation on this SBML document.
Definition SBMLDocument.cpp:699
virtual XMLNamespaces * getNamespaces() const
Returns a list of XML Namespaces associated with the XML content of this SBML document.
Definition SBMLDocument.cpp:1334
const SBMLError * getError(unsigned int n) const
Returns the nth error or warning encountered during parsing, consistency checking,...
Definition SBMLDocument.cpp:1152
void printErrors(std::ostream &stream=std::cerr) const
Prints all the errors or warnings encountered trying to parse, check, or translate this SBML document...
Definition SBMLDocument.cpp:1192
unsigned int checkInternalConsistency()
Performs consistency checking on libSBML's internal representation of an SBML Model.
Definition SBMLDocument.cpp:870
const Model * getModel() const
Returns the Model object stored in this SBMLDocument.
Definition SBMLDocument.cpp:350
Definition SBMLError.h:1100
Definition SBMLWriter.h:115
bool writeSBML(const SBMLDocument *d, const std::string &filename)
Writes the given SBML document to filename.
Definition SBMLWriter.cpp:140
int setNotes(const XMLNode *notes)
Sets the value of the "notes" subelement of this SBML object.
Definition SBase.cpp:1786
int setSpecies(const std::string &sid)
Sets the "species" attribute of this SimpleSpeciesReference.
Definition SimpleSpeciesReference.cpp:196
Definition Species.h:429
int setCompartment(const std::string &sid)
Sets the "compartment" attribute of this Species object.
Definition Species.cpp:661
int setInitialConcentration(double value)
Sets the "initialConcentration" attribute of this Species and marks the field as set.
Definition Species.cpp:695
int setInitialAmount(double value)
Sets the "initialAmount" attribute of this Species and marks the field as set.
Definition Species.cpp:680
virtual int setName(const std::string &name)
Sets the value of the "name" attribute of this Species.
Definition Species.cpp:609
virtual int setId(const std::string &sid)
Sets the value of the "id" attribute of this Species.
Definition Species.cpp:591
Definition SpeciesReference.h:281
Definition UnitDefinition.h:282
virtual int setId(const std::string &sid)
Sets the value of the "id" attribute of this UnitDefinition.
Definition UnitDefinition.cpp:237
Unit * createUnit()
Creates a new and empty Unit, adds it to this UnitDefinition's list of units, and returns it.
Definition UnitDefinition.cpp:682
Definition Unit.h:231
int setKind(UnitKind_t kind)
Sets the "kind" attribute value of this Unit.
Definition Unit.cpp:755
int setExponent(int value)
Sets the "exponent" attribute value of this Unit.
Definition Unit.cpp:774
int setScale(int value)
Sets the "scale" attribute value of this Unit.
Definition Unit.cpp:817
Definition XMLAttributes.h:257
bool isError() const
Predicate returning true or false depending on whether this error is a significant error.
Definition XMLError.cpp:661
bool isFatal() const
Predicate returning true or false depending on whether this error is a fatal run-time error.
Definition XMLError.cpp:671
int add(const std::string &uri, const std::string prefix="")
Appends an XML namespace prefix and URI pair to this list of namespace declarations.
Definition XMLNamespaces.cpp:119
Definition XMLNode.h:178
Definition XMLTriple.h:94