COPASI API  4.16.103
CFunctionDB.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010 - 2013 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 /**
16  * CFunctionDB
17  *
18  * Created for Copasi by Stefan Hoops
19  * (C) Stefan Hoops 2001
20  */
21 
22 #include <algorithm>
23 
24 #include "copasi.h"
25 
26 #include "CFunctionDB.h"
27 #include "CFunction.h"
28 #include "FunctionDB.xml.h"
29 
32 #include "report/CKeyFactory.h"
33 #include "xml/CCopasiXML.h"
34 #include "model/CModel.h"
35 
36 CFunctionDB::CFunctionDB(const std::string & name,
37  const CCopasiContainer * pParent):
38  CCopasiContainer(name, pParent, "FunctionDB"),
39  mFilename(),
40  mLoadedFunctions("Functions", this)
41 {
42  initObjects();
44 }
45 
47 {
48  cleanup();
50 }
51 
53 
55 {
57 }
58 
60 {
61  CCopasiXML XML;
63 
64  std::stringstream DB;
65  DB.str(FunctionDBxml);
66 
67  if (DB.fail())
68  return false;
69 
70  if (!XML.load(DB, ""))
71  return false;
72 
73  return true;
74 }
75 
76 bool CFunctionDB::load(const std::string& fileName)
77 {
78  CCopasiXML XML;
80  std::fstream str(fileName.c_str());
81 
82  if (str.fail())
83  return false;
84 
85  if (!XML.load(str, ""))
86  return false;
87 
88  return true;
89 }
90 
91 bool CFunctionDB::save(const std::string& fileName)
92 {
93  CCopasiXML XML;
95  return XML.CCopasiXMLInterface::save(fileName, fileName);
96 }
97 
99 {
100  CFunction Function;
101  CFunction * pFunction = NULL;
102 
103  C_INT32 Size = 0;
104  C_INT32 Fail = 0;
105 
106  configbuffer.getVariable("TotalUDKinetics", "C_INT32", &Size,
108 
109  for (C_INT32 i = 0; i < Size; i++)
110  {
111  Function.load(configbuffer);
112 
113  switch (Function.getType())
114  {
116  pFunction = new CFunction(Function);
117  break;
118 
120  pFunction = new CMassAction(Function);
121  break;
122 
125  pFunction = new CKinFunction(Function,
126  &configbuffer);
127  break;
128 
129  default:
130  fatalError();
131  break;
132  }
133 
134  pFunction->compile();
135 
136  if (!mLoadedFunctions.add(pFunction, true))
137  {
138  pdelete(pFunction);
139 
140  // We ignore:
141  // CCopasiVector (2): Object '%s' allready exists.
142  if ((MCCopasiVector + 2) != CCopasiMessage::peekLastMessage().getNumber())
143  return Fail = 1;
144 
145  // Remove the ignored meesage.
147  }
148  }
149 
150  return Fail;
151 }
152 
153 void CFunctionDB::setFilename(const std::string & filename)
154 {mFilename = filename;}
155 
156 std::string CFunctionDB::getFilename() const
157 {return mFilename;}
158 
159 #ifdef FFFF
160 CFunction * CFunctionDB::dBLoad(const std::string & functionName)
161 {
162  CFunction Function("NoName", &mLoadedFunctions);
163  CFunction * pFunction = NULL;
164 
165  if (mFilename == "") return NULL;
166 
167  CReadConfig inbuf(mFilename);
168 
169  while (functionName != Function.getObjectName())
170  {
171  Function.cleanup();
172  Function.load(inbuf);
173  }
174 
175  switch (Function.getType())
176  {
177  case CFunction::Base:
178  pFunction = new CFunction(Function);
179  break;
180 
182  pFunction = new CMassAction(Function.isReversible());
183  break;
184 
186 
188  pFunction = new CKinFunction(Function, &inbuf);
189  break;
190 
192  fatalError(); //disabled
193  //pFunction = new CUDFunction(Function);
194  break;
195 
196  default:
197  fatalError();
198  }
199 
200  if (!mLoadedFunctions.add(pFunction))
201  {
202  pdelete(pFunction);
203 
204  // We ignore:
205  // CCopasiVector (2): Object '%s' allready exists.
206  if ((MCCopasiVector + 2) != CCopasiMessage::getLastMessage().getNumber())
207 
208  pFunction = mLoadedFunctions[Function.getObjectName()];
209  }
210 
211  return pFunction;
212 }
213 #endif // FFFF
214 
215 #ifdef FFFF
216 CEvaluationTree * CFunctionDB::createFunction(const std::string & name, const CEvaluationTree::Type & type)
217 {
219  return NULL;
220 
221  //CFunction * pFunction = new CFunction(name);
222 
223  CEvaluationTree * pFunction = NULL;
224 
225  switch (type)
226  {
227  case CEvaluationTree::Base:
228  pFunction = new CFunction(name);
229  break;
230 
232  pFunction = new CMassAction(name);
233  break;
234 
235  case CEvaluationTree::PreDefinedKineticLaw:
236  case CEvaluationTree::UserDefinedKineticLaw:
237  pFunction = new CKinFunction(name);
238  break;
239 
240  default:
241  fatalError();
242  }
243 
244  if (!mLoadedFunctions.add(pFunction, true))
245  {
246  delete pFunction;
247  return NULL;
248  }
249 
250  return pFunction;
251 }
252 #endif // FFFF
253 
254 bool CFunctionDB::add(CFunction * pFunction,
255  const bool & adopt)
256 {return mLoadedFunctions.add(pFunction, adopt);}
257 
259 {
260  if (!pFunction) return NULL;
261 
262  std::string basename = pFunction->getObjectName();
263  std::string name = basename;
264  //CFunction* pFunc;
265  //CCopasiVectorN<CEvaluationTree>& FunctionList
266  //= this->loadedFunctions();
267  int i = 0;
268 
269  size_t Index = C_INVALID_INDEX;
270 
271  while ((Index = mLoadedFunctions.getIndex(name)) != C_INVALID_INDEX)
272  {
273  // Check whether the new functions and the old are the same.
274  if (*mLoadedFunctions[Index] == *pFunction)
275  {
276  pdelete(pFunction);
277  return mLoadedFunctions[Index];
278  }
279 
280  i++;
281  std::ostringstream ss; ss << "[" << i << "]";
282  name = basename + ss.str();
283  }
284 
285  pFunction->setObjectName(name);
286  this->add(pFunction, true);
287 
288  return pFunction;
289 }
290 
291 bool CFunctionDB::removeFunction(size_t index)
292 {
293  if (index == C_INVALID_INDEX) return false;
294 
295  // We need to delete all dependent objects in all data models.
298 
299  std::set< const CCopasiObject * > DeletedObjects = mLoadedFunctions[index]->getDeletedObjects();
300 
301  for (; it != end; ++it)
302  {
303  (*it)->getModel()->removeDependentModelObjects(DeletedObjects);
304  }
305 
306  mLoadedFunctions.CCopasiVector<CFunction>::remove(index);
307 
308  return true;
309 }
310 
311 bool CFunctionDB::removeFunction(const std::string &key)
312 {
313  CEvaluationTree* func = dynamic_cast< CEvaluationTree * >(CCopasiRootContainer::getKeyFactory()->get(key));
314 
315  if (!func) return false;
316 
317  size_t index =
318  mLoadedFunctions.CCopasiVector<CFunction>::getIndex(func);
319 
320  if (index == C_INVALID_INDEX) return false;
321 
322  return removeFunction(index);
323 }
324 
325 CFunction * CFunctionDB::findFunction(const std::string & functionName)
326 {
327  size_t index = mLoadedFunctions.getIndex(functionName);
328 
329  if (index != C_INVALID_INDEX)
330  return mLoadedFunctions[index];
331  else
332  return NULL;
333 }
334 
335 CFunction * CFunctionDB::findLoadFunction(const std::string & functionName)
336 {
337  size_t i;
338 
339  for (i = 0; i < mLoadedFunctions.size(); i++)
340  if (functionName == mLoadedFunctions[i]->getObjectName())
341  return mLoadedFunctions[i];
342 
343  return NULL;
344 }
345 
347 {return mLoadedFunctions;}
348 
349 std::vector<CFunction*>
350 CFunctionDB::suitableFunctions(const size_t noSubstrates,
351  const size_t noProducts,
352  const TriLogic reversibility)
353 {
354  std::vector<CFunction*> ret;
355  CFunction *pFunction;
356 
357  size_t i, imax = mLoadedFunctions.size();
358 
359  for (i = 0; i < imax; i++)
360  {
361  pFunction = dynamic_cast<CFunction *>(mLoadedFunctions[i]);
362 
363  if (!pFunction) continue;
364 
365  if (pFunction->isSuitable(noSubstrates, noProducts, reversibility))
366  ret.push_back(pFunction);
367  }
368 
369  //always add constant flux it is is missing
370  if (reversibility == TriTrue)
371  {
372  if ((noSubstrates > 0) || (noProducts > 0)) //constant flux was not yet added
373  {
374  pFunction = dynamic_cast<CFunction*>(findFunction("Constant flux (reversible)"));
375 
376  if (!pFunction) fatalError();
377 
378  ret.push_back(pFunction);
379  }
380  }
381  else //irreversible
382  {
383  if (noSubstrates > 0) //constant flux was not yet added
384  {
385  pFunction = dynamic_cast<CFunction*>(findFunction("Constant flux (irreversible)"));
386 
387  if (!pFunction) fatalError();
388 
389  ret.push_back(pFunction);
390  }
391  }
392 
393  return ret;
394 }
395 
396 bool CFunctionDB::appendDependentFunctions(std::set< const CCopasiObject * > candidates,
397  std::set< const CCopasiObject * > & dependentFunctions) const
398 {
399  size_t Size = dependentFunctions.size();
400  CCallParameters< C_FLOAT64 > CallParmeters;
401 
404 
405  for (; it != end; ++it)
406  if (candidates.find(*it) == candidates.end() &&
407  (*it)->CEvaluationTree::dependsOn(candidates))
408  dependentFunctions.insert((*it));
409 
410  return Size < dependentFunctions.size();
411 }
412 
413 std::set<std::string>
414 CFunctionDB::listDependentTrees(const std::string & name) const
415 {
416  std::set<std::string> List;
417 
420 
421  for (; it != end; ++it)
422  if ((*it)->dependsOnTree(name))
423  List.insert((*it)->getObjectName());
424 
425  return List;
426 }
427 
428 std::vector< CFunction * > CFunctionDB::getUsedFunctions(const CModel* pModel) const
429 {
430  std::vector< CFunction * > UsedFunctions;
433 
434  for (; it != end; ++it)
435  {
436  std::set< const CCopasiObject * > Function;
437  Function.insert(*it);
438 
439  std::set< const CCopasiObject * > Reactions;
440  std::set< const CCopasiObject * > Metabolites;
441  std::set< const CCopasiObject * > Values;
442  std::set< const CCopasiObject * > Compartments;
443  std::set< const CCopasiObject * > Events;
444 
445  pModel->appendDependentModelObjects(Function,
446  Reactions, Metabolites, Compartments, Values, Events);
447 
448  if (Reactions.size() != 0)
449  {
450  UsedFunctions.push_back(*it);
451  continue;
452  }
453 
454  if (Metabolites.size() != 0)
455  {
456  UsedFunctions.push_back(*it);
457  continue;
458  }
459 
460  if (Values.size() != 0)
461  {
462  UsedFunctions.push_back(*it);
463  continue;
464  }
465 
466  if (Compartments.size() != 0)
467  {
468  UsedFunctions.push_back(*it);
469  continue;
470  }
471 
472  if (Events.size() != 0)
473  {
474  UsedFunctions.push_back(*it);
475  continue;
476  }
477  }
478 
479  CFunction::completeFunctionList(UsedFunctions);
480 
481  return UsedFunctions;
482 }
std::string mFilename
Definition: CFunctionDB.h:42
static const CCopasiMessage & peekLastMessage()
CCopasiVectorN< CFunction > mLoadedFunctions
Definition: CFunctionDB.h:47
CCopasiVectorN< CFunction > & loadedFunctions()
CFunction * addAndAdaptName(CFunction *pFunction)
static bool completeFunctionList(std::vector< CFunction * > &list, const size_t &added=0)
Definition: CFunction.cpp:303
#define pdelete(p)
Definition: copasi.h:215
const std::string & getObjectName() const
virtual size_t size() const
std::vector< CFunction * > suitableFunctions(const size_t noSubstrates, const size_t noProducts, const TriLogic reversibility)
virtual ~CFunctionDB()
Definition: CFunctionDB.cpp:46
CCopasiObject * get(const std::string &key)
iterator begin()
TriLogic
Definition: copasi.h:125
#define fatalError()
bool setFunctionList(CCopasiVectorN< CFunction > *pFunctionList)
Definition: CCopasiXML.cpp:270
bool isSuitable(const size_t noSubstrates, const size_t noProducts, const TriLogic reversible)
Definition: CFunction.cpp:254
std::vector< CFunction * > getUsedFunctions(const CModel *pModel) const
const CEvaluationTree::Type & getType() const
#define C_INVALID_INDEX
Definition: copasi.h:222
virtual size_t getIndex(const std::string &name) const
#define C_INT32
Definition: copasi.h:90
CFunction * findLoadFunction(const std::string &functionName)
void initObjects()
Definition: CFunctionDB.cpp:54
void cleanup()
Definition: CFunctionDB.cpp:52
std::set< std::string > listDependentTrees(const std::string &name) const
CFunctionDB(const std::string &name, const CCopasiContainer *pParent)
Definition: CFunctionDB.cpp:36
#define DESTRUCTOR_TRACE
Definition: copasi.h:206
iterator end()
bool appendDependentModelObjects(const std::set< const CCopasiObject * > &candidates, std::set< const CCopasiObject * > &dependentReactions, std::set< const CCopasiObject * > &dependentMetabolites, std::set< const CCopasiObject * > &dependentCompartments, std::set< const CCopasiObject * > &dependentModelValues, std::set< const CCopasiObject * > &dependentEvents) const
Definition: CModel.cpp:2364
virtual bool add(const CType &src)
void setFilename(const std::string &filename)
virtual void cleanup()
virtual void load(CReadConfig &configBuffer, CReadConfig::Mode mode=CReadConfig::SEARCH)
Definition: CFunction.cpp:182
static CCopasiVector< CCopasiDataModel > * getDatamodelList()
bool appendDependentFunctions(std::set< const CCopasiObject * > candidates, std::set< const CCopasiObject * > &dependentFunctions) const
bool save(const std::string &fileName)
Definition: CFunctionDB.cpp:91
static CKeyFactory * getKeyFactory()
bool removeFunction(size_t index)
std::string getFilename() const
static CCopasiMessage getLastMessage()
virtual bool compile()
The class for handling a chemical kinetic function.
Definition: CFunction.h:29
Definition: CModel.h:50
virtual bool load(std::istream &is, const std::string &pwd)
Definition: CCopasiXML.cpp:169
C_INT32 getVariable(const std::string &name, const std::string &type, void *pout, CReadConfig::Mode mode=CReadConfig::NEXT)
Definition: CReadConfig.cpp:81
static char FunctionDBxml[]
bool setObjectName(const std::string &name)
CFunction * findFunction(const std::string &functionName)
CCopasiObject * addObjectReference(const std::string &name, CType &reference, const unsigned C_INT32 &flag=0)
#define MCCopasiVector
#define CONSTRUCTOR_TRACE
Definition: copasi.h:202
CNormalFunction * createFunction(const CEvaluationNode *node)
bool add(CFunction *pFunction, const bool &adopt)