CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/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.3 2012/05/02 09:24:23 xiezhen Exp $
00011 
00012 #include "FWCore/Framework/interface/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::EDProducer {
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&);
00085 
00086   virtual void beginRun(edm::Run&, edm::EventSetup const &);
00087 
00088   virtual void beginLuminosityBlock(edm::LuminosityBlock & iLBlock,
00089                                     edm::EventSetup const& iSetup);
00090   virtual void endLuminosityBlock(edm::LuminosityBlock& lumiBlock, 
00091                                   edm::EventSetup const& c);
00092   
00093   virtual void endRun(edm::Run&, edm::EventSetup const &);
00094 
00095   bool fillLumi(edm::LuminosityBlock & iLBlock);
00096   void fillLSCache(unsigned int runnum,unsigned int luminum);
00097   void writeProductsForEntry(edm::LuminosityBlock & iLBlock,unsigned int luminum);
00098   void writeEmptyProductForEntry(edm::LuminosityBlock &iLBlock);
00099   unsigned int maxavailableLSforRun(coral::ISchema& schema,const std::string&tablename,unsigned int runnumber);
00100   std::string m_connectStr;
00101   unsigned int m_cachedrun;
00102   bool m_isNullRun; //if lumi data exist for this run
00103   unsigned int m_cachesize;
00104   std::map< unsigned int,PerLSData > m_lscache;
00105 };
00106 
00107 ExpressLumiProducer::
00108 ExpressLumiProducer::ExpressLumiProducer(const edm::ParameterSet& iConfig):m_cachedrun(0),m_isNullRun(false),m_cachesize(0)
00109 {
00110   // register your products
00111   produces<LumiSummary, edm::InLumi>();
00112   produces<LumiDetails, edm::InLumi>();
00113   // set up cache
00114   m_connectStr=iConfig.getParameter<std::string>("connect");
00115   m_cachesize=iConfig.getUntrackedParameter<unsigned int>("ncacheEntries",5);
00116 }
00117 
00118 ExpressLumiProducer::~ExpressLumiProducer(){ 
00119 }
00120 
00121 //
00122 // member functions
00123 //
00124 void 
00125 ExpressLumiProducer::produce(edm::Event& e, const edm::EventSetup& iSetup)
00126 { 
00127 }
00128 void 
00129 ExpressLumiProducer::beginRun(edm::Run& run,edm::EventSetup const &iSetup)
00130 {
00131 }
00132 
00133 void 
00134 ExpressLumiProducer::writeEmptyProductForEntry(edm::LuminosityBlock &iLBlock){
00135   std::auto_ptr<LumiSummary> pOut1;
00136   std::auto_ptr<LumiDetails> pOut2;
00137   LumiSummary* pIn1=new LumiSummary;
00138   LumiDetails* pIn2=new LumiDetails;
00139   pOut1.reset(pIn1);
00140   iLBlock.put(pOut1);
00141   pOut2.reset(pIn2);
00142   iLBlock.put(pOut2);
00143 }
00144 void 
00145 ExpressLumiProducer::beginLuminosityBlock(edm::LuminosityBlock &iLBlock, edm::EventSetup const &iSetup)
00146 {
00147   unsigned int currentrun=iLBlock.run();
00148   unsigned int currentls=iLBlock.luminosityBlock();
00149   //if is null run, fill empty values and return
00150   if(m_isNullRun){
00151     writeEmptyProductForEntry(iLBlock);
00152     return;
00153   }
00154   if(m_cachedrun!=currentrun){
00155     fillLSCache(currentrun,currentls);
00156   }else{
00157     if(m_lscache.find(currentls)==m_lscache.end()){
00158       //if runnumber is cached but LS is not, this is the first LS, fill LS cache to full capacity
00159       fillLSCache(currentrun,currentls);
00160     }
00161   }
00162   if( m_lscache.empty() ){
00163     writeEmptyProductForEntry(iLBlock);
00164     return;
00165   }
00166   unsigned int lstowriteout=0;
00167   if(m_lscache.find(currentls)==m_lscache.end()){//if the currentls is not in the cache
00168     std::vector<unsigned int> v;
00169     for(std::map<unsigned int,ExpressLumiProducer::PerLSData >::iterator it=m_lscache.begin();it!=m_lscache.end();++it){
00170       v.push_back(it->first);
00171     }
00172     lstowriteout=v.back();//last available
00173   }else{//if the current ls is cached
00174     lstowriteout=currentls;
00175   }
00176   //here the presence of ls is guaranteed
00177   //std::cout<<"writing "<<runnumber<<" "<<luminum<<std::endl;
00178   if(lstowriteout==0){
00179     writeEmptyProductForEntry(iLBlock);
00180   }else{
00181     writeProductsForEntry(iLBlock,lstowriteout); 
00182   }
00183 }
00184 void 
00185 ExpressLumiProducer::endLuminosityBlock(edm::LuminosityBlock & iLBlock, edm::EventSetup const& iSetup)
00186 {
00187 }
00188 void 
00189 ExpressLumiProducer::endRun(edm::Run& run,edm::EventSetup const &iSetup)
00190 {
00191 }
00192 
00193 unsigned int
00194 ExpressLumiProducer::maxavailableLSforRun(coral::ISchema& schema,const std::string&tablename,unsigned int runnumber){
00198   unsigned int result=0;
00199   coral::AttributeList bindVariables;
00200   bindVariables.extend("runnumber",typeid(unsigned int));
00201   bindVariables["runnumber"].data<unsigned int>()=runnumber;
00202   std::string conditionStr("RUNNUMBER=:runnumber");
00203   coral::AttributeList MyOutput;
00204   MyOutput.extend("maxavailablels",typeid(unsigned int));
00205   coral::IQuery* myQuery=schema.newQuery();
00206   myQuery->addToTableList(tablename);
00207   myQuery->addToOutputList("max(LUMISECTION)","maxavailablels");
00208   myQuery->setCondition(conditionStr,bindVariables);
00209   myQuery->defineOutput(MyOutput);
00210   coral::ICursor& mycursor=myQuery->execute();
00211   while( mycursor.next() ){
00212     const coral::AttributeList& row=mycursor.currentRow();
00213     if(!row["maxavailablels"].isNull()){
00214       result=row["maxavailablels"].data<unsigned int>();
00215     }
00216   }
00217   return result;
00218 }
00219 void
00220 ExpressLumiProducer::fillLSCache(unsigned int runnumber,unsigned int currentlsnum){
00221   m_lscache.clear();
00222   m_cachedrun=runnumber;
00223   //
00224   //queries once per cache refill
00225   //
00226   //select lumisection,instlumi,delivlumi,livelumi from cms_runtime_logger.lumi_sections where lumisection>=:lsmin and lumisection<:lsmax and runnumber=:runnumber;
00227   //
00228   edm::Service<lumi::service::DBService> mydbservice;
00229   if( !mydbservice.isAvailable() ){
00230     throw cms::Exception("Non existing service lumi::service::DBService");
00231   }
00232   coral::ISessionProxy* session=mydbservice->connectReadOnly(m_connectStr);
00233   coral::ITypeConverter& tconverter=session->typeConverter();
00234   tconverter.setCppTypeForSqlType(std::string("float"),std::string("FLOAT(63)"));
00235   tconverter.setCppTypeForSqlType(std::string("unsigned int"),std::string("NUMBER(10)"));
00236   tconverter.setCppTypeForSqlType(std::string("unsigned short"),std::string("NUMBER(1)"));
00237   unsigned int lsmin=1;
00238   unsigned int lsmax=currentlsnum;
00239   try{
00240     session->transaction().start(true);
00241     coral::ISchema& schema=session->nominalSchema();
00242     unsigned int maxavailableLS=maxavailableLSforRun(schema,std::string("LUMI_SECTIONS"),m_cachedrun);
00243     if(maxavailableLS!=0 && maxavailableLS<currentlsnum){
00244       lsmax=maxavailableLS;
00245     }else if(maxavailableLS==0){
00246       //this run not existing (yet)
00247       session->transaction().commit();
00248       mydbservice->disconnect(session);
00249       return;
00250     }
00251     if(m_cachesize!=0){
00252       lsmin=(lsmax-m_cachesize)>0 ? (lsmax-m_cachesize+1) : 1;
00253     }
00254     for(unsigned int n=lsmin;n<=lsmax;++n){
00255       PerLSData l;
00256       std::vector<float> mytmp(3564,0.0);
00257       l.bunchlumivalue.swap(mytmp);
00258       std::vector<float> myerrtmp(3564,0.0);
00259       l.bunchlumierror.swap(myerrtmp);
00260       std::vector<short> myqtmp(3564,0);
00261       l.bunchlumiquality.swap(myqtmp);
00262       m_lscache.insert(std::make_pair(n,l));
00263     }
00264  
00265     coral::AttributeList lumisummaryBindVariables;
00266     lumisummaryBindVariables.extend("lsmin",typeid(unsigned int));
00267     lumisummaryBindVariables.extend("runnumber",typeid(unsigned int));
00268     lumisummaryBindVariables["runnumber"].data<unsigned int>()=m_cachedrun;
00269     lumisummaryBindVariables["lsmin"].data<unsigned int>()=lsmin;
00270     std::string conditionStr(" RUNNUMBER=:runnumber AND LUMISECTION>=:lsmin ");
00271     coral::AttributeList lumisummaryOutput;
00272     lumisummaryOutput.extend("LUMISECTION",typeid(unsigned int));
00273     lumisummaryOutput.extend("INSTLUMI",typeid(float));
00274     lumisummaryOutput.extend("DELIVLUMISECTION",typeid(float));
00275     lumisummaryOutput.extend("LIVELUMISECTION",typeid(float));
00276     lumisummaryOutput.extend("STARTORBIT",typeid(unsigned long long));
00277     if(m_cachesize!=0){
00278       lumisummaryBindVariables.extend("lsmax",typeid(unsigned int));
00279       conditionStr=conditionStr+"AND LUMISECTION<=:lsmax";
00280       lumisummaryBindVariables["lsmax"].data<unsigned int>()=lsmax;      
00281     }
00282     coral::IQuery* lumisummaryQuery=schema.newQuery();
00283     lumisummaryQuery->addToTableList(std::string("LUMI_SECTIONS"));
00284     lumisummaryQuery->addToOutputList("LUMISECTION");
00285     lumisummaryQuery->addToOutputList("INSTLUMI");
00286     lumisummaryQuery->addToOutputList("DELIVLUMISECTION");
00287     lumisummaryQuery->addToOutputList("LIVELUMISECTION");
00288     lumisummaryQuery->addToOutputList("STARTORBIT");
00289     lumisummaryQuery->setCondition(conditionStr,lumisummaryBindVariables);
00290     lumisummaryQuery->defineOutput(lumisummaryOutput);
00291     coral::ICursor& lumisummarycursor=lumisummaryQuery->execute();
00292     unsigned int rowcounter=0;
00293     while( lumisummarycursor.next() ){
00294       const coral::AttributeList& row=lumisummarycursor.currentRow();
00295       unsigned int lsnum=row["LUMISECTION"].data<unsigned int>();
00296       float instlumi=0.0;
00297       if(!row["INSTLUMI"].isNull()){
00298         instlumi=row["INSTLUMI"].data<float>();//Hz/ub
00299       }
00300       float deadfrac=1.0;
00301       float intgdellumi=0.0;
00302       float intgreclumi=0.0;
00303       unsigned long long startorbit=0;
00304       if(!row["DELIVLUMISECTION"].isNull()){
00305         intgdellumi=row["DELIVLUMISECTION"].data<float>()*1000.0;//convert to /ub
00306       }
00307       if(!row["LIVELUMISECTION"].isNull()){
00308         intgreclumi=row["LIVELUMISECTION"].data<float>()*1000.0;//convert to /ub
00309       }
00310       if(intgdellumi>0){
00311         deadfrac=1.0-intgreclumi/intgdellumi;
00312       }
00313       if(!row["STARTORBIT"].isNull()){
00314         startorbit=row["STARTORBIT"].data<unsigned long long>();//convert to /ub
00315       }
00316       unsigned long long deadcount=deadfrac*10000.0;
00317       unsigned long long bitzerocount=10000.0;
00318       PerLSData& lsdata=m_lscache[lsnum];
00319       lsdata.lsnum=lsnum;
00320       lsdata.lumivalue=instlumi; 
00321       lsdata.deadcount=deadcount;
00322       lsdata.bitzerocount=bitzerocount;
00323       lsdata.startorbit=startorbit;
00324       lsdata.numorbit=262144;
00325       ++rowcounter;
00326     }
00327     if (rowcounter==0){
00328       m_isNullRun=true;
00329     }
00330     delete lumisummaryQuery;
00331     if(m_isNullRun) return;
00332     //
00333     //queries once per cache refill
00334     //
00335     //select lumisection,bunch,bunchlumi from cms_runtime_logger.bunch_lumi_sections where lumisection>=:lsmin and lumisection<:lsmax and runnumber=:runnumber;
00336     //
00337     coral::AttributeList lumidetailBindVariables;
00338     lumidetailBindVariables.extend("lsmin",typeid(unsigned int));
00339     lumidetailBindVariables.extend("runnumber",typeid(unsigned int));
00340     lumidetailBindVariables["runnumber"].data<unsigned int>()=m_cachedrun;
00341     lumidetailBindVariables["lsmin"].data<unsigned int>()=lsmin;
00342     std::string detailconditionStr(" RUNNUMBER=:runnumber AND LUMISECTION>=:lsmin AND BUNCHLUMI>0 ");
00343     coral::AttributeList lumidetailOutput;
00344     lumidetailOutput.extend("LUMISECTION",typeid(unsigned int));
00345     lumidetailOutput.extend("BUNCH",typeid(unsigned int));
00346     lumidetailOutput.extend("BUNCHLUMI",typeid(float));
00347     if(m_cachesize!=0){
00348       lumidetailBindVariables.extend("lsmax",typeid(unsigned int));
00349       detailconditionStr=detailconditionStr+"AND LUMISECTION<=:lsmax";
00350       lumidetailBindVariables["lsmax"].data<unsigned int>()=lsmax;      
00351     }
00352     coral::IQuery* lumidetailQuery=schema.newQuery();
00353     lumidetailQuery->addToTableList(std::string("BUNCH_LUMI_SECTIONS"));
00354     lumidetailQuery->addToOutputList("LUMISECTION");
00355     lumidetailQuery->addToOutputList("BUNCH");
00356     lumidetailQuery->addToOutputList("BUNCHLUMI");
00357     lumidetailQuery->setCondition(detailconditionStr,lumidetailBindVariables);
00358     lumidetailQuery->defineOutput(lumidetailOutput);
00359     coral::ICursor& lumidetailcursor=lumidetailQuery->execute();
00360     while( lumidetailcursor.next() ){
00361       const coral::AttributeList& row=lumidetailcursor.currentRow();
00362       unsigned int lsnum=row["LUMISECTION"].data<unsigned int>();
00363       unsigned int bxidx=row["BUNCH"].data<unsigned int>();
00364       float bxlumi=row["BUNCHLUMI"].data<float>();//Hz/ub
00365       m_lscache[lsnum].bunchlumivalue[bxidx]=bxlumi;
00366     }
00367     delete lumidetailQuery;
00368     session->transaction().commit();
00369   }catch(const coral::Exception& er){
00370     session->transaction().rollback();
00371     mydbservice->disconnect(session);
00372     throw cms::Exception("DatabaseError ")<<er.what();
00373   }
00374   mydbservice->disconnect(session);
00375 }
00376 void
00377 ExpressLumiProducer::writeProductsForEntry(edm::LuminosityBlock & iLBlock,unsigned int luminum){
00378   //std::cout<<"writing runnumber,luminum "<<runnumber<<" "<<luminum<<std::endl;
00379   std::auto_ptr<LumiSummary> pOut1;
00380   std::auto_ptr<LumiDetails> pOut2;
00381   LumiSummary* pIn1=new LumiSummary;
00382   LumiDetails* pIn2=new LumiDetails;
00383   if(m_isNullRun){
00384     pIn1->setLumiVersion("DIP");
00385     pIn2->setLumiVersion("DIP");
00386     pOut1.reset(pIn1);
00387     iLBlock.put(pOut1);
00388     pOut2.reset(pIn2);
00389     iLBlock.put(pOut2);
00390     return;
00391   }
00392   PerLSData& lsdata=m_lscache[luminum];
00393   pIn1->setLumiVersion("DIP");
00394   pIn1->setLumiData(lsdata.lumivalue,0.0,0.0);
00395   pIn1->setDeadCount(lsdata.deadcount);
00396   pIn1->setBitZeroCount(lsdata.bitzerocount);
00397   pIn1->setlsnumber(lsdata.lsnum);
00398   pIn1->setOrbitData(lsdata.startorbit,lsdata.numorbit);
00399 
00400   pIn2->setLumiVersion("DIP");
00401   pIn2->fill(LumiDetails::kOCC1,lsdata.bunchlumivalue,lsdata.bunchlumierror,lsdata.bunchlumiquality);
00402   pOut1.reset(pIn1);
00403   iLBlock.put(pOut1);
00404   pOut2.reset(pIn2);
00405   iLBlock.put(pOut2);
00406 }
00407 #include "FWCore/Framework/interface/MakerMacros.h"
00408 DEFINE_FWK_MODULE(ExpressLumiProducer);