musrfit  1.9.2
PFunction.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  PFunction.cpp
4 
5  Author: Andreas Suter
6  e-mail: andreas.suter@psi.ch
7 
8 ***************************************************************************/
9 
10 /***************************************************************************
11  * Copyright (C) 2007-2023 by Andreas Suter *
12  * andreas.suter@psi.ch *
13  * *
14  * This program is free software; you can redistribute it and/or modify *
15  * it under the terms of the GNU General Public License as published by *
16  * the Free Software Foundation; either version 2 of the License, or *
17  * (at your option) any later version. *
18  * *
19  * This program is distributed in the hope that it will be useful, *
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22  * GNU General Public License for more details. *
23  * *
24  * You should have received a copy of the GNU General Public License *
25  * along with this program; if not, write to the *
26  * Free Software Foundation, Inc., *
27  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
28  ***************************************************************************/
29 
30 #include<cmath>
31 
32 #include <iostream>
33 
34 #include <boost/algorithm/string/trim.hpp> // for stripping leading whitespace in std::string
35 
36 #include "PMusr.h"
37 #include "PFunction.h"
38 
39 //--------------------------------------------------------------------------
40 // Constructor
41 //--------------------------------------------------------------------------
62 PFunction::PFunction(tree_parse_info<> info) : fInfo(info)
63 {
64  // init class variables
65  fValid = true;
66  fFuncNo = -1;
67 
68  // set the function number
69  SetFuncNo();
70 
71  // generate function evaluation tree
72  if (!GenerateFuncEvalTree()) {
73  fValid = false;
74  }
75 
76  EvalTreeForString(info);
77 }
78 
79 //--------------------------------------------------------------------------
80 // Destructor
81 //--------------------------------------------------------------------------
86 {
87  fParam.clear();
88  fMap.clear();
89 
91 }
92 
93 //--------------------------------------------------------------------------
94 // InitNode (protected)
95 //--------------------------------------------------------------------------
102 {
103  node.fID = 0;
104  node.fOperatorTag = 0;
105  node.fFunctionTag = 0;
106  node.fIvalue = 0;
107  node.fSign = false;
108  node.fDvalue = 0.0;
109 }
110 
111 //-------------------------------------------------------------
112 // SetFuncNo (protected)
113 //-------------------------------------------------------------
120 {
121  Int_t funNo = -1;
122  Int_t status;
123  Bool_t success = true;
124 
125  // get root
126  iter_t i = fInfo.trees.begin(); // assignement
127  i = i->children.begin(); // FUNx
128 
129  // get string from tree
130  std::string str(i->value.begin(), i->value.end());
131  boost::algorithm::trim(str);
132 
133  // extract function number from string
134  status = sscanf(str.c_str(), "FUN%d", &funNo);
135  if (status == 1) { // found 1 Int_t
136  fFuncNo = funNo;
137  } else { // wrong string
138  success = false;
139  }
140 
141  return success;
142 }
143 
144 //-------------------------------------------------------------
145 // GenerateFuncEvalTree (protected)
146 //-------------------------------------------------------------
152 {
153  InitNode(fFunc);
154  FillFuncEvalTree(fInfo.trees.begin(), fFunc);
155 
156  return true;
157 }
158 
159 //-------------------------------------------------------------
160 // FillFuncEvalTree (protected)
161 //-------------------------------------------------------------
169 {
170  Double_t dvalue;
171  Int_t ivalue;
172  Int_t status;
173  std::string str;
174  PFuncTreeNode child;
175 
176  InitNode(child);
177 
178  if (i->value.id() == PFunctionGrammar::realID) { // handle number
179  str = std::string(i->value.begin(), i->value.end()); // get string
180  boost::algorithm::trim(str);
181  status = sscanf(str.c_str(), "%lf", &dvalue); // convert string to Double_t
182  node.fID = PFunctionGrammar::realID; // keep the ID
183  node.fDvalue = dvalue; // keep the value
184  } else if (i->value.id() == PFunctionGrammar::constPiID) { // handle constant pi
185  node.fID = PFunctionGrammar::constPiID; // keep the ID
186  node.fDvalue = 3.14159265358979323846; // keep the value
187  } else if (i->value.id() == PFunctionGrammar::constGammaMuID) { // handle constant gamma_mu
188  node.fID = PFunctionGrammar::constGammaMuID; // keep the ID
189  node.fDvalue = GAMMA_BAR_MUON; // keep the value
190  } else if (i->value.id() == PFunctionGrammar::constFieldID) { // handle constant field from meta data
191  node.fID = PFunctionGrammar::constFieldID; // keep the ID
192  } else if (i->value.id() == PFunctionGrammar::constEnergyID) { // handle constant energy from meta data
193  node.fID = PFunctionGrammar::constEnergyID; // keep the ID
194  } else if (i->value.id() == PFunctionGrammar::constTempID) { // handle constant temperature from meta data
195  str = std::string(i->value.begin(), i->value.end()); // get string
196  boost::algorithm::trim(str);
197  status = sscanf(str.c_str(), "T%d", &ivalue); // convert string to temperature index
198  node.fID = PFunctionGrammar::constTempID; // keep the ID
199  node.fIvalue = ivalue; // Temp idx
200  } else if (i->value.id() == PFunctionGrammar::parameterID) { // handle parameter number
201  str = std::string(i->value.begin(), i->value.end()); // get string
202  boost::algorithm::trim(str);
203  if (strstr(str.c_str(), "-")) {
204  node.fSign = true;
205  status = sscanf(str.c_str(), "-PAR%d", &ivalue); // convert string to parameter number
206  } else {
207  status = sscanf(str.c_str(), "PAR%d", &ivalue); // convert string to parameter number
208  }
209  node.fID = PFunctionGrammar::parameterID; // keep the ID
210  node.fIvalue = ivalue; // keep the value
211  } else if (i->value.id() == PFunctionGrammar::mapID) { // handle map number
212  str = std::string(i->value.begin(), i->value.end()); // get string
213  boost::algorithm::trim(str);
214  status = sscanf(str.c_str(), "MAP%d", &ivalue); // convert string to map number
215  node.fID = PFunctionGrammar::mapID; // keep the ID
216  node.fIvalue = ivalue; // keep the value
217  } else if (i->value.id() == PFunctionGrammar::functionID) { // handle function like cos ...
218  // keep the id
220  // keep function tag
221  str = std::string(i->value.begin(), i->value.end()); // get string
222  if (!strcmp(str.c_str(), "COS"))
223  node.fFunctionTag = FUN_COS;
224  else if (!strcmp(str.c_str(), "SIN"))
225  node.fFunctionTag = FUN_SIN;
226  else if (!strcmp(str.c_str(), "TAN"))
227  node.fFunctionTag = FUN_TAN;
228  else if (!strcmp(str.c_str(), "COSH"))
229  node.fFunctionTag = FUN_COSH;
230  else if (!strcmp(str.c_str(), "SINH"))
231  node.fFunctionTag = FUN_SINH;
232  else if (!strcmp(str.c_str(), "TANH"))
233  node.fFunctionTag = FUN_TANH;
234  else if (!strcmp(str.c_str(), "ACOS"))
235  node.fFunctionTag = FUN_ACOS;
236  else if (!strcmp(str.c_str(), "ASIN"))
237  node.fFunctionTag = FUN_ASIN;
238  else if (!strcmp(str.c_str(), "ATAN"))
239  node.fFunctionTag = FUN_ATAN;
240  else if (!strcmp(str.c_str(), "ACOSH"))
241  node.fFunctionTag = FUN_ACOSH;
242  else if (!strcmp(str.c_str(), "ASINH"))
243  node.fFunctionTag = FUN_ASINH;
244  else if (!strcmp(str.c_str(), "ATANH"))
245  node.fFunctionTag = FUN_ATANH;
246  else if (!strcmp(str.c_str(), "LOG"))
247  node.fFunctionTag = FUN_LOG;
248  else if (!strcmp(str.c_str(), "LN"))
249  node.fFunctionTag = FUN_LN;
250  else if (!strcmp(str.c_str(), "EXP"))
251  node.fFunctionTag = FUN_EXP;
252  else if (!strcmp(str.c_str(), "SQRT"))
253  node.fFunctionTag = FUN_SQRT;
254  else {
255  std::cerr << std::endl << "**PANIC ERROR**: function " << str << " doesn't exist, but you never should have reached this point!";
256  std::cerr << std::endl;
257  assert(0);
258  }
259  // add node
260  node.children.push_back(child);
261  // i: '(', 'expression', ')'
262  FillFuncEvalTree(i->children.begin()+1, node.children[0]);
263  } else if (i->value.id() == PFunctionGrammar::powerID) {
264  // keep the id
266  // keep function tag
267  str = std::string(i->value.begin(), i->value.end()); // get string
268 
269  if (!strcmp(str.c_str(), "POW"))
270  node.fFunctionTag = FUN_POW;
271  else {
272  std::cerr << std::endl << "**PANIC ERROR**: function " << str << " doesn't exist, but you never should have reached this point!";
273  std::cerr << std::endl;
274  assert(0);
275  }
276  // i: '(', 'expression', ',', expression, ')'
277  // add node
278  node.children.push_back(child);
279  FillFuncEvalTree(i->children.begin()+1, node.children[0]); // base
280  // add node
281  node.children.push_back(child);
282  FillFuncEvalTree(i->children.begin()+3, node.children[1]); // exponent
283  } else if (i->value.id() == PFunctionGrammar::factorID) {
284  // keep the id
286  // add child lhs
287  node.children.push_back(child);
288  FillFuncEvalTree(i->children.begin(), node.children[0]);
289  } else if (i->value.id() == PFunctionGrammar::termID) {
290  // keep the id
292  // keep operator tag
293  if (*i->value.begin() == '*')
294  node.fOperatorTag = OP_MUL;
295  else
296  node.fOperatorTag = OP_DIV;
297  // add child lhs
298  node.children.push_back(child);
299  FillFuncEvalTree(i->children.begin(), node.children[0]);
300  // add child rhs
301  node.children.push_back(child);
302  FillFuncEvalTree(i->children.begin()+1, node.children[1]);
303  } else if (i->value.id() == PFunctionGrammar::expressionID) { // handle expression
304  // keep the id
306  // keep operator tag
307  if (*i->value.begin() == '+')
308  node.fOperatorTag = OP_ADD;
309  else
310  node.fOperatorTag = OP_SUB;
311  // add child lhs
312  node.children.push_back(child);
313  FillFuncEvalTree(i->children.begin(), node.children[0]);
314  // add child rhs
315  node.children.push_back(child);
316  FillFuncEvalTree(i->children.begin()+1, node.children[1]);
317  } else if (i->value.id() == PFunctionGrammar::assignmentID) {
318  // nothing to be done except to pass the next element in the ast
319  // i: 'funx', '=', 'expression'
320  FillFuncEvalTree(i->children.begin()+2, node);
321  }
322 }
323 
324 //-------------------------------------------------------------
325 // CheckMapAndParamRange (public)
326 //-------------------------------------------------------------
333 Bool_t PFunction::CheckMapAndParamRange(UInt_t mapSize, UInt_t paramSize)
334 {
335  return FindAndCheckMapAndParamRange(fFunc, mapSize, paramSize);
336 }
337 
338 //-------------------------------------------------------------
339 // FindAndCheckMapAndParamRange (protected)
340 //-------------------------------------------------------------
348 Bool_t PFunction::FindAndCheckMapAndParamRange(PFuncTreeNode &node, UInt_t mapSize, UInt_t paramSize)
349 {
350  if (node.fID == PFunctionGrammar::realID) {
351  return true;
352  } else if (node.fID == PFunctionGrammar::constPiID) {
353  return true;
354  } else if (node.fID == PFunctionGrammar::constGammaMuID) {
355  return true;
356  } else if (node.fID == PFunctionGrammar::constFieldID) {
357  return true;
358  } else if (node.fID == PFunctionGrammar::constEnergyID) {
359  return true;
360  } else if (node.fID == PFunctionGrammar::constTempID) {
361  return true;
362  } else if (node.fID == PFunctionGrammar::parameterID) {
363  if (node.fIvalue <= static_cast<Int_t>(paramSize))
364  return true;
365  else
366  return false;
367  } else if (node.fID == PFunctionGrammar::mapID) {
368  if (node.fIvalue <= static_cast<Int_t>(mapSize))
369  return true;
370  else
371  return false;
372  } else if (node.fID == PFunctionGrammar::functionID) {
373  return FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize);
374  } else if (node.fID == PFunctionGrammar::powerID) {
375  if (FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize))
376  return FindAndCheckMapAndParamRange(node.children[1], mapSize, paramSize);
377  else
378  return false;
379  } else if (node.fID == PFunctionGrammar::factorID) {
380  return FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize);
381  } else if (node.fID == PFunctionGrammar::termID) {
382  if (FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize))
383  return FindAndCheckMapAndParamRange(node.children[1], mapSize, paramSize);
384  else
385  return false;
386  } else if (node.fID == PFunctionGrammar::expressionID) {
387  if (FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize))
388  return FindAndCheckMapAndParamRange(node.children[1], mapSize, paramSize);
389  else
390  return false;
391  } else {
392  std::cerr << std::endl << ">> **PANIC ERROR**: PFunction::FindAndCheckMapAndParamRange: you never should have reached this point!";
393  std::cerr << std::endl << ">> node.fID = " << node.fID;
394  std::cerr << std::endl;
395  assert(0);
396  }
397  return true;
398 }
399 
400 //-------------------------------------------------------------
401 // Eval (public)
402 //-------------------------------------------------------------
410 Double_t PFunction::Eval(std::vector<Double_t> param, PMetaData metaData)
411 {
412  fParam = param;
413  fMetaData = metaData;
414 
415  return EvalNode(fFunc);
416 }
417 
418 //-------------------------------------------------------------
419 // EvalNode (protected)
420 //-------------------------------------------------------------
427 {
428  if (node.fID == PFunctionGrammar::realID) {
429  return node.fDvalue;
430  } else if (node.fID == PFunctionGrammar::constPiID) {
431  return node.fDvalue;
432  } else if (node.fID == PFunctionGrammar::constGammaMuID) {
433  return node.fDvalue;
434  } else if (node.fID == PFunctionGrammar::constFieldID) {
435  return fMetaData.fField;
436  } else if (node.fID == PFunctionGrammar::constEnergyID) {
438  std::cerr << std::endl << "**PANIC ERROR**: PFunction::EvalNode: energy meta data not available." << std::endl;
439  std::cerr << std::endl;
440  exit(0);
441  }
442  return fMetaData.fEnergy;
443  } else if (node.fID == PFunctionGrammar::constTempID) {
444  if (node.fIvalue >= fMetaData.fTemp.size()) {
445  std::cerr << std::endl << "**PANIC ERROR**: PFunction::EvalNode: Temp idx=" << node.fIvalue << " requested which is >= #Temp(s)=" << fMetaData.fTemp.size() << " available." << std::endl;
446  std::cerr << std::endl;
447  exit(0);
448  }
449  return fMetaData.fTemp[node.fIvalue];
450  } else if (node.fID == PFunctionGrammar::parameterID) {
451  Double_t dval;
452  if (node.fSign)
453  dval = -fParam[node.fIvalue-1];
454  else
455  dval = fParam[node.fIvalue-1];
456  return dval;
457  } else if (node.fID == PFunctionGrammar::mapID) {
458  if (fMap[node.fIvalue-1] == 0) // map == 0
459  return 0.0;
460  else
461  return fParam[fMap[node.fIvalue-1]-1];
462  } else if (node.fID == PFunctionGrammar::functionID) {
463  if (node.fFunctionTag == FUN_COS) {
464  return cos(EvalNode(node.children[0]));
465  } else if (node.fFunctionTag == FUN_SIN) {
466  return sin(EvalNode(node.children[0]));
467  } else if (node.fFunctionTag == FUN_TAN) {
468  return tan(EvalNode(node.children[0]));
469  } else if (node.fFunctionTag == FUN_COSH) {
470  return cosh(EvalNode(node.children[0]));
471  } else if (node.fFunctionTag == FUN_SINH) {
472  return sinh(EvalNode(node.children[0]));
473  } else if (node.fFunctionTag == FUN_TANH) {
474  return tanh(EvalNode(node.children[0]));
475  } else if (node.fFunctionTag == FUN_ACOS) {
476  return acos(EvalNode(node.children[0]));
477  } else if (node.fFunctionTag == FUN_ASIN) {
478  return asin(EvalNode(node.children[0]));
479  } else if (node.fFunctionTag == FUN_ATAN) {
480  return atan(EvalNode(node.children[0]));
481  } else if (node.fFunctionTag == FUN_ACOSH) {
482  return acosh(EvalNode(node.children[0]));
483  } else if (node.fFunctionTag == FUN_ASINH) {
484  return asinh(EvalNode(node.children[0]));
485  } else if (node.fFunctionTag == FUN_ATANH) {
486  return atanh(EvalNode(node.children[0]));
487  } else if (node.fFunctionTag == FUN_LOG) {
488  return log(fabs(EvalNode(node.children[0])))/log(10.0);
489  } else if (node.fFunctionTag == FUN_LN) {
490  return log(fabs(EvalNode(node.children[0])));
491  } else if (node.fFunctionTag == FUN_EXP) {
492  return exp(EvalNode(node.children[0]));
493  } else if (node.fFunctionTag == FUN_SQRT) {
494  return sqrt(fabs(EvalNode(node.children[0])));
495  } else {
496  std::cerr << std::endl << "**PANIC ERROR**: PFunction::EvalNode: node.fID == PFunctionGrammar::functionID: you never should have reached this point!";
497  std::cerr << std::endl;
498  assert(0);
499  }
500  } else if (node.fID == PFunctionGrammar::powerID) {
501  if (node.fFunctionTag == FUN_POW) {
502  Double_t base = EvalNode(node.children[0]);
503  Double_t expo = EvalNode(node.children[1]);
504  // check that no complex number will result
505  if (base < 0.0) { // base is negative which might be fatal
506  if (expo-floor(expo) != 0.0) // exponent is not an integer number, hence take -base (positive) to avoid complex numbers, i.e. nan
507  base = -base;
508  }
509  return pow(base, expo);
510  } else {
511  std::cerr << std::endl << "**PANIC ERROR**: PFunction::EvalNode: node.fID == PFunctionGrammar::powerID: you never should have reached this point!";
512  std::cerr << std::endl;
513  assert(0);
514  }
515  } else if (node.fID == PFunctionGrammar::factorID) {
516  return EvalNode(node.children[0]);
517  } else if (node.fID == PFunctionGrammar::termID) {
518  if (node.fOperatorTag == OP_MUL) {
519  return EvalNode(node.children[0]) * EvalNode(node.children[1]);
520  } else {
521  Double_t denominator = EvalNode(node.children[1]);
522  if (denominator == 0.0) {
523  std::cerr << std::endl << "**PANIC ERROR**: PFunction::EvalNode: division by 0.0";
524  std::cerr << std::endl << "**PANIC ERROR**: PFunction::EvalNode: requested operation: " << EvalNode(node.children[0]) << "/" << EvalNode(node.children[1]);
525  std::cerr << std::endl << ">> " << fFuncString.Data() << std::endl;
526  std::cerr << std::endl;
527  assert(0);
528  }
529  return EvalNode(node.children[0]) / denominator;
530  }
531  } else if (node.fID == PFunctionGrammar::expressionID) {
532  if (node.fOperatorTag == OP_ADD) {
533  return EvalNode(node.children[0]) + EvalNode(node.children[1]);
534  } else {
535  return EvalNode(node.children[0]) - EvalNode(node.children[1]);
536  }
537  } else {
538  std::cerr << std::endl << "**PANIC ERROR**: PFunction::EvalNode: you never should have reached this point!";
539  std::cerr << std::endl;
540  assert(0);
541  }
542  return 0.0;
543 }
544 
545 //-------------------------------------------------------------
546 // CleanupFuncEvalTree (protected)
547 //-------------------------------------------------------------
552 {
553  // clean up all children
555 }
556 
557 //-------------------------------------------------------------
558 // CleanupNode (protected)
559 //-------------------------------------------------------------
566 {
567  if (node.children.size() != 0) {
568  for (UInt_t i=0; i<node.children.size(); i++) {
569  CleanupNode(node.children[i]);
570  }
571  node.children.clear();
572  }
573 }
574 
575 //-------------------------------------------------------------
576 // EvalTreeForString (private)
577 //-------------------------------------------------------------
583 void PFunction::EvalTreeForString(tree_parse_info<> info)
584 {
585  fFuncString = "";
586  EvalTreeForStringExpression(info.trees.begin());
587 }
588 
589 //-------------------------------------------------------------
590 // EvalTreeForStringExpression (private)
591 //-------------------------------------------------------------
598 {
599  static Int_t termOp = 0;
600 
601  if (i->value.id() == PFunctionGrammar::realID) {
602  assert(i->children.size() == 0);
603  if (*i->value.begin() == '-')
604  fFuncString += "(";
605  fFuncString += boost::algorithm::trim_copy(std::string(i->value.begin(), i->value.end())).c_str();
606  if (*i->value.begin() == '-')
607  fFuncString += ")";
608  } else if (i->value.id() == PFunctionGrammar::constPiID) {
609  fFuncString += "Pi";
610  } else if (i->value.id() == PFunctionGrammar::constGammaMuID) {
611  fFuncString += "gamma_mu";
612  } else if (i->value.id() == PFunctionGrammar::constFieldID) {
613  fFuncString += "B";
614  } else if (i->value.id() == PFunctionGrammar::constEnergyID) {
615  fFuncString += "EN";
616  } else if (i->value.id() == PFunctionGrammar::constTempID) {
617  assert(i->children.size() == 0);
618  fFuncString += boost::algorithm::trim_copy(std::string(i->value.begin(), i->value.end())).c_str();
619  } else if (i->value.id() == PFunctionGrammar::funLabelID) {
620  assert(i->children.size() == 0);
621  //SetFuncNo(i);
622  fFuncString += std::string(i->value.begin(), i->value.end()).c_str(); // funx
623  } else if (i->value.id() == PFunctionGrammar::parameterID) {
624  assert(i->children.size() == 0);
625  fFuncString += boost::algorithm::trim_copy(std::string(i->value.begin(), i->value.end())).c_str();
626  } else if (i->value.id() == PFunctionGrammar::mapID) {
627  assert(i->children.size() == 0);
628  fFuncString += boost::algorithm::trim_copy(std::string(i->value.begin(), i->value.end())).c_str();
629  } else if (i->value.id() == PFunctionGrammar::functionID) {
630  assert(i->children.size() == 3);
631  fFuncString += std::string(i->value.begin(), i->value.end()).c_str(); // keep function name
632  fFuncString += "(";
633  // '(', expression, ')'
634  EvalTreeForStringExpression(i->children.begin()+1); // the real stuff
635  fFuncString += ")";
636  } else if (i->value.id() == PFunctionGrammar::powerID) {
637  assert(i->children.size() == 5);
638  fFuncString += std::string(i->value.begin(), i->value.end()).c_str(); // keep function name
639  fFuncString += "(";
640  // '(', expression, ',' expression, ')'
641  EvalTreeForStringExpression(i->children.begin()+1); // base expression
642  fFuncString += ",";
643  EvalTreeForStringExpression(i->children.begin()+3); // exponent expression
644  fFuncString += ")";
645  } else if (i->value.id() == PFunctionGrammar::factorID) {
646  EvalTreeForStringExpression(i->children.begin());
647  } else if (i->value.id() == PFunctionGrammar::termID) {
648  termOp++;
649  if (*i->value.begin() == '*') {
650  assert(i->children.size() == 2);
651  EvalTreeForStringExpression(i->children.begin());
652  fFuncString += " * ";
653  EvalTreeForStringExpression(i->children.begin()+1);
654  } else if (*i->value.begin() == '/') {
655  assert(i->children.size() == 2);
656  EvalTreeForStringExpression(i->children.begin());
657  fFuncString += " / ";
658  EvalTreeForStringExpression(i->children.begin()+1);
659  } else {
660  assert(0);
661  }
662  termOp--;
663  } else if (i->value.id() == PFunctionGrammar::expressionID) {
664  if (termOp > 0)
665  fFuncString += "(";
666  if (*i->value.begin() == '+') {
667  assert(i->children.size() == 2);
668  EvalTreeForStringExpression(i->children.begin());
669  fFuncString += " + ";
670  EvalTreeForStringExpression(i->children.begin()+1);
671  } else if (*i->value.begin() == '-') {
672  assert(i->children.size() == 2);
673  EvalTreeForStringExpression(i->children.begin());
674  fFuncString += " - ";
675  EvalTreeForStringExpression(i->children.begin()+1);
676  } else {
677  assert(0);
678  }
679  if (termOp > 0)
680  fFuncString += ")";
681  } else if (i->value.id() == PFunctionGrammar::assignmentID) {
682  assert(i->children.size() == 3);
683  EvalTreeForStringExpression(i->children.begin());
684  EvalTreeForStringExpression(i->children.begin()+1); // this is the string "="
685  EvalTreeForStringExpression(i->children.begin()+2); // this is the real stuff
686  } else if (*i->value.begin() == '=') {
687  fFuncString += " = ";
688  } else {
689  assert(0);
690  }
691 }
static const int constFieldID
#define FUN_COSH
Definition: PFunction.h:59
Bool_t fValid
flag showing if the function is valid
Definition: PFunction.h:122
static const int funLabelID
virtual void CleanupNode(PFuncTreeNode &node)
Definition: PFunction.cpp:565
virtual void FillFuncEvalTree(iter_t const &i, PFuncTreeNode &node)
Definition: PFunction.cpp:168
static const int assignmentID
static const int realID
#define FUN_ACOSH
Definition: PFunction.h:65
#define FUN_SQRT
Definition: PFunction.h:71
virtual Double_t Eval(std::vector< Double_t > param, PMetaData metaData)
Definition: PFunction.cpp:410
static const int constPiID
#define FUN_SIN
Definition: PFunction.h:57
#define FUN_SINH
Definition: PFunction.h:60
static const int mapID
Int_t fOperatorTag
tag for &#39;+&#39;, &#39;-&#39;, &#39;*&#39;, &#39;/&#39;
Definition: PFunction.h:80
static const int constTempID
PDoubleVector fTemp
temperature(s) in (K)
Definition: PMusr.h:229
#define FUN_ACOS
Definition: PFunction.h:62
static const int expressionID
#define OP_MUL
Definition: PFunction.h:53
static const int termID
#define FUN_ASIN
Definition: PFunction.h:63
PFuncTreeNode fFunc
Definition: PFunction.h:120
#define FUN_POW
Definition: PFunction.h:72
virtual Bool_t FindAndCheckMapAndParamRange(PFuncTreeNode &node, UInt_t mapSize, UInt_t paramSize)
Definition: PFunction.cpp:348
virtual Bool_t GenerateFuncEvalTree()
Definition: PFunction.cpp:151
Double_t fDvalue
for numbers
Definition: PFunction.h:84
#define FUN_COS
Definition: PFunction.h:56
#define FUN_ATANH
Definition: PFunction.h:67
virtual ~PFunction()
Definition: PFunction.cpp:85
parse_tree_match_t::tree_iterator iter_t
virtual void InitNode(PFuncTreeNode &node)
Definition: PFunction.cpp:101
#define FUN_TAN
Definition: PFunction.h:58
virtual void EvalTreeForString(tree_parse_info<> info)
Definition: PFunction.cpp:583
static const int powerID
#define PMUSR_UNDEFINED
Definition: PMusr.h:89
std::vector< Double_t > fParam
parameter vector (from the msr-file Fit Parameter block)
Definition: PFunction.h:118
Double_t fEnergy
energy in (keV)
Definition: PMusr.h:228
#define FUN_ASINH
Definition: PFunction.h:66
Int_t fFuncNo
function number, i.e. FUNx with x the function number
Definition: PFunction.h:123
virtual Double_t EvalNode(PFuncTreeNode &node)
Definition: PFunction.cpp:426
std::vector< Int_t > fMap
map vector
Definition: PFunction.h:119
virtual void CleanupFuncEvalTree()
Definition: PFunction.cpp:551
#define OP_SUB
Definition: PFunction.h:52
Bool_t fSign
for sign, true means &#39;-&#39;, false &#39;+&#39;
Definition: PFunction.h:83
Int_t fFunctionTag
tag got "cos", "sin", ...
Definition: PFunction.h:81
#define FUN_ATAN
Definition: PFunction.h:64
#define FUN_EXP
Definition: PFunction.h:70
#define OP_ADD
Definition: PFunction.h:51
PMetaData fMetaData
keeps meta data from data files (field, energy, temperature, ...)
Definition: PFunction.h:129
static const int functionID
static const int factorID
virtual Bool_t CheckMapAndParamRange(UInt_t mapSize, UInt_t paramSize)
Definition: PFunction.cpp:333
Int_t fID
tag showing what tree element this is
Definition: PFunction.h:79
virtual Bool_t SetFuncNo()
Definition: PFunction.cpp:119
Int_t fIvalue
for parameter numbers and maps
Definition: PFunction.h:82
return status
std::vector< func_tree_node > children
holding sub-tree
Definition: PFunction.h:85
PFunction(tree_parse_info<> info)
Definition: PFunction.cpp:62
virtual void EvalTreeForStringExpression(iter_t const &i)
Definition: PFunction.cpp:597
#define FUN_LOG
Definition: PFunction.h:68
static const int constGammaMuID
TString fFuncString
clear text representation of the function
Definition: PFunction.h:127
#define FUN_TANH
Definition: PFunction.h:61
static const int constEnergyID
tree_parse_info fInfo
AST parse tree holding a single parsed msr-function in an ascii representation.
Definition: PFunction.h:117
#define FUN_LN
Definition: PFunction.h:69
#define GAMMA_BAR_MUON
Definition: PMusr.h:78
static const int parameterID
#define OP_DIV
Definition: PFunction.h:54
Double_t fField
field in (G)
Definition: PMusr.h:227