Example #1
0
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);
}
Example #2
0
int main(int argc, char** argv)
{
  // initialize the backend library
  CCopasiRootContainer::init(argc, argv);
  assert(CCopasiRootContainer::getRoot() != NULL);
  // create a new datamodel
  CCopasiDataModel* pDataModel = CCopasiRootContainer::addDatamodel();
  assert(CCopasiRootContainer::getDatamodelList()->size() == 1);

  // the only argument to the main routine should be the name of an SBML file
  if (argc == 2)
    {
      std::string filename = argv[1];

      try
        {
          // load the model without progress report
          pDataModel->importSBML(filename, NULL);
        }
      catch (...)
        {
          std::cerr << "Error while importing the model from file named \"" << filename << "\"." << std::endl;
          CCopasiRootContainer::destroy();
          return 1;
        }

      CModel* pModel = pDataModel->getModel();
      assert(pModel != NULL);
      // create a report with the correct filename and all the species against
      // time.
      CReportDefinitionVector* pReports = pDataModel->getReportDefinitionList();
      // create a new report definition object
      CReportDefinition* pReport = pReports->createReportDefinition("Report", "Output for timecourse");
      // set the task type for the report definition to timecourse
      pReport->setTaskType(CTaskEnum::timeCourse);
      // we don't want a table
      pReport->setIsTable(false);
      // the entries in the output should be seperated by a ", "
      pReport->setSeparator(", ");

      // we need a handle to the header and the body
      // the header will display the ids of the metabolites and "time" for
      // the first column
      // the body will contain the actual timecourse data
      std::vector<CRegisteredObjectName>* pHeader = pReport->getHeaderAddr();
      std::vector<CRegisteredObjectName>* pBody = pReport->getBodyAddr();
      pBody->push_back(CCopasiObjectName(pDataModel->getModel()->getCN() + ",Reference=Time"));
      pBody->push_back(CRegisteredObjectName(pReport->getSeparator().getCN()));
      pHeader->push_back(CCopasiStaticString("time").getCN());
      pHeader->push_back(pReport->getSeparator().getCN());

      size_t i, iMax = pModel->getMetabolites().size();

      for (i = 0; i < iMax; ++i)
        {
          CMetab* pMetab = &pModel->getMetabolites()[i];
          assert(pMetab != NULL);

          // we don't want output for FIXED metabolites right now
          if (pMetab->getStatus() != CModelEntity::FIXED)
            {
              // we want the concentration oin the output
              // alternatively, we could use "Reference=Amount" to get the
              // particle number
              pBody->push_back(pMetab->getObject(CCopasiObjectName("Reference=Concentration"))->getCN());
              // after each entry, we need a seperator
              pBody->push_back(pReport->getSeparator().getCN());

              // add the corresponding id to the header
              pHeader->push_back(CCopasiStaticString(pMetab->getSBMLId()).getCN());
              // and a seperator
              pHeader->push_back(pReport->getSeparator().getCN());
            }
        }

      if (iMax > 0)
        {
          // delete the last separator
          // since we don't need one after the last element on each line
          if ((*pBody->rbegin()) == pReport->getSeparator().getCN())
            {
              pBody->erase(--pBody->end());
            }

          if ((*pHeader->rbegin()) == pReport->getSeparator().getCN())
            {
              pHeader->erase(--pHeader->end());
            }
        }

      // get the task list
      CCopasiVectorN< CCopasiTask > & TaskList = * pDataModel->getTaskList();

      // get the trajectory task object
      CTrajectoryTask* pTrajectoryTask = dynamic_cast<CTrajectoryTask*>(&TaskList["Time-Course"]);

      // if there isn't one
      if (pTrajectoryTask == NULL)
        {
          // remove any existing trajectory task just to be sure since in
          // theory only the cast might have failed above
          TaskList.remove("Time-Course");

          // create a new one
          pTrajectoryTask = new CTrajectoryTask(& TaskList);

          // add the new time course task to the task list
          TaskList.add(pTrajectoryTask, true);
        }

      // run a deterministic time course
      pTrajectoryTask->setMethodType(CTaskEnum::deterministic);

      // Activate the task so that it will be run when the model is saved
      // and passed to CopasiSE
      pTrajectoryTask->setScheduled(true);

      // set the report for the task
      pTrajectoryTask->getReport().setReportDefinition(pReport);
      // set the output filename
      pTrajectoryTask->getReport().setTarget("example3.txt");
      // don't append output if the file exists, but overwrite the file
      pTrajectoryTask->getReport().setAppend(false);

      // get the problem for the task to set some parameters
      CTrajectoryProblem* pProblem = dynamic_cast<CTrajectoryProblem*>(pTrajectoryTask->getProblem());

      // simulate 100 steps
      pProblem->setStepNumber(100);
      // start at time 0
      pDataModel->getModel()->setInitialTime(0.0);
      // simulate a duration of 10 time units
      pProblem->setDuration(10);
      // tell the problem to actually generate time series data
      pProblem->setTimeSeriesRequested(true);

      // set some parameters for the LSODA method through the method
      CTrajectoryMethod* pMethod = dynamic_cast<CTrajectoryMethod*>(pTrajectoryTask->getMethod());

      CCopasiParameter* pParameter = pMethod->getParameter("Absolute Tolerance");
      assert(pParameter != NULL);
      pParameter->setValue(1.0e-12);

      try
        {
          // initialize the trajectory task
          // we want complete output (HEADER, BODY and FOOTER)
          //
          // The output has to be set to OUTPUT_UI, otherwise the time series will not be
          // kept in memory and some of the assert further down will fail
          // If it is OK that the output is only written to file, the output type can
          // be set to OUTPUT_SE
          pTrajectoryTask->initialize(CCopasiTask::OUTPUT_UI, pDataModel, NULL);
          // now we run the actual trajectory
          pTrajectoryTask->process(true);
        }
      catch (...)
        {
          std::cerr << "Error. Running the time course simulation failed." << std::endl;

          // check if there are additional error messages
          if (CCopasiMessage::size() > 0)
            {
              // print the messages in chronological order
              std::cerr << CCopasiMessage::getAllMessageText(true);
            }

          CCopasiRootContainer::destroy();
          return 1;
        }

      // restore the state of the trajectory
      pTrajectoryTask->restore();

      // look at the timeseries
      const CTimeSeries* pTimeSeries = &pTrajectoryTask->getTimeSeries();
      // we simulated 100 steps, including the initial state, this should be
      // 101 step in the timeseries
      assert(pTimeSeries->getRecordedSteps() == 101);
      std::cout << "The time series consists of " << pTimeSeries->getRecordedSteps() << "." << std::endl;
      std::cout << "Each step contains " << pTimeSeries->getNumVariables() << " variables." << std::endl;
      std::cout << "The final state is: " << std::endl;
      iMax = pTimeSeries->getNumVariables();
      size_t lastIndex = pTimeSeries->getRecordedSteps() - 1;

      for (i = 0; i < iMax; ++i)
        {
          // here we get the particle number (at least for the species)
          // the unit of the other variables may not be particle numbers
          // the concentration data can be acquired with getConcentrationData
          std::cout << pTimeSeries->getTitle(i) << ": " << pTimeSeries->getData(lastIndex, i) << std::endl;
        }
    }
  else
    {
      std::cerr << "Usage: example3 SBMLFILE" << std::endl;
      CCopasiRootContainer::destroy();
      return 1;
    }

  // clean up the library
  CCopasiRootContainer::destroy();
}