CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoLuminosity/LumiProducer/plugins/ExpressLumiProducer.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    LumiProducer
00004 // Class:      ExpressLumiProducer
00005 // 
00009 // read lumi from dip database and dump to express stream
00010 // $Id: ExpressLumiProducer.cc,v 1.4 2013/05/17 20:54:13 chrjones Exp $
00011 
00012 #include "FWCore/Framework/interface/one/EDProducer.h"
00013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00014 #include "FWCore/Framework/interface/Event.h"
00015 #include "FWCore/Framework/interface/LuminosityBlock.h"
00016 #include "FWCore/Framework/interface/Run.h"
00017 #include "DataFormats/Provenance/interface/BranchType.h"
00018 #include "DataFormats/Provenance/interface/LuminosityBlockID.h"
00019 #include "DataFormats/Luminosity/interface/LumiSummaryRunHeader.h"
00020 #include "DataFormats/Luminosity/interface/LumiSummary.h"
00021 #include "DataFormats/Luminosity/interface/LumiDetails.h"
00022 #include "FWCore/ServiceRegistry/interface/Service.h"
00023 #include "FWCore/Framework/interface/EventSetup.h"
00024 
00025 #include "CoralBase/Exception.h"
00026 #include "CoralBase/AttributeList.h"
00027 #include "CoralBase/Attribute.h"
00028 #include "CoralBase/AttributeSpecification.h"
00029 #include "CoralBase/Exception.h"
00030 #include "CoralBase/Blob.h"
00031 #include "RelationalAccess/ISessionProxy.h"
00032 #include "RelationalAccess/ITransaction.h"
00033 #include "RelationalAccess/AccessMode.h"
00034 #include "RelationalAccess/ITypeConverter.h"
00035 #include "RelationalAccess/IQuery.h"
00036 #include "RelationalAccess/ICursor.h"
00037 #include "RelationalAccess/ISchema.h"
00038 #include "RelationalAccess/ITable.h"
00039 
00040 #include "RecoLuminosity/LumiProducer/interface/DBService.h"
00041 #include "RecoLuminosity/LumiProducer/interface/Exception.h"
00042 #include "RecoLuminosity/LumiProducer/interface/ConstantDef.h"
00043 #include <iostream>
00044 #include <sstream>
00045 #include <string>
00046 #include <memory>
00047 #include <algorithm>
00048 #include <vector>
00049 #include <cstring>
00050 #include <iterator>
00051 #include <boost/foreach.hpp>
00052 #include <boost/tokenizer.hpp>
00053 #include "boost/filesystem/path.hpp"
00054 #include "boost/filesystem/operations.hpp"
00055 
00056 namespace edm {
00057   class EventSetup;
00058 }
00059 
00060 //
00061 // class declaration
00062 //
00063 class ExpressLumiProducer : public edm::one::EDProducer<edm::BeginLuminosityBlockProducer> {
00064 public:
00065   struct PerLSData{
00066     unsigned int lsnum;
00067     float lumivalue;
00068     unsigned long long deadcount;
00069     unsigned int numorbit;
00070     unsigned int startorbit;
00071     unsigned int bitzerocount;
00072     std::vector<float> bunchlumivalue;
00073     std::vector<float> bunchlumierror;
00074     std::vector<short> bunchlumiquality;
00075   };
00076   
00077   explicit ExpressLumiProducer(const edm::ParameterSet&);
00078   
00079   ~ExpressLumiProducer();
00080   
00081 private:
00082   
00083 
00084   virtual void produce(edm::Event&, const edm::EventSetup&) override final;
00085 
00086   virtual void beginLuminosityBlockProduce(edm::LuminosityBlock & iLBlock,
00087                                     edm::EventSetup const& iSetup) override final;
00088 
00089   bool fillLumi(edm::LuminosityBlock & iLBlock);
00090   void fillLSCache(unsigned int runnum,unsigned int luminum);
00091   void writeProductsForEntry(edm::LuminosityBlock & iLBlock,unsigned int luminum);
00092   void writeEmptyProductForEntry(edm::LuminosityBlock &iLBlock);
00093   unsigned int maxavailableLSforRun(coral::ISchema& schema,const std::string&tablename,unsigned int runnumber);
00094   std::string m_connectStr;
00095   unsigned int m_cachedrun;
00096   bool m_isNullRun; //if lumi data exist for this run
00097   unsigned int m_cachesize;
00098   std::map< unsigned int,PerLSData > m_lscache;
00099 };
00100 
00101 ExpressLumiProducer::
00102 ExpressLumiProducer::ExpressLumiProducer(const edm::ParameterSet& iConfig):m_cachedrun(0),m_isNullRun(false),m_cachesize(0)
00103 {
00104   // register your products
00105   produces<LumiSummary, edm::InLumi>();
00106   produces<LumiDetails, edm::InLumi>();
00107   // set up cache
00108   m_connectStr=iConfig.getParameter<std::string>("connect");
00109   m_cachesize=iConfig.getUntrackedParameter<unsigned int>("ncacheEntries",5);
00110 }
00111 
00112 ExpressLumiProducer::~ExpressLumiProducer(){ 
00113 }
00114 
00115 //
00116 // member functions
00117 //
00118 void 
00119 ExpressLumiProducer::produce(edm::Event& e, const edm::EventSetup& iSetup)
00120 { 
00121 }
00122 
00123 void 
00124 ExpressLumiProducer::writeEmptyProductForEntry(edm::LuminosityBlock &iLBlock){
00125   std::auto_ptr<LumiSummary> pOut1;
00126   std::auto_ptr<LumiDetails> pOut2;
00127   LumiSummary* pIn1=new LumiSummary;
00128   LumiDetails* pIn2=new LumiDetails;
00129   pOut1.reset(pIn1);
00130   iLBlock.put(pOut1);
00131   pOut2.reset(pIn2);
00132   iLBlock.put(pOut2);
00133 }
00134 void 
00135 ExpressLumiProducer::beginLuminosityBlockProduce(edm::LuminosityBlock &iLBlock, edm::EventSetup const &iSetup)
00136 {
00137   unsigned int currentrun=iLBlock.run();
00138   unsigned int currentls=iLBlock.luminosityBlock();
00139   //if is null run, fill empty values and return
00140   if(m_isNullRun){
00141     writeEmptyProductForEntry(iLBlock);
00142     return;
00143   }
00144   if(m_cachedrun!=currentrun){
00145     fillLSCache(currentrun,currentls);
00146   }else{
00147     if(m_lscache.find(currentls)==m_lscache.end()){
00148       //if runnumber is cached but LS is not, this is the first LS, fill LS cache to full capacity
00149       fillLSCache(currentrun,currentls);
00150     }
00151   }
00152   if( m_lscache.empty() ){
00153     writeEmptyProductForEntry(iLBlock);
00154     return;
00155   }
00156   unsigned int lstowriteout=0;
00157   if(m_lscache.find(currentls)==m_lscache.end()){//if the currentls is not in the cache
00158     std::vector<unsigned int> v;
00159     for(std::map<unsigned int,ExpressLumiProducer::PerLSData >::iterator it=m_lscache.begin();it!=m_lscache.end();++it){
00160       v.push_back(it->first);
00161     }
00162     lstowriteout=v.back();//last available
00163   }else{//if the current ls is cached
00164     lstowriteout=currentls;
00165   }
00166   //here the presence of ls is guaranteed
00167   //std::cout<<"writing "<<runnumber<<" "<<luminum<<std::endl;
00168   if(lstowriteout==0){
00169     writeEmptyProductForEntry(iLBlock);
00170   }else{
00171     writeProductsForEntry(iLBlock,lstowriteout); 
00172   }
00173 }
00174 
00175 unsigned int
00176 ExpressLumiProducer::maxavailableLSforRun(coral::ISchema& schema,const std::string&tablename,unsigned int runnumber){
00180   unsigned int result=0;
00181   coral::AttributeList bindVariables;
00182   bindVariables.extend("runnumber",typeid(unsigned int));
00183   bindVariables["runnumber"].data<unsigned int>()=runnumber;
00184   std::string conditionStr("RUNNUMBER=:runnumber");
00185   coral::AttributeList MyOutput;
00186   MyOutput.extend("maxavailablels",typeid(unsigned int));
00187   coral::IQuery* myQuery=schema.newQuery();
00188   myQuery->addToTableList(tablename);
00189   myQuery->addToOutputList("max(LUMISECTION)","maxavailablels");
00190   myQuery->setCondition(conditionStr,bindVariables);
00191   myQuery->defineOutput(MyOutput);
00192   coral::ICursor& mycursor=myQuery->execute();
00193   while( mycursor.next() ){
00194     const coral::AttributeList& row=mycursor.currentRow();
00195     if(!row["maxavailablels"].isNull()){
00196       result=row["maxavailablels"].data<unsigned int>();
00197     }
00198   }
00199   return result;
00200 }
00201 void
00202 ExpressLumiProducer::fillLSCache(unsigned int runnumber,unsigned int currentlsnum){
00203   m_lscache.clear();
00204   m_cachedrun=runnumber;
00205   //
00206   //queries once per cache refill
00207   //
00208   //select lumisection,instlumi,delivlumi,livelumi from cms_runtime_logger.lumi_sections where lumisection>=:lsmin and lumisection<:lsmax and runnumber=:runnumber;
00209   //
00210   edm::Service<lumi::service::DBService> mydbservice;
00211   if( !mydbservice.isAvailable() ){
00212     throw cms::Exception("Non existing service lumi::service::DBService");
00213   }
00214   coral::ISessionProxy* session=mydbservice->connectReadOnly(m_connectStr);
00215   coral::ITypeConverter& tconverter=session->typeConverter();
00216   tconverter.setCppTypeForSqlType(std::string("float"),std::string("FLOAT(63)"));
00217   tconverter.setCppTypeForSqlType(std::string("unsigned int"),std::string("NUMBER(10)"));
00218   tconverter.setCppTypeForSqlType(std::string("unsigned short"),std::string("NUMBER(1)"));
00219   unsigned int lsmin=1;
00220   unsigned int lsmax=currentlsnum;
00221   try{
00222     session->transaction().start(true);
00223     coral::ISchema& schema=session->nominalSchema();
00224     unsigned int maxavailableLS=maxavailableLSforRun(schema,std::string("LUMI_SECTIONS"),m_cachedrun);
00225     if(maxavailableLS!=0 && maxavailableLS<currentlsnum){
00226       lsmax=maxavailableLS;
00227     }else if(maxavailableLS==0){
00228       //this run not existing (yet)
00229       session->transaction().commit();
00230       mydbservice->disconnect(session);
00231       return;
00232     }
00233     if(m_cachesize!=0){
00234       lsmin=(lsmax-m_cachesize)>0 ? (lsmax-m_cachesize+1) : 1;
00235     }
00236     for(unsigned int n=lsmin;n<=lsmax;++n){
00237       PerLSData l;
00238       std::vector<float> mytmp(3564,0.0);
00239       l.bunchlumivalue.swap(mytmp);
00240       std::vector<float> myerrtmp(3564,0.0);
00241       l.bunchlumierror.swap(myerrtmp);
00242       std::vector<short> myqtmp(3564,0);
00243       l.bunchlumiquality.swap(myqtmp);
00244       m_lscache.insert(std::make_pair(n,l));
00245     }
00246  
00247     coral::AttributeList lumisummaryBindVariables;
00248     lumisummaryBindVariables.extend("lsmin",typeid(unsigned int));
00249     lumisummaryBindVariables.extend("runnumber",typeid(unsigned int));
00250     lumisummaryBindVariables["runnumber"].data<unsigned int>()=m_cachedrun;
00251     lumisummaryBindVariables["lsmin"].data<unsigned int>()=lsmin;
00252     std::string conditionStr(" RUNNUMBER=:runnumber AND LUMISECTION>=:lsmin ");
00253     coral::AttributeList lumisummaryOutput;
00254     lumisummaryOutput.extend("LUMISECTION",typeid(unsigned int));
00255     lumisummaryOutput.extend("INSTLUMI",typeid(float));
00256     lumisummaryOutput.extend("DELIVLUMISECTION",typeid(float));
00257     lumisummaryOutput.extend("LIVELUMISECTION",typeid(float));
00258     lumisummaryOutput.extend("STARTORBIT",typeid(unsigned long long));
00259     if(m_cachesize!=0){
00260       lumisummaryBindVariables.extend("lsmax",typeid(unsigned int));
00261       conditionStr=conditionStr+"AND LUMISECTION<=:lsmax";
00262       lumisummaryBindVariables["lsmax"].data<unsigned int>()=lsmax;      
00263     }
00264     coral::IQuery* lumisummaryQuery=schema.newQuery();
00265     lumisummaryQuery->addToTableList(std::string("LUMI_SECTIONS"));
00266     lumisummaryQuery->addToOutputList("LUMISECTION");
00267     lumisummaryQuery->addToOutputList("INSTLUMI");
00268     lumisummaryQuery->addToOutputList("DELIVLUMISECTION");
00269     lumisummaryQuery->addToOutputList("LIVELUMISECTION");
00270     lumisummaryQuery->addToOutputList("STARTORBIT");
00271     lumisummaryQuery->setCondition(conditionStr,lumisummaryBindVariables);
00272     lumisummaryQuery->defineOutput(lumisummaryOutput);
00273     coral::ICursor& lumisummarycursor=lumisummaryQuery->execute();
00274     unsigned int rowcounter=0;
00275     while( lumisummarycursor.next() ){
00276       const coral::AttributeList& row=lumisummarycursor.currentRow();
00277       unsigned int lsnum=row["LUMISECTION"].data<unsigned int>();
00278       float instlumi=0.0;
00279       if(!row["INSTLUMI"].isNull()){
00280         instlumi=row["INSTLUMI"].data<float>();//Hz/ub
00281       }
00282       float deadfrac=1.0;
00283       float intgdellumi=0.0;
00284       float intgreclumi=0.0;
00285       unsigned long long startorbit=0;
00286       if(!row["DELIVLUMISECTION"].isNull()){
00287         intgdellumi=row["DELIVLUMISECTION"].data<float>()*1000.0;//convert to /ub
00288       }
00289       if(!row["LIVELUMISECTION"].isNull()){
00290         intgreclumi=row["LIVELUMISECTION"].data<float>()*1000.0;//convert to /ub
00291       }
00292       if(intgdellumi>0){
00293         deadfrac=1.0-intgreclumi/intgdellumi;
00294       }
00295       if(!row["STARTORBIT"].isNull()){
00296         startorbit=row["STARTORBIT"].data<unsigned long long>();//convert to /ub
00297       }
00298       unsigned long long deadcount=deadfrac*10000.0;
00299       unsigned long long bitzerocount=10000.0;
00300       PerLSData& lsdata=m_lscache[lsnum];
00301       lsdata.lsnum=lsnum;
00302       lsdata.lumivalue=instlumi; 
00303       lsdata.deadcount=deadcount;
00304       lsdata.bitzerocount=bitzerocount;
00305       lsdata.startorbit=startorbit;
00306       lsdata.numorbit=262144;
00307       ++rowcounter;
00308     }
00309     if (rowcounter==0){
00310       m_isNullRun=true;
00311     }
00312     delete lumisummaryQuery;
00313     if(m_isNullRun) return;
00314     //
00315     //queries once per cache refill
00316     //
00317     //select lumisection,bunch,bunchlumi from cms_runtime_logger.bunch_lumi_sections where lumisection>=:lsmin and lumisection<:lsmax and runnumber=:runnumber;
00318     //
00319     coral::AttributeList lumidetailBindVariables;
00320     lumidetailBindVariables.extend("lsmin",typeid(unsigned int));
00321     lumidetailBindVariables.extend("runnumber",typeid(unsigned int));
00322     lumidetailBindVariables["runnumber"].data<unsigned int>()=m_cachedrun;
00323     lumidetailBindVariables["lsmin"].data<unsigned int>()=lsmin;
00324     std::string detailconditionStr(" RUNNUMBER=:runnumber AND LUMISECTION>=:lsmin AND BUNCHLUMI>0 ");
00325     coral::AttributeList lumidetailOutput;
00326     lumidetailOutput.extend("LUMISECTION",typeid(unsigned int));
00327     lumidetailOutput.extend("BUNCH",typeid(unsigned int));
00328     lumidetailOutput.extend("BUNCHLUMI",typeid(float));
00329     if(m_cachesize!=0){
00330       lumidetailBindVariables.extend("lsmax",typeid(unsigned int));
00331       detailconditionStr=detailconditionStr+"AND LUMISECTION<=:lsmax";
00332       lumidetailBindVariables["lsmax"].data<unsigned int>()=lsmax;      
00333     }
00334     coral::IQuery* lumidetailQuery=schema.newQuery();
00335     lumidetailQuery->addToTableList(std::string("BUNCH_LUMI_SECTIONS"));
00336     lumidetailQuery->addToOutputList("LUMISECTION");
00337     lumidetailQuery->addToOutputList("BUNCH");
00338     lumidetailQuery->addToOutputList("BUNCHLUMI");
00339     lumidetailQuery->setCondition(detailconditionStr,lumidetailBindVariables);
00340     lumidetailQuery->defineOutput(lumidetailOutput);
00341     coral::ICursor& lumidetailcursor=lumidetailQuery->execute();
00342     while( lumidetailcursor.next() ){
00343       const coral::AttributeList& row=lumidetailcursor.currentRow();
00344       unsigned int lsnum=row["LUMISECTION"].data<unsigned int>();
00345       unsigned int bxidx=row["BUNCH"].data<unsigned int>();
00346       float bxlumi=row["BUNCHLUMI"].data<float>();//Hz/ub
00347       m_lscache[lsnum].bunchlumivalue[bxidx]=bxlumi;
00348     }
00349     delete lumidetailQuery;
00350     session->transaction().commit();
00351   }catch(const coral::Exception& er){
00352     session->transaction().rollback();
00353     mydbservice->disconnect(session);
00354     throw cms::Exception("DatabaseError ")<<er.what();
00355   }
00356   mydbservice->disconnect(session);
00357 }
00358 void
00359 ExpressLumiProducer::writeProductsForEntry(edm::LuminosityBlock & iLBlock,unsigned int luminum){
00360   //std::cout<<"writing runnumber,luminum "<<runnumber<<" "<<luminum<<std::endl;
00361   std::auto_ptr<LumiSummary> pOut1;
00362   std::auto_ptr<LumiDetails> pOut2;
00363   LumiSummary* pIn1=new LumiSummary;
00364   LumiDetails* pIn2=new LumiDetails;
00365   if(m_isNullRun){
00366     pIn1->setLumiVersion("DIP");
00367     pIn2->setLumiVersion("DIP");
00368     pOut1.reset(pIn1);
00369     iLBlock.put(pOut1);
00370     pOut2.reset(pIn2);
00371     iLBlock.put(pOut2);
00372     return;
00373   }
00374   PerLSData& lsdata=m_lscache[luminum];
00375   pIn1->setLumiVersion("DIP");
00376   pIn1->setLumiData(lsdata.lumivalue,0.0,0.0);
00377   pIn1->setDeadCount(lsdata.deadcount);
00378   pIn1->setBitZeroCount(lsdata.bitzerocount);
00379   pIn1->setlsnumber(lsdata.lsnum);
00380   pIn1->setOrbitData(lsdata.startorbit,lsdata.numorbit);
00381 
00382   pIn2->setLumiVersion("DIP");
00383   pIn2->fill(LumiDetails::kOCC1,lsdata.bunchlumivalue,lsdata.bunchlumierror,lsdata.bunchlumiquality);
00384   pOut1.reset(pIn1);
00385   iLBlock.put(pOut1);
00386   pOut2.reset(pIn2);
00387   iLBlock.put(pOut2);
00388 }
00389 #include "FWCore/Framework/interface/MakerMacros.h"
00390 DEFINE_FWK_MODULE(ExpressLumiProducer);