File indexing completed on 2024-04-06 12:26:35
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "FWCore/Framework/interface/one/EDProducer.h"
0012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0013 #include "FWCore/Framework/interface/Event.h"
0014 #include "FWCore/Framework/interface/LuminosityBlock.h"
0015 #include "FWCore/Framework/interface/Run.h"
0016 #include "DataFormats/Provenance/interface/BranchType.h"
0017 #include "DataFormats/Provenance/interface/LuminosityBlockID.h"
0018 #include "DataFormats/Luminosity/interface/LumiSummaryRunHeader.h"
0019 #include "DataFormats/Luminosity/interface/LumiSummary.h"
0020 #include "DataFormats/Luminosity/interface/LumiDetails.h"
0021 #include "FWCore/ServiceRegistry/interface/Service.h"
0022 #include "FWCore/Framework/interface/EventSetup.h"
0023
0024 #include "CoralBase/Exception.h"
0025 #include "CoralBase/AttributeList.h"
0026 #include "CoralBase/Attribute.h"
0027 #include "CoralBase/AttributeSpecification.h"
0028 #include "CoralBase/Exception.h"
0029 #include "CoralBase/Blob.h"
0030 #include "RelationalAccess/ISessionProxy.h"
0031 #include "RelationalAccess/ITransaction.h"
0032 #include "RelationalAccess/AccessMode.h"
0033 #include "RelationalAccess/ITypeConverter.h"
0034 #include "RelationalAccess/IQuery.h"
0035 #include "RelationalAccess/ICursor.h"
0036 #include "RelationalAccess/ISchema.h"
0037 #include "RelationalAccess/ITable.h"
0038
0039 #include "RecoLuminosity/LumiProducer/interface/DBService.h"
0040 #include "RecoLuminosity/LumiProducer/interface/Exception.h"
0041 #include "RecoLuminosity/LumiProducer/interface/ConstantDef.h"
0042 #include <iostream>
0043 #include <sstream>
0044 #include <string>
0045 #include <memory>
0046 #include <algorithm>
0047 #include <vector>
0048 #include <cstring>
0049 #include <iterator>
0050 #include <filesystem>
0051
0052 #include <boost/tokenizer.hpp>
0053
0054 namespace edm {
0055 class EventSetup;
0056 }
0057
0058
0059
0060
0061 class ExpressLumiProducer : public edm::one::EDProducer<edm::BeginLuminosityBlockProducer> {
0062 public:
0063 struct PerLSData {
0064 unsigned int lsnum = 0;
0065 float lumivalue = 0.0;
0066 unsigned long long deadcount = 0;
0067 unsigned int numorbit = 0;
0068 unsigned int startorbit = 0;
0069 unsigned int bitzerocount = 0;
0070 std::vector<float> bunchlumivalue;
0071 std::vector<float> bunchlumierror;
0072 std::vector<short> bunchlumiquality;
0073 };
0074
0075 explicit ExpressLumiProducer(const edm::ParameterSet&);
0076
0077 ~ExpressLumiProducer() override;
0078
0079 private:
0080 void produce(edm::Event&, const edm::EventSetup&) final;
0081
0082 void beginLuminosityBlockProduce(edm::LuminosityBlock& iLBlock, edm::EventSetup const& iSetup) final;
0083
0084 bool fillLumi(edm::LuminosityBlock& iLBlock);
0085 void fillLSCache(unsigned int runnum, unsigned int luminum);
0086 void writeProductsForEntry(edm::LuminosityBlock& iLBlock, unsigned int luminum);
0087 void writeEmptyProductForEntry(edm::LuminosityBlock& iLBlock);
0088 unsigned int maxavailableLSforRun(coral::ISchema& schema, const std::string& tablename, unsigned int runnumber);
0089 std::string m_connectStr;
0090 unsigned int m_cachedrun;
0091 bool m_isNullRun;
0092 unsigned int m_cachesize;
0093 std::map<unsigned int, PerLSData> m_lscache;
0094 };
0095
0096 ExpressLumiProducer::ExpressLumiProducer::ExpressLumiProducer(const edm::ParameterSet& iConfig)
0097 : m_cachedrun(0), m_isNullRun(false), m_cachesize(0) {
0098
0099 produces<LumiSummary, edm::Transition::BeginLuminosityBlock>();
0100 produces<LumiDetails, edm::Transition::BeginLuminosityBlock>();
0101
0102 m_connectStr = iConfig.getParameter<std::string>("connect");
0103 m_cachesize = iConfig.getUntrackedParameter<unsigned int>("ncacheEntries", 5);
0104 }
0105
0106 ExpressLumiProducer::~ExpressLumiProducer() {}
0107
0108
0109
0110
0111 void ExpressLumiProducer::produce(edm::Event& e, const edm::EventSetup& iSetup) {}
0112
0113 void ExpressLumiProducer::writeEmptyProductForEntry(edm::LuminosityBlock& iLBlock) {
0114 iLBlock.put(std::make_unique<LumiSummary>());
0115 iLBlock.put(std::make_unique<LumiDetails>());
0116 }
0117 void ExpressLumiProducer::beginLuminosityBlockProduce(edm::LuminosityBlock& iLBlock, edm::EventSetup const& iSetup) {
0118 unsigned int currentrun = iLBlock.run();
0119 unsigned int currentls = iLBlock.luminosityBlock();
0120
0121 if (m_isNullRun) {
0122 writeEmptyProductForEntry(iLBlock);
0123 return;
0124 }
0125 if (m_cachedrun != currentrun) {
0126 fillLSCache(currentrun, currentls);
0127 } else {
0128 if (m_lscache.find(currentls) == m_lscache.end()) {
0129
0130 fillLSCache(currentrun, currentls);
0131 }
0132 }
0133 if (m_lscache.empty()) {
0134 writeEmptyProductForEntry(iLBlock);
0135 return;
0136 }
0137 unsigned int lstowriteout = 0;
0138 if (m_lscache.find(currentls) == m_lscache.end()) {
0139 std::vector<unsigned int> v;
0140 for (std::map<unsigned int, ExpressLumiProducer::PerLSData>::iterator it = m_lscache.begin(); it != m_lscache.end();
0141 ++it) {
0142 v.push_back(it->first);
0143 }
0144 lstowriteout = v.back();
0145 } else {
0146 lstowriteout = currentls;
0147 }
0148
0149
0150 if (lstowriteout == 0) {
0151 writeEmptyProductForEntry(iLBlock);
0152 } else {
0153 writeProductsForEntry(iLBlock, lstowriteout);
0154 }
0155 }
0156
0157 unsigned int ExpressLumiProducer::maxavailableLSforRun(coral::ISchema& schema,
0158 const std::string& tablename,
0159 unsigned int runnumber) {
0160
0161
0162
0163 unsigned int result = 0;
0164 coral::AttributeList bindVariables;
0165 bindVariables.extend("runnumber", typeid(unsigned int));
0166 bindVariables["runnumber"].data<unsigned int>() = runnumber;
0167 std::string conditionStr("RUNNUMBER=:runnumber");
0168 coral::AttributeList MyOutput;
0169 MyOutput.extend("maxavailablels", typeid(unsigned int));
0170 coral::IQuery* myQuery = schema.newQuery();
0171 myQuery->addToTableList(tablename);
0172 myQuery->addToOutputList("max(LUMISECTION)", "maxavailablels");
0173 myQuery->setCondition(conditionStr, bindVariables);
0174 myQuery->defineOutput(MyOutput);
0175 coral::ICursor& mycursor = myQuery->execute();
0176 while (mycursor.next()) {
0177 const coral::AttributeList& row = mycursor.currentRow();
0178 if (!row["maxavailablels"].isNull()) {
0179 result = row["maxavailablels"].data<unsigned int>();
0180 }
0181 }
0182 return result;
0183 }
0184 void ExpressLumiProducer::fillLSCache(unsigned int runnumber, unsigned int currentlsnum) {
0185 m_lscache.clear();
0186 m_cachedrun = runnumber;
0187
0188
0189
0190
0191
0192 edm::Service<lumi::service::DBService> mydbservice;
0193 if (!mydbservice.isAvailable()) {
0194 throw cms::Exception("Non existing service lumi::service::DBService");
0195 }
0196 auto session = mydbservice->connectReadOnly(m_connectStr);
0197 coral::ITypeConverter& tconverter = session->typeConverter();
0198 tconverter.setCppTypeForSqlType(std::string("float"), std::string("FLOAT(63)"));
0199 tconverter.setCppTypeForSqlType(std::string("unsigned int"), std::string("NUMBER(10)"));
0200 tconverter.setCppTypeForSqlType(std::string("unsigned short"), std::string("NUMBER(1)"));
0201 unsigned int lsmin = 1;
0202 unsigned int lsmax = currentlsnum;
0203 try {
0204 session->transaction().start(true);
0205 coral::ISchema& schema = session->nominalSchema();
0206 unsigned int maxavailableLS = maxavailableLSforRun(schema, std::string("LUMI_SECTIONS"), m_cachedrun);
0207 if (maxavailableLS != 0 && maxavailableLS < currentlsnum) {
0208 lsmax = maxavailableLS;
0209 } else if (maxavailableLS == 0) {
0210
0211 session->transaction().commit();
0212 return;
0213 }
0214 if (m_cachesize != 0) {
0215 lsmin = (lsmax - m_cachesize) > 0 ? (lsmax - m_cachesize + 1) : 1;
0216 }
0217 for (unsigned int n = lsmin; n <= lsmax; ++n) {
0218 m_lscache.insert(std::make_pair(
0219 n, PerLSData{.bunchlumivalue = {3564, 0.0}, .bunchlumierror = {3564, 0.0}, .bunchlumiquality = {3564, 0}}));
0220 }
0221
0222 coral::AttributeList lumisummaryBindVariables;
0223 lumisummaryBindVariables.extend("lsmin", typeid(unsigned int));
0224 lumisummaryBindVariables.extend("runnumber", typeid(unsigned int));
0225 lumisummaryBindVariables["runnumber"].data<unsigned int>() = m_cachedrun;
0226 lumisummaryBindVariables["lsmin"].data<unsigned int>() = lsmin;
0227 std::string conditionStr(" RUNNUMBER=:runnumber AND LUMISECTION>=:lsmin ");
0228 coral::AttributeList lumisummaryOutput;
0229 lumisummaryOutput.extend("LUMISECTION", typeid(unsigned int));
0230 lumisummaryOutput.extend("INSTLUMI", typeid(float));
0231 lumisummaryOutput.extend("DELIVLUMISECTION", typeid(float));
0232 lumisummaryOutput.extend("LIVELUMISECTION", typeid(float));
0233 lumisummaryOutput.extend("STARTORBIT", typeid(unsigned long long));
0234 if (m_cachesize != 0) {
0235 lumisummaryBindVariables.extend("lsmax", typeid(unsigned int));
0236 conditionStr = conditionStr + "AND LUMISECTION<=:lsmax";
0237 lumisummaryBindVariables["lsmax"].data<unsigned int>() = lsmax;
0238 }
0239 coral::IQuery* lumisummaryQuery = schema.newQuery();
0240 lumisummaryQuery->addToTableList(std::string("LUMI_SECTIONS"));
0241 lumisummaryQuery->addToOutputList("LUMISECTION");
0242 lumisummaryQuery->addToOutputList("INSTLUMI");
0243 lumisummaryQuery->addToOutputList("DELIVLUMISECTION");
0244 lumisummaryQuery->addToOutputList("LIVELUMISECTION");
0245 lumisummaryQuery->addToOutputList("STARTORBIT");
0246 lumisummaryQuery->setCondition(conditionStr, lumisummaryBindVariables);
0247 lumisummaryQuery->defineOutput(lumisummaryOutput);
0248 coral::ICursor& lumisummarycursor = lumisummaryQuery->execute();
0249 unsigned int rowcounter = 0;
0250 while (lumisummarycursor.next()) {
0251 const coral::AttributeList& row = lumisummarycursor.currentRow();
0252 unsigned int lsnum = row["LUMISECTION"].data<unsigned int>();
0253 float instlumi = 0.0;
0254 if (!row["INSTLUMI"].isNull()) {
0255 instlumi = row["INSTLUMI"].data<float>();
0256 }
0257 float deadfrac = 1.0;
0258 float intgdellumi = 0.0;
0259 float intgreclumi = 0.0;
0260 unsigned long long startorbit = 0;
0261 if (!row["DELIVLUMISECTION"].isNull()) {
0262 intgdellumi = row["DELIVLUMISECTION"].data<float>() * 1000.0;
0263 }
0264 if (!row["LIVELUMISECTION"].isNull()) {
0265 intgreclumi = row["LIVELUMISECTION"].data<float>() * 1000.0;
0266 }
0267 if (intgdellumi > 0) {
0268 deadfrac = 1.0 - intgreclumi / intgdellumi;
0269 }
0270 if (!row["STARTORBIT"].isNull()) {
0271 startorbit = row["STARTORBIT"].data<unsigned long long>();
0272 }
0273 unsigned long long deadcount = deadfrac * 10000.0;
0274 unsigned long long bitzerocount = 10000.0;
0275 PerLSData& lsdata = m_lscache[lsnum];
0276 lsdata.lsnum = lsnum;
0277 lsdata.lumivalue = instlumi;
0278 lsdata.deadcount = deadcount;
0279 lsdata.bitzerocount = bitzerocount;
0280 lsdata.startorbit = startorbit;
0281 lsdata.numorbit = 262144;
0282 ++rowcounter;
0283 }
0284 if (rowcounter == 0) {
0285 m_isNullRun = true;
0286 }
0287 delete lumisummaryQuery;
0288 if (m_isNullRun)
0289 return;
0290
0291
0292
0293
0294
0295 coral::AttributeList lumidetailBindVariables;
0296 lumidetailBindVariables.extend("lsmin", typeid(unsigned int));
0297 lumidetailBindVariables.extend("runnumber", typeid(unsigned int));
0298 lumidetailBindVariables["runnumber"].data<unsigned int>() = m_cachedrun;
0299 lumidetailBindVariables["lsmin"].data<unsigned int>() = lsmin;
0300 std::string detailconditionStr(" RUNNUMBER=:runnumber AND LUMISECTION>=:lsmin AND BUNCHLUMI>0 ");
0301 coral::AttributeList lumidetailOutput;
0302 lumidetailOutput.extend("LUMISECTION", typeid(unsigned int));
0303 lumidetailOutput.extend("BUNCH", typeid(unsigned int));
0304 lumidetailOutput.extend("BUNCHLUMI", typeid(float));
0305 if (m_cachesize != 0) {
0306 lumidetailBindVariables.extend("lsmax", typeid(unsigned int));
0307 detailconditionStr = detailconditionStr + "AND LUMISECTION<=:lsmax";
0308 lumidetailBindVariables["lsmax"].data<unsigned int>() = lsmax;
0309 }
0310 coral::IQuery* lumidetailQuery = schema.newQuery();
0311 lumidetailQuery->addToTableList(std::string("BUNCH_LUMI_SECTIONS"));
0312 lumidetailQuery->addToOutputList("LUMISECTION");
0313 lumidetailQuery->addToOutputList("BUNCH");
0314 lumidetailQuery->addToOutputList("BUNCHLUMI");
0315 lumidetailQuery->setCondition(detailconditionStr, lumidetailBindVariables);
0316 lumidetailQuery->defineOutput(lumidetailOutput);
0317 coral::ICursor& lumidetailcursor = lumidetailQuery->execute();
0318 while (lumidetailcursor.next()) {
0319 const coral::AttributeList& row = lumidetailcursor.currentRow();
0320 unsigned int lsnum = row["LUMISECTION"].data<unsigned int>();
0321 unsigned int bxidx = row["BUNCH"].data<unsigned int>();
0322 float bxlumi = row["BUNCHLUMI"].data<float>();
0323 m_lscache[lsnum].bunchlumivalue[bxidx] = bxlumi;
0324 }
0325 delete lumidetailQuery;
0326 session->transaction().commit();
0327 } catch (const coral::Exception& er) {
0328 session->transaction().rollback();
0329 throw cms::Exception("DatabaseError ") << er.what();
0330 }
0331 }
0332 void ExpressLumiProducer::writeProductsForEntry(edm::LuminosityBlock& iLBlock, unsigned int luminum) {
0333
0334 auto pIn1 = std::make_unique<LumiSummary>();
0335 auto pIn2 = std::make_unique<LumiDetails>();
0336 if (m_isNullRun) {
0337 pIn1->setLumiVersion("DIP");
0338 pIn2->setLumiVersion("DIP");
0339 iLBlock.put(std::move(pIn1));
0340 iLBlock.put(std::move(pIn2));
0341 return;
0342 }
0343 PerLSData& lsdata = m_lscache[luminum];
0344 pIn1->setLumiVersion("DIP");
0345 pIn1->setLumiData(lsdata.lumivalue, 0.0, 0.0);
0346 pIn1->setDeadCount(lsdata.deadcount);
0347 pIn1->setBitZeroCount(lsdata.bitzerocount);
0348 pIn1->setlsnumber(lsdata.lsnum);
0349 pIn1->setOrbitData(lsdata.startorbit, lsdata.numorbit);
0350
0351 pIn2->setLumiVersion("DIP");
0352 pIn2->fill(LumiDetails::kOCC1, lsdata.bunchlumivalue, lsdata.bunchlumierror, lsdata.bunchlumiquality);
0353 iLBlock.put(std::move(pIn1));
0354 iLBlock.put(std::move(pIn2));
0355 }
0356 #include "FWCore/Framework/interface/MakerMacros.h"
0357 DEFINE_FWK_MODULE(ExpressLumiProducer);