ATLAS Offline Software
Loading...
Searching...
No Matches
Trigger/TrigConfiguration/TrigConfL1Data/Root/HelperFunctions.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6#include <iostream>
7#include <sstream>
8#include <cassert>
9#include <cstdlib>
10
15
16#include "boost/algorithm/string.hpp"
17#include <algorithm>
18#include <boost/algorithm/string/trim.hpp>
19using namespace std;
20using namespace TrigConf;
21
22
23
24std::vector<std::string>
25TrigConf::split(const std::string& line, const std::string& del) {
26 std::vector<std::string> res;
27 boost::split(res, line, boost::is_any_of(del));
28 return res;
29}
30
31// helper method: removing all spaces at beginning and end of a string
32void
33TrigConf::strip(std::string& str) {
34 boost::algorithm::trim(str);
35}
36
37// helper method: replace tabs by single space
38void TrigConf::replaceTabs(std::string& str) {
39 std::replace(str.begin(), str.end(), '\t', ' ');
40}
41
42
43// helper function: all chars to lower chars
44void
45TrigConf::toLower(std::string& s) {
46 for(size_t i=0; i<s.size(); i++) s[i] += (s[i]>='A'&&s[i]<='Z')?'a'-'A':0;
47}
48
49
50
51namespace {
52
54 parseToken(const std::string& givenlogic,
55 std::string::size_type& pos,
56 const std::vector<std::string>& conditions,
57 const std::vector<TrigConf::TriggerThreshold*>& thrs);
58
59
61 parseExpr(const std::string& expr,
62 const std::vector<std::string>& conditions,
63 const std::vector<TrigConf::TriggerThreshold*>& thrs)
64 {
65
66
67 std::string::size_type pos = 0;
68 std::string::size_type last = expr.size();
69
70 TrigConf::TriggerItemNode * newNode = 0;
71
72 while(pos!=last) {
73
74 TrigConf::TriggerItemNode * nodeForToken = parseToken(expr, pos, conditions, thrs);
75
76 // deal with the end of the expression
77 if(pos == last) {
78 if(newNode==0)
79 return nodeForToken; // single token
80 newNode->addChild(nodeForToken);
81 return newNode;
82 }
83
84
85 // determine the &/| type from the next character
86 TriggerItemNode::NodeType typeFromChar;
87 if(expr[pos]=='&' || expr[pos]=='|') {
88 typeFromChar = TriggerItemNode::typeFromChar(expr[pos]);
89 } else {
90 throw std::logic_error(string("Unexpected character '") + expr[pos] + "' in expression '" + expr
91 + "' at position" + std::to_string(pos) + " [b]");
92 }
93
94
95 if(newNode==0) {
96 // create Node upon first encounter of & or |
97 newNode = new TriggerItemNode(typeFromChar);
98 } else {
99 // check that current character matches the type of the node
100 if(newNode->type() != typeFromChar) {
101 throw std::logic_error(string("Unexpected character '") + expr[pos] + "' in expression '" + expr
102 + "' at position" + std::to_string(pos) + " [c] Expected "
103 + TriggerItemNode::typeAsString(newNode->type()) );
104 }
105 }
106
107 newNode->addChild(nodeForToken);
108 pos++; // move beyond the &/|
109 }
110
111 return newNode;
112 }
113
114 std::string getSubExpr(const std::string &exp, const std::string::size_type begin) {
115 std::string::size_type pos = begin;
116 std::string::size_type last = exp.size();
117
118 uint32_t openBrackets = 0;
119 while(pos!=last) {
120 char cc = exp[pos];
121 if(cc=='(') openBrackets++;
122 if(cc==')') openBrackets--;
123 if(openBrackets==0 && (cc=='&' or cc=='|') ) break;
124 pos++;
125 }
126 if (openBrackets>0) {
127 std::cout << "ERROR: No matching closing bracket in '" << exp << "'" << std::endl;
128 assert(0);
129 }
130 std::string se(exp, begin, pos-begin);
131 // std::cout << "Subexp of '" << exp << "'[" << begin<<"] returns " << se << std::endl;
132 return se;
133 }
134
135
137 parseToken(const std::string& logic,
138 std::string::size_type& pos,
139 const std::vector<std::string>& conditions,
140 const std::vector<TrigConf::TriggerThreshold*>& thrs) {
141
142 // logic should be the definition of a node
143 //
144 // this means it needs to start with a number, '(', or '!'
145
146 //std::cout << "parse '" << givenlogic << "'" << std::endl;
147 //for(uint32_t i =0; i<conditions.size(); i++) std::cout << conditions[i] << std::endl;
148 //std::cout << thrs.size() << ")" << std::endl;
149
150
151 //std::string::size_type last = logic.size();
152
153 TriggerItemNode* thisNode(0);
154 // tokenize
155
156 // need three tokens to build a TriggerItemNode
157 char cur = logic[pos];
158 switch(cur) {
159 case '!':
160 {
161 pos++;
163 std::string se = getSubExpr(logic,pos);
164 thisNode->addChild( parse(se,conditions,thrs) );
165 pos += se.size();
166 break;
167 }
168 case '(':
169 {
170 std::string se = getSubExpr(logic,pos);
171 pos += se.size();
172 // should have outer parentheses (...)
173 std::string senop(se, 1, se.size()-2);
174 thisNode = parse(senop,conditions,thrs);
175 break;
176 }
177 case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
178 {
179 std::string se = getSubExpr(logic,pos);
180 pos += se.size();
181 uint32_t condIdx = static_cast<uint32_t>(std::stoul(se));
182 thisNode = buildObjNode(condIdx, conditions, thrs);
183 break;
184 }
185 default:
186 {
187 std::string errMsg = "Unexpected character '";
188 errMsg += logic[pos];
189 errMsg += "' in expression '" + logic + "' at position" + std::to_string(pos) + " [a]";
190 throw std::logic_error(errMsg);
191 }
192 break;
193 }
194
195
196 return thisNode;
197 }
198}
199
200
201
203TrigConf::buildObjNode(uint32_t condIdx,
204 const vector<string>& conditions,
205 const vector<TrigConf::TriggerThreshold*>& thrs) {
206
208
209 try {
210 vector<string> condDef = split(conditions[condIdx-1], ",");
211
212 if(condDef.size()==1) { // internal trigger (condDef contains internal trigger name)
213
214 newNode->setInternalTrigger( condDef[0] );
215
216 } else { // threshold (condDef contains multiplicity, condName, and threshold name)
217 // set multiplicity
218 newNode->setMultiplicity(std::stoi(condDef[0]));
219 // find trigger threshold in list of all thresholds and set it in the TriggerItemNode
220 std::string& name = condDef[2];
221 if(thrs.size()>0) {
222 std::vector<TrigConf::TriggerThreshold*>::const_iterator thrIt = thrs.begin();
223 for(;thrIt!=thrs.end(); ++thrIt ) {
224 if((*thrIt)->name()==name) {
225 newNode->setTriggerThreshold(*thrIt);
226 break;
227 }
228 }
229 } else {
230 newNode->setThresholdName(name);
231 }
232 }
233 }
234 catch(const std::exception& e) {
235 std::cout << "Exeption caught in buildObjNode for " << conditions[condIdx-1] << ": " << e.what() << std::endl;
236 throw;
237 }
238 return newNode;
239}
240
241
243TrigConf::parse(const std::string& givenlogic,
244 const std::vector<std::string>& conditions,
245 const std::vector<TrigConf::TriggerThreshold*>& thrs) {
246
247 // balance expression
248 std::string expr = insertParenthesis(givenlogic);
249
250 // parse
251 TriggerItemNode* topNode = parseExpr(expr, conditions, thrs);
252
253 // wrap in an AND
254 if( topNode->type() != TriggerItemNode::AND) {
256 newNode->addChild(topNode);
257 topNode = newNode;
258 }
259
260 return topNode;
261}
262
263
264
265
266
267
268// pos: position of the current opening bracket
269std::string::size_type
270TrigConf::findClosingBracket(std::string::size_type pos,
271 const std::string& logic) {
272
273 pos++;
274 uint32_t openBrackets = 1;
275 std::string::size_type last = logic.size();
276 while(openBrackets>0 && pos!=last) {
277 if(logic[pos]==')') openBrackets--;
278 if(logic[pos]=='(') openBrackets++;
279 pos++;
280 }
281 if (openBrackets>0) {
282 std::string errMsg = "No matching closing bracket in '";
283 errMsg += logic;
284 errMsg += "'";
285 throw std::logic_error(errMsg);
286 }
287 return pos-1;
288}
289
290std::string
291TrigConf::insertParenthesis(const std::string& givenlogic) {
292 std::string logicWithPars(givenlogic);
293 size_t last = givenlogic.size()-1;
294 bool leadingAnd(false);
295 for(size_t pos = 0;pos<last;pos++) {
296 char c = logicWithPars[pos];
297 if(c=='(') { pos=findClosingBracket(pos,givenlogic); continue; }
298 if(c=='&') leadingAnd=true;
299 if(c=='|') {
300 if(leadingAnd) {
301 logicWithPars.insert(pos,")");
302 logicWithPars.insert(0,"(");
303 }
304 break;
305 }
306 }
307 return logicWithPars;
308}
309
310
311
312uint32_t
313TrigConf::bin2uint(const std::string& binary) {
314 uint32_t value(0);
315 for(char c: binary) {
316 value <<= 1;
317 if(c=='1') value += 1;
318 }
319 return value;
320}
321
322
323std::string
324TrigConf::uint2bin(uint32_t value, uint16_t width) {
325 stringstream ss;
326 for(uint32_t mask = 1 << (width-1); mask>0; mask>>=1)
327 ss << ( (value & mask) == 0 ? '0' : '1' );
328
329 return ss.str();
330}
std::pair< std::vector< unsigned int >, bool > res
static Double_t ss
const double width
static NodeType typeFromChar(const char &c)
static std::string typeAsString(NodeType)
void setInternalTrigger(L1DataDef::TriggerType x, unsigned int thresholdNumber)
void addChild(TriggerItemNode *node)
void setTriggerThreshold(TriggerThreshold *thr)
void setThresholdName(const std::string &thrname)
Forward iterator to traverse the main components of the trigger configuration.
Definition Config.h:22
std::string uint2bin(uint32_t uinteger, uint16_t width)
std::string insertParenthesis(const std::string &givenlogic)
std::string::size_type findClosingBracket(std::string::size_type pos, const std::string &logic)
std::vector< std::string > split(const std::string &line, const std::string &del=" ")
TrigConf::TriggerItemNode * buildObjNode(uint32_t condIdx, const std::vector< std::string > &conditions, const std::vector< TrigConf::TriggerThreshold * > &thrs)
std::vector< std::string > parse(std::string names)
STL namespace.
setEventNumber uint32_t