CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ConditionDBWriter.h
Go to the documentation of this file.
1 #ifndef CommonTools_ConditionDBWriter_ConditionDBWriter_h
2 #define CommonTools_ConditionDBWriter_ConditionDBWriter_h
3 // -*- C++ -*-
4 //
5 // Package: ConditionDBWriter
6 // Class: ConditionDBWriter
7 //
8 // \class ConditionDBWriter
9 //
10 // Description:
11 
12 // Implementation:
13 
14 // This class can be very useful whenever a CMSSW application needs to store data
15 // to the offline DB. Typically such applications require access to event data
16 // and/or need to be notified about the start of Run, Lumi section in order
17 // to set a correct Interval Of Validity (IOV) for the data they have to store.
18 // Therefore the FWK EDAnalyzer is an excellent candidate for the implementation
19 // of such applications; this is the reason why this class inherits from
20 // the EDAnalyzer class.
21 
22 // The user class should inherit from this class.
23 // The templated type must be the type of the object that
24 // has to be written on the DB (e.g. MyCalibration). Examples of use of
25 // this class can be found in package CalibTracker/SiStripChannelGain. Have a
26 // look also at the test/ directory for examples of full cfg files.
27 
28 // The user must implement in his derived class the abstract method below
29 
30 // virtual MyCalibration * getNewObject()=0;
31 
32 // in this method, the user must create a new instance of the DB object and
33 // return a pointer to it. The object must be created with "new" and never
34 // be deleted by the user: it will be the FWK that takes control over it.
35 
36 // The user can optionally implement the following methods
37 
38 // //Will be called at the beginning of the job
39 // virtual void algoBeginJob(const edm::EventSetup&){};
40 // //Will be called at the beginning of each run in the job
41 // virtual void algoBeginRun(const edm::Run &, const edm::EventSetup &){};
42 // //Will be called at the beginning of each luminosity block in the run
43 // virtual void algoBeginLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &){};
44 // //Will be called at every event
45 // virtual void algoAnalyze(const edm::Event&, const edm::EventSetup&){};
46 // //Will be called at the end of each run in the job
47 // virtual void algoEndRun(const edm::Run &, const edm::EventSetup &){};
48 // //Will be called at the end of the job
49 // virtual void algoEndJob(){};
50 
51 // where he can access information needed to build his object. For instance, if
52 // he is computing a calibration that is computed as the mean of a certain
53 // quantity that varies from event to event, he will implement the algoAnalyze
54 // method.
55 
56 // The important part is the IOV setting. The advantage of using this class is
57 // that this setting is performed almost automatically: the only thing
58 // that the user has to do is to pass prescriptions about the IOV setting
59 // in the configuration of his module. A typical
60 // configuration is as follows:
61 
62 
63 // module prod = SiStripGainRandomCalculator {
64 
65 // #parameters of the derived class
66 // double MinPositiveGain = 0.1
67 // double MeanGain = 1
68 // double SigmaGain = 0
69 // untracked bool printDebug = true
70 
71 // #parameters of the base class
72 // string IOVMode = "Run"
73 // bool SinceAppendMode = true
74 // string Record = "SiStripApvGainRcd"
75 
76 // }
77 
78 // Two subsets of parameters can be found. The first subset contains the specific
79 // parameters of the user class, which is called in this case
80 // SiStripGainRandomCalculator. The second subset contains the parameters of
81 // the base class. These are the following:
82 
83 // 1) string IOVMode
84 
85 // 4 possible values can be given: "Job", "Run", "LumiBlock" and "AlgoDriven"
86 // This card determines the length of the IOV. In other words, together with
87 // the number of Lumysections/runs the user has decided to run his application,
88 // this card determines the number of objects that will be stored on the DB
89 // (the getNewObject method will be called as many times).
90 // For example if the user is running on the events of one Run, which has
91 // 10 luminosity sections and chooses the "LumiBlock" mode, then 10 objects
92 // with corresponding IOV will be written. If the "Job" mode is chosen, only one
93 // object will be stored irrespective of the dataset on which the user is
94 // running.
95 // The "AlgoDriven" option is special. If this choice is made, then it is
96 // up to the user to tell in the code when the getNewObject method must be
97 // called. This can be done by calling the method below void storeOnDbNow()
98 // must be invoked whenever a certain condition that justifies the start/end
99 // of an IOV is met.
100 
101 // 2) bool SinceAppendMode
102 
103 // obsolete option
104 // now ONLY Since append mode is supported
105 
106 
107 //
108 // WARNING: due to the policy of the framework, objects SHALL be stored
109 // in IOV chronological order. If you have 10 runs, then execute your application starting from run 1 and not for example in two steps: first from Run 6 to Run 10 and then from Run 1 to Run 6.
110 
111 
112 // 3)string Record
113 
114 // this is the eventsetup record of your object.
115 
116 
117 
118 //
119 // Original Author: Giacomo Bruno
120 // Created: May 23 10:04:31 CET 2007
121 //
122 //
123 
124 
125 // system include files
126 #include <memory>
127 #include <string>
128 #include <cstdlib>
129 
130 
131 // user include files
139 
142 
144 //#include "FWCore/Framework/interface/EventSetup.h"
145 
148 
149 
150 template< class T >
152 
153 public:
154 
156  {
157  edm::LogInfo("ConditionDBWriter::ConditionDBWriter()") << std::endl;
158  SinceAppendMode_=iConfig.getParameter<bool>("SinceAppendMode");
159  std::string IOVMode=iConfig.getParameter<std::string>("IOVMode");
160  if (IOVMode==std::string("Job")) JobMode_=true;
161  else if (IOVMode==std::string("Run")) RunMode_=true;
162  else if (IOVMode==std::string("LumiBlock")) LumiBlockMode_=true;
163  else if (IOVMode==std::string("AlgoDriven")) AlgoDrivenMode_=true;
164  else edm::LogError("ConditionDBWriter::ConditionDBWriter(): ERROR - unknown IOV interval write mode...will not store anything on the DB") << std::endl;
165  Record_=iConfig.getParameter<std::string>("Record");
166  doStore_=iConfig.getParameter<bool>("doStoreOnDB");
167 
168  if(! SinceAppendMode_ )
169  edm::LogError("ConditionDBWriter::endJob(): ERROR - only SinceAppendMode support!!!!");
170  }
171 
173  {
174  edm::LogInfo("ConditionDBWriter::~ConditionDBWriter()") << std::endl;
175  }
176 
177 private:
178 
179  // 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!)
180 
181  virtual T * getNewObject()=0;
182 
183 
184  // Optional methods that may be implemented (technically "overridden") in the derived classes if needed
185 
186  //Will be called at the beginning of the job
187  virtual void algoBeginJob(const edm::EventSetup&){};
188  //Will be called at the beginning of each run in the job
189  virtual void algoBeginRun(const edm::Run &, const edm::EventSetup &){};
190  //Will be called at the beginning of each luminosity block in the run
192  //Will be called at every event
193  virtual void algoAnalyze(const edm::Event&, const edm::EventSetup&){};
194  //Will be called at the end of each run in the job
195  virtual void algoEndRun(const edm::Run &, const edm::EventSetup &){};
196  //Will be called at the end of the job
197  virtual void algoEndJob(){};
198 
199  void beginJob() {}
200 
201  void beginRun(const edm::Run & run, const edm::EventSetup & es)
202  {
203  if( firstRun_ ) {
204  edm::LogInfo("ConditionDBWriter::beginJob") << std::endl;
206  algoBeginJob(es);
207  firstRun_ = false;
208  }
209  edm::LogInfo("ConditionDBWriter::beginRun") << std::endl;
211  algoBeginRun(run,es);
212  }
213 
214  void beginLuminosityBlock(const edm::LuminosityBlock & lumiBlock, const edm::EventSetup & iSetup)
215  {
216  edm::LogInfo("ConditionDBWriter::beginLuminosityBlock") << std::endl;
218  algoBeginLuminosityBlock(lumiBlock, iSetup);
219  }
220 
221  void analyze(const edm::Event& event, const edm::EventSetup& iSetup)
222  {
223  if(setSinceTime_ ){
224  setTime(); //set new since time for possible next upload to DB
225  setSinceTime_=false;
226  }
227  algoAnalyze(event, iSetup);
228  }
229 
230  void endLuminosityBlock(const edm::LuminosityBlock & lumiBlock, const edm::EventSetup & es)
231  {
232  edm::LogInfo("ConditionDBWriter::endLuminosityBlock") << std::endl;
233  algoEndLuminosityBlock(lumiBlock, es);
234 
235  if(LumiBlockMode_){
236 
237  T * objPointer = getNewObject();
238 
239  if(objPointer ){
240  storeOnDb(objPointer);
241  }
242  else {
243  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;
244  }
245  }
246  }
247 
249 
250  void endRun(const edm::Run & run, const edm::EventSetup & es)
251  {
252  edm::LogInfo("ConditionDBWriter::endRun") << std::endl;
253 
254  algoEndRun(run, es);
255 
256  if(RunMode_){
257 
258  T * objPointer = getNewObject();
259 
260  if(objPointer ){
261  storeOnDb(objPointer);
262  }
263  else {
264  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;
265  }
266  }
267  }
268 
269  void endJob()
270  {
271  edm::LogInfo("ConditionDBWriter::endJob") << std::endl;
272 
273  algoEndJob();
274 
275  if(JobMode_){
276 
277  T * objPointer = getNewObject();
278 
279  if( objPointer ){
280  storeOnDb(objPointer);
281  }
282 
283  else {
284 
285  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;
286  }
287  }
288  }
289 
290  void storeOnDb(T * objPointer)
291  {
292  edm::LogInfo("ConditionDBWriter::storeOnDb ") << std::endl;
293 
294  setSinceTime_=true;
295 
296  if(! objPointer) {
297  edm::LogError("ConditionDBWriter: Pointer to object has not been set...storing no data on DB") ;
298  return;
299  }
300 
301  //And now write data in DB
302  if( !doStore_ ) return;
304  if (! mydbservice.isAvailable() ) {
305  edm::LogError("ConditionDBWriter")<<"PoolDBOutputService is unavailable"<<std::endl;
306  return;
307  }
308 
309  cond::Time_t since =
310  ( mydbservice->isNewTagRequest(Record_) ) ? mydbservice->beginOfTime() : Time_;
311 
312  edm::LogInfo("ConditionDBWriter") << "appending a new object to tag "
313  <<Record_ <<" in since mode " << std::endl;
314  mydbservice->writeOne<T>(objPointer, since, Record_);
315  }
316 
317  void setTime()
318  {
320 
321  if( mydbservice.isAvailable() ){
322  Time_ = mydbservice->currentTime();
323  edm::LogInfo("ConditionDBWriter::setTime: time set to ") << Time_ << std::endl;
324  }
325  else{
326  edm::LogError("ConditionDBWriter::setTime(): PoolDBOutputService is not available...cannot set current time") << std::endl;
327  }
328  }
329 
330 protected:
331 
332  // 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
333 
335  {
336  T * objPointer = 0;
337 
338  if(AlgoDrivenMode_){
339 
340  setSinceTime_=true;
341 
342  objPointer = getNewObject();
343 
344  if (!objPointer ) {
345  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;
346  return;
347  }
348  else {storeOnDb(objPointer);}
349 
350  }
351  else {
352 
353  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;
354  return;
355  }
356  }
357 
358  // utility method: it returns the lastly set IOV time (till or since according to what was chosen in the configuration)
359 
361 
362 private:
363 
364  bool SinceAppendMode_; // till or since append mode
365 
366  bool LumiBlockMode_; //LumiBlock since/till time
367  bool RunMode_; //
368  bool JobMode_;
370  bool doStore_;
371 
372  std::string Record_;
373  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.
374 
376 
377  bool firstRun_;
378 };
379 
380 #endif
T getParameter(std::string const &) const
void storeOnDb(T *objPointer)
virtual T * getNewObject()=0
virtual void algoBeginJob(const edm::EventSetup &)
virtual void algoBeginLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &)
void endLuminosityBlock(const edm::LuminosityBlock &lumiBlock, const edm::EventSetup &es)
cond::Time_t timeOfLastIOV()
unsigned long long Time_t
Definition: Time.h:16
bool isNewTagRequest(const std::string &recordName)
bool isAvailable() const
Definition: Service.h:47
void beginLuminosityBlock(const edm::LuminosityBlock &lumiBlock, const edm::EventSetup &iSetup)
void writeOne(T *payload, Time_t time, const std::string &recordName, bool withlogging=false)
virtual void algoEndJob()
virtual void algoBeginRun(const edm::Run &, const edm::EventSetup &)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
void beginRun(const edm::Run &run, const edm::EventSetup &es)
void analyze(const edm::Event &event, const edm::EventSetup &iSetup)
ConditionDBWriter(const edm::ParameterSet &iConfig)
virtual void algoEndRun(const edm::Run &, const edm::EventSetup &)
void endRun(const edm::Run &run, const edm::EventSetup &es)
virtual void algoAnalyze(const edm::Event &, const edm::EventSetup &)
virtual void algoEndLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &)
Definition: Run.h:31
virtual ~ConditionDBWriter()