00001
00002
00003
00004
00005
00009
00010
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
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;
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
00111 produces<LumiSummary, edm::InLumi>();
00112 produces<LumiDetails, edm::InLumi>();
00113
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
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
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
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()){
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();
00173 }else{
00174 lstowriteout=currentls;
00175 }
00176
00177
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
00225
00226
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
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>();
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;
00306 }
00307 if(!row["LIVELUMISECTION"].isNull()){
00308 intgreclumi=row["LIVELUMISECTION"].data<float>()*1000.0;
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>();
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
00334
00335
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>();
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
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);