00001
00002
00003
00004
00005
00009
00010
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
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;
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
00105 produces<LumiSummary, edm::InLumi>();
00106 produces<LumiDetails, edm::InLumi>();
00107
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
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
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
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()){
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();
00163 }else{
00164 lstowriteout=currentls;
00165 }
00166
00167
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
00207
00208
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
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>();
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;
00288 }
00289 if(!row["LIVELUMISECTION"].isNull()){
00290 intgreclumi=row["LIVELUMISECTION"].data<float>()*1000.0;
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>();
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
00316
00317
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>();
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
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);