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