COPASI API  4.16.103
Expression2PresentationMML.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) 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) 2008 - 2009 by Sven Sahle and University of Heidelberg
12 // All rights reserved.
13 
15 #include <sbml/Model.h>
16 
17 #include "utilities/copasimathml.h"
18 
20  : mRootNode(rootnode), mpModel(NULL), mpReaction(NULL),
21  mUseReactionNameInLocalParameters(true)
22 {
23 }
24 
25 void Expression2PresentationMML::writeMathML(std::ostream & out) const
26 {
27  writeMathML(out, mRootNode, 0);
28 }
29 
30 #define SPC(level) std::string(level, ' ')
31 
32 void Expression2PresentationMML::writeMathML(std::ostream & out, const ASTNode* node, size_t l) const
33 {
34  int type = (int)node->getType();
35 
36  //piecewise
37  if (type == AST_FUNCTION_PIECEWISE)
38  {
39  size_t i;
40  out << SPC(l) << "<mrow>" << std::endl;
41  out << SPC(l + 1) << "<mo> {</mo>" << std::endl;
42  out << SPC(l + 1) << "<mtable>" << std::endl;
43 
44  for (i = 0; i < node->getNumChildren() / 2 + 1; ++i)
45  {
46  out << SPC(l + 2) << "<mtr>" << std::endl;
47  out << SPC(l + 3) << "<mtd>" << std::endl;
48  writeMathML(out, node->getChild((unsigned int)(0 + i * 2)), l + 3);
49  out << SPC(l + 3) << "<mo> , </mo>" << std::endl;
50  out << SPC(l + 3) << "</mtd>" << std::endl;
51 
52  out << SPC(l + 3) << "<mtd>" << std::endl;
53 
54  if (1 + i * 2 >= node->getNumChildren())
55  out << SPC(l + 3) << "<mo> else </mo>" << std::endl;
56  else
57  writeMathML(out, node->getChild((unsigned int)(1 + i * 2)), l + 3);
58 
59  out << SPC(l + 3) << "</mtd>" << std::endl;
60  out << SPC(l + 2) << "</mtr>" << std::endl;
61  }
62 
63  out << SPC(l + 1) << "</mtable>" << std::endl;
64  out << SPC(l) << "</mrow>" << std::endl;
65  return;
66  }
67 
68  //other functions like power, root
69  if (type == AST_FUNCTION_POWER)
70  type = AST_POWER;
71 
72  //generic functions, including call nodes. Call nodes may be handles separately later.
73  if (type >= AST_FUNCTION/*_ABS*/ && type <= AST_FUNCTION_TANH)
74  {
75  writeMathMLFunction(out, node, l);
76  return;
77  }
78 
79  if (node->isNumber())
80  {
81  writeMathMLNumber(out, node, l);
82  return;
83  }
84 
85  size_t i;
86  size_t tmp;
87  bool flag;
88 
89  switch (type)
90  {
91  case AST_NAME:
92  writeMathMLName(out, node, l);
93  break;
94 
95  case AST_PLUS:
96  out << SPC(l) << "<mrow>" << std::endl;
97 
98  for (i = 0; i < node->getNumChildren(); ++i)
99  {
100  if (i)
101  out << SPC(l + 1) << "<mo>" << "+" << "</mo>" << std::endl;
102 
103  writeMathML(out, node->getChild((unsigned int) i), l + 1);
104  }
105 
106  out << SPC(l) << "</mrow>" << std::endl;
107  break;
108 
109  case AST_MINUS:
110 
111  if (node->getNumChildren() <= 0 || node->getNumChildren() > 2)
112  break;
113 
114  out << SPC(l) << "<mrow>" << std::endl;
115 
116  if (node->getNumChildren() == 2)
117  writeMathML(out, node->getChild(0), l + 1);
118 
119  out << SPC(l + 1) << "<mo>" << "-" << "</mo>" << std::endl;
120 
121  tmp = node->getNumChildren() - 1; //the last child
122  flag = (node->getChild((unsigned int) tmp)->getType() == AST_PLUS)
123  || (node->getChild((unsigned int) tmp)->getType() == AST_MINUS);
124 
125  // || ((node->getChild(tmp)->getType() == AST_FUNCTION) && expand)); // a function call
126  if (flag) out << SPC(l + 1) << "<mfenced>" << std::endl;
127 
128  writeMathML(out, node->getChild((unsigned int) tmp), l + 2);
129 
130  if (flag) out << SPC(l + 1) << "</mfenced>" << std::endl;
131 
132  out << SPC(l) << "</mrow>" << std::endl;
133  break;
134 
135  case AST_TIMES:
136  out << SPC(l) << "<mrow>" << std::endl;
137 
138  for (i = 0; i < node->getNumChildren(); ++i)
139  {
140  if (i)
141  out << SPC(l + 1) << "<mo>" << "&CenterDot;" << "</mo>" << std::endl;
142 
143  //do we need "()" ?
144  flag = (node->getChild((unsigned int) i)->getType() == AST_PLUS)
145  || (node->getChild((unsigned int) i)->getType() == AST_MINUS);
146 
147  // || ((node->getChild(i)->getType() == AST_FUNCTION) && expand)); // a function call
148  if (flag) out << SPC(l + 1) << "<mfenced>" << std::endl;
149 
150  writeMathML(out, node->getChild((unsigned int) i), l + 1);
151 
152  if (flag) out << SPC(l + 1) << "</mfenced>" << std::endl;
153  }
154 
155  out << SPC(l) << "</mrow>" << std::endl;
156  break;
157 
158  case AST_DIVIDE:
159  out << SPC(l) << "<mfrac>" << std::endl;
160 
161  //out << SPC(l + 1) << "<mrow>" << std::endl;
162  writeMathML(out, node->getChild(0), l + 1);
163  //out << SPC(level + 1) << "</mrow>" << std::endl;
164 
165  //out << SPC(l + 1) << "<mrow>" << std::endl;
166  writeMathML(out, node->getChild(1), l + 1);
167  //out << SPC(l + 1) << "</mrow>" << std::endl;
168 
169  out << SPC(l) << "</mfrac>" << std::endl;
170  break;
171 
172  case AST_POWER:
173  out << SPC(l) << "<msup>" << std::endl;
174 
175  //do we need "()" ?
176  flag = ((node->getChild(0)->getType() == AST_PLUS)
177  || (node->getChild(0)->getType() == AST_MINUS)
178  || (node->getChild(0)->getType() == AST_TIMES)
179  || (node->getChild(0)->getType() == AST_DIVIDE)
180  || (node->getChild(0)->getType() == AST_POWER));
181  // || (((node->getChild(0)->getType() == AST_FUNCTION) && expand)
182 
183  if (flag) out << SPC(l + 1) << "<mfenced>" << std::endl;
184 
185  writeMathML(out, node->getChild(0), l + 2);
186 
187  if (flag) out << SPC(l + 1) << "</mfenced>" << std::endl;
188 
189  out << SPC(l + 1) << "<mrow>" << std::endl;
190  writeMathML(out, node->getChild(1), l + 2);
191  out << SPC(l + 1) << "</mrow>" << std::endl;
192 
193  out << SPC(l) << "</msup>" << std::endl;
194  break;
195 
196  case AST_CONSTANT_E:
197  out << "<mi>&ExponentialE;</mi>" << std::endl;
198  break;
199 
200  case AST_CONSTANT_PI:
201  out << SPC(l) << "<mi>&pi;</mi>" << std::endl;
202  break;
203 
204  case AST_CONSTANT_FALSE:
205  out << SPC(l) << "<mi>false</mi>" << std::endl;
206  break;
207 
208  case AST_CONSTANT_TRUE:
209  out << SPC(l) << "<mi>true</mi>" << std::endl;
210  break;
211 
212  case AST_NAME_TIME:
213  out << SPC(l) << "<mi>t</mi>" << std::endl;
214  break;
215 
216  case AST_LOGICAL_AND:
217  case AST_LOGICAL_OR:
218  case AST_LOGICAL_XOR:
219  case AST_RELATIONAL_EQ:
220  case AST_RELATIONAL_GEQ:
221  case AST_RELATIONAL_GT:
222  case AST_RELATIONAL_LEQ:
223  case AST_RELATIONAL_LT:
224  case AST_RELATIONAL_NEQ:
225  {
226  std::string op;
227 
228  switch (type)
229  {
230  case AST_LOGICAL_AND: op = "&And;"; flag = true; break;
231 
232  case AST_LOGICAL_OR: op = "&Or;"; flag = true; break;
233 
234  case AST_LOGICAL_XOR: op = "xor"; flag = true; break;
235 
236  case AST_RELATIONAL_EQ: op = "="; flag = false; break;
237 
238  case AST_RELATIONAL_GEQ: op = "&geq;"; flag = false; break;
239 
240  case AST_RELATIONAL_GT: op = "&gt;"; flag = false; break;
241 
242  case AST_RELATIONAL_LEQ: op = "&leq;"; flag = false; break;
243 
244  case AST_RELATIONAL_LT: op = "&lt;"; flag = false; break;
245 
246  case AST_RELATIONAL_NEQ: op = "&NotEqual;"; flag = false; break;
247 
248  default: op = "???"; flag = true; break;
249  }
250 
251  out << SPC(l) << "<mrow>" << std::endl;
252 
253  for (i = 0; i < node->getNumChildren(); ++i)
254  {
255  if (i)
256  out << SPC(l + 1) << "<mo>" << op << "</mo>" << std::endl;
257 
258  //do we need "()" ?
259 
260  if (flag) out << SPC(l + 1) << "<mfenced>" << std::endl;
261 
262  writeMathML(out, node->getChild((unsigned int) i), l + 1);
263 
264  if (flag) out << SPC(l + 1) << "</mfenced>" << std::endl;
265  }
266 
267  out << SPC(l) << "</mrow>" << std::endl;
268  }
269  break;
270 
271  case AST_LOGICAL_NOT:
272  out << SPC(l) << "<mover>" << std::endl;
273  writeMathML(out, node->getChild(0), l + 1);
274  out << SPC(l) << "<mo>&OverBar;</mo></mover>" << std::endl;
275  break;
276 
277  default:
278  out << SPC(l) << "<mi>" << "xxx" << "</mi>" << std::endl;
279  break;
280  }
281 }
282 
283 void Expression2PresentationMML::writeMathMLFunction(std::ostream & out, const ASTNode* node, size_t l) const
284 {
285  out << SPC(l) << "<mrow>" << std::endl;
286 
287  out << SPC(l + 1) << "<mi>" << CMathMl::fixName(node->getName()) << "</mi>" << std::endl;
288  out << SPC(l + 1) << "<mo> &ApplyFunction; </mo>" << std::endl;
289  out << SPC(l + 1) << "<mrow>" << std::endl;
290  out << SPC(l + 2) << "<mo> (</mo>" << std::endl;
291  out << SPC(l + 2) << "<mrow>" << std::endl;
292 
293  size_t i;
294 
295  for (i = 0; i < node->getNumChildren(); ++i)
296  {
297  if (i)
298  out << SPC(l + 3) << "<mo> , </mo>" << std::endl;
299 
300  writeMathML(out, node->getChild((unsigned int) i), l + 3);
301  }
302 
303  out << SPC(l + 2) << "</mrow>" << std::endl;
304  out << SPC(l + 2) << "<mo>) </mo>" << std::endl;
305 
306  out << SPC(l + 1) << "</mrow>" << std::endl;
307  out << SPC(l) << "</mrow>" << std::endl;
308 }
309 
310 void Expression2PresentationMML::writeMathMLName(std::ostream & out, const ASTNode* node, size_t l) const
311 {
312 
313  if (!mpModel)
314  {
315  out << SPC(l) << "<mi>" << CMathMl::fixName(node->getName()) << "</mi>" << std::endl;
316  return;
317  }
318 
319  if (mpReaction)
320  {
321  const Parameter* p = mpReaction->getKineticLaw()->getParameter(node->getName());
322 
323  if (p)
324  {
325  std::string ident = p->getName() == "" ? p->getId() : p->getName();
326  std::string r_ident = mpReaction->getName() == "" ? mpReaction->getId() : mpReaction->getName();
327 
328  if (!mUseReactionNameInLocalParameters) r_ident = "local";
329 
330  out << SPC(l) << "<msub><mi>" << ident << "</mi><mi>" << r_ident << "</mi></msub>" << std::endl;
331  return;
332  }
333  }
334 
335  const Compartment* c = mpModel->getCompartment(node->getName());
336 
337  if (c)
338  {
339  std::string ident = c->getName() == "" ? c->getId() : c->getName();
340  std::string ccc;
341 
342  switch (c->getSpatialDimensions())
343  {
344  case 1: ccc = "l"; break;
345 
346  case 2: ccc = "A"; break;
347 
348  case 3: ccc = "V"; break;
349 
350  default: ccc = "ERROR";
351  }
352 
353  out << SPC(l) << "<msub><mi>" << ccc << "</mi><mi>" << ident << "</mi></msub>" << std::endl;
354  return;
355  }
356 
357  const Species* s = mpModel->getSpecies(node->getName());
358 
359  if (s)
360  {
361  std::string ident = s->getName() == "" ? s->getId() : s->getName();
362 
363  if (!s->getHasOnlySubstanceUnits())
364  out << SPC(l) << "<mi>[" << ident << "]</mi>" << std::endl;
365  else
366  {
367  out << SPC(l) << "<mrow><msup><mphantom><mi>.</mi></mphantom><mi mathcolor=\"gray\">S</mi></msup><mi>" << ident << "</mi></mrow>" << std::endl;
368  }
369 
370  return;
371  }
372 
373  const Parameter* p = mpModel->getParameter(node->getName());
374 
375  if (p)
376  {
377  std::string ident = p->getName() == "" ? p->getId() : p->getName();
378  //out << SPC(l) << "<mi>" << ident << "</mi>" << std::endl;
379  out << SPC(l) << "<mrow><msup><mphantom><mi>.</mi></mphantom><mi mathcolor=\"gray\">P</mi></msup><mi>" << ident << "</mi></mrow>" << std::endl;
380  return;
381  }
382 
383  //TODO area, length, reaction rates
384  out << SPC(l) << "<mi>" << CMathMl::fixName(node->getName()) << "</mi>" << std::endl;
385 }
386 
387 void Expression2PresentationMML::writeMathMLNumber(std::ostream & out, const ASTNode* node, size_t l) const
388 {
389  if (node->isInteger())
390  out << SPC(l) << "<mn>" << node->getInteger() << "</mn>" << std::endl;
391  else if (node->isReal())
392  out << SPC(l) << "<mn>" << node->getReal() << "</mn>" << std::endl;
393 
394  //TODO rational
395 }
virtual void writeMathMLNumber(std::ostream &out, const ASTNode *node, size_t l) const
void writeMathML(std::ostream &out) const
static std::string fixName(const std::string &name)
Definition: copasimathml.h:33
virtual void writeMathMLFunction(std::ostream &out, const ASTNode *node, size_t l) const
#define SPC(level)
Expression2PresentationMML(const ASTNode *rootnode)
long int flag
Definition: f2c.h:52
virtual void writeMathMLName(std::ostream &out, const ASTNode *node, size_t l) const