File indexing completed on 2024-07-22 23:31:17
0001 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0002 #include "DataFormats/Common/interface/Handle.h"
0003 #include "FWCore/Utilities/interface/EDGetToken.h"
0004 #include "FWCore/Framework/interface/GetterOfProducts.h"
0005 #include "FWCore/Framework/interface/TypeMatch.h"
0006
0007 #include "FWCore/Framework/interface/MakerMacros.h"
0008 #include "DataFormats/Common/interface/View.h"
0009
0010 #include "FWCore/Framework/interface/Frameworkfwd.h"
0011 #include "FWCore/Framework/interface/one/EDProducer.h"
0012
0013 #include "FWCore/ServiceRegistry/interface/Service.h"
0014 #include "FWCore/Framework/interface/TriggerNamesService.h"
0015 #include "FWCore/ParameterSet/interface/Registry.h"
0016
0017 #include "DataFormats/Common/interface/PathStatus.h"
0018 #include "FWCore/Framework/interface/ConsumesCollector.h"
0019 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0020 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0021 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0022 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0023 #include "FWCore/Utilities/interface/EDGetToken.h"
0024 #include "FWCore/Utilities/interface/Exception.h"
0025 #include "FWCore/Utilities/interface/InputTag.h"
0026 #include "FWCore/Utilities/interface/propagate_const.h"
0027
0028 #include <boost/spirit/include/qi.hpp>
0029
0030 #include "DataFormats/L1Trigger/interface/P2GTCandidate.h"
0031 #include "DataFormats/L1Trigger/interface/P2GTAlgoBlock.h"
0032
0033 #include <string>
0034 #include <memory>
0035 #include <utility>
0036 #include <map>
0037 #include <unordered_map>
0038 #include <vector>
0039 #include <set>
0040 #include <tuple>
0041
0042
0043
0044 namespace qi = boost::spirit::qi;
0045 namespace ascii = boost::spirit::ascii;
0046
0047 namespace pathStatusExpression {
0048 class Evaluator {
0049 public:
0050 virtual ~Evaluator() {}
0051
0052 enum EvaluatorType { Name, Not, And, Or, BeginParen };
0053 virtual EvaluatorType type() const = 0;
0054
0055 virtual const char* pathName() const { return ""; }
0056
0057 virtual void setLeft(std::unique_ptr<Evaluator>&&) {}
0058 virtual void setRight(std::unique_ptr<Evaluator>&&) {}
0059
0060 virtual void print(std::ostream& out, unsigned int indentation) const {}
0061 virtual void init(edm::ConsumesCollector&) {}
0062 virtual bool evaluate(edm::Event const& event) const { return true; };
0063 };
0064
0065 class Operand : public Evaluator {
0066 public:
0067 Operand(std::vector<char> const& pathName) : pathName_(pathName.begin(), pathName.end()) {}
0068
0069 EvaluatorType type() const override { return Name; }
0070
0071 void print(std::ostream& out, unsigned int indentation) const override {
0072 out << std::string(indentation, ' ') << pathName_ << "\n";
0073 }
0074
0075 void init(edm::ConsumesCollector& iC) override { token_ = iC.consumes<edm::PathStatus>(edm::InputTag(pathName_)); }
0076
0077 bool evaluate(edm::Event const& event) const override { return event.get(token_).accept(); }
0078
0079 private:
0080 std::string pathName_;
0081 edm::EDGetTokenT<edm::PathStatus> token_;
0082 };
0083
0084 class NotOperator : public Evaluator {
0085 public:
0086 EvaluatorType type() const override { return Not; }
0087
0088 void setLeft(std::unique_ptr<Evaluator>&& v) override { operand_ = std::move(v); }
0089
0090 void print(std::ostream& out, unsigned int indentation) const override {
0091 out << std::string(indentation, ' ') << "not\n";
0092 operand_->print(out, indentation + 4);
0093 }
0094
0095 void init(edm::ConsumesCollector& iC) override { operand_->init(iC); }
0096
0097 bool evaluate(edm::Event const& event) const override { return !operand_->evaluate(event); }
0098
0099 private:
0100 edm::propagate_const<std::unique_ptr<Evaluator>> operand_;
0101 };
0102
0103 template <typename T>
0104 class BinaryOperator : public Evaluator {
0105 public:
0106 EvaluatorType type() const override;
0107
0108 void setLeft(std::unique_ptr<Evaluator>&& v) override { left_ = std::move(v); }
0109 void setRight(std::unique_ptr<Evaluator>&& v) override { right_ = std::move(v); }
0110
0111 void print(std::ostream& out, unsigned int indentation) const override;
0112
0113 void init(edm::ConsumesCollector& iC) override {
0114 left_->init(iC);
0115 right_->init(iC);
0116 }
0117
0118 bool evaluate(edm::Event const& event) const override {
0119 T op;
0120 return op(left_->evaluate(event), right_->evaluate(event));
0121 }
0122
0123 private:
0124 edm::propagate_const<std::unique_ptr<Evaluator>> left_;
0125 edm::propagate_const<std::unique_ptr<Evaluator>> right_;
0126 };
0127
0128 template <>
0129 inline Evaluator::EvaluatorType BinaryOperator<std::logical_and<bool>>::type() const {
0130 return And;
0131 }
0132
0133 template <>
0134 inline Evaluator::EvaluatorType BinaryOperator<std::logical_or<bool>>::type() const {
0135 return Or;
0136 }
0137
0138 template <>
0139 void BinaryOperator<std::logical_and<bool>>::print(std::ostream& out, unsigned int indentation) const {
0140 out << std::string(indentation, ' ') << "and\n";
0141 left_->print(out, indentation + 4);
0142 right_->print(out, indentation + 4);
0143 }
0144 template <>
0145 void BinaryOperator<std::logical_or<bool>>::print(std::ostream& out, unsigned int indentation) const {
0146 out << std::string(indentation, ' ') << "or\n";
0147 left_->print(out, indentation + 4);
0148 right_->print(out, indentation + 4);
0149 }
0150
0151 using AndOperator = BinaryOperator<std::logical_and<bool>>;
0152 using OrOperator = BinaryOperator<std::logical_or<bool>>;
0153
0154 class BeginParenthesis : public Evaluator {
0155 public:
0156 EvaluatorType type() const override { return BeginParen; }
0157 };
0158
0159
0160
0161
0162
0163 class ShuntingYardAlgorithm {
0164 public:
0165 void addPathName(std::vector<char> const& s) {
0166 operandStack.push_back(std::make_unique<Operand>(s));
0167 pathNames_.emplace_back(s.begin(), s.end());
0168 }
0169
0170 void addOperatorNot() {
0171 if (operatorStack.empty() || operatorStack.back()->type() != Evaluator::Not) {
0172 operatorStack.push_back(std::make_unique<NotOperator>());
0173 } else {
0174
0175 operatorStack.pop_back();
0176 }
0177 }
0178
0179 void moveBinaryOperator() {
0180 std::unique_ptr<Evaluator>& backEvaluator = operatorStack.back();
0181 backEvaluator->setRight(std::move(operandStack.back()));
0182 operandStack.pop_back();
0183 backEvaluator->setLeft(std::move(operandStack.back()));
0184 operandStack.pop_back();
0185 operandStack.push_back(std::move(backEvaluator));
0186 operatorStack.pop_back();
0187 }
0188
0189 void moveNotOperator() {
0190 std::unique_ptr<Evaluator>& backEvaluator = operatorStack.back();
0191 backEvaluator->setLeft(std::move(operandStack.back()));
0192 operandStack.pop_back();
0193 operandStack.push_back(std::move(backEvaluator));
0194 operatorStack.pop_back();
0195 }
0196
0197 void addOperatorAnd() {
0198 while (!operatorStack.empty()) {
0199 std::unique_ptr<Evaluator>& backEvaluator = operatorStack.back();
0200 if (backEvaluator->type() == Evaluator::And) {
0201 moveBinaryOperator();
0202 } else if (backEvaluator->type() == Evaluator::Not) {
0203 moveNotOperator();
0204 } else {
0205 break;
0206 }
0207 }
0208 operatorStack.push_back(std::make_unique<AndOperator>());
0209 }
0210
0211 void addOperatorOr() {
0212 while (!operatorStack.empty()) {
0213 std::unique_ptr<Evaluator>& backEvaluator = operatorStack.back();
0214 if (backEvaluator->type() == Evaluator::And || backEvaluator->type() == Evaluator::Or) {
0215 moveBinaryOperator();
0216 } else if (backEvaluator->type() == Evaluator::Not) {
0217 moveNotOperator();
0218 } else {
0219 break;
0220 }
0221 }
0222 operatorStack.push_back(std::make_unique<OrOperator>());
0223 }
0224
0225 void addBeginParenthesis() { operatorStack.push_back(std::make_unique<BeginParenthesis>()); }
0226
0227 void addEndParenthesis() {
0228 while (!operatorStack.empty()) {
0229 std::unique_ptr<Evaluator>& backEvaluator = operatorStack.back();
0230 if (backEvaluator->type() == Evaluator::BeginParen) {
0231 operatorStack.pop_back();
0232 break;
0233 }
0234 if (backEvaluator->type() == Evaluator::And || backEvaluator->type() == Evaluator::Or) {
0235 moveBinaryOperator();
0236 } else if (backEvaluator->type() == Evaluator::Not) {
0237 moveNotOperator();
0238 }
0239 }
0240 }
0241
0242 std::unique_ptr<Evaluator> finish() {
0243 while (!operatorStack.empty()) {
0244 std::unique_ptr<Evaluator>& backEvaluator = operatorStack.back();
0245
0246
0247 if (backEvaluator->type() == Evaluator::BeginParen) {
0248 throw cms::Exception("LogicError") << "Should be impossible to get this error. Contact a Framework developer";
0249 }
0250 if (backEvaluator->type() == Evaluator::And || backEvaluator->type() == Evaluator::Or) {
0251 moveBinaryOperator();
0252 } else if (backEvaluator->type() == Evaluator::Not) {
0253 moveNotOperator();
0254 }
0255 }
0256
0257
0258 if (!operatorStack.empty() || operandStack.size() != 1U) {
0259 throw cms::Exception("LogicError") << "Should be impossible to get this error. Contact a Framework developer";
0260 }
0261 std::unique_ptr<Evaluator> temp = std::move(operandStack.back());
0262 operandStack.pop_back();
0263 return temp;
0264 }
0265
0266 const std::vector<std::string>& pathNames() { return pathNames_; }
0267
0268 private:
0269 std::vector<std::string> pathNames_;
0270 std::vector<std::unique_ptr<Evaluator>> operandStack;
0271 std::vector<std::unique_ptr<Evaluator>> operatorStack;
0272 };
0273
0274
0275 template <typename Iterator>
0276 class Grammar : public qi::grammar<Iterator, ascii::space_type> {
0277 public:
0278 Grammar(ShuntingYardAlgorithm* algorithm) : Grammar::base_type(expression), algorithm_(algorithm) {
0279
0280 auto addPathName = std::bind(&ShuntingYardAlgorithm::addPathName, algorithm_, std::placeholders::_1);
0281 auto addOperatorNot = std::bind(&ShuntingYardAlgorithm::addOperatorNot, algorithm_);
0282 auto addOperatorAnd = std::bind(&ShuntingYardAlgorithm::addOperatorAnd, algorithm_);
0283 auto addOperatorOr = std::bind(&ShuntingYardAlgorithm::addOperatorOr, algorithm_);
0284 auto addBeginParenthesis = std::bind(&ShuntingYardAlgorithm::addBeginParenthesis, algorithm_);
0285 auto addEndParenthesis = std::bind(&ShuntingYardAlgorithm::addEndParenthesis, algorithm_);
0286
0287
0288 pathName = !unaryOperator >> !binaryOperatorTest >> (+qi::char_("a-zA-Z0-9_"))[addPathName];
0289 binaryOperand = (qi::lit('(')[addBeginParenthesis] >> expression >> qi::lit(')')[addEndParenthesis]) |
0290 (unaryOperator[addOperatorNot] >> binaryOperand) | pathName;
0291 afterOperator = ascii::space | &qi::lit('(') | &qi::eoi;
0292 unaryOperator = qi::lit("not") >> afterOperator;
0293
0294 binaryOperatorTest = (qi::lit("and") >> afterOperator) | (qi::lit("or") >> afterOperator);
0295 binaryOperator =
0296 (qi::lit("and") >> afterOperator)[addOperatorAnd] | (qi::lit("or") >> afterOperator)[addOperatorOr];
0297 expression = binaryOperand % binaryOperator;
0298 }
0299
0300 private:
0301 qi::rule<Iterator> pathName;
0302 qi::rule<Iterator, ascii::space_type> binaryOperand;
0303 qi::rule<Iterator> afterOperator;
0304 qi::rule<Iterator> unaryOperator;
0305 qi::rule<Iterator> binaryOperatorTest;
0306 qi::rule<Iterator> binaryOperator;
0307 qi::rule<Iterator, ascii::space_type> expression;
0308
0309 ShuntingYardAlgorithm* algorithm_;
0310 };
0311 }
0312
0313 using namespace l1t;
0314
0315 class L1GTAlgoBlockProducer
0316 : public edm::one::EDProducer<edm::RunCache<std::unordered_map<std::string, unsigned int>>> {
0317 public:
0318 explicit L1GTAlgoBlockProducer(const edm::ParameterSet&);
0319 ~L1GTAlgoBlockProducer() override = default;
0320
0321 static void fillDescriptions(edm::ConfigurationDescriptions&);
0322
0323 private:
0324 struct AlgoDefinition {
0325 edm::propagate_const<std::unique_ptr<pathStatusExpression::Evaluator>> evaluator_;
0326 std::vector<std::string> pathNames_;
0327 std::set<std::tuple<std::string, std::string>> filtModules_;
0328 unsigned int prescale_;
0329 unsigned int prescalePreview_;
0330 std::set<unsigned int> bunchMask_;
0331 bool isVeto_;
0332 int triggerTypes_;
0333 };
0334
0335 void init(const edm::ProcessHistory&);
0336 void produce(edm::Event&, const edm::EventSetup&) override;
0337 std::shared_ptr<std::unordered_map<std::string, unsigned int>> globalBeginRun(edm::Run const&,
0338 edm::EventSetup const&) const override;
0339
0340 void globalEndRun(edm::Run const&, edm::EventSetup const&) override {}
0341
0342 edm::GetterOfProducts<P2GTCandidateVectorRef> getterOfPassedReferences_;
0343 std::map<std::string, AlgoDefinition> algoDefinitions_;
0344 bool initialized_ = false;
0345 int bunchCrossingEmu_ = 0;
0346 };
0347
0348 void L1GTAlgoBlockProducer::fillDescriptions(edm::ConfigurationDescriptions& description) {
0349 edm::ParameterSetDescription algoDesc;
0350 algoDesc.add<std::string>("name", "");
0351 algoDesc.add<std::string>("expression");
0352 algoDesc.add<double>("prescale", 1);
0353 algoDesc.add<double>("prescalePreview", 1);
0354 algoDesc.add<std::vector<unsigned int>>("bunchMask", {});
0355
0356 algoDesc.add<std::vector<int>>("triggerTypes", {1});
0357 algoDesc.add<bool>("veto", false);
0358
0359 edm::ParameterSetDescription desc;
0360 desc.addVPSet("algorithms", algoDesc);
0361
0362 description.addWithDefaultLabel(desc);
0363 }
0364
0365 L1GTAlgoBlockProducer::L1GTAlgoBlockProducer(const edm::ParameterSet& config)
0366 : getterOfPassedReferences_(edm::TypeMatch(), this) {
0367 edm::ConsumesCollector iC(consumesCollector());
0368
0369 for (const auto& algoConfig : config.getParameterSetVector("algorithms")) {
0370 const std::string logicalExpression = algoConfig.getParameter<std::string>("expression");
0371 std::string name = algoConfig.getParameter<std::string>("name");
0372 if (name.empty()) {
0373 name = logicalExpression;
0374 }
0375
0376 pathStatusExpression::ShuntingYardAlgorithm shuntingYardAlgorithm;
0377 pathStatusExpression::Grammar<std::string::const_iterator> grammar(&shuntingYardAlgorithm);
0378
0379 auto it = logicalExpression.cbegin();
0380 if (!qi::phrase_parse(it, logicalExpression.cend(), grammar, ascii::space) || (it != logicalExpression.cend())) {
0381 throw cms::Exception("Configuration") << "Syntax error in logical expression. Here is an example of how\n"
0382 << "the syntax should look:\n"
0383 << " \"path1 and not (path2 or not path3)\"\n"
0384 << "The expression must contain alternating appearances of operands\n"
0385 << "which are path names and binary operators which can be \'and\'\n"
0386 << "or \'or\', with a path name at the beginning and end. There\n"
0387 << "must be at least one path name. In addition to the alternating\n"
0388 << "path names and binary operators, the unary operator \'not\' can\n"
0389 << "be inserted before a path name or a begin parenthesis.\n"
0390 << "Parentheses are allowed. Parentheses must come in matching pairs.\n"
0391 << "Matching begin and end parentheses must contain a complete and\n"
0392 << "syntactically correct logical expression. There must be at least\n"
0393 << "one space or parenthesis between operators and path names. Extra\n"
0394 << "space is ignored and OK. Path names can only contain upper and\n"
0395 << "lower case letters, numbers, and underscores. A path name cannot\n"
0396 << "be the same as an operator name.\n";
0397 }
0398
0399 AlgoDefinition definition;
0400
0401 for (const std::string& pathName : shuntingYardAlgorithm.pathNames()) {
0402 definition.pathNames_.push_back(pathName);
0403 }
0404
0405 definition.evaluator_ = shuntingYardAlgorithm.finish();
0406 double dPrescale = algoConfig.getParameter<double>("prescale");
0407 if ((dPrescale < 1. || dPrescale >= std::pow(2, 24) / 100 - 1) && dPrescale != 0) {
0408 throw cms::Exception("Configuration")
0409 << "Prescale value error. Expected prescale value between 1 and 2^24/100 - 1 or 0 got " << dPrescale << "."
0410 << std::endl;
0411 }
0412
0413 definition.prescale_ = std::round(dPrescale * 100);
0414
0415 double dPrescalePreview = algoConfig.getParameter<double>("prescalePreview");
0416 if ((dPrescalePreview < 1. || dPrescalePreview >= std::pow(2, 24) / 100 - 1) && dPrescalePreview != 0) {
0417 throw cms::Exception("Configuration")
0418 << "PrescalePreview value error. Expected prescale value between 1 and 2^24/100 - 1 or 0 got "
0419 << dPrescalePreview << "." << std::endl;
0420 }
0421
0422 definition.prescalePreview_ = std::round(dPrescalePreview * 100);
0423
0424 std::vector<unsigned int> vBunchMask = algoConfig.getParameter<std::vector<unsigned int>>("bunchMask");
0425 definition.bunchMask_ =
0426 std::set<unsigned int>(std::make_move_iterator(vBunchMask.begin()), std::make_move_iterator(vBunchMask.end()));
0427
0428 definition.isVeto_ = algoConfig.getParameter<bool>("veto");
0429 definition.triggerTypes_ = 0;
0430 const std::vector<int> triggerTypes = algoConfig.getParameter<std::vector<int>>("triggerTypes");
0431 for (int type : triggerTypes) {
0432 definition.triggerTypes_ |= type;
0433 }
0434
0435 definition.evaluator_->init(iC);
0436 auto [iter, wasInserted] = algoDefinitions_.emplace(std::move(name), std::move(definition));
0437 if (!wasInserted) {
0438 throw cms::Exception("Configuration")
0439 << "Algorithm " << iter->first << " already exists. Algorithm names must be unique." << std::endl;
0440 }
0441 }
0442
0443 callWhenNewProductsRegistered(getterOfPassedReferences_);
0444 produces<P2GTAlgoBlockMap>();
0445 }
0446
0447 void L1GTAlgoBlockProducer::init(const edm::ProcessHistory& pHistory) {
0448 const std::string& pName = edm::Service<edm::service::TriggerNamesService>()->getProcessName();
0449
0450 edm::ProcessConfiguration cfg;
0451
0452 pHistory.getConfigurationForProcess(pName, cfg);
0453
0454 const edm::ParameterSet* pset = edm::pset::Registry::instance()->getMapped(cfg.parameterSetID());
0455
0456 for (auto& [name, algoDef] : algoDefinitions_) {
0457 for (const std::string& pathName : algoDef.pathNames_) {
0458 if (pset->existsAs<std::vector<std::string>>(pathName)) {
0459 const auto& modules = pset->getParameter<std::vector<std::string>>(pathName);
0460 for (const auto& mod : modules) {
0461 if (mod.front() != std::string("-") && pset->exists(mod)) {
0462 const auto& modPSet = pset->getParameterSet(mod);
0463 if (modPSet.getParameter<std::string>("@module_edm_type") == "EDFilter") {
0464 if (modPSet.getParameter<std::string>("@module_type") == "L1GTSingleObjectCond") {
0465 algoDef.filtModules_.insert({mod, modPSet.getParameter<edm::InputTag>("tag").instance()});
0466 } else if (modPSet.getParameter<std::string>("@module_type") == "L1GTDoubleObjectCond") {
0467 algoDef.filtModules_.insert(
0468 {mod, modPSet.getParameterSet("collection1").getParameter<edm::InputTag>("tag").instance()});
0469 algoDef.filtModules_.insert(
0470 {mod, modPSet.getParameterSet("collection2").getParameter<edm::InputTag>("tag").instance()});
0471 } else if (modPSet.getParameter<std::string>("@module_type") == "L1GTTripleObjectCond") {
0472 algoDef.filtModules_.insert(
0473 {mod, modPSet.getParameterSet("collection1").getParameter<edm::InputTag>("tag").instance()});
0474 algoDef.filtModules_.insert(
0475 {mod, modPSet.getParameterSet("collection2").getParameter<edm::InputTag>("tag").instance()});
0476 algoDef.filtModules_.insert(
0477 {mod, modPSet.getParameterSet("collection3").getParameter<edm::InputTag>("tag").instance()});
0478 } else if (modPSet.getParameter<std::string>("@module_type") == "L1GTQuadObjectCond") {
0479 algoDef.filtModules_.insert(
0480 {mod, modPSet.getParameterSet("collection1").getParameter<edm::InputTag>("tag").instance()});
0481 algoDef.filtModules_.insert(
0482 {mod, modPSet.getParameterSet("collection2").getParameter<edm::InputTag>("tag").instance()});
0483 algoDef.filtModules_.insert(
0484 {mod, modPSet.getParameterSet("collection3").getParameter<edm::InputTag>("tag").instance()});
0485 algoDef.filtModules_.insert(
0486 {mod, modPSet.getParameterSet("collection4").getParameter<edm::InputTag>("tag").instance()});
0487 }
0488 }
0489 }
0490 }
0491 }
0492 }
0493 }
0494 }
0495
0496 std::shared_ptr<std::unordered_map<std::string, unsigned int>> L1GTAlgoBlockProducer::globalBeginRun(
0497 edm::Run const&, edm::EventSetup const&) const {
0498
0499 return std::make_shared<std::unordered_map<std::string, unsigned int>>();
0500 }
0501
0502 void L1GTAlgoBlockProducer::produce(edm::Event& event, const edm::EventSetup& eventSetup) {
0503 if (!initialized_) {
0504 init(event.processHistory());
0505 initialized_ = true;
0506 }
0507
0508 std::vector<edm::Handle<P2GTCandidateVectorRef>> handles;
0509 getterOfPassedReferences_.fillHandles(event, handles);
0510
0511 std::unique_ptr<P2GTAlgoBlockMap> algoCollection = std::make_unique<P2GTAlgoBlockMap>();
0512
0513 std::unordered_map<std::string, unsigned int>& prescaleCounters = *runCache(event.getRun().index());
0514
0515 int bunchCrossing = event.isRealData() ? event.bunchCrossing() : bunchCrossingEmu_ + 1;
0516
0517 for (const auto& [name, algoDef] : algoDefinitions_) {
0518 bool decisionBeforeBxAndPrescale = algoDef.evaluator_->evaluate(event);
0519 bool decisionBeforePrescale = decisionBeforeBxAndPrescale && algoDef.bunchMask_.count(bunchCrossing) == 0;
0520 bool decisionFinal = false;
0521 bool decisionFinalPreview = false;
0522
0523 if (algoDef.prescale_ != 0 && decisionBeforePrescale) {
0524 if (prescaleCounters.count(name) > 0) {
0525 prescaleCounters[name] += 100;
0526 } else {
0527 prescaleCounters[name] = 100;
0528 }
0529
0530 if (prescaleCounters[name] >= algoDef.prescale_) {
0531 decisionFinal = true;
0532 prescaleCounters[name] -= algoDef.prescale_;
0533 } else {
0534 decisionFinal = false;
0535 }
0536 }
0537
0538 if (algoDef.prescalePreview_ != 0 && decisionBeforePrescale) {
0539 std::string previewName = name + "_preview";
0540 if (prescaleCounters.count(previewName) > 0) {
0541 prescaleCounters[previewName] += 100;
0542 } else {
0543 prescaleCounters[previewName] = 100;
0544 }
0545
0546 if (prescaleCounters[previewName] >= algoDef.prescalePreview_) {
0547 decisionFinalPreview = true;
0548 prescaleCounters[previewName] -= algoDef.prescalePreview_;
0549 } else {
0550 decisionFinalPreview = false;
0551 }
0552 }
0553
0554 P2GTCandidateVectorRef trigObjects;
0555
0556 if (decisionFinal) {
0557 for (const auto& handle : handles) {
0558 const std::string& module = handle.provenance()->moduleLabel();
0559 const std::string& instance = handle.provenance()->productInstanceName();
0560
0561 if (algoDef.filtModules_.count({module, instance}) > 0) {
0562 trigObjects.insert(trigObjects.end(), handle->begin(), handle->end());
0563 }
0564 }
0565 }
0566
0567 algoCollection->emplace(name,
0568 P2GTAlgoBlock(decisionBeforeBxAndPrescale,
0569 decisionBeforePrescale,
0570 decisionFinal,
0571 decisionFinalPreview,
0572 algoDef.isVeto_,
0573 algoDef.triggerTypes_,
0574 std::move(trigObjects)));
0575 }
0576
0577 event.put(std::move(algoCollection));
0578
0579 bunchCrossingEmu_ = (bunchCrossingEmu_ + 1) % 3564;
0580 }
0581
0582 DEFINE_FWK_MODULE(L1GTAlgoBlockProducer);