diff --git a/HLTrigger/HLTcore/interface/FractionalPrescale.h b/HLTrigger/HLTcore/interface/FractionalPrescale.h new file mode 100644 index 0000000000000..b6a8dbb97731a --- /dev/null +++ b/HLTrigger/HLTcore/interface/FractionalPrescale.h @@ -0,0 +1,7 @@ +#ifndef HLTrigger_HLTcore_FractionalPrescale_h +#define HLTrigger_HLTcore_FractionalPrescale_h + +#include +using FractionalPrescale = boost::rational; + +#endif diff --git a/HLTrigger/HLTcore/interface/HLTConfigProvider.h b/HLTrigger/HLTcore/interface/HLTConfigProvider.h index 610299d4258ae..fdd303a278146 100644 --- a/HLTrigger/HLTcore/interface/HLTConfigProvider.h +++ b/HLTrigger/HLTcore/interface/HLTConfigProvider.h @@ -16,6 +16,7 @@ #include "FWCore/Framework/interface/LuminosityBlock.h" #include "HLTrigger/HLTcore/interface/HLTConfigData.h" +#include "HLTrigger/HLTcore/interface/FractionalPrescale.h" #include #include @@ -183,7 +184,13 @@ class HLTConfigProvider { /// Number of HLT prescale sets unsigned int prescaleSize() const { return hltConfigData_->prescaleSize(); } /// HLT prescale value in specific prescale set for a specific trigger path - unsigned int prescaleValue(unsigned int set, const std::string& trigger) const { + template + T prescaleValue(unsigned int set, const std::string& trigger) const { + //limit to only 4 allowed types + static_assert(std::is_same_v or std::is_same_v or std::is_same_v or + std::is_same_v, + "Please use prescaleValue, prescaleValue, prescaleValue, or " + "prescaleValue,\n note int and unsigned int will be depreated soon"); return hltConfigData_->prescaleValue(set, trigger); } diff --git a/HLTrigger/HLTcore/interface/HLTPrescaleProvider.h b/HLTrigger/HLTcore/interface/HLTPrescaleProvider.h index 6744907cdff95..1c59175548269 100644 --- a/HLTrigger/HLTcore/interface/HLTPrescaleProvider.h +++ b/HLTrigger/HLTcore/interface/HLTPrescaleProvider.h @@ -15,6 +15,7 @@ * function calls were added. W. David Dagenhart */ +#include "HLTrigger/HLTcore/interface/FractionalPrescale.h" #include "HLTrigger/HLTcore/interface/HLTConfigProvider.h" #include "L1Trigger/GlobalTriggerAnalyzer/interface/L1GtUtils.h" #include "L1Trigger/L1TGlobal/interface/L1TGlobalUtil.h" @@ -58,25 +59,53 @@ class HLTPrescaleProvider { // negative == error /// combining the two methods above - unsigned int prescaleValue(const edm::Event& iEvent, const edm::EventSetup& iSetup, const std::string& trigger); + template + T prescaleValue(const edm::Event& iEvent, const edm::EventSetup& iSetup, const std::string& trigger) { + const int set(prescaleSet(iEvent, iSetup)); + //there is a template specialisation for unsigned in which returns +1 which + //emulates old behaviour + return set < 0 ? -1 : hltConfigProvider_.prescaleValue(static_cast(set), trigger); + } /// Combined L1T (pair.first) and HLT (pair.second) prescales per HLT path - std::pair prescaleValues(const edm::Event& iEvent, - const edm::EventSetup& iSetup, - const std::string& trigger); + template + std::pair prescaleValues(const edm::Event& iEvent, + const edm::EventSetup& iSetup, + const std::string& trigger) { + return {convertL1PS(getL1PrescaleValue(iEvent, iSetup, trigger)), + prescaleValue(iEvent, iSetup, trigger)}; + } // any one negative => error in retrieving this (L1T or HLT) prescale // In case of a complex Boolean expression as L1 seed - std::pair >, int> prescaleValuesInDetail(const edm::Event& iEvent, - const edm::EventSetup& iSetup, - const std::string& trigger); + template + std::pair >, THLT> prescaleValuesInDetail(const edm::Event& iEvent, + const edm::EventSetup& iSetup, + const std::string& trigger) { + std::pair >, THLT> retval; + for (auto& entry : getL1PrescaleValueInDetail(iEvent, iSetup, trigger)) { + retval.first.emplace_back(std::move(entry.first), convertL1PS(entry.second)); + } + retval.second = prescaleValue(iEvent, iSetup, trigger); + return retval; + } // Event rejected by HLTPrescaler on ith HLT path? bool rejectedByHLTPrescaler(const edm::TriggerResults& triggerResults, unsigned int i) const; + static int l1PrescaleDenominator() { return kL1PrescaleDenominator_; } private: void checkL1GtUtils() const; void checkL1TGlobalUtil() const; + template + T convertL1PS(double val) const { + return T(val); + } + double getL1PrescaleValue(const edm::Event& iEvent, const edm::EventSetup& iSetup, const std::string& trigger); + std::vector > getL1PrescaleValueInDetail(const edm::Event& iEvent, + const edm::EventSetup& iSetup, + const std::string& trigger); + static constexpr int kL1PrescaleDenominator_ = 100; HLTConfigProvider hltConfigProvider_; std::unique_ptr l1GtUtils_; std::unique_ptr l1tGlobalUtil_; @@ -97,4 +126,13 @@ HLTPrescaleProvider::HLTPrescaleProvider(edm::ParameterSet const& pset, edm::Con l1tGlobalUtil_ = std::make_unique(pset, iC, module, l1t::UseEventSetupIn::Run); } } + +template <> +FractionalPrescale HLTPrescaleProvider::convertL1PS(double val) const; + +template <> +unsigned int HLTPrescaleProvider::prescaleValue(const edm::Event& iEvent, + const edm::EventSetup& iSetup, + const std::string& trigger); + #endif diff --git a/HLTrigger/HLTcore/plugins/HLTPrescaleExample.cc b/HLTrigger/HLTcore/plugins/HLTPrescaleExample.cc new file mode 100644 index 0000000000000..508016066f039 --- /dev/null +++ b/HLTrigger/HLTcore/plugins/HLTPrescaleExample.cc @@ -0,0 +1,71 @@ + +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "HLTrigger/HLTcore/interface/HLTPrescaleProvider.h" +#include + +class HLTPrescaleExample : public edm::one::EDAnalyzer { +public: + HLTPrescaleExample(edm::ParameterSet const& iPSet); + + void beginJob() override {} + void beginRun(edm::Run const& iEvent, edm::EventSetup const&) override; + void analyze(edm::Event const& iEvent, edm::EventSetup const&) override; + void endRun(edm::Run const& iEvent, edm::EventSetup const&) override {} + void endJob() override {} + +private: + HLTPrescaleProvider hltPSProvider_; + std::string hltProcess_; + std::string hltPath_; +}; + +HLTPrescaleExample::HLTPrescaleExample(edm::ParameterSet const& iPSet) + : hltPSProvider_(iPSet.getParameter("hltPSProvCfg"), consumesCollector(), *this), + hltProcess_(iPSet.getParameter("hltProcess")), + hltPath_(iPSet.getParameter("hltPath")) {} + +void HLTPrescaleExample::beginRun(edm::Run const& iRun, edm::EventSetup const& iSetup) { + bool changed = false; + hltPSProvider_.init(iRun, iSetup, hltProcess_, changed); +} + +void HLTPrescaleExample::analyze(edm::Event const& iEvent, edm::EventSetup const& iSetup) { + auto hltPSDouble = hltPSProvider_.prescaleValue(iEvent, iSetup, hltPath_); + auto hltPSInt = hltPSProvider_.prescaleValue(iEvent, iSetup, hltPath_); + auto hltPSUInt = hltPSProvider_.prescaleValue(iEvent, iSetup, hltPath_); + auto hltPSFrac = hltPSProvider_.prescaleValue(iEvent, iSetup, hltPath_); + + auto l1HLTPSDouble = hltPSProvider_.prescaleValues(iEvent, iSetup, hltPath_); + auto l1HLTPSInt = hltPSProvider_.prescaleValues(iEvent, iSetup, hltPath_); + auto l1HLTPSFrac = hltPSProvider_.prescaleValues(iEvent, iSetup, hltPath_); + auto l1HLTPSDoubleFrac = hltPSProvider_.prescaleValues(iEvent, iSetup, hltPath_); + + auto l1HLTDetailPSDouble = hltPSProvider_.prescaleValuesInDetail(iEvent, iSetup, hltPath_); + auto l1HLTDetailPSInt = hltPSProvider_.prescaleValuesInDetail(iEvent, iSetup, hltPath_); + auto l1HLTDetailPSFrac = hltPSProvider_.prescaleValuesInDetail(iEvent, iSetup, hltPath_); + + std::cout << "---------Begin Event--------" << std::endl; + std::cout << "hltDouble " << hltPSDouble << " hltInt " << hltPSInt << " hltPSUInt " << hltPSUInt << " hltFrac " + << hltPSFrac << std::endl; + + std::cout << " l1HLTDouble " << l1HLTPSDouble.first << " " << l1HLTPSDouble.second << " l1HLTInt " << l1HLTPSInt.first + << " " << l1HLTPSInt.second << " l1HLTFrac " << l1HLTPSFrac.first << " " << l1HLTPSFrac.second + << " l1HLTDoubleFrac " << l1HLTPSDoubleFrac.first << " " << l1HLTPSDoubleFrac.second << std::endl; + auto printL1HLTDetail = [](const std::string& text, const auto& val, std::ostream& out) { + out << text; + for (const auto& entry : val.first) { + out << entry.first << ":" << entry.second << " "; + } + out << " HLT : " << val.second << std::endl; + }; + + printL1HLTDetail("l1HLTDetailDouble ", l1HLTDetailPSDouble, std::cout); + printL1HLTDetail("l1HLTDetailInt ", l1HLTDetailPSInt, std::cout); + printL1HLTDetail("l1HLTDetailFrac ", l1HLTDetailPSFrac, std::cout); + std::cout << "---------End Event--------" << std::endl << std::endl; +} + +DEFINE_FWK_MODULE(HLTPrescaleExample); diff --git a/HLTrigger/HLTcore/src/HLTPrescaleProvider.cc b/HLTrigger/HLTcore/src/HLTPrescaleProvider.cc index 7c021e8a669c4..176bb1b1d0ceb 100644 --- a/HLTrigger/HLTcore/src/HLTPrescaleProvider.cc +++ b/HLTrigger/HLTcore/src/HLTPrescaleProvider.cc @@ -102,46 +102,39 @@ int HLTPrescaleProvider::prescaleSet(const edm::Event& iEvent, const edm::EventS } } -unsigned int HLTPrescaleProvider::prescaleValue(const edm::Event& iEvent, - const edm::EventSetup& iSetup, - const std::string& trigger) { - const int set(prescaleSet(iEvent, iSetup)); - if (set < 0) { - return 1; - } else { - return hltConfigProvider_.prescaleValue(static_cast(set), trigger); +template <> +FractionalPrescale HLTPrescaleProvider::convertL1PS(double val) const { + int numer = static_cast(val * kL1PrescaleDenominator_ + 0.5); + static constexpr double kL1RoundingEpsilon = 0.001; + if (std::abs(numer - val * kL1PrescaleDenominator_) > kL1RoundingEpsilon) { + edm::LogWarning("ValueError") << " Error, L1 prescale val " << val + << "does not appear to precisely expressable as int / " << kL1PrescaleDenominator_ + << ", using a FractionalPrescale is a loss of precision"; } -} -std::pair HLTPrescaleProvider::prescaleValues(const edm::Event& iEvent, - const edm::EventSetup& iSetup, - const std::string& trigger) { - // start with setting both L1T and HLT prescale values to 0 - std::pair result(std::pair(0, 0)); - - // get HLT prescale (possible if HLT prescale set index is correctly found) - const int set(prescaleSet(iEvent, iSetup)); - if (set < 0) { - result.second = -1; - } else { - result.second = static_cast(hltConfigProvider_.prescaleValue(static_cast(set), trigger)); - } + return {numer, kL1PrescaleDenominator_}; +} +double HLTPrescaleProvider::getL1PrescaleValue(const edm::Event& iEvent, + const edm::EventSetup& iSetup, + const std::string& trigger) { // get L1T prescale - works only for those hlt trigger paths with // exactly one L1GT seed module which has exactly one L1T name as seed + double result = -1; + const unsigned int l1tType(hltConfigProvider_.l1tType()); if (l1tType == 1) { checkL1GtUtils(); const unsigned int nL1GTSeedModules(hltConfigProvider_.hltL1GTSeeds(trigger).size()); if (nL1GTSeedModules == 0) { // no L1 seed module on path hence no L1 seed hence formally no L1 prescale - result.first = 1; + result = 1; } else if (nL1GTSeedModules == 1) { l1GtUtils_->getL1GtRunCache(iEvent, iSetup, useL1EventSetup, useL1GtTriggerMenuLite); const std::string l1tname(hltConfigProvider_.hltL1GTSeeds(trigger).at(0).second); int l1error(0); - result.first = l1GtUtils_->prescaleFactor(iEvent, l1tname, l1error); + result = l1GtUtils_->prescaleFactor(iEvent, l1tname, l1error); if (l1error != 0) { if (count_[1] < countMax) { count_[1] += 1; @@ -154,7 +147,7 @@ std::pair HLTPrescaleProvider::prescaleValues(const edm::Event& iEvent << " For seeds being complex logical expressions, try the new method 'prescaleValuesInDetail'." << std::endl; } - result.first = -1; + result = -1; } } else { /// error - can't handle properly multiple L1GTSeed modules @@ -169,18 +162,18 @@ std::pair HLTPrescaleProvider::prescaleValues(const edm::Event& iEvent << nL1GTSeedModules << ", with L1 seeds: " << dump << ". (Note: at most one L1GTSeed module is allowed for a proper determination of the L1T prescale!)"; } - result.first = -1; + result = -1; } } else if (l1tType == 2) { checkL1TGlobalUtil(); const unsigned int nL1TSeedModules(hltConfigProvider_.hltL1TSeeds(trigger).size()); if (nL1TSeedModules == 0) { // no L1 seed module on path hence no L1 seed hence formally no L1 prescale - result.first = 1; + result = 1; } else if (nL1TSeedModules == 1) { // l1tGlobalUtil_->retrieveL1Event(iEvent,iSetup); const std::string l1tname(hltConfigProvider_.hltL1TSeeds(trigger).at(0)); - bool l1error(!l1tGlobalUtil_->getPrescaleByName(l1tname, result.first)); + bool l1error(!l1tGlobalUtil_->getPrescaleByName(l1tname, result)); if (l1error) { if (count_[1] < countMax) { count_[1] += 1; @@ -193,7 +186,7 @@ std::pair HLTPrescaleProvider::prescaleValues(const edm::Event& iEvent << " For seeds being complex logical expressions, try the new method 'prescaleValuesInDetail'." << std::endl; } - result.first = -1; + result = -1; } } else { /// error - can't handle properly multiple L1TSeed modules @@ -208,34 +201,22 @@ std::pair HLTPrescaleProvider::prescaleValues(const edm::Event& iEvent << nL1TSeedModules << ", with L1T seeds: " << dump << ". (Note: at most one L1TSeed module is allowed for a proper determination of the L1T prescale!)"; } - result.first = -1; + result = -1; } } else { if (count_[1] < countMax) { count_[1] += 1; edm::LogError("HLTPrescaleProvider") << " Unknown L1T Type " << l1tType << " - can not determine L1T prescale! "; } - result.first = -1; + result = -1; } return result; } -std::pair >, int> HLTPrescaleProvider::prescaleValuesInDetail( +std::vector > HLTPrescaleProvider::getL1PrescaleValueInDetail( const edm::Event& iEvent, const edm::EventSetup& iSetup, const std::string& trigger) { - std::pair >, int> result; - result.first.clear(); - - // get HLT prescale (possible if HLT prescale set index is correctly found) - const int set(prescaleSet(iEvent, iSetup)); - if (set < 0) { - result.second = -1; - } else { - result.second = static_cast(hltConfigProvider_.prescaleValue(static_cast(set), trigger)); - } - - // get L1T prescale - works only for those hlt trigger paths with - // exactly one L1GT seed module + std::vector > result; const unsigned int l1tType(hltConfigProvider_.l1tType()); if (l1tType == 1) { @@ -244,14 +225,19 @@ std::pair >, int> HLTPrescaleProvider::p const unsigned int nL1GTSeedModules(hltConfigProvider_.hltL1GTSeeds(trigger).size()); if (nL1GTSeedModules == 0) { // no L1 seed module on path hence no L1 seed hence formally no L1 prescale - result.first.clear(); + result.clear(); } else if (nL1GTSeedModules == 1) { l1GtUtils_->getL1GtRunCache(iEvent, iSetup, useL1EventSetup, useL1GtTriggerMenuLite); const std::string l1tname(hltConfigProvider_.hltL1GTSeeds(trigger).at(0).second); L1GtUtils::LogicalExpressionL1Results l1Logical(l1tname, *l1GtUtils_); l1Logical.logicalExpressionRunUpdate(iEvent.getRun(), iSetup, l1tname); const std::vector >& errorCodes(l1Logical.errorCodes(iEvent)); - result.first = l1Logical.prescaleFactors(); + auto resultInt = l1Logical.prescaleFactors(); + result.clear(); + for (const auto& entry : resultInt) { + result.push_back(entry); + } + int l1error(l1Logical.isValid() ? 0 : 1); for (auto const& errorCode : errorCodes) { l1error += std::abs(errorCode.second); @@ -264,13 +250,12 @@ std::pair >, int> HLTPrescaleProvider::p << l1tname << "' using L1GtUtils: " << std::endl << " isValid=" << l1Logical.isValid() << " l1tname/error/prescale " << errorCodes.size() << std::endl; for (unsigned int i = 0; i < errorCodes.size(); ++i) { - message << " " << i << ":" << errorCodes[i].first << "/" << errorCodes[i].second << "/" - << result.first[i].second; + message << " " << i << ":" << errorCodes[i].first << "/" << errorCodes[i].second << "/" << result[i].second; } message << "."; edm::LogError("HLTPrescaleProvider") << message.str(); } - result.first.clear(); + result.clear(); } } else { /// error - can't handle properly multiple L1GTSeed modules @@ -285,14 +270,14 @@ std::pair >, int> HLTPrescaleProvider::p << nL1GTSeedModules << ", with L1 seeds: " << dump << ". (Note: at most one L1GTSeed module is allowed for a proper determination of the L1T prescale!)"; } - result.first.clear(); + result.clear(); } } else if (l1tType == 2) { checkL1TGlobalUtil(); const unsigned int nL1TSeedModules(hltConfigProvider_.hltL1TSeeds(trigger).size()); if (nL1TSeedModules == 0) { // no L1 seed module on path hence no L1 seed hence formally no L1 prescale - result.first.clear(); + result.clear(); } else if (nL1TSeedModules == 1) { // l1tGlobalUtil_->retrieveL1Event(iEvent,iSetup); std::string l1tname(hltConfigProvider_.hltL1TSeeds(trigger).at(0)); @@ -305,7 +290,7 @@ std::pair >, int> HLTPrescaleProvider::p if (!l1tGlobalUtil_->getPrescaleByName(l1tSeed, l1tPrescale)) { l1error += 1; } - result.first.push_back(std::pair(l1tSeed, l1tPrescale)); + result.push_back(std::pair(l1tSeed, l1tPrescale)); } if (l1error != 0) { if (count_[3] < countMax) { @@ -319,12 +304,12 @@ std::pair >, int> HLTPrescaleProvider::p for (unsigned int i = 0; i < l1tSeeds.size(); ++i) { const string& l1tSeed = l1tSeeds[i].tokenName; message << " " << i << ":" << l1tSeed << "/" << l1tGlobalUtil_->getPrescaleByName(l1tSeed, l1tPrescale) - << "/" << result.first[i].second; + << "/" << result[i].second; } message << "."; edm::LogError("HLTPrescaleProvider") << message.str(); } - result.first.clear(); + result.clear(); } } else { /// error - can't handle properly multiple L1TSeed modules @@ -339,14 +324,14 @@ std::pair >, int> HLTPrescaleProvider::p << nL1TSeedModules << ", with L1T seeds: " << dump << ". (Note: at most one L1TSeed module is allowed for a proper determination of the L1T prescale!)"; } - result.first.clear(); + result.clear(); } } else { if (count_[3] < countMax) { count_[3] += 1; edm::LogError("HLTPrescaleProvider") << " Unknown L1T Type " << l1tType << " - can not determine L1T prescale! "; } - result.first.clear(); + result.clear(); } return result; @@ -375,3 +360,11 @@ void HLTPrescaleProvider::checkL1TGlobalUtil() const { "or input is from mixed eras"; } } + +template <> +unsigned int HLTPrescaleProvider::prescaleValue(const edm::Event& iEvent, + const edm::EventSetup& iSetup, + const std::string& trigger) { + const int set(prescaleSet(iEvent, iSetup)); + return set < 0 ? 1 : hltConfigProvider_.prescaleValue(static_cast(set), trigger); +} diff --git a/HLTrigger/HLTcore/test/hltPrescaleExample_cfg.py b/HLTrigger/HLTcore/test/hltPrescaleExample_cfg.py new file mode 100644 index 0000000000000..7ef175aaac1c4 --- /dev/null +++ b/HLTrigger/HLTcore/test/hltPrescaleExample_cfg.py @@ -0,0 +1,54 @@ + +import FWCore.ParameterSet.Config as cms +process = cms.Process("HLTPSCheck") + +import FWCore.ParameterSet.VarParsing as VarParsing +options = VarParsing.VarParsing ('analysis') +options.register('globalTag','auto:run2_data',options.multiplicity.singleton,options.varType.string,"global tag to use") +options.parseArguments() + +print options.inputFiles +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring(options.inputFiles), + ) + +# initialize MessageLogger and output report +process.load("FWCore.MessageLogger.MessageLogger_cfi") +process.MessageLogger.cerr.FwkReport = cms.untracked.PSet( + reportEvery = cms.untracked.int32(5000), + limit = cms.untracked.int32(10000000) +) + +process.options = cms.untracked.PSet( wantSummary = cms.untracked.bool(False) ) + + +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, options.globalTag, '') + + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(options.maxEvents) +) + + +process.hltPSExample = cms.EDAnalyzer("HLTPrescaleExample", + hltProcess=cms.string("HLT"), +# hltPath=cms.string("HLT_Photon50_v13"), + hltPath=cms.string("HLT_Photon33_v5"), + hltPSProvCfg=cms.PSet( + stageL1Trigger = cms.uint32(2) + ) + ) + + +process.p = cms.Path( + process.hltPSExample +) + + + +print "global tag: ",process.GlobalTag.globaltag + + +