musrfit 1.10.0
PFunctionHandler.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 PFunctionHandler.cpp
4
5 Author: Andreas Suter
6 e-mail: andreas.suter@psi.ch
7
8***************************************************************************/
9
10/***************************************************************************
11 * Copyright (C) 2007-2026 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 <string>
31#include <cassert>
32
33#include <boost/spirit/home/x3.hpp>
34
35#include "PFunctionHandler.h"
36
37namespace x3 = boost::spirit::x3;
38
39//-------------------------------------------------------------
40// Constructor
41//-------------------------------------------------------------
48{
49 fValid = true;
50}
51
52//-------------------------------------------------------------
53// Destructor
54//-------------------------------------------------------------
59{
60 fLines.clear();
61 fFuncs.clear();
62 fFuncComment.clear();
63}
64
65//-------------------------------------------------------------
66// DoParse (public)
67//-------------------------------------------------------------
72{
73 Bool_t success = true;
74 TString line;
75
76 // feed the function block into the parser. Start with i=1, since i=0 is FUNCTIONS
77 for (UInt_t i=1; i<fLines.size(); i++) {
78
79 // function line to upper case after cutting out prepended comment
80 line = fLines[i].fLine;
81 Ssiz_t pos = line.First('#'); // find prepended comment
82 TString Comment("");
83 if (pos != kNPOS) { // comment present
84 for (Int_t i=pos; i<line.Length(); i++) {
85 Comment += line[i];
86 }
87 }
88 fFuncComment.push_back(Comment);
89 if (pos != kNPOS) { // comment present, hence remove it from the string to be parsed
90 line.Remove(pos);
91 line.Remove(TString::kTrailing, ' ');
92 }
93 line.ToUpper();
94
95 // do parsing with X3
96 musrfit::ast::assignment assignment;
97 std::string str(line.Data());
98 auto iter = str.begin();
99 auto end = str.end();
100
101 // Get the X3 grammar
102 auto const& grammar = musrfit::function_grammar();
103
104 try {
105 bool parseSuccess = x3::phrase_parse(iter, end, grammar, x3::space, assignment);
106
107 if (parseSuccess && iter == end) { // parsing successful
108 PFunction func(assignment); // generate an evaluation function object based on the AST
109 fFuncs.push_back(func); // feeds it to the functions vector
110 } else {
111 std::cerr << std::endl << "**ERROR**: FUNCTIONS parse failed in line " << fLines[i].fLineNo << std::endl;
112 if (iter != end) {
113 std::cerr << "**ERROR**: Stopped at: " << std::string(iter, end) << std::endl;
114 }
115 success = false;
116 break;
117 }
118 } catch (x3::expectation_failure<std::string::iterator> const& e) {
119 std::cerr << std::endl << "**ERROR**: FUNCTIONS parse failed in line " << fLines[i].fLineNo << std::endl;
120 std::cerr << "**ERROR**: Expected: " << e.which() << std::endl;
121 success = false;
122 break;
123 }
124 }
125
126 // check that the function numbers are unique
127 if (success) {
128 for (UInt_t i=0; i<fFuncs.size(); i++) {
129 for (UInt_t j=i+1; j<fFuncs.size(); j++) {
130 if (fFuncs[i].GetFuncNo() == fFuncs[j].GetFuncNo()) {
131 std::cerr << std::endl << "**ERROR**: function number " << fFuncs[i].GetFuncNo();
132 std::cerr << " is at least twice present! Fix this first.";
133 std::cerr << std::endl;
134 success = false;
135 }
136 }
137 }
138 }
139
140 return success;
141}
142
143//-------------------------------------------------------------
144// CheckMapAndParamRange (public)
145//-------------------------------------------------------------
154Bool_t PFunctionHandler::CheckMapAndParamRange(UInt_t mapSize, UInt_t paramSize)
155{
156 Bool_t success = true;
157
158 for (UInt_t i=0; i<fFuncs.size(); i++) {
159 success = fFuncs[i].CheckMapAndParamRange(mapSize, paramSize);
160 if (!success)
161 break;
162 }
163
164 return success;
165}
166
167//-------------------------------------------------------------
168// Eval (public)
169//-------------------------------------------------------------
179Double_t PFunctionHandler::Eval(Int_t funNo, std::vector<Int_t> map, std::vector<double> param, PMetaData metaData)
180{
181 if (GetFuncIndex(funNo) == -1) {
182 std::cerr << std::endl << "**ERROR**: Couldn't find FUN" << funNo << " for evaluation";
183 std::cerr << std::endl;
184 return 0.0;
185 }
186
187 // set correct map
188 fFuncs[GetFuncIndex(funNo)].SetMap(map);
189
190 // return evaluated function
191 return fFuncs[GetFuncIndex(funNo)].Eval(param, metaData);
192}
193
194//-------------------------------------------------------------
195// GetFuncNo (public)
196//-------------------------------------------------------------
203{
204 if (idx > fFuncs.size())
205 return -1;
206
207 return fFuncs[idx].GetFuncNo();
208}
209
210//-------------------------------------------------------------
211// GetFuncIndex (public)
212//-------------------------------------------------------------
219{
220 Int_t index = -1;
221
222 for (UInt_t i=0; i<fFuncs.size(); i++) {
223 if (fFuncs[i].GetFuncNo() == funcNo) {
224 index = i;
225 break;
226 }
227 }
228
229 return index;
230}
231
232//-------------------------------------------------------------
233// GetFuncString (public)
234//-------------------------------------------------------------
241{
242 TString funStr("");
243
244 if ((idx > fFuncs.size()) || (idx > fFuncComment.size()))
245 return funStr;
246
247 if (fFuncComment[idx].Length() > 0)
248 funStr = *fFuncs[idx].GetFuncString() + " " + fFuncComment[idx];
249 else
250 funStr = *fFuncs[idx].GetFuncString();
251
252 return funStr;
253}
std::vector< PMsrLineStructure > PMsrLines
Definition PMusr.h:989
std::vector< TString > fFuncComment
vector of prepended function comments
PFunctionHandler(PMsrLines lines)
std::vector< PFunction > fFuncs
vector of all evaluatable functions
virtual Bool_t DoParse()
Bool_t fValid
true = function handler has valid functions
virtual Bool_t CheckMapAndParamRange(UInt_t mapSize, UInt_t paramSize)
virtual double Eval(Int_t funNo, std::vector< Int_t > map, std::vector< double > param, PMetaData metaData)
PMsrLines fLines
stores the msr-file FUNCTIONS block as clear text.
virtual Int_t GetFuncIndex(Int_t funcNo)
virtual TString GetFuncString(UInt_t idx)
virtual Int_t GetFuncNo(UInt_t idx)
Class for parsing and evaluating mathematical functions from msr-file FUNCTIONS blocks.
Definition PFunction.h:69
auto const & function_grammar()
Provides access to the top-level grammar rule.