COPASI API  4.16.103
CODEExporterXPPAUT.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 "CODEExporterXPPAUT.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 <iostream>
48 #include <fstream>
49 #include <ctype.h>
50 
51 /**
52  ** Constructor for the exporter.
53  */
55 {}
56 
57 bool CODEExporterXPPAUT::exportTitleData(const CCopasiDataModel* pDataModel, std::ostream & os)
58 {
59  os << "@ t0=0,"; //TODO
60  const CTrajectoryTask * pTrajectory =
61  dynamic_cast<const CTrajectoryTask *>((*const_cast<CCopasiDataModel*>(pDataModel)->getTaskList())["Time-Course"]);
62  const CTrajectoryProblem * pTrajectoryProblem =
63  dynamic_cast<const CTrajectoryProblem *>(pTrajectory->getProblem());
64 
65  os << "total=" << pTrajectoryProblem->getDuration() << ",";
66  os << "dt=" << pTrajectoryProblem->getStepSize()
67  << ",METH=stiff" << std::endl; //gear is the only method with automatic step size
68 
69  return true;
70 }
71 
73 {return "t";}
74 /**
75  ** This method adapt a Copasi name for XPPAUT syntax:
76  ** all XPPAUT names can have up to 9 letters each.
77  ** Names can not start with a number.
78  ** Any other combination of letters and numbers is valid as is the underscore.
79  **/
80 std::string CODEExporterXPPAUT::translateObjectName(const std::string & realName)
81 {
82  std::locale C("C");
83  char ch;
84 
85  std::string newName;
86  std::ostringstream tmpName;
87 
88  size_t realName_size = realName.size();
89  size_t i;
90 
91  ch = realName[0];
92 
93  if (!std::isalpha(ch, C))
94  {
95  tmpName << "_";
96 
97  if (std::isdigit(ch, C)) tmpName << ch;
98  }
99  else tmpName << ch;
100 
101  for (i = 1; i < realName_size; i++)
102  {
103  ch = realName[i];
104 
105  if (std::isalpha(ch, C))
106  {
107  if (std::isspace(realName[i - 1], C) && std::islower(ch, C))
108  tmpName << (char) toupper(ch);
109  else
110  tmpName << ch;
111  }
112 
113  if (std::isdigit(ch, C)) tmpName << ch;
114 
115  if (std::ispunct(ch, C))
116  switch (ch)
117  {
118  case '_':
119  tmpName << ch;
120  break;
121 
122  case '-':
123  tmpName << "_";
124  break;
125 
126  case '{':
127  tmpName << "_";
128  break;
129 
130  case '}':
131  tmpName << "_";
132  break;
133 
134  default:
135  break;
136  }
137  }
138 
139  newName = tmpName.str();
140 
141  size_t newName_size = newName.size();
142 
143  if (newName_size > 7)
144  {
145  std::ostringstream cutName;
146 
147  for (i = 0; i < 7; i++)
148  cutName << newName[i];
149 
150  newName = cutName.str();
151  }
152 
153  return testName(newName);
154 }
155 /**
156  ** This method tests whether the given XPPAUT name already assigned,
157  ** put the new name (in cappital letters:
158  ** all names can be upper or lower case)
159  ** in the set of assigned names
160  ** or modify the name
161  **/
162 std::string CODEExporterXPPAUT::testName(const std::string & name)
163 {
164  std::locale C("C");
165  char ch;
166 
167  std::ostringstream newname, tmp;
168 
169  size_t name_size = name.size();
170  size_t i;
171 
172  for (i = 0; i < name_size; i++)
173  {
174  ch = name[i];
175 
176  if (std::isalpha(ch, C) && std::islower(ch, C))
177  tmp << (char) toupper(ch);
178  else
179  tmp << ch;
180  }
181 
182  if (NameSet.find(tmp.str()) == NameSet.end())
183  {
184  NameSet.insert(tmp.str());
185  Frequancy[tmp.str()] = 0;
186 
187  return name;
188  }
189  else
190  {
191 
192  std::string ecount;
193  std::ostringstream tmpecount;
194  std::ostringstream tmpname;
195  size_t ecount_size, tmpname_size;
196 
197  Frequancy[tmp.str()]++;
198  tmpecount << Frequancy[tmp.str()];
199 
200  ecount = tmpecount.str();
201 
202  ecount_size = ecount.size();
203 
204  if (ecount_size > 6)
205  {
206  CCopasiMessage(CCopasiMessage::ERROR, "too many repeated names to modify to XPP syntax"); //TODO
207  fatalError();
208  }
209 
210  tmpname_size = name_size + ecount_size;
211 
212  if (tmpname_size > 7)
213  {
214  for (i = 0; i < (7 - ecount_size); i++)
215  tmpname << name[i];
216  }
217  else
218  tmpname << name << ecount;
219 
220  return testName(tmpname.str());
221  }
222 }
223 
225 {
226  size_t i;
227 
228  const std::string reserved[45] =
229  {
230  "SIN", "COS", "TAN", "ATAN", "ATAN2", "SINH", "EXP", "DELAY", "LN", "LOG10",
231  "LOG", "T", "PI", "IF", "THEN", "ELSE", "ASIN", "ACOS", "HEAV", "SIGN",
232  "CEIL", "FLR", "RAN", "ABS", "MAX", "MIN", "NORMAL", "BESSELJ", "BESSELY", "ERF",
233  "ERFS", "ARG1", "ARG2", "ARG2", "ARG4", "ARG5", "ARG6", "ARG7", "ARG8", "ARG9",
234  "SHIFT", "NOT", "INT", "SUM", "OF"
235  };
236 
237  for (i = 0; i < 45; i++)
238  {
239  NameSet.insert(reserved[i]);
240  Frequancy[reserved[i]] = 0;
241  }
242 
243  return;
244 }
245 
246 std::string CODEExporterXPPAUT::setODEName(const std::string & objName)
247 {
248  return "d" + objName + "/dt";
249 }
250 
251 std::string CODEExporterXPPAUT::setConcentrationName(const std::string & objName)
252 {
253  return objName + "_c";
254 }
255 
256 /*
257  ** The line length in XPPAUT ODE files (ASCII readable files) is limited to 256 characters.
258  ** Individual lines can be continued with the UNIX backslash character, "\".
259  ** The total length of any line cannot exceed 1000 characters.
260  */
261 void CODEExporterXPPAUT::exportSingleLine(const std::string & line, std::ostringstream & which)
262 {
263 
264  std::locale C("C");
265 
266  size_t limit = 256, total = 1000;
267 
268  //size_t limit = 10, total = 15;
269  if (line.size() > total)
271 
272  if (line.size() > limit)
273  {
274 
275  size_t i, pos0, pos, end = line.size();
276 
277  pos0 = 0;
278  pos = limit - 1;
279 
280  while (pos < end)
281  {
282 
283  std::string part;
284  char ch;
285  ch = line[pos];
286 
287  while (std::isalnum(ch, C) || ch == '_' || ch == ')')
288  {
289  pos--;
290  ch = line[pos];
291  }
292 
293  for (i = pos0; i < pos; i++)
294  {
295  part += line[i];
296  }
297 
298  part += " \\";
299 
300  which << part.c_str() << std::endl;
301 
302  pos0 = pos;
303  pos += limit;
304  }
305 
306  if (pos > end)
307  {
308  std::string part;
309 
310  for (i = pos0; i < end; i++)
311  {
312  part += line[i];
313  }
314 
315  which << part.c_str() << std::endl;
316  }
317  }
318  else
319  which << line << std::endl;
320 
321  return;
322 }
323 
324 bool CODEExporterXPPAUT::exportSingleObject(std::ostringstream & which,
325  const std::string & name,
326  const std::string & expression,
327  const std::string & /* comments */)
328 {
329  std::ostringstream line;
330 
331  line << name << "=" << expression;
332  exportSingleLine(line.str(), which);
333 
334  return true;
335 }
336 
337 bool CODEExporterXPPAUT::exportSingleMetabolite(const CMetab* metab, std::string & expression, std::string & comments)
338 {
339  std::string name;
340 
341  std::ostringstream smKey;
342  smKey << "sm_" << metab->getKey();
343  name = NameMap[smKey.str()];
344 
345  switch (metab->getStatus())
346  {
347  case CModelEntity::FIXED:
348  {
349  fixed << "#" << comments << std::endl;
350  fixed << "param ";
351 
352  if (!exportSingleObject(fixed, name, expression, comments))
353  return false;
354 
355  break;
356  }
357 
358  case CModelEntity::ODE:
360  {
361  if (!metab->isDependent())
362  {
363  initial << "#" << comments << std::endl;
364  initial << "init ";
365 
366  if (!exportSingleObject(initial, name, expression, comments))
367  return false;
368  }
369  else
370  {
371  assignment << "#" << comments << std::endl;
372 
373  if (!exportSingleObject(assignment, name, expression, comments))
374  return false;
375  }
376 
377  break;
378  }
379 
381  {
382  assignment << "#" << comments << std::endl;
383 
384  if (!exportSingleObject(assignment, name, expression, comments))
385  return false;
386 
387  break;
388  }
389 
390  default:
391  return false;
392  break;
393  }
394 
395  return true;
396 }
397 
398 bool CODEExporterXPPAUT::exportSingleCompartment(const CCompartment* comp, std::string & expression, std::string & comments)
399 {
400 
401  switch (comp->getStatus())
402  {
403  case CModelEntity::FIXED:
404  {
405  fixed << "#" << comments << std::endl;
406  fixed << "param ";
407 
408  if (!exportSingleObject(fixed, NameMap[comp->getKey()], expression, comments))
409  return false;
410 
411  break;
412  }
413 
414  case CModelEntity::ODE:
415  {
416  initial << "#" << comments << std::endl;
417  initial << "init ";
418 
419  if (!exportSingleObject(initial, NameMap[comp->getKey()], expression, comments))
420  return false;
421 
422  break;
423  }
424 
426  {
427 #if 0
428  assignment << "#" << comments << std::endl;
429 
430  if (!exportSingleObject(assignment, NameMap[comp->getKey()], expression, comments))
431  return false;
432 
433 #endif
434  break;
435  }
436 
437  default:
438  return false;
439  break;
440  }
441 
442  return true;
443 }
444 
445 bool CODEExporterXPPAUT::exportSingleModVal(const CModelValue* modval, std::string & expression, std::string & comments)
446 {
447 
448  switch (modval->getStatus())
449  {
450  case CModelEntity::FIXED:
451  {
452  fixed << "#" << comments << std::endl;
453  fixed << "param ";
454 
455  if (!exportSingleObject(fixed, NameMap[modval->getKey()], expression, comments))
456  return false;
457 
458  break;
459  }
460 
461  case CModelEntity::ODE:
462  {
463  initial << "#" << comments << std::endl;
464  initial << "init ";
465 
466  if (!exportSingleObject(initial, NameMap[modval->getKey()], expression, comments))
467  return false;
468 
469  break;
470  }
471 
473  {
474 #if 0
475  assignment << "#" << comments << std::endl;
476 
477  if (!exportSingleObject(assignment, NameMap[modval->getKey()], expression, comments))
478  return false;
479 
480 #endif
481  break;
482  }
483 
484  default:
485  return false;
486  break;
487  }
488 
489  return true;
490 }
491 
492 bool CODEExporterXPPAUT::exportSingleModelEntity(const CModelEntity* tmp, std::string & expression, std::string & comments)
493 {
494  std::string name;
495 
496  const CMetab* metab;
497  metab = dynamic_cast< const CMetab * >(tmp);
498 
499  if (metab)
500  {
501  std::ostringstream smKey;
502  smKey << "sm_" << metab->getKey();
503  name = NameMap[smKey.str()];
504  }
505  else
506  name = NameMap[tmp->getKey()];
507 
508  switch (tmp->getStatus())
509  {
510  case CModelEntity::FIXED:
511  {
512  fixed << "#" << comments << std::endl;
513  fixed << "param ";
514 
515  if (!exportSingleObject(fixed, name, expression, comments))
516  return false;
517 
518  break;
519  }
520 
521  case CModelEntity::ODE:
522  {
523  initial << "#" << comments << std::endl;
524  initial << "init ";
525 
526  if (!exportSingleObject(initial, name, expression, comments))
527  return false;
528 
529  break;
530  }
531 
533  {
534  assignment << "#" << comments << std::endl;
535 
536  if (!exportSingleObject(assignment, name, expression, comments))
537  return false;
538 
539  break;
540  }
541 
542  default:
543  return false;
544  break;
545  }
546 
547  return true;
548 }
549 
550 bool CODEExporterXPPAUT::exportSingleParameter(const CCopasiParameter* param, std::string & expression, std::string & comments)
551 {
552  fixed << "#" << comments << std::endl;
553 
554  fixed << "param ";
555 
556  if (!exportSingleObject(fixed, NameMap[param->getKey()], expression, comments)) return false;
557 
558  return true;
559 }
560 
562 {
563  std::string str1;
564  str1 = func->getRoot()->buildXPPString();
565  return str1;
566 }
567 
569 {
570  std::string str1;
571  str1 = tmp->getRoot()->buildXPPString();
572  return str1;
573 }
574 
576 {
577 
578  std::ostringstream localKey;
579  localKey << reac->getKey() << "_root_func";
580 
581  return NameMap[localKey.str()];
582 }
583 
584 bool CODEExporterXPPAUT::exportSingleODE(const CModelEntity* mentity, std::string & equation, std::string & comments)
585 {
586  std::ostringstream odeKey;
587 
588  if (!isEmptyString(comments)) ode << "#" << comments << std::endl;
589 
590  odeKey << "ode_" << mentity->getKey();
591 
592  if (!exportSingleObject(ode, NameMap[odeKey.str()], equation, comments)) return false;
593 
594  return true;
595 }
596 
597 std::string CODEExporterXPPAUT::exportTitleString(const size_t tmp)
598 {
599  switch (tmp)
600  {
601  case INITIAL:
602  return "# Initial values:";
603 
604  case FIXED:
605  return "# Fixed Model Entities:";
606 
607  case ASSIGNMENT:
608  return "# Assignment Model Entities:";
609 
610  case FUNCTIONS:
611  return "#Kinetics: ";
612 
613  case HEADERS:
614  return " ";
615 
616  case ODEs:
617  return "# Equations:";
618 
619  default:
620  return " ";
621  }
622 }
623 
624 bool CODEExporterXPPAUT::exportClosingData(const CModel* /* copasiModel */, std::ostream & os)
625 {
626  os << "done" << std::endl;
627  return true;
628 }
Header file of class CExpression.
virtual bool exportSingleParameter(const CCopasiParameter *param, std::string &expression, std::string &comments)
virtual std::string getDisplayFunctionString(CFunction *func)
CCopasiProblem * getProblem()
virtual bool exportSingleMetabolite(const CMetab *metab, std::string &expression, std::string &comments)
std::set< std::string > NameSet
virtual bool exportSingleODE(const CModelEntity *mentity, std::string &equation, std::string &comments)
virtual const std::string & getKey() const
Definition: CReaction.cpp:190
#define fatalError()
virtual std::string exportTitleString(const size_t tmp)
bool exportClosingData(const CModel *copasiModel, std::ostream &os)
std::ostringstream initial
Definition: CODEExporter.h:155
void exportSingleLine(const std::string &line, std::ostringstream &which)
Definition: CMetab.h:178
virtual std::string translateObjectName(const std::string &realName)
virtual bool exportSingleCompartment(const CCompartment *comp, std::string &expression, std::string &comments)
virtual bool isEmptyString(std::string &str)
std::string setConcentrationName(const std::string &objName)
std::string testName(const std::string &name)
const C_FLOAT64 & getStepSize() const
virtual bool exportSingleModVal(const CModelValue *modval, std::string &expression, std::string &comments)
std::string buildXPPString() const
#define MCODEExporter
std::ostringstream ode
Definition: CODEExporter.h:160
const C_FLOAT64 & getDuration() const
virtual const std::string & getKey() const
virtual const std::string & getKey() const
virtual std::string getDisplayExpressionString(CExpression *tmp)
static size_t size()
virtual bool exportTitleData(const CCopasiDataModel *pDataModel, std::ostream &os)
virtual std::string translateTimeVariableName()
bool isDependent() const
Definition: CMetab.cpp:989
std::map< std::string, std::string > NameMap
Definition: CODEExporter.h:151
std::ostringstream assignment
Definition: CODEExporter.h:157
The class for handling a chemical kinetic function.
Definition: CFunction.h:29
virtual bool exportSingleObject(std::ostringstream &which, const std::string &name, const std::string &expression, const std::string &comments)
Definition: CModel.h:50
std::map< std::string, unsigned C_INT32 > Frequancy
std::ostringstream fixed
Definition: CODEExporter.h:156
const CModelEntity::Status & getStatus() const
virtual bool exportSingleModelEntity(const CModelEntity *tmp, std::string &expression, std::string &comments)
virtual void setReservedNames()
CEvaluationNode * getRoot()
virtual std::string KineticFunction2ODEmember(const CReaction *reac)
std::string setODEName(const std::string &objName)