COPASI API  4.16.103
test000075.cpp
Go to the documentation of this file.
1 // Begin CVS Header
2 // $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/sbml/unittests/test000075.cpp,v $
3 // $Revision: 1.10 $
4 // $Name: $
5 // $Author: gauges $
6 // $Date: 2010/03/11 11:52:00 $
7 // End CVS Header
8 
9 // Copyright (C) 2010 by Pedro Mendes, Virginia Tech Intellectual
10 // Properties, Inc., University of Heidelberg, and The University
11 // of Manchester.
12 // All rights reserved.
13 
14 // Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
15 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
16 // and The University of Manchester.
17 // All rights reserved.
18 
19 #include "test000075.h"
20 
21 #include <string>
22 #include <vector>
23 
25 #include "copasi/model/CModel.h"
28 #include "copasi/model/CMetab.h"
29 #include "copasi/model/CReaction.h"
30 #include "copasi/model/CEvent.h"
38 
39 #include "sbml/SBMLDocument.h"
40 #include "sbml/Model.h"
41 #include "sbml/FunctionDefinition.h"
42 #include "sbml/math/ASTNode.h"
43 #include "sbml/Rule.h"
44 #include "sbml/KineticLaw.h"
45 #include "sbml/Reaction.h"
46 #include "sbml/InitialAssignment.h"
47 #include "sbml/Event.h"
48 #include "sbml/Trigger.h"
49 #include "sbml/EventAssignment.h"
50 
52 
53 /**
54  * Test if importing function definitions which are explicitely time dependent
55  * works.
56  * Problems related to this are also tracked in Bug 1093.
57  * This test also covers the bugs described there.
58  */
59 CCopasiDataModel* test000075::pCOPASIDATAMODEL = NULL;
60 
62 {
63  // Create the root container.
64  CCopasiRootContainer::init(0, NULL, false);
65  // Create the global data model.
67 }
68 
70 {
72 }
73 
75 {
76  CCopasiDataModel* pDataModel = pCOPASIDATAMODEL;
77  CPPUNIT_ASSERT(pDataModel->importSBMLFromString(MODEL_STRING1));
78  // there have to be 2 function definitions, 1 compartment, 4 species, 4
79  // parameters, 1 reaction, 1 initial assignment, 5 rules (2 rate + 2
80  // assignment) and 1 event
81  const CModel* pCModel = pCOPASIDATAMODEL->getModel();
82  CPPUNIT_ASSERT(pCModel != NULL);
83  CPPUNIT_ASSERT(pCModel->getCompartments().size() == 1);
84  const CCompartment* pCCompartment = pCModel->getCompartments()[0];
85  CPPUNIT_ASSERT(pCCompartment != NULL);
86  CPPUNIT_ASSERT(pCCompartment->getStatus() == CModelEntity::FIXED);
87  const CEvaluationNodeObject* pCObjectNode = NULL;
88  const CRegisteredObjectName* pCObjectName = NULL;
89  std::vector<CCopasiContainer*> listOfContainers;
90  listOfContainers.push_back(pCOPASIDATAMODEL->getModel());
91  const CCopasiObject* pCObject = NULL;
92 
93  CPPUNIT_ASSERT(pCModel->getMetabolites().size() == 4);
94  // get species_1 and species_2 those two should have rules defined
95  const CMetab* pCSpecies1 = NULL;
96  const CMetab* pCSpecies2 = NULL;
97  unsigned int i, iMax = pCModel->getMetabolites().size();
98 
99  for (i = 0; i < iMax; ++i)
100  {
101  if (pCModel->getMetabolites()[i]->getObjectName() == std::string("species_1"))
102  {
103  pCSpecies1 = pCModel->getMetabolites()[i];
104  }
105  else if (pCModel->getMetabolites()[i]->getObjectName() == std::string("species_2"))
106  {
107  pCSpecies2 = pCModel->getMetabolites()[i];
108  }
109  }
110 
111  CPPUNIT_ASSERT(pCSpecies1 != NULL);
112  CPPUNIT_ASSERT(pCSpecies1->getStatus() == CModelEntity::ASSIGNMENT);
113  const CExpression* pCExpression = pCSpecies1->getExpressionPtr();
114  CPPUNIT_ASSERT(pCExpression != NULL);
115  const CEvaluationNode* pCRoot = pCExpression->getRoot();
116  CPPUNIT_ASSERT(pCRoot != NULL);
117  CPPUNIT_ASSERT(CEvaluationNode::type(pCRoot->getType()) == CEvaluationNode::CALL);
118  const CEvaluationNodeCall* pCCallNode = dynamic_cast<const CEvaluationNodeCall*>(pCRoot);
119  CPPUNIT_ASSERT(pCCallNode != NULL);
120  CPPUNIT_ASSERT(pCCallNode->getData() == std::string("time_dependent"));
121  // the first child is a number
122  const CEvaluationNode* pCChild1 = dynamic_cast<const CEvaluationNode*>(pCCallNode->getChild());
123  CPPUNIT_ASSERT(pCChild1 != NULL);
124  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild1->getType()) == CEvaluationNode::NUMBER);
125  // the second node must be an object node that points to the model
126  const CEvaluationNode* pCChild2 = dynamic_cast<const CEvaluationNode*>(pCChild1->getSibling());
127  CPPUNIT_ASSERT(pCChild2 != NULL);
128  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild2->getType()) == CEvaluationNode::OBJECT);
129  pCObjectNode = dynamic_cast<const CEvaluationNodeObject*>(pCChild2);
130  CPPUNIT_ASSERT(pCObjectNode != NULL);
131  pCObjectName = &pCObjectNode->getObjectCN();
132  pCObject = pCOPASIDATAMODEL->ObjectFromName(listOfContainers, *pCObjectName);
133  CPPUNIT_ASSERT(pCObject != NULL);
134  CPPUNIT_ASSERT(pCObject->isReference() == true);
135  CPPUNIT_ASSERT(pCObject->getObjectName() == std::string("Time"));
136  CPPUNIT_ASSERT(pCObject->getObjectParent() == pCModel);
137 
138  CPPUNIT_ASSERT(pCSpecies2 != NULL);
139  CPPUNIT_ASSERT(pCSpecies2->getStatus() == CModelEntity::ODE);
140  pCExpression = pCSpecies2->getExpressionPtr();
141  CPPUNIT_ASSERT(pCExpression != NULL);
142  pCRoot = pCExpression->getRoot();
143  CPPUNIT_ASSERT(pCRoot != NULL);
144  CPPUNIT_ASSERT(CEvaluationNode::type(pCRoot->getType()) == CEvaluationNode::CALL);
145  pCCallNode = dynamic_cast<const CEvaluationNodeCall*>(pCRoot);
146  CPPUNIT_ASSERT(pCCallNode != NULL);
147  CPPUNIT_ASSERT(pCCallNode->getData() == std::string("time_dependent"));
148  // the first child is a number
149  pCChild1 = dynamic_cast<const CEvaluationNode*>(pCCallNode->getChild());
150  CPPUNIT_ASSERT(pCChild1 != NULL);
151  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild1->getType()) == CEvaluationNode::NUMBER);
152  // the second node must be an object node that points to the model
153  pCChild2 = dynamic_cast<const CEvaluationNode*>(pCChild1->getSibling());
154  CPPUNIT_ASSERT(pCChild2 != NULL);
155  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild2->getType()) == CEvaluationNode::OBJECT);
156  pCObjectNode = dynamic_cast<const CEvaluationNodeObject*>(pCChild2);
157  CPPUNIT_ASSERT(pCObjectNode != NULL);
158  pCObjectName = &pCObjectNode->getObjectCN();
159  pCObject = pCOPASIDATAMODEL->ObjectFromName(listOfContainers, *pCObjectName);
160  CPPUNIT_ASSERT(pCObject != NULL);
161  CPPUNIT_ASSERT(pCObject->isReference() == true);
162  CPPUNIT_ASSERT(pCObject->getObjectName() == std::string("Time"));
163  CPPUNIT_ASSERT(pCObject->getObjectParent() == pCModel);
164 
165  CPPUNIT_ASSERT(pCModel->getModelValues().size() == 5);
166  // check parameter_1 and parameter_2 which have rules defined
167  // also check parameter_4 und parameter_5 which have initial assignments
168  const CModelValue* pCModelValue1 = NULL;
169  const CModelValue* pCModelValue2 = NULL;
170  const CModelValue* pCModelValue4 = NULL;
171  const CModelValue* pCModelValue5 = NULL;
172  iMax = pCModel->getModelValues().size();
173 
174  for (i = 0; i < iMax; ++i)
175  {
176  if (pCModel->getModelValues()[i]->getObjectName() == std::string("parameter_1"))
177  {
178  pCModelValue1 = pCModel->getModelValues()[i];
179  }
180  else if (pCModel->getModelValues()[i]->getObjectName() == std::string("parameter_2"))
181  {
182  pCModelValue2 = pCModel->getModelValues()[i];
183  }
184  else if (pCModel->getModelValues()[i]->getObjectName() == std::string("parameter_4"))
185  {
186  pCModelValue4 = pCModel->getModelValues()[i];
187  }
188  else if (pCModel->getModelValues()[i]->getObjectName() == std::string("parameter_5"))
189  {
190  pCModelValue5 = pCModel->getModelValues()[i];
191  }
192  }
193 
194  CPPUNIT_ASSERT(pCModelValue1 != NULL);
195  CPPUNIT_ASSERT(pCModelValue1->getStatus() == CModelEntity::ASSIGNMENT);
196  pCExpression = pCModelValue1->getExpressionPtr();
197  CPPUNIT_ASSERT(pCExpression != NULL);
198  pCRoot = pCExpression->getRoot();
199  CPPUNIT_ASSERT(pCRoot != NULL);
200  CPPUNIT_ASSERT(CEvaluationNode::type(pCRoot->getType()) == CEvaluationNode::CALL);
201  pCCallNode = dynamic_cast<const CEvaluationNodeCall*>(pCRoot);
202  CPPUNIT_ASSERT(pCCallNode != NULL);
203  CPPUNIT_ASSERT(pCCallNode->getData() == std::string("time_dependent"));
204  // the first child is a number
205  pCChild1 = dynamic_cast<const CEvaluationNode*>(pCCallNode->getChild());
206  CPPUNIT_ASSERT(pCChild1 != NULL);
207  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild1->getType()) == CEvaluationNode::NUMBER);
208  // the second node must be an object node that points to the model
209  pCChild2 = dynamic_cast<const CEvaluationNode*>(pCChild1->getSibling());
210  CPPUNIT_ASSERT(pCChild2 != NULL);
211  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild2->getType()) == CEvaluationNode::OBJECT);
212  pCObjectNode = dynamic_cast<const CEvaluationNodeObject*>(pCChild2);
213  CPPUNIT_ASSERT(pCObjectNode != NULL);
214  pCObjectName = &pCObjectNode->getObjectCN();
215  pCObject = pCOPASIDATAMODEL->ObjectFromName(listOfContainers, *pCObjectName);
216  CPPUNIT_ASSERT(pCObject != NULL);
217  CPPUNIT_ASSERT(pCObject->isReference() == true);
218  CPPUNIT_ASSERT(pCObject->getObjectName() == std::string("Time"));
219  CPPUNIT_ASSERT(pCObject->getObjectParent() == pCModel);
220 
221  CPPUNIT_ASSERT(pCModelValue2 != NULL);
222  CPPUNIT_ASSERT(pCModelValue2->getStatus() == CModelEntity::ODE);
223  pCExpression = pCModelValue2->getExpressionPtr();
224  CPPUNIT_ASSERT(pCExpression != NULL);
225  pCRoot = pCExpression->getRoot();
226  CPPUNIT_ASSERT(pCRoot != NULL);
227  CPPUNIT_ASSERT(CEvaluationNode::type(pCRoot->getType()) == CEvaluationNode::CALL);
228  pCCallNode = dynamic_cast<const CEvaluationNodeCall*>(pCRoot);
229  CPPUNIT_ASSERT(pCCallNode != NULL);
230  CPPUNIT_ASSERT(pCCallNode->getData() == std::string("time_dependent"));
231  // the first child is a number
232  pCChild1 = dynamic_cast<const CEvaluationNode*>(pCCallNode->getChild());
233  CPPUNIT_ASSERT(pCChild1 != NULL);
234  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild1->getType()) == CEvaluationNode::NUMBER);
235  // the second node must be an object node that points to the model
236  pCChild2 = dynamic_cast<const CEvaluationNode*>(pCChild1->getSibling());
237  CPPUNIT_ASSERT(pCChild2 != NULL);
238  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild2->getType()) == CEvaluationNode::OBJECT);
239  pCObjectNode = dynamic_cast<const CEvaluationNodeObject*>(pCChild2);
240  CPPUNIT_ASSERT(pCObjectNode != NULL);
241  pCObjectName = &pCObjectNode->getObjectCN();
242  pCObject = pCOPASIDATAMODEL->ObjectFromName(listOfContainers, *pCObjectName);
243  CPPUNIT_ASSERT(pCObject != NULL);
244  CPPUNIT_ASSERT(pCObject->isReference() == true);
245  CPPUNIT_ASSERT(pCObject->getObjectName() == std::string("Time"));
246  CPPUNIT_ASSERT(pCObject->getObjectParent() == pCModel);
247 
248  CPPUNIT_ASSERT(pCModelValue4 != NULL);
249  CPPUNIT_ASSERT(pCModelValue4->getStatus() == CModelEntity::FIXED);
250  pCExpression = pCModelValue4->getInitialExpressionPtr();
251  CPPUNIT_ASSERT(pCExpression != NULL);
252  pCRoot = pCExpression->getRoot();
253  CPPUNIT_ASSERT(pCRoot != NULL);
254  CPPUNIT_ASSERT(CEvaluationNode::type(pCRoot->getType()) == CEvaluationNode::CALL);
255  pCCallNode = dynamic_cast<const CEvaluationNodeCall*>(pCRoot);
256  CPPUNIT_ASSERT(pCCallNode != NULL);
257  CPPUNIT_ASSERT(pCCallNode->getData() == std::string("time_dependent"));
258  // the first child is a number
259  pCChild1 = dynamic_cast<const CEvaluationNode*>(pCCallNode->getChild());
260  CPPUNIT_ASSERT(pCChild1 != NULL);
261  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild1->getType()) == CEvaluationNode::NUMBER);
262  // the second node must be an object node that points to the model
263  pCChild2 = dynamic_cast<const CEvaluationNode*>(pCChild1->getSibling());
264  CPPUNIT_ASSERT(pCChild2 != NULL);
265  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild2->getType()) == CEvaluationNode::OBJECT);
266  pCObjectNode = dynamic_cast<const CEvaluationNodeObject*>(pCChild2);
267  CPPUNIT_ASSERT(pCObjectNode != NULL);
268  pCObjectName = &pCObjectNode->getObjectCN();
269  pCObject = pCOPASIDATAMODEL->ObjectFromName(listOfContainers, *pCObjectName);
270  CPPUNIT_ASSERT(pCObject != NULL);
271  CPPUNIT_ASSERT(pCObject->isReference() == true);
272  CPPUNIT_ASSERT(pCObject->getObjectName() == std::string("Initial Time"));
273  CPPUNIT_ASSERT(pCObject->getObjectParent() == pCModel);
274 
275  CPPUNIT_ASSERT(pCModelValue5 != NULL);
276  CPPUNIT_ASSERT(pCModelValue5->getStatus() == CModelEntity::FIXED);
277  pCExpression = pCModelValue5->getInitialExpressionPtr();
278  CPPUNIT_ASSERT(pCExpression != NULL);
279  pCRoot = pCExpression->getRoot();
280  CPPUNIT_ASSERT(pCRoot != NULL);
281  CPPUNIT_ASSERT(CEvaluationNode::type(pCRoot->getType()) == CEvaluationNode::CALL);
282  pCCallNode = dynamic_cast<const CEvaluationNodeCall*>(pCRoot);
283  CPPUNIT_ASSERT(pCCallNode != NULL);
284  // the first child is a number node
285  CPPUNIT_ASSERT(pCCallNode->getData() == std::string("indirectly_time_dependent"));
286  pCChild1 = dynamic_cast<const CEvaluationNode*>(pCCallNode->getChild());
287  CPPUNIT_ASSERT(pCChild1 != NULL);
288  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild1->getType()) == CEvaluationNode::NUMBER);
289 
290  // the second child is the time object
291  pCChild2 = dynamic_cast<const CEvaluationNode*>(pCChild1->getSibling());
292  CPPUNIT_ASSERT(pCChild2 != NULL);
293  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild2->getType()) == CEvaluationNode::OBJECT);
294  pCObjectNode = dynamic_cast<const CEvaluationNodeObject*>(pCChild2);
295  CPPUNIT_ASSERT(pCObjectNode != NULL);
296  pCObjectName = &pCObjectNode->getObjectCN();
297  pCObject = pCOPASIDATAMODEL->ObjectFromName(listOfContainers, *pCObjectName);
298  CPPUNIT_ASSERT(pCObject != NULL);
299  CPPUNIT_ASSERT(pCObject->isReference() == true);
300  CPPUNIT_ASSERT(pCObject->getObjectName() == std::string("Initial Time"));
301  CPPUNIT_ASSERT(pCObject->getObjectParent() == pCModel);
302 
303  CPPUNIT_ASSERT(pCModel->getReactions().size() == 1);
304  const CReaction* pCReaction = pCModel->getReactions()[0];
305  CPPUNIT_ASSERT(pCReaction != NULL);
306  CPPUNIT_ASSERT(pCReaction->isReversible() == false);
307  const CChemEq& chemEq = pCReaction->getChemEq();
308  CPPUNIT_ASSERT(chemEq.getSubstrates().size() == 1);
309  CPPUNIT_ASSERT(chemEq.getProducts().size() == 1);
310  CPPUNIT_ASSERT(chemEq.getModifiers().size() == 0);
311  const CFunction* pCFunction = pCReaction->getFunction();
312  CPPUNIT_ASSERT(pCFunction != NULL);
313  pCRoot = pCFunction->getRoot();
314  CPPUNIT_ASSERT(pCRoot != NULL);
315  CPPUNIT_ASSERT(CEvaluationNode::type(pCRoot->getType()) == CEvaluationNode::CALL);
316  pCCallNode = dynamic_cast<const CEvaluationNodeCall*>(pCRoot);
317  CPPUNIT_ASSERT(pCCallNode != NULL);
318  CPPUNIT_ASSERT(pCCallNode->getData() == std::string("time_dependent"));
319  // the first child is a number
320  pCChild1 = dynamic_cast<const CEvaluationNode*>(pCCallNode->getChild());
321  CPPUNIT_ASSERT(pCChild1 != NULL);
322  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild1->getType()) == CEvaluationNode::NUMBER);
323  // the second node must be an object node that points to the model
324  pCChild2 = dynamic_cast<const CEvaluationNode*>(pCChild1->getSibling());
325  CPPUNIT_ASSERT(pCChild2 != NULL);
326  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild2->getType()) == CEvaluationNode::VARIABLE);
327  // get the argument for this variable
328  std::string variableName = pCChild2->getData();
329  const std::vector<std::string>& parameterMapping = pCReaction->getParameterMapping(variableName);
330  CPPUNIT_ASSERT(parameterMapping.size() == 1);
331  std::string objectKey = parameterMapping[0];
332  CPPUNIT_ASSERT(!objectKey.empty());
333  pCObject = CCopasiRootContainer::getKeyFactory()->get(objectKey);
334  CPPUNIT_ASSERT(pCObject != NULL);
335  CPPUNIT_ASSERT(pCObject == pCModel);
336 
337  // events
338  CPPUNIT_ASSERT(pCModel->getEvents().size() == 1);
339  const CEvent* pCEvent = pCModel->getEvents()[0];
340  CPPUNIT_ASSERT(pCEvent != NULL);
341  // event trigger functionDefinition1(5.0,TIME) > 2.0
342  pCExpression = pCEvent->getTriggerExpressionPtr();
343  CPPUNIT_ASSERT(pCExpression != NULL);
344  pCRoot = pCExpression->getRoot();
345  CPPUNIT_ASSERT(pCRoot != NULL);
346  // root must be the gt operator
347  CPPUNIT_ASSERT(CEvaluationNode::type(pCRoot->getType()) == CEvaluationNode::LOGICAL);
349  pCChild1 = dynamic_cast<const CEvaluationNode*>(pCRoot->getChild());
350  CPPUNIT_ASSERT(pCChild1 != NULL);
351  // first child must be the changed call
352  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild1->getType()) == CEvaluationNode::CALL);
353  pCCallNode = dynamic_cast<const CEvaluationNodeCall*>(pCChild1);
354  CPPUNIT_ASSERT(pCCallNode != NULL);
355  CPPUNIT_ASSERT(pCCallNode->getData() == std::string("time_dependent"));
356  // the first child is a number
357  pCChild1 = dynamic_cast<const CEvaluationNode*>(pCCallNode->getChild());
358  CPPUNIT_ASSERT(pCChild1 != NULL);
359  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild1->getType()) == CEvaluationNode::NUMBER);
360  // the second node must be an object node that points to the model
361  pCChild2 = dynamic_cast<const CEvaluationNode*>(pCChild1->getSibling());
362  CPPUNIT_ASSERT(pCChild2 != NULL);
363  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild2->getType()) == CEvaluationNode::OBJECT);
364  pCObjectNode = dynamic_cast<const CEvaluationNodeObject*>(pCChild2);
365  CPPUNIT_ASSERT(pCObjectNode != NULL);
366  pCObjectName = &pCObjectNode->getObjectCN();
367  pCObject = pCOPASIDATAMODEL->ObjectFromName(listOfContainers, *pCObjectName);
368  CPPUNIT_ASSERT(pCObject != NULL);
369  CPPUNIT_ASSERT(pCObject->isReference() == true);
370  CPPUNIT_ASSERT(pCObject->getObjectName() == std::string("Time"));
371  CPPUNIT_ASSERT(pCObject->getObjectParent() == pCModel);
372  //
373  // second child must be a number
374  pCChild2 = dynamic_cast<const CEvaluationNode*>(pCRoot->getChild()->getSibling());
375  CPPUNIT_ASSERT(pCChild2 != NULL);
376  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild2->getType()) == CEvaluationNode::NUMBER);
377 
378  // event assignment
379  CPPUNIT_ASSERT(pCEvent->getAssignments().size() == 1);
380  pCExpression = pCEvent->getAssignments()[0]->getExpressionPtr();
381  CPPUNIT_ASSERT(pCExpression != NULL);
382  pCRoot = pCExpression->getRoot();
383  CPPUNIT_ASSERT(pCRoot != NULL);
384  CPPUNIT_ASSERT(CEvaluationNode::type(pCRoot->getType()) == CEvaluationNode::CALL);
385  pCCallNode = dynamic_cast<const CEvaluationNodeCall*>(pCRoot);
386  CPPUNIT_ASSERT(pCCallNode != NULL);
387  CPPUNIT_ASSERT(pCCallNode->getData() == std::string("time_dependent"));
388  // the first child is a number
389  pCChild1 = dynamic_cast<const CEvaluationNode*>(pCCallNode->getChild());
390  CPPUNIT_ASSERT(pCChild1 != NULL);
391  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild1->getType()) == CEvaluationNode::NUMBER);
392  // the second node must be an object node that points to the model
393  pCChild2 = dynamic_cast<const CEvaluationNode*>(pCChild1->getSibling());
394  CPPUNIT_ASSERT(pCChild2 != NULL);
395  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild2->getType()) == CEvaluationNode::OBJECT);
396  pCObjectNode = dynamic_cast<const CEvaluationNodeObject*>(pCChild2);
397  CPPUNIT_ASSERT(pCObjectNode != NULL);
398  pCObjectName = &pCObjectNode->getObjectCN();
399  pCObject = pCOPASIDATAMODEL->ObjectFromName(listOfContainers, *pCObjectName);
400  CPPUNIT_ASSERT(pCObject != NULL);
401  CPPUNIT_ASSERT(pCObject->isReference() == true);
402  CPPUNIT_ASSERT(pCObject->getObjectName() == std::string("Time"));
403  CPPUNIT_ASSERT(pCObject->getObjectParent() == pCModel);
404 
405  // check if the function definitions are imported correctly
407  CPPUNIT_ASSERT(pFunctionDB != NULL);
408  const CEvaluationTree* pCTree = pFunctionDB->findFunction("time_dependent");
409  CPPUNIT_ASSERT(pCTree != NULL);
410  pCFunction = dynamic_cast<const CFunction*>(pCTree);
411  CPPUNIT_ASSERT(pCFunction != NULL);
412  // should have two parameters instead of one
413  CPPUNIT_ASSERT(pCFunction->getVariables().size() == 2);
414  pCRoot = pCFunction->getRoot();
415  CPPUNIT_ASSERT(CEvaluationNode::type(pCRoot->getType()) == CEvaluationNode::OPERATOR);
417  pCChild1 = dynamic_cast<const CEvaluationNode*>(pCRoot->getChild());
418  CPPUNIT_ASSERT(pCChild1 != NULL);
419  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild1->getType()) == CEvaluationNode::VARIABLE);
420  pCChild2 = dynamic_cast<const CEvaluationNode*>(pCChild1->getSibling());
421  CPPUNIT_ASSERT(pCChild2 != NULL);
422  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild2->getType()) == CEvaluationNode::VARIABLE);
423  CPPUNIT_ASSERT(pCChild2->getSibling() == NULL);
424 
425  pCTree = pFunctionDB->findFunction("indirectly_time_dependent");
426  CPPUNIT_ASSERT(pCTree != NULL);
427  pCFunction = dynamic_cast<const CFunction*>(pCTree);
428  CPPUNIT_ASSERT(pCFunction != NULL);
429  // should have two parameters instead of one
430  CPPUNIT_ASSERT(pCFunction->getVariables().size() == 2);
431  pCRoot = pCFunction->getRoot();
432  CPPUNIT_ASSERT(CEvaluationNode::type(pCRoot->getType()) == CEvaluationNode::CALL);
433  pCChild1 = dynamic_cast<const CEvaluationNode*>(pCRoot->getChild());
434  CPPUNIT_ASSERT(pCChild1 != NULL);
435  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild1->getType()) == CEvaluationNode::VARIABLE);
436  pCChild2 = dynamic_cast<const CEvaluationNode*>(pCChild1->getSibling());
437  CPPUNIT_ASSERT(pCChild2 != NULL);
438  CPPUNIT_ASSERT(CEvaluationNode::type(pCChild2->getType()) == CEvaluationNode::VARIABLE);
439  CPPUNIT_ASSERT(pCChild2->getSibling() == NULL);
440 
441  // make sure that the function definitions and all function calls in the
442  // original SBML model are unmodified
443  //
444  const SBMLDocument* pSBMLDocument = pCOPASIDATAMODEL->getCurrentSBMLDocument();
445  CPPUNIT_ASSERT(pSBMLDocument != NULL);
446  const Model* pModel = pSBMLDocument->getModel();
447  CPPUNIT_ASSERT(pModel != NULL);
448  iMax = pModel->getNumFunctionDefinitions();
449  CPPUNIT_ASSERT(iMax == 2);
450  const FunctionDefinition* pFunctionDefinition1 = NULL;
451  const FunctionDefinition* pFunctionDefinition2 = NULL;
452 
453  for (i = 0; i < iMax; ++i)
454  {
455  if (pModel->getFunctionDefinition(i)->getId() == std::string("functionDefinition_1"))
456  {
457  pFunctionDefinition1 = pModel->getFunctionDefinition(i);
458  }
459  else if (pModel->getFunctionDefinition(i)->getId() == std::string("functionDefinition_2"))
460  {
461  pFunctionDefinition2 = pModel->getFunctionDefinition(i);
462  }
463  }
464 
465  CPPUNIT_ASSERT(pFunctionDefinition1 != NULL);
466  CPPUNIT_ASSERT(pFunctionDefinition1->getNumArguments() == 1);
467  const ASTNode* pRoot = pFunctionDefinition1->getMath();
468  CPPUNIT_ASSERT(pRoot != NULL);
469  // the expression is the last child
470  CPPUNIT_ASSERT(pRoot->getNumChildren() == 2);
471  pRoot = pRoot->getChild(1);
472  CPPUNIT_ASSERT(pRoot != NULL);
473  CPPUNIT_ASSERT(pRoot->getType() == AST_TIMES);
474  CPPUNIT_ASSERT(pRoot->getNumChildren() == 2);
475  CPPUNIT_ASSERT(pRoot->getChild(0)->getType() == AST_NAME_TIME);
476  CPPUNIT_ASSERT(pRoot->getChild(1)->getType() == AST_NAME);
477  // second function definition
478  CPPUNIT_ASSERT(pFunctionDefinition2 != NULL);
479  CPPUNIT_ASSERT(pFunctionDefinition2->getNumArguments() == 1);
480  pRoot = pFunctionDefinition2->getMath();
481  CPPUNIT_ASSERT(pRoot != NULL);
482  // the expression is the last child
483  CPPUNIT_ASSERT(pRoot->getNumChildren() == 2);
484  pRoot = pRoot->getChild(1);
485  CPPUNIT_ASSERT(pRoot != NULL);
486  CPPUNIT_ASSERT(pRoot->getType() == AST_FUNCTION);
487  CPPUNIT_ASSERT(pRoot->getNumChildren() == 1);
488  CPPUNIT_ASSERT(pRoot->getChild(0)->getType() == AST_NAME);
489  CPPUNIT_ASSERT(pRoot->getChild(0)->getName() == std::string("n"));
490 
491  // initial assignment
492  iMax = pModel->getListOfInitialAssignments()->size();
493  CPPUNIT_ASSERT(iMax == 2);
494  const InitialAssignment* pInitialAssignment1 = NULL;
495  const InitialAssignment* pInitialAssignment2 = NULL;
496 
497  for (i = 0; i < iMax; ++i)
498  {
499  if (pModel->getInitialAssignment(i)->getSymbol() == std::string("parameter_4"))
500  {
501  pInitialAssignment1 = pModel->getInitialAssignment(i);
502  }
503  else if (pModel->getInitialAssignment(i)->getSymbol() == std::string("parameter_5"))
504  {
505  pInitialAssignment2 = pModel->getInitialAssignment(i);
506  }
507  }
508 
509  CPPUNIT_ASSERT(pInitialAssignment1 != NULL);
510  pRoot = pInitialAssignment1->getMath();
511  CPPUNIT_ASSERT(pRoot->getType() == AST_FUNCTION);
512  CPPUNIT_ASSERT(pRoot->getName() == std::string("functionDefinition_1"));
513  CPPUNIT_ASSERT(pRoot->getNumChildren() == 1);
514  CPPUNIT_ASSERT(pRoot->getChild(0)->getType() == AST_REAL);
515 
516  CPPUNIT_ASSERT(pInitialAssignment2 != NULL);
517  pRoot = pInitialAssignment2->getMath();
518  CPPUNIT_ASSERT(pRoot->getType() == AST_FUNCTION);
519  CPPUNIT_ASSERT(pRoot->getName() == std::string("functionDefinition_2"));
520  CPPUNIT_ASSERT(pRoot->getNumChildren() == 1);
521  CPPUNIT_ASSERT(pRoot->getChild(0)->getType() == AST_REAL);
522 
523  // rules
524  iMax = pModel->getListOfRules()->size();
525  CPPUNIT_ASSERT(iMax == 4);
526 
527  for (i = 0; i < iMax; ++i)
528  {
529  // only check the expression
530  // in this test we don't care if the variable is correct and if the rule
531  // type is correct
532  const Rule* pRule = pModel->getRule(i);
533  CPPUNIT_ASSERT(pRule != NULL);
534  pRoot = pRule->getMath();
535  CPPUNIT_ASSERT(pRoot != NULL);
536  CPPUNIT_ASSERT(pRoot->getType() == AST_FUNCTION);
537  CPPUNIT_ASSERT(pRoot->getNumChildren() == 1);
538  CPPUNIT_ASSERT(pRoot->getChild(0)->getType() == AST_REAL);
539  }
540 
541  // reaction
542  CPPUNIT_ASSERT(pModel->getListOfReactions()->size() == 1);
543  const Reaction* pReaction = pModel->getReaction(0);
544  CPPUNIT_ASSERT(pReaction != NULL);
545  const KineticLaw* pKineticLaw = pReaction->getKineticLaw();
546  CPPUNIT_ASSERT(pKineticLaw != NULL);
547  pRoot = pKineticLaw->getMath();
548  CPPUNIT_ASSERT(pRoot != NULL);
549  // multiplication by compartment volume
550  CPPUNIT_ASSERT(pRoot->getType() == AST_TIMES);
551  CPPUNIT_ASSERT(pRoot->getNumChildren() == 2);
552  CPPUNIT_ASSERT(pRoot->getChild(0)->getType() == AST_NAME);
553  CPPUNIT_ASSERT(pRoot->getChild(1)->getType() == AST_FUNCTION);
554  pRoot = pRoot->getChild(1);
555  CPPUNIT_ASSERT(pRoot->getNumChildren() == 1);
556  CPPUNIT_ASSERT(pRoot->getChild(0)->getType() == AST_REAL);
557 
558  // event
559  CPPUNIT_ASSERT(pModel->getListOfEvents()->size() == 1);
560  const Event* pEvent = pModel->getEvent(0);
561  CPPUNIT_ASSERT(pEvent != NULL);
562  const Trigger* pTrigger = pEvent->getTrigger();
563  CPPUNIT_ASSERT(pTrigger != NULL);
564  pRoot = pTrigger->getMath();
565  CPPUNIT_ASSERT(pRoot != NULL);
566  // functionDefinition_1(5.0) > 2.0
567  CPPUNIT_ASSERT(pRoot->getType() == AST_RELATIONAL_GT);
568  CPPUNIT_ASSERT(pRoot->getNumChildren() == 2);
569  CPPUNIT_ASSERT(pRoot->getChild(1) != NULL);
570  CPPUNIT_ASSERT(pRoot->getChild(1)->getType() == AST_REAL);
571  CPPUNIT_ASSERT(pRoot->getChild(0) != NULL);
572  pRoot = pRoot->getChild(0);
573  CPPUNIT_ASSERT(pRoot != NULL);
574  CPPUNIT_ASSERT(pRoot->getType() == AST_FUNCTION);
575  CPPUNIT_ASSERT(pRoot->getNumChildren() == 1);
576  CPPUNIT_ASSERT(pRoot->getChild(0)->getType() == AST_REAL);
577 
578  CPPUNIT_ASSERT(pEvent->getListOfEventAssignments()->size() == 1);
579  const EventAssignment* pEventAssignment = pEvent->getEventAssignment(0);
580  CPPUNIT_ASSERT(pEventAssignment != NULL);
581  pRoot = pEventAssignment->getMath();
582  CPPUNIT_ASSERT(pRoot != NULL);
583  CPPUNIT_ASSERT(pRoot->getType() == AST_FUNCTION);
584  CPPUNIT_ASSERT(pRoot->getNumChildren() == 1);
585  CPPUNIT_ASSERT(pRoot->getChild(0)->getType() == AST_REAL);
586 }
587 
588 const char* test000075::MODEL_STRING1 =
589  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
590  "<sbml xmlns=\"http://www.sbml.org/sbml/level2/version2\" level=\"2\" version=\"2\">\n"
591  " <model id=\"model_1\" name=\"model_1\">\n"
592  " <notes>\n"
593  " <p xmlns=\"http://www.w3.org/1999/xhtml\">\n"
594  " This model contains an explicitly time dependent function definition.\n"
595  " On import in COPASI this should be converted to a function definition that has time as it's only argument.\n"
596  " All calls to this function must be replaced.\n"
597  " </p>\n"
598  " </notes>\n"
599  " <listOfFunctionDefinitions>\n"
600  " <functionDefinition id=\"functionDefinition_1\" name=\"time_dependent\">\n"
601  " <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n"
602  " <lambda>\n"
603  " <bvar>\n"
604  " <ci>p</ci>\n"
605  " </bvar>\n"
606  " <apply>\n"
607  " <times/>\n"
608  " <csymbol encoding=\"text\" definitionURL=\"http://www.sbml.org/sbml/symbols/time\"> time </csymbol>\n"
609  " <ci>p</ci>\n"
610  " </apply> \n"
611  " </lambda>\n"
612  " </math>\n"
613  " </functionDefinition>\n"
614  " <functionDefinition id=\"functionDefinition_2\" name=\"indirectly_time_dependent\">\n"
615  " <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n"
616  " <lambda>\n"
617  " <bvar>\n"
618  " <ci>n</ci>\n"
619  " </bvar>\n"
620  " <apply>\n"
621  " <ci> functionDefinition_1 </ci>\n"
622  " <ci> n </ci>\n"
623  " </apply>\n"
624  " </lambda>\n"
625  " </math>\n"
626  " </functionDefinition>\n"
627  " </listOfFunctionDefinitions>\n"
628  " <listOfCompartments>\n"
629  " <compartment id=\"compartment_1\" name=\"compartment_1\" size=\"1\" />\n"
630  " </listOfCompartments>\n"
631  " <listOfSpecies>\n"
632  " <species id=\"species_1\" name=\"species_1\" compartment=\"compartment_1\" initialConcentration=\"0.0\" />\n"
633  " <species id=\"species_2\" name=\"species_2\" compartment=\"compartment_1\" initialConcentration=\"0.0\" />\n"
634  " <species id=\"species_3\" name=\"species_3\" compartment=\"compartment_1\" initialConcentration=\"0.0\" />\n"
635  " <species id=\"species_4\" name=\"species_4\" compartment=\"compartment_1\" initialConcentration=\"0.0\" />\n"
636  " </listOfSpecies>\n"
637  " <listOfParameters>\n"
638  " <parameter id=\"parameter_1\" name=\"parameter_1\" constant=\"false\"/>\n"
639  " <parameter id=\"parameter_2\" name=\"parameter_2\" constant=\"false\"/>\n"
640  " <parameter id=\"parameter_3\" name=\"parameter_3\" constant=\"false\"/>\n"
641  " <parameter id=\"parameter_4\" name=\"parameter_4\" constant=\"true\"/>\n"
642  " <parameter id=\"parameter_5\" name=\"parameter_5\" constant=\"true\"/>\n"
643  " </listOfParameters>\n"
644  " <listOfInitialAssignments>\n"
645  " <initialAssignment symbol=\"parameter_4\">\n"
646  " <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n"
647  " <apply>\n"
648  " <ci> functionDefinition_1 </ci>\n"
649  " <cn> 5.0 </cn>\n"
650  " </apply>\n"
651  " </math>\n"
652  " </initialAssignment>\n"
653  " <initialAssignment symbol=\"parameter_5\">\n"
654  " <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n"
655  " <apply>\n"
656  " <ci> functionDefinition_2 </ci>\n"
657  " <cn> 3.2 </cn>\n"
658  " </apply>\n"
659  " </math>\n"
660  " </initialAssignment>\n"
661  " </listOfInitialAssignments>\n"
662  " <listOfRules>\n"
663  " <assignmentRule variable=\"parameter_1\">\n"
664  " <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n"
665  " <apply>\n"
666  " <ci> functionDefinition_1 </ci>\n"
667  " <cn> 5.0 </cn>\n"
668  " </apply>\n"
669  " </math>\n"
670  " </assignmentRule>\n"
671  " <rateRule variable=\"parameter_2\">\n"
672  " <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n"
673  " <apply>\n"
674  " <ci> functionDefinition_1 </ci>\n"
675  " <cn> 5.0 </cn>\n"
676  " </apply>\n"
677  " </math>\n"
678  " </rateRule>\n"
679  " <assignmentRule variable=\"species_1\">\n"
680  " <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n"
681  " <apply>\n"
682  " <ci> functionDefinition_1 </ci>\n"
683  " <cn> 5.0 </cn>\n"
684  " </apply>\n"
685  " </math>\n"
686  " </assignmentRule>\n"
687  " <rateRule variable=\"species_2\">\n"
688  " <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n"
689  " <apply>\n"
690  " <ci> functionDefinition_1 </ci>\n"
691  " <cn> 5.0 </cn>\n"
692  " </apply>\n"
693  " </math>\n"
694  " </rateRule>\n"
695  " </listOfRules>\n"
696  " <listOfReactions>\n"
697  " <reaction id=\"reaction_1\" name=\"reaction_1\" reversible=\"false\">\n"
698  " <listOfReactants>\n"
699  " <speciesReference species=\"species_3\"/>\n"
700  " </listOfReactants>\n"
701  " <listOfProducts>\n"
702  " <speciesReference species=\"species_4\"/>\n"
703  " </listOfProducts>\n"
704  " <kineticLaw>\n"
705  " <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n"
706  " <apply>\n"
707  " <times/>\n"
708  " <ci> compartment_1 </ci>\n"
709  " <apply>\n"
710  " <ci> functionDefinition_1 </ci>\n"
711  " <cn> 5.0 </cn>\n"
712  " </apply>\n"
713  " </apply>\n"
714  " </math>\n"
715  " </kineticLaw>\n"
716  " </reaction>\n"
717  " </listOfReactions>\n"
718  " <listOfEvents>\n"
719  " <event>\n"
720  " <trigger>\n"
721  " <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n"
722  " <apply>\n"
723  " <gt/>\n"
724  " <apply>\n"
725  " <ci> functionDefinition_1 </ci>\n"
726  " <cn> 5.0 </cn>\n"
727  " </apply>\n"
728  " <cn> 2.0 </cn>\n"
729  " </apply>\n"
730  " </math>\n"
731  " </trigger>\n"
732  " <listOfEventAssignments>\n"
733  " <eventAssignment variable=\"parameter_3\">\n"
734  " <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n"
735  " <apply>\n"
736  " <ci> functionDefinition_1 </ci>\n"
737  " <cn> 5.0 </cn>\n"
738  " </apply>\n"
739  " </math>\n"
740  " </eventAssignment>\n"
741  " </listOfEventAssignments>\n"
742  " </event>\n"
743  " </listOfEvents>\n"
744  " </model>\n"
745  "</sbml>\n"
746  ;
const CExpression * getExpressionPtr() const
Definition: CEvent.h:152
Header file of class CExpression.
SBMLDocument * getCurrentSBMLDocument()
Header file of class CModelEntity and CModelValue.
void test_import_time_dependent_function_definition()
Definition: test000075.cpp:74
static const char * MODEL_STRING1
Definition: test000075.h:34
void setUp()
Definition: test000075.cpp:61
const std::string & getObjectName() const
CCopasiObject * get(const std::string &key)
const Type & getType() const
Definition: CMetab.h:178
static CCopasiDataModel * pCOPASIDATAMODEL
Definition: test000075.h:35
static Type type(const Type &type)
virtual const Data & getData() const
bool isReference() const
static CFunctionDB * getFunctionList()
static CCopasiDataModel * addDatamodel()
static Type subType(const Type &type)
static CKeyFactory * getKeyFactory()
bool importSBMLFromString(const std::string &sbmlDocumentText, CProcessReport *pImportHandler=NULL, const bool &deleteOldData=true)
The class for handling a chemical kinetic function.
Definition: CFunction.h:29
static void init(int argc, char *argv[], const bool &withGui=false)
Definition: CModel.h:50
Header file of class CEvent.
virtual const Data & getData() const
Definition: CCopasiNode.h:118
const CModelEntity::Status & getStatus() const
void tearDown()
Definition: test000075.cpp:69
CCopasiNode< Data > * getChild()
Definition: CCopasiNode.h:210
CCopasiObject * ObjectFromName(const std::vector< CCopasiContainer * > &listOfContainer, const CCopasiObjectName &CN) const
CCopasiContainer * getObjectParent() const
const CExpression * getInitialExpressionPtr() const