CMS 3D CMS Logo

L1GTAlgoBlockProducer.cc
Go to the documentation of this file.
6 
9 
12 
16 
27 
28 #include <boost/spirit/include/qi.hpp>
29 
32 
33 #include <string>
34 #include <memory>
35 #include <utility>
36 #include <map>
37 #include <unordered_map>
38 #include <vector>
39 #include <set>
40 #include <tuple>
41 
44 namespace qi = boost::spirit::qi;
45 namespace ascii = boost::spirit::ascii;
46 
48  class Evaluator {
49  public:
50  virtual ~Evaluator() {}
51 
53  virtual EvaluatorType type() const = 0;
54 
55  virtual const char* pathName() const { return ""; }
56 
57  virtual void setLeft(std::unique_ptr<Evaluator>&&) {}
58  virtual void setRight(std::unique_ptr<Evaluator>&&) {}
59 
60  virtual void print(std::ostream& out, unsigned int indentation) const {}
61  virtual void init(edm::ConsumesCollector&) {}
62  virtual bool evaluate(edm::Event const& event) const { return true; };
63  };
64 
65  class Operand : public Evaluator {
66  public:
67  Operand(std::vector<char> const& pathName) : pathName_(pathName.begin(), pathName.end()) {}
68 
69  EvaluatorType type() const override { return Name; }
70 
71  void print(std::ostream& out, unsigned int indentation) const override {
72  out << std::string(indentation, ' ') << pathName_ << "\n";
73  }
74 
76 
77  bool evaluate(edm::Event const& event) const override { return event.get(token_).accept(); }
78 
79  private:
82  };
83 
84  class NotOperator : public Evaluator {
85  public:
86  EvaluatorType type() const override { return Not; }
87 
88  void setLeft(std::unique_ptr<Evaluator>&& v) override { operand_ = std::move(v); }
89 
90  void print(std::ostream& out, unsigned int indentation) const override {
91  out << std::string(indentation, ' ') << "not\n";
92  operand_->print(out, indentation + 4);
93  }
94 
95  void init(edm::ConsumesCollector& iC) override { operand_->init(iC); }
96 
97  bool evaluate(edm::Event const& event) const override { return !operand_->evaluate(event); }
98 
99  private:
101  };
102 
103  template <typename T>
104  class BinaryOperator : public Evaluator {
105  public:
106  EvaluatorType type() const override;
107 
108  void setLeft(std::unique_ptr<Evaluator>&& v) override { left_ = std::move(v); }
109  void setRight(std::unique_ptr<Evaluator>&& v) override { right_ = std::move(v); }
110 
111  void print(std::ostream& out, unsigned int indentation) const override;
112 
113  void init(edm::ConsumesCollector& iC) override {
114  left_->init(iC);
115  right_->init(iC);
116  }
117 
118  bool evaluate(edm::Event const& event) const override {
119  T op;
120  return op(left_->evaluate(event), right_->evaluate(event));
121  }
122 
123  private:
126  };
127 
128  template <>
130  return And;
131  }
132 
133  template <>
135  return Or;
136  }
137 
138  template <>
139  void BinaryOperator<std::logical_and<bool>>::print(std::ostream& out, unsigned int indentation) const {
140  out << std::string(indentation, ' ') << "and\n";
141  left_->print(out, indentation + 4);
142  right_->print(out, indentation + 4);
143  }
144  template <>
145  void BinaryOperator<std::logical_or<bool>>::print(std::ostream& out, unsigned int indentation) const {
146  out << std::string(indentation, ' ') << "or\n";
147  left_->print(out, indentation + 4);
148  right_->print(out, indentation + 4);
149  }
150 
153 
154  class BeginParenthesis : public Evaluator {
155  public:
156  EvaluatorType type() const override { return BeginParen; }
157  };
158 
159  // This class exists to properly handle the precedence of the
160  // operators and also handle the order of operations specified
161  // by parentheses. (search for shunting yard algorithm on the
162  // internet for a description of this algorithm)
164  public:
165  void addPathName(std::vector<char> const& s) {
166  operandStack.push_back(std::make_unique<Operand>(s));
167  pathNames_.emplace_back(s.begin(), s.end());
168  }
169 
170  void addOperatorNot() {
171  if (operatorStack.empty() || operatorStack.back()->type() != Evaluator::Not) {
172  operatorStack.push_back(std::make_unique<NotOperator>());
173  } else {
174  // Two Not operations in a row cancel and are the same as no operation at all.
175  operatorStack.pop_back();
176  }
177  }
178 
180  std::unique_ptr<Evaluator>& backEvaluator = operatorStack.back();
181  backEvaluator->setRight(std::move(operandStack.back()));
182  operandStack.pop_back();
183  backEvaluator->setLeft(std::move(operandStack.back()));
184  operandStack.pop_back();
185  operandStack.push_back(std::move(backEvaluator));
186  operatorStack.pop_back();
187  }
188 
190  std::unique_ptr<Evaluator>& backEvaluator = operatorStack.back();
191  backEvaluator->setLeft(std::move(operandStack.back()));
192  operandStack.pop_back();
193  operandStack.push_back(std::move(backEvaluator));
194  operatorStack.pop_back();
195  }
196 
197  void addOperatorAnd() {
198  while (!operatorStack.empty()) {
199  std::unique_ptr<Evaluator>& backEvaluator = operatorStack.back();
200  if (backEvaluator->type() == Evaluator::And) {
202  } else if (backEvaluator->type() == Evaluator::Not) {
203  moveNotOperator();
204  } else {
205  break;
206  }
207  }
208  operatorStack.push_back(std::make_unique<AndOperator>());
209  }
210 
211  void addOperatorOr() {
212  while (!operatorStack.empty()) {
213  std::unique_ptr<Evaluator>& backEvaluator = operatorStack.back();
214  if (backEvaluator->type() == Evaluator::And || backEvaluator->type() == Evaluator::Or) {
216  } else if (backEvaluator->type() == Evaluator::Not) {
217  moveNotOperator();
218  } else {
219  break;
220  }
221  }
222  operatorStack.push_back(std::make_unique<OrOperator>());
223  }
224 
225  void addBeginParenthesis() { operatorStack.push_back(std::make_unique<BeginParenthesis>()); }
226 
228  while (!operatorStack.empty()) {
229  std::unique_ptr<Evaluator>& backEvaluator = operatorStack.back();
230  if (backEvaluator->type() == Evaluator::BeginParen) {
231  operatorStack.pop_back();
232  break;
233  }
234  if (backEvaluator->type() == Evaluator::And || backEvaluator->type() == Evaluator::Or) {
236  } else if (backEvaluator->type() == Evaluator::Not) {
237  moveNotOperator();
238  }
239  }
240  }
241 
242  std::unique_ptr<Evaluator> finish() {
243  while (!operatorStack.empty()) {
244  std::unique_ptr<Evaluator>& backEvaluator = operatorStack.back();
245  // Just a sanity check. The grammar defined for the boost Spirit parser
246  // should catch any errors of this type before we get here.
247  if (backEvaluator->type() == Evaluator::BeginParen) {
248  throw cms::Exception("LogicError") << "Should be impossible to get this error. Contact a Framework developer";
249  }
250  if (backEvaluator->type() == Evaluator::And || backEvaluator->type() == Evaluator::Or) {
252  } else if (backEvaluator->type() == Evaluator::Not) {
253  moveNotOperator();
254  }
255  }
256  // Just a sanity check. The grammar defined for the boost Spirit parser
257  // should catch any errors of this type before we get here.
258  if (!operatorStack.empty() || operandStack.size() != 1U) {
259  throw cms::Exception("LogicError") << "Should be impossible to get this error. Contact a Framework developer";
260  }
261  std::unique_ptr<Evaluator> temp = std::move(operandStack.back());
262  operandStack.pop_back();
263  return temp;
264  }
265 
266  const std::vector<std::string>& pathNames() { return pathNames_; }
267 
268  private:
269  std::vector<std::string> pathNames_;
270  std::vector<std::unique_ptr<Evaluator>> operandStack;
271  std::vector<std::unique_ptr<Evaluator>> operatorStack;
272  };
273 
274  // Use boost Spirit to parse the logical expression character string
275  template <typename Iterator>
276  class Grammar : public qi::grammar<Iterator, ascii::space_type> {
277  public:
279  // setup functors that call into shunting algorithm while parsing the logical expression
280  auto addPathName = std::bind(&ShuntingYardAlgorithm::addPathName, algorithm_, std::placeholders::_1);
281  auto addOperatorNot = std::bind(&ShuntingYardAlgorithm::addOperatorNot, algorithm_);
282  auto addOperatorAnd = std::bind(&ShuntingYardAlgorithm::addOperatorAnd, algorithm_);
283  auto addOperatorOr = std::bind(&ShuntingYardAlgorithm::addOperatorOr, algorithm_);
284  auto addBeginParenthesis = std::bind(&ShuntingYardAlgorithm::addBeginParenthesis, algorithm_);
285  auto addEndParenthesis = std::bind(&ShuntingYardAlgorithm::addEndParenthesis, algorithm_);
286 
287  // Define the syntax allowed in the logical expressions
288  pathName = !unaryOperator >> !binaryOperatorTest >> (+qi::char_("a-zA-Z0-9_"))[addPathName];
289  binaryOperand = (qi::lit('(')[addBeginParenthesis] >> expression >> qi::lit(')')[addEndParenthesis]) |
290  (unaryOperator[addOperatorNot] >> binaryOperand) | pathName;
291  afterOperator = ascii::space | &qi::lit('(') | &qi::eoi;
292  unaryOperator = qi::lit("not") >> afterOperator;
293  // The only difference in the next two is that one calls a functor and the other does not
294  binaryOperatorTest = (qi::lit("and") >> afterOperator) | (qi::lit("or") >> afterOperator);
296  (qi::lit("and") >> afterOperator)[addOperatorAnd] | (qi::lit("or") >> afterOperator)[addOperatorOr];
298  }
299 
300  private:
301  qi::rule<Iterator> pathName;
302  qi::rule<Iterator, ascii::space_type> binaryOperand;
303  qi::rule<Iterator> afterOperator;
304  qi::rule<Iterator> unaryOperator;
305  qi::rule<Iterator> binaryOperatorTest;
306  qi::rule<Iterator> binaryOperator;
307  qi::rule<Iterator, ascii::space_type> expression;
308 
310  };
311 } // namespace pathStatusExpression
312 
313 using namespace l1t;
314 
316  : public edm::one::EDProducer<edm::RunCache<std::unordered_map<std::string, unsigned int>>> {
317 public:
318  explicit L1GTAlgoBlockProducer(const edm::ParameterSet&);
319  ~L1GTAlgoBlockProducer() override = default;
320 
322 
323 private:
324  struct AlgoDefinition {
326  std::vector<std::string> pathNames_;
327  std::set<std::tuple<std::string, std::string>> filtModules_;
328  unsigned int prescale_;
329  unsigned int prescalePreview_;
330  std::set<unsigned int> bunchMask_;
331  bool isVeto_;
333  };
334 
335  void init(const edm::ProcessHistory&);
336  void produce(edm::Event&, const edm::EventSetup&) override;
337  std::shared_ptr<std::unordered_map<std::string, unsigned int>> globalBeginRun(edm::Run const&,
338  edm::EventSetup const&) const override;
339 
340  void globalEndRun(edm::Run const&, edm::EventSetup const&) override {}
341 
343  std::map<std::string, AlgoDefinition> algoDefinitions_;
344  bool initialized_ = false;
345  int bunchCrossingEmu_ = 0;
346 };
347 
350  algoDesc.add<std::string>("name", "");
351  algoDesc.add<std::string>("expression");
352  algoDesc.add<double>("prescale", 1);
353  algoDesc.add<double>("prescalePreview", 1);
354  algoDesc.add<std::vector<unsigned int>>("bunchMask", {});
355 
356  algoDesc.add<std::vector<int>>("triggerTypes", {1});
357  algoDesc.add<bool>("veto", false);
358 
360  desc.addVPSet("algorithms", algoDesc);
361 
362  description.addWithDefaultLabel(desc);
363 }
364 
366  : getterOfPassedReferences_(edm::TypeMatch(), this) {
368 
369  for (const auto& algoConfig : config.getParameterSetVector("algorithms")) {
370  const std::string logicalExpression = algoConfig.getParameter<std::string>("expression");
371  std::string name = algoConfig.getParameter<std::string>("name");
372  if (name.empty()) {
374  }
375 
376  pathStatusExpression::ShuntingYardAlgorithm shuntingYardAlgorithm;
377  pathStatusExpression::Grammar<std::string::const_iterator> grammar(&shuntingYardAlgorithm);
378 
379  auto it = logicalExpression.cbegin();
380  if (!qi::phrase_parse(it, logicalExpression.cend(), grammar, ascii::space) || (it != logicalExpression.cend())) {
381  throw cms::Exception("Configuration") << "Syntax error in logical expression. Here is an example of how\n"
382  << "the syntax should look:\n"
383  << " \"path1 and not (path2 or not path3)\"\n"
384  << "The expression must contain alternating appearances of operands\n"
385  << "which are path names and binary operators which can be \'and\'\n"
386  << "or \'or\', with a path name at the beginning and end. There\n"
387  << "must be at least one path name. In addition to the alternating\n"
388  << "path names and binary operators, the unary operator \'not\' can\n"
389  << "be inserted before a path name or a begin parenthesis.\n"
390  << "Parentheses are allowed. Parentheses must come in matching pairs.\n"
391  << "Matching begin and end parentheses must contain a complete and\n"
392  << "syntactically correct logical expression. There must be at least\n"
393  << "one space or parenthesis between operators and path names. Extra\n"
394  << "space is ignored and OK. Path names can only contain upper and\n"
395  << "lower case letters, numbers, and underscores. A path name cannot\n"
396  << "be the same as an operator name.\n";
397  }
398 
399  AlgoDefinition definition;
400 
401  for (const std::string& pathName : shuntingYardAlgorithm.pathNames()) {
402  definition.pathNames_.push_back(pathName);
403  }
404 
405  definition.evaluator_ = shuntingYardAlgorithm.finish();
406  double dPrescale = algoConfig.getParameter<double>("prescale");
407  if ((dPrescale < 1. || dPrescale >= std::pow(2, 24) / 100 - 1) && dPrescale != 0) {
408  throw cms::Exception("Configuration")
409  << "Prescale value error. Expected prescale value between 1 and 2^24/100 - 1 or 0 got " << dPrescale << "."
410  << std::endl;
411  }
412 
413  definition.prescale_ = std::round(dPrescale * 100);
414 
415  double dPrescalePreview = algoConfig.getParameter<double>("prescalePreview");
416  if ((dPrescalePreview < 1. || dPrescalePreview >= std::pow(2, 24) / 100 - 1) && dPrescalePreview != 0) {
417  throw cms::Exception("Configuration")
418  << "PrescalePreview value error. Expected prescale value between 1 and 2^24/100 - 1 or 0 got "
419  << dPrescalePreview << "." << std::endl;
420  }
421 
422  definition.prescalePreview_ = std::round(dPrescalePreview * 100);
423 
424  std::vector<unsigned int> vBunchMask = algoConfig.getParameter<std::vector<unsigned int>>("bunchMask");
425  definition.bunchMask_ =
426  std::set<unsigned int>(std::make_move_iterator(vBunchMask.begin()), std::make_move_iterator(vBunchMask.end()));
427 
428  definition.isVeto_ = algoConfig.getParameter<bool>("veto");
429  definition.triggerTypes_ = 0;
430  const std::vector<int> triggerTypes = algoConfig.getParameter<std::vector<int>>("triggerTypes");
431  for (int type : triggerTypes) {
432  definition.triggerTypes_ |= type;
433  }
434 
435  definition.evaluator_->init(iC);
436  auto [iter, wasInserted] = algoDefinitions_.emplace(std::move(name), std::move(definition));
437  if (!wasInserted) {
438  throw cms::Exception("Configuration")
439  << "Algorithm " << iter->first << " already exists. Algorithm names must be unique." << std::endl;
440  }
441  }
442 
444  produces<P2GTAlgoBlockMap>();
445 }
446 
449 
451 
452  pHistory.getConfigurationForProcess(pName, cfg);
453 
454  const edm::ParameterSet* pset = edm::pset::Registry::instance()->getMapped(cfg.parameterSetID());
455 
456  for (auto& [name, algoDef] : algoDefinitions_) {
457  for (const std::string& pathName : algoDef.pathNames_) {
458  if (pset->existsAs<std::vector<std::string>>(pathName)) {
459  const auto& modules = pset->getParameter<std::vector<std::string>>(pathName);
460  for (const auto& mod : modules) {
461  if (mod.front() != std::string("-") && pset->exists(mod)) {
462  const auto& modPSet = pset->getParameterSet(mod);
463  if (modPSet.getParameter<std::string>("@module_edm_type") == "EDFilter") {
464  if (modPSet.getParameter<std::string>("@module_type") == "L1GTSingleObjectCond") {
465  algoDef.filtModules_.insert({mod, modPSet.getParameter<edm::InputTag>("tag").instance()});
466  } else if (modPSet.getParameter<std::string>("@module_type") == "L1GTDoubleObjectCond") {
467  algoDef.filtModules_.insert(
468  {mod, modPSet.getParameterSet("collection1").getParameter<edm::InputTag>("tag").instance()});
469  algoDef.filtModules_.insert(
470  {mod, modPSet.getParameterSet("collection2").getParameter<edm::InputTag>("tag").instance()});
471  } else if (modPSet.getParameter<std::string>("@module_type") == "L1GTTripleObjectCond") {
472  algoDef.filtModules_.insert(
473  {mod, modPSet.getParameterSet("collection1").getParameter<edm::InputTag>("tag").instance()});
474  algoDef.filtModules_.insert(
475  {mod, modPSet.getParameterSet("collection2").getParameter<edm::InputTag>("tag").instance()});
476  algoDef.filtModules_.insert(
477  {mod, modPSet.getParameterSet("collection3").getParameter<edm::InputTag>("tag").instance()});
478  } else if (modPSet.getParameter<std::string>("@module_type") == "L1GTQuadObjectCond") {
479  algoDef.filtModules_.insert(
480  {mod, modPSet.getParameterSet("collection1").getParameter<edm::InputTag>("tag").instance()});
481  algoDef.filtModules_.insert(
482  {mod, modPSet.getParameterSet("collection2").getParameter<edm::InputTag>("tag").instance()});
483  algoDef.filtModules_.insert(
484  {mod, modPSet.getParameterSet("collection3").getParameter<edm::InputTag>("tag").instance()});
485  algoDef.filtModules_.insert(
486  {mod, modPSet.getParameterSet("collection4").getParameter<edm::InputTag>("tag").instance()});
487  }
488  }
489  }
490  }
491  }
492  }
493  }
494 }
495 
496 std::shared_ptr<std::unordered_map<std::string, unsigned int>> L1GTAlgoBlockProducer::globalBeginRun(
497  edm::Run const&, edm::EventSetup const&) const {
498  // Reset prescale counters at the beginning of a new run
499  return std::make_shared<std::unordered_map<std::string, unsigned int>>();
500 }
501 
503  if (!initialized_) {
504  init(event.processHistory());
505  initialized_ = true;
506  }
507 
508  std::vector<edm::Handle<P2GTCandidateVectorRef>> handles;
510 
511  std::unique_ptr<P2GTAlgoBlockMap> algoCollection = std::make_unique<P2GTAlgoBlockMap>();
512 
513  std::unordered_map<std::string, unsigned int>& prescaleCounters = *runCache(event.getRun().index());
514 
515  int bunchCrossing = event.isRealData() ? event.bunchCrossing() : bunchCrossingEmu_ + 1;
516 
517  for (const auto& [name, algoDef] : algoDefinitions_) {
518  bool decisionBeforeBxAndPrescale = algoDef.evaluator_->evaluate(event);
519  bool decisionBeforePrescale = decisionBeforeBxAndPrescale && algoDef.bunchMask_.count(bunchCrossing) == 0;
520  bool decisionFinal = false;
521  bool decisionFinalPreview = false;
522 
523  if (algoDef.prescale_ != 0 && decisionBeforePrescale) {
524  if (prescaleCounters.count(name) > 0) {
525  prescaleCounters[name] += 100;
526  } else {
527  prescaleCounters[name] = 100;
528  }
529 
530  if (prescaleCounters[name] >= algoDef.prescale_) {
531  decisionFinal = true;
532  prescaleCounters[name] -= algoDef.prescale_;
533  } else {
534  decisionFinal = false;
535  }
536  }
537 
538  if (algoDef.prescalePreview_ != 0 && decisionBeforePrescale) {
539  std::string previewName = name + "_preview";
540  if (prescaleCounters.count(previewName) > 0) {
541  prescaleCounters[previewName] += 100;
542  } else {
543  prescaleCounters[previewName] = 100;
544  }
545 
546  if (prescaleCounters[previewName] >= algoDef.prescalePreview_) {
547  decisionFinalPreview = true;
548  prescaleCounters[previewName] -= algoDef.prescalePreview_;
549  } else {
550  decisionFinalPreview = false;
551  }
552  }
553 
554  P2GTCandidateVectorRef trigObjects;
555 
556  if (decisionFinal) {
557  for (const auto& handle : handles) {
558  const std::string& module = handle.provenance()->moduleLabel();
559  const std::string& instance = handle.provenance()->productInstanceName();
560 
561  if (algoDef.filtModules_.count({module, instance}) > 0) {
562  trigObjects.insert(trigObjects.end(), handle->begin(), handle->end());
563  }
564  }
565  }
566 
567  algoCollection->emplace(name,
568  P2GTAlgoBlock(decisionBeforeBxAndPrescale,
569  decisionBeforePrescale,
570  decisionFinal,
571  decisionFinalPreview,
572  algoDef.isVeto_,
573  algoDef.triggerTypes_,
574  std::move(trigObjects)));
575  }
576 
577  event.put(std::move(algoCollection));
578 
579  bunchCrossingEmu_ = (bunchCrossingEmu_ + 1) % 3564;
580 }
581 
virtual bool evaluate(edm::Event const &event) const
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
void callWhenNewProductsRegistered(std::function< void(BranchDescription const &)> const &func)
Definition: ProducerBase.h:87
qi::rule< Iterator, ascii::space_type > expression
static void fillDescriptions(edm::ConfigurationDescriptions &)
bool getMapped(key_type const &k, value_type &result) const
Definition: Registry.cc:17
void setRight(std::unique_ptr< Evaluator > &&v) override
std::set< std::tuple< std::string, std::string > > filtModules_
void addPathName(std::vector< char > const &s)
static PFTauRenderPlugin instance
virtual void setRight(std::unique_ptr< Evaluator > &&)
edm::propagate_const< std::unique_ptr< pathStatusExpression::Evaluator > > evaluator_
void init(edm::ConsumesCollector &iC) override
int init
Definition: HydjetWrapper.h:66
virtual void init(edm::ConsumesCollector &)
delete x;
Definition: CaloConfig.h:22
Definition: config.py:1
std::vector< std::unique_ptr< Evaluator > > operandStack
void produce(edm::Event &, const edm::EventSetup &) override
bool getConfigurationForProcess(std::string const &name, ProcessConfiguration &config) const
void print(std::ostream &out, unsigned int indentation) const override
std::map< std::string, AlgoDefinition > algoDefinitions_
void setLeft(std::unique_ptr< Evaluator > &&v) override
edm::EDGetTokenT< edm::PathStatus > token_
edm::propagate_const< std::unique_ptr< Evaluator > > left_
bool evaluate(edm::Event const &event) const override
edm::propagate_const< std::unique_ptr< Evaluator > > right_
void init(edm::ConsumesCollector &iC) override
L1GTAlgoBlockProducer(const edm::ParameterSet &)
std::vector< BaseVolumeHandle * > handles
void print(std::ostream &out, unsigned int indentation) const override
EvaluatorType type() const override
edm::propagate_const< std::unique_ptr< Evaluator > > operand_
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
virtual EvaluatorType type() const =0
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
EvaluatorType type() const override
Operand(std::vector< char > const &pathName)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
edm::GetterOfProducts< P2GTCandidateVectorRef > getterOfPassedReferences_
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void init(const edm::ProcessHistory &)
virtual const char * pathName() const
def getProcessName(pdgGen, requiredNumberOfGeneratedObjects)
void fillHandles(ProductContainer const &productContainer, std::vector< edm::Handle< T >> &handles) const
void print(std::ostream &out, unsigned int indentation) const override
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
virtual void print(std::ostream &out, unsigned int indentation) const
bool evaluate(edm::Event const &event) const override
void init(edm::ConsumesCollector &iC) override
qi::rule< Iterator, ascii::space_type > binaryOperand
virtual void setLeft(std::unique_ptr< Evaluator > &&)
EvaluatorType type() const override
std::vector< P2GTCandidateRef > P2GTCandidateVectorRef
Definition: P2GTCandidate.h:20
std::vector< std::unique_ptr< Evaluator > > operatorStack
bool evaluate(edm::Event const &event) const override
HLT enums.
void setLeft(std::unique_ptr< Evaluator > &&v) override
std::shared_ptr< std::unordered_map< std::string, unsigned int > > globalBeginRun(edm::Run const &, edm::EventSetup const &) const override
HLTPathStatus PathStatus
Definition: PathStatus.h:7
const std::vector< std::string > & pathNames()
long double T
void globalEndRun(edm::Run const &, edm::EventSetup const &) override
T mod(const T &a, const T &b)
Definition: ecalDccMap.h:4
Grammar(ShuntingYardAlgorithm *algorithm)
ShuntingYardAlgorithm * algorithm_
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
def move(src, dest)
Definition: eostools.py:511
static Registry * instance()
Definition: Registry.cc:12
Definition: event.py:1
Definition: Run.h:45