CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/RecoLuminosity/LumiProducer/plugins/DIPLumiProducer.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    LumiProducer
00004 // Class:      DIPLumiProducer
00005 // 
00009 // $Id: DIPLumiProducer.cc,v 1.13 2012/04/04 10:25:50 xiezhen Exp $
00010 
00011 //#include <memory>
00012 //#include "boost/shared_ptr.hpp"
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){//i'm in a new run
00082     fillsummarycache(currentrun,currentls);//starting ls
00083   }else{ //i'm in an old run
00084     if(m_summarycache.find(currentls)==m_summarycache.end()){//i'm not cached 
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){//i'm in a new run
00114     filldetailcache(currentrun,currentls);//starting ls
00115   }else{ //i'm in an known run
00116     if(m_detailcache.find(currentls)==m_detailcache.end()){//i'm in a unknown ls
00117       filldetailcache(currentrun,currentls);//cache all ls>=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   // queries once per cache refill
00153   //
00154   // select max(lumi_sections) as maxavailable from  cms_runtime_logger.lumi_sections where runnumber=:runnumber;
00155   //
00156   // if maxavailable<currentls: get lsmax=maxavailable ; else: get lsmax=currentls 
00157   // lsmin=lsmax-cachesize
00158   // select runnumber,lumisection,instlumi,delivlumi,livelumi from cms_runtime_logger.lumi_sections where lumisection>=:lsmin and lumisection<=:lsmax and runnumber=:runnumber;
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       //this run not existing (yet)
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     //std::cout<<"lsmin "<<lsmin<<" lsmax "<<lsmax<<std::endl;
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>();//Hz/ub
00217       }
00218       float intgdellumi=0.0;
00219       if(!row["DELIVLUMISECTION"].isNull()){
00220         intgdellumi=row["DELIVLUMISECTION"].data<float>()*1000.0;//convert to /ub
00221       }
00222       float intgreclumi=0.0;
00223       if(!row["LIVELUMISECTION"].isNull()){
00224         intgreclumi=row["LIVELUMISECTION"].data<float>()*1000.0;//convert to /ub
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       //std::cout<<"filling "<<lsnum<<std::endl;
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   //queries once per cache refill
00276   //
00277   //select lumisection,bunch,bunchlumi from cms_runtime_logger.bunch_lumi_sections where lumisection>=:lsmin and lumisection<:lsmax and runnumber=:runnumber ;
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       //this run not existing (yet)
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>();//Hz/ub
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 //define this as a plug-in
00351 DEFINE_FWK_EVENTSETUP_SOURCE(DIPLumiProducer);