END_TEST START_TEST (test_MathMLFromAST_scalarproduct) { const char* expected = wrapMathML ( " <apply>\n" " <scalarproduct/>\n" " <ci> y </ci>\n" " <ci> z </ci>\n" " </apply>\n" ); ASTNode * y = new ASTNode(AST_NAME); fail_unless(y->setName("y") == LIBSBML_OPERATION_SUCCESS); ASTNode * z = new ASTNode(AST_NAME); fail_unless(z->setName("z") == LIBSBML_OPERATION_SUCCESS); N = new ASTNode(AST_LINEAR_ALGEBRA_SCALAR_PRODUCT); fail_unless( N->getPackageName() == "arrays"); fail_unless(N->addChild(y) == LIBSBML_OPERATION_SUCCESS); fail_unless(N->addChild(z) == LIBSBML_OPERATION_SUCCESS); S = writeMathMLToString(N); fail_unless( equals(expected, S) ); }
END_TEST START_TEST (test_MathMLFromAST_plus_nary_4) { const char* expected = wrapMathML ( " <apply>\n" " <plus/>\n" " <cn type=\"integer\"> 1 </cn>\n" " <cn type=\"integer\"> 2 </cn>\n" " <apply>\n" " <times/>\n" " <ci> x </ci>\n" " <ci> y </ci>\n" " <ci> z </ci>\n" " </apply>\n" " <cn type=\"integer\"> 3 </cn>\n" " </apply>\n" ); // N = SBML_parseFormula("1 + 2 + x * y * z + 3"); N = new ASTNode(AST_PLUS); ASTNode *c1 = new ASTNode(AST_INTEGER); c1->setValue(1); ASTNode *c2 = new ASTNode(AST_INTEGER); c2->setValue(2); ASTNode *c3 = new ASTNode(AST_INTEGER); c3->setValue(3); ASTNode *cx = new ASTNode(AST_NAME); cx->setName("x"); ASTNode *cy = new ASTNode(AST_NAME); cy->setName("y"); ASTNode *cz = new ASTNode(AST_NAME); cz->setName("z"); ASTNode *times = new ASTNode(AST_TIMES); times->addChild(cx); times->addChild(cy); times->addChild(cz); N->addChild(c1); N->addChild(c2); N->addChild(times); N->addChild(c3); S = writeMathMLToString(N); fail_unless( equals(expected, S) ); }
ASTNode* CEvaluationNodeVariable::toAST(const CCopasiDataModel* /*pDataModel*/) const { ASTNode* node = new ASTNode(); node->setType(AST_NAME); node->setName(this->getData().c_str()); return node; }
END_TEST START_TEST (test_getUnitDefinition_power_one_child) { ASTNode * node = new ASTNode(AST_POWER); ASTNode * c = new ASTNode(AST_NAME); c->setName("k"); node->addChild(c); UnitDefinition * ud = NULL; ud = uff->getUnitDefinition(node); fail_unless(uff->getContainsUndeclaredUnits() == true); fail_unless(uff->canIgnoreUndeclaredUnits() == false); fail_unless(ud != NULL); fail_unless(ud->getNumUnits() == 1); fail_unless(ud->getUnit(0)->getKind() == UNIT_KIND_METRE); fail_unless(util_isEqual(ud->getUnit(0)->getExponent(), 1)); delete node; delete ud; }
END_TEST START_TEST (test_MathMLFromAST_transpose) { const char* expected = wrapMathML ( " <apply>\n" " <transpose/>\n" " <ci> y </ci>\n" " </apply>\n" ); ASTNode * y = new ASTNode(AST_NAME); fail_unless(y->setName("y") == LIBSBML_OPERATION_SUCCESS); N = new ASTNode(AST_LINEAR_ALGEBRA_TRANSPOSE); fail_unless( N->getPackageName() == "arrays"); fail_unless(N->addChild(y) == LIBSBML_OPERATION_SUCCESS); S = writeMathMLToString(N); fail_unless( equals(expected, S) ); }
/** * Sets the type of an ASTNode based on the given MathML <ci> element. * Errors will be logged in the stream's SBMLErrorLog object. */ static void setTypeCI (ASTNode& node, const XMLToken& element, XMLInputStream& stream) { if (element.getName() == "csymbol") { string url; element.getAttributes().readInto("definitionURL", url); if ( url == URL_DELAY ) node.setType(AST_FUNCTION_DELAY); else if ( url == URL_TIME ) node.setType(AST_NAME_TIME); else if ( url == URL_AVOGADRO ) node.setType(AST_NAME_AVOGADRO); else { static_cast <SBMLErrorLog*> (stream.getErrorLog())->logError(BadCsymbolDefinitionURLValue, stream.getSBMLNamespaces()->getLevel(), stream.getSBMLNamespaces()->getVersion()); } } else if (element.getName() == "ci") { node.setDefinitionURL(element.getAttributes()); } const string name = trim( stream.next().getCharacters() ); node.setName( name.c_str() ); }
END_TEST #endif START_TEST (test_getUnitDefinition_power_dim_param_exponent) { ASTNode * node = new ASTNode(AST_POWER); ASTNode * c = new ASTNode(AST_NAME); c->setName("k"); ASTNode * c1 = new ASTNode(AST_NAME); c1->setName("a"); node->addChild(c); node->addChild(c1); UnitDefinition * ud = NULL; ud = uff->getUnitDefinition(node); fail_unless(uff->getContainsUndeclaredUnits() == false); fail_unless(uff->canIgnoreUndeclaredUnits() == false); fail_unless(ud != NULL); fail_unless(ud->getNumUnits() == 1); fail_unless(ud->getUnit(0)->getKind() == UNIT_KIND_METRE); fail_unless(util_isEqual(ud->getUnit(0)->getExponentAsDouble(), 3.5)); delete node; delete ud; }
END_TEST #if (0) START_TEST (test_getUnitDefinition_power_minus_double_exponent) { ASTNode * node = new ASTNode(AST_POWER); ASTNode * c = new ASTNode(AST_NAME); c->setName("k"); ASTNode * c1 = new ASTNode(AST_REAL); c1->setValue(0.3); ASTNode * c2 = new ASTNode(AST_MINUS); c2->addChild(c1); node->addChild(c); node->addChild(c2); UnitDefinition * ud = NULL; ud = uff->getUnitDefinition(node); fail_unless(uff->getContainsUndeclaredUnits() == false); fail_unless(uff->canIgnoreUndeclaredUnits() == false); fail_unless(ud != NULL); fail_unless(ud->getNumUnits() == 1); fail_unless(ud->getUnit(0)->getKind() == UNIT_KIND_METRE); fail_unless(util_isEqual(ud->getUnit(0)->getExponentAsDouble(), -0.3)); delete node; delete ud; }
END_TEST START_TEST (test_getUnitDefinition_power_three_children) { ASTNode * node = new ASTNode(AST_POWER); ASTNode * c = new ASTNode(AST_NAME); c->setName("k"); ASTNode * c1 = new ASTNode(AST_INTEGER); c1->setValue(1); ASTNode * c2 = new ASTNode(AST_INTEGER); c2->setValue(2); node->addChild(c); node->addChild(c1); node->addChild(c2); UnitDefinition * ud = NULL; ud = uff->getUnitDefinition(node); fail_unless(uff->getContainsUndeclaredUnits() == true); fail_unless(uff->canIgnoreUndeclaredUnits() == false); fail_unless(ud != NULL); fail_unless(ud->getNumUnits() == 0); delete node; delete ud; }
END_TEST START_TEST (test_MathMLFromAST_function_2) { const char* expected = wrapMathML ( " <apply>\n" " <ci> foo </ci>\n" " <cn type=\"integer\"> 1 </cn>\n" " <cn type=\"integer\"> 2 </cn>\n" " <apply>\n" " <ci> bar </ci>\n" " <ci> z </ci>\n" " </apply>\n" " </apply>\n" ); // N = SBML_parseFormula("foo(1, 2, bar(z))"); N = new ASTNode(AST_FUNCTION); fail_unless( N->setName("foo") == LIBSBML_OPERATION_SUCCESS); ASTNode *c1 = new ASTNode(AST_INTEGER); c1->setValue(long(1)); ASTNode *c2 = new ASTNode(AST_INTEGER); c2->setValue(long(2)); ASTNode *bar = new ASTNode(AST_FUNCTION); bar->setName("bar"); ASTNode *cz = new ASTNode(AST_NAME); cz->setName("z"); fail_unless (bar->addChild(cz) == LIBSBML_OPERATION_SUCCESS); fail_unless (N->addChild(c1) == LIBSBML_OPERATION_SUCCESS); fail_unless (N->addChild(c2) == LIBSBML_OPERATION_SUCCESS); fail_unless (N->addChild(bar) == LIBSBML_OPERATION_SUCCESS); S = writeMathMLToString(N); fail_unless( equals(expected, S) ); }
END_TEST START_TEST (test_MathMLFromAST_selector) { const char* expected = wrapMathML ( " <apply>\n" " <selector/>\n" " <ci> y </ci>\n" " <ci> z </ci>\n" " <cn type=\"integer\"> 5 </cn>\n" " </apply>\n" ); ASTNode * y = new ASTNode(AST_NAME); fail_unless(y->setName("y") == LIBSBML_OPERATION_SUCCESS); ASTNode * z = new ASTNode(AST_NAME); fail_unless(z->setName("z") == LIBSBML_OPERATION_SUCCESS); ASTNode *int1 = new ASTNode(AST_INTEGER); fail_unless(int1->setValue((long)(5)) == LIBSBML_OPERATION_SUCCESS); N = new ASTNode(AST_LINEAR_ALGEBRA_SELECTOR); fail_unless( N->getPackageName() == "arrays"); fail_unless(N->addChild(y) == LIBSBML_OPERATION_SUCCESS); fail_unless(N->addChild(z) == LIBSBML_OPERATION_SUCCESS); fail_unless(N->addChild(int1) == LIBSBML_OPERATION_SUCCESS); S = writeMathMLToString(N); fail_unless( equals(expected, S) ); }
ASTNode* CEvaluationNodeCall::toAST(const CCopasiDataModel* pDataModel) const { ASTNode* pNode = NULL; pNode = new ASTNode(AST_FUNCTION); const std::string funName = this->getData(); CFunction * pFun = CCopasiRootContainer::getFunctionList()->findFunction(funName); assert(pFun != NULL); if (pFun == NULL || pFun->getSBMLId().empty()) fatalError(); pNode->setName(pFun->getSBMLId().c_str()); const CEvaluationNode* child = static_cast<const CEvaluationNode*>(this->getChild()); while (child) { pNode->addChild(child->toAST(pDataModel)); child = static_cast<const CEvaluationNode*>(child->getSibling()); } return pNode; }
/** * * 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; }
END_TEST START_TEST (test_MathMLFromAST_matrix) { const char* expected = wrapMathML ( " <matrix>\n" " <matrixrow>\n" " <apply>\n" " <cos/>\n" " <cn type=\"integer\"> 5 </cn>\n" " </apply>\n" " <ci> y </ci>\n" " </matrixrow>\n" " <matrixrow>\n" " <cn type=\"integer\"> 2 </cn>\n" " <cn type=\"integer\"> 4 </cn>\n" " </matrixrow>\n" " </matrix>\n" ); ASTNode * y = new ASTNode(AST_NAME); fail_unless(y->setName("y") == LIBSBML_OPERATION_SUCCESS); ASTNode *int1 = new ASTNode(AST_INTEGER); fail_unless(int1->setValue((long)(5)) == LIBSBML_OPERATION_SUCCESS); ASTNode *cos = new ASTNode(AST_FUNCTION_COS); fail_unless(cos->addChild(int1) == LIBSBML_OPERATION_SUCCESS); ASTNode *row1 = new ASTNode(AST_LINEAR_ALGEBRA_MATRIXROW_CONSTRUCTOR); fail_unless( row1->getPackageName() == "arrays"); fail_unless(row1->addChild(cos) == LIBSBML_OPERATION_SUCCESS); fail_unless(row1->addChild(y) == LIBSBML_OPERATION_SUCCESS); ASTNode *int2 = new ASTNode(AST_INTEGER); fail_unless(int2->setValue((long)(2)) == LIBSBML_OPERATION_SUCCESS); ASTNode *int3 = new ASTNode(AST_INTEGER); fail_unless(int3->setValue((long)(4)) == LIBSBML_OPERATION_SUCCESS); ASTNode *row2 = new ASTNode(AST_LINEAR_ALGEBRA_MATRIXROW_CONSTRUCTOR); fail_unless( row2->getPackageName() == "arrays"); fail_unless(row2->addChild(int2) == LIBSBML_OPERATION_SUCCESS); fail_unless(row2->addChild(int3) == LIBSBML_OPERATION_SUCCESS); N = new ASTNode(AST_LINEAR_ALGEBRA_MATRIX_CONSTRUCTOR); fail_unless( N->getPackageName() == "arrays"); fail_unless(N->addChild(row1) == LIBSBML_OPERATION_SUCCESS); fail_unless(N->addChild(row2) == LIBSBML_OPERATION_SUCCESS); S = writeMathMLToString(N); fail_unless( equals(expected, S) ); }
ASTNode* CEvaluationNodeObject::toAST(const CCopasiDataModel* pDataModel) const { ASTNode* node = new ASTNode(); node->setType(AST_NAME); // since I can not get the model in which this node is located, I just // assume that it will always be the current global model. const CCopasiObject* object = pDataModel->getObject(mRegisteredObjectCN); assert(object); // if it is a reference, we get the parent of the reference if (object->isReference()) { object = object->getObjectParent(); } const CModelEntity* pME = dynamic_cast<const CModelEntity*>(object); if (pME != NULL) { const CModel* pModel = dynamic_cast<const CModel*>(pME); if (pModel != NULL) { node->setType(AST_NAME_TIME); node->setName("time"); if (pModel->getInitialTime() != 0.0) { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 1); } } else { node->setName(pME->getSBMLId().c_str()); } } else { const CCopasiParameter* pPara = dynamic_cast<const CCopasiParameter*>(object); if (pPara != NULL) { // now we have to use the common name as the name for the // node since we need to be able to identify local parameters // in arbitrary expressions for the export node->setName(pPara->getCN().c_str()); } else { const CReaction* pReaction = dynamic_cast<const CReaction*>(object); if (pReaction) { node->setName(pReaction->getSBMLId().c_str()); } else { fatalError(); } } } return node; }
ASTNode* CEvaluationNodeFunction::toAST(const CCopasiDataModel* pDataModel) const { SubType subType = (SubType)this->subType(); ASTNode* node = new ASTNode(); bool needFirstArg = true; switch (subType) { case S_INVALID: break; case S_LOG: node->setType(AST_FUNCTION_LN); break; case S_LOG10: { // log 10 needs two children, the log and the base node->setType(AST_FUNCTION_LOG); ASTNode* logBase = new ASTNode(); logBase->setType(AST_INTEGER); logBase->setValue(10); node->addChild(logBase); break; } case S_EXP: node->setType(AST_FUNCTION_EXP); break; case S_SIN: node->setType(AST_FUNCTION_SIN); break; case S_COS: node->setType(AST_FUNCTION_COS); break; case S_TAN: node->setType(AST_FUNCTION_TAN); break; case S_SEC: node->setType(AST_FUNCTION_SEC); break; case S_CSC: node->setType(AST_FUNCTION_CSC); break; case S_COT: node->setType(AST_FUNCTION_COT); break; case S_SINH: node->setType(AST_FUNCTION_SINH); break; case S_COSH: node->setType(AST_FUNCTION_COSH); break; case S_TANH: node->setType(AST_FUNCTION_TANH); break; case S_SECH: node->setType(AST_FUNCTION_SECH); break; case S_CSCH: node->setType(AST_FUNCTION_CSCH); break; case S_COTH: node->setType(AST_FUNCTION_COTH); break; case S_ARCSIN: node->setType(AST_FUNCTION_ARCSIN); break; case S_ARCCOS: node->setType(AST_FUNCTION_ARCCOS); break; case S_ARCTAN: node->setType(AST_FUNCTION_ARCTAN); break; case S_ARCSEC: node->setType(AST_FUNCTION_ARCSEC); break; case S_ARCCSC: node->setType(AST_FUNCTION_ARCCSC); break; case S_ARCCOT: node->setType(AST_FUNCTION_ARCCOT); break; case S_ARCSINH: node->setType(AST_FUNCTION_ARCSINH); break; case S_ARCCOSH: node->setType(AST_FUNCTION_ARCCOSH); break; case S_ARCTANH: node->setType(AST_FUNCTION_ARCTANH); break; case S_ARCSECH: node->setType(AST_FUNCTION_ARCSECH); break; case S_ARCCSCH: node->setType(AST_FUNCTION_ARCCSCH); break; case S_ARCCOTH: node->setType(AST_FUNCTION_ARCCOTH); break; case S_SQRT: node->setType(AST_FUNCTION_ROOT); break; case S_ABS: node->setType(AST_FUNCTION_ABS); break; case S_CEIL: node->setType(AST_FUNCTION_CEILING); break; case S_FLOOR: node->setType(AST_FUNCTION_FLOOR); break; case S_FACTORIAL: node->setType(AST_FUNCTION_FACTORIAL); break; case S_MINUS: node->setType(AST_MINUS); break; case S_PLUS: // if this is the unary plus as I suspect, // the node will be replaced by its only child delete node; node = dynamic_cast<const CEvaluationNode*>(this->getChild())->toAST(pDataModel); break; case S_NOT: node->setType(AST_LOGICAL_NOT); break; case S_RUNIFORM: { needFirstArg = false; node->setType(AST_FUNCTION); node->setName("RUNIFORM"); const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild()); const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling()); node->addChild(child->toAST(pDataModel)); node->addChild(sibling->toAST(pDataModel)); } break; case S_RNORMAL: { needFirstArg = false; node->setType(AST_FUNCTION); node->setName("RNORMAL"); const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild()); const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling()); node->addChild(child->toAST(pDataModel)); node->addChild(sibling->toAST(pDataModel)); } break; case S_RGAMMA: { needFirstArg = false; node->setType(AST_FUNCTION); node->setName("RGAMMA"); const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild()); const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling()); node->addChild(child->toAST(pDataModel)); node->addChild(sibling->toAST(pDataModel)); } break; case S_RPOISSON: { needFirstArg = false; node->setType(AST_FUNCTION); node->setName("RPOISSON"); const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild()); node->addChild(child->toAST(pDataModel)); } break; case S_MAX: { needFirstArg = false; node->setType(AST_FUNCTION); node->setName("MAX"); const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild()); const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling()); node->addChild(child->toAST(pDataModel)); node->addChild(sibling->toAST(pDataModel)); } break; case S_MIN: { needFirstArg = false; node->setType(AST_FUNCTION); node->setName("MIN"); const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild()); const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling()); node->addChild(child->toAST(pDataModel)); node->addChild(sibling->toAST(pDataModel)); } break; // :TODO: Bug 894: Implement me. //fatalError(); break; } if (subType != S_INVALID) { // the following is a workaround for a bug in libsbml 3.1.1 and 3.2.0 // where libsbml does not handle the case correctly that a root // function can have one or two children (MathML.cpp in function // writeFunctionRoot) if (subType == S_SQRT) { // add a degree node of value 2 as the first child ASTNode* pDegreeNode = new ASTNode(); pDegreeNode->setType(AST_INTEGER); pDegreeNode->setValue(2); node->addChild(pDegreeNode); } if (needFirstArg) { const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild()); node->addChild(child->toAST(pDataModel)); } } return node; }