void test000087::test_simulate_reaction_flux_reference_1() { try { bool result = pCOPASIDATAMODEL->importSBMLFromString(test000087::MODEL_STRING5); CPPUNIT_ASSERT(result = true); } catch (...) { // there should be no exception CPPUNIT_ASSERT(false); } CModel* pModel = pCOPASIDATAMODEL->getModel(); CPPUNIT_ASSERT(pModel != NULL); CPPUNIT_ASSERT(pModel->getCompartments().size() == 1); CPPUNIT_ASSERT(pModel->getMetabolites().size() == 2); CPPUNIT_ASSERT(pModel->getModelValues().size() == 2); CPPUNIT_ASSERT(pModel->getReactions().size() == 1); const CReaction* pReaction = pModel->getReactions()[0]; CPPUNIT_ASSERT(pReaction != NULL); CModelValue* pConstParameter = NULL; CModelValue* pNonConstParameter = NULL; unsigned int i, iMax = pModel->getModelValues().size(); for (i = 0; i < iMax; ++i) { if (pModel->getModelValues()[i]->getStatus() == CModelEntity::FIXED) { pConstParameter = pModel->getModelValues()[i]; } if (pModel->getModelValues()[i]->getStatus() == CModelEntity::ASSIGNMENT) { pNonConstParameter = pModel->getModelValues()[i]; } } CPPUNIT_ASSERT(pConstParameter != NULL); CPPUNIT_ASSERT(pNonConstParameter != NULL); // check if the kinetic law is mass action with const global parameter as the kinetic constant CPPUNIT_ASSERT(pReaction->getChemEq().getSubstrates().size() == 1); CPPUNIT_ASSERT(pReaction->getChemEq().getProducts().size() == 1); CPPUNIT_ASSERT(pReaction->getChemEq().getModifiers().size() == 0); CPPUNIT_ASSERT(pReaction->isReversible() == false); const CFunction* pKineticLaw = pReaction->getFunction(); CPPUNIT_ASSERT(pKineticLaw != NULL); CPPUNIT_ASSERT(pKineticLaw->getType() == CEvaluationTree::MassAction); const std::vector< std::vector<std::string> > & parameterMappings = pReaction->getParameterMappings(); CPPUNIT_ASSERT(parameterMappings.size() == 2); CPPUNIT_ASSERT(parameterMappings[0].size() == 1); CPPUNIT_ASSERT(parameterMappings[0][0] == pConstParameter->getKey()); CPPUNIT_ASSERT(parameterMappings[1].size() == 1); std::string substrateKey = parameterMappings[1][0]; const CCopasiObject* pTempObject = CCopasiRootContainer::getKeyFactory()->get(substrateKey); CPPUNIT_ASSERT(pTempObject != NULL); const CMetab* pSubstrate = dynamic_cast<const CMetab*>(pTempObject); CPPUNIT_ASSERT(pSubstrate != NULL); // check that the assignment consists of only one object node that is a reference to the reaction flux const CExpression* pExpression = pNonConstParameter->getExpressionPtr(); CPPUNIT_ASSERT(pExpression != NULL); const CEvaluationNode* pRoot = pExpression->getRoot(); CPPUNIT_ASSERT(pRoot != NULL); CPPUNIT_ASSERT(CEvaluationNode::type(pRoot->getType()) == CEvaluationNode::OBJECT); const CEvaluationNodeObject* pObjectNode = dynamic_cast<const CEvaluationNodeObject*>(pRoot); CPPUNIT_ASSERT(pObjectNode != NULL); const CRegisteredObjectName cn = pObjectNode->getObjectCN(); std::vector<CCopasiContainer*> listOfContainers; listOfContainers.push_back(pCOPASIDATAMODEL->getModel()); const CCopasiObject* pObject = pCOPASIDATAMODEL->ObjectFromName(listOfContainers, cn); CPPUNIT_ASSERT(pObject != NULL); CPPUNIT_ASSERT(pObject->isReference() == true); CPPUNIT_ASSERT(pObject->getObjectName() == "Flux"); CPPUNIT_ASSERT(pObject->getObjectParent() == pReaction); // Simulate the model (5 steps, stepsize 1 and check that at each step, the value of the variable parameter // is the same as the flux through the reaction. std::ostringstream result; // create a report with the correct filename and all the species against // time. CReportDefinitionVector* pReports = pCOPASIDATAMODEL->getReportDefinitionList(); CReportDefinition* pReport = pReports->createReportDefinition("Report", "Output for simulation"); pReport->setTaskType(CCopasiTask::timeCourse); pReport->setIsTable(false); pReport->setSeparator(CCopasiReportSeparator(", ")); std::vector<CRegisteredObjectName>* pHeader = pReport->getHeaderAddr(); std::vector<CRegisteredObjectName>* pBody = pReport->getBodyAddr(); pHeader->push_back(CCopasiStaticString("time").getCN()); pHeader->push_back(pReport->getSeparator().getCN()); pHeader->push_back(CCopasiStaticString("substrate").getCN()); pHeader->push_back(pReport->getSeparator().getCN()); pHeader->push_back(CCopasiStaticString("reaction flux").getCN()); pHeader->push_back(pReport->getSeparator().getCN()); pHeader->push_back(CCopasiStaticString("variable model value").getCN()); pBody->push_back(CCopasiObjectName(pCOPASIDATAMODEL->getModel()->getCN() + ",Reference=Time")); pBody->push_back(CRegisteredObjectName(pReport->getSeparator().getCN())); pBody->push_back(CCopasiObjectName(pSubstrate->getCN() + ",Reference=Concentration")); pBody->push_back(CRegisteredObjectName(pReport->getSeparator().getCN())); pBody->push_back(CCopasiObjectName(pReaction->getCN() + ",Reference=Flux")); pBody->push_back(CRegisteredObjectName(pReport->getSeparator().getCN())); pBody->push_back(CCopasiObjectName(pNonConstParameter->getCN() + ",Reference=Value")); // // create a trajectory task CTrajectoryTask* pTrajectoryTask = new CTrajectoryTask(); // use LSODAR from now on since we will have events pretty soon pTrajectoryTask->setMethodType(CCopasiMethod::LSODAR); pTrajectoryTask->getProblem()->setModel(pCOPASIDATAMODEL->getModel()); pTrajectoryTask->setScheduled(true); pTrajectoryTask->getReport().setReportDefinition(pReport); // the target needs to be set in order to get output on the stream // object passed to the task in the call to initialize below pTrajectoryTask->getReport().setTarget("test.tmp"); CTrajectoryProblem* pProblem = dynamic_cast<CTrajectoryProblem*>(pTrajectoryTask->getProblem()); pProblem->setStepNumber((const unsigned C_INT32)30); pCOPASIDATAMODEL->getModel()->setInitialTime((const C_FLOAT64)0.0); pProblem->setDuration((const C_FLOAT64)30); pProblem->setTimeSeriesRequested(true); CTrajectoryMethod* pMethod = dynamic_cast<CTrajectoryMethod*>(pTrajectoryTask->getMethod()); pMethod->getParameter("Absolute Tolerance")->setValue(1.0e-12); CCopasiVectorN< CCopasiTask > & TaskList = * pCOPASIDATAMODEL->getTaskList(); TaskList.remove("Time-Course"); TaskList.add(pTrajectoryTask, true); try { pTrajectoryTask->initialize(CCopasiTask::OUTPUT_UI, pCOPASIDATAMODEL, &result); pTrajectoryTask->process(true); pTrajectoryTask->restore(); } catch (...) { // there should be no exception CPPUNIT_ASSERT(false); } // analyse the result CPPUNIT_ASSERT(!result.str().empty()); std::string result_string = result.str(); std::string delimiter = "\n"; std::string delimiter2 = ","; std::size_t lastPos = result_string.find_first_not_of(delimiter); std::size_t pos; std::string line, number_string; unsigned int index = 0; unsigned int index2; std::size_t lastPos2; std::size_t pos2; double last = std::numeric_limits<double>::max(), current = std::numeric_limits<double>::max(); while (lastPos != std::string::npos) { pos = result_string.find_first_of(delimiter, lastPos); line = result_string.substr(lastPos, pos - lastPos); lastPos = result_string.find_first_not_of(delimiter, pos); lastPos2 = line.find_first_not_of(delimiter2); // skip the header line if (index != 0) { index2 = 0; while (lastPos2 != std::string::npos) { pos2 = line.find_first_of(delimiter2, lastPos2); number_string = line.substr(lastPos2, pos2 - lastPos2); lastPos2 = line.find_first_not_of(delimiter2, pos2); // skip the time column if (index2 != 0) { //check that all values in the row (besides the time) // are always the same if (index2 == 1) { last = strToDouble(number_string.c_str(), NULL); if (index == 1) { // just make sure that we don't compare all zeros // The initial value of the substrate hould be higher than 1 CPPUNIT_ASSERT(fabs(pSubstrate->getInitialValue()) > 1); // the first rwo should correspond the the initial value of the substrate // We check this to make sure that the whole timeseries does not consist of zeros CPPUNIT_ASSERT(fabs((last - pSubstrate->getInitialConcentration()) / pSubstrate->getInitialConcentration()) < 1e-20); } } else { current = strToDouble(number_string.c_str(), NULL); CPPUNIT_ASSERT(fabs((current - last) / last) < 1e-20); last = current; } } ++index2; } } ++index; } // make sure there actually were datapoints CPPUNIT_ASSERT(index > 1); // the simulation is set to run until all substrate is depleted, so in the end // last should be below the absolute tolerance for the simulation CPPUNIT_ASSERT(last < *pMethod->getParameter("Absolute Tolerance")->getValue().pDOUBLE); }
bool CModelMerging::mergeMetabolites(std::string toKey, std::string key) { bool info = false; //merge in the relevant reactions size_t i, imax = mpModel->getReactions().size(); size_t j, jmax; for (i = 0; i < imax; ++i) { CReaction * reac = &mpModel->getReactions()[i]; jmax = reac->getChemEq().getSubstrates().size(); for (j = 0; j < jmax; ++j) { CChemEqElement * subst = const_cast< CChemEqElement * >(&reac->getChemEq().getSubstrates()[j]); if (subst->getMetabolite()->getKey() == key) subst->setMetabolite(toKey); } jmax = reac->getChemEq().getProducts().size(); for (j = 0; j < jmax; ++j) { CChemEqElement * prod = const_cast< CChemEqElement * >(&reac->getChemEq().getProducts()[j]); if (prod->getMetabolite()->getKey() == key) prod->setMetabolite(toKey); } jmax = reac->getChemEq().getModifiers().size(); for (j = 0; j < jmax; ++j) { CChemEqElement * modif = const_cast< CChemEqElement * >(&reac->getChemEq().getModifiers()[j]); if (modif->getMetabolite()->getKey() == key) modif->setMetabolite(toKey); } //change parameters of the kinetic function for (j = 0; j < reac->getFunctionParameters().size(); ++j) { switch (reac->getFunctionParameters()[j]->getUsage()) { case CFunctionParameter::SUBSTRATE: case CFunctionParameter::PRODUCT: case CFunctionParameter::MODIFIER: //translate the metab keys { //we assume that only SUBSTRATE, PRODUCT, MODIFIER can be vectors size_t k, kmax = reac->getParameterMappings()[j].size(); for (k = 0; k < kmax; ++k) if (reac->getParameterMappings()[j][k] == key) reac->getParameterMappings()[j][k] = toKey; } break; case CFunctionParameter::TIME: break; case CFunctionParameter::VOLUME: // ??? TODO : have to ask break; case CFunctionParameter::PARAMETER: break; default: return info; break; } } } imax = mpModel->getEvents().size(); for (i = 0; i < imax; ++i) { CEvent * event = &mpModel->getEvents()[i]; if (!event) return info; /* merge in trigger expressions */ CExpression* pExpression = event->getTriggerExpressionPtr(); if (pExpression == NULL) return info; if (!mergeInExpression(toKey, key, pExpression)) return info; pExpression = event->getDelayExpressionPtr(); if (pExpression) if (!mergeInExpression(toKey, key, pExpression)) return info; jmax = event->getAssignments().size(); for (j = 0; j < jmax; ++j) { CEventAssignment* assignment = &event->getAssignments()[j]; if (!assignment) return info; std::string assignmentKey = assignment->getTargetKey(); if (assignmentKey == key) assignment->setTargetKey(toKey); pExpression = assignment->getExpressionPtr(); if (pExpression == NULL) return info; if (!mergeInExpression(toKey, key, pExpression)) return info; } } imax = mpModel->getMetabolites().size(); for (i = 0; i < imax; ++i) { CMetab* metab = &mpModel->getMetabolites()[i]; if (!metab) return info; switch (metab->getStatus()) { case CModelEntity::FIXED: case CModelEntity::REACTIONS: break; case CModelEntity::ASSIGNMENT: if (!mergeInExpression(toKey, key, metab->getExpressionPtr())) return info; break; case CModelEntity::ODE: if (!mergeInExpression(toKey, key, metab->getExpressionPtr())) return info; if (metab->getInitialExpression() != "") if (!mergeInExpression(toKey, key, metab->getInitialExpressionPtr())) return info; break; default: return info; break; } } imax = mpModel->getCompartments().size(); for (i = 0; i < imax; ++i) { CCompartment* comp = &mpModel->getCompartments()[i]; if (!comp) return info; switch (comp ->getStatus()) { case CModelEntity::FIXED: break; case CModelEntity::ASSIGNMENT: if (!mergeInExpression(toKey, key, comp->getExpressionPtr())) return info; break; case CModelEntity::ODE: if (!mergeInExpression(toKey, key, comp->getExpressionPtr())) return info; if (comp->getInitialExpression() != "") if (!mergeInExpression(toKey, key, comp->getInitialExpressionPtr())) return info; break; default: return info; break; } } imax = mpModel->getModelValues().size(); for (i = 0; i < imax; ++i) { CModelValue* modval = &mpModel->getModelValues()[i]; if (!modval) return info; switch (modval ->getStatus()) { case CModelEntity::FIXED: break; case CModelEntity::ASSIGNMENT: if (!mergeInExpression(toKey, key, modval->getExpressionPtr())) return info; break; case CModelEntity::ODE: if (!mergeInExpression(toKey, key, modval->getExpressionPtr())) return info; if (modval->getInitialExpression() != "") if (!mergeInExpression(toKey, key, modval->getInitialExpressionPtr())) return info; break; default: return info; break; } } return true; }