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 #include <boost/config/warning_disable.hpp>
9 #include <boost/spirit/include/qi.hpp>
10 #include <boost/spirit/include/qi_rule.hpp>
11 #include <boost/lambda/lambda.hpp>
12 #include <boost/spirit/include/phoenix.hpp>
13 #include <boost/phoenix/bind/bind_member_function.hpp>
14 #include <boost/spirit/include/qi_grammar.hpp>
15 
16 #include <iostream>
17 #include <cstdlib>
18 #include <typeinfo>
19 #include <functional>
20 #include <unordered_map>
21 
22 struct BinaryOP;
23 struct UnaryOP;
24 struct Nil {};
25 
26 struct ExpressionAST {
27  typedef boost::variant<Nil,
28  int,
30  boost::recursive_wrapper<ExpressionAST>,
31  boost::recursive_wrapper<BinaryOP>,
32  boost::recursive_wrapper<UnaryOP> >
34 
35  ExpressionAST() : expr(Nil()) {}
36 
37  template <typename Expr>
38  ExpressionAST(Expr const& expr) : expr(expr) {}
39 
40  int evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const;
41 
42  ExpressionAST& operator!();
43 
45 };
46 
47 ExpressionAST operator>(ExpressionAST const& lhs, ExpressionAST const& rhs);
48 ExpressionAST operator>=(ExpressionAST const& lhs, ExpressionAST const& rhs);
49 ExpressionAST operator==(ExpressionAST const& lhs, ExpressionAST const& rhs);
50 ExpressionAST operator<=(ExpressionAST const& lhs, ExpressionAST const& rhs);
51 ExpressionAST operator<(ExpressionAST const& lhs, ExpressionAST const& rhs);
52 ExpressionAST operator!=(ExpressionAST const& lhs, ExpressionAST const& rhs);
53 ExpressionAST operator&&(ExpressionAST const& lhs, ExpressionAST const& rhs);
54 ExpressionAST operator||(ExpressionAST const& lhs, ExpressionAST const& rhs);
55 
56 struct BinaryOP {
57  enum class OP { GREATER, GREATER_EQUAL, EQUAL, LESS_EQUAL, LESS, NOT_EQUAL, AND, OR } op;
60 
61  BinaryOP(OP op, ExpressionAST const& left, ExpressionAST const& right) : op(op), left(left), right(right) {}
62 
63  int evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const {
64  switch (op) {
65  case OP::GREATER:
66  return left.evaluate(detId, trackerTopology) > right.evaluate(detId, trackerTopology);
67  case OP::GREATER_EQUAL:
68  return left.evaluate(detId, trackerTopology) >= right.evaluate(detId, trackerTopology);
69  case OP::EQUAL:
70  return left.evaluate(detId, trackerTopology) == right.evaluate(detId, trackerTopology);
71  case OP::LESS_EQUAL:
72  return left.evaluate(detId, trackerTopology) <= right.evaluate(detId, trackerTopology);
73  case OP::LESS:
74  return left.evaluate(detId, trackerTopology) < right.evaluate(detId, trackerTopology);
75  case OP::NOT_EQUAL:
76  return left.evaluate(detId, trackerTopology) != right.evaluate(detId, trackerTopology);
77  case OP::AND:
78  return left.evaluate(detId, trackerTopology) && right.evaluate(detId, trackerTopology);
79  case OP::OR:
80  return left.evaluate(detId, trackerTopology) || right.evaluate(detId, trackerTopology);
81  }
82  return 0;
83  }
84 };
85 
86 struct UnaryOP {
87  enum class OP { NEG } op;
89  UnaryOP(OP op, ExpressionAST const& subject) : op(op), subject(subject) {}
90 
91  int evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const {
92  switch (op) {
93  case OP::NEG:
94  return !subject.evaluate(detId, trackerTopology);
95  }
96  return 0;
97  }
98 };
99 
101 private:
102  const DetId& _detId;
104 
105 public:
106  typedef std::function<int(const TrackerTopology& trackerTopology, const DetId&)> DetIdFunction;
107  typedef std::unordered_map<std::string, DetIdFunction> StringFunctionMap;
108  const static StringFunctionMap functionTable;
109 
110  TrackerDetIdSelector(const DetId& detId, const TrackerTopology& trackerTopology)
111  : _detId(detId), _trackerTopology(trackerTopology) {}
112 
113  bool passSelection(std::string selectionStr) const;
114 };
115 
116 class Accessor : public boost::static_visitor<int> {
117 private:
118  const DetId& _detId;
120 
121 public:
122  Accessor(const DetId& detId, const TrackerTopology& trackerTopology)
123  : _detId(detId), _trackerTopology(trackerTopology) {}
124 
125  int operator()(Nil i) const {
126  throw cms::Exception("FastSimulation/TrackingRecHitProducer/TrackerDetIdSelector",
127  "while evaluating a DetId selection a symbol was not set");
128  }
129  int operator()(const int& i) const { return i; }
130  int operator()(const std::string& s) const {
131  TrackerDetIdSelector::StringFunctionMap::const_iterator it = TrackerDetIdSelector::functionTable.find(s);
132  int value = 0;
133  if (it != TrackerDetIdSelector::functionTable.cend()) {
134  value = (it->second)(_trackerTopology, _detId);
135  //std::cout<<"attr="<<s<<", value="<<value<<std::endl;
136  } else {
137  //std::cout<<"attr="<<s<<" unknown"<<std::endl;
138  std::string msg =
139  "error while parsing DetId selection: named identifier '" + s + "' not known. Possible values are: ";
141  msg += pair.first + ",";
142  }
143  throw cms::Exception("FastSimulation/TrackingRecHitProducer/TrackerDetIdSelector", msg);
144  }
145  return value;
146  }
147  int operator()(const ExpressionAST& ast) const { return ast.evaluate(_detId, _trackerTopology); }
148  int operator()(const BinaryOP& binaryOP) const { return binaryOP.evaluate(_detId, _trackerTopology); }
149  int operator()(const UnaryOP& unaryOP) const { return unaryOP.evaluate(_detId, _trackerTopology); }
150 };
151 
152 struct WalkAST {
154 
155  WalkAST(const DetId& detId, const TrackerTopology& trackerTopology) : _acc(detId, trackerTopology) {}
156 
157  typedef void result_type;
158 
159  void operator()() const {}
160  void operator()(int n) const {
161  std::cout << n;
162  std::cout << " [" << _acc(n) << "] ";
163  }
164  void operator()(std::string str) const {
165  std::cout << str;
166  std::cout << " [" << _acc(str) << "] ";
167  }
168  void operator()(ExpressionAST const& ast) const {
169  boost::apply_visitor(*this, ast.expr);
170  std::cout << " [=" << _acc(ast) << "] ";
171  }
172 
173  void operator()(BinaryOP const& expr) const {
174  std::cout << "(";
175  boost::apply_visitor(*this, expr.left.expr);
176  switch (expr.op) {
178  std::cout << " > ";
179  break;
181  std::cout << " >= ";
182  break;
183  case BinaryOP::OP::EQUAL:
184  std::cout << " == ";
185  break;
187  std::cout << " <= ";
188  break;
189  case BinaryOP::OP::LESS:
190  std::cout << " < ";
191  break;
193  std::cout << " != ";
194  break;
195  case BinaryOP::OP::AND:
196  std::cout << " && ";
197  break;
198  case BinaryOP::OP::OR:
199  std::cout << " || ";
200  break;
201  }
202  boost::apply_visitor(*this, expr.right.expr);
203  std::cout << ')';
204  }
205 
206  void operator()(UnaryOP const& expr) const {
207  switch (expr.op) {
208  case UnaryOP::OP::NEG:
209  std::cout << " !(";
210  break;
211  }
212  boost::apply_visitor(*this, expr.subject.expr);
213  std::cout << ')';
214  }
215 };
216 
217 template <typename ITERATOR>
218 struct TrackerDetIdSelectorGrammar : boost::spirit::qi::grammar<ITERATOR,
219  ExpressionAST(),
220  boost::spirit::ascii::space_type,
221  boost::spirit::qi::locals<ExpressionAST> > {
222  boost::spirit::qi::rule<ITERATOR, std::string(), boost::spirit::ascii::space_type> identifierFctRule;
223 
224  boost::spirit::qi::rule<ITERATOR, ExpressionAST(), boost::spirit::ascii::space_type> identifierRule, expressionRule;
225 
226  boost::spirit::qi::
227  rule<ITERATOR, ExpressionAST(), boost::spirit::ascii::space_type, boost::spirit::qi::locals<ExpressionAST> >
229 
231  namespace qi = boost::spirit::qi;
232  namespace ascii = boost::spirit::ascii;
233  namespace phoenix = boost::phoenix;
234 
235  identifierFctRule = qi::lexeme[+qi::alpha[qi::_val += qi::_1]];
236 
237  identifierRule = (qi::true_[qi::_val = 1] | qi::false_[qi::_val = 0]) | (qi::int_[qi::_val = qi::_1]) |
238  identifierFctRule[qi::_val = qi::_1];
239 
240  comboRule = (expressionRule[qi::_a = qi::_1] >>
241  *((qi::lit("&&") >> expressionRule[qi::_a = qi::_a && qi::_1]) |
242  (qi::lit("||") >> expressionRule[qi::_a = qi::_a || qi::_1])))[qi::_val = qi::_a];
243 
244  expressionRule = qi::lit("(") >> comboRule[qi::_val = qi::_1] >> qi::lit(")") |
245  (identifierRule >> qi::lit(">") >> identifierRule)[qi::_val = qi::_1 > qi::_2] |
246  (identifierRule >> qi::lit(">=") >> identifierRule)[qi::_val = qi::_1 >= qi::_2] |
247  (identifierRule >> qi::lit("<") >> identifierRule)[qi::_val = qi::_1 < qi::_2] |
248  (identifierRule >> qi::lit("<=") >> identifierRule)[qi::_val = qi::_1 <= qi::_2] |
249  (identifierRule >> qi::lit("==") >> identifierRule)[qi::_val = qi::_1 == qi::_2] |
250  (identifierRule >> qi::lit("!=") >> identifierRule)[qi::_val = qi::_1 != qi::_2] |
251  identifierRule[qi::_val = qi::_1];
252  }
253 };
254 
256  std::string::const_iterator begin = selectionStr.cbegin();
257  std::string::const_iterator end = selectionStr.cend();
258 
260  ExpressionAST exprAST;
261 
262  bool success = boost::spirit::qi::phrase_parse(begin, end, grammar, boost::spirit::ascii::space, exprAST);
263  if (begin != end) {
264  throw cms::Exception("FastSimulation/TrackingRecHitProducer/TrackerDetIdSelector",
265  "parsing selection '" + selectionStr + "' failed at " +
266  std::string(selectionStr.cbegin(), begin) + "^^^" + std::string(begin, end));
267  }
268  if (!success) {
269  throw cms::Exception("FastSimulation/TrackingRecHitProducer/TrackerDetIdSelector",
270  "parsing selection '" + selectionStr + "' failed.");
271  }
272  /* Comment out for debugging
273  WalkAST walker(_detId,_trackerTopology);
274  walker(exprAST);
275  std::cout<<std::endl;
276  */
277  return exprAST.evaluate(_detId, _trackerTopology);
278 }
279 
280 int ExpressionAST::evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const {
281  return boost::apply_visitor(Accessor(detId, trackerTopology), this->expr);
282 }
283 
284 #endif
ExpressionAST operator!=(ExpressionAST const &lhs, ExpressionAST const &rhs)
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)
int operator()(const BinaryOP &binaryOP) const
void operator()() const
boost::spirit::qi::rule< ITERATOR, ExpressionAST(), boost::spirit::ascii::space_type, boost::spirit::qi::locals< ExpressionAST > > comboRule
ExpressionAST operator<=(ExpressionAST const &lhs, ExpressionAST const &rhs)
const TrackerTopology & _trackerTopology
bool passSelection(std::string selectionStr) const
int operator()(const ExpressionAST &ast) const
std::unordered_map< std::string, DetIdFunction > StringFunctionMap
boost::variant< Nil, int, std::string, boost::recursive_wrapper< ExpressionAST >, boost::recursive_wrapper< BinaryOP >, boost::recursive_wrapper< UnaryOP > > Type
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
ExpressionAST operator==(ExpressionAST const &lhs, ExpressionAST const &rhs)
Definition: DetId.h:17
ExpressionAST subject
boost::spirit::qi::rule< ITERATOR, ExpressionAST(), boost::spirit::ascii::space_type > identifierRule
ExpressionAST operator>(ExpressionAST const &lhs, ExpressionAST const &rhs)
tuple msg
Definition: mps_check.py:285
ExpressionAST(Expr const &expr)
bool AND(const TrackBaseRef &track, const RecoTauQualityCuts::TrackQCutFuncCollection &cuts)
#define begin
Definition: vmac.h:32
void operator()(int n) const
alpha
zGenParticlesMatch = cms.InputTag(""),
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
boost::spirit::qi::rule< ITERATOR, std::string(), boost::spirit::ascii::space_type > identifierFctRule
enum BinaryOP::OP op
int operator()(const std::string &s) const
UnaryOP(OP op, ExpressionAST const &subject)