COPASI API  4.16.103
CModelMerging.cpp
Go to the documentation of this file.
1 // Begin CVS Header
2 // $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/model/CModelMerging.cpp,v $
3 // $Revision: 1.18 $
4 // $Name: $
5 // $Author: shoops $
6 // $Date: 2011/03/14 19:19:37 $
7 // End CVS Header
8 
9 // Copyright (C) 2011 - 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 "CModelMerging.h"
20 #include "CModel.h"
21 #include "function/CExpression.h"
22 #include "report/CCopasiObject.h"
25 #include "model/CEvent.h"
26 #include "model/CChemEqElement.h"
27 
29  : mpModel(pModel), mmModel(mModel)
30 {
31 }
32 
33 void CModelAdd::setModel(CModel* pModel, CModel* mModel)
34 {
35  mpModel = pModel;
36  mmModel = mModel;
37 }
38 
40 {
41  if (!mpModel)
42  {
43  fatalError();
44  }
45 
46  if (!mmModel)
47  {
48  fatalError();
49  }
50 
52 
53  std::string name = "model_2"; // temporary we do not take care about naming conflicts.
54  // : "model_2" is the appendix for the names of compartments and reactions,
55  // comming form the second model
56 
57  bool progress = addCompartments(name)
58  && addMetabolites(name)
59  && addModelValues(name)
63  && addReactions(name)
64  && addEvents(name);
65 
66  if (!progress)
67  {
69  return;
70  }
71 
73 }
74 
75 bool CModelAdd::addEvents(std::string name)
76 {
77 
78  bool info = false;
79 
80  size_t i, imax = mmModel->getEvents().size();
81 
82  for (i = 0; i < imax; ++i)
83  {
84  const CEvent* sourceEvent = mmModel->getEvents()[i];
85 
86  if (!sourceEvent) return info;
87 
88  //create new event
89 
90  std::string eventName;
91 
92  eventName = sourceEvent->getObjectName();
93 
94  std::string appendix = "";
95 #if 0
96  unsigned int counter = 2;
97  std::ostringstream numberStream;
98 
99  while (mpModel->getEvents().getIndex(eventName + appendix) != C_INVALID_INDEX)
100  {
101  numberStream.str("");
102  numberStream << "_" << counter;
103  counter++;
104  appendix = numberStream.str();
105  }
106 
107 #else
108  appendix = "_" + name;
109 #endif
110 
111  CEvent* newEvent = mpModel->createEvent(eventName + appendix);
112 
113  if (newEvent == NULL) return info;
114 
115  /* copy trigger expression */
116 
117  if (sourceEvent->getTriggerExpressionPtr() != NULL)
118  {
119  if (!copyTriggerExpression(sourceEvent, newEvent))
120  return info;
121  }
122  else
123  {
124  return info;
125  }
126 
127  /* set whether the calculation or the assignment shall be delayed */
128 
129  newEvent->setDelayAssignment(sourceEvent->getDelayAssignment());
130 
131  /* copy the delay expression */
132 
133  if (sourceEvent->getDelayExpressionPtr() != NULL)
134  if (!copyDelayExpression(sourceEvent, newEvent)) return info;
135 
136  /* copy the assignments */
137 
138  size_t j, jmax = sourceEvent->getAssignments().size();
139 
140  for (j = 0; j < jmax; ++j)
141  {
142  const CEventAssignment* sourceAssignment = sourceEvent->getAssignments()[j];
143 
144  if (!sourceAssignment) return info;
145 
146  std::string key = sourceAssignment->getTargetKey();
147 
148  CEventAssignment* newAssignment = new CEventAssignment;
149 
150  newEvent->getAssignments().add(newAssignment, true);
151 
152  newAssignment->setTargetKey(keyMap[key]);
153 
154  if (sourceAssignment->getExpressionPtr() != NULL)
155  {
156  if (!copyEventAssignmentExpression(sourceAssignment, newAssignment))
157  return info;
158  }
159  else
160  {
161  return info;
162  }
163  }
164  }
165 
166  return true;
167 }
168 bool CModelAdd::copyEventAssignmentExpression(const CEventAssignment * sourceAssignment, CEventAssignment * newAssignment)
169 {
170 
171  bool info = false;
172 
173  const CExpression* pExpression = sourceAssignment->getExpressionPtr();
174 
175  if (pExpression == NULL) return info;
176 
177  CExpression* tmp;
178  tmp = new CExpression(*pExpression, mmModel);
179 
180  const std::vector<CEvaluationNode*>& objectNodes = tmp->getNodeList();
181  size_t j, jmax = objectNodes.size();
182 
183  for (j = 0; j < jmax; ++j)
184  {
185  if (CEvaluationNode::type(objectNodes[j]->getType()) == CEvaluationNode::OBJECT)
186  {
187  CEvaluationNodeObject* pObjectNode = dynamic_cast<CEvaluationNodeObject*>(objectNodes[j]);
188 
189  if (pObjectNode == NULL) return info;
190 
191  CCopasiObjectName cn = pObjectNode->getObjectCN();
192 
193  const CCopasiObject* mObject =
194  static_cast< const CCopasiObject * >(mmModel->getObjectDataModel()->getObject(cn));
195 
196  if (mObject == NULL) return info;
197 
198  std::string host = "";
199 
200  if (mObject->isReference())
201  {
202  host = ",Reference=" + mObject->getObjectName();
203  mObject = mObject->getObjectParent();
204  }
205 
206  if (mObject == NULL) return info;
207 
208  std::string key = keyMap[(dynamic_cast<const CModelEntity * >(mObject))->getKey()];
210 
211  cn = pObject->getCN() + host;
212 
213  pObjectNode->setData("<" + cn + ">");
214  }
215  }
216 
217  tmp->updateTree();
218 
219  newAssignment->setExpression(tmp->getInfix().c_str());
220 
221  return true;
222 }
223 
224 bool CModelAdd::copyDelayExpression(const CEvent * sourceEvent, CEvent * newEvent)
225 {
226 
227  bool info = false;
228 
229  const CExpression* pExpression = sourceEvent->getDelayExpressionPtr();
230 
231  if (pExpression == NULL) return info;
232 
233  CExpression* tmp;
234  tmp = new CExpression(*pExpression, mmModel);
235 
236  const std::vector<CEvaluationNode*>& objectNodes = tmp->getNodeList();
237  size_t j, jmax = objectNodes.size();
238 
239  for (j = 0; j < jmax; ++j)
240  {
241  if (CEvaluationNode::type(objectNodes[j]->getType()) == CEvaluationNode::OBJECT)
242  {
243  CEvaluationNodeObject* pObjectNode = dynamic_cast<CEvaluationNodeObject*>(objectNodes[j]);
244 
245  if (pObjectNode == NULL) return info;
246 
247  CCopasiObjectName cn = pObjectNode->getObjectCN();
248 
249  const CCopasiObject* mObject =
250  static_cast< const CCopasiObject * >(mmModel->getObjectDataModel()->getObject(cn));
251 
252  if (mObject == NULL) return info;
253 
254  std::string host = "";
255 
256  if (mObject->isReference())
257  {
258  host = ",Reference=" + mObject->getObjectName();
259  mObject = mObject->getObjectParent();
260  }
261 
262  if (mObject == NULL) return info;
263 
264  std::string key = keyMap[(dynamic_cast<const CModelEntity * >(mObject))->getKey()];
266 
267  cn = pObject->getCN() + host;
268 
269  pObjectNode->setData("<" + cn + ">");
270  }
271  }
272 
273  tmp->updateTree();
274 
275  newEvent->setDelayExpression(tmp->getInfix().c_str());
276 
277  return true;
278 }
279 
280 bool CModelAdd::copyTriggerExpression(const CEvent * sourceEvent, CEvent * newEvent)
281 {
282 
283  bool info = false;
284 
285  const CExpression* pExpression = sourceEvent->getTriggerExpressionPtr();
286 
287  if (pExpression == NULL) return info;
288 
289  CExpression* tmp;
290  tmp = new CExpression(*pExpression, mmModel);
291 
292  const std::vector<CEvaluationNode*>& objectNodes = tmp->getNodeList();
293  size_t j, jmax = objectNodes.size();
294 
295  for (j = 0; j < jmax; ++j)
296  {
297  if (CEvaluationNode::type(objectNodes[j]->getType()) == CEvaluationNode::OBJECT)
298  {
299  CEvaluationNodeObject* pObjectNode = dynamic_cast<CEvaluationNodeObject*>(objectNodes[j]);
300 
301  if (pObjectNode == NULL) return info;
302 
303  CCopasiObjectName cn = pObjectNode->getObjectCN();
304 
305  const CCopasiObject* mObject =
306  static_cast< const CCopasiObject * >(mmModel->getObjectDataModel()->getObject(cn));
307 
308  if (mObject == NULL) return info;
309 
310  std::string host = "";
311 
312  if (mObject->isReference())
313  {
314  host = ",Reference=" + mObject->getObjectName();
315  mObject = mObject->getObjectParent();
316  }
317 
318  if (mObject == NULL) return info;
319 
320  std::string key = keyMap[(dynamic_cast<const CModelEntity * >(mObject))->getKey()];
322 
323  cn = pObject->getCN() + host;
324 
325  pObjectNode->setData("<" + cn + ">");
326  }
327  }
328 
329  tmp->updateTree();
330 
331  newEvent->setTriggerExpression(tmp->getInfix().c_str());
332 
333  return true;
334 }
335 
336 bool CModelAdd::copyExpression(const CModelEntity * sourceEntity, CModelEntity * newEntity)
337 {
338 
339  bool info = false;
340 
341  const CExpression* pExpression = sourceEntity->getExpressionPtr();
342 
343  if (pExpression == NULL) return info;
344 
345  CExpression* tmp;
346  tmp = new CExpression(*pExpression, mmModel);
347 
348  const std::vector<CEvaluationNode*>& objectNodes = tmp->getNodeList();
349  size_t j, jmax = objectNodes.size();
350 
351  for (j = 0; j < jmax; ++j)
352  {
353  if (CEvaluationNode::type(objectNodes[j]->getType()) == CEvaluationNode::OBJECT)
354  {
355  CEvaluationNodeObject* pObjectNode = dynamic_cast<CEvaluationNodeObject*>(objectNodes[j]);
356 
357  if (pObjectNode == NULL) return info;
358 
359  CCopasiObjectName cn = pObjectNode->getObjectCN();
360 
361  const CCopasiObject* mObject =
362  static_cast< const CCopasiObject * >(mmModel->getObjectDataModel()->getObject(cn));
363 
364  if (mObject == NULL) return info;
365 
366  std::string host = "";
367 
368  if (mObject->isReference())
369  {
370  host = ",Reference=" + mObject->getObjectName();
371  mObject = mObject->getObjectParent();
372  }
373 
374  if (mObject == NULL) return info;
375 
376  std::string key = keyMap[(dynamic_cast<const CModelEntity * >(mObject))->getKey()];
378 
379  cn = pObject->getCN() + host;
380 
381  pObjectNode->setData("<" + cn + ">");
382  }
383  }
384 
385  tmp->updateTree();
386 
387  newEntity->setExpression(tmp->getInfix().c_str());
388 
389  return true;
390 }
391 
392 bool CModelAdd::copyInitialExpression(const CModelEntity * sourceEntity, CModelEntity * newEntity)
393 {
394 
395  bool info = false;
396 
397  const CExpression* pExpression = sourceEntity->getInitialExpressionPtr();
398 
399  if (pExpression == NULL) return info;
400 
401  CExpression* tmp;
402  tmp = new CExpression(*pExpression, mmModel);
403 
404  const std::vector<CEvaluationNode*>& objectNodes = tmp->getNodeList();
405  size_t j, jmax = objectNodes.size();
406 
407  for (j = 0; j < jmax; ++j)
408  {
409  if (CEvaluationNode::type(objectNodes[j]->getType()) == CEvaluationNode::OBJECT)
410  {
411  CEvaluationNodeObject* pObjectNode = dynamic_cast<CEvaluationNodeObject*>(objectNodes[j]);
412 
413  if (pObjectNode == NULL) return info;
414 
415  CCopasiObjectName cn = pObjectNode->getObjectCN();
416 
417  const CCopasiObject* mObject =
418  static_cast< const CCopasiObject * >(mmModel->getObjectDataModel()->getObject(cn));
419 
420  if (mObject == NULL) return info;
421 
422  std::string host = "";
423 
424  if (mObject->isReference())
425  {
426  host = ",Reference=" + mObject->getObjectName();
427  mObject = mObject->getObjectParent();
428  }
429 
430  if (mObject == NULL) return info;
431 
432  std::string key = keyMap[(dynamic_cast<const CModelEntity * >(mObject))->getKey()];
434 
435  cn = pObject->getCN() + host;
436 
437  pObjectNode->setData("<" + cn + ">");
438  }
439  }
440 
441  tmp->updateTree();
442 
443  newEntity->setInitialExpression(tmp->getInfix().c_str());
444 
445  return info;
446 }
447 
448 bool CModelAdd::addCompartments(std::string name)
449 {
450 
451  size_t i, imax = mmModel->getCompartments().size();
452 
453  for (i = 0; i < imax; ++i)
454  {
455  const CCompartment* sourceComp = mmModel->getCompartments()[i];
456 
457  if (!sourceComp) return false;
458 
459  //create new compartment
460 
461  std::string newName = sourceComp->getObjectName() + "_" + name;
462 
463  CCompartment* newComp = mpModel->createCompartment(newName, sourceComp->getInitialValue());
464 
465  if (!newComp) return false;
466 
467  newComp->setStatus(sourceComp->getStatus());
468 
469  newComp->setDimensionality(sourceComp->getDimensionality());
470 
471  keyMap[sourceComp->getKey()] = newComp->getKey();
472  nameMap[sourceComp->getObjectName()] = newName;
473  }
474 
475  return true;
476 }
477 
479 {
480 
481  bool info = false;
482 
483  size_t i, imax = mmModel->getCompartments().size();
484 
485  for (i = 0; i < imax; ++i)
486  {
487  const CCompartment* sourceComp = mmModel->getCompartments()[i];
488 
489  if (!sourceComp) return info;
490 
491  std::string newKey = keyMap[sourceComp->getKey()];
492 
493  CCopasiObject* pObject = (CCopasiRootContainer::getKeyFactory()->get(newKey));
494 
495  CCompartment* newComp = dynamic_cast< CCompartment * >(pObject);
496 
497  if (!newComp) return info;
498 
499  switch (newComp ->getStatus())
500  {
501  case CModelEntity::FIXED:
502 
503  break;
505 
506  if (!copyExpression(sourceComp, newComp)) return info;
507 
508  break;
509 
510  case CModelEntity::ODE:
511 
512  if (!copyExpression(sourceComp, newComp)) return info;
513 
514  if (sourceComp->getInitialExpression() != "")
515  if (!copyInitialExpression(sourceComp, newComp)) return info;
516 
517  break;
518 
519  default:
520 
521  return info;
522 
523  break;
524  }
525  }
526 
527  return true;
528 }
529 
530 bool CModelAdd::addMetabolites(std::string name)
531 {
532  bool info = false;
533 
534  size_t i, imax = mmModel->getMetabolites().size();
535 
536  for (i = 0; i < imax; ++i)
537  {
538  const CMetab* sourceMetab = mmModel->getMetabolites()[i];
539  const CCompartment* sourceComp = sourceMetab->getCompartment();
540 
541  if (!sourceMetab) return info;
542 
543  if (!sourceComp) return info;
544 
545  //create new metabolite
546 
547  std::string newName = sourceMetab->getObjectName() + "_" + name;
548 
549  CMetab* newMetab = mpModel->createMetabolite(sourceMetab->getObjectName(), nameMap[sourceComp->getObjectName()], sourceMetab->getInitialConcentration());
550 
551  if (!newMetab) return info;
552 
553  newMetab->setStatus(sourceMetab->getStatus());
554 
555  keyMap[sourceMetab->getKey()] = newMetab->getKey();
556  nameMap[sourceMetab->getObjectName()] = newName;
557  }
558 
559  return true;
560 }
561 
563 {
564  bool info = false;
565 
566  size_t i, imax = mmModel->getMetabolites().size();
567 
568  for (i = 0; i < imax; ++i)
569  {
570  const CMetab* sourceMetab = mmModel->getMetabolites()[i];
571 
572  if (!sourceMetab) return info;
573 
574  std::string newKey = keyMap[sourceMetab->getKey()];
575 
576  CCopasiObject* pObject = (CCopasiRootContainer::getKeyFactory()->get(newKey));
577 
578  CMetab* newMetab = dynamic_cast< CMetab * >(pObject);
579 
580  if (!newMetab) return info;
581 
582  switch (newMetab ->getStatus())
583  {
584  case CModelEntity::FIXED:
585 
586  break;
588 
589  if (!copyExpression(sourceMetab, newMetab)) return info;
590 
591  break;
592 
593  case CModelEntity::ODE:
594 
595  if (!copyExpression(sourceMetab, newMetab)) return info;
596 
597  if (sourceMetab->getInitialExpression() != "")
598  if (!copyInitialExpression(sourceMetab, newMetab)) return info;
599 
600  break;
601 
603 
604  break;
605  default:
606 
607  return info;
608 
609  break;
610  }
611  }
612 
613  return true;
614 }
615 
616 bool CModelAdd::addModelValues(std::string name)
617 {
618  bool info = false;
619 
620  size_t i, imax = mmModel->getModelValues().size();
621 
622  for (i = 0; i < imax; ++i)
623  {
624  const CModelValue* sourceModVal = mmModel->getModelValues()[i];
625 
626  if (!sourceModVal) return info;
627 
628  //create new model value
629 
630  std::string newName = sourceModVal->getObjectName() + "_" + name;
631 
632  CModelValue* newModVal = mpModel->createModelValue(newName, sourceModVal->getInitialValue());
633 
634  if (!newModVal) return info;
635 
636  newModVal->setStatus(sourceModVal->getStatus());
637 
638  keyMap[sourceModVal->getKey()] = newModVal->getKey();
639  nameMap[sourceModVal->getObjectName()] = newName;
640  }
641 
642  return true;
643 }
644 
646 {
647  bool info = false;
648 
649  size_t i, imax = mmModel->getModelValues().size();
650 
651  for (i = 0; i < imax; ++i)
652  {
653  const CModelValue* sourceModVal = mmModel->getModelValues()[i];
654 
655  if (!sourceModVal) return info;
656 
657  std::string newKey = keyMap[sourceModVal->getKey()];
658 
659  CCopasiObject* pObject = (CCopasiRootContainer::getKeyFactory()->get(newKey));
660 
661  CModelValue* newModVal = dynamic_cast<CModelValue * >(pObject);
662 
663  if (!newModVal) return info;
664 
665  switch (newModVal ->getStatus())
666  {
667  case CModelEntity::FIXED:
668 
669  break;
671 
672  if (!copyExpression(sourceModVal, newModVal)) return info;
673 
674  break;
675 
676  case CModelEntity::ODE:
677 
678  if (!copyExpression(sourceModVal, newModVal)) return info;
679 
680  if (sourceModVal->getInitialExpression() != "")
681  if (!copyInitialExpression(sourceModVal, newModVal)) return info;
682 
683  break;
684 
685  default:
686 
687  return info;
688 
689  break;
690  }
691  }
692 
693  return true;
694 }
695 
696 bool CModelAdd::addReactions(std::string name)
697 {
698 
699  bool info = false;
700 
701  //create copies of the relevant reactions
702 
703  size_t i, imax = mmModel->getReactions().size();
704 
705  size_t ic, icmax = mmModel->getCompartments().size();
706 
707  for (ic = 0; ic < icmax; ++ic)
708  {
709  const CCompartment* sourceComp = mmModel->getCompartments()[ic];
710 
711  if (!sourceComp) return info;
712 
713  for (i = 0; i < imax; ++i)
714  {
715  CReaction * sourceReac = mmModel->getReactions()[i];
716 
717  if (reactionInvolvesCompartment(sourceReac, sourceComp))
718  {
719 
720  std::string newName = sourceReac->getObjectName() + "_" + name;
721 
722  CReaction* newReac = mpModel->createReaction(newName);
723 
724  if (!newReac) return info;
725 
726  //copy the chemical equation. If the involved metabs are among those that
727  //were copied with the compartment, replace them. Otherwise keep the original metab
728  newReac->setReversible(sourceReac->isReversible());
729  std::map<std::string, std::string>::const_iterator mapIt;
730  std::string targetKey;
731  size_t j, jmax = sourceReac->getChemEq().getSubstrates().size();
732 
733  for (j = 0; j < jmax; ++j)
734  {
735  const CChemEqElement * sourceElement = sourceReac->getChemEq().getSubstrates()[j];
736  //check if the metab is in the map. If yes, translate it, otherwise not.
737  mapIt = keyMap.find(sourceElement->getMetaboliteKey());
738 
739  if (mapIt == keyMap.end())
740  {
741  targetKey = sourceElement->getMetaboliteKey();
742  }
743  else
744  targetKey = mapIt->second;
745 
746  newReac->addSubstrate(targetKey, sourceElement->getMultiplicity());
747  }
748 
749  jmax = sourceReac->getChemEq().getProducts().size();
750 
751  for (j = 0; j < jmax; ++j)
752  {
753  const CChemEqElement * sourceElement = sourceReac->getChemEq().getProducts()[j];
754  //check if the metab is in the map. If yes, translate it, otherwise not.
755  mapIt = keyMap.find(sourceElement->getMetaboliteKey());
756 
757  if (mapIt == keyMap.end())
758  {
759  targetKey = sourceElement->getMetaboliteKey();
760  }
761  else
762  targetKey = mapIt->second;
763 
764  newReac->addProduct(targetKey, sourceElement->getMultiplicity());
765  }
766 
767  jmax = sourceReac->getChemEq().getModifiers().size();
768 
769  for (j = 0; j < jmax; ++j)
770  {
771  const CChemEqElement * sourceElement = sourceReac->getChemEq().getModifiers()[j];
772  //check if the metab is in the map. If yes, translate it, otherwise not.
773 
774  mapIt = keyMap.find(sourceElement->getMetaboliteKey());
775 
776  if (mapIt == keyMap.end())
777  {
778  targetKey = sourceElement->getMetaboliteKey();
779  }
780  else
781  targetKey = mapIt->second;
782 
783  newReac->addModifier(targetKey);
784  }
785 
786  //set the kinetic function
787  newReac->setFunction(const_cast<CFunction*>(sourceReac->getFunction()));
788 
789  //mapping and local parameters
790  for (j = 0; j < newReac->getFunctionParameters().size(); ++j)
791  {
792  switch (newReac->getFunctionParameters()[j]->getUsage())
793  {
797  //translate the metab keys
798  {
799  bool isVector = (newReac->getFunctionParameters()[j]->getType() == CFunctionParameter::VFLOAT64);
800 
801  //we assume that only SUBSTRATE, PRODUCT, MODIFIER can be vectors
802  if (isVector)
803  newReac->clearParameterMapping(j);
804 
805  size_t k;
806 
807  for (k = 0; k < sourceReac->getParameterMappings()[j].size(); ++k)
808  {
809  mapIt = keyMap.find(sourceReac->getParameterMappings()[j][k]);
810 
811  if (mapIt == keyMap.end())
812  {
813  targetKey = sourceReac->getParameterMappings()[j][k];
814  }
815  else
816  targetKey = mapIt->second;
817 
818  if (isVector)
819  newReac->addParameterMapping(j, targetKey);
820  else
821  newReac->setParameterMapping(j, targetKey);
822  }
823  }
824  break;
825 
827  //just copy the key
828  {
829  mapIt = keyMap.find(sourceReac->getParameterMappings()[j][0]);
830 
831  if (mapIt == keyMap.end())
832  {
833  targetKey = sourceReac->getParameterMappings()[j][0];
834  }
835  else
836  targetKey = mapIt->second;
837 
838  newReac->setParameterMapping(j, targetKey);
839  }
840  break;
841 
843 
844  //translate the compartment key if necessary
845  if (sourceReac->getParameterMappings()[j][0] == sourceComp->getKey())
846  newReac->setParameterMapping(j, keyMap[sourceComp->getKey()]);
847  else
848  {
849  mapIt = keyMap.find(sourceReac->getParameterMappings()[j][0]);
850 
851  if (mapIt == keyMap.end())
852  {
853  targetKey = sourceReac->getParameterMappings()[j][0];
854  }
855  else
856  targetKey = mapIt->second;
857 
858  newReac->setParameterMapping(j, targetKey);
859  }
860 
861  //TODO: this needs to be adapted when sets of compartments will be copied
862  break;
863 
865 
866  if (sourceReac->isLocalParameter(j))
867  newReac->setParameterValue(newReac->getFunctionParameters()[j]->getObjectName(),
868  sourceReac->getParameterValue(newReac->getFunctionParameters()[j]->getObjectName()));
869  else
870  {
871  mapIt = keyMap.find(sourceReac->getParameterMappings()[j][0]);
872 
873  if (mapIt == keyMap.end())
874  {
875  targetKey = sourceReac->getParameterMappings()[j][0];
876  }
877  else
878  targetKey = mapIt->second;
879 
880  newReac->setParameterMapping(j, targetKey);
881  }
882 
883  break;
884 
885  default:
886  return info;
887  break;
888  }
889  }
890  }
891  }
892  }
893 
894  return true;
895 }
896 
897 //static
899 {
900  if (!reac) return false;
901 
902  if (!comp) return false;
903 
904  size_t i, imax = reac->getChemEq().getSubstrates().size();
905 
906  for (i = 0; i < imax; ++i)
907  if (reac->getChemEq().getSubstrates()[i]->getMetabolite()->getCompartment() == comp)
908  return true;
909 
910  imax = reac->getChemEq().getProducts().size();
911 
912  for (i = 0; i < imax; ++i)
913  if (reac->getChemEq().getProducts()[i]->getMetabolite()->getCompartment() == comp)
914  return true;
915 
916  imax = reac->getChemEq().getModifiers().size();
917 
918  for (i = 0; i < imax; ++i)
919  if (reac->getChemEq().getModifiers()[i]->getMetabolite()->getCompartment() == comp)
920  return true;
921 
922  return false;
923 }
924 
925 const std::string CModelMerging::TypeName[] =
926 {
927  "ignore",
928  "merge",
929  ""
930 };
931 
933  : mpModel(pModel)
934 {
935 }
936 
938 {
939  mpModel = pModel;
940 }
941 
942 void CModelMerging::simpleCall(std::vector< std::string > & /* toKey */, std::vector< std::string > & objectKey)
943 {
944  if (!mpModel)
945  {
946  fatalError();
947  }
948 
949  size_t i, j, imax = mpModel->getMetabolites().size();
950 
951  CMetab * metab;
952  CMetab * metab1;
953  CMetab* tmp;
954  std::string empty = "";
955 
956  for (i = 0; i < imax; ++i)
957  {
958  metab = mpModel->getMetabolites()[i];
959 
960  for (j = 0; j < imax; ++j)
961  {
962  if (objectKey[i] != "")
963  {
964  tmp = mpModel->getMetabolites()[j];
965 
966  if (tmp->getKey() == objectKey[i])
967  {
968  metab1 = tmp;
969  }
970  }
971  }
972 
973  if (! mergeMetabolites(metab->getKey(), objectKey[i]))
974  {
976  metab1->getObjectName().c_str(), metab->getObjectName().c_str());
977  return;
978  }
979  }
980 
981  for (i = 0; i < imax; ++i)
982  {
983  if (objectKey[i] != empty) mpModel->removeMetabolite(objectKey[i] , false);
984  }
985 
987 }
988 
989 bool CModelMerging::mergeMetabolites(std::string toKey, std::string key)
990 {
991 
992  bool info = false;
993 
994  //merge in the relevant reactions
995 
996  size_t i, imax = mpModel->getReactions().size();
997  size_t j, jmax;
998 
999  for (i = 0; i < imax; ++i)
1000  {
1001  CReaction * reac = mpModel->getReactions()[i];
1002 
1003  jmax = reac->getChemEq().getSubstrates().size();
1004 
1005  for (j = 0; j < jmax; ++j)
1006  {
1007  CChemEqElement * subst = reac->getChemEq().getSubstrates()[j];
1008 
1009  if (subst->getMetabolite()->getKey() == key)
1010  subst->setMetabolite(toKey);
1011  }
1012 
1013  jmax = reac->getChemEq().getProducts().size();
1014 
1015  for (j = 0; j < jmax; ++j)
1016  {
1017  CChemEqElement * prod = reac->getChemEq().getProducts()[j];
1018 
1019  if (prod->getMetabolite()->getKey() == key)
1020  prod->setMetabolite(toKey);
1021  }
1022 
1023  jmax = reac->getChemEq().getModifiers().size();
1024 
1025  for (j = 0; j < jmax; ++j)
1026  {
1027  CChemEqElement * modif = reac->getChemEq().getModifiers()[j];
1028 
1029  if (modif->getMetabolite()->getKey() == key)
1030  modif->setMetabolite(toKey);
1031  }
1032 
1033  //change parameters of the kinetic function
1034 
1035  for (j = 0; j < reac->getFunctionParameters().size(); ++j)
1036  {
1037  switch (reac->getFunctionParameters()[j]->getUsage())
1038  {
1042  //translate the metab keys
1043  {
1044 
1045  //we assume that only SUBSTRATE, PRODUCT, MODIFIER can be vectors
1046 
1047  size_t k, kmax = reac->getParameterMappings()[j].size();
1048 
1049  for (k = 0; k < kmax; ++k)
1050  if (reac->getParameterMappings()[j][k] == key)
1051  reac->getParameterMappings()[j][k] = toKey;
1052  }
1053  break;
1054 
1056  break;
1057 
1059  // ??? TODO : have to ask
1060  break;
1061 
1063  break;
1064 
1065  default:
1066  return info;
1067  break;
1068  }
1069  }
1070  }
1071 
1072  imax = mpModel->getEvents().size();
1073 
1074  for (i = 0; i < imax; ++i)
1075  {
1076  CEvent* event = mpModel->getEvents()[i];
1077 
1078  if (!event) return info;
1079 
1080  /* merge in trigger expressions */
1081  CExpression* pExpression = event->getTriggerExpressionPtr();
1082 
1083  if (pExpression == NULL) return info;
1084 
1085  if (!mergeInExpression(toKey, key, pExpression)) return info;
1086 
1087  pExpression = event->getDelayExpressionPtr();
1088 
1089  if (pExpression)
1090  if (!mergeInExpression(toKey, key, pExpression))
1091  return info;
1092 
1093  jmax = event->getAssignments().size();
1094 
1095  for (j = 0; j < jmax; ++j)
1096  {
1097  CEventAssignment* assignment = event->getAssignments()[j];
1098 
1099  if (!assignment) return info;
1100 
1101  std::string assignmentKey = assignment->getTargetKey();
1102 
1103  if (assignmentKey == key) assignment->setTargetKey(toKey);
1104 
1105  pExpression = assignment->getExpressionPtr();
1106 
1107  if (pExpression == NULL) return info;
1108 
1109  if (!mergeInExpression(toKey, key, pExpression)) return info;
1110  }
1111  }
1112 
1113  imax = mpModel->getMetabolites().size();
1114 
1115  for (i = 0; i < imax; ++i)
1116  {
1117  CMetab* metab = mpModel->getMetabolites()[i];
1118 
1119  if (!metab) return info;
1120 
1121  switch (metab->getStatus())
1122  {
1123  case CModelEntity::FIXED:
1125 
1126  break;
1128 
1129  if (!mergeInExpression(toKey, key, metab->getExpressionPtr())) return info;
1130 
1131  break;
1132 
1133  case CModelEntity::ODE:
1134 
1135  if (!mergeInExpression(toKey, key, metab->getExpressionPtr())) return info;
1136 
1137  if (metab->getInitialExpression() != "")
1138  if (!mergeInExpression(toKey, key, metab->getInitialExpressionPtr())) return info;
1139 
1140  break;
1141 
1142  default:
1143  return info;
1144  break;
1145  }
1146  }
1147 
1148  imax = mpModel->getCompartments().size();
1149 
1150  for (i = 0; i < imax; ++i)
1151  {
1152  CCompartment* comp = mpModel->getCompartments()[i];
1153 
1154  if (!comp) return info;
1155 
1156  switch (comp ->getStatus())
1157  {
1158  case CModelEntity::FIXED:
1159 
1160  break;
1162 
1163  if (!mergeInExpression(toKey, key, comp->getExpressionPtr())) return info;
1164 
1165  break;
1166 
1167  case CModelEntity::ODE:
1168 
1169  if (!mergeInExpression(toKey, key, comp->getExpressionPtr())) return info;
1170 
1171  if (comp->getInitialExpression() != "")
1172  if (!mergeInExpression(toKey, key, comp->getInitialExpressionPtr())) return info;
1173 
1174  break;
1175 
1176  default:
1177  return info;
1178  break;
1179  }
1180  }
1181 
1182  imax = mpModel->getModelValues().size();
1183 
1184  for (i = 0; i < imax; ++i)
1185  {
1186  CModelValue* modval = mpModel->getModelValues()[i];
1187 
1188  if (!modval) return info;
1189 
1190  switch (modval ->getStatus())
1191  {
1192  case CModelEntity::FIXED:
1193 
1194  break;
1196 
1197  if (!mergeInExpression(toKey, key, modval->getExpressionPtr())) return info;
1198 
1199  break;
1200 
1201  case CModelEntity::ODE:
1202 
1203  if (!mergeInExpression(toKey, key, modval->getExpressionPtr())) return info;
1204 
1205  if (modval->getInitialExpression() != "")
1206  if (!mergeInExpression(toKey, key, modval->getInitialExpressionPtr())) return info;
1207 
1208  break;
1209 
1210  default:
1211  return info;
1212  break;
1213  }
1214  }
1215 
1216  return true;
1217 }
1218 
1219 bool CModelMerging::mergeInExpression(std::string toKey, std::string key, CExpression *pExpression)
1220 {
1221 
1222  bool info = false;
1223 
1224  if (pExpression == NULL) return info;
1225 
1226  const std::vector<CEvaluationNode*>& objectNodes = pExpression->getNodeList();
1227  size_t j, jmax = objectNodes.size();
1228 
1229  for (j = 0; j < jmax; ++j)
1230  {
1231  if (CEvaluationNode::type(objectNodes[j]->getType()) == CEvaluationNode::OBJECT)
1232  {
1233  CEvaluationNodeObject* pObjectNode = dynamic_cast<CEvaluationNodeObject*>(objectNodes[j]);
1234 
1235  if (pObjectNode == NULL) return info;
1236 
1237  CCopasiObjectName cn = pObjectNode->getObjectCN();
1238 
1239  const CCopasiObject* mObject =
1240  static_cast< const CCopasiObject * >(mpModel->getObjectDataModel()->getObject(cn));
1241 
1242  if (mObject == NULL) return info;
1243 
1244  std::string host = "";
1245 
1246  if (mObject->isReference())
1247  {
1248  host = ",Reference=" + mObject->getObjectName();
1249  mObject = mObject->getObjectParent();
1250  }
1251 
1252  if (mObject == NULL) return info;
1253 
1254  CCopasiObject* pObject;
1255 
1256  std::string ikey = (dynamic_cast<const CModelEntity * >(mObject))->getKey();
1257 
1258  if (ikey == key)
1259  {
1260  pObject = (CCopasiRootContainer::getKeyFactory()->get(toKey));
1261 
1262  cn = pObject->getCN() + host;
1263 
1264  pObjectNode->setData("<" + cn + ">");
1265  }
1266  }
1267  }
1268 
1269  pExpression->updateTree();
1270 
1271  return true;
1272 }
const CExpression * getExpressionPtr() const
Definition: CEvent.h:152
Header file of class CExpression.
CCopasiDataModel * getObjectDataModel()
void setReversible(bool reversible)
Definition: CReaction.cpp:247
CModel * mmModel
Definition: CModelMerging.h:69
const CCopasiVectorN< CEventAssignment > & getAssignments() const
Definition: CEvent.cpp:678
const bool & getDelayAssignment() const
Definition: CEvent.cpp:419
bool mergeMetabolites(std::string toKey, std::string key)
bool addMetabolitesExpressions()
CEvent * createEvent(const std::string &name)
Definition: CModel.cpp:2928
CCopasiVectorN< CEvent > & getEvents()
Definition: CModel.cpp:1110
virtual CCopasiObjectName getCN() const
bool addSubstrate(const std::string &metabKey, const C_FLOAT64 &multiplicity=1.0)
Definition: CReaction.cpp:232
const CCopasiVector< CMetab > & getMetabolites() const
Definition: CModel.cpp:1051
const std::string & getObjectName() const
bool setDimensionality(unsigned C_INT32 dim)
const CCopasiVectorN< CModelValue > & getModelValues() const
Definition: CModel.cpp:1060
virtual void setStatus(const CModelEntity::Status &status)
Definition: CMetab.cpp:291
unsigned C_INT32 getDimensionality() const
virtual size_t size() const
const C_FLOAT64 & getInitialConcentration() const
Definition: CMetab.cpp:220
const CRegisteredObjectName & getObjectCN() const
bool removeMetabolite(const std::string &key, const bool &recursive=true)
Definition: CModel.cpp:2667
const std::string & getTargetKey() const
Definition: CEvent.cpp:162
CCopasiObject * get(const std::string &key)
static const std::string TypeName[]
Definition: CModelMerging.h:95
void setParameterValue(const std::string &parameterName, const C_FLOAT64 &value, const bool &updateStatus=true)
Definition: CReaction.cpp:303
void setModel(CModel *pModel, CModel *mModel)
const CMetab * getMetabolite() const
#define fatalError()
std::map< std::string, std::string > keyMap
Definition: CModelMerging.h:42
const CExpression * getExpressionPtr() const
Definition: CEvent.cpp:226
bool setExpression(const std::string &expression)
Definition: CEvent.cpp:167
bool addProduct(const std::string &metabKey, const C_FLOAT64 &multiplicity=1.0)
Definition: CReaction.cpp:236
void setModel(CModel *pModel)
bool isLocalParameter(const size_t &index) const
Definition: CReaction.cpp:449
bool addEvents(std::string name)
bool setInitialExpression(const std::string &expression)
#define C_INVALID_INDEX
Definition: copasi.h:222
void clearParameterMapping(const std::string &parameterName)
Definition: CReaction.cpp:407
CModel * mpModel
Definition: CModelMerging.h:68
CModelValue * createModelValue(const std::string &name, const C_FLOAT64 &value=0.0)
Definition: CModel.cpp:2838
virtual size_t getIndex(const std::string &name) const
bool setTargetKey(const std::string &targetKey)
Definition: CEvent.cpp:151
bool mergeInExpression(std::string toKey, std::string key, CExpression *pExpression)
Definition: CMetab.h:178
bool addModelValuesExpressions()
bool copyEventAssignmentExpression(const CEventAssignment *sourceAssignment, CEventAssignment *newAssignment)
CExpression * getDelayExpressionPtr()
Definition: CEvent.cpp:606
CModel * mpModel
bool copyExpression(const CModelEntity *sourceEntity, CModelEntity *newEntity)
virtual const std::string & getKey() const
const C_FLOAT64 & getInitialValue() const
bool addMetabolites(std::string name)
std::map< std::string, std::string > nameMap
Definition: CModelMerging.h:43
const CCopasiVector< CChemEqElement > & getProducts() const
Definition: CChemEq.cpp:63
static Type type(const Type &type)
const CFunction * getFunction() const
Definition: CReaction.cpp:252
bool addCompartmentsExpressions()
const CFunctionParameters & getFunctionParameters() const
Definition: CReaction.cpp:576
CModelAdd(CModel *pModel, CModel *mModel)
virtual bool add(const CType &src)
bool isReference() const
bool addModifier(const std::string &metabKey, const C_FLOAT64 &multiplicity=1.0)
Definition: CReaction.cpp:240
void setMetabolite(const std::string &key)
bool setFunction(const std::string &functionName)
Definition: CReaction.cpp:255
virtual const std::string & getKey() const
virtual void setStatus(const CModelEntity::Status &status)
CReaction * createReaction(const std::string &name)
Definition: CModel.cpp:2760
bool setTriggerExpression(const std::string &expression)
Definition: CEvent.cpp:474
bool addCompartments(std::string name)
const C_FLOAT64 & getMultiplicity() const
const std::string & getMetaboliteKey() const
std::string getInitialExpression() const
bool addModelValues(std::string name)
bool copyTriggerExpression(const CEvent *sourceEvent, CEvent *newEvent)
void simpleCall(std::vector< std::string > &toKey, std::vector< std::string > &objectKey)
just a simple method to call during development
void setDelayAssignment(const bool &delayCalculation)
Definition: CEvent.cpp:408
const CCopasiVector< CChemEqElement > & getSubstrates() const
Definition: CChemEq.cpp:60
const std::string & getKey() const
Definition: CModel.cpp:1142
bool isReversible() const
Definition: CReaction.cpp:229
CCopasiVectorNS< CCompartment > & getCompartments()
Definition: CModel.cpp:1145
const CExpression * getTriggerExpressionPtr() const
Definition: CEvent.cpp:534
static CKeyFactory * getKeyFactory()
bool setDelayExpression(const std::string &expression)
Definition: CEvent.cpp:544
bool compileIfNecessary(CProcessReport *pProcessReport)
Definition: CModel.cpp:612
const CCopasiVector< CChemEqElement > & getModifiers() const
Definition: CChemEq.cpp:66
void setParameterMapping(const size_t &index, const std::string &key)
Definition: CReaction.cpp:339
CCopasiVectorNS< CReaction > & getReactions()
Definition: CModel.cpp:1039
virtual bool setData(const Data &data)
bool copyDelayExpression(const CEvent *sourceEvent, CEvent *newEvent)
Definition: CModel.h:50
Header file of class CEvent.
virtual const CObjectInterface * getObject(const CCopasiObjectName &cn) const
static bool reactionInvolvesCompartment(const CReaction *reac, const CCompartment *comp)
bool copyInitialExpression(const CModelEntity *sourceEntity, CModelEntity *newEntity)
const CModelEntity::Status & getStatus() const
const std::vector< std::vector< std::string > > & getParameterMappings() const
Definition: CReaction.h:285
bool setExpression(const std::string &expression)
void simpleCall()
just a simple method to call during development
const std::vector< CEvaluationNode * > & getNodeList() const
const CCompartment * getCompartment() const
Definition: CMetab.cpp:222
#define MCModelMerging
const CChemEq & getChemEq() const
Definition: CReaction.cpp:223
CModelMerging(CModel *pModel)
const C_FLOAT64 & getParameterValue(const std::string &parameterName) const
Definition: CReaction.cpp:326
const std::string & getInfix() const
CCopasiContainer * getObjectParent() const
const CExpression * getInitialExpressionPtr() const
void addParameterMapping(const size_t &index, const std::string &key)
Definition: CReaction.cpp:348
CCompartment * createCompartment(const std::string &name, const C_FLOAT64 &volume=1.0)
Definition: CModel.cpp:2698
bool addReactions(std::string name)
CMetab * createMetabolite(const std::string &name, const std::string &compartment, const C_FLOAT64 &iconc=1.0, const CModelEntity::Status &status=CModelEntity::REACTIONS)
Definition: CModel.cpp:2622