Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:18:26

0001 /** \class HLTPrescaleProvider
0002  *
0003  * See header file for documentation
0004  *
0005  *
0006  *  \author Martin Grunewald
0007  *
0008  */
0009 
0010 #include "HLTrigger/HLTcore/interface/HLTPrescaleProvider.h"
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012 #include "FWCore/Utilities/interface/Exception.h"
0013 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0014 
0015 #include <cassert>
0016 #include <sstream>
0017 
0018 static const bool useL1EventSetup(true);
0019 static const bool useL1GtTriggerMenuLite(false);
0020 static const unsigned char countMax(2);
0021 
0022 bool HLTPrescaleProvider::init(const edm::Run& iRun,
0023                                const edm::EventSetup& iSetup,
0024                                const std::string& processName,
0025                                bool& changed) {
0026   inited_ = true;
0027 
0028   count_[0] = 0;
0029   count_[1] = 0;
0030   count_[2] = 0;
0031   count_[3] = 0;
0032   count_[4] = 0;
0033 
0034   const bool result(hltConfigProvider_.init(iRun, iSetup, processName, changed));
0035 
0036   const unsigned int l1tType(hltConfigProvider_.l1tType());
0037   if (l1tType == 1) {
0038     checkL1GtUtils();
0039     /// L1 GTA V3: https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideL1TriggerL1GtUtils#Version_3
0040     l1GtUtils_->getL1GtRunCache(iRun, iSetup, useL1EventSetup, useL1GtTriggerMenuLite);
0041   } else if (l1tType == 2) {
0042     checkL1TGlobalUtil();
0043     l1tGlobalUtil_->retrieveL1Setup(iSetup);
0044   } else {
0045     edm::LogError("HLTPrescaleProvider") << " Unknown L1T Type " << l1tType << " - prescales will not be avaiable!";
0046   }
0047 
0048   return result;
0049 }
0050 
0051 L1GtUtils const& HLTPrescaleProvider::l1GtUtils() const {
0052   checkL1GtUtils();
0053   return *l1GtUtils_;
0054 }
0055 
0056 l1t::L1TGlobalUtil const& HLTPrescaleProvider::l1tGlobalUtil() const {
0057   checkL1TGlobalUtil();
0058   return *l1tGlobalUtil_;
0059 }
0060 
0061 int HLTPrescaleProvider::prescaleSet(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0062   if (!inited_) {
0063     throw cms::Exception("LogicError") << "HLTPrescaleProvider::prescaleSet,\n"
0064                                           "HLTPrescaleProvider::init was not called at beginRun\n";
0065   }
0066   const unsigned int l1tType(hltConfigProvider_.l1tType());
0067   if (l1tType == 1) {
0068     checkL1GtUtils();
0069 
0070     // return hltPrescaleTable_.set();
0071     l1GtUtils_->getL1GtRunCache(iEvent, iSetup, useL1EventSetup, useL1GtTriggerMenuLite);
0072     int errorTech(0);
0073     const int psfsiTech(l1GtUtils_->prescaleFactorSetIndex(iEvent, L1GtUtils::TechnicalTrigger, errorTech));
0074     int errorPhys(0);
0075     const int psfsiPhys(l1GtUtils_->prescaleFactorSetIndex(iEvent, L1GtUtils::AlgorithmTrigger, errorPhys));
0076     assert(psfsiTech == psfsiPhys);
0077     if ((errorTech == 0) && (errorPhys == 0) && (psfsiTech >= 0) && (psfsiPhys >= 0) && (psfsiTech == psfsiPhys)) {
0078       return psfsiPhys;
0079     } else {
0080       /// error - notify user!
0081       if (count_[0] < countMax) {
0082         count_[0] += 1;
0083         edm::LogError("HLTPrescaleProvider")
0084             << " Using processName '" << hltConfigProvider_.processName() << "':"
0085             << " Error in determining HLT prescale set index from L1 data using L1GtUtils:"
0086             << " Tech/Phys error = " << errorTech << "/" << errorPhys << " Tech/Phys psfsi = " << psfsiTech << "/"
0087             << psfsiPhys;
0088       }
0089       return -1;
0090     }
0091   } else if (l1tType == 2) {
0092     checkL1TGlobalUtil();
0093     l1tGlobalUtil_->retrieveL1Event(iEvent, iSetup);
0094     return static_cast<int>(l1tGlobalUtil_->prescaleColumn());
0095   } else {
0096     if (count_[0] < countMax) {
0097       count_[0] += 1;
0098       edm::LogError("HLTPrescaleProvider")
0099           << " Using processName '" << hltConfigProvider_.processName() << "':"
0100           << " Unknown L1T Type " << l1tType << " - can not determine prescale set index!";
0101     }
0102     return -1;
0103   }
0104 }
0105 
0106 template <>
0107 FractionalPrescale HLTPrescaleProvider::convertL1PS(double val) const {
0108   int numer = static_cast<int>(val * kL1PrescaleDenominator_ + 0.5);
0109   static constexpr double kL1RoundingEpsilon = 0.001;
0110   if (std::abs(numer - val * kL1PrescaleDenominator_) > kL1RoundingEpsilon) {
0111     edm::LogWarning("ValueError") << " Error, L1 prescale val " << val
0112                                   << " does not appear to precisely expressable as int / " << kL1PrescaleDenominator_
0113                                   << ", using a FractionalPrescale is a loss of precision";
0114   }
0115 
0116   return {numer, kL1PrescaleDenominator_};
0117 }
0118 
0119 double HLTPrescaleProvider::getL1PrescaleValue(const edm::Event& iEvent,
0120                                                const edm::EventSetup& iSetup,
0121                                                const std::string& trigger) {
0122   // get L1T prescale - works only for those hlt trigger paths with
0123   // exactly one L1GT seed module which has exactly one L1T name as seed
0124 
0125   double result = -1;
0126 
0127   const unsigned int l1tType(hltConfigProvider_.l1tType());
0128   if (l1tType == 1) {
0129     checkL1GtUtils();
0130     const unsigned int nL1GTSeedModules(hltConfigProvider_.hltL1GTSeeds(trigger).size());
0131     if (nL1GTSeedModules == 0) {
0132       // no L1 seed module on path hence no L1 seed hence formally no L1 prescale
0133       result = 1;
0134     } else if (nL1GTSeedModules == 1) {
0135       l1GtUtils_->getL1GtRunCache(iEvent, iSetup, useL1EventSetup, useL1GtTriggerMenuLite);
0136       const std::string l1tname(hltConfigProvider_.hltL1GTSeeds(trigger).at(0).second);
0137       if (l1tname == l1tGlobalDecisionKeyword_) {
0138         LogDebug("HLTPrescaleProvider") << "Undefined L1T prescale for HLT path: '" << trigger << "' with L1T seed '"
0139                                         << l1tGlobalDecisionKeyword_ << "' (keyword for global decision of L1T)";
0140         result = -1;
0141       } else {
0142         int l1error(0);
0143         result = l1GtUtils_->prescaleFactor(iEvent, l1tname, l1error);
0144         if (l1error != 0) {
0145           if (count_[1] < countMax) {
0146             count_[1] += 1;
0147             edm::LogError("HLTPrescaleProvider")
0148                 << " Error in determining L1T prescale for HLT path: '" << trigger << "' with L1T seed: '" << l1tname
0149                 << "' using L1GtUtils: error code = " << l1error << "." << std::endl
0150                 << " Note: for this method ('prescaleValues'), only a single L1T name (and not a bit number)"
0151                 << " is allowed as seed!" << std::endl
0152                 << " For seeds being complex logical expressions, try the new method 'prescaleValuesInDetail'."
0153                 << std::endl;
0154           }
0155           result = -1;
0156         }
0157       }
0158     } else {
0159       /// error - can't handle properly multiple L1GTSeed modules
0160       if (count_[2] < countMax) {
0161         count_[2] += 1;
0162         std::string dump("'" + hltConfigProvider_.hltL1GTSeeds(trigger).at(0).second + "'");
0163         for (unsigned int i = 1; i != nL1GTSeedModules; ++i) {
0164           dump += " * '" + hltConfigProvider_.hltL1GTSeeds(trigger).at(i).second + "'";
0165         }
0166         edm::LogError("HLTPrescaleProvider")
0167             << " Error in determining L1T prescale for HLT path: '" << trigger << "' has multiple L1GTSeed modules, "
0168             << nL1GTSeedModules << ", with L1 seeds: " << dump
0169             << ". (Note: at most one L1GTSeed module is allowed for a proper determination of the L1T prescale!)";
0170       }
0171       result = -1;
0172     }
0173   } else if (l1tType == 2) {
0174     checkL1TGlobalUtil();
0175     const unsigned int nL1TSeedModules(hltConfigProvider_.hltL1TSeeds(trigger).size());
0176     if (nL1TSeedModules == 0) {
0177       // no L1 seed module on path hence no L1 seed hence formally no L1 prescale
0178       result = 1;
0179     } else if (nL1TSeedModules == 1) {
0180       //    l1tGlobalUtil_->retrieveL1Event(iEvent,iSetup);
0181       const std::string l1tname(hltConfigProvider_.hltL1TSeeds(trigger).at(0));
0182       if (l1tname == l1tGlobalDecisionKeyword_) {
0183         LogDebug("HLTPrescaleProvider") << "Undefined L1T prescale for HLT path: '" << trigger << "' with L1T seed '"
0184                                         << l1tGlobalDecisionKeyword_ << "' (keyword for global decision of L1T)";
0185         result = -1;
0186       } else {
0187         bool l1error(!l1tGlobalUtil_->getPrescaleByName(l1tname, result));
0188         if (l1error) {
0189           if (count_[1] < countMax) {
0190             count_[1] += 1;
0191             edm::LogError("HLTPrescaleProvider")
0192                 << " Error in determining L1T prescale for HLT path: '" << trigger << "' with L1T seed: '" << l1tname
0193                 << "' using L1TGlobalUtil: error cond = " << l1error << "." << std::endl
0194                 << " Note: for this method ('prescaleValues'), only a single L1T name (and not a bit number)"
0195                 << " is allowed as seed!" << std::endl
0196                 << " For seeds being complex logical expressions, try the new method 'prescaleValuesInDetail'."
0197                 << std::endl;
0198           }
0199           result = -1;
0200         }
0201       }
0202     } else {
0203       /// error - can't handle properly multiple L1TSeed modules
0204       if (count_[2] < countMax) {
0205         count_[2] += 1;
0206         std::string dump("'" + hltConfigProvider_.hltL1TSeeds(trigger).at(0) + "'");
0207         for (unsigned int i = 1; i != nL1TSeedModules; ++i) {
0208           dump += " * '" + hltConfigProvider_.hltL1TSeeds(trigger).at(i) + "'";
0209         }
0210         edm::LogError("HLTPrescaleProvider")
0211             << " Error in determining L1T prescale for HLT path: '" << trigger << "' has multiple L1TSeed modules, "
0212             << nL1TSeedModules << ", with L1T seeds: " << dump
0213             << ". (Note: at most one L1TSeed module is allowed for a proper determination of the L1T prescale!)";
0214       }
0215       result = -1;
0216     }
0217   } else {
0218     if (count_[1] < countMax) {
0219       count_[1] += 1;
0220       edm::LogError("HLTPrescaleProvider") << " Unknown L1T Type " << l1tType << " - can not determine L1T prescale! ";
0221     }
0222     result = -1;
0223   }
0224 
0225   return result;
0226 }
0227 
0228 std::vector<std::pair<std::string, double>> HLTPrescaleProvider::getL1PrescaleValueInDetail(
0229     const edm::Event& iEvent, const edm::EventSetup& iSetup, const std::string& trigger) {
0230   std::vector<std::pair<std::string, double>> result;
0231 
0232   const unsigned int l1tType(hltConfigProvider_.l1tType());
0233   if (l1tType == 1) {
0234     checkL1GtUtils();
0235 
0236     const unsigned int nL1GTSeedModules(hltConfigProvider_.hltL1GTSeeds(trigger).size());
0237     if (nL1GTSeedModules == 0) {
0238       // no L1 seed module on path hence no L1 seed hence formally no L1 prescale
0239       result.clear();
0240     } else if (nL1GTSeedModules == 1) {
0241       l1GtUtils_->getL1GtRunCache(iEvent, iSetup, useL1EventSetup, useL1GtTriggerMenuLite);
0242       const std::string l1tname(hltConfigProvider_.hltL1GTSeeds(trigger).at(0).second);
0243       if (l1tname == l1tGlobalDecisionKeyword_) {
0244         LogDebug("HLTPrescaleProvider") << "Undefined L1T prescales for HLT path: '" << trigger << "' with L1T seed '"
0245                                         << l1tGlobalDecisionKeyword_ << "' (keyword for global decision of L1T)";
0246         result.clear();
0247       } else {
0248         L1GtUtils::LogicalExpressionL1Results l1Logical(l1tname, *l1GtUtils_);
0249         l1Logical.logicalExpressionRunUpdate(iEvent.getRun(), iSetup, l1tname);
0250         const std::vector<std::pair<std::string, int>>& errorCodes(l1Logical.errorCodes(iEvent));
0251         auto resultInt = l1Logical.prescaleFactors();
0252         result.clear();
0253         result.reserve(resultInt.size());
0254         for (const auto& entry : resultInt) {
0255           result.push_back(entry);
0256         }
0257         int l1error(l1Logical.isValid() ? 0 : 1);
0258         for (auto const& errorCode : errorCodes) {
0259           l1error += std::abs(errorCode.second);
0260         }
0261         if (l1error != 0) {
0262           if (count_[3] < countMax) {
0263             count_[3] += 1;
0264             std::ostringstream message;
0265             message << " Error in determining L1T prescales for HLT path: '" << trigger << "' with complex L1T seed: '"
0266                     << l1tname << "' using L1GtUtils: " << std::endl
0267                     << " isValid=" << l1Logical.isValid() << " l1tname/error/prescale " << errorCodes.size()
0268                     << std::endl;
0269             for (unsigned int i = 0; i < errorCodes.size(); ++i) {
0270               message << " " << i << ":" << errorCodes[i].first << "/" << errorCodes[i].second << "/"
0271                       << result[i].second;
0272             }
0273             message << ".";
0274             edm::LogError("HLTPrescaleProvider") << message.str();
0275           }
0276           result.clear();
0277         }
0278       }
0279     } else {
0280       /// error - can't handle properly multiple L1GTSeed modules
0281       if (count_[4] < countMax) {
0282         count_[4] += 1;
0283         std::string dump("'" + hltConfigProvider_.hltL1GTSeeds(trigger).at(0).second + "'");
0284         for (unsigned int i = 1; i != nL1GTSeedModules; ++i) {
0285           dump += " * '" + hltConfigProvider_.hltL1GTSeeds(trigger).at(i).second + "'";
0286         }
0287         edm::LogError("HLTPrescaleProvider")
0288             << " Error in determining L1T prescale for HLT path: '" << trigger << "' has multiple L1GTSeed modules, "
0289             << nL1GTSeedModules << ", with L1 seeds: " << dump
0290             << ". (Note: at most one L1GTSeed module is allowed for a proper determination of the L1T prescale!)";
0291       }
0292       result.clear();
0293     }
0294   } else if (l1tType == 2) {
0295     checkL1TGlobalUtil();
0296     const unsigned int nL1TSeedModules(hltConfigProvider_.hltL1TSeeds(trigger).size());
0297     if (nL1TSeedModules == 0) {
0298       // no L1 seed module on path hence no L1 seed hence formally no L1 prescale
0299       result.clear();
0300     } else if (nL1TSeedModules == 1) {
0301       std::string l1tname(hltConfigProvider_.hltL1TSeeds(trigger).at(0));
0302       if (l1tname == l1tGlobalDecisionKeyword_) {
0303         LogDebug("HLTPrescaleProvider") << "Undefined L1T prescales for HLT path: '" << trigger << "' with L1T seed '"
0304                                         << l1tGlobalDecisionKeyword_ << "' (keyword for global decision of L1T)";
0305         result.clear();
0306       } else {
0307         GlobalLogicParser l1tGlobalLogicParser = GlobalLogicParser(l1tname);
0308         const std::vector<GlobalLogicParser::OperandToken> l1tSeeds = l1tGlobalLogicParser.expressionSeedsOperandList();
0309         int l1error(0);
0310         double l1tPrescale(-1);
0311         result.clear();
0312         result.reserve(l1tSeeds.size());
0313         for (auto const& i : l1tSeeds) {
0314           const string& l1tSeed = i.tokenName;
0315           if (!l1tGlobalUtil_->getPrescaleByName(l1tSeed, l1tPrescale)) {
0316             l1error += 1;
0317           }
0318           result.push_back(std::pair<std::string, double>(l1tSeed, l1tPrescale));
0319         }
0320         if (l1error != 0) {
0321           if (count_[3] < countMax) {
0322             count_[3] += 1;
0323             string l1name = l1tname;
0324             std::ostringstream message;
0325             message << " Error in determining L1T prescales for HLT path: '" << trigger << "' with complex L1T seed: '"
0326                     << l1tname << "' using L1TGlobalUtil: " << std::endl
0327                     << " isValid=" << l1tGlobalLogicParser.checkLogicalExpression(l1name) << " l1tname/error/prescale "
0328                     << l1tSeeds.size() << std::endl;
0329             for (unsigned int i = 0; i < l1tSeeds.size(); ++i) {
0330               const string& l1tSeed = l1tSeeds[i].tokenName;
0331               message << " " << i << ":" << l1tSeed << "/" << l1tGlobalUtil_->getPrescaleByName(l1tSeed, l1tPrescale)
0332                       << "/" << result[i].second;
0333             }
0334             message << ".";
0335             edm::LogError("HLTPrescaleProvider") << message.str();
0336           }
0337           result.clear();
0338         }
0339       }
0340     } else {
0341       /// error - can't handle properly multiple L1TSeed modules
0342       if (count_[4] < countMax) {
0343         count_[4] += 1;
0344         std::string dump("'" + hltConfigProvider_.hltL1TSeeds(trigger).at(0) + "'");
0345         for (unsigned int i = 1; i != nL1TSeedModules; ++i) {
0346           dump += " * '" + hltConfigProvider_.hltL1TSeeds(trigger).at(i) + "'";
0347         }
0348         edm::LogError("HLTPrescaleProvider")
0349             << " Error in determining L1T prescale for HLT path: '" << trigger << "' has multiple L1TSeed modules, "
0350             << nL1TSeedModules << ", with L1T seeds: " << dump
0351             << ". (Note: at most one L1TSeed module is allowed for a proper determination of the L1T prescale!)";
0352       }
0353       result.clear();
0354     }
0355   } else {
0356     if (count_[3] < countMax) {
0357       count_[3] += 1;
0358       edm::LogError("HLTPrescaleProvider") << " Unknown L1T Type " << l1tType << " - can not determine L1T prescale! ";
0359     }
0360     result.clear();
0361   }
0362 
0363   return result;
0364 }
0365 
0366 bool HLTPrescaleProvider::rejectedByHLTPrescaler(const edm::TriggerResults& triggerResults, unsigned int i) const {
0367   return hltConfigProvider_.moduleType(hltConfigProvider_.moduleLabel(i, triggerResults.index(i))) == "HLTPrescaler";
0368 }
0369 
0370 void HLTPrescaleProvider::checkL1GtUtils() const {
0371   if (!l1GtUtils_) {
0372     throw cms::Exception("Configuration") << "HLTPrescaleProvider::checkL1GtUtils(),\n"
0373                                              "Attempt to use L1GtUtils object when none was constructed.\n"
0374                                              "Possibly the proper era is not configured or\n"
0375                                              "the module configuration does not use the era properly\n"
0376                                              "or input is from mixed eras";
0377   }
0378 }
0379 
0380 void HLTPrescaleProvider::checkL1TGlobalUtil() const {
0381   if (!l1tGlobalUtil_) {
0382     throw cms::Exception("Configuration") << "HLTPrescaleProvider:::checkL1TGlobalUtil(),\n"
0383                                              "Attempt to use L1TGlobalUtil object when none was constructed.\n"
0384                                              "Possibly the proper era is not configured or\n"
0385                                              "the module configuration does not use the era properly\n"
0386                                              "or input is from mixed eras";
0387   }
0388 }
0389 
0390 void HLTPrescaleProvider::fillPSetDescription(edm::ParameterSetDescription& desc,
0391                                               unsigned int stageL1Trigger,
0392                                               edm::InputTag const& l1tAlgBlkInputTag,
0393                                               edm::InputTag const& l1tExtBlkInputTag,
0394                                               bool readPrescalesFromFile) {
0395   desc.add<unsigned int>("stageL1Trigger", stageL1Trigger);
0396   L1GtUtils::fillDescription(desc);
0397   l1t::L1TGlobalUtil::fillDescription(desc, l1tAlgBlkInputTag, l1tExtBlkInputTag, readPrescalesFromFile);
0398 }