CMS 3D CMS Logo

TrackerDetIdSelector.h
Go to the documentation of this file.
1 #ifndef FastSimulation_TrackingRecHitProducer_TrackerDetIdSelector_H
2 #define FastSimulation_TrackingRecHitProducer_TrackerDetIdSelector_H
3 
7 
8 
9 #include <boost/config/warning_disable.hpp>
10 #include <boost/spirit/include/qi.hpp>
11 #include <boost/spirit/include/qi_rule.hpp>
12 #include <boost/lambda/lambda.hpp>
13 #include <boost/spirit/include/phoenix.hpp>
14 #include <boost/phoenix/bind/bind_member_function.hpp>
15 #include <boost/spirit/include/qi_grammar.hpp>
16 
17 #include <iostream>
18 #include <cstdlib>
19 #include <typeinfo>
20 #include <functional>
21 #include <unordered_map>
22 
23 struct BinaryOP;
24 struct UnaryOP;
25 struct Nil {};
26 
28 {
29 
30  typedef
31  boost::variant<
32  Nil,
33  int,
35  boost::recursive_wrapper<ExpressionAST>,
36  boost::recursive_wrapper<BinaryOP>,
37  boost::recursive_wrapper<UnaryOP>
38  >
40 
42  expr(Nil())
43  {
44  }
45 
46  template <typename Expr>
47  ExpressionAST(Expr const& expr):
48  expr(expr)
49  {
50  }
51 
52  int evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const;
53 
54  ExpressionAST& operator!();
55 
57 };
58 
59 ExpressionAST operator>(ExpressionAST const& lhs, ExpressionAST const& rhs);
60 ExpressionAST operator>=(ExpressionAST const& lhs, ExpressionAST const& rhs);
61 ExpressionAST operator==(ExpressionAST const& lhs, ExpressionAST const& rhs);
62 ExpressionAST operator<=(ExpressionAST const& lhs, ExpressionAST const& rhs);
63 ExpressionAST operator<(ExpressionAST const& lhs, ExpressionAST const& rhs);
64 ExpressionAST operator!=(ExpressionAST const& lhs, ExpressionAST const& rhs);
65 ExpressionAST operator&&(ExpressionAST const& lhs, ExpressionAST const& rhs);
66 ExpressionAST operator||(ExpressionAST const& lhs, ExpressionAST const& rhs);
67 
68 struct BinaryOP
69 {
70  enum class OP
71  {
72  GREATER, GREATER_EQUAL, EQUAL, LESS_EQUAL, LESS, NOT_EQUAL, AND, OR
73  } op;
76 
77  BinaryOP(OP op, ExpressionAST const& left, ExpressionAST const& right):
78  op(op),
79  left(left),
80  right(right)
81  {
82  }
83 
84  int evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const
85  {
86  switch(op)
87  {
88  case OP::GREATER:
89  return left.evaluate(detId,trackerTopology) > right.evaluate(detId,trackerTopology);
90  case OP::GREATER_EQUAL:
91  return left.evaluate(detId,trackerTopology) >= right.evaluate(detId,trackerTopology);
92  case OP::EQUAL:
93  return left.evaluate(detId,trackerTopology) == right.evaluate(detId,trackerTopology);
94  case OP::LESS_EQUAL:
95  return left.evaluate(detId,trackerTopology) <= right.evaluate(detId,trackerTopology);
96  case OP::LESS:
97  return left.evaluate(detId,trackerTopology) < right.evaluate(detId,trackerTopology);
98  case OP::NOT_EQUAL:
99  return left.evaluate(detId,trackerTopology) != right.evaluate(detId,trackerTopology);
100  case OP::AND:
101  return left.evaluate(detId,trackerTopology) && right.evaluate(detId,trackerTopology);
102  case OP::OR:
103  return left.evaluate(detId,trackerTopology) || right.evaluate(detId,trackerTopology);
104  }
105  return 0;
106  }
107 };
108 
109 struct UnaryOP
110 {
111  enum class OP
112  {
113  NEG
114  } op;
116  UnaryOP(OP op, ExpressionAST const& subject):
117  op(op),
118  subject(subject)
119  {
120  }
121 
122  int evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const
123  {
124  switch (op)
125  {
126  case OP::NEG:
127  return !subject.evaluate(detId,trackerTopology);
128  }
129  return 0;
130  }
131 
132 };
133 
135 {
136  private:
137  const DetId& _detId;
139 
140  public:
141  typedef std::function<int(const TrackerTopology& trackerTopology, const DetId&)> DetIdFunction;
142  typedef std::unordered_map<std::string, DetIdFunction> StringFunctionMap;
143  const static StringFunctionMap functionTable;
144 
145  TrackerDetIdSelector(const DetId& detId, const TrackerTopology& trackerTopology):
146  _detId(detId),
147  _trackerTopology(trackerTopology)
148  {
149  }
150 
151  bool passSelection(std::string selectionStr) const;
152 };
153 
154 class Accessor:
155  public boost::static_visitor<int>
156 {
157  private:
158  const DetId& _detId;
160  public:
161  Accessor(const DetId& detId, const TrackerTopology& trackerTopology):
162  _detId(detId),
163  _trackerTopology(trackerTopology)
164  {
165  }
166 
167  int operator()(Nil i) const
168  {
169  throw cms::Exception("FastSimulation/TrackingRecHitProducer/TrackerDetIdSelector","while evaluating a DetId selection a symbol was not set");
170  }
171  int operator()(const int& i) const
172  {
173  return i;
174  }
175  int operator()(const std::string& s) const
176  {
177  TrackerDetIdSelector::StringFunctionMap::const_iterator it = TrackerDetIdSelector::functionTable.find(s);
178  int value = 0;
179  if (it != TrackerDetIdSelector::functionTable.cend())
180  {
181  value = (it->second)(_trackerTopology,_detId);
182  //std::cout<<"attr="<<s<<", value="<<value<<std::endl;
183  }
184  else
185  {
186  //std::cout<<"attr="<<s<<" unknown"<<std::endl;
187  std::string msg = "error while parsing DetId selection: named identifier '"+s+"' not known. Possible values are: ";
189  {
190  msg+=pair.first+",";
191  }
192  throw cms::Exception("FastSimulation/TrackingRecHitProducer/TrackerDetIdSelector",msg);
193  }
194  return value;
195  }
196  int operator()(const ExpressionAST& ast) const
197  {
198  return ast.evaluate(_detId,_trackerTopology);
199  }
200  int operator()(const BinaryOP& binaryOP) const
201  {
202  return binaryOP.evaluate(_detId,_trackerTopology);
203  }
204  int operator()(const UnaryOP& unaryOP) const
205  {
206  return unaryOP.evaluate(_detId,_trackerTopology);
207  }
208 };
209 
210 
211 
212 
213 
214 struct WalkAST
215 {
217 
218  WalkAST(const DetId& detId, const TrackerTopology& trackerTopology):
219  _acc(detId,trackerTopology)
220  {
221  }
222 
223  typedef void result_type;
224 
225  void operator()() const {}
226  void operator()(int n) const { std::cout << n; std::cout<<" ["<<_acc(n)<<"] "; }
227  void operator()(std::string str) const { std::cout << str; std::cout<<" ["<<_acc(str)<<"] "; }
228  void operator()(ExpressionAST const& ast) const
229  {
230  boost::apply_visitor(*this, ast.expr);
231  std::cout<<" [="<<_acc(ast)<<"] ";
232  }
233 
234  void operator()(BinaryOP const& expr) const
235  {
236  std::cout << "(";
237  boost::apply_visitor(*this, expr.left.expr);
238  switch(expr.op)
239  {
241  std::cout<<" > ";
242  break;
244  std::cout<<" >= ";
245  break;
246  case BinaryOP::OP::EQUAL:
247  std::cout<<" == ";
248  break;
250  std::cout<<" <= ";
251  break;
252  case BinaryOP::OP::LESS:
253  std::cout<<" < ";
254  break;
256  std::cout<<" != ";
257  break;
258  case BinaryOP::OP::AND:
259  std::cout<<" && ";
260  break;
261  case BinaryOP::OP::OR:
262  std::cout<<" || ";
263  break;
264  }
265  boost::apply_visitor(*this, expr.right.expr);
266  std::cout << ')';
267  }
268 
269  void operator()(UnaryOP const& expr) const
270  {
271  switch (expr.op)
272  {
273  case UnaryOP::OP::NEG:
274  std::cout<<" !(";
275  break;
276  }
277  boost::apply_visitor(*this, expr.subject.expr);
278  std::cout << ')';
279  }
280 };
281 
282 template <typename ITERATOR>
284  boost::spirit::qi::grammar<
285  ITERATOR,
286  ExpressionAST(),
287  boost::spirit::ascii::space_type,
288  boost::spirit::qi::locals<ExpressionAST>
289  >
290 {
291  boost::spirit::qi::rule<
292  ITERATOR,
293  std::string(),
294  boost::spirit::ascii::space_type
296 
297  boost::spirit::qi::rule<
298  ITERATOR,
299  ExpressionAST(),
300  boost::spirit::ascii::space_type
301  > identifierRule, expressionRule;
302 
303  boost::spirit::qi::rule<
304  ITERATOR,
305  ExpressionAST(),
306  boost::spirit::ascii::space_type,
307  boost::spirit::qi::locals<ExpressionAST>
309 
310 
312  TrackerDetIdSelectorGrammar::base_type(comboRule)
313  {
314  namespace qi = boost::spirit::qi;
315  namespace ascii = boost::spirit::ascii;
316  namespace phoenix = boost::phoenix;
317 
318  identifierFctRule =
319  qi::lexeme[+qi::alpha[qi::_val+=qi::_1]];
320 
321  identifierRule =
322  (qi::true_[qi::_val=1] | qi::false_[qi::_val=0]) |
323  (qi::int_[qi::_val=qi::_1]) |
324  identifierFctRule[qi::_val=qi::_1];
325 
326  comboRule =
327  (expressionRule[qi::_a=qi::_1] >>
328  *(
329  (qi::lit("&&") >> expressionRule[qi::_a=qi::_a && qi::_1]) |
330  (qi::lit("||") >> expressionRule[qi::_a=qi::_a || qi::_1])
331  ))[qi::_val=qi::_a];
332 
333  expressionRule =
334  qi::lit("(") >> comboRule[qi::_val=qi::_1] >> qi::lit(")") |
335  (identifierRule >> qi::lit(">") >> identifierRule)[qi::_val=qi::_1>qi::_2] |
336  (identifierRule >> qi::lit(">=") >> identifierRule)[qi::_val=qi::_1>=qi::_2] |
337  (identifierRule >> qi::lit("<") >> identifierRule)[qi::_val=qi::_1<qi::_2] |
338  (identifierRule >> qi::lit("<=") >> identifierRule)[qi::_val=qi::_1<=qi::_2] |
339  (identifierRule >> qi::lit("==") >> identifierRule)[qi::_val=qi::_1==qi::_2] |
340  (identifierRule >> qi::lit("!=") >> identifierRule)[qi::_val=qi::_1!=qi::_2] |
341  identifierRule[qi::_val=qi::_1];
342  }
343 
344 };
345 
346 
348 {
349  std::string::const_iterator begin = selectionStr.cbegin();
350  std::string::const_iterator end = selectionStr.cend();
351 
352 
354  ExpressionAST exprAST;
355 
356  bool success = boost::spirit::qi::phrase_parse(begin,end, grammar, boost::spirit::ascii::space, exprAST);
357  if (begin!=end)
358  {
359  throw cms::Exception("FastSimulation/TrackingRecHitProducer/TrackerDetIdSelector",
360  "parsing selection '"+selectionStr+"' failed at "+std::string(selectionStr.cbegin(), begin)+"^^^"+std::string(begin, end));
361  }
362  if (!success)
363  {
364  throw cms::Exception("FastSimulation/TrackingRecHitProducer/TrackerDetIdSelector","parsing selection '"+selectionStr+"' failed.");
365  }
366  /* Comment out for debugging
367  WalkAST walker(_detId,_trackerTopology);
368  walker(exprAST);
369  std::cout<<std::endl;
370  */
371  return exprAST.evaluate(_detId,_trackerTopology);
372 
373 }
374 
375 
376 
377 int ExpressionAST::evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const
378 {
379  return boost::apply_visitor(Accessor(detId,trackerTopology),this->expr);
380 }
381 
382 #endif
ExpressionAST operator!=(ExpressionAST const &lhs, ExpressionAST const &rhs)
float alpha
Definition: AMPTWrapper.h:95
ExpressionAST left
WalkAST(const DetId &detId, const TrackerTopology &trackerTopology)
ExpressionAST right
void operator()(UnaryOP const &expr) const
ExpressionAST operator<(ExpressionAST const &lhs, ExpressionAST const &rhs)
int operator()(const UnaryOP &unaryOP) const
ExpressionAST operator>=(ExpressionAST const &lhs, ExpressionAST const &rhs)
void operator()(std::string str) const
enum UnaryOP::OP op
void operator()(BinaryOP const &expr) const
Accessor(const DetId &detId, const TrackerTopology &trackerTopology)
int operator()(const int &i) const
static const StringFunctionMap functionTable
void operator()(ExpressionAST const &ast) const
const DetId & _detId
ExpressionAST operator||(ExpressionAST const &lhs, ExpressionAST const &rhs)
boost::spirit::qi::rule< ITERATOR, ExpressionAST(), boost::spirit::ascii::space_type, boost::spirit::qi::locals< ExpressionAST > > comboRule
int operator()(const BinaryOP &binaryOP) const
void operator()() const
ExpressionAST operator<=(ExpressionAST const &lhs, ExpressionAST const &rhs)
const TrackerTopology & _trackerTopology
bool passSelection(std::string selectionStr) const
boost::spirit::qi::rule< ITERATOR, ExpressionAST(), boost::spirit::ascii::space_type > identifierRule
int operator()(const ExpressionAST &ast) const
std::unordered_map< std::string, DetIdFunction > StringFunctionMap
int evaluate(const DetId &detId, const TrackerTopology &trackerTopology) const
ExpressionAST operator&&(ExpressionAST const &lhs, ExpressionAST const &rhs)
int evaluate(const DetId &detId, const TrackerTopology &trackerTopology) const
std::function< int(const TrackerTopology &trackerTopology, const DetId &)> DetIdFunction
#define end
Definition: vmac.h:39
Definition: value.py:1
int operator()(Nil i) const
boost::spirit::qi::rule< ITERATOR, std::string(), boost::spirit::ascii::space_type > identifierFctRule
ExpressionAST operator==(ExpressionAST const &lhs, ExpressionAST const &rhs)
Definition: DetId.h:18
ExpressionAST subject
ExpressionAST operator>(ExpressionAST const &lhs, ExpressionAST const &rhs)
tuple msg
Definition: mps_check.py:277
ExpressionAST(Expr const &expr)
bool AND(const TrackBaseRef &track, const RecoTauQualityCuts::TrackQCutFuncCollection &cuts)
#define begin
Definition: vmac.h:32
boost::variant< Nil, int, std::string, boost::recursive_wrapper< ExpressionAST >, boost::recursive_wrapper< BinaryOP >, boost::recursive_wrapper< UnaryOP > > Type
void operator()(int n) const
const TrackerTopology & _trackerTopology
TrackerDetIdSelector(const DetId &detId, const TrackerTopology &trackerTopology)
BinaryOP(OP op, ExpressionAST const &left, ExpressionAST const &right)
#define str(s)
int evaluate(const DetId &detId, const TrackerTopology &trackerTopology) const
enum BinaryOP::OP op
int operator()(const std::string &s) const
UnaryOP(OP op, ExpressionAST const &subject)