Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:00:59

0001 #ifndef FastSimulation_TrackingRecHitProducer_TrackerDetIdSelector_H
0002 #define FastSimulation_TrackingRecHitProducer_TrackerDetIdSelector_H
0003 
0004 #include "DataFormats/DetId/interface/DetId.h"
0005 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0006 #include "FWCore/Utilities/interface/Exception.h"
0007 
0008 #include <boost/variant/recursive_variant.hpp>
0009 
0010 #include <iostream>
0011 #include <cstdlib>
0012 #include <typeinfo>
0013 #include <functional>
0014 #include <unordered_map>
0015 
0016 struct BinaryOP;
0017 struct UnaryOP;
0018 struct ExpressionAST;
0019 struct Nil {};
0020 
0021 namespace detail {
0022   ExpressionAST opLesser(ExpressionAST const& lhs, ExpressionAST const& rhs);
0023   ExpressionAST opLesserEq(ExpressionAST const& lhs, ExpressionAST const& rhs);
0024   ExpressionAST opEq(ExpressionAST const& lhs, ExpressionAST const& rhs);
0025   ExpressionAST opNotEq(ExpressionAST const& lhs, ExpressionAST const& rhs);
0026   ExpressionAST opGreater(ExpressionAST const& lhs, ExpressionAST const& rhs);
0027   ExpressionAST opGreaterEq(ExpressionAST const& lhs, ExpressionAST const& rhs);
0028   ExpressionAST opAnd(ExpressionAST const& lhs, ExpressionAST const& rhs);
0029   ExpressionAST opOr(ExpressionAST const& lhs, ExpressionAST const& rhs);
0030 }  // namespace detail
0031 
0032 struct ExpressionAST {
0033   typedef boost::variant<Nil,
0034                          int,
0035                          std::string,
0036                          boost::recursive_wrapper<ExpressionAST>,
0037                          boost::recursive_wrapper<BinaryOP>,
0038                          boost::recursive_wrapper<UnaryOP> >
0039       Type;
0040 
0041   ExpressionAST() : expr(Nil()) {}
0042 
0043   template <typename Expr>
0044   ExpressionAST(Expr const& expr) : expr(expr) {}
0045 
0046   int evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const;
0047 
0048   ExpressionAST& operator!();
0049 
0050   Type expr;
0051 
0052   friend ExpressionAST operator>(ExpressionAST const& lhs, ExpressionAST const& rhs) {
0053     return detail::opGreater(lhs, rhs);
0054   }
0055   friend ExpressionAST operator>=(ExpressionAST const& lhs, ExpressionAST const& rhs) {
0056     return detail::opGreaterEq(lhs, rhs);
0057   }
0058   friend ExpressionAST operator==(ExpressionAST const& lhs, ExpressionAST const& rhs) { return detail::opEq(lhs, rhs); }
0059   friend ExpressionAST operator!=(ExpressionAST const& lhs, ExpressionAST const& rhs) {
0060     return detail::opNotEq(lhs, rhs);
0061   }
0062   friend ExpressionAST operator<(ExpressionAST const& lhs, ExpressionAST const& rhs) {
0063     return detail::opLesser(lhs, rhs);
0064   }
0065   friend ExpressionAST operator<=(ExpressionAST const& lhs, ExpressionAST const& rhs) {
0066     return detail::opLesserEq(lhs, rhs);
0067   }
0068   friend ExpressionAST operator&&(ExpressionAST const& lhs, ExpressionAST const& rhs) {
0069     return detail::opAnd(lhs, rhs);
0070   }
0071   friend ExpressionAST operator||(ExpressionAST const& lhs, ExpressionAST const& rhs) { return detail::opOr(lhs, rhs); }
0072 };
0073 
0074 struct BinaryOP {
0075   enum class OP { GREATER, GREATER_EQUAL, EQUAL, LESS_EQUAL, LESS, NOT_EQUAL, AND, OR } op;
0076   ExpressionAST left;
0077   ExpressionAST right;
0078 
0079   BinaryOP(OP op, ExpressionAST const& left, ExpressionAST const& right) : op(op), left(left), right(right) {}
0080 
0081   int evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const {
0082     switch (op) {
0083       case OP::GREATER:
0084         return left.evaluate(detId, trackerTopology) > right.evaluate(detId, trackerTopology);
0085       case OP::GREATER_EQUAL:
0086         return left.evaluate(detId, trackerTopology) >= right.evaluate(detId, trackerTopology);
0087       case OP::EQUAL:
0088         return left.evaluate(detId, trackerTopology) == right.evaluate(detId, trackerTopology);
0089       case OP::LESS_EQUAL:
0090         return left.evaluate(detId, trackerTopology) <= right.evaluate(detId, trackerTopology);
0091       case OP::LESS:
0092         return left.evaluate(detId, trackerTopology) < right.evaluate(detId, trackerTopology);
0093       case OP::NOT_EQUAL:
0094         return left.evaluate(detId, trackerTopology) != right.evaluate(detId, trackerTopology);
0095       case OP::AND:
0096         return left.evaluate(detId, trackerTopology) && right.evaluate(detId, trackerTopology);
0097       case OP::OR:
0098         return left.evaluate(detId, trackerTopology) || right.evaluate(detId, trackerTopology);
0099     }
0100     return 0;
0101   }
0102 };
0103 
0104 struct UnaryOP {
0105   enum class OP { NEG } op;
0106   ExpressionAST subject;
0107   UnaryOP(OP op, ExpressionAST const& subject) : op(op), subject(subject) {}
0108 
0109   int evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const {
0110     switch (op) {
0111       case OP::NEG:
0112         return !subject.evaluate(detId, trackerTopology);
0113     }
0114     return 0;
0115   }
0116 };
0117 
0118 class TrackerDetIdSelector {
0119 private:
0120   const DetId& _detId;
0121   const TrackerTopology& _trackerTopology;
0122 
0123 public:
0124   typedef std::function<int(const TrackerTopology& trackerTopology, const DetId&)> DetIdFunction;
0125   typedef std::unordered_map<std::string, DetIdFunction> StringFunctionMap;
0126   const static StringFunctionMap functionTable;
0127 
0128   TrackerDetIdSelector(const DetId& detId, const TrackerTopology& trackerTopology)
0129       : _detId(detId), _trackerTopology(trackerTopology) {}
0130 
0131   bool passSelection(const std::string& selectionStr) const;
0132 };
0133 
0134 class Accessor : public boost::static_visitor<int> {
0135 private:
0136   const DetId& _detId;
0137   const TrackerTopology& _trackerTopology;
0138 
0139 public:
0140   Accessor(const DetId& detId, const TrackerTopology& trackerTopology)
0141       : _detId(detId), _trackerTopology(trackerTopology) {}
0142 
0143   int operator()(Nil i) const {
0144     throw cms::Exception("FastSimulation/TrackingRecHitProducer/TrackerDetIdSelector",
0145                          "while evaluating a DetId selection a symbol was not set");
0146   }
0147   int operator()(const int& i) const { return i; }
0148   int operator()(const std::string& s) const {
0149     TrackerDetIdSelector::StringFunctionMap::const_iterator it = TrackerDetIdSelector::functionTable.find(s);
0150     int value = 0;
0151     if (it != TrackerDetIdSelector::functionTable.cend()) {
0152       value = (it->second)(_trackerTopology, _detId);
0153       //std::cout<<"attr="<<s<<", value="<<value<<std::endl;
0154     } else {
0155       //std::cout<<"attr="<<s<<" unknown"<<std::endl;
0156       std::string msg =
0157           "error while parsing DetId selection: named identifier '" + s + "' not known. Possible values are: ";
0158       for (const TrackerDetIdSelector::StringFunctionMap::value_type& pair : TrackerDetIdSelector::functionTable) {
0159         msg += pair.first + ",";
0160       }
0161       throw cms::Exception("FastSimulation/TrackingRecHitProducer/TrackerDetIdSelector", msg);
0162     }
0163     return value;
0164   }
0165   int operator()(const ExpressionAST& ast) const { return ast.evaluate(_detId, _trackerTopology); }
0166   int operator()(const BinaryOP& binaryOP) const { return binaryOP.evaluate(_detId, _trackerTopology); }
0167   int operator()(const UnaryOP& unaryOP) const { return unaryOP.evaluate(_detId, _trackerTopology); }
0168 };
0169 
0170 struct WalkAST {
0171   Accessor _acc;
0172 
0173   WalkAST(const DetId& detId, const TrackerTopology& trackerTopology) : _acc(detId, trackerTopology) {}
0174 
0175   typedef void result_type;
0176 
0177   void operator()() const {}
0178   void operator()(int n) const {
0179     std::cout << n;
0180     std::cout << " [" << _acc(n) << "] ";
0181   }
0182   void operator()(std::string str) const {
0183     std::cout << str;
0184     std::cout << " [" << _acc(str) << "] ";
0185   }
0186   void operator()(ExpressionAST const& ast) const {
0187     boost::apply_visitor(*this, ast.expr);
0188     std::cout << " [=" << _acc(ast) << "] ";
0189   }
0190 
0191   void operator()(BinaryOP const& expr) const {
0192     std::cout << "(";
0193     boost::apply_visitor(*this, expr.left.expr);
0194     switch (expr.op) {
0195       case BinaryOP::OP::GREATER:
0196         std::cout << " > ";
0197         break;
0198       case BinaryOP::OP::GREATER_EQUAL:
0199         std::cout << " >= ";
0200         break;
0201       case BinaryOP::OP::EQUAL:
0202         std::cout << " == ";
0203         break;
0204       case BinaryOP::OP::LESS_EQUAL:
0205         std::cout << " <= ";
0206         break;
0207       case BinaryOP::OP::LESS:
0208         std::cout << " < ";
0209         break;
0210       case BinaryOP::OP::NOT_EQUAL:
0211         std::cout << " != ";
0212         break;
0213       case BinaryOP::OP::AND:
0214         std::cout << " && ";
0215         break;
0216       case BinaryOP::OP::OR:
0217         std::cout << " || ";
0218         break;
0219     }
0220     boost::apply_visitor(*this, expr.right.expr);
0221     std::cout << ')';
0222   }
0223 
0224   void operator()(UnaryOP const& expr) const {
0225     switch (expr.op) {
0226       case UnaryOP::OP::NEG:
0227         std::cout << " !(";
0228         break;
0229     }
0230     boost::apply_visitor(*this, expr.subject.expr);
0231     std::cout << ')';
0232   }
0233 };
0234 
0235 inline int ExpressionAST::evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const {
0236   return boost::apply_visitor(Accessor(detId, trackerTopology), this->expr);
0237 }
0238 
0239 #endif