COPASI API  4.16.103
CMetab.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010 - 2014 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 // Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
7 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
8 // and The University of Manchester.
9 // All rights reserved.
10 
11 // Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
12 // Properties, Inc. and EML Research, gGmbH.
13 // All rights reserved.
14 
15 #include <iostream>
16 #include <string>
17 #include <vector>
18 #include <limits>
19 
20 #include "copasi.h"
21 
23 #include "utilities/utility.h"
24 #include "report/CKeyFactory.h"
25 #include "CCompartment.h"
26 #include "CModel.h"
27 #include "CMetab.h"
28 #include "CMetabNameInterface.h"
29 #include "function/CExpression.h"
31 
32 #define METAB_MOIETY 7
33 
34 //static
36  const CCompartment & compartment,
37  const CModel & model)
38 {return concentration * compartment.getInitialValue() * model.getQuantity2NumberFactor();}
39 
40 //static
42  const CCompartment & compartment,
43  const CModel & model)
44 {return number / compartment.getInitialValue() * model.getNumber2QuantityFactor();}
45 
46 CMetab::CMetab(const std::string & name,
47  const CCopasiContainer * pParent):
48  CModelEntity(name, pParent, "Metabolite",
49  CCopasiObject::NonUniqueName),
50  mConc(std::numeric_limits<C_FLOAT64>::quiet_NaN()),
51  mIConc(0.0),
52  mConcRate(0.0),
53  mTT(0.0),
54  mpCompartment(NULL),
55  mpMoiety(NULL),
56  mIsInitialConcentrationChangeAllowed(true)
57 {
58  mKey = CCopasiRootContainer::getKeyFactory()->add("Metabolite", this);
59  initObjects();
60 
62 
63  if (getObjectParent())
64  {
65  initCompartment(NULL);
66 
68  setConcentration(1.0);
69  }
70 
72 }
73 
74 CMetab::CMetab(const CMetab & src,
75  const CCopasiContainer * pParent):
76  CModelEntity(src, pParent),
77  mConc(src.mConc),
78  mIConc(src.mIConc),
79  mConcRate(src.mConcRate),
80  mTT(src.mTT),
81  mpCompartment(NULL),
82  mpMoiety(src.mpMoiety),
83  mIsInitialConcentrationChangeAllowed(src.mIsInitialConcentrationChangeAllowed)
84 {
85  mKey = CCopasiRootContainer::getKeyFactory()->add("Metabolite", this);
86 
87  initObjects();
88 
91 }
92 
94 {
96 
97  setStatus(RHS.mStatus);
98 
99  // We need to set the initial particle number since that is the expected for the initial state
100  C_FLOAT64 InitialParticleNumber =
102  setInitialValue(InitialParticleNumber);
103 
104  mRate = 0.0;
105  mConcRate = 0.0;
106  mTT = 0.0;
107 
108  return *this; // Assignment operator returns left side.
109 }
110 
112 {
115 }
116 
117 // virtual
118 std::string CMetab::getChildObjectUnits(const CCopasiObject * pObject) const
119 {
120  if (mpModel == NULL) return "";
121 
122  if (pObject == mpIValueReference ||
123  pObject == mpValueReference)
124  {
125  return "";
126  }
127  else if (pObject == mpRateReference)
128  {
130  }
131  else if (pObject == mpTTReference)
132  {
134  }
135  else if (mpCompartment != NULL)
136  {
137  std::string Unit = mpModel->getQuantityUnitsDisplayString();
138  std::string CompartmentUnit = mpCompartment->getChildObjectUnits(mpCompartment->getInitialValueReference());
139  std::string TimeUnit = mpModel->getTimeUnitsDisplayString();
140 
141  if (pObject == mpIConcReference ||
142  pObject == mpConcReference)
143  {
144  if (Unit == "")
145  {
146  if (CompartmentUnit == "")
147  {
148  return "";
149  }
150 
151  return "1/" + CompartmentUnit;
152  }
153 
154  if (CompartmentUnit == "")
155  {
156  return Unit;
157  }
158 
159  return Unit + "/" + CompartmentUnit;
160  }
161  else if (pObject == this->mpConcRateReference)
162  {
163  if (Unit == "")
164  {
165  if (CompartmentUnit == "")
166  {
167  if (TimeUnit == "")
168  {
169  return "";
170  }
171 
172  return "1/" + TimeUnit;
173  }
174 
175  if (TimeUnit == "")
176  {
177  return "1/" + CompartmentUnit;
178  }
179 
180  return "1/(" + CompartmentUnit + "*" + TimeUnit + ")";
181  }
182  else
183  {
184  if (CompartmentUnit == "")
185  {
186  if (TimeUnit == "")
187  {
188  return Unit;
189  }
190 
191  return Unit + "/" + TimeUnit;
192  }
193 
194  if (TimeUnit == "")
195  {
196  return Unit + "/" + CompartmentUnit;
197  }
198 
199  return Unit + "/(" + CompartmentUnit + "*" + TimeUnit + ")";
200  }
201  }
202  }
203 
204  return "";
205 }
206 
208 
209 void CMetab::initCompartment(const CCompartment * pCompartment)
210 {
211  mpCompartment =
212  dynamic_cast< const CCompartment * >(getObjectAncestor("Compartment"));
213 
214  if (!mpCompartment)
215  mpCompartment = pCompartment;
216 }
217 
218 const C_FLOAT64 & CMetab::getConcentration() const {return mConc;}
219 
221 
223 
224 const CModel * CMetab::getModel() const {return mpModel;}
225 
226 void CMetab::setTransitionTime(const C_FLOAT64 & transitionTime)
227 {mTT = transitionTime;}
228 
229 const C_FLOAT64 & CMetab::getTransitionTime() const {return mTT;}
230 
232 {
234  initCompartment(NULL);
235 
236  Status CurrentStatus = getStatus();
237 
238  if (CurrentStatus != FIXED)
239  setStatus(FIXED);
240  else
242 
243  setStatus(CurrentStatus);
244 
245  return true;
246 }
247 
248 // ***** set quantities ********
249 
250 void CMetab::setConcentration(const C_FLOAT64 concentration)
251 {
252  if (isFixed()) return;
253 
254  mConc = concentration;
255 }
256 
257 void CMetab::setInitialConcentration(const C_FLOAT64 & initialConcentration)
258 {
259  mIConc = initialConcentration;
260 
261  return;
262 }
263 
265 {
267 }
268 
270 {
271  if (mpInitialExpression != NULL &&
272  mpInitialExpression->getInfix() != "")
274  else
275  mIConc =
277 
278  if (isFixed()) mConc = mIConc;
279 }
280 
282 {
284 }
285 
287 {
289 }
290 
292 {
293  Status OldStatus = getStatus();
294 
295  CModelEntity::setStatus(status);
296 
297  if (status == OldStatus) return;
298 
299  CCopasiObject::DataObjectSet Dependencies;
300 
301  const CCopasiObject * pVolumeReference = NULL;
302 
303  if (mpCompartment)
304  pVolumeReference = mpCompartment->getValueReference();
305 
306  switch (getStatus())
307  {
308  case FIXED:
309  break;
310 
311  case ASSIGNMENT:
312  Dependencies.insert(mpConcReference);
313 
314  if (pVolumeReference)
315  Dependencies.insert(pVolumeReference);
316 
319 
322 
323  // The dependencies and refresh of the rate are correct (see CModelEntity::setStatus).
324 
327  break;
328 
329  case ODE:
332 
333  Dependencies.insert(mpValueReference);
334 
335  if (pVolumeReference)
336  Dependencies.insert(pVolumeReference);
337 
338  mpConcReference->setDirectDependencies(Dependencies);
340 
341  Dependencies.clear();
342  Dependencies.insert(mpConcRateReference);
343 
344  if (pVolumeReference)
345  Dependencies.insert(pVolumeReference);
346 
347  mpRateReference->setDirectDependencies(Dependencies);
349 
352 
353  break;
354 
355  case REACTIONS:
358 
359  if (pVolumeReference)
360  Dependencies.insert(pVolumeReference);
361 
362  Dependencies.insert(mpValueReference);
363  mpConcReference->setDirectDependencies(Dependencies);
365 
367 
368  Dependencies.clear();
369 
370  if (pVolumeReference)
371  Dependencies.insert(pVolumeReference);
372 
373  Dependencies.insert(mpRateReference);
376  break;
377 
378  default:
379  break;
380  }
381 
383 }
384 
386 {
387  bool success = true;
388 
389  // We first clear all dependencies and refreshes
390  // Particle Number
393 
394  // Rate (particle number rate)
395  mRateVector.clear();
398 
399  // Concentration
402 
403  // Concentration Rate
406 
407  // Transition Time
410 
411  // Prepare the compilation
412  std::set<const CCopasiObject *> Dependencies;
413  std::vector< CCopasiContainer * > listOfContainer;
414  listOfContainer.push_back(getObjectAncestor("Model"));
415 
416  CCopasiDataModel* pDataModel = NULL;
417  const CCopasiObject * pVolumeReference = NULL;
418 
419  if (mpCompartment)
420  pVolumeReference = mpCompartment->getValueReference();
421 
422  // Compile the value (particle number)
423  Dependencies.insert(mpConcReference);
424 
425  if (pVolumeReference)
426  Dependencies.insert(pVolumeReference);
427 
428  // We no longer need to distinguish the cases since the reference are now context sensitive
431 
432  Dependencies.clear();
433 
434  // Compiling of the rest.
435  switch (getStatus())
436  {
437  case FIXED:
438  // Concentration
439  Dependencies.insert(mpValueReference);
440 
441  if (pVolumeReference)
442  Dependencies.insert(pVolumeReference);
443 
444  mpConcReference->setDirectDependencies(Dependencies);
446 
447  // Fixed values
448  mRate = 0.0;
449  mConcRate = 0.0;
450  mTT = std::numeric_limits<C_FLOAT64>::infinity();
451  break;
452 
453  case ASSIGNMENT:
454  // Concentration
455  success = mpExpression->compile(listOfContainer);
458 
459  // Implicit initial expression
461  pDataModel = getObjectDataModel();
463  mpInitialExpression->setObjectName("InitialExpression");
464 
465  // Fixed values
466  mRate = std::numeric_limits< C_FLOAT64 >::quiet_NaN();
467  mConcRate = std::numeric_limits< C_FLOAT64 >::quiet_NaN();
468  mTT = std::numeric_limits< C_FLOAT64 >::quiet_NaN();
469  break;
470 
471  case ODE:
472  // Concentration
473  Dependencies.insert(mpValueReference);
474 
475  if (pVolumeReference)
476  Dependencies.insert(pVolumeReference);
477 
478  mpConcReference->setDirectDependencies(Dependencies);
480 
481  // Rate (particle number rate)
482  success = mpExpression->compile(listOfContainer);
483  Dependencies = mpExpression->getDirectDependencies();
484 
485  if (pVolumeReference)
486  Dependencies.insert(pVolumeReference);
487 
488  mpRateReference->setDirectDependencies(Dependencies);
490  Dependencies.clear();
491 
492  // Concentration Rate
493  Dependencies.insert(mpRateReference);
494  Dependencies.insert(mpConcReference);
495 
496  if (pVolumeReference)
497  Dependencies.insert(pVolumeReference);
498 
499  if (mpCompartment)
500  Dependencies.insert(mpCompartment->getRateReference());
501 
504  Dependencies.clear();
505 
506  // Transition Time
507  Dependencies.insert(mpValueReference);
508  Dependencies.insert(mpRateReference);
509  mpTTReference->setDirectDependencies(Dependencies);
511  Dependencies.clear();
512  break;
513 
514  case REACTIONS:
515  // Concentration
516  Dependencies.insert(mpValueReference);
517 
518  if (pVolumeReference)
519  Dependencies.insert(pVolumeReference);
520 
521  mpConcReference->setDirectDependencies(Dependencies);
523 
524  Dependencies.clear();
525 
526  // Create the rate vector
527  {
530 
531  for (; it != end; ++it)
532  {
533  const CCopasiVector< CChemEqElement > &Balances =
534  (*it)->getChemEq().getBalances();
537 
538  for (; itChem != endChem; ++itChem)
539  if ((*itChem)->getMetaboliteKey() == mKey)
540  break;
541 
542  if (itChem != endChem)
543  {
544  Dependencies.insert((*it)->getParticleFluxReference());
545 
546  std::pair< C_FLOAT64, const C_FLOAT64 * > Insert;
547  Insert.first = (*itChem)->getMultiplicity();
548  Insert.second = &(*it)->getParticleFlux();
549 
550  mRateVector.push_back(Insert);
551  }
552  }
553  }
554 
555  // Rate (particle number rate)
557  mpRateReference->setDirectDependencies(Dependencies);
558 
559  // Transition Time
561  mpTTReference->setDirectDependencies(Dependencies);
562  Dependencies.clear();
563 
564  // Concentration Rate
565  Dependencies.insert(mpRateReference);
566  Dependencies.insert(mpConcReference);
567 
568  if (pVolumeReference)
569  Dependencies.insert(pVolumeReference);
570 
571  if (mpCompartment)
572  Dependencies.insert(mpCompartment->getRateReference());
573 
576  Dependencies.clear();
577 
578  break;
579 
580  default:
581  break;
582  }
583 
584  // The initial values
585  success &= compileInitialValueDependencies();
586 
587  return success;
588 }
589 
591 {
592  bool success = true;
593  std::set<const CCopasiObject *> Dependencies;
594  std::vector< CCopasiContainer * > listOfContainer;
595  listOfContainer.push_back(getObjectAncestor("Model"));
596 
597  // If we have an assignment or a valid initial expression we must update both
598  if (getStatus() == ASSIGNMENT ||
599  (mpInitialExpression != NULL &&
600  mpInitialExpression->getInfix() != ""))
601  {
602  // Initial concentration
603  success &= mpInitialExpression->compile(listOfContainer);
605 
606  // Initial particle number
607  Dependencies.insert(mpIConcReference);
608 
609  if (mpCompartment)
610  Dependencies.insert(mpCompartment->getInitialValueReference());
611 
613  Dependencies.clear();
614 
615  // If we have a valid initial expression, we update the initial value.
616  // In case the expression is constant this suffices others are updated lated again.
619 
620  return success;
621  }
622 
623  // The context sensitivity is handle in the virtual method getDirectDependencies();
624 
625  // Initial particle number
626  Dependencies.insert(mpIConcReference);
627 
628  if (mpCompartment)
629  Dependencies.insert(mpCompartment->getInitialValueReference());
630 
632  Dependencies.clear();
633 
634  // Initial concentration
635  Dependencies.insert(mpIValueReference);
636 
637  if (mpCompartment)
638  Dependencies.insert(mpCompartment->getInitialValueReference());
639 
641  return success;
642 }
643 
645 {
646  // We check whether changing the initial concentration will lead to circular
647  // dependencies in the system.
648 
649  // These circular dependencies must always involve the initial particle number, i.e.,
650  // it suffices to check whether the initial particle number has circular dependencies when the
651  // concentration is changes.
652 
653  CCopasiObject::DataObjectSet Candidates;
656 
657  Context.insert(this->mpIConcReference);
658 
660 
661  return;
662 }
663 
665 {
667 }
668 
670 {
671  switch (getStatus())
672  {
673  case FIXED:
674  break;
675 
676  case ASSIGNMENT:
678  break;
679 
680  case ODE:
682  break;
683 
684  case REACTIONS:
685 
686  if (isDependent())
688 
689  break;
690 
691  default:
692  break;
693  }
694 }
695 
697 {
698  switch (getStatus())
699  {
700  case FIXED:
701  break;
702 
703  case ASSIGNMENT:
704  break;
705 
706  case ODE:
707  break;
708 
709  case REACTIONS:
710  {
711  mRate = 0.0;
712 
713  std::vector< std::pair< C_FLOAT64, const C_FLOAT64 * > >::const_iterator it =
714  mRateVector.begin();
715  std::vector< std::pair< C_FLOAT64, const C_FLOAT64 * > >::const_iterator end =
716  mRateVector.end();
717 
718  for (; it != end; ++it)
719  mRate += it->first * *it->second;
720  }
721  break;
722 
723  default:
724  break;
725  }
726 }
727 
729 {
730  switch (getStatus())
731  {
732  case FIXED:
733  break;
734 
735  case ASSIGNMENT:
736  break;
737 
738  case ODE:
739  mTT = *mpValue / fabs(mRate);
740  break;
741 
742  case REACTIONS:
743  {
744  C_FLOAT64 PositiveFlux = 0;
745  C_FLOAT64 NegativeFlux = 0;
746  C_FLOAT64 Flux;
747 
748  std::vector< std::pair< C_FLOAT64, const C_FLOAT64 * > >::const_iterator it =
749  mRateVector.begin();
750  std::vector< std::pair< C_FLOAT64, const C_FLOAT64 * > >::const_iterator end =
751  mRateVector.end();
752 
753  for (; it != end; ++it)
754  {
755  Flux = it->first * *it->second;
756 
757  if (Flux > 0.0)
758  PositiveFlux += Flux;
759  else
760  NegativeFlux -= Flux;
761  }
762 
763  Flux = std::min(PositiveFlux, NegativeFlux);
764 
765  if (Flux == 0.0)
766  mTT = std::numeric_limits<C_FLOAT64>::infinity();
767  else
768  mTT = *mpValue / Flux;
769  }
770  break;
771 
772  default:
773  break;
774  }
775 }
776 
778 {
779  // We need to have mpIValueRefernce point to a CParticleReference object.
780  C_FLOAT64 * pValue = static_cast< C_FLOAT64 * >(mpValueReference->getValuePointer());
781  assert(pValue != NULL);
783  mpIValueReference = new CParticleReference("InitialParticleNumber", this, *pValue);
785 
786  // We need to have mpValueRefernce point to a CParticleReference object.
787  pValue = static_cast< C_FLOAT64 * >(mpValueReference->getValuePointer());
788  assert(pValue != NULL);
790  mpValueReference = new CParticleReference("ParticleNumber", this, *pValue);
791 
792  mpRateReference->setObjectName("ParticleNumberRate");
793 
794  mpIConcReference = new CConcentrationReference("InitialConcentration", this, mIConc);
796 
797  mpConcReference = new CConcentrationReference("Concentration", this, mConc);
798 
801 
802  mpTTReference =
804 }
805 
807 {
809 
810  Deleted.insert(mpIConcReference);
811  Deleted.insert(mpConcReference);
812  Deleted.insert(mpConcRateReference);
813  Deleted.insert(mpTTReference);
814 
815  return Deleted;
816 }
817 
818 // virtual
819 bool CMetab::mustBeDeleted(const CCopasiObject::DataObjectSet & deletedObjects) const
820 {
821  bool MustBeDeleted = false;
822 
823  DataObjectSet ChildObjects = getDeletedObjects();
824 
825  DataObjectSet::const_iterator it = ChildObjects.begin();
826  DataObjectSet::const_iterator end = ChildObjects.end();
827 
828  for (; it != end; ++it)
829  {
830  if (*it == this)
831  {
832  if ((*it)->CCopasiObject::mustBeDeleted(deletedObjects))
833  {
834  MustBeDeleted = true;
835  break;
836  }
837 
838  continue;
839  }
840 
841  // The following objects are automatically corrected, i.e., they
842  // are no reasons for being deleted.
843  if (getStatus() == REACTIONS &&
844  (*it == this->mpConcRateReference ||
845  *it == this->mpRateReference ||
846  *it == this->mpTTReference))
847  {
848  continue;
849  }
850 
851  if ((*it)->mustBeDeleted(deletedObjects))
852  {
853  MustBeDeleted = true;
854  break;
855  }
856  }
857 
858  return MustBeDeleted;
859 }
860 
862 {return mpIConcReference;}
863 
865 {return mpConcReference;}
866 
868 {return mpConcRateReference;}
869 
871 {
872  const_cast<CMetab *>(this)->refreshConcentrationRate();
873  return mConcRate;
874 }
875 
877 {
878  // d(Particle Number*conversion/Volume)/dt
879  // = (Rate / Volume - Particle Number / Volume^2 * Volume Rate) * conversion
880  // = (Rate - Particle Number / Volume * Volume Rate) / Volume * conversion
881  // = (Rate * conversion - Concentration * Volume Rate) / Volume
882 
883  mConcRate =
885  / mpCompartment->getValue();
886 }
887 
888 // virtual
890 {
891  return mpConcReference;
892 }
893 
894 // virtual
896 {
897  return const_cast<C_FLOAT64 *>(&mConc);
898 }
899 
900 std::ostream & operator<<(std::ostream &os, const CMetab & d)
901 {
902  os << " ++++CMetab: " << d.getObjectName() << std::endl;
903  os << " mConc " << d.mConc << " mIConc " << d.mIConc << std::endl;
904  os << " mValue (particle number) " << *d.mpValue << " mIValue " << *d.mpIValue << std::endl;
905  os << " mRate " << d.mRate << " mTT " << d.mTT << " mStatus " << d.getStatus() << std::endl;
906 
907  if (d.mpCompartment)
908  os << " mpCompartment == " << d.mpCompartment << std::endl;
909  else
910  os << " mpCompartment == 0 " << std::endl;
911 
912  if (d.mpModel)
913  os << " mpModel == " << d.mpModel << std::endl;
914  else
915  os << " mpModel == 0 " << std::endl;
916 
917  os << " ----CMetab " << std::endl;
918 
919  return os;
920 }
921 
923 {
924  C_INT32 Fail = 0;
925 
926  std::string tmp;
927  Fail = configbuffer.getVariable("Metabolite", "string",
928  (void *) & tmp,
930 
931  if (Fail)
932  return Fail;
933 
934  setObjectName(tmp);
935 
936  Fail = configbuffer.getVariable("InitialConcentration", "C_FLOAT64",
937  (void *) & mIConc);
938 
941 
942  Status GepasiStatus;
943  Fail = configbuffer.getVariable("Type", "C_INT16",
944  (void *) & GepasiStatus);
945 
946  if (Fail)
947  return Fail;
948 
949  setStatus(GepasiStatus);
950 
951  // sanity check
952  if ((GepasiStatus < 0) || (GepasiStatus > 7))
953  {
955  "The file specifies a non-existing type "
956  "for '%s'.\nReset to internal species.",
957  getObjectName().c_str());
959  }
960 
961  // sanity check
962  if ((GepasiStatus != METAB_MOIETY) && (mIConc < 0.0))
963  {
965  "The file specifies a negative concentration "
966  "for '%s'.\nReset to default.",
967  getObjectName().c_str());
968  mIConc = 1.0;
969  }
970 
971  return Fail;
972 }
973 
974 std::string CMetab::getObjectDisplayName(bool regular, bool richtext) const
975 {
976  CModel* tmp = dynamic_cast<CModel*>(this->getObjectAncestor("Model"));
977 
978  if (tmp)
979  {
980  return CMetabNameInterface::getDisplayName(tmp, *this, false);
981  }
982 
983  return CCopasiObject::getObjectDisplayName(regular, richtext);
984 }
985 
986 void CMetab::setDependentOn(const CMoiety * pMoiety)
987 {mpMoiety = pMoiety;}
988 
990 {return mpMoiety != NULL;}
991 
992 const CMoiety * CMetab::getMoiety() const
993 {return mpMoiety;}
994 
995 //******************* CMetabOld ***************************************************
996 
997 CMetabOld::CMetabOld(const std::string & name,
998  const CCopasiContainer * pParent):
999  CCopasiContainer(name, pParent, "Old Metabolite"),
1000  mIConc(1.0),
1001  mStatus(CModelEntity::REACTIONS),
1002  mCompartment()
1004 
1006  const CCopasiContainer * pParent):
1007  CCopasiContainer(src, pParent),
1008  mIConc(src.mIConc),
1009  mStatus(src.mStatus),
1010  mCompartment(src.mCompartment)
1012 
1014 
1016 
1018 {
1019  C_INT32 Fail = 0;
1020  std::string tmp;
1021  Fail = configbuffer.getVariable("Metabolite", "string",
1022  (void *) & tmp,
1024 
1025  if (Fail)
1026  return Fail;
1027 
1028  setObjectName(tmp);
1029 
1030  Fail = configbuffer.getVariable("Concentration", "C_FLOAT64",
1031  (void *) & mIConc);
1032 
1033  if (Fail)
1034  return Fail;
1035 
1036  Fail = configbuffer.getVariable("Compartment", "C_INT32",
1037  (void *) & mCompartment);
1038 
1039  if (Fail)
1040  return Fail;
1041 
1042  C_INT32 Status;
1043 
1044  Fail = configbuffer.getVariable("Type", "C_INT32",
1045  (void *) & Status);
1046 
1047  if (Status == 0)
1049  else
1051 
1052  // sanity check
1053  if ((mStatus < 0) || (mStatus > 7))
1054  {
1056  "The file specifies a non-existing type "
1057  "for '%s'.\nReset to internal species.",
1058  getObjectName().c_str());
1060  }
1061 
1062  // sanity check
1063  if ((mStatus != METAB_MOIETY) && (mIConc < 0.0))
1064  {
1066  "The file specifies a negative concentration "
1067  "for '%s'.\nReset to default.",
1068  getObjectName().c_str());
1069  mIConc = 1.0;
1070  }
1071 
1072  return Fail;
1073 }
1074 
1076 
1077 // static
1079 
1081  const CCopasiContainer * pParent,
1082  C_FLOAT64 & reference) :
1083  CCopasiObjectReference< C_FLOAT64 >(name, pParent, reference),
1084  mpApplyInitialValuesRefresh(NULL)
1085 {
1086  const CMetab * pMetab = static_cast< const CMetab * >(pParent);
1087 
1089  new RefreshTemplate< CMetab >(const_cast< CMetab * >(pMetab),
1091 }
1092 
1094  const CCopasiContainer * pParent) :
1095  CCopasiObjectReference< C_FLOAT64 >(src, pParent),
1096  mpApplyInitialValuesRefresh(NULL)
1097 {
1098  const CMetab * pMetab = static_cast< const CMetab * >(pParent);
1099 
1101  new RefreshTemplate< CMetab >(const_cast< CMetab * >(pMetab),
1103 }
1104 
1106 {
1108 }
1109 
1110 // virtual
1113 {
1114  // If the concentration was changed in the context it has no further dependencies
1115  if (context.count(this) > 0)
1116  {
1117  return EmptyDependencies;
1118  }
1119 
1121 }
1122 
1123 // virtual
1125  const CMath::SimulationContextFlag & /* context */,
1126  const CObjectInterface::ObjectSet & changedObjects) const
1127 {
1128  // If the value is in the context, it does not depend on the object.
1129  if (changedObjects.find(this) != changedObjects.end())
1130  return false;
1131 
1132  // Densities which are not in the context have to be recalculated.
1133  return true;
1134 }
1135 
1137 {
1139 }
1140 
1141 // static
1143 
1145  const CCopasiContainer * pParent,
1146  C_FLOAT64 & reference) :
1147  CCopasiObjectReference< C_FLOAT64 >(name, pParent, reference),
1148  mPrerequisites()
1149 {}
1150 
1152  const CCopasiContainer * pParent) :
1153  CCopasiObjectReference< C_FLOAT64 >(src, pParent)
1154 {}
1155 
1157 {}
1158 
1159 // virtual
1162 {
1163  // If the particle number was changed in the context it has no further dependencies
1164  if (context.count(this) > 0)
1165  {
1166  return EmptyDependencies;
1167  }
1168 
1169  const CMetab * pSpecies = static_cast< const CMetab * >(getObjectParent());
1170 
1171  // In an assignment the particles (initial or transient) have always dependencies
1172  if (pSpecies == NULL ||
1173  pSpecies->getStatus() == CModelEntity::ASSIGNMENT)
1174  {
1176  }
1177 
1178  // We need to distinguish between initial and transient value.
1179  const CCopasiObject * pConcentrationReference = NULL;
1180 
1181  if (getObjectName() == "InitialParticleNumber")
1182  {
1183  // If we have an initial expression the initial particle number has dependencies.
1184  if (pSpecies->getInitialExpression() != "")
1186 
1187  pConcentrationReference = pSpecies->getInitialConcentrationReference();
1188  }
1189  else
1190  {
1191  pConcentrationReference = pSpecies->getConcentrationReference();
1192  }
1193 
1194  // In other cases we need to find out whether the concentration was changed in
1195  // the context.
1196 
1197  if (pConcentrationReference != NULL &&
1198  context.count(pConcentrationReference) > 0)
1199  {
1201  }
1202 
1203  return EmptyDependencies;
1204 }
1205 
1206 // virtual
1208 {
1210  const CMoiety * pMoiety = static_cast< const CMetab * >(getObjectParent())->getMoiety();
1211 
1212  if (pMoiety != NULL)
1213  {
1214  mPrerequisites.insert(pMoiety->getDependentNumberReference());
1215  }
1216 
1217  return mPrerequisites;
1218 }
1219 
1220 // virtual
1222  const CMath::SimulationContextFlag & context ,
1223  const CObjectInterface::ObjectSet & changedObjects) const
1224 {
1225  const CMetab * pSpecies = static_cast< const CMetab * >(getObjectParent());
1226 
1227  if ((context & CMath::UseMoieties) &&
1228  pSpecies->isDependent())
1229  {
1230  return true;
1231  }
1232 
1233  // If the value is changed it must not be recalculated, i.e., it does not depend on the object.
1234  if (changedObjects.find(this) != changedObjects.end())
1235  return false;
1236 
1237  // Amounts which are determine by assignment need to be recalculated.
1238  if (pSpecies->getStatus() == CModelEntity::ASSIGNMENT)
1239  return true;
1240 
1241  const CConcentrationReference * pConcentrationReference = NULL;
1242 
1243  if (getObjectName() != "ParticleNumber")
1244  {
1245  pConcentrationReference = pSpecies->getInitialConcentrationReference();
1246  }
1247  else
1248  {
1249  pConcentrationReference = pSpecies->getConcentrationReference();
1250  }
1251 
1252  // If the concentration was changed in the context we need to recalculate.
1253  if (changedObjects.find(pConcentrationReference) != changedObjects.end())
1254  return true;
1255 
1256  return false;
1257 }
Header file of class CExpression.
CCopasiDataModel * getObjectDataModel()
C_INT32 load(CReadConfig &configbuffer)
Definition: CMetab.cpp:922
void setInitialConcentration(const C_FLOAT64 &initialConcentration)
Definition: CMetab.cpp:257
CCopasiContainer * getObjectAncestor(const std::string &type) const
bool remove(const std::string &key)
static DataObjectSet EmptyDependencies
Definition: CMetab.h:170
virtual std::string getObjectDisplayName(bool regular=true, bool richtext=false) const
void clearDirectDependencies()
void setRefresh(CType *pType, void(CType::*method)(void))
#define pdelete(p)
Definition: copasi.h:215
const CMoiety * getMoiety() const
Definition: CMetab.cpp:992
CCopasiObjectReference< C_FLOAT64 > * mpIValueReference
Definition: CModelValue.h:356
std::string getTimeUnitsDisplayString() const
Definition: CModel.cpp:4531
CExpression * mpInitialExpression
Definition: CModelValue.h:341
const C_FLOAT64 & getRate() const
CMetab & operator=(const CMetabOld &rhs)
Definition: CMetab.cpp:93
void initCompartment(const CCompartment *pCompartment=NULL)
Definition: CMetab.cpp:209
const std::string & getObjectName() const
std::string getFrequencyUnitsDisplayString() const
Definition: CModel.cpp:4539
virtual void setStatus(const CModelEntity::Status &status)
Definition: CMetab.cpp:291
C_FLOAT64 mTT
Definition: CMetab.h:226
static DataObjectSet EmptyDependencies
Definition: CMetab.h:100
virtual void * getValuePointer() const
Definition: CMetab.cpp:895
const C_FLOAT64 & getInitialConcentration() const
Definition: CMetab.cpp:220
C_FLOAT64 mRate
Definition: CModelValue.h:331
C_FLOAT64 * mpValue
Definition: CModelValue.h:321
virtual bool setObjectParent(const CCopasiContainer *pParent)
Definition: CMetab.cpp:231
bool mIsInitialConcentrationChangeAllowed
Definition: CMetab.h:241
virtual void calculate()
Definition: CMetab.cpp:669
bool hasCircularDependencies(DataObjectSet &candidates, DataObjectSet &verified, const DataObjectSet &context) const
CCopasiObject * getInitialValueReference() const
bool compileInitialValueDependencies()
Definition: CMetab.cpp:590
virtual bool mustBeDeleted(const DataObjectSet &deletedObjects) const
Definition: CMetab.cpp:819
iterator begin()
void setDirectDependencies(const DataObjectSet &directDependencies)
CCopasiObjectReference< C_FLOAT64 > * mpRateReference
Definition: CModelValue.h:358
C_INT32 load(CReadConfig &configbuffer)
Definition: CMetab.cpp:1017
virtual std::string getObjectDisplayName(bool regular=true, bool richtext=false) const
Definition: CMetab.cpp:974
virtual bool compile(std::vector< CCopasiContainer * > listOfContainer=CCopasiContainer::EmptyList)
Definition: CExpression.cpp:97
~CMetabOld()
Definition: CMetab.cpp:1013
#define C_INT32
Definition: copasi.h:90
static std::string getDisplayName(const CModel *model, const std::string &key, const bool &quoted)
C_FLOAT64 mConc
Definition: CMetab.h:211
Definition: CMetab.h:178
static CExpression * createInitialExpression(const CExpression &expression, const CCopasiDataModel *pDataModel)
virtual bool isPrerequisiteForContext(const CObjectInterface *pObject, const CMath::SimulationContextFlag &context, const CObjectInterface::ObjectSet &changedObjects) const
Definition: CMetab.cpp:1124
virtual const DataObjectSet & getDirectDependencies(const DataObjectSet &context=DataObjectSet()) const
Definition: CMetab.cpp:1112
void cleanup()
Definition: CMetab.cpp:207
C_FLOAT64 * mpIValue
Definition: CModelValue.h:326
virtual DataObjectSet getDeletedObjects() const
Definition: CMetab.cpp:806
std::string mKey
Definition: CAnnotation.h:119
bool isFixed() const
Definition: CModelValue.h:124
const C_FLOAT64 & getInitialValue() const
virtual const CCopasiObject * getValueObject() const
Definition: CMetab.cpp:889
CMetabOld(const std::string &name="NoName", const CCopasiContainer *pParent=NULL)
Definition: CMetab.cpp:997
virtual std::string getChildObjectUnits(const CCopasiObject *pObject) const
#define DESTRUCTOR_TRACE
Definition: copasi.h:206
iterator end()
const C_FLOAT64 & getQuantity2NumberFactor() const
Definition: CModel.cpp:2354
void setDependentOn(const CMoiety *pMoiety)
Definition: CMetab.cpp:986
const C_FLOAT64 & getNumber2QuantityFactor() const
Definition: CModel.cpp:2357
virtual const C_FLOAT64 & calcValue()
const CCompartment * mpCompartment
Definition: CMetab.h:232
const bool & isInitialConcentrationChangeAllowed() const
Definition: CMetab.cpp:664
virtual void setStatus(const CModelEntity::Status &status)
const CModel * getModel() const
Definition: CMetab.cpp:224
Refresh * mpApplyInitialValuesRefresh
Definition: CMetab.h:105
CCopasiObject * getConcentrationRateReference() const
Definition: CMetab.cpp:867
std::string getInitialExpression() const
C_FLOAT64 mConcRate
Definition: CMetab.h:221
void refreshRate()
Definition: CMetab.cpp:696
const C_FLOAT64 & getDependentNumber() const
Definition: CMoiety.cpp:145
void refreshNumber()
Definition: CMetab.cpp:286
void refreshTransitionTime()
Definition: CMetab.cpp:728
bool isUsable() const
virtual void refreshInitialValue()
Definition: CMetab.cpp:264
static C_FLOAT64 convertToNumber(const C_FLOAT64 &concentration, const CCompartment &compartment, const CModel &model)
Definition: CMetab.cpp:35
void setConcentration(const C_FLOAT64 concentration)
Definition: CMetab.cpp:250
CCopasiObjectReference< C_FLOAT64 > * mpValueReference
Definition: CModelValue.h:357
std::string add(const std::string &prefix, CCopasiObject *pObject)
void refreshInitialConcentration()
Definition: CMetab.cpp:269
void compileIsInitialConcentrationChangeAllowed()
Definition: CMetab.cpp:644
virtual std::set< const CCopasiObject * > getDeletedObjects() const
virtual void * getValuePointer() const
CCopasiObjectReference< C_FLOAT64 > * mpTTReference
Definition: CMetab.h:247
bool isDependent() const
Definition: CMetab.cpp:989
virtual std::string getChildObjectUnits(const CCopasiObject *pObject) const
Definition: CMetab.cpp:118
C_INT32 getIndex() const
Definition: CMetab.cpp:1075
CConcentrationReference * mpIConcReference
Definition: CMetab.h:244
std::set< const CObjectInterface * > ObjectSet
virtual bool compile()
Definition: CMetab.cpp:385
void refreshConcentration()
Definition: CMetab.cpp:281
virtual const DataObjectSet & getDirectDependencies(const DataObjectSet &context=DataObjectSet()) const
virtual bool setObjectParent(const CCopasiContainer *pParent)
#define METAB_MOIETY
Definition: CMetab.cpp:32
std::string getQuantityUnitsDisplayString() const
Definition: CModel.cpp:4647
const C_FLOAT64 & getValue() const
CMetab::Status mStatus
Definition: CMetab.h:501
static CKeyFactory * getKeyFactory()
C_INT32 mCompartment
Definition: CMetab.h:506
C_FLOAT64 mIConc
Definition: CMetab.h:216
#define C_FLOAT64
Definition: copasi.h:92
void refreshConcentrationRate()
Definition: CMetab.cpp:876
Refresh * getApplyInitialValueRefresh() const
Definition: CMetab.cpp:1136
void initObjects()
Definition: CMetab.cpp:777
CExpression * mpExpression
Definition: CModelValue.h:336
C_FLOAT64 mIConc
Definition: CMetab.h:495
const CMoiety * mpMoiety
Definition: CMetab.h:237
virtual const DataObjectSet & getDirectDependencies(const DataObjectSet &context=DataObjectSet()) const
Definition: CMetab.cpp:1161
CCopasiVectorNS< CReaction > & getReactions()
Definition: CModel.cpp:1039
const C_FLOAT64 & getConcentration() const
Definition: CMetab.cpp:218
virtual void setInitialValue(const C_FLOAT64 &initialValue)
Definition: CModel.h:50
~CMetab()
Definition: CMetab.cpp:111
C_INT32 getVariable(const std::string &name, const std::string &type, void *pout, CReadConfig::Mode mode=CReadConfig::NEXT)
Definition: CReadConfig.cpp:81
virtual const CObjectInterface::ObjectSet & getPrerequisites() const
Definition: CMetab.cpp:1207
const CModelEntity::Status & getStatus() const
CConcentrationReference * getInitialConcentrationReference() const
Definition: CMetab.cpp:861
CMetab(const std::string &name="NoName", const CCopasiContainer *pParent=NULL)
Definition: CMetab.cpp:46
void cleanup()
Definition: CMetab.cpp:1015
bool setObjectName(const std::string &name)
const C_FLOAT64 & getTransitionTime() const
Definition: CMetab.cpp:229
C_FLOAT64 getConcentrationRate() const
Definition: CMetab.cpp:870
CCopasiObject * getRateReference() const
CCopasiObjectReference< C_FLOAT64 > * mpConcRateReference
Definition: CMetab.h:246
std::set< const CCopasiObject * > DataObjectSet
void setTransitionTime(const C_FLOAT64 &transitionTime)
Definition: CMetab.cpp:226
static C_FLOAT64 convertToConcentration(const C_FLOAT64 &number, const CCompartment &compartment, const CModel &model)
Definition: CMetab.cpp:41
CModel * mpModel
Definition: CModelValue.h:359
CCopasiObject * addObjectReference(const std::string &name, CType &reference, const unsigned C_INT32 &flag=0)
const CCompartment * getCompartment() const
Definition: CMetab.cpp:222
ObjectSet mPrerequisites
Definition: CMetab.h:175
#define min(a, b)
Definition: f2c.h:175
CConcentrationReference * mpConcReference
Definition: CMetab.h:245
std::ostream & operator<<(std::ostream &os, const CMetab &d)
Definition: CMetab.cpp:900
const std::string & getInfix() const
CCopasiObject * getDependentNumberReference() const
Definition: CMoiety.cpp:151
CCopasiContainer * getObjectParent() const
#define CONSTRUCTOR_TRACE
Definition: copasi.h:202
virtual bool isPrerequisiteForContext(const CObjectInterface *pObject, const CMath::SimulationContextFlag &context, const CObjectInterface::ObjectSet &changedObjects) const
Definition: CMetab.cpp:1221
CConcentrationReference * getConcentrationReference() const
Definition: CMetab.cpp:864
CCopasiObject * getValueReference() const
std::vector< std::pair< C_FLOAT64, const C_FLOAT64 * > > mRateVector
Definition: CMetab.h:239