Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-09-03 00:00:07

0001 // -*- C++ -*-
0002 //
0003 // Package:    LumiProducer
0004 // Class:      ExpressLumiProducer
0005 //
0006 /**\class ExpressLumiProducer ExpressLumiProducer.cc RecoLuminosity/LumiProducer/src/ExpressLumiProducer.cc
0007 Description: A essource/esproducer for lumi values from DIP via runtime logger DB
0008 */
0009 // read lumi from dip database and dump to express stream
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 // class declaration
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;  //if lumi data exist for this run
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   // register your products
0099   produces<LumiSummary, edm::Transition::BeginLuminosityBlock>();
0100   produces<LumiDetails, edm::Transition::BeginLuminosityBlock>();
0101   // set up cache
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 // member functions
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   //if is null run, fill empty values and return
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       //if runnumber is cached but LS is not, this is the first LS, fill LS cache to full capacity
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()) {  //if the currentls is not in the cache
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();  //last available
0145   } else {                    //if the current ls is cached
0146     lstowriteout = currentls;
0147   }
0148   //here the presence of ls is guaranteed
0149   //std::cout<<"writing "<<runnumber<<" "<<luminum<<std::endl;
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      select  max(lumisection) as maxavailable from  cms_runtime_logger.lumi_sections where runnumber=:runnumber;
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   //queries once per cache refill
0189   //
0190   //select lumisection,instlumi,delivlumi,livelumi from cms_runtime_logger.lumi_sections where lumisection>=:lsmin and lumisection<:lsmax and runnumber=:runnumber;
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       //this run not existing (yet)
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>();  //Hz/ub
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;  //convert to /ub
0263       }
0264       if (!row["LIVELUMISECTION"].isNull()) {
0265         intgreclumi = row["LIVELUMISECTION"].data<float>() * 1000.0;  //convert to /ub
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>();  //convert to /ub
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     //queries once per cache refill
0292     //
0293     //select lumisection,bunch,bunchlumi from cms_runtime_logger.bunch_lumi_sections where lumisection>=:lsmin and lumisection<:lsmax and runnumber=:runnumber;
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>();  //Hz/ub
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   //std::cout<<"writing runnumber,luminum "<<runnumber<<" "<<luminum<<std::endl;
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);