00001
00002
00003
00004
00005
00009
00010
00011
00012
00013 #include "FWCore/Framework/interface/SourceFactory.h"
00014 #include "FWCore/Framework/interface/ESProducer.h"
00015 #include "FWCore/Framework/interface/ESHandle.h"
00016 #include "FWCore/Framework/interface/EventSetup.h"
00017
00018 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00019 #include "FWCore/Framework/interface/Event.h"
00020 #include "FWCore/Framework/interface/LuminosityBlock.h"
00021 #include "FWCore/Framework/interface/Run.h"
00022 #include "DataFormats/Provenance/interface/LuminosityBlockID.h"
00023 #include "FWCore/ServiceRegistry/interface/Service.h"
00024
00025 #include "FWCore/Framework/interface/IOVSyncValue.h"
00026
00027 #include "CoralBase/Exception.h"
00028 #include "CoralBase/AttributeList.h"
00029 #include "CoralBase/Attribute.h"
00030 #include "CoralBase/AttributeSpecification.h"
00031 #include "CoralBase/Exception.h"
00032 #include "RelationalAccess/ISessionProxy.h"
00033 #include "RelationalAccess/ITransaction.h"
00034 #include "RelationalAccess/AccessMode.h"
00035 #include "RelationalAccess/ITypeConverter.h"
00036 #include "RelationalAccess/IQuery.h"
00037 #include "RelationalAccess/ICursor.h"
00038 #include "RelationalAccess/ISchema.h"
00039 #include "RelationalAccess/ITable.h"
00040 #include "RecoLuminosity/LumiProducer/interface/DBService.h"
00041 #include "RecoLuminosity/LumiProducer/interface/Exception.h"
00042 #include "RecoLuminosity/LumiProducer/interface/ConstantDef.h"
00043 #include "RecoLuminosity/LumiProducer/interface/DIPLumiSummary.h"
00044 #include "RecoLuminosity/LumiProducer/interface/DIPLumiDetail.h"
00045 #include "RecoLuminosity/LumiProducer/interface/DIPLuminosityRcd.h"
00046 #include "DIPLumiProducer.h"
00047 #include <iostream>
00048 #include <sstream>
00049 #include <string>
00050 #include <memory>
00051 #include <algorithm>
00052 #include <vector>
00053 #include <cstring>
00054 #include <iterator>
00055 #include <boost/foreach.hpp>
00056 #include <boost/tokenizer.hpp>
00057 #include <xercesc/dom/DOM.hpp>
00058 #include <xercesc/parsers/XercesDOMParser.hpp>
00059 #include <xercesc/util/PlatformUtils.hpp>
00060 #include <xercesc/util/XMLString.hpp>
00061
00062 #include "boost/filesystem/path.hpp"
00063 #include "boost/filesystem/operations.hpp"
00064
00065 DIPLumiProducer::DIPLumiProducer(const edm::ParameterSet& iConfig):m_connectStr(""),m_summarycachedrun(0),m_detailcachedrun(0),m_cachesize(0){
00066 setWhatProduced(this,&DIPLumiProducer::produceSummary);
00067 setWhatProduced(this,&DIPLumiProducer::produceDetail);
00068 findingRecord<DIPLuminosityRcd>();
00069 m_connectStr=iConfig.getParameter<std::string>("connect");
00070 m_cachesize=iConfig.getUntrackedParameter<unsigned int>("ncacheEntries",3);
00071 }
00072
00073 DIPLumiProducer::ReturnSummaryType
00074 DIPLumiProducer::produceSummary(const DIPLuminosityRcd&)
00075 {
00076 unsigned int currentrun=m_pcurrentTime->eventID().run();
00077 unsigned int currentls=m_pcurrentTime->luminosityBlockNumber();
00078 if(currentls==0||currentls==4294967295){
00079 return boost::shared_ptr<DIPLumiSummary>(new DIPLumiSummary());
00080 }
00081 if(m_summarycachedrun!=currentrun){
00082 fillsummarycache(currentrun,currentls);
00083 }else{
00084 if(m_summarycache.find(currentls)==m_summarycache.end()){
00085 fillsummarycache(currentrun,currentls);
00086 }
00087 }
00088 if(m_summarycache.empty()){
00089 return boost::shared_ptr<DIPLumiSummary>(new DIPLumiSummary());
00090 }
00091 if(m_summarycache.find(currentls)==m_summarycache.end()){
00092 std::vector<unsigned int> v;
00093 for(std::map<unsigned int,boost::shared_ptr<DIPLumiSummary> >::iterator it=m_summarycache.begin();it!=m_summarycache.end();++it){
00094 v.push_back(it->first);
00095 }
00096 m_summaryresult=m_summarycache[v.back()];
00097 }else{
00098 m_summaryresult=m_summarycache[currentls];
00099 }
00100 if(m_summaryresult.get()==0){
00101 return boost::shared_ptr<DIPLumiSummary>(new DIPLumiSummary());
00102 }
00103 return m_summaryresult;
00104 }
00105 DIPLumiProducer::ReturnDetailType
00106 DIPLumiProducer::produceDetail(const DIPLuminosityRcd&)
00107 {
00108 unsigned int currentrun=m_pcurrentTime->eventID().run();
00109 unsigned int currentls=m_pcurrentTime->luminosityBlockNumber();
00110 if(currentls==0||currentls==4294967295){
00111 return boost::shared_ptr<DIPLumiDetail>(new DIPLumiDetail());
00112 }
00113 if(m_detailcachedrun!=currentrun){
00114 filldetailcache(currentrun,currentls);
00115 }else{
00116 if(m_detailcache.find(currentls)==m_detailcache.end()){
00117 filldetailcache(currentrun,currentls);
00118 }
00119 }
00120 if(m_detailcache.empty()){
00121 return boost::shared_ptr<DIPLumiDetail>(new DIPLumiDetail());
00122 }
00123 if(m_detailcache.find(currentls)==m_detailcache.end()){
00124 std::vector<unsigned int> v;
00125 for(std::map<unsigned int,boost::shared_ptr<DIPLumiDetail> >::iterator it=m_detailcache.begin();it!=m_detailcache.end();++it){
00126 v.push_back(it->first);
00127 }
00128 m_detailresult=m_detailcache[v.back()];
00129 }else{
00130 m_detailresult=m_detailcache[currentls];
00131 }
00132 if(m_detailresult.get()==0){
00133 return boost::shared_ptr<DIPLumiDetail>(new DIPLumiDetail());
00134 }
00135 return m_detailresult;
00136 }
00137
00138 void
00139 DIPLumiProducer::setIntervalFor( const edm::eventsetup::EventSetupRecordKey& iKey,
00140 const edm::IOVSyncValue& iTime,
00141 edm::ValidityInterval& oValidity ) {
00142 m_pcurrentTime=&iTime;
00143 oValidity.setFirst(iTime);
00144 oValidity.setLast(iTime);
00145 }
00146
00147 void
00148 DIPLumiProducer::fillsummarycache(unsigned int runnumber,unsigned int currentlsnum){
00149 m_summarycache.clear();
00150 m_summarycachedrun=runnumber;
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 edm::Service<lumi::service::DBService> mydbservice;
00161 if( !mydbservice.isAvailable() ){
00162 throw cms::Exception("Non existing service lumi::service::DBService");
00163 }
00164 coral::ISessionProxy* session=mydbservice->connectReadOnly(m_connectStr);
00165 coral::ITypeConverter& tconverter=session->typeConverter();
00166 tconverter.setCppTypeForSqlType(std::string("float"),std::string("FLOAT(63)"));
00167 tconverter.setCppTypeForSqlType(std::string("unsigned int"),std::string("NUMBER(10)"));
00168 tconverter.setCppTypeForSqlType(std::string("unsigned short"),std::string("NUMBER(1)"));
00169 unsigned int lsmin=1;
00170 unsigned int lsmax=currentlsnum;
00171 try{
00172 session->transaction().start(true);
00173 coral::ISchema& schema=session->nominalSchema();
00174 unsigned int maxavailableLS=maxavailableLSforRun(schema,std::string("LUMI_SECTIONS"),m_summarycachedrun);
00175 if(maxavailableLS!=0 && maxavailableLS<currentlsnum){
00176 lsmax=maxavailableLS;
00177 }else if(maxavailableLS==0){
00178
00179 session->transaction().commit();
00180 mydbservice->disconnect(session);
00181 return;
00182 }
00183 if(m_cachesize!=0){
00184 lsmin=(lsmax-m_cachesize)>0 ? (lsmax-m_cachesize+1) : 1;
00185 }
00186
00187 coral::AttributeList lumisummaryBindVariables;
00188 lumisummaryBindVariables.extend("lsmin",typeid(unsigned int));
00189 lumisummaryBindVariables.extend("lsmax",typeid(unsigned int));
00190 lumisummaryBindVariables.extend("runnumber",typeid(unsigned int));
00191 lumisummaryBindVariables["runnumber"].data<unsigned int>()=m_summarycachedrun;
00192 lumisummaryBindVariables["lsmin"].data<unsigned int>()=lsmin;
00193 lumisummaryBindVariables["lsmax"].data<unsigned int>()=lsmax;
00194 std::string conditionStr("RUNNUMBER=:runnumber AND LUMISECTION>=:lsmin AND LUMISECTION<=:lsmax");
00195 coral::AttributeList lumisummaryOutput;
00196 lumisummaryOutput.extend("LUMISECTION",typeid(unsigned int));
00197 lumisummaryOutput.extend("INSTLUMI",typeid(float));
00198 lumisummaryOutput.extend("DELIVLUMISECTION",typeid(float));
00199 lumisummaryOutput.extend("LIVELUMISECTION",typeid(float));
00200 lumisummaryOutput.extend("CMS_ACTIVE",typeid(unsigned short));
00201 coral::IQuery* lumisummaryQuery=schema.newQuery();
00202 lumisummaryQuery->addToTableList(std::string("LUMI_SECTIONS"));
00203 lumisummaryQuery->addToOutputList("LUMISECTION");
00204 lumisummaryQuery->addToOutputList("INSTLUMI");
00205 lumisummaryQuery->addToOutputList("DELIVLUMISECTION");
00206 lumisummaryQuery->addToOutputList("LIVELUMISECTION");
00207 lumisummaryQuery->addToOutputList("CMS_ACTIVE");
00208 lumisummaryQuery->setCondition(conditionStr,lumisummaryBindVariables);
00209 lumisummaryQuery->defineOutput(lumisummaryOutput);
00210 coral::ICursor& lumisummarycursor=lumisummaryQuery->execute();
00211 while( lumisummarycursor.next() ){
00212 const coral::AttributeList& row=lumisummarycursor.currentRow();
00213 unsigned int lsnum=row["LUMISECTION"].data<unsigned int>();
00214 float instlumi=0.0;
00215 if(!row["INSTLUMI"].isNull()){
00216 instlumi=row["INSTLUMI"].data<float>();
00217 }
00218 float intgdellumi=0.0;
00219 if(!row["DELIVLUMISECTION"].isNull()){
00220 intgdellumi=row["DELIVLUMISECTION"].data<float>()*1000.0;
00221 }
00222 float intgreclumi=0.0;
00223 if(!row["LIVELUMISECTION"].isNull()){
00224 intgreclumi=row["LIVELUMISECTION"].data<float>()*1000.0;
00225 }
00226 unsigned short cmsalive=0;
00227 if(!row["CMS_ACTIVE"].isNull()){
00228 cmsalive=row["CMS_ACTIVE"].data<unsigned short>();
00229 }
00230 boost::shared_ptr<DIPLumiSummary> tmpls(new DIPLumiSummary(instlumi,intgdellumi,intgreclumi,cmsalive));
00231 tmpls->setOrigin(m_summarycachedrun,lsnum);
00232
00233 m_summarycache.insert(std::make_pair(lsnum,tmpls));
00234 }
00235 delete lumisummaryQuery;
00236 session->transaction().commit();
00237 }catch(const coral::Exception& er){
00238 session->transaction().rollback();
00239 mydbservice->disconnect(session);
00240 throw cms::Exception("DatabaseError ")<<er.what();
00241 }
00242 mydbservice->disconnect(session);
00243 }
00244 unsigned int
00245 DIPLumiProducer::maxavailableLSforRun(coral::ISchema& schema,const std::string&tablename,unsigned int runnumber){
00249 unsigned int result=0;
00250 coral::AttributeList bindVariables;
00251 bindVariables.extend("runnumber",typeid(unsigned int));
00252 bindVariables["runnumber"].data<unsigned int>()=runnumber;
00253 std::string conditionStr("RUNNUMBER=:runnumber");
00254 coral::AttributeList MyOutput;
00255 MyOutput.extend("maxavailablels",typeid(unsigned int));
00256 coral::IQuery* myQuery=schema.newQuery();
00257 myQuery->addToTableList(tablename);
00258 myQuery->addToOutputList("max(LUMISECTION)","maxavailablels");
00259 myQuery->setCondition(conditionStr,bindVariables);
00260 myQuery->defineOutput(MyOutput);
00261 coral::ICursor& mycursor=myQuery->execute();
00262 while( mycursor.next() ){
00263 const coral::AttributeList& row=mycursor.currentRow();
00264 if(!row["maxavailablels"].isNull()){
00265 result=row["maxavailablels"].data<unsigned int>();
00266 }
00267 }
00268 return result;
00269 }
00270 void
00271 DIPLumiProducer::filldetailcache(unsigned int runnumber,unsigned int currentlsnum){
00272 m_detailcache.clear();
00273 m_detailcachedrun=runnumber;
00274
00275
00276
00277
00278
00279 edm::Service<lumi::service::DBService> mydbservice;
00280 if( !mydbservice.isAvailable() ){
00281 throw cms::Exception("Non existing service lumi::service::DBService");
00282 }
00283 coral::ISessionProxy* session=mydbservice->connectReadOnly(m_connectStr);
00284 coral::ITypeConverter& tconverter=session->typeConverter();
00285 tconverter.setCppTypeForSqlType(std::string("float"),std::string("FLOAT(63)"));
00286 tconverter.setCppTypeForSqlType(std::string("unsigned int"),std::string("NUMBER(10)"));
00287 unsigned int lsmin=1;
00288 unsigned int lsmax=currentlsnum;
00289 try{
00290 session->transaction().start(true);
00291 coral::ISchema& schema=session->nominalSchema();
00292 unsigned int maxavailableLS=maxavailableLSforRun(schema,std::string("BUNCH_LUMI_SECTIONS"),m_summarycachedrun);
00293 if(maxavailableLS!=0 &&maxavailableLS<currentlsnum ){
00294 lsmax=maxavailableLS;
00295 }else if(maxavailableLS==0){
00296
00297 session->transaction().commit();
00298 mydbservice->disconnect(session);
00299 return;
00300 }
00301 if(m_cachesize!=0){
00302 lsmin=(lsmax-m_cachesize)>0 ? (lsmax-m_cachesize+1) : 1;
00303 }
00304 coral::AttributeList lumidetailBindVariables;
00305 lumidetailBindVariables.extend("lsmin",typeid(unsigned int));
00306 lumidetailBindVariables.extend("lsmax",typeid(unsigned int));
00307 lumidetailBindVariables.extend("runnumber",typeid(unsigned int));
00308 lumidetailBindVariables["runnumber"].data<unsigned int>()=m_detailcachedrun;
00309 lumidetailBindVariables["lsmin"].data<unsigned int>()=lsmin;
00310 lumidetailBindVariables["lsmax"].data<unsigned int>()=lsmax;
00311 std::string conditionStr("RUNNUMBER=:runnumber AND LUMISECTION>=:lsmin AND LUMISECTION<=:lsmax AND BUNCHLUMI>0 ");
00312 coral::AttributeList lumidetailOutput;
00313 lumidetailOutput.extend("LUMISECTION",typeid(unsigned int));
00314 lumidetailOutput.extend("BUNCH",typeid(unsigned int));
00315 lumidetailOutput.extend("BUNCHLUMI",typeid(float));
00316 coral::IQuery* lumidetailQuery=schema.newQuery();
00317 lumidetailQuery->addToTableList(std::string("BUNCH_LUMI_SECTIONS"));
00318 lumidetailQuery->addToOutputList("LUMISECTION");
00319 lumidetailQuery->addToOutputList("BUNCH");
00320 lumidetailQuery->addToOutputList("BUNCHLUMI");
00321 lumidetailQuery->setCondition(conditionStr,lumidetailBindVariables);
00322 lumidetailQuery->defineOutput(lumidetailOutput);
00323 coral::ICursor& lumidetailcursor=lumidetailQuery->execute();
00324 while( lumidetailcursor.next() ){
00325 const coral::AttributeList& row=lumidetailcursor.currentRow();
00326 unsigned int lsnum=row["LUMISECTION"].data<unsigned int>();
00327 if(m_detailcache.find(lsnum)==m_detailcache.end()){
00328 m_detailcache.insert(std::make_pair(lsnum,boost::shared_ptr<DIPLumiDetail>(new DIPLumiDetail)));
00329 m_detailcache[lsnum]->setOrigin(m_detailcachedrun,lsnum);
00330 }
00331 if(!row["BUNCH"].isNull()){
00332 unsigned int bxidx=row["BUNCH"].data<unsigned int>();
00333 float bxlumi=0.0;
00334 if(!row["BUNCHLUMI"].isNull()){
00335 bxlumi=row["BUNCHLUMI"].data<float>();
00336 }
00337 m_detailcache[lsnum]->fillbxdata(bxidx,bxlumi);
00338 }
00339 }
00340 delete lumidetailQuery;
00341 session->transaction().commit();
00342 }catch(const coral::Exception& er){
00343 session->transaction().rollback();
00344 mydbservice->disconnect(session);
00345 throw cms::Exception("DatabaseError ")<<er.what();
00346 }
00347 mydbservice->disconnect(session);
00348 }
00349 DIPLumiProducer::~DIPLumiProducer(){}
00350
00351 DEFINE_FWK_EVENTSETUP_SOURCE(DIPLumiProducer);