END_TEST START_TEST (test_WriteL3SBML_UnitDefinition) { const char* expected = "<unitDefinition id=\"myUnit\">\n" " <listOfUnits>\n" " <unit kind=\"mole\" exponent=\"1\" scale=\"0\" multiplier=\"1.8\"/>\n" " </listOfUnits>\n" "</unitDefinition>"; UnitDefinition* ud = D->createModel()->createUnitDefinition(); ud->setId("myUnit"); Unit* u1 = ud->createUnit(); u1->setKind(UnitKind_forName("mole")); u1->setMultiplier(1.8); u1->setScale(0); u1->setExponent(1); char* sbml = ud->toSBML(); fail_unless( equals(expected, sbml) ); safe_free(sbml); }
/* * Eliminate all dimensionless units from the given UnitDefinition. * A new UnitDefinition without the dimensionless units is returned. * The scale and multiplier are preserved. If the UnitDefinition has only * one unit the is a dimensionless, it is not deleted. * @param UnitDefinition* pUdef * @return UnitDefinition* result */ LIBSBML_EXTERN UnitDefinition* UnitConversionFactory::eliminateDimensionless(UnitDefinition* pUdef) { unsigned int maxUnits = pUdef->getNumUnits(); UnitDefinition* pTmpUdef = NULL; Unit* pU = NULL; if (maxUnits > 1) { int scale = 0; double multiplier = 1.0; unsigned int i = 0; pTmpUdef = new UnitDefinition(UnitConversionFactory::SBML_LEVEL, UnitConversionFactory::SBML_VERSION); while (i < maxUnits) { pU = new Unit(*(pUdef->getUnit(i))); if (pU->getKind() != UNIT_KIND_DIMENSIONLESS) { pTmpUdef->addUnit(pU); } else { // conserve scale and multiplier scale = scale + pU->getScale(); multiplier = multiplier * pU->getMultiplier(); } delete pU; ++i; } i = pTmpUdef->getNumUnits(); if (i > 0 && i < maxUnits) { pTmpUdef->setName(pUdef->getName()); pTmpUdef->setId(pUdef->getId()); pU = pTmpUdef->getUnit(0); pU->setScale(pU->getScale() + scale); pU->setMultiplier(pU->getMultiplier()*multiplier); } else { delete pTmpUdef; pTmpUdef = NULL; } } return pTmpUdef; }
END_TEST START_TEST ( test_UnitDefinition ) { UnitDefinition* ud = new UnitDefinition(2, 4); fail_unless (!(ud->hasRequiredAttributes())); ud->setId("ud"); fail_unless (ud->hasRequiredAttributes()); delete ud; }
END_TEST START_TEST ( test_UnitDefinition_parent_add ) { UnitDefinition *ia = new UnitDefinition(2, 4); Model *m = new Model(2, 4); ia->setId("u"); ia->createUnit(); m->addUnitDefinition(ia); delete ia; ListOf *lo = m->getListOfUnitDefinitions(); fail_unless(lo == m->getUnitDefinition(0)->getParentSBMLObject()); fail_unless(m == lo->getParentSBMLObject()); }
/** * * 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->setKind(UNIT_KIND_MOLE); 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->setKind(UNIT_KIND_MOLE); unit->setScale(-3); // Creates an Unit inside the UnitDefinition object ("mmls") unit = unitdef->createUnit(); unit->setKind(UNIT_KIND_LITRE); unit->setExponent(-1); // Creates an Unit inside the UnitDefinition object ("mmls") unit = unitdef->createUnit(); unit->setKind(UNIT_KIND_SECOND); 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->setKind(UNIT_KIND_MOLE); unit->setScale(-3); // Creates an Unit inside the UnitDefinition object ("mml") unit = unitdef->createUnit(); unit->setKind(UNIT_KIND_LITRE); 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 . // sp->setInitialConcentration(1); //--------------------------------------------------------------------------- // (Species2) Creates a Species object ("x1") //--------------------------------------------------------------------------- sp = model->createSpecies(); sp->setId("x1"); sp->setCompartment(compName); sp->setInitialConcentration(1); //--------------------------------------------------------------------------- // (Species3) Creates a Species object ("s1") //--------------------------------------------------------------------------- sp = model->createSpecies(); sp->setCompartment(compName); sp->setId("s1"); sp->setInitialConcentration(1); //--------------------------------------------------------------------------- // (Species4) Creates a Species object ("s2") //--------------------------------------------------------------------------- sp = model->createSpecies(); sp->setCompartment(compName); sp->setId("s2"); sp->setInitialConcentration(1); //--------------------------------------------------------------------------- // // 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; SpeciesReference* spr; KineticLaw* kl; //--------------------------------------------------------------------------- // (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(¬esXMLNode); //--------------------------------------------------------------------------- // 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.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->setKind(UNIT_KIND_SECOND); 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->setKind(UNIT_KIND_MOLE); unit->setExponent(-1); // Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second") unit = unitdef->createUnit(); unit->setKind(UNIT_KIND_LITRE); unit->setExponent(1); // Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second") unit = unitdef->createUnit(); unit->setKind(UNIT_KIND_SECOND); 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. // sp->setInitialAmount(0); //--------------------------------------------------------------------------- // (Species2) Creates a Species object ("P") //--------------------------------------------------------------------------- sp = model->createSpecies(); sp->setCompartment(compName); sp->setId("P"); sp->setName("P"); sp->setInitialAmount(0); //--------------------------------------------------------------------------- // (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; SpeciesReference* spr; KineticLaw* kl; //--------------------------------------------------------------------------- // (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; }
/* in L1 and L2 there were built in values for key units * such as 'volume', 'length', 'area', 'substance' and 'time' * In L3 these have been removed - thus if a model uses one of these * it needs a unitDefinition to define it */ void Model::addDefinitionsForDefaultUnits() { /* create a list of unit values */ IdList unitsUsed; unsigned int n; bool implicitVolume = false; bool implicitArea = false; bool implicitLength = false; bool implicitSubstance = false; for (n = 0; n < getNumCompartments(); n++) { if (getCompartment(n)->isSetUnits()) { unitsUsed.append(getCompartment(n)->getUnits()); } else { if (getCompartment(n)->getSpatialDimensions() == 3) { implicitVolume = true; getCompartment(n)->setUnits("volume"); } else if (getCompartment(n)->getSpatialDimensions() == 2) { implicitArea = true; getCompartment(n)->setUnits("area"); } else if (getCompartment(n)->getSpatialDimensions() == 1) { implicitLength = true; getCompartment(n)->setUnits("length"); } } } for (n = 0; n < getNumSpecies(); n++) { if (getSpecies(n)->isSetSubstanceUnits()) { unitsUsed.append(getSpecies(n)->getSubstanceUnits()); } else { implicitSubstance = true; getSpecies(n)->setSubstanceUnits("substance"); } if (getSpecies(n)->isSetSpatialSizeUnits()) unitsUsed.append(getSpecies(n)->getSpatialSizeUnits()); } for (n = 0; n < getNumParameters(); n++) { if (getParameter(n)->isSetUnits()) unitsUsed.append(getParameter(n)->getUnits()); } if (getUnitDefinition("volume") == NULL) { if (unitsUsed.contains("volume") || implicitVolume) { UnitDefinition * ud = createUnitDefinition(); ud->setId("volume"); Unit * u = ud->createUnit(); u->setKind(UnitKind_forName("litre")); u->setScale(0); u->setExponent(1.0); u->setMultiplier(1.0); setVolumeUnits("volume"); } else { setVolumeUnits("litre"); } } else { setVolumeUnits("volume"); } if (getUnitDefinition("substance") == NULL) { if (unitsUsed.contains("substance") || implicitSubstance) { UnitDefinition * ud = createUnitDefinition(); ud->setId("substance"); Unit * u = ud->createUnit(); u->setKind(UnitKind_forName("mole")); u->setScale(0); u->setExponent(1.0); u->setMultiplier(1.0); setSubstanceUnits("substance"); setExtentUnits("substance"); } else { setSubstanceUnits("mole"); setExtentUnits("mole"); } } else { setSubstanceUnits("substance"); setExtentUnits("substance"); } if (getUnitDefinition("area") == NULL) { UnitDefinition * ud = createUnitDefinition(); ud->setId("area"); Unit * u = ud->createUnit(); u->setKind(UnitKind_forName("metre")); u->setScale(0); u->setExponent(2.0); u->setMultiplier(1.0); setAreaUnits("area"); } else { setAreaUnits("area"); } if (getUnitDefinition("length") == NULL) { if (unitsUsed.contains("length") || implicitLength) { UnitDefinition * ud = createUnitDefinition(); ud->setId("length"); Unit * u = ud->createUnit(); u->setKind(UnitKind_forName("metre")); u->setScale(0); u->setExponent(1.0); u->setMultiplier(1.0); setLengthUnits("length"); } else { setLengthUnits("metre"); } } else { setLengthUnits("length"); } if (getUnitDefinition("time") == NULL) { setTimeUnits("second"); } else { setTimeUnits("time"); } }
void Model::dealWithModelUnits() { UnitRefsFilter filter; List * elements = getAllElements(&filter); unsigned int n = 0; unsigned int num = elements->getSize(); if (isSetVolumeUnits()) { std::string volume = getVolumeUnits(); // if in an L3 model a user used volume as an id of a UnitDefinition // but they declared the volume units of teh model to be something // else then the UD with id volume is nothing to do with the // L2 interpretation of volume // so replace that UD and all references to it if (volume != "volume") { UnitDefinition * existingUD = removeUnitDefinition("volume"); if (existingUD != NULL) { std::string newSubsName = "volumeFromOriginal"; existingUD->setId(newSubsName); SBase* obj; for (n = 0; n < num; n++) { obj = (SBase*)(elements->get(n)); obj->renameUnitSIdRefs("volume", newSubsName); } addUnitDefinition(existingUD); } } UnitDefinition * ud = getUnitDefinition(volume) != NULL ? getUnitDefinition(volume)->clone() : NULL; if (ud != NULL) { ud->setId("volume"); } else { Unit *u = new Unit(getSBMLNamespaces()); u->initDefaults(); u->setKind(UnitKind_forName(volume.c_str())); ud = new UnitDefinition(getSBMLNamespaces()); ud->setId("volume"); ud->addUnit(u); } addUnitDefinition(ud); } if (isSetAreaUnits()) { std::string area = getAreaUnits(); // if in an L3 model a user used area as an id of a UnitDefinition // but they declared the area units of teh model to be something // else then the UD with id area is nothing to do with the // L2 interpretation of area // so replace that UD and all references to it if (area != "area") { UnitDefinition * existingUD = removeUnitDefinition("area"); if (existingUD != NULL) { std::string newSubsName = "areaFromOriginal"; existingUD->setId(newSubsName); SBase* obj; for (n = 0; n < num; n++) { obj = (SBase*)(elements->get(n)); obj->renameUnitSIdRefs("area", newSubsName); } addUnitDefinition(existingUD); } } UnitDefinition * ud = getUnitDefinition(area) != NULL ? getUnitDefinition(area)->clone() : NULL; if (ud != NULL) { ud->setId("area"); } else { Unit *u = new Unit(getSBMLNamespaces()); u->initDefaults(); u->setKind(UnitKind_forName(area.c_str())); ud = new UnitDefinition(getSBMLNamespaces()); ud->setId("area"); ud->addUnit(u); } addUnitDefinition(ud); } if (isSetLengthUnits()) { std::string length = getLengthUnits(); // if in an L3 model a user used length as an id of a UnitDefinition // but they declared the length units of teh model to be something // else then the UD with id length is nothing to do with the // L2 interpretation of length // so replace that UD and all references to it if (length != "length") { UnitDefinition * existingUD = removeUnitDefinition("length"); if (existingUD != NULL) { std::string newSubsName = "lengthFromOriginal"; existingUD->setId(newSubsName); SBase* obj; for (n = 0; n < num; n++) { obj = (SBase*)(elements->get(n)); obj->renameUnitSIdRefs("length", newSubsName); } addUnitDefinition(existingUD); } } UnitDefinition * ud = getUnitDefinition(length) != NULL ? getUnitDefinition(length)->clone() : NULL; if (ud != NULL) { ud->setId("length"); } else { Unit *u = new Unit(getSBMLNamespaces()); u->initDefaults(); u->setKind(UnitKind_forName(length.c_str())); ud = new UnitDefinition(getSBMLNamespaces()); ud->setId("length"); ud->addUnit(u); } addUnitDefinition(ud); } if (isSetSubstanceUnits()) { std::string substance = getSubstanceUnits(); // if in an L3 model a user used substance as an id of a UnitDefinition // but they declared the substance units of teh model to be something // else then the UD with id substance is nothing to do with the // L2 interpretation of substance // so replace that UD and all references to it if (substance != "substance") { UnitDefinition * existingUD = removeUnitDefinition("substance"); if (existingUD != NULL) { std::string newSubsName = "substanceFromOriginal"; existingUD->setId(newSubsName); SBase* obj; for (n = 0; n < num; n++) { obj = (SBase*)(elements->get(n)); obj->renameUnitSIdRefs("substance", newSubsName); } addUnitDefinition(existingUD); } } UnitDefinition * ud = getUnitDefinition(substance) != NULL ? getUnitDefinition(substance)->clone() : NULL; if (ud != NULL) { ud->setId("substance"); } else { Unit *u = new Unit(getSBMLNamespaces()); u->initDefaults(); u->setKind(UnitKind_forName(substance.c_str())); ud = new UnitDefinition(getSBMLNamespaces()); ud->setId("substance"); ud->addUnit(u); } addUnitDefinition(ud); } if (isSetTimeUnits()) { std::string time = getTimeUnits(); // if in an L3 model a user used time as an id of a UnitDefinition // but they declared the time units of teh model to be something // else then the UD with id time is nothing to do with the // L2 interpretation of time // so replace that UD and all references to it if (time != "time") { UnitDefinition * existingUD = removeUnitDefinition("time"); if (existingUD != NULL) { std::string newSubsName = "timeFromOriginal"; existingUD->setId(newSubsName); SBase* obj; for (n = 0; n < num; n++) { obj = (SBase*)(elements->get(n)); obj->renameUnitSIdRefs("time", newSubsName); } addUnitDefinition(existingUD); } } UnitDefinition * ud = getUnitDefinition(time) != NULL ? getUnitDefinition(time)->clone() : NULL; if (ud != NULL) { ud->setId("time"); } else { ud = new UnitDefinition(getSBMLNamespaces()); ud->setId("time"); Unit *u = ud->createUnit(); u->initDefaults(); u->setKind(UnitKind_forName(time.c_str())); } addUnitDefinition(ud); } }
/* * Converts a Unit into the corresponding UnitDefinition that consists * only of SI units. * Possible offsets are ignored. * Freeing the memory for the returned UnitDefinition is up to the * receiver. * On failure a NULL pointer is returned. * @param const Unit& unit * @return UnitDefinition* result */ LIBSBML_EXTERN UnitDefinition* UnitConversionFactory::convertToSI(const Unit& unit) { UnitDefinition* pUdef = NULL; Unit* pU = NULL; if (!unit.isSetKind()) return pUdef; UnitKind_t uKind = unit.getKind(); switch (uKind) { case UNIT_KIND_AMPERE: pUdef = convertAmpereToSI(unit); break; case UNIT_KIND_BECQUEREL: case UNIT_KIND_HERTZ: pUdef = convertFrequencyToSI(unit); break; case UNIT_KIND_CANDELA: pUdef = convertCandelaToSI(unit); break; case UNIT_KIND_CELSIUS: pUdef = convertCelsiusToSI(unit); break; case UNIT_KIND_COULOMB: pUdef = convertCoulombToSI(unit); break; case UNIT_KIND_DIMENSIONLESS: case UNIT_KIND_ITEM: case UNIT_KIND_RADIAN: case UNIT_KIND_STERADIAN: pUdef = convertDimensionlessToSI(unit); break; case UNIT_KIND_FARAD: pUdef = convertFaradToSI(unit); break; case UNIT_KIND_GRAM: pU = new Unit(unit); pU->setScale(pU->getScale() - 3); pU->setKind(UNIT_KIND_KILOGRAM); pUdef = convertKilogramToSI(*pU); delete pU; break; case UNIT_KIND_GRAY: case UNIT_KIND_SIEVERT: pUdef = convertDoseToSI(unit); break; case UNIT_KIND_HENRY: pUdef = convertHenryToSI(unit); break; case UNIT_KIND_JOULE: pUdef = convertJouleToSI(unit); break; case UNIT_KIND_KATAL: pUdef = convertKatalToSI(unit); break; case UNIT_KIND_KELVIN: pUdef = convertKelvinToSI(unit); break; case UNIT_KIND_KILOGRAM: pUdef = convertKilogramToSI(unit); break; case UNIT_KIND_LITER: case UNIT_KIND_LITRE: pU = new Unit(unit); pU->setKind(UNIT_KIND_METER); pU->setExponent(pU->getExponent()*3); pU->setScale(pU->getScale() - 3); pUdef = convertMeterToSI(*pU); delete pU; break; case UNIT_KIND_LUMEN: pUdef = convertLumenToSI(unit); break; case UNIT_KIND_LUX: pUdef = convertLuxToSI(unit); break; case UNIT_KIND_METER: case UNIT_KIND_METRE: pUdef = convertMeterToSI(unit); break; case UNIT_KIND_MOLE: #if LIBSBML_VERSION >= 40100 // this may be not totally correct, but this is the way we currently intend to // handle it in COPASI case UNIT_KIND_AVOGADRO: #endif // LIBSBML_VERSION pUdef = convertMoleToSI(unit); break; case UNIT_KIND_NEWTON: pUdef = convertNewtonToSI(unit); break; case UNIT_KIND_OHM: pUdef = convertOhmToSI(unit); break; case UNIT_KIND_PASCAL: pUdef = convertPascalToSI(unit); break; case UNIT_KIND_SECOND: pUdef = convertSecondToSI(unit); break; case UNIT_KIND_SIEMENS: pUdef = convertSiemensToSI(unit); break; case UNIT_KIND_TESLA: pUdef = convertTeslaToSI(unit); break; case UNIT_KIND_VOLT: pUdef = convertVoltToSI(unit); break; case UNIT_KIND_WATT: pUdef = convertWattToSI(unit); break; case UNIT_KIND_WEBER: pUdef = convertWeberToSI(unit); break; case UNIT_KIND_INVALID: delete pUdef; pUdef = NULL; break; } if (pUdef != NULL) { unsigned int num = 1; std::stringstream ss; ss << "UnitDefinition_" << num; while (!UnitConversionFactory::isIdUnused(ss.str())) { ++num; ss.str(""); ss << "UnitDefinition_" << num; } std::string id = ss.str(); usedIds.push_back(id); pUdef->setId(id); UnitKind_t uKind = unit.getKind(); pUdef->setName(UnitKind_toString(uKind)); } return pUdef; }
void Model::dealWithModelUnits() { if (isSetVolumeUnits()) { std::string volume = getVolumeUnits(); UnitDefinition * ud = removeUnitDefinition(volume); if (ud != NULL) { ud->setId("volume"); } else { Unit *u = new Unit(getSBMLNamespaces()); u->initDefaults(); u->setKind(UnitKind_forName(volume.c_str())); ud = new UnitDefinition(getSBMLNamespaces()); ud->setId("volume"); ud->addUnit(u); } addUnitDefinition(ud); } if (isSetAreaUnits()) { std::string area = getAreaUnits(); UnitDefinition * ud = removeUnitDefinition(area); if (ud != NULL) { ud->setId("area"); } else { Unit *u = new Unit(getSBMLNamespaces()); u->initDefaults(); u->setKind(UnitKind_forName(area.c_str())); ud = new UnitDefinition(getSBMLNamespaces()); ud->setId("area"); ud->addUnit(u); } addUnitDefinition(ud); } if (isSetLengthUnits()) { std::string length = getLengthUnits(); UnitDefinition * ud = removeUnitDefinition(length); if (ud != NULL) { ud->setId("length"); } else { Unit *u = new Unit(getSBMLNamespaces()); u->initDefaults(); u->setKind(UnitKind_forName(length.c_str())); ud = new UnitDefinition(getSBMLNamespaces()); ud->setId("length"); ud->addUnit(u); } addUnitDefinition(ud); } if (isSetSubstanceUnits()) { std::string substance = getSubstanceUnits(); UnitDefinition * ud = removeUnitDefinition(substance); if (ud != NULL) { ud->setId("substance"); } else { Unit *u = new Unit(getSBMLNamespaces()); u->initDefaults(); u->setKind(UnitKind_forName(substance.c_str())); ud = new UnitDefinition(getSBMLNamespaces()); ud->setId("substance"); ud->addUnit(u); } addUnitDefinition(ud); } if (isSetTimeUnits()) { std::string time = getTimeUnits(); UnitDefinition * ud = removeUnitDefinition(time); if (ud != NULL) { ud->setId("time"); } else { ud = new UnitDefinition(getSBMLNamespaces()); ud->setId("time"); Unit *u = ud->createUnit(); u->initDefaults(); u->setKind(UnitKind_forName(time.c_str())); } addUnitDefinition(ud); } }