File indexing completed on 2023-03-17 11:19:56
0001 #ifndef RecoLuminosity_LumiProducer_LumiCalculator_h
0002 #define RecoLuminosity_LumiProducer_LumiCalculator_h
0003 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0004 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0005 #include "FWCore/Framework/interface/Event.h"
0006 #include "FWCore/Framework/interface/Run.h"
0007 #include "FWCore/Framework/interface/LuminosityBlock.h"
0008 #include "DataFormats/Common/interface/Handle.h"
0009 #include "DataFormats/Luminosity/interface/LumiSummaryRunHeader.h"
0010 #include "DataFormats/Luminosity/interface/LumiSummary.h"
0011 #include "FWCore/Framework/interface/MakerMacros.h"
0012 #include "HLTrigger/HLTcore/interface/HLTConfigProvider.h"
0013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0014 #include <boost/regex.hpp>
0015 #include <iostream>
0016 #include <map>
0017 #include "FWCore/Utilities/interface/EDGetToken.h"
0018 #include "FWCore/Utilities/interface/InputTag.h"
0019 struct hltPerPathInfo {
0020 hltPerPathInfo() : prescale(0) {}
0021 unsigned int prescale;
0022 };
0023 struct l1PerBitInfo {
0024 l1PerBitInfo() : prescale(0) {}
0025 unsigned int prescale;
0026 };
0027 struct MyPerLumiInfo {
0028 unsigned int lsnum;
0029 float livefraction;
0030 float intglumi;
0031 unsigned long long deadcount;
0032 };
0033
0034 class LumiCalculator : public edm::one::EDAnalyzer<edm::one::WatchRuns, edm::one::WatchLuminosityBlocks> {
0035 public:
0036 explicit LumiCalculator(edm::ParameterSet const& pset);
0037 ~LumiCalculator() override;
0038
0039 private:
0040 void beginJob() override;
0041 void beginRun(const edm::Run& run, const edm::EventSetup& c) override;
0042 void analyze(edm::Event const& e, edm::EventSetup const& c) override;
0043 void beginLuminosityBlock(edm::LuminosityBlock const& lumiBlock, edm::EventSetup const& c) override {}
0044 void endLuminosityBlock(edm::LuminosityBlock const& lumiBlock, edm::EventSetup const& c) override;
0045 void endRun(edm::Run const&, edm::EventSetup const&) override;
0046 void endJob() override;
0047 std::vector<std::string> splitpathstr(const std::string& strValue, const std::string separator);
0048 HLTConfigProvider hltConfig_;
0049 std::multimap<std::string, std::string> trgpathMmap_;
0050 std::map<std::string, hltPerPathInfo> hltmap_;
0051 std::map<std::string, l1PerBitInfo> l1map_;
0052 std::vector<MyPerLumiInfo> perrunlumiinfo_;
0053
0054 private:
0055 edm::LogInfo* log_;
0056 bool showTrgInfo_;
0057 unsigned int currentlumi_;
0058 };
0059
0060
0061
0062 LumiCalculator::LumiCalculator(edm::ParameterSet const& pset) : log_(new edm::LogInfo("LumiReport")), currentlumi_(0) {
0063 showTrgInfo_ = pset.getUntrackedParameter<bool>("showTriggerInfo", false);
0064 consumes<LumiSummary, edm::InLumi>(edm::InputTag("lumiProducer", ""));
0065 consumes<LumiSummaryRunHeader, edm::InRun>(edm::InputTag("lumiProducer", ""));
0066 }
0067
0068
0069
0070 LumiCalculator::~LumiCalculator() {
0071 delete log_;
0072 log_ = nullptr;
0073 }
0074
0075
0076
0077 void LumiCalculator::analyze(edm::Event const& e, edm::EventSetup const&) {}
0078
0079
0080
0081 void LumiCalculator::beginJob() {}
0082
0083
0084
0085 void LumiCalculator::beginRun(const edm::Run& run, const edm::EventSetup& c) {
0086
0087
0088
0089
0090 bool changed(true);
0091 const std::string processname("HLT");
0092 if (!hltConfig_.init(run, c, processname, changed)) {
0093 throw cms::Exception("HLT process cannot be initialized");
0094 }
0095 perrunlumiinfo_.clear();
0096 trgpathMmap_.clear();
0097 hltmap_.clear();
0098 l1map_.clear();
0099
0100
0101
0102
0103 if (showTrgInfo_) {
0104 *log_ << "======Trigger Configuration Overview======\n";
0105 *log_ << "Run " << run.run() << " Trigger Table : " << hltConfig_.tableName() << "\n";
0106 }
0107 unsigned int totaltrg = hltConfig_.size();
0108 for (unsigned int t = 0; t < totaltrg; ++t) {
0109 std::string hltname(hltConfig_.triggerName(t));
0110 std::vector<std::string> numpathmodules = hltConfig_.moduleLabels(hltname);
0111 if (showTrgInfo_) {
0112 *log_ << t << " HLT path\t" << hltname << "\n";
0113 }
0114 hltPerPathInfo hlt;
0115 hlt.prescale = 1;
0116 hltmap_.insert(std::make_pair(hltname, hlt));
0117 std::vector<std::string>::iterator hltpathBeg = numpathmodules.begin();
0118 std::vector<std::string>::iterator hltpathEnd = numpathmodules.end();
0119 unsigned int mycounter = 0;
0120 for (std::vector<std::string>::iterator numpathmodule = hltpathBeg; numpathmodule != hltpathEnd; ++numpathmodule) {
0121 if (hltConfig_.moduleType(*numpathmodule) != "HLTLevel1GTSeed") {
0122 continue;
0123 }
0124 ++mycounter;
0125
0126 edm::ParameterSet l1GTPSet = hltConfig_.modulePSet(*numpathmodule);
0127 std::string l1pathname = l1GTPSet.getParameter<std::string>("L1SeedsLogicalExpression");
0128
0129 if (mycounter > 1) {
0130 if (showTrgInfo_) {
0131 *log_ << "\tskip and erase previous seeds : multiple L1SeedsLogicalExpressions per hlt path\n";
0132 }
0133
0134 trgpathMmap_.erase(hltname);
0135 continue;
0136 }
0137 if (l1pathname.find('(') != std::string::npos) {
0138 if (showTrgInfo_) {
0139 *log_ << " L1SeedsLogicalExpression(Complex)\t" << l1pathname << "\n";
0140 *log_ << "\tskip:contain complex logic\n";
0141 }
0142 continue;
0143 } else if (l1pathname.find("OR") != std::string::npos) {
0144 if (showTrgInfo_) {
0145 *log_ << " L1SeedsLogicalExpression(ORed)\t" << l1pathname << "\n";
0146 }
0147 std::vector<std::string> seeds = splitpathstr(l1pathname, " OR ");
0148 if (seeds.size() > 2) {
0149 if (showTrgInfo_) {
0150 *log_ << "\tskip:contain >1 OR\n";
0151 }
0152 continue;
0153 } else {
0154 for (std::vector<std::string>::iterator i = seeds.begin(); i != seeds.end(); ++i) {
0155 if (!i->empty() && showTrgInfo_)
0156 *log_ << "\t\tseed: " << *i << "\n";
0157 if (i == seeds.begin()) {
0158 trgpathMmap_.insert(std::make_pair(hltname, *i));
0159 }
0160 }
0161 }
0162 } else if (l1pathname.find("AND") != std::string::npos) {
0163 if (showTrgInfo_) {
0164 *log_ << " L1SeedsLogicalExpression(ANDed)\t" << l1pathname << "\n";
0165 }
0166 std::vector<std::string> seeds = splitpathstr(l1pathname, " AND ");
0167 if (seeds.size() > 2) {
0168 if (showTrgInfo_) {
0169 *log_ << "\tskip:contain >1 AND\n";
0170 }
0171 continue;
0172 } else {
0173 for (std::vector<std::string>::iterator i = seeds.begin(); i != seeds.end(); ++i) {
0174 if (!i->empty() && showTrgInfo_)
0175 *log_ << "\t\tseed: " << *i << "\n";
0176 if (i == seeds.begin()) {
0177 trgpathMmap_.insert(std::make_pair(hltname, *i));
0178 }
0179 }
0180 }
0181 } else {
0182 if (showTrgInfo_) {
0183 *log_ << " L1SeedsLogicalExpression(ONE)\t" << l1pathname << "\n";
0184 }
0185 if (splitpathstr(l1pathname, " NOT ").size() > 1) {
0186 if (showTrgInfo_) {
0187 *log_ << "\tskip:contain NOT\n";
0188 }
0189 continue;
0190 }
0191 trgpathMmap_.insert(std::make_pair(hltname, l1pathname));
0192 }
0193 }
0194 }
0195 if (showTrgInfo_) {
0196 *log_ << "================\n";
0197 }
0198 }
0199
0200
0201 void LumiCalculator::endLuminosityBlock(edm::LuminosityBlock const& lumiBlock, edm::EventSetup const& c) {
0202
0203
0204
0205
0206
0207 edm::Handle<LumiSummary> lumiSummary;
0208 lumiBlock.getByLabel("lumiProducer", lumiSummary);
0209
0210 edm::Handle<LumiSummaryRunHeader> lumiSummaryRH;
0211 lumiBlock.getRun().getByLabel("lumiProducer", lumiSummaryRH);
0212
0213 MyPerLumiInfo l;
0214 l.lsnum = lumiBlock.id().luminosityBlock();
0215
0216
0217
0218
0219 l.deadcount = lumiSummary->deadcount();
0220 l.intglumi = lumiSummary->avgInsDelLumi() * 93.244;
0221 l.livefraction = lumiSummary->liveFrac();
0222
0223 *log_ << "====== Lumi Section " << lumiBlock.id().luminosityBlock() << " ======\n";
0224 *log_ << "\t Luminosity " << l.intglumi << "\n";
0225 *log_ << "\t Dead count " << l.deadcount << "\n";
0226 *log_ << "\t Deadtime corrected Luminosity " << l.intglumi * l.livefraction << "\n";
0227
0228
0229
0230
0231 if (showTrgInfo_) {
0232 std::map<std::string, hltPerPathInfo>::iterator hltit;
0233 std::map<std::string, hltPerPathInfo>::iterator hltitBeg = hltmap_.begin();
0234 std::map<std::string, hltPerPathInfo>::iterator hltitEnd = hltmap_.end();
0235
0236 typedef std::pair<std::multimap<std::string, std::string>::iterator,
0237 std::multimap<std::string, std::string>::iterator>
0238 TRGMAPIT;
0239 unsigned int c = 0;
0240 for (hltit = hltitBeg; hltit != hltitEnd; ++hltit) {
0241 std::string hltname = hltit->first;
0242 *log_ << c << " HLT path " << hltname << " , prescale : " << hltit->second.prescale << "\n";
0243 TRGMAPIT ppp;
0244 ppp = trgpathMmap_.equal_range(hltname);
0245 if (ppp.first == ppp.second) {
0246 *log_ << " no L1\n";
0247 }
0248 for (std::multimap<std::string, std::string>::iterator mit = ppp.first; mit != ppp.second; ++mit) {
0249 std::string l1name = mit->second;
0250 *log_ << " L1 name : " << l1name;
0251 LumiSummary::L1 l1result = lumiSummary->l1info(lumiSummaryRH->getL1Index(l1name));
0252 *log_ << " prescale : " << l1result.prescale << "\n";
0253 *log_ << "\n";
0254 }
0255 ++c;
0256 }
0257 }
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269 size_t n = lumiSummary->nTriggerLine();
0270 for (size_t i = 0; i < n; ++i) {
0271 std::string l1bitname = lumiSummaryRH->getL1Name(lumiSummary->l1info(i).triggernameidx);
0272 l1PerBitInfo t;
0273 if (currentlumi_ == 0) {
0274 t.prescale = lumiSummary->l1info(i).prescale;
0275 l1map_.insert(std::make_pair(l1bitname, t));
0276 }
0277 }
0278
0279 perrunlumiinfo_.push_back(l);
0280
0281 ++currentlumi_;
0282 }
0283
0284
0285 void LumiCalculator::endRun(edm::Run const& run, edm::EventSetup const& c) {
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304 std::vector<MyPerLumiInfo>::const_iterator lumiIt;
0305 std::vector<MyPerLumiInfo>::const_iterator lumiItBeg = perrunlumiinfo_.begin();
0306 std::vector<MyPerLumiInfo>::const_iterator lumiItEnd = perrunlumiinfo_.end();
0307 float recorded = 0.0;
0308
0309 *log_ << "================ Run Summary " << run.run() << "================\n";
0310 for (lumiIt = lumiItBeg; lumiIt != lumiItEnd; ++lumiIt) {
0311 recorded += lumiIt->intglumi * lumiIt->livefraction;
0312 }
0313 *log_ << " CMS Recorded Lumi (e+27cm^-2) : " << recorded << "\n";
0314 *log_ << " Effective Lumi (e+27cm^-2) per trigger path: "
0315 << "\n\n";
0316 std::multimap<std::string, std::string>::iterator it;
0317 std::multimap<std::string, std::string>::iterator itBeg = trgpathMmap_.begin();
0318 std::multimap<std::string, std::string>::iterator itEnd = trgpathMmap_.end();
0319 unsigned int cc = 0;
0320 for (it = itBeg; it != itEnd; ++it) {
0321 *log_ << " " << cc << " " << it->first << " - " << it->second << " : ";
0322 ++cc;
0323 std::map<std::string, hltPerPathInfo>::const_iterator hltIt = hltmap_.find(it->first);
0324 if (hltIt == hltmap_.end()) {
0325 std::cout << "HLT path " << it->first << " not found" << std::endl;
0326 *log_ << "\n";
0327 continue;
0328 }
0329 std::map<std::string, l1PerBitInfo>::const_iterator l1It = l1map_.find(it->second);
0330 if (l1It == l1map_.end()) {
0331 std::cout << "L1 bit " << it->second << " not found" << std::endl;
0332 *log_ << "\n";
0333 continue;
0334 }
0335 unsigned int hltprescale = hltIt->second.prescale;
0336 unsigned int l1prescale = l1It->second.prescale;
0337 if (hltprescale != 0 && l1prescale != 0) {
0338 float effectiveLumi = recorded / (hltprescale * l1prescale);
0339 *log_ << effectiveLumi << "\n";
0340 } else {
0341 *log_ << "0 prescale exception\n";
0342 continue;
0343 }
0344 *log_ << "\n";
0345 }
0346 }
0347
0348
0349 void LumiCalculator::endJob() {}
0350
0351 std::vector<std::string> LumiCalculator::splitpathstr(const std::string& strValue, const std::string separator) {
0352 std::vector<std::string> vecstrResult;
0353 boost::regex re(separator);
0354 boost::sregex_token_iterator p(strValue.begin(), strValue.end(), re, -1);
0355 boost::sregex_token_iterator end;
0356 while (p != end) {
0357 vecstrResult.push_back(*p++);
0358 }
0359 return vecstrResult;
0360 }
0361
0362 DEFINE_FWK_MODULE(LumiCalculator);
0363 #endif