Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-03-19 06:07:39

0001 // -*- C++ -*-
0002 //
0003 // Package:    LumiProducer
0004 // Class:      DIPLumiProducer
0005 //
0006 /**\class DIPLumiProducer DIPLumiProducer.cc RecoLuminosity/LumiProducer/src/DIPLumiProducer.cc
0007 Description: A essource/esproducer for lumi values from DIP via runtime logger DB
0008 */
0009 
0010 //#include <memory>
0011 #include "FWCore/Framework/interface/SourceFactory.h"
0012 #include "FWCore/Framework/interface/ESProducer.h"
0013 #include "FWCore/Framework/interface/ESHandle.h"
0014 #include "FWCore/Framework/interface/EventSetup.h"
0015 
0016 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0017 #include "FWCore/Framework/interface/Event.h"
0018 #include "FWCore/Framework/interface/LuminosityBlock.h"
0019 #include "FWCore/Framework/interface/Run.h"
0020 #include "DataFormats/Provenance/interface/LuminosityBlockID.h"
0021 #include "FWCore/ServiceRegistry/interface/Service.h"
0022 
0023 #include "FWCore/Framework/interface/IOVSyncValue.h"
0024 
0025 #include "CoralBase/Exception.h"
0026 #include "CoralBase/AttributeList.h"
0027 #include "CoralBase/Attribute.h"
0028 #include "CoralBase/AttributeSpecification.h"
0029 #include "CoralBase/Exception.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 #include "RecoLuminosity/LumiProducer/interface/DBService.h"
0039 #include "RecoLuminosity/LumiProducer/interface/Exception.h"
0040 #include "RecoLuminosity/LumiProducer/interface/ConstantDef.h"
0041 #include "RecoLuminosity/LumiProducer/interface/DIPLumiSummary.h"
0042 #include "RecoLuminosity/LumiProducer/interface/DIPLumiDetail.h"
0043 #include "RecoLuminosity/LumiProducer/interface/DIPLuminosityRcd.h"
0044 #include "DIPLumiProducer.h"
0045 #include <iostream>
0046 #include <sstream>
0047 #include <string>
0048 #include <memory>
0049 #include <algorithm>
0050 #include <vector>
0051 #include <cstring>
0052 #include <iterator>
0053 #include <boost/tokenizer.hpp>
0054 #include <xercesc/dom/DOM.hpp>
0055 #include <xercesc/parsers/XercesDOMParser.hpp>
0056 #include "Utilities/Xerces/interface/Xerces.h"
0057 #include <xercesc/util/XMLString.hpp>
0058 
0059 DIPLumiProducer::DIPLumiProducer(const edm::ParameterSet& iConfig)
0060     : m_connectStr(""), m_summarycachedrun(0), m_detailcachedrun(0), m_cachesize(0) {
0061   setWhatProduced(this, &DIPLumiProducer::produceSummary);
0062   setWhatProduced(this, &DIPLumiProducer::produceDetail);
0063   findingRecord<DIPLuminosityRcd>();
0064   m_connectStr = iConfig.getParameter<std::string>("connect");
0065   m_cachesize = iConfig.getUntrackedParameter<unsigned int>("ncacheEntries", 3);
0066 }
0067 
0068 DIPLumiProducer::ReturnSummaryType DIPLumiProducer::produceSummary(const DIPLuminosityRcd&) {
0069   unsigned int currentrun = m_pcurrentTime->eventID().run();
0070   unsigned int currentls = m_pcurrentTime->luminosityBlockNumber();
0071   if (currentls == 0 || currentls == 4294967295) {
0072     return std::make_shared<const DIPLumiSummary>();
0073   }
0074   if (m_summarycachedrun != currentrun) {                          //i'm in a new run
0075     fillsummarycache(currentrun, currentls);                       //starting ls
0076   } else {                                                         //i'm in an old run
0077     if (m_summarycache.find(currentls) == m_summarycache.end()) {  //i'm not cached
0078       fillsummarycache(currentrun, currentls);                     //
0079     }
0080   }
0081   if (m_summarycache.empty()) {
0082     return std::make_shared<const DIPLumiSummary>();
0083   }
0084   if (m_summarycache.find(currentls) == m_summarycache.end()) {
0085     std::vector<unsigned int> v;
0086     for (std::map<unsigned int, std::shared_ptr<const DIPLumiSummary> >::iterator it = m_summarycache.begin();
0087          it != m_summarycache.end();
0088          ++it) {
0089       v.push_back(it->first);
0090     }
0091     m_summaryresult = m_summarycache[v.back()];
0092   } else {
0093     m_summaryresult = m_summarycache[currentls];
0094   }
0095   if (m_summaryresult.get() == nullptr) {
0096     return std::make_shared<const DIPLumiSummary>();
0097   }
0098   return m_summaryresult;
0099 }
0100 DIPLumiProducer::ReturnDetailType DIPLumiProducer::produceDetail(const DIPLuminosityRcd&) {
0101   unsigned int currentrun = m_pcurrentTime->eventID().run();
0102   unsigned int currentls = m_pcurrentTime->luminosityBlockNumber();
0103   if (currentls == 0 || currentls == 4294967295) {
0104     return std::make_shared<const DIPLumiDetail>();
0105   }
0106   if (m_detailcachedrun != currentrun) {                         //i'm in a new run
0107     filldetailcache(currentrun, currentls);                      //starting ls
0108   } else {                                                       //i'm in an known run
0109     if (m_detailcache.find(currentls) == m_detailcache.end()) {  //i'm in a unknown ls
0110       filldetailcache(currentrun, currentls);                    //cache all ls>=currentls
0111     }
0112   }
0113   if (m_detailcache.empty()) {
0114     return std::make_shared<const DIPLumiDetail>();
0115   }
0116   if (m_detailcache.find(currentls) == m_detailcache.end()) {
0117     std::vector<unsigned int> v;
0118     for (std::map<unsigned int, std::shared_ptr<const DIPLumiDetail> >::iterator it = m_detailcache.begin();
0119          it != m_detailcache.end();
0120          ++it) {
0121       v.push_back(it->first);
0122     }
0123     m_detailresult = m_detailcache[v.back()];
0124   } else {
0125     m_detailresult = m_detailcache[currentls];
0126   }
0127   if (m_detailresult.get() == nullptr) {
0128     return std::make_shared<const DIPLumiDetail>();
0129   }
0130   return m_detailresult;
0131 }
0132 
0133 void DIPLumiProducer::setIntervalFor(const edm::eventsetup::EventSetupRecordKey& iKey,
0134                                      const edm::IOVSyncValue& iTime,
0135                                      edm::ValidityInterval& oValidity) {
0136   m_pcurrentTime = &iTime;
0137   oValidity.setFirst(iTime);
0138   oValidity.setLast(iTime);
0139 }
0140 
0141 void DIPLumiProducer::fillsummarycache(unsigned int runnumber, unsigned int currentlsnum) {
0142   m_summarycache.clear();
0143   m_summarycachedrun = runnumber;
0144   //
0145   // queries once per cache refill
0146   //
0147   // select max(lumi_sections) as maxavailable from  cms_runtime_logger.lumi_sections where runnumber=:runnumber;
0148   //
0149   // if maxavailable<currentls: get lsmax=maxavailable ; else: get lsmax=currentls
0150   // lsmin=lsmax-cachesize
0151   // select runnumber,lumisection,instlumi,delivlumi,livelumi from cms_runtime_logger.lumi_sections where lumisection>=:lsmin and lumisection<=:lsmax and runnumber=:runnumber;
0152   //
0153   edm::Service<lumi::service::DBService> mydbservice;
0154   if (!mydbservice.isAvailable()) {
0155     throw cms::Exception("Non existing service lumi::service::DBService");
0156   }
0157   auto session = mydbservice->connectReadOnly(m_connectStr);
0158   coral::ITypeConverter& tconverter = session->typeConverter();
0159   tconverter.setCppTypeForSqlType(std::string("float"), std::string("FLOAT(63)"));
0160   tconverter.setCppTypeForSqlType(std::string("unsigned int"), std::string("NUMBER(10)"));
0161   tconverter.setCppTypeForSqlType(std::string("unsigned short"), std::string("NUMBER(1)"));
0162   unsigned int lsmin = 1;
0163   unsigned int lsmax = currentlsnum;
0164   try {
0165     session->transaction().start(true);
0166     coral::ISchema& schema = session->nominalSchema();
0167     unsigned int maxavailableLS = maxavailableLSforRun(schema, std::string("LUMI_SECTIONS"), m_summarycachedrun);
0168     if (maxavailableLS != 0 && maxavailableLS < currentlsnum) {
0169       lsmax = maxavailableLS;
0170     } else if (maxavailableLS == 0) {
0171       //this run not existing (yet)
0172       session->transaction().commit();
0173       return;
0174     }
0175     if (m_cachesize != 0) {
0176       lsmin = (lsmax - m_cachesize) > 0 ? (lsmax - m_cachesize + 1) : 1;
0177     }
0178     //std::cout<<"lsmin "<<lsmin<<" lsmax "<<lsmax<<std::endl;
0179     coral::AttributeList lumisummaryBindVariables;
0180     lumisummaryBindVariables.extend("lsmin", typeid(unsigned int));
0181     lumisummaryBindVariables.extend("lsmax", typeid(unsigned int));
0182     lumisummaryBindVariables.extend("runnumber", typeid(unsigned int));
0183     lumisummaryBindVariables["runnumber"].data<unsigned int>() = m_summarycachedrun;
0184     lumisummaryBindVariables["lsmin"].data<unsigned int>() = lsmin;
0185     lumisummaryBindVariables["lsmax"].data<unsigned int>() = lsmax;
0186     std::string conditionStr("RUNNUMBER=:runnumber AND LUMISECTION>=:lsmin AND LUMISECTION<=:lsmax");
0187     coral::AttributeList lumisummaryOutput;
0188     lumisummaryOutput.extend("LUMISECTION", typeid(unsigned int));
0189     lumisummaryOutput.extend("INSTLUMI", typeid(float));
0190     lumisummaryOutput.extend("DELIVLUMISECTION", typeid(float));
0191     lumisummaryOutput.extend("LIVELUMISECTION", typeid(float));
0192     lumisummaryOutput.extend("CMS_ACTIVE", typeid(unsigned short));
0193     coral::IQuery* lumisummaryQuery = schema.newQuery();
0194     lumisummaryQuery->addToTableList(std::string("LUMI_SECTIONS"));
0195     lumisummaryQuery->addToOutputList("LUMISECTION");
0196     lumisummaryQuery->addToOutputList("INSTLUMI");
0197     lumisummaryQuery->addToOutputList("DELIVLUMISECTION");
0198     lumisummaryQuery->addToOutputList("LIVELUMISECTION");
0199     lumisummaryQuery->addToOutputList("CMS_ACTIVE");
0200     lumisummaryQuery->setCondition(conditionStr, lumisummaryBindVariables);
0201     lumisummaryQuery->defineOutput(lumisummaryOutput);
0202     coral::ICursor& lumisummarycursor = lumisummaryQuery->execute();
0203     while (lumisummarycursor.next()) {
0204       const coral::AttributeList& row = lumisummarycursor.currentRow();
0205       unsigned int lsnum = row["LUMISECTION"].data<unsigned int>();
0206       float instlumi = 0.0;
0207       if (!row["INSTLUMI"].isNull()) {
0208         instlumi = row["INSTLUMI"].data<float>();  //Hz/ub
0209       }
0210       float intgdellumi = 0.0;
0211       if (!row["DELIVLUMISECTION"].isNull()) {
0212         intgdellumi = row["DELIVLUMISECTION"].data<float>() * 1000.0;  //convert to /ub
0213       }
0214       float intgreclumi = 0.0;
0215       if (!row["LIVELUMISECTION"].isNull()) {
0216         intgreclumi = row["LIVELUMISECTION"].data<float>() * 1000.0;  //convert to /ub
0217       }
0218       unsigned short cmsalive = 0;
0219       if (!row["CMS_ACTIVE"].isNull()) {
0220         cmsalive = row["CMS_ACTIVE"].data<unsigned short>();
0221       }
0222       auto tmpls = std::make_unique<DIPLumiSummary>(instlumi, intgdellumi, intgreclumi, cmsalive);
0223       tmpls->setOrigin(m_summarycachedrun, lsnum);
0224       //std::cout<<"filling "<<lsnum<<std::endl;
0225       std::shared_ptr<const DIPLumiSummary> const_tmpls = std::move(tmpls);
0226       m_summarycache.insert(std::make_pair(lsnum, const_tmpls));
0227     }
0228     delete lumisummaryQuery;
0229     session->transaction().commit();
0230   } catch (const coral::Exception& er) {
0231     session->transaction().rollback();
0232     throw cms::Exception("DatabaseError ") << er.what();
0233   }
0234 }
0235 unsigned int DIPLumiProducer::maxavailableLSforRun(coral::ISchema& schema,
0236                                                    const std::string& tablename,
0237                                                    unsigned int runnumber) {
0238   /**
0239      select  max(lumisection) as maxavailable from  cms_runtime_logger.lumi_sections where runnumber=:runnumber;
0240   **/
0241   unsigned int result = 0;
0242   coral::AttributeList bindVariables;
0243   bindVariables.extend("runnumber", typeid(unsigned int));
0244   bindVariables["runnumber"].data<unsigned int>() = runnumber;
0245   std::string conditionStr("RUNNUMBER=:runnumber");
0246   coral::AttributeList MyOutput;
0247   MyOutput.extend("maxavailablels", typeid(unsigned int));
0248   coral::IQuery* myQuery = schema.newQuery();
0249   myQuery->addToTableList(tablename);
0250   myQuery->addToOutputList("max(LUMISECTION)", "maxavailablels");
0251   myQuery->setCondition(conditionStr, bindVariables);
0252   myQuery->defineOutput(MyOutput);
0253   coral::ICursor& mycursor = myQuery->execute();
0254   while (mycursor.next()) {
0255     const coral::AttributeList& row = mycursor.currentRow();
0256     if (!row["maxavailablels"].isNull()) {
0257       result = row["maxavailablels"].data<unsigned int>();
0258     }
0259   }
0260   return result;
0261 }
0262 void DIPLumiProducer::filldetailcache(unsigned int runnumber, unsigned int currentlsnum) {
0263   m_detailcache.clear();
0264   m_detailcachedrun = runnumber;
0265 
0266   std::map<unsigned int, std::unique_ptr<DIPLumiDetail> > detailcache;
0267   //
0268   //queries once per cache refill
0269   //
0270   //select lumisection,bunch,bunchlumi from cms_runtime_logger.bunch_lumi_sections where lumisection>=:lsmin and lumisection<:lsmax and runnumber=:runnumber ;
0271   //
0272   edm::Service<lumi::service::DBService> mydbservice;
0273   if (!mydbservice.isAvailable()) {
0274     throw cms::Exception("Non existing service lumi::service::DBService");
0275   }
0276   auto session = mydbservice->connectReadOnly(m_connectStr);
0277   coral::ITypeConverter& tconverter = session->typeConverter();
0278   tconverter.setCppTypeForSqlType(std::string("float"), std::string("FLOAT(63)"));
0279   tconverter.setCppTypeForSqlType(std::string("unsigned int"), std::string("NUMBER(10)"));
0280   unsigned int lsmin = 1;
0281   unsigned int lsmax = currentlsnum;
0282   try {
0283     session->transaction().start(true);
0284     coral::ISchema& schema = session->nominalSchema();
0285     unsigned int maxavailableLS = maxavailableLSforRun(schema, std::string("BUNCH_LUMI_SECTIONS"), m_summarycachedrun);
0286     if (maxavailableLS != 0 && maxavailableLS < currentlsnum) {
0287       lsmax = maxavailableLS;
0288     } else if (maxavailableLS == 0) {
0289       //this run not existing (yet)
0290       session->transaction().commit();
0291       return;
0292     }
0293     if (m_cachesize != 0) {
0294       lsmin = (lsmax - m_cachesize) > 0 ? (lsmax - m_cachesize + 1) : 1;
0295     }
0296     coral::AttributeList lumidetailBindVariables;
0297     lumidetailBindVariables.extend("lsmin", typeid(unsigned int));
0298     lumidetailBindVariables.extend("lsmax", typeid(unsigned int));
0299     lumidetailBindVariables.extend("runnumber", typeid(unsigned int));
0300     lumidetailBindVariables["runnumber"].data<unsigned int>() = m_detailcachedrun;
0301     lumidetailBindVariables["lsmin"].data<unsigned int>() = lsmin;
0302     lumidetailBindVariables["lsmax"].data<unsigned int>() = lsmax;
0303     std::string conditionStr("RUNNUMBER=:runnumber AND LUMISECTION>=:lsmin AND LUMISECTION<=:lsmax AND BUNCHLUMI>0 ");
0304     coral::AttributeList lumidetailOutput;
0305     lumidetailOutput.extend("LUMISECTION", typeid(unsigned int));
0306     lumidetailOutput.extend("BUNCH", typeid(unsigned int));
0307     lumidetailOutput.extend("BUNCHLUMI", typeid(float));
0308     coral::IQuery* lumidetailQuery = schema.newQuery();
0309     lumidetailQuery->addToTableList(std::string("BUNCH_LUMI_SECTIONS"));
0310     lumidetailQuery->addToOutputList("LUMISECTION");
0311     lumidetailQuery->addToOutputList("BUNCH");
0312     lumidetailQuery->addToOutputList("BUNCHLUMI");
0313     lumidetailQuery->setCondition(conditionStr, lumidetailBindVariables);
0314     lumidetailQuery->defineOutput(lumidetailOutput);
0315     coral::ICursor& lumidetailcursor = lumidetailQuery->execute();
0316     while (lumidetailcursor.next()) {
0317       const coral::AttributeList& row = lumidetailcursor.currentRow();
0318       unsigned int lsnum = row["LUMISECTION"].data<unsigned int>();
0319       if (detailcache.find(lsnum) == detailcache.end()) {
0320         detailcache.insert(std::make_pair(lsnum, std::make_unique<DIPLumiDetail>()));
0321         detailcache[lsnum]->setOrigin(m_detailcachedrun, lsnum);
0322       }
0323       if (!row["BUNCH"].isNull()) {
0324         unsigned int bxidx = row["BUNCH"].data<unsigned int>();
0325         float bxlumi = 0.0;
0326         if (!row["BUNCHLUMI"].isNull()) {
0327           bxlumi = row["BUNCHLUMI"].data<float>();  //Hz/ub
0328         }
0329         detailcache[lsnum]->fillbxdata(bxidx, bxlumi);
0330       }
0331     }
0332     for (auto& item : detailcache) {
0333       m_detailcache[item.first] = std::move(item.second);
0334     }
0335     delete lumidetailQuery;
0336     session->transaction().commit();
0337   } catch (const coral::Exception& er) {
0338     session->transaction().rollback();
0339     throw cms::Exception("DatabaseError ") << er.what();
0340   }
0341 }
0342 DIPLumiProducer::~DIPLumiProducer() {}
0343 //define this as a plug-in
0344 DEFINE_FWK_EVENTSETUP_SOURCE(DIPLumiProducer);