int Submodel::convertTimeAndExtent() { int ret=LIBSBML_OPERATION_SUCCESS; string tcf = ""; ASTNode* tcf_ast = NULL; if (isSetTimeConversionFactor()) { tcf = getTimeConversionFactor(); tcf_ast = new ASTNode(AST_NAME); tcf_ast->setName(tcf.c_str()); } string xcf = ""; ASTNode* xcf_ast = NULL; if (isSetExtentConversionFactor()) { xcf = getExtentConversionFactor(); xcf_ast = new ASTNode(AST_NAME); xcf_ast->setName(xcf.c_str()); } ASTNode* klmod = NULL; if (xcf_ast != NULL) { klmod = xcf_ast; } if (tcf_ast != NULL) { if (klmod==NULL) { klmod = new ASTNode(AST_INTEGER); klmod->setValue(1); } ASTNode* divide = new ASTNode(AST_DIVIDE); divide->addChild(klmod); divide->addChild(tcf_ast); klmod = divide; } ret = convertTimeAndExtentWith(tcf_ast, xcf_ast, klmod); delete klmod; return ret; }
void parseElse(CurrPtr& curr, EndPtr end) { getToken(curr, end); // consume else if (!getColon(curr, end)) return; ASTNode* pop = currNode; currNode = new ASTNode(kTokenElse); pop->addChild(currNode); parseStatements(curr, end, currNode); getSemiColon(curr, end); currNode = pop; }
void parseStatements(CurrPtr& curr, EndPtr end, ASTNode *& currNode) { ASTNode* pop = currNode; ASTNode* ast = new ASTNode(kTokenStatements); pop->addChild(ast); currNode = ast; while (more(curr, end)) { if (*curr == kTerminalChar) // ; at the end of the block of statements { break; } parseStatement(curr, end); } currNode = pop; }
void parseLandruVarDeclaration(CurrPtr& curr, EndPtr end, ASTNode *& currNode) { bool sharedToken = peekToken(curr, end) == kTokenShared; bool paramToken = !sharedToken && peekToken(curr, end) == kTokenParam; if (sharedToken || paramToken) getToken(curr, end); char varType[256]; getType(curr, end, varType); if (!strlen(varType)) lcRaiseError("Expected variable type, found:", curr, 32); TokenId declaredType = peekToken(varType, varType+sizeof(varType)); char name[256]; getDeclarator(curr, end, name); if (!strlen(name)) lcRaiseError("Expected variable name, found:", curr, 32); auto token = kTokenLocalVariable; if (sharedToken) token = kTokenSharedVariable; else if (paramToken) token = kTokenParam; ASTNode * variableNode = new ASTNode(token, varType, name); currNode->addChild(variableNode); token = peekToken(curr, end); if (token == kTokenEq) { getToken(curr, end); // consume assignment operator ASTNode * pop = currNode; if (sharedToken) currNode = new ASTNode(kTokenInitialAssignment, name); else currNode = new ASTNode(kTokenAssignment, name); variableNode->addChild(currNode); parseLiteral(curr, end, currNode, declaredType); // and put the assigned value in the tree currNode = pop; } }
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) ); }
void parseFunction(CurrPtr& curr, EndPtr end, TokenId token) { char buff[256]; getNameSpacedDeclarator(curr, end, buff); // get function name ASTNode* pop = currNode; currNode = new ASTNode(token, buff); pop->addChild(currNode); parseParamList(curr, end); currNode = pop; more(curr, end); if (peekChar(curr, end) == '.') { // chained functions assume that the previous function left something on the stack // which can have a function invoked on it. ++curr; currNode->addChild(new ASTNode(kTokenDotChain, buff)); parseFunction(curr, end, kTokenFunction); } }
void parseOn(CurrPtr& curr, EndPtr end) { getToken(curr, end); // consume on char name[256]; name[0] = '\0'; TokenId what = peekToken(curr, end); if (what == kTokenUnknown) { char const* tokenStr; uint32_t length; curr = tsGetNameSpacedTokenAlphaNumeric(curr, end, '.', &tokenStr, &length); strncpy(name, tokenStr, length); name[length] = '\0'; what = kTokenFunction; } else { getToken(curr, end); } ASTNode* pop = currNode; ASTNode* onNode = new ASTNode(kTokenOn); currNode->addChild(onNode); currNode = onNode; ASTNode* eventNode = new ASTNode(what, name); onNode->addChild(eventNode); currNode = eventNode; // curr is now the qualifier, eg. message more(curr, end); if (peekChar(curr, end) == '(') parseParamList(curr, end); currNode = onNode; if (!getColon(curr, end)) return; parseStatements(curr, end, currNode); getSemiColon(curr, end); currNode = pop; }
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; }
END_TEST START_TEST (test_MathMLFromAST_plus_nary_3) { const char* expected = wrapMathML ( " <apply>\n" " <plus/>\n" " <cn type=\"integer\"> 1 </cn>\n" " <cn type=\"integer\"> 2 </cn>\n" " <cn type=\"integer\"> 3 </cn>\n" " </apply>\n" ); // N = SBML_parseFormula("1 + (2 + 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 *plus = new ASTNode(AST_PLUS); plus->addChild(c2); plus->addChild(c3); N->addChild(c1); N->addChild(plus); S = writeMathMLToString(N); fail_unless( equals(expected, S) ); }
END_TEST START_TEST (test_MathMLFromAST_replaceIDWithFunction_1) { const char* expected = wrapMathML ( " <apply>\n" " <plus/>\n" " <cn> 1 </cn>\n" " </apply>\n" ); const char* original = wrapMathML ( " <ci> x </ci>\n" ); N = new ASTNode(AST_NAME); N->setName("x"); ASTNode *replaced = new ASTNode(AST_PLUS); ASTNode *c = new ASTNode(); c->setValue(1.0); replaced->addChild(c); S = writeMathMLToString(N); fail_unless( equals(original, S) ); N->replaceIDWithFunction("x", replaced); S = writeMathMLToString(N); fail_unless( equals(expected, S) ); }
END_TEST START_TEST (test_UnitFormulaFormatter_getUnitDefinition_piecewise) { UnitDefinition * ud = new UnitDefinition(2, 4); ud = uff->getUnitDefinition(m->getRule(7)->getMath()); fail_unless(ud->getNumUnits() == 1); fail_unless(!strcmp(ud->getId().c_str(), ""), NULL); fail_unless(ud->getUnit(0)->getMultiplier() == 1); fail_unless(ud->getUnit(0)->getScale() == 0); fail_unless(ud->getUnit(0)->getExponent() == 1); fail_unless(ud->getUnit(0)->getOffset() == 0.0); fail_unless(ud->getUnit(0)->getKind() == UNIT_KIND_METRE); /* check deals with invalid nodes */ delete ud; UnitDefinition * ud1 = new UnitDefinition(m->getLevel(), m->getVersion()); ASTNode *node = new ASTNode(AST_FUNCTION_PIECEWISE); ud1 == uff->getUnitDefinition(node); fail_unless (ud1->getNumUnits() == 0); ASTNode *c = new ASTNode(AST_UNKNOWN); node->addChild(c); ud1 == uff->getUnitDefinition(node); fail_unless (ud1->getNumUnits() == 0); delete ud1; delete node; }
LIBSBML_CPP_NAMESPACE_USE int main (int argc, char* argv[]) { SBMLNamespaces sbmlns(3,1,"arrays",1); // create the document SBMLDocument *document = new SBMLDocument(&sbmlns); // set the required attribute to true ArraysSBMLDocumentPlugin * docPlug = static_cast<ArraysSBMLDocumentPlugin*>(document->getPlugin("arrays")); docPlug->setRequired(true); // create the Model Model* model=document->createModel(); // create the parameters // first parameter - for dimension m Parameter * p = model->createParameter(); p->setId("m"); p->setConstant(true); p->setValue(2); // second parameter - for dimension n p = model->createParameter(); p->setId("n"); p->setConstant(true); p->setValue(1); // third parameter - 2 x 1 matrix of parameters p = model->createParameter(); p->setId("x"); p->setConstant(false); // create the Dimensions via the Plugin ArraysSBasePlugin * arraysPlug = static_cast<ArraysSBasePlugin*>(p->getPlugin("arrays")); // first dimension Dimension * dim = arraysPlug->createDimension(); dim->setArrayDimension(0); dim->setSize("m"); // second dimension dim = arraysPlug->createDimension(); dim->setArrayDimension(1); dim->setSize("n"); // other parameters p = model->createParameter(); p->setId("y"); p->setConstant(true); p->setValue(2.3); // create the initialAssignment InitialAssignment *ia = model->createInitialAssignment(); ia->setSymbol("x"); ASTNode * row1 = new ASTNode(AST_LINEAR_ALGEBRA_VECTOR_CONSTRUCTOR); ASTNode * ci1 = new ASTNode(AST_NAME); ci1->setName("y"); row1->addChild(ci1); ASTNode * row2 = new ASTNode(AST_LINEAR_ALGEBRA_VECTOR_CONSTRUCTOR); ASTNode * ci2 = new ASTNode(AST_INTEGER); ci2->setValue(2); row2->addChild(ci2); ASTNode * math = new ASTNode(AST_LINEAR_ALGEBRA_VECTOR_CONSTRUCTOR); math->addChild(row1); math->addChild(row2); ia->setMath(math); writeSBML(document,"arrays_example3.xml"); delete document; return 0; }
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) ); }
void parseParamList(CurrPtr& curr, EndPtr end) { // if parsing a function, then an opening paren must have been encountered if (peekChar(curr, end) != '(') { lcRaiseError("Expecting a parameter list, no opening parenthesis found", curr, 32); return; } std::vector<std::string> paramList; parseExpression(curr, end, paramList); // closing paren if (peekChar(curr, end) == ')') getChar(curr, end); // consume ')' else lcRaiseError("Expected closing parenthesis, found", curr, 32); ASTNode* popNode = currNode; std::vector<ASTNode*> nodeStack; // this is where the things that get parameters go ASTNode* paramNode = 0; for (auto i = paramList.begin(); i != paramList.end(); ++i) { const std::string& s = *i; const char* strstart = s.c_str(); const char* strend = strstart + s.size(); if (s == "(") { nodeStack.push_back(currNode); currNode = new ASTNode(kTokenParameters); } else if (s == ")") { paramNode = currNode; currNode = nodeStack.back(); nodeStack.pop_back(); } else if (*(strend - 1) == '#') { if (!paramNode) lcRaiseError("Missing parameters for function", curr, 32); std::string funcName; funcName = s.substr(0, s.size() - 1); ASTNode* functionNode = new ASTNode(kTokenFunction, funcName.c_str()); functionNode->addChild(paramNode); paramNode = 0; currNode->addChild(functionNode); } else if (peekIsLiteral(strstart, strend)) parseLiteral(strstart, strend, currNode, kTokenNullLiteral); else if (s == "*") currNode->addChild(new ASTNode(kTokenOpMultiply)); else if (s == "+") currNode->addChild(new ASTNode(kTokenOpAdd)); else if (s == "/") currNode->addChild(new ASTNode(kTokenOpDivide)); else if (s == "-") currNode->addChild(new ASTNode(kTokenOpSubtract)); else if (s == "!") currNode->addChild(new ASTNode(kTokenOpNegate)); else if (s == "%") currNode->addChild(new ASTNode(kTokenOpModulus)); else if (s == ">") currNode->addChild(new ASTNode(kTokenOpGreaterThan)); else if (s == "<") currNode->addChild(new ASTNode(kTokenOpLessThan)); //else if (s == "=") // pushAssign(); else if (s[0] == '@') currNode->addChild(new ASTNode(kTokenGetVariableReference, strstart+1)); else currNode->addChild(new ASTNode(kTokenGetVariable, strstart)); } if (!nodeStack.empty() || !paramNode) lcRaiseError("Unmatched parenthesis in expression", curr, 32); currNode = popNode; currNode->addChild(paramNode); }
int Submodel::convertTimeAndExtentWith(const ASTNode* tcf, const ASTNode* xcf, const ASTNode* klmod) { if (tcf==NULL && xcf==NULL) return LIBSBML_OPERATION_SUCCESS; Model* model = getInstantiation(); if (model==NULL) { //getInstantiation sets its own error messages. return LIBSBML_OPERATION_FAILED; } ASTNode* tcftimes = NULL; ASTNode* tcfdiv = NULL; if (tcf != NULL) { tcftimes = new ASTNode(AST_TIMES); tcftimes->addChild(tcf->deepCopy()); tcfdiv = new ASTNode(AST_DIVIDE); tcfdiv->addChild(tcf->deepCopy()); } ASTNode* rxndivide = NULL; if (klmod != NULL) { rxndivide = new ASTNode(AST_DIVIDE); ASTNode rxnref(AST_NAME); rxndivide->addChild(rxnref.deepCopy()); rxndivide->addChild(klmod->deepCopy()); } List* allelements = model->getAllElements(); for (unsigned int el=0; el<allelements->getSize(); el++) { SBase* element = static_cast<SBase*>(allelements->get(el)); assert(element != NULL); ASTNode* ast1 = NULL; ASTNode* ast2 = NULL; Constraint* constraint = NULL; Delay* delay = NULL; EventAssignment* ea = NULL; InitialAssignment* ia = NULL; KineticLaw* kl = NULL; Priority* priority = NULL; RateRule* rrule = NULL; Rule* rule = NULL; Submodel* submodel = NULL; Trigger* trigger = NULL; string cf = ""; //Reaction math will be converted below, in the bits with the kinetic law. But because of that, we need to handle references *to* the reaction: even if it has no kinetic law, the units have changed, and this needs to be reflected by the flattening routine. if (rxndivide != NULL && element->getTypeCode()==SBML_REACTION && element->isSetId()) { rxndivide->getChild(0)->setName(element->getId().c_str()); for (unsigned int sube=0; sube<allelements->getSize(); sube++) { SBase* subelement = static_cast<SBase*>(allelements->get(sube)); subelement->replaceSIDWithFunction(element->getId(), rxndivide); } } //Submodels need their timeConversionFactor and extentConversionFactor attributes converted. We're moving top-down, so all we need to do here is fix the conversion factor attributes themselves, pointing them to new parameters if need be. if ((tcf !=NULL || xcf != NULL) && element->getTypeCode()==SBML_COMP_SUBMODEL) { submodel = static_cast<Submodel*>(element); if (tcf != NULL) { if (submodel->isSetTimeConversionFactor()) { createNewConversionFactor(cf, tcf, submodel->getTimeConversionFactor(), model); submodel->setTimeConversionFactor(cf); } else { submodel->setTimeConversionFactor(tcf->getName()); } } if (xcf != NULL) { if (submodel->isSetExtentConversionFactor()) { createNewConversionFactor(cf, xcf, submodel->getExtentConversionFactor(), model); submodel->setExtentConversionFactor(cf); } else { submodel->setExtentConversionFactor(xcf->getName()); } } } if (tcf==NULL) { if (klmod !=NULL && element->getTypeCode()==SBML_KINETIC_LAW) { kl = static_cast<KineticLaw*>(element); if (kl->isSetMath()) { ast1 = new ASTNode(AST_TIMES); ast1->addChild(klmod->deepCopy()); ast1->addChild(kl->getMath()->deepCopy()); kl->setMath(ast1); delete ast1; } } } else { // All math 'time' and 'delay' csymbols must still be converted. // Also, several constructs are modified directly. switch(element->getTypeCode()) { //This would be a WHOLE LOT SIMPLER if there was a 'hasMath' class in libsbml. But even so, it would have to // handle the kinetic laws, rate rules, and delays separately. case SBML_KINETIC_LAW: //Kinetic laws are multiplied by 'klmod'. kl = static_cast<KineticLaw*>(element); ast1 = kl->getMath()->deepCopy(); convertCSymbols(ast1, tcfdiv, tcftimes); if (klmod !=NULL) { kl = static_cast<KineticLaw*>(element); if (kl->isSetMath()) { ast2 = new ASTNode(AST_TIMES); ast2->addChild(klmod->deepCopy()); ast2->addChild(ast1); kl->setMath(ast2); delete ast2; } } else { kl->setMath(ast1); delete ast1; } break; case SBML_DELAY: //Delays are multiplied by the time conversion factor. delay = static_cast<Delay*>(element); if (delay->isSetMath()) { ast1 = delay->getMath()->deepCopy(); convertCSymbols(ast1, tcfdiv, tcftimes); tcftimes->addChild(ast1); delay->setMath(tcftimes); tcftimes->removeChild(1); } break; case SBML_RATE_RULE: //Rate rules are divided by the time conversion factor. rrule = static_cast<RateRule*>(element); if (rrule->isSetMath()) { ast1 = rrule->getMath()->deepCopy(); tcfdiv->insertChild(0, rrule->getMath()->deepCopy()); rrule->setMath(tcfdiv); tcfdiv->removeChild(0); } //Fall through to: case SBML_ASSIGNMENT_RULE: case SBML_ALGEBRAIC_RULE: //Rules in general need csymbols converted. rule = static_cast<Rule*>(element); if (rule->isSetMath()) { ast1 = rule->getMath()->deepCopy(); convertCSymbols(ast1, tcfdiv, tcftimes); rule->setMath(ast1); delete ast1; } break; case SBML_EVENT_ASSIGNMENT: //Event assignments need csymbols converted. ea = static_cast<EventAssignment*>(element); if (ea->isSetMath()) { ast1 = ea->getMath()->deepCopy(); convertCSymbols(ast1, tcfdiv, tcftimes); ea->setMath(ast1); delete ast1; } break; case SBML_INITIAL_ASSIGNMENT: //Initial assignments need csymbols converted. ia = static_cast<InitialAssignment*>(element); if (ia->isSetMath()) { ast1 = ia->getMath()->deepCopy(); convertCSymbols(ast1, tcfdiv, tcftimes); ia->setMath(ast1); delete ast1; } break; case SBML_CONSTRAINT: //Constraints need csymbols converted. constraint = static_cast<Constraint*>(element); if (constraint->isSetMath()) { ast1 = constraint->getMath()->deepCopy(); convertCSymbols(ast1, tcfdiv, tcftimes); constraint->setMath(ast1); delete ast1; } break; case SBML_PRIORITY: //Priorities need csymbols converted. priority = static_cast<Priority*>(element); if (priority->isSetMath()) { ast1 = priority->getMath()->deepCopy(); convertCSymbols(ast1, tcfdiv, tcftimes); priority->setMath(ast1); delete ast1; } break; case SBML_TRIGGER: //Triggers need csymbols converted. trigger = static_cast<Trigger*>(element); if (trigger->isSetMath()) { ast1 = trigger->getMath()->deepCopy(); convertCSymbols(ast1, tcfdiv, tcftimes); trigger->setMath(ast1); delete ast1; } break; default: //Do nothing! If we wanted to call a plugin routine, this would be the place. The only other alternative is to #ifdef some code in here that deals with the math-containing package objects explicitly. Which might be the best option, all told. break; } } } delete allelements; return LIBSBML_OPERATION_SUCCESS; }
/** * * 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; }
void parseGlobalVarDecls(CurrPtr& curr, EndPtr end, ASTNode *& currNode #ifdef LANDRU_HAVE_JSON , std::vector<std::pair<std::string, Json::Value*> >* jsonVars #endif ) { bool declareBlock = peekToken(curr, end) == kTokenDeclare; if (declareBlock) { parseDeclare(curr, end, currNode); return; } char name[256]; char require[256]; getDeclarator(curr, end, name); CurrPtr t = curr; if (!getToken(kTokenEq, curr, end)) { lcRaiseError("Missing = after global declaration. Eg: \nio = require(\"io\")\n", curr, 32); } ASTNode* globVar = new ASTNode(kTokenGlobalVariable, name); currNode->addChild(globVar); #ifdef LANDRU_HAVE_JSON if (peekChar('{', curr, end) || peekChar('[', curr, end)) { const char* jsonStart = curr; // Parse a JSON block. JSONCallback jsonCallback; ASTNode* pop = currNode; currNode = new ASTNode(kTokenStaticData); globVar->addChild(currNode); if (!Lab::Json::parseJsonValue(curr, end, &jsonCallback)) lcRaiseError("Poorly formed JSON chunk", curr, 32); const char* jsonEnd = curr; Json::Reader reader; Json::Value* root = new Json::Value(); reader.parse(jsonStart, jsonEnd, *root, false); // false = ignore comments jsonVars->push_back(std::pair<std::string, Json::Value*>(name, root)); currNode = pop; } else #endif if (getToken(kTokenRequire, curr, end)) { if (getChar('(', curr, end)) { curr = tsSkipCommentsAndWhitespace(curr, end); char const* value; uint32_t length; if (*curr == '"') { curr = tsGetString(curr, end, true, &value, &length); strncpy(require, value, length); require[length] = '\0'; } curr = tsSkipCommentsAndWhitespace(curr, end); if (!getChar(')', curr, end)) { lcRaiseError("Poorly formed require", curr, 32); } } globVar->addChild(new ASTNode(kTokenRequire, require)); } else { curr = t; } }
ASTNode *UnaryOp::parse(Parser *parser, Token token) { ASTNode *node = new ASTNode(Type,token.Begin); node->str = token.String; node->addChild(parser->parseExpression()); // parse operand return node; }
ASTNode* CEvaluationNodeLogical::toAST(const CCopasiDataModel* pDataModel) const { SubType subType = (SubType)CEvaluationNode::subType(this->getType()); ASTNode* node = new ASTNode(); switch (subType) { case AND: node->setType(AST_LOGICAL_AND); break; case OR: node->setType(AST_LOGICAL_OR); break; case XOR: node->setType(AST_LOGICAL_XOR); break; case EQ: node->setType(AST_RELATIONAL_EQ); break; case NE: node->setType(AST_RELATIONAL_NEQ); break; case GT: node->setType(AST_RELATIONAL_GT); break; case GE: node->setType(AST_RELATIONAL_GEQ); break; case LT: node->setType(AST_RELATIONAL_LT); break; case LE: node->setType(AST_RELATIONAL_LEQ); break; case INVALID: break; default: subType = INVALID; break; } if (subType != INVALID) { const CEvaluationNode* child1 = dynamic_cast<const CEvaluationNode*>(this->getChild()); const CEvaluationNode* child2 = dynamic_cast<const CEvaluationNode*>(child1->getSibling()); node->addChild(child1->toAST(pDataModel)); node->addChild(child2->toAST(pDataModel)); } return node; }
int ASTPiecewiseFunctionNode::addChild(ASTBase* child, bool inRead) { // now here what I want to do is just keep track of the number // of children being added so the mNumPiece and mHasOtherwise // variables can be given appropriate values // but not if we are reading a stream because then we already know if (inRead == false) { if (child->getType() != AST_CONSTRUCTOR_PIECE && child->getType() != AST_CONSTRUCTOR_OTHERWISE) { // this child does not have a piece/otherwise but if // the rest of the function does then it needs to fit in with that unsigned int currentNum = getNumChildren(); if (usingChildConstructors() == false) { if ((currentNum+1)%2 == 0) { setNumPiece(getNumPiece()+1); setHasOtherwise(false); } else { setHasOtherwise(true); } return ASTFunctionBase::addChild(child); } else { ASTBase * lastChild = ASTFunctionBase::getChild(ASTFunctionBase::getNumChildren()-1); if (lastChild == NULL) { // we have a serious issue going on but may as well just // add the child return ASTFunctionBase::addChild(child); } else if (lastChild->getType() == AST_CONSTRUCTOR_PIECE) { ASTNode * piece = dynamic_cast<ASTNode*>(lastChild); if (piece == NULL) { return LIBSBML_OPERATION_FAILED; } if (piece->getNumChildren() == 1) { return piece->addChild((ASTNode*)(child)); } else { ASTNode * otherwise = new ASTNode(AST_CONSTRUCTOR_OTHERWISE); if (otherwise->addChild((ASTNode*)(child)) == LIBSBML_OPERATION_SUCCESS) { setHasOtherwise(true); return ASTFunctionBase::addChild(otherwise); } else { return LIBSBML_OPERATION_FAILED; } } } else { ASTNode * otherwise = dynamic_cast<ASTNode*>(lastChild); if (otherwise == NULL || otherwise->getNumChildren() != 1) { return LIBSBML_OPERATION_FAILED; } ASTNode * piece = new ASTNode(AST_CONSTRUCTOR_PIECE); // add teh child from teh otherwise if (piece->addChild(otherwise->getChild(0)) != LIBSBML_OPERATION_SUCCESS) { return LIBSBML_OPERATION_FAILED; } else { if (piece->addChild((ASTNode*)(child)) == LIBSBML_OPERATION_SUCCESS) { this->removeChild(currentNum-1); setHasOtherwise(false); setNumPiece(getNumPiece() + 1); return ASTFunctionBase::addChild(piece); } else { return LIBSBML_OPERATION_FAILED; } } } } } else { if (child->getType() == AST_CONSTRUCTOR_PIECE) { setNumPiece(getNumPiece()+1); } else { setHasOtherwise(true); } return ASTFunctionBase::addChild(child); } } else { return ASTFunctionBase::addChild(child); } }
/** * * 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; }
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; }