CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/CommonTools/ConditionDBWriter/interface/ConditionDBWriter.h

Go to the documentation of this file.
00001 #ifndef CommonTools_ConditionDBWriter_ConditionDBWriter_h
00002 #define CommonTools_ConditionDBWriter_ConditionDBWriter_h
00003 // -*- C++ -*-
00004 //
00005 // Package:    ConditionDBWriter
00006 // Class:      ConditionDBWriter
00007 // 
00008 // \class ConditionDBWriter 
00009 //
00010 //  Description: 
00011 
00122 //
00123 
00124 
00125 //
00126 // Original Author:  Giacomo Bruno
00127 //         Created:  May 23 10:04:31 CET 2007
00128 //
00129 //
00130 
00131 
00132 // system include files
00133 #include <memory>
00134 #include <string>
00135 #include <cstdlib>
00136 
00137 
00138 // user include files
00139 #include "FWCore/Framework/interface/Frameworkfwd.h"
00140 #include "FWCore/Framework/interface/EDAnalyzer.h"
00141 #include "FWCore/Framework/interface/Run.h"
00142 #include "CondCore/DBCommon/interface/Time.h"
00143 #include "FWCore/Framework/interface/ESHandle.h"
00144 #include "FWCore/ServiceRegistry/interface/Service.h"
00145 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00146 
00147 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00148 #include "CondCore/DBOutputService/interface/PoolDBOutputService.h"
00149 
00150 #include "FWCore/Utilities/interface/Exception.h"
00151 //#include "FWCore/Framework/interface/EventSetup.h"
00152 
00153 #include "FWCore/Framework/interface/Event.h"
00154 #include "DataFormats/Common/interface/Handle.h"
00155 
00156 
00157 template< class T >
00158 class ConditionDBWriter : public edm::EDAnalyzer {
00159   
00160 public:
00161 
00162   explicit ConditionDBWriter(const edm::ParameterSet& iConfig) : LumiBlockMode_(false), RunMode_(false), JobMode_(false), AlgoDrivenMode_(false), Time_(0), setSinceTime_(false), firstRun_(true)
00163   {
00164     edm::LogInfo("ConditionDBWriter::ConditionDBWriter()") << std::endl;
00165     SinceAppendMode_=iConfig.getParameter<bool>("SinceAppendMode");
00166     std::string IOVMode=iConfig.getParameter<std::string>("IOVMode");
00167     if (IOVMode==std::string("Job")) JobMode_=true;
00168     else if (IOVMode==std::string("Run")) RunMode_=true;
00169     else if (IOVMode==std::string("LumiBlock")) LumiBlockMode_=true;
00170     else if (IOVMode==std::string("AlgoDriven")) AlgoDrivenMode_=true;
00171     else  edm::LogError("ConditionDBWriter::ConditionDBWriter(): ERROR - unknown IOV interval write mode...will not store anything on the DB") << std::endl;
00172     Record_=iConfig.getParameter<std::string>("Record");
00173     doStore_=iConfig.getParameter<bool>("doStoreOnDB");
00174     timeFromEndRun_=iConfig.getUntrackedParameter<bool>("TimeFromEndRun", false);
00175     
00176     if(! SinceAppendMode_ ) 
00177       edm::LogError("ConditionDBWriter::endJob(): ERROR - only SinceAppendMode support!!!!");
00178   }
00179   
00180   virtual ~ConditionDBWriter()
00181   {
00182     edm::LogInfo("ConditionDBWriter::~ConditionDBWriter()") << std::endl;
00183   }
00184   
00185 private:
00186   
00187   // method to be implemented by derived class. Must return a pointer to the DB object to be stored, which must have been created with "new". The derived class looses control on it (must not "delete" it at any time in its code!) 
00188   
00189   virtual T * getNewObject()=0;
00190   
00191   
00192   // Optional methods that may be implemented (technically "overridden") in the derived classes if needed
00193   
00194   //Will be called at the beginning of the job
00195   virtual void algoBeginJob(const edm::EventSetup&){};
00196   //Will be called at the beginning of each run in the job
00197   virtual void algoBeginRun(const edm::Run &, const edm::EventSetup &){};
00198   //Will be called at the beginning of each luminosity block in the run
00199   virtual void algoBeginLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &){};
00200   //Will be called at every event
00201   virtual void algoAnalyze(const edm::Event&, const edm::EventSetup&){};
00202   //Will be called at the end of each run in the job
00203   virtual void algoEndRun(const edm::Run &, const edm::EventSetup &){};
00204   //Will be called at the end of the job
00205   virtual void algoEndJob(){};
00206 
00207   void beginJob() {}
00208 
00209   void beginRun(const edm::Run & run, const edm::EventSetup &  es)
00210   {
00211     if( firstRun_ ) {
00212       edm::LogInfo("ConditionDBWriter::beginJob") << std::endl;
00213       if( (JobMode_ || AlgoDrivenMode_) && SinceAppendMode_) setSinceTime_=true;
00214       algoBeginJob(es);
00215       firstRun_ = false;
00216     }
00217     edm::LogInfo("ConditionDBWriter::beginRun") << std::endl;
00218     if(RunMode_ && SinceAppendMode_) setSinceTime_=true;
00219     algoBeginRun(run,es);
00220   }
00221   
00222   void beginLuminosityBlock(const edm::LuminosityBlock & lumiBlock, const edm::EventSetup & iSetup)
00223   {
00224     edm::LogInfo("ConditionDBWriter::beginLuminosityBlock") << std::endl;
00225     if(LumiBlockMode_ && SinceAppendMode_) setSinceTime_=true;
00226     algoBeginLuminosityBlock(lumiBlock, iSetup);
00227   }
00228 
00229   void analyze(const edm::Event& event, const edm::EventSetup& iSetup)
00230   {
00231     if(setSinceTime_ ){
00232       setTime(); //set new since time for possible next upload to DB  
00233       setSinceTime_=false;
00234     }
00235     algoAnalyze(event, iSetup);
00236   }
00237   
00238   void endLuminosityBlock(const edm::LuminosityBlock & lumiBlock, const edm::EventSetup & es)
00239   {
00240     edm::LogInfo("ConditionDBWriter::endLuminosityBlock") << std::endl;
00241     algoEndLuminosityBlock(lumiBlock, es);
00242     
00243     if(LumiBlockMode_){
00244       
00245       T * objPointer = getNewObject();
00246       
00247       if(objPointer ){
00248         storeOnDb(objPointer);
00249       }
00250       else {
00251         edm::LogError("ConditionDBWriter::endLuminosityblock(): ERROR - requested to store on DB on a Lumi Block based interval, but received null pointer...will not store anything on the DB") << std::endl;
00252       }
00253     }
00254   }
00255   
00256   virtual void algoEndLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &){};
00257 
00258   void endRun(const edm::Run & run, const edm::EventSetup & es)
00259   {
00260     edm::LogInfo("ConditionDBWriter::endRun") << std::endl;
00261     
00262     algoEndRun(run, es);
00263     
00264     if(RunMode_){
00265       
00266       T * objPointer = getNewObject();
00267       
00268       if(objPointer ){
00269         if( timeFromEndRun_ ) Time_ = run.id().run();
00270         storeOnDb(objPointer);
00271       }
00272       else {
00273         edm::LogError("ConditionDBWriter::endRun(): ERROR - requested to store on DB on a Run based interval, but received null pointer...will not store anything on the DB") << std::endl;
00274       }
00275     }
00276   }
00277   
00278   void endJob()
00279   {
00280     edm::LogInfo("ConditionDBWriter::endJob") << std::endl;
00281     
00282     algoEndJob();
00283     
00284     if(JobMode_){
00285       
00286       T * objPointer = getNewObject();
00287       
00288       if( objPointer ){
00289         storeOnDb(objPointer);
00290       }
00291       
00292       else {
00293         
00294         edm::LogError("ConditionDBWriter::endJob(): ERROR - requested to store on DB on a Job based interval, but received null pointer...will not store anything on the DB") << std::endl;
00295       }
00296     }
00297   }
00298 
00299   void storeOnDb(T * objPointer)
00300   {
00301     edm::LogInfo("ConditionDBWriter::storeOnDb ")  << std::endl;
00302     
00303     setSinceTime_=true;
00304     
00305     if(! objPointer) {
00306       edm::LogError("ConditionDBWriter: Pointer to object has not been set...storing no data on DB") ;
00307       return;
00308     }
00309     
00310     //And now write  data in DB
00311     if( !doStore_ ) return;
00312     edm::Service<cond::service::PoolDBOutputService> mydbservice;
00313     if (!  mydbservice.isAvailable() ) {
00314       edm::LogError("ConditionDBWriter")<<"PoolDBOutputService is unavailable"<<std::endl;
00315       return;
00316     }
00317     
00318     cond::Time_t since = 
00319       ( mydbservice->isNewTagRequest(Record_) && !timeFromEndRun_ ) ? mydbservice->beginOfTime() : Time_;
00320 
00321     edm::LogInfo("ConditionDBWriter") << "appending a new object to tag " 
00322                                       <<Record_ <<" in since mode " << std::endl;
00323     mydbservice->writeOne<T>(objPointer, since, Record_);
00324   }
00325 
00326   void setTime()
00327   {
00328     edm::Service<cond::service::PoolDBOutputService> mydbservice;
00329     
00330     if( mydbservice.isAvailable() ){
00331       Time_ = mydbservice->currentTime();
00332       edm::LogInfo("ConditionDBWriter::setTime: time set to ") << Time_ << std::endl;
00333     }
00334     else{
00335       edm::LogError("ConditionDBWriter::setTime(): PoolDBOutputService is not available...cannot set current time") << std::endl;
00336     }
00337   }
00338 
00339 protected:
00340 
00341   // This method should be called by the derived class only if it support the algodriven mode; this method will trigger a call of  the getNewObject method, but only if algoDrivenMode is chosen
00342 
00343   void storeOnDbNow()
00344   {
00345     T * objPointer = 0;
00346     
00347     if(AlgoDrivenMode_){
00348       
00349       setSinceTime_=true;
00350       
00351       objPointer = getNewObject();
00352       
00353       if (!objPointer ) {
00354         edm::LogError("ConditionDBWriter::storeOnDbNow: ERROR - requested to store on DB a new object (module configuration is algo driven based IOV), but received NULL pointer...will not store anything on the DB") << std::endl;
00355         return;
00356       }
00357       else {storeOnDb(objPointer);}
00358       
00359     }
00360     else {
00361       
00362       edm::LogError("ConditionDBWriter::storeOnDbNow(): ERROR - received a direct request from concrete algorithm to store on DB a new object, but module configuration is not to store on DB on an algo driven based interval...will not store anything on the DB") << std::endl;
00363       return;
00364     }
00365   }
00366 
00367   // utility method: it returns the lastly set IOV time (till or since according to what was chosen in the configuration)
00368 
00369   cond::Time_t timeOfLastIOV(){return Time_;}
00370 
00372   void setDoStore(const bool doStore) {doStore_ = doStore;}
00373 
00374 private:
00375   
00376   bool SinceAppendMode_; // till or since append mode 
00377 
00378   bool LumiBlockMode_; //LumiBlock since/till time
00379   bool RunMode_; //
00380   bool JobMode_;
00381   bool AlgoDrivenMode_;
00382   bool doStore_;
00383 
00384   std::string Record_;
00385   cond::Time_t Time_; //time until which the DB object is valid. It is taken from the time of the first event analyzed. The end of the validity is infinity. However as soon as a new DB object with a later start time is inserted, the end time of this one becomes the start time of the new one. 
00386 
00387   bool setSinceTime_;
00388 
00389   bool firstRun_;
00390 
00391   bool timeFromEndRun_;
00392 };
00393 
00394 #endif