void Module::SetAssignmentFor(Model* sbmlmod, const Variable* var) { char cc = g_registry.GetCC(); formula_type ftype = var->GetFormulaType(); const Formula* formula = var->GetFormula(); if (!formula->IsEmpty()) { ASTNode* math = parseStringToASTNode(formula->ToSBMLString()); if (ftype == formulaASSIGNMENT) { AssignmentRule* ar = sbmlmod->createAssignmentRule(); ar->setVariable(var->GetNameDelimitedBy(cc)); ar->setMath(math); } else if (!formula->IsDouble() && !(IsSpecies(var->GetType()) && formula->IsAmountIn(var->GetCompartment()))) { //if it was a double or a species with an amount, we already dealt with it. Otherwise: InitialAssignment* ia = sbmlmod->createInitialAssignment(); ia->setSymbol(var->GetNameDelimitedBy(cc)); ia->setMath(math); } delete math; } if (ftype == formulaRATE) { formula = var->GetRateRule(); if (!formula->IsEmpty()) { ASTNode* math = parseStringToASTNode(var->GetRateRule()->ToSBMLString()); RateRule* rr = sbmlmod->createRateRule(); rr->setVariable(var->GetNameDelimitedBy(cc)); rr->setMath(math); delete math; } } }
END_TEST START_TEST ( test_InitialAssignment ) { InitialAssignment* ia = new InitialAssignment(2, 4); fail_unless (!(ia->hasRequiredElements())); ia->setMath(SBML_parseFormula("ia")); fail_unless (ia->hasRequiredElements()); delete ia; }
END_TEST START_TEST ( test_InitialAssignment_parent_add ) { InitialAssignment *ia = new InitialAssignment(2, 4); Model *m = new Model(2, 4); ia->setSymbol("c"); ia->setMath(SBML_parseFormula("9")); m->addInitialAssignment(ia); delete ia; ListOf *lo = m->getListOfInitialAssignments(); fail_unless(lo == m->getInitialAssignment(0)->getParentSBMLObject()); fail_unless(m == lo->getParentSBMLObject()); }
void Submodel::createNewConversionFactor(string& cf, const ASTNode* newcf, string oldcf, Model* model) { stringstream npID; npID << oldcf << "_times_" << newcf->getName(); int i=0; while (model->getElementBySId(npID.str()) != NULL) { i++; npID.clear(); npID << oldcf << "_times_" << newcf->getName() << "_" << i; } cf = npID.str(); Parameter* newparam = model->createParameter(); newparam->setId(cf); newparam->setConstant(true); InitialAssignment* ia = model->createInitialAssignment(); ia->setSymbol(cf); string math = oldcf + " * " + newcf->getName(); ia->setMath(SBML_parseL3Formula(math.c_str())); }
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(AST_TIMES); ASTNode tcfdiv(AST_DIVIDE); if (tcf != NULL) { tcftimes.addChild(tcf->deepCopy()); tcfdiv.addChild(tcf->deepCopy()); } ASTNode rxndivide(AST_DIVIDE); if (klmod != NULL) { ASTNode rxnref(AST_NAME); rxndivide.addChild(rxnref.deepCopy()); rxndivide.addChild(klmod->deepCopy()); } List* allElements = model->getAllElements(); for (ListIterator iter = allElements->begin(); iter != allElements->end(); ++iter) { SBase* element = static_cast<SBase*>(*iter); 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.getNumChildren() != 0 && element->getTypeCode()==SBML_REACTION && element->isSetId()) { rxndivide.getChild(0)->setName(element->getId().c_str()); for (ListIterator iter = allElements->begin(); iter != allElements->end(); ++iter) { SBase* subelement = static_cast<SBase*>(*iter); 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); delete ast1; } 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, ast1); rrule->setMath(&tcfdiv); tcfdiv.removeChild(0); delete ast1; } //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; }
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; }
void dealWithL1Stoichiometry(Model & m, bool l2) { unsigned int idCount = 0; char newid[15]; std::string id; for (unsigned int i = 0; i < m.getNumReactions(); i++) { Reaction *r = m.getReaction(i); unsigned int j; for (j = 0; j < r->getNumReactants(); j++) { SpeciesReference *sr = r->getReactant(j); if (sr->getDenominator() != 1) { long stoich = static_cast<long>(sr->getStoichiometry()); int denom = sr->getDenominator(); ASTNode *node = new ASTNode(); node->setValue(stoich, denom); if (l2 == true) { StoichiometryMath * sm = sr->createStoichiometryMath(); sm->setMath(node); } else { sprintf(newid, "speciesRefId_%u", idCount); id.assign(newid); idCount++; sr->setId(id); InitialAssignment * ar = m.createInitialAssignment(); ar->setSymbol(id); ar->setMath(node); sr->unsetStoichiometry(); } } } for (j = 0; j < r->getNumProducts(); j++) { SpeciesReference *sr = r->getProduct(j); if (sr->getDenominator() != 1) { long stoich = static_cast<long>(sr->getStoichiometry()); int denom = sr->getDenominator(); ASTNode *node = new ASTNode(); node->setValue(stoich, denom); if (l2 == true) { StoichiometryMath * sm = sr->createStoichiometryMath(); sm->setMath(node); } else { sprintf(newid, "speciesRefId_%u", idCount); id.assign(newid); idCount++; sr->setId(id); InitialAssignment * ar = m.createInitialAssignment(); ar->setSymbol(id); ar->setMath(node); sr->unsetStoichiometry(); } } } } }