COPASI API  4.16.103
CODEExporterC.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) 2007 by Pedro Mendes, Virginia Tech Intellectual
12 // Properties, Inc. and EML Research, gGmbH.
13 // All rights reserved.
14 
15 #include <sstream>
16 #include <locale>
17 #include <cmath>
18 
19 #include "copasi.h"
20 
23 
24 #include "CODEExporterC.h"
25 
26 #include "model/CModel.h"
27 #include "model/CMetab.h"
30 #include "model/CReaction.h"
31 #include "model/CMoiety.h"
32 #include "model/CChemEqElement.h"
33 #include "function/CExpression.h"
34 #include "function/CFunction.h"
35 #include "function/CFunctionDB.h"
36 #include "report/CKeyFactory.h"
42 #include "utilities/CCopasiTree.h"
43 
46 
47 #include <sbml/util/util.h>
48 
49 #include <iostream>
50 #include <fstream>
51 #include <ctype.h>
52 
53 /**
54  ** Constructor for the exporter.
55  */
57 {}
58 
60 {
61  return "// ";
62 }
63 
64 bool startsWith(const std::string& str, const std::string& sub)
65 {
66  if (str.length() < sub.length()) return false;
67 
68  if (sub.empty()) return true;
69 
70  for (size_t i = 0; i < sub.length(); ++i)
71  if (str[i] != sub[i]) return false;
72 
73  return true;
74 }
75 
76 void printNameForKey(std::ostringstream& stream, CKeyFactory* kf, const std::string& key, const std::string prefix = "")
77 {
78  CCopasiObject* obj = kf->get(key);
79 
80  if (obj != NULL)
81  {
82  stream << "\"" << prefix << obj->getObjectName() << "\", ";
83  }
84  else if (startsWith(key, "sm_"))
85  {
86  printNameForKey(stream, kf, key.substr(3), "");
87  }
88  else if (startsWith(key, "ode_"))
89  {
90  printNameForKey(stream, kf, key.substr(4), "ODE ");
91  }
92  else
93  {
94  stream << "\"" << prefix << key << "\", ";
95  }
96 }
97 
98 bool CODEExporterC::exportTitleData(const CModel* copasiModel, std::ostream & os)
99 {
100 
101  size_t metab_size = copasiModel->getMetabolitesX().size();
102  size_t indep_size = copasiModel->getNumIndependentReactionMetabs();
103  size_t ode_size = copasiModel->getNumODEMetabs();
104  size_t comps_size = copasiModel->getCompartments().size();
105  size_t modvals_size = copasiModel->getModelValues().size();
106  size_t reacs_size = copasiModel->getReactions().size();
107 
108  size_t i, j, num_params, count;
109  const CCopasiVector< CReaction > & reacs = copasiModel->getReactions();
110  CReaction* reac;
111 
112  count = 0;
113 
114  for (i = 0; i < reacs_size; ++i)
115  {
116 
117  reac = reacs[i];
118  num_params = reac->getParameters().size();
119 
120  for (j = 0; j < num_params; ++j)
121  {
122  if (reac->isLocalParameter(j))
123  ++count;
124  }
125  }
126 
127  size_t numX = 0;
128  size_t numY = 0;
129  size_t numXC = 0;
130  size_t numYC = 0;
131  size_t numPC = 0;
132  size_t numP = 0;
133  size_t numDX = 0;
134  size_t numCT = 0;
135 
136  std::ostringstream p_names; p_names << "const char* p_names[] = {";
137  std::ostringstream x_names; x_names << "const char* x_names[] = {";
138  std::ostringstream y_names; y_names << "const char* y_names[] = {";
139  std::ostringstream xc_names; xc_names << "const char* xc_names[] = {";
140  std::ostringstream pc_names; pc_names << "const char* pc_names[] = {";
141  std::ostringstream yc_names; yc_names << "const char* yc_names[] = {";
142  std::ostringstream dx_names; dx_names << "const char* dx_names[] = {";
143  std::ostringstream ct_names; ct_names << "const char* ct_names[] = {";
144 
146 
147  std::map< std::string, std::string >::const_iterator it = NameMap.begin();
148  std::map< std::string, std::string > reverse_map;
149 
150  while (it != NameMap.end())
151  {
152  const std::string& abbrev = it->second;
153  const std::string& key = it->first;
154 
155  if (startsWith(abbrev, "p["))
156  {
157  reverse_map[abbrev] = key;
158  ++numP;
159  }
160  else if (startsWith(abbrev, "x["))
161  {
162  reverse_map[abbrev] = key;
163  ++numX;
164  }
165  else if (startsWith(abbrev, "y["))
166  {
167  reverse_map[abbrev] = key;
168  ++numY;
169  }
170  else if (startsWith(abbrev, "dx["))
171  {
172  reverse_map[abbrev] = key;
173  ++numDX;
174  }
175  else if (startsWith(abbrev, "ct["))
176  {
177  reverse_map[abbrev] = key;
178  ++numCT;
179  }
180  else if (startsWith(abbrev, "x_c["))
181  {
182  CCopasiObject* obj = kf->get(key);
183 
184  if (obj != NULL)
185  {
186  reverse_map[abbrev] = obj->getObjectName();
187  }
188  else
189  {
190  reverse_map[abbrev] = key;
191  }
192 
193  ++numXC;
194  }
195  else if (startsWith(abbrev, "p_c["))
196  {
197  CCopasiObject* obj = kf->get(key);
198 
199  if (obj != NULL)
200  {
201  reverse_map[abbrev] = obj->getObjectName();
202  }
203  else
204  {
205  reverse_map[abbrev] = key;
206  }
207 
208  ++numPC;
209  }
210  else if (startsWith(abbrev, "y_c["))
211  {
212  CCopasiObject* obj = kf->get(key);
213 
214  if (obj != NULL)
215  {
216  reverse_map[abbrev] = obj->getObjectName();
217  }
218  else
219  {
220  reverse_map[abbrev] = key;
221  }
222 
223  ++numYC;
224  }
225 
226  ++it;
227  }
228 
229  for (size_t i = 0; i < numP; ++i)
230  {
231  std::stringstream str; str << "p[" << i << "]";
232  printNameForKey(p_names, kf, reverse_map[str.str()]);
233  }
234 
235  for (size_t i = 0; i < numX; ++i)
236  {
237  std::stringstream str; str << "x[" << i << "]";
238  printNameForKey(x_names, kf, reverse_map[str.str()]);
239  }
240 
241  for (size_t i = 0; i < numY; ++i)
242  {
243  std::stringstream str; str << "y[" << i << "]";
244  printNameForKey(y_names, kf, reverse_map[str.str()]);
245  }
246 
247  for (size_t i = 0; i < numDX; ++i)
248  {
249  std::stringstream str; str << "dx[" << i << "]";
250  printNameForKey(dx_names, kf, reverse_map[str.str()]);
251  }
252 
253  for (size_t i = 0; i < numCT; ++i)
254  {
255  std::stringstream str; str << "ct[" << i << "]";
256  printNameForKey(ct_names, kf, reverse_map[str.str()]);
257  }
258 
259  for (size_t i = 0; i < numXC; ++i)
260  {
261  std::stringstream str; str << "x_c[" << i << "]";
262  xc_names << "\"" << reverse_map[str.str()] << "\", ";
263  }
264 
265  for (size_t i = 0; i < numPC; ++i)
266  {
267  std::stringstream str; str << "p_c[" << i << "]";
268  pc_names << "\"" << reverse_map[str.str()] << "\", ";
269  }
270 
271  for (size_t i = 0; i < numYC; ++i)
272  {
273  std::stringstream str; str << "y_c[" << i << "]";
274  yc_names << "\"" << reverse_map[str.str()] << "\", ";
275  }
276 
277  os << "#ifdef SIZE_DEFINITIONS" << std::endl;
278  os << "#define N_METABS " << metab_size << std::endl;
279  os << "#define N_ODE_METABS " << ode_size << std::endl;
280  os << "#define N_INDEP_METABS " << indep_size << std::endl;
281  os << "#define N_COMPARTMENTS " << comps_size << std::endl;
282  os << "#define N_GLOBAL_PARAMS " << modvals_size << std::endl;
283  os << "#define N_KIN_PARAMS " << count << std::endl;
284  os << "#define N_REACTIONS " << reacs_size << std::endl << std::endl;
285 
286  os << "#define N_ARRAY_SIZE_P " << numP << "\t// number of parameters" << std::endl;
287  os << "#define N_ARRAY_SIZE_X " << numX << "\t// number of initials" << std::endl;
288  os << "#define N_ARRAY_SIZE_Y " << numY << "\t// number of assigned elements" << std::endl;
289  os << "#define N_ARRAY_SIZE_XC " << numXC << "\t// number of x concentration" << std::endl;
290  os << "#define N_ARRAY_SIZE_PC " << numPC << "\t// number of p concentration" << std::endl;
291  os << "#define N_ARRAY_SIZE_YC " << numYC << "\t// number of y concentration" << std::endl;
292  os << "#define N_ARRAY_SIZE_DX " << numDX << "\t// number of ODEs " << std::endl;
293  os << "#define N_ARRAY_SIZE_CT " << numCT << "\t// number of conserved totals" << std::endl << std::endl;
294 
295  os << "#endif // SIZE_DEFINITIONS" << std::endl;
296  os << std::endl;
297 
298  os << "#ifdef TIME" << std::endl;
299  os << "#define T <set here a user name for the time variable> " << std::endl;
300  os << "#endif // TIME" << std::endl;
301 
302  os << std::endl;
303  os << "#ifdef NAME_ARRAYS" << std::endl;
304  os << p_names.str() << " \"\" };" << std::endl;
305  os << x_names.str() << " \"\" };" << std::endl;
306  os << y_names.str() << " \"\" };" << std::endl;
307  os << xc_names.str() << " \"\" };" << std::endl;
308  os << pc_names.str() << " \"\" };" << std::endl;
309  os << yc_names.str() << " \"\" };" << std::endl;
310  os << dx_names.str() << " \"\" };" << std::endl;
311  os << ct_names.str() << " \"\" };" << std::endl;
312  os << "#endif // NAME_ARRAYS" << std::endl;
313 
314  return true;
315 }
316 
318 {return;} // TODO
319 
321 {return "T";}
322 
323 std::string CODEExporterC::setExportName(const CModelEntity::Status & status, size_t n[], size_t dependent)
324 {
325  std::ostringstream name;
326 
327  switch (status)
328  {
329  case CModelEntity::FIXED:
330  name << "p[" << n[0] << "]";
331  n[0] ++;
332  break;
333 
335 
336  if (!dependent)
337  {
338  name << "x[" << n[1] << "]";
339  n[1] ++;
340  }
341  else
342  {
343  name << "y[" << n[2] << "]";
344  n[2] ++;
345  }
346 
347  break;
348 
349  case CModelEntity::ODE:
350  name << "x[" << n[1] << "]";
351  n[1] ++;
352  break;
353 
355  name << "y[" << n[2] << "]";
356  n[2] ++;
357  break;
358 
359  default:
360  return " ";
361  break;
362  }
363 
364  return name.str();
365 }
366 
367 std::string CODEExporterC::setConcentrationName(const CModelEntity::Status & status, size_t n[], size_t dependent)
368 {
369  std::ostringstream name;
370 
371  switch (status)
372  {
373  case CModelEntity::FIXED:
374  name << "p_c[" << n[0] << "]";
375  n[0] ++;
376  break;
377 
379 
380  if (!dependent)
381  {
382  name << "x_c[" << n[1] << "]";
383  n[1] ++;
384  }
385  else
386  {
387  name << "y_c[" << n[2] << "]";
388  n[2] ++;
389  }
390 
391  break;
392 
393  case CModelEntity::ODE:
394  name << "x_c[" << n[1] << "]";
395  n[1] ++;
396  break;
397 
399  name << "y_c[" << n[2] << "]";
400  n[2] ++;
401  break;
402 
403  default:
404  return " ";
405  break;
406  }
407 
408  return name.str();
409 }
410 
411 /**
412  ** This method adapt a Copasi name for C syntax:
413  ** Names can not start with a number.
414  ** Any other combination of letters and numbers is valid as is the underscore.
415  **/
416 std::string CODEExporterC::translateObjectName(const std::string & realName)
417 {
418  std::locale C("C");
419  char ch;
420 
421  std::ostringstream tmpName;
422 
423  size_t realName_size = realName.size();
424  size_t i;
425 
426  ch = realName[0];
427 
428  if (!std::isalpha(ch, C))
429  {
430  tmpName << "_";
431 
432  if (std::isdigit(ch, C)) tmpName << ch;
433  }
434  else tmpName << ch;
435 
436  for (i = 1; i < realName_size; i++)
437  {
438  ch = realName[i];
439 
440  if (std::isalpha(ch, C))
441  {
442  if (std::isspace(realName[i - 1], C) && std::islower(ch, C))
443  tmpName << (char) toupper(ch);
444  else
445  tmpName << ch;
446  }
447 
448  if (std::isdigit(ch, C)) tmpName << ch;
449 
450  if (std::ispunct(ch, C))
451  switch (ch)
452  {
453  case '_':
454  tmpName << ch;
455  break;
456 
457  case '-':
458  case '{':
459  case '}':
460  case '(':
461  case ')':
462  case '[':
463  case ']':
464  tmpName << "_";
465  break;
466 
467  default:
468  break;
469  }
470  }
471 
472  return testName(tmpName.str());
473 }
474 /**
475  ** This method tests whether the given C name already assigned,
476  ** put the new name (in cappital letters:
477  ** all names can be upper or lower case)
478  ** in the set of assigned names
479  ** or modify the name
480  **/
481 
482 std::string CODEExporterC::testName(const std::string & name)
483 {
484  std::locale C("C");
485  char ch;
486 
487  std::ostringstream newname, tmp;
488 
489  size_t name_size = name.size();
490  size_t i;
491 
492  for (i = 0; i < name_size; i++)
493  {
494  ch = name[i];
495 
496  if (std::isalpha(ch, C) && std::islower(ch, C))
497  tmp << (char) toupper(ch);
498  else
499  tmp << ch;
500  }
501 
502  if (NameSet.find(tmp.str()) == NameSet.end())
503  {
504  NameSet.insert(tmp.str());
505  Frequancy[tmp.str()] = 0;
506 
507  return name;
508  }
509  else
510  {
511  Frequancy[tmp.str()]++;
512  newname << name << "_" << Frequancy[tmp.str()];
513 
514  return testName(newname.str());
515  }
516 }
517 
518 std::string CODEExporterC::setODEName(const std::string & objName)
519 {
520  return "d" + objName;
521 }
522 
523 bool CODEExporterC::preprocess(const CModel* copasiModel)
524 
525 {
526  size_t n[3] = {0, 0, 0};
527  size_t n_c[3] = {0, 0, 0};
528  size_t i, j;
529  size_t dependent;
530 
532 
534 
535  const CCopasiVector< CMetab > & metabs = copasiModel->getMetabolitesX();
536  size_t metabs_size = metabs.size();
537 
538  for (i = 0; i < metabs_size; i++)
539  {
540  CMetab * metab = metabs[i];
541 
542  //if (metab->isUsed())
543  {
544  std::string smname;
545  std::string name;
546  dependent = metab->isDependent();
547 
548  smname = setExportName(metab->getStatus(), n, dependent);
549  name = setConcentrationName(metab->getStatus(), n_c, dependent);
550 
551  NameMap[metab->getKey()] = name;
552 
553  std::ostringstream smKey;
554  smKey << "sm_" << metab->getKey();
555 
556  NameMap[smKey.str()] = smname;
557 
558  if ((metab->getStatus() == CModelEntity::REACTIONS && !metab->isDependent()) || metab->getStatus() == CModelEntity::ODE)
559  {
560  std::ostringstream odeKey;
561  odeKey << "ode_" << metab->getKey();
562 
563  NameMap[odeKey.str()] = setODEName(smname);
564  }
565  }
566  }
567 
568  size_t comps_size = copasiModel->getCompartments().size();
569  const CCopasiVector< CCompartment > & comps = copasiModel->getCompartments();
570 
571  for (i = 0; i < comps_size; i++)
572  {
573  CCompartment * comp = comps[i];
574 
575  std::string name;
576  dependent = 0;
577 
578  name = setExportName(comp->getStatus(), n, dependent);
579  NameMap[comp->getKey()] = name;
580 
581  if (comp->getStatus() == CModelEntity::ODE)
582  {
583  std::ostringstream odeKey;
584  odeKey << "ode_" << comp->getKey();
585 
586  NameMap[odeKey.str()] = setODEName(name);
587  }
588  }
589 
590  size_t modvals_size = copasiModel->getModelValues().size();
591  const CCopasiVector< CModelValue > & modvals = copasiModel->getModelValues();
592 
593  for (i = 0; i < modvals_size; i++)
594  {
595  CModelValue* modval = modvals[i];
596  std::string name = setExportName(modval->getStatus(), n, 0);
597  NameMap[modval->getKey()] = name;
598 
599  if (modval->getStatus() == CModelEntity::ODE)
600  {
601  std::ostringstream odeKey;
602  odeKey << "ode_" << modval->getKey();
603  NameMap[odeKey.str()] = setODEName(name);
604  }
605  }
606 
607  size_t reacs_size = copasiModel->getReactions().size();
608 
609  const CCopasiVector< CReaction > & reacs = copasiModel->getReactions();
610 
611  std::set<std::string> tmpset;
612 
613  for (i = 0; i < reacs_size; ++i)
614  {
615  size_t params_size;
616 
617  params_size = reacs[i]->getParameters().size();
618 
619  for (j = 0; j < params_size; ++j)
620  {
621  if (!reacs[i]->isLocalParameter(reacs[i]->getParameters().getParameter(j)->getObjectName()))
622  continue;
623 
624  std::ostringstream name;
625 
626  name << "p[" << n[0] << "]";
627  n[0] ++;
628 
629  NameMap[reacs[i]->getParameters().getParameter(j)->getKey()] = name.str();
630  }
631 
632  const CFunction* func = reacs[i]->getFunction();
633 
634  std::string name = func->getObjectName();
635 
636  if (func->getRoot())
637  setExportNameOfFunction(func->getRoot(), tmpset);
638 
639  if (func->getType() != CEvaluationTree::MassAction)
640  if (tmpset.find(name) == tmpset.end())
641  {
642  NameMap[func->getKey()] = translateObjectName(name);
643  tmpset.insert(name);
644  }
645  }
646 
647  return true;
648 }
649 
650 void CODEExporterC::setExportNameOfFunction(const CEvaluationNode* pNode, std::set<std::string> & tmpset)
651 {
652  if (pNode)
653  {
656 
657  while (treeIt != NULL)
658  {
659  if (CEvaluationNode::type(treeIt->getType()) == CEvaluationNode::CALL)
660  {
661  const CFunction* ifunc;
662  ifunc = static_cast<CFunction*>(pFunctionDB->findFunction((*treeIt).getData()));
663 
664  setExportNameOfFunction(ifunc->getRoot(), tmpset);
665 
666  if (ifunc->getType() != CEvaluationTree::MassAction)
667  if (tmpset.find(ifunc->getObjectName()) == tmpset.end())
668  {
669  NameMap[ifunc->getKey()] = translateObjectName(ifunc->getObjectName());
670  tmpset.insert(ifunc->getObjectName());
671  }
672  }
673 
674  ++treeIt;
675  }
676  }
677 }
678 
679 bool CODEExporterC::exportSingleObject(std::ostringstream & which, const std::string & name, const std::string & expression, const std::string & comments)
680 {
681  which << name << " = " << expression << ";"
682  << '\t' << "//" << comments << std::endl;
683 
684  return true;
685 }
686 
687 bool CODEExporterC::exportSingleMetabolite(const CMetab* metab, std::string & expression, std::string & comments)
688 {
689 
690  std::string name;
691 
692  std::ostringstream smKey;
693  smKey << "sm_" << metab->getKey();
694  name = NameMap[smKey.str()];
695 
696  switch (metab->getStatus())
697  {
698 
699  case CModelEntity::FIXED:
700 
701  if (!exportSingleObject(fixed, name, expression, comments))
702  return false;
703 
704  break;
705 
707  case CModelEntity::ODE:
708  {
709  if (metab->isDependent())
710  {
711  if (!exportSingleObject(assignment, name, expression, comments))
712  return false;
713  }
714  else
715  {
716  if (!exportSingleObject(initial, name, expression, comments))
717  return false;
718  }
719 
720  break;
721  }
722 
724  {
725  if (!exportSingleObject(assignment, name, expression, comments))
726  return false;
727 
728  break;
729  }
730 
731  default:
732  return false;
733  break;
734  }
735 
736  return true;
737 }
738 
739 bool CODEExporterC::exportSingleCompartment(const CCompartment* comp, std::string & expression, std::string & comments)
740 {
741  switch (comp->getStatus())
742  {
743  case CModelEntity::FIXED:
744  {
745  if (!exportSingleObject(fixed, NameMap[comp->getKey()], expression, comments))
746  return false;
747 
748  break;
749  }
750 
751  case CModelEntity::ODE:
752  {
753  if (!exportSingleObject(initial, NameMap[comp->getKey()], expression, comments))
754  return false;
755 
756  break;
757  }
758 
760  {
761  if (!exportSingleObject(assignment, NameMap[comp->getKey()], expression, comments))
762  return false;
763 
764  break;
765  }
766 
767  default:
768  return false;
769  break;
770  }
771 
772  return true;
773 }
774 
775 std::string CODEExporterC::exportNumber(double number)
776 {
777  if (util_isNaN(number))
778  return "NaN";
779 
780  if (util_isInf(number))
781  return "INFINITY";
782 
783  std::stringstream str; str << number;
784  return str.str();
785 }
786 
787 bool CODEExporterC::exportSingleModVal(const CModelValue* modval, std::string & expression, std::string & comments)
788 {
789  switch (modval->getStatus())
790  {
791  case CModelEntity::FIXED:
792  {
793  if (!exportSingleObject(fixed, NameMap[modval->getKey()], expression, comments))
794  return false;
795 
796  break;
797  }
798 
799  case CModelEntity::ODE:
800  {
801  if (!exportSingleObject(initial, NameMap[modval->getKey()], expression, comments))
802  return false;
803 
804  break;
805  }
806 
808  {
809  if (!exportSingleObject(assignment, NameMap[modval->getKey()], expression, comments))
810  return false;
811 
812  break;
813  }
814 
815  default:
816  return false;
817  break;
818  }
819 
820  return true;
821 }
822 
823 bool CODEExporterC::exportSingleModelEntity(const CModelEntity* tmp, std::string & expression, std::string & comments)
824 {
825 
826  std::string name;
827 
828  const CMetab* metab;
829  metab = dynamic_cast< const CMetab * >(tmp);
830 
831  if (metab)
832  {
833  std::ostringstream smKey;
834  smKey << "sm_" << metab->getKey();
835  name = NameMap[smKey.str()];
836  }
837  else
838  name = NameMap[tmp->getKey()];
839 
840  switch (tmp->getStatus())
841  {
842  case CModelEntity::FIXED:
843  {
844  if (!exportSingleObject(fixed, name, expression, comments))
845  return false;
846 
847  break;
848  }
849 
850  case CModelEntity::ODE:
851  {
852  if (!exportSingleObject(initial, name, expression, comments))
853  return false;
854 
855  break;
856  }
857 
859  {
860  // prevent assignment from being written multiple times ...
861  if (Frequancy[name] == 1)
862  break;
863 
864  if (!exportSingleObject(assignment, name, expression, comments))
865  return false;
866 
867  Frequancy[name] = 1;
868  break;
869  }
870 
871  default:
872  return false;
873  break;
874  }
875 
876  return true;
877 }
878 
879 bool CODEExporterC::exportSingleParameter(const CCopasiParameter* param, std::string & expression, std::string & comments)
880 {
881  if (!exportSingleObject(fixed, NameMap[param->getKey()], expression, comments)) return false;
882 
883  return true;
884 }
885 
887 {return true;}
888 
890 {
891  const CCopasiVector< CReaction > & reacs = copasiModel->getReactions();
892  size_t size = reacs.size();
893  CReaction* reac;
894 
895  size_t i;
896 
897  for (i = 0; i < size; ++i)
898  {
899  reac = reacs[i];
900  const CFunction* func = reac->getFunction();
901 
902  if (func->getRoot())
903  findFunctionsCalls(func->getRoot());
904 
905  if (func->getType() != CEvaluationTree::MassAction)
906  {
907  if (!CODEExporter::exportSingleFunction(func)) return false;
908  }
909  }
910 
911  return true;
912 }
913 
914 bool CODEExporterC::exportSingleFunction(const CFunction *func, std::set<std::string>& isExported)
915 {
917 
918  CFunction* tmpfunc = NULL;
919  tmpfunc = new CFunction(*func);
920 
921  if (func->getType() != CEvaluationTree::MassAction)
922  {
923 
926 
927  size_t j, varbs_size = tmpfunc->getVariables().size();
928  std::map< std::string, std::string > parameterNameMap;
929  std::set<std::string> parameterNameSet;
930 
931  std::map< CFunctionParameter::Role, std::string > constName;
932  std::map< CFunctionParameter::Role, size_t > tmpIndex;
933 
934  constName[CFunctionParameter::SUBSTRATE] = "sub_"; tmpIndex[CFunctionParameter::SUBSTRATE] = 0;
935  constName[CFunctionParameter::PRODUCT] = "prod_"; tmpIndex[CFunctionParameter::PRODUCT] = 0;
936  constName[CFunctionParameter::PARAMETER] = "param_"; tmpIndex[CFunctionParameter::PARAMETER] = 0;
937  constName[CFunctionParameter::MODIFIER] = "modif_"; tmpIndex[CFunctionParameter::MODIFIER] = 0;
938  constName[CFunctionParameter::VOLUME] = "volume_"; tmpIndex[CFunctionParameter::VOLUME] = 0;
939  constName[CFunctionParameter::VARIABLE] = "varb_"; tmpIndex[CFunctionParameter::VARIABLE] = 0;
940  constName[CFunctionParameter::TIME] = "time_"; tmpIndex[CFunctionParameter::VARIABLE] = 0;
941 
942  for (j = 0; j < varbs_size; ++j)
943  {
944  if (parameterNameSet.find(tmpfunc->getVariables()[j]->getObjectName()) == parameterNameSet.end())
945  {
946  std::ostringstream tmpName;
947  CFunctionParameter::Role role = tmpfunc->getVariables()[j]->getUsage();
948 
949  tmpName << constName[role] << tmpIndex[role];
950  parameterNameMap[ tmpfunc->getVariables()[j]->getObjectName()] = tmpName.str();
951  parameterNameSet.insert(tmpfunc->getVariables()[j]->getObjectName());
952  tmpIndex[role]++;
953  }
954  }
955 
957 
958  while (newIt != NULL)
959  {
960  if (CEvaluationNode::type(newIt->getType()) == CEvaluationNode::VARIABLE)
961  {
962  newIt->setData(parameterNameMap[ tmpfunc->getVariables()[newIt->getData()]->getObjectName()]);
963  }
964 
965  if (CEvaluationNode::type(newIt->getType()) == CEvaluationNode::CALL)
966  {
967  const CFunction* callfunc;
968  callfunc = static_cast<CFunction*>(pFunctionDB->findFunction((*newIt).getData()));
969 
970  if (callfunc->getType() != CEvaluationTree::MassAction)
971  newIt->setData(NameMap[callfunc->getKey()]);
972  }
973 
974  ++newIt;
975  }
976 
977  std::string name = func->getObjectName();
978 
979  if (isExported.find(name) == isExported.end())
980  {
981  size_t j, varbs_size = tmpfunc->getVariables().size();
982 
983  std::string mappedName = NameMap[func->getKey()];
984 
985  if (mappedName.empty())
986  {
987  NameMap[func->getKey()] = translateObjectName(name);
988  mappedName = NameMap[func->getKey()];
989  }
990 
991  functions << "double " << mappedName << "(";
992  headers << "double " << mappedName << "(";
993 
994  for (j = 0; j < varbs_size; ++j)
995  {
996  functions << "double " << parameterNameMap[ tmpfunc->getVariables()[j]->getObjectName().c_str()];
997 
998  if (j != varbs_size - 1) functions << ", ";
999 
1000  headers << "double " << parameterNameMap[ tmpfunc->getVariables()[j]->getObjectName().c_str()];
1001 
1002  if (j != varbs_size - 1) headers << ", ";
1003  }
1004 
1005  functions << ") ";
1006  functions << '\t' << "//" << name << std::endl;
1007  functions << "{return " << tmpfunc->getRoot()->buildCCodeString().c_str() << ";} " << std::endl;
1008 
1009  headers << "); " << std::endl;
1010 
1011  isExported.insert(name);
1012  }
1013  }
1014 
1015  return true;
1016 }
1017 
1019 {
1020  std::ostringstream equation;
1021 
1023  {
1024  const CFunctionParameters & params = reac->getFunctionParameters();
1025  size_t k, params_size = params.size();
1026  const std::vector<std::vector<std::string> > & keyMap = reac->getParameterMappings();
1027  std::string name;
1028  equation << NameMap[reac->getFunction()->getKey()] << "(";
1029 
1030  for (k = 0; k < params_size; ++k)
1031  {
1032 
1033  CFunctionParameter::Role role = params[k]->getUsage();
1034 
1035  CCopasiObject * obj = CCopasiRootContainer::getKeyFactory()->get(keyMap[k][0]);
1036 
1037  if ((role == CFunctionParameter::SUBSTRATE)
1038  || (role == CFunctionParameter::PRODUCT)
1039  || (role == CFunctionParameter::MODIFIER))
1040  {
1041  if (obj)
1042  name = NameMap[obj->getKey()];
1043  else
1044  name = "unknown";
1045  }
1046 
1047  if (role == CFunctionParameter::PARAMETER)
1048  {
1049  if (!(reac->isLocalParameter(k)))
1050  {
1051  CModelValue* modval;
1052  modval = dynamic_cast< CModelValue * >(obj);
1053  name = NameMap[modval->getKey()];
1054  }
1055  else
1056  {
1057  CCopasiParameter* param;
1058  param = dynamic_cast< CCopasiParameter * >(obj);
1059  name = NameMap[param->getKey()];
1060  }
1061  }
1062 
1063  if (role == CFunctionParameter::VOLUME)
1064  {
1065  CCompartment* comp;
1066  comp = dynamic_cast< CCompartment * >(obj);
1067  name = NameMap[comp->getKey()];
1068  }
1069 
1070  if (role == CFunctionParameter::TIME)
1071  {
1072  name = "T";
1073  }
1074 
1075  if (name.empty())
1076  {
1077  std::string message = "Could not export C code, since one of the arguments could not be resolved. Please consider filing a bug with the COPASI tracker: http://www.copasi.org/tracker";
1078  CCopasiMessage(CCopasiMessage::EXCEPTION, message.c_str());
1079  }
1080 
1081  equation << name;
1082 
1083  if (k != params_size - 1)
1084  equation << ", ";
1085  }
1086 
1087  equation << ")";
1088  }
1089  else
1090  {
1091  const CCopasiVector<CChemEqElement> & substrs = reac->getChemEq().getSubstrates();
1092  const CCopasiVector<CChemEqElement> & prods = reac->getChemEq().getProducts();
1093  const std::vector<std::vector<std::string> > & keyMap = reac->getParameterMappings();
1094  CCopasiObject * obj;
1095 
1096  size_t substrs_size = substrs.size(), prods_size = prods.size();
1097  size_t k, m, mult;
1098 
1099  CChemEqElement* substr;
1100  CChemEqElement* prod;
1101 
1102  const CMassAction cMassAction = *static_cast<const CMassAction*>(reac->getFunction());
1103 
1104  equation << "(";
1105 
1106  obj = CCopasiRootContainer::getKeyFactory()->get(keyMap[0][0]);
1107 
1108  if (!(reac->isLocalParameter(0)))
1109  {
1110  CModelValue* modval;
1111  modval = dynamic_cast< CModelValue * >(obj);
1112 
1113  equation << NameMap[modval->getKey()];
1114  }
1115  else
1116  {
1117  CCopasiParameter* param;
1118  param = dynamic_cast< CCopasiParameter * >(obj);
1119 
1120  equation << NameMap[param->getKey()];
1121  }
1122 
1123  for (k = 0; k < substrs_size; ++k)
1124  {
1125  substr = substrs[k];
1126  mult = (size_t) substr->getMultiplicity();
1127 
1128  assert(substr->getMetabolite());
1129  equation << " * " << NameMap[substr->getMetabolite()->getKey()];
1130 
1131  if (mult > 1)
1132  for (m = 1; m < mult; ++m)
1133  equation << " * " << NameMap[substr->getMetabolite()->getKey()];
1134  }
1135 
1136  if (cMassAction.isReversible() == TriTrue)
1137  {
1138  equation << " - ";
1139 
1140  obj = CCopasiRootContainer::getKeyFactory()->get(keyMap[2][0]);
1141 
1142  if (!(reac->isLocalParameter(2)))
1143  {
1144  CModelValue* modval;
1145  modval = dynamic_cast< CModelValue * >(obj);
1146 
1147  equation << NameMap[modval->getKey()];
1148  }
1149  else
1150  {
1151  CCopasiParameter* param;
1152  param = dynamic_cast< CCopasiParameter * >(obj);
1153 
1154  equation << NameMap[param->getKey()];
1155  }
1156 
1157  for (k = 0; k < prods_size; ++k)
1158  {
1159  prod = prods[k];
1160  mult = (size_t) prod->getMultiplicity();
1161 
1162  assert(prod->getMetabolite());
1163  equation << " * " << NameMap[prod->getMetabolite()->getKey()];
1164 
1165  if (mult > 1)
1166  for (m = 1; m < mult; ++m)
1167  equation << " * " << NameMap[prod->getMetabolite()->getKey()];
1168  }
1169  }
1170 
1171  equation << ") ";
1172  }
1173 
1174  return equation.str();
1175 }
1176 
1177 bool CODEExporterC::exportSingleODE(const CModelEntity* mentity, std::string & equation, std::string & comments)
1178 {
1179  std::ostringstream odeKey;
1180  odeKey << "ode_" << mentity->getKey();
1181 
1182  if (!exportSingleObject(ode, NameMap[odeKey.str()], equation, comments)) return false;
1183 
1184  return true;
1185 }
1186 
1187 std::string CODEExporterC::exportTitleString(const size_t tmp)
1188 {
1189  switch (tmp)
1190  {
1191  case INITIAL:
1192  return "#ifdef INITIAL";
1193 
1194  case FIXED:
1195  return "#ifdef FIXED";
1196 
1197  case ASSIGNMENT:
1198  return "#ifdef ASSIGNMENT";
1199 
1200  case HEADERS:
1201  return "#ifdef FUNCTIONS_HEADERS";
1202 
1203  case FUNCTIONS:
1204  return "#ifdef FUNCTIONS";
1205 
1206  case ODEs:
1207  return "#ifdef ODEs";
1208 
1209  default:
1210  return " ";
1211  }
1212 }
1213 
1215 {
1216  std::string str1;
1217 
1218  str1 = tmp->getRoot()->buildCCodeString().c_str();
1219 
1220  return str1;
1221 }
1222 
1223 std::string CODEExporterC::exportClosingString(const size_t tmp)
1224 {
1225  switch (tmp)
1226  {
1227  case INITIAL:
1228  return "#endif /* INITIAL */\n";
1229 
1230  case FIXED:
1231  return "#endif /* FIXED */\n";
1232 
1233  case ASSIGNMENT:
1234  return "#endif /* ASSIGNMENT */\n";
1235 
1236  case HEADERS:
1237  return "#endif /* FUNCTIONS_HEADERS */\n";
1238 
1239  case FUNCTIONS:
1240  return "#endif /* FUNCTIONS */\n";
1241 
1242  case ODEs:
1243  return "#endif /* ODEs */\n";
1244 
1245  default:
1246  return " ";
1247  }
1248 }
Header file of class CExpression.
bool startsWith(const std::string &str, const std::string &sub)
virtual bool exportSingleModVal(const CModelValue *modval, std::string &expression, std::string &comments)
std::set< std::string > NameSet
Definition: CODEExporterC.h:87
virtual bool exportSingleModelEntity(const CModelEntity *tmp, std::string &expression, std::string &comments)
virtual std::string translateTimeVariableName()
std::ostringstream headers
Definition: CODEExporter.h:159
virtual std::string translateObjectName(const std::string &realName)
virtual bool exportSingleFunction(const CFunction *func, std::set< std::string > &isExported)
virtual bool exportSingleMetabolite(const CMetab *metab, std::string &expression, std::string &comments)
const std::string & getObjectName() const
const CCopasiVectorN< CModelValue > & getModelValues() const
Definition: CModel.cpp:1060
virtual std::string KineticFunction2ODEmember(const CReaction *reac)
virtual size_t size() const
CCopasiObject * get(const std::string &key)
virtual std::string exportTitleString(const size_t tmp)
const CMetab * getMetabolite() const
bool isLocalParameter(const size_t &index) const
Definition: CReaction.cpp:449
const CEvaluationTree::Type & getType() const
virtual bool exportSingleODE(const CModelEntity *mentity, std::string &equation, std::string &comments)
virtual bool exportSingleObject(std::ostringstream &which, const std::string &name, const std::string &expression, const std::string &comments)
virtual void setReservedNames()
size_t getNumODEMetabs() const
Definition: CModel.cpp:1124
std::ostringstream initial
Definition: CODEExporter.h:155
std::string buildCCodeString() const
Definition: CMetab.h:178
const std::string & getKey() const
Definition: CFunction.cpp:58
std::map< std::string, size_t > Frequancy
Definition: CODEExporterC.h:86
void printNameForKey(std::ostringstream &stream, CKeyFactory *kf, const std::string &key, const std::string prefix="")
virtual std::string exportClosingString(const size_t tmp)
virtual const std::string & getKey() const
const CCopasiVector< CChemEqElement > & getProducts() const
Definition: CChemEq.cpp:63
static Type type(const Type &type)
const CFunction * getFunction() const
Definition: CReaction.cpp:252
virtual std::string exportNumber(double number)
const CFunctionParameters & getFunctionParameters() const
Definition: CReaction.cpp:576
std::ostringstream ode
Definition: CODEExporter.h:160
virtual bool exportSingleCompartment(const CCompartment *comp, std::string &expression, std::string &comments)
std::ostringstream functions
Definition: CODEExporter.h:158
const TriLogic & isReversible() const
Definition: CFunction.cpp:145
virtual const std::string & getKey() const
virtual bool exportSingleParameter(const CCopasiParameter *param, std::string &expression, std::string &comments)
virtual const std::string & getKey() const
const C_FLOAT64 & getMultiplicity() const
virtual std::string getSingleLineComment()
void setExportNameOfFunction(const CEvaluationNode *pNode, std::set< std::string > &tmpset)
std::string testName(const std::string &name)
const CCopasiVector< CChemEqElement > & getSubstrates() const
Definition: CChemEq.cpp:60
std::string setODEName(const std::string &objName)
static CFunctionDB * getFunctionList()
size_t getNumIndependentReactionMetabs() const
Definition: CModel.cpp:1130
bool isDependent() const
Definition: CMetab.cpp:989
void modifyTreeForMassAction(CFunction *tmpfunc)
CCopasiVectorNS< CCompartment > & getCompartments()
Definition: CModel.cpp:1145
static CKeyFactory * getKeyFactory()
std::map< std::string, std::string > NameMap
Definition: CODEExporter.h:151
const CCopasiParameterGroup & getParameters() const
Definition: CReaction.cpp:333
std::string timeKey
Definition: CODEExporter.h:152
virtual bool exportKineticFunctionGroup(const CModel *copasiModel)
std::ostringstream assignment
Definition: CODEExporter.h:157
The class for handling a chemical kinetic function.
Definition: CFunction.h:29
CCopasiVectorNS< CReaction > & getReactions()
Definition: CModel.cpp:1039
void findFunctionsCalls(const CEvaluationNode *pNode)
virtual bool exportKineticFunction(CReaction *reac)
Definition: CModel.h:50
std::string setExportName(const CModelEntity::Status &status, size_t n[], size_t dependent)
std::ostringstream fixed
Definition: CODEExporter.h:156
const CModelEntity::Status & getStatus() const
const CCopasiVector< CMetab > & getMetabolitesX() const
Definition: CModel.cpp:1057
const std::vector< std::vector< std::string > > & getParameterMappings() const
Definition: CReaction.h:285
virtual bool preprocess(const CModel *copasiModel)
virtual bool exportTitleData(const CModel *copasiModel, std::ostream &os)
CFunction * findFunction(const std::string &functionName)
const CChemEq & getChemEq() const
Definition: CReaction.cpp:223
CEvaluationNode * getRoot()
std::string setConcentrationName(const CModelEntity::Status &status, size_t n[], size_t dependent)
bool exportSingleFunction(const CFunction *func)
CFunctionParameters & getVariables()
Definition: CFunction.cpp:148
virtual std::string getDisplayExpressionString(CExpression *tmp)