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/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) {
0075 fillsummarycache(currentrun, currentls);
0076 } else {
0077 if (m_summarycache.find(currentls) == m_summarycache.end()) {
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) {
0107 filldetailcache(currentrun, currentls);
0108 } else {
0109 if (m_detailcache.find(currentls) == m_detailcache.end()) {
0110 filldetailcache(currentrun, 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
0146
0147
0148
0149
0150
0151
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
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
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>();
0209 }
0210 float intgdellumi = 0.0;
0211 if (!row["DELIVLUMISECTION"].isNull()) {
0212 intgdellumi = row["DELIVLUMISECTION"].data<float>() * 1000.0;
0213 }
0214 float intgreclumi = 0.0;
0215 if (!row["LIVELUMISECTION"].isNull()) {
0216 intgreclumi = row["LIVELUMISECTION"].data<float>() * 1000.0;
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
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
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
0269
0270
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
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>();
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
0344 DEFINE_FWK_EVENTSETUP_SOURCE(DIPLumiProducer);