CMS 3D CMS Logo

EDMtoMEConverter.cc
Go to the documentation of this file.
1 
9 // framework & common header files
26 
27 //DQM services
30 
31 // data format
34 
35 // helper files
36 #include <cassert>
37 #include <iostream>
38 #include <cstdlib>
39 #include <string>
40 #include <memory>
41 #include <vector>
42 #include <map>
43 #include <tuple>
44 
45 #include "TString.h"
46 #include "TList.h"
47 
48 #include "classlib/utils/StringList.h"
49 #include "classlib/utils/StringOps.h"
50 
51 class EDMtoMEConverter : public edm::one::EDProducer<edm::one::WatchRuns,
52  edm::one::WatchLuminosityBlocks,
53  edm::one::SharedResources,
54  edm::EndLuminosityBlockProducer,
55  edm::EndRunProducer> {
56 public:
59 
60  explicit EDMtoMEConverter(const edm::ParameterSet &);
61  ~EDMtoMEConverter() override = default;
62 
63  void beginRun(const edm::Run &, const edm::EventSetup &) final{};
64  void endRun(const edm::Run &, const edm::EventSetup &) final{};
67  void produce(edm::Event &, edm::EventSetup const &) final{};
68 
70  void endRunProduce(edm::Run &run, edm::EventSetup const &setup) override;
71 
72  template <class T>
73  void getData(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter, T &iGetFrom);
74 
75  using TagList = std::vector<uint32_t>;
76 
77 private:
79  int verbosity;
80  int frequency;
81 
85 
86  template <typename T>
87  class Tokens {
88  public:
89  using type = T;
91 
92  Tokens() = default;
93 
95 
96  void getData(const edm::Run &iRun, edm::Handle<Product> &handle) const;
97  void getData(const edm::LuminosityBlock &iLumi, edm::Handle<Product> &handle) const;
98 
99  private:
102  };
103 
104  std::tuple<Tokens<TH1F>,
105  Tokens<TH1S>,
106  Tokens<TH1D>,
107  Tokens<TH1I>,
108  Tokens<TH2F>,
109  Tokens<TH2S>,
110  Tokens<TH2D>,
111  Tokens<TH2I>,
112  Tokens<TH3F>,
116  Tokens<int>,
120 
123 }; // end class declaration
124 
125 using namespace lat;
128 
129 template <typename T>
133  runToken = iC.mayConsume<MEtoEDM<T>, edm::InRun>(runInputTag);
134  lumiToken = iC.mayConsume<MEtoEDM<T>, edm::InLumi>(lumiInputTag);
135 }
136 
137 template <typename T>
139  iRun.getByToken(runToken, handle);
140 }
141 
142 template <typename T>
144  iLumi.getByToken(lumiToken, handle);
145 }
146 
147 namespace {
148  // general
149  template <size_t I, size_t N>
150  struct ForEachHelper {
151  template <typename Tuple, typename Func>
152  static void call(Tuple &&tpl, Func &&func) {
153  func(std::get<I - 1>(tpl));
154  ForEachHelper<I + 1, N>::call(std::forward<Tuple>(tpl), std::forward<Func>(func));
155  }
156  };
157  // break recursion
158  template <size_t N>
159  struct ForEachHelper<N, N> {
160  template <typename Tuple, typename Func>
161  static void call(Tuple &&tpl, Func &&func) {
162  func(std::get<N - 1>(tpl));
163  }
164  };
165 
166  // helper function to provide nice interface
167  template <typename Tuple, typename Func>
168  void for_each(Tuple &&tpl, Func &&func) {
170  ForEachHelper<1, size>::call(std::forward<Tuple>(tpl), std::forward<Func>(func));
171  }
172 
173  template <typename T>
174  struct HistoTraits;
175  template <>
176  struct HistoTraits<TH1F> {
177  static TH1F *get(MonitorElement *me) { return me->getTH1F(); }
178  template <typename... Args>
179  static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
180  return iBooker.book1D(std::forward<Args>(args)...);
181  }
182  };
183  template <>
184  struct HistoTraits<TH1S> {
185  static TH1S *get(MonitorElement *me) { return me->getTH1S(); }
186  template <typename... Args>
187  static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
188  return iBooker.book1S(std::forward<Args>(args)...);
189  }
190  };
191  template <>
192  struct HistoTraits<TH1D> {
193  static TH1D *get(MonitorElement *me) { return me->getTH1D(); }
194  template <typename... Args>
195  static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
196  return iBooker.book1DD(std::forward<Args>(args)...);
197  }
198  };
199  template <>
200  struct HistoTraits<TH1I> {
201  static TH1I *get(MonitorElement *me) { return me->getTH1I(); }
202  template <typename... Args>
203  static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
204  return iBooker.book1I(std::forward<Args>(args)...);
205  }
206  };
207  template <>
208  struct HistoTraits<TH2F> {
209  static TH2F *get(MonitorElement *me) { return me->getTH2F(); }
210  template <typename... Args>
211  static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
212  return iBooker.book2D(std::forward<Args>(args)...);
213  }
214  };
215  template <>
216  struct HistoTraits<TH2S> {
217  static TH2S *get(MonitorElement *me) { return me->getTH2S(); }
218  template <typename... Args>
219  static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
220  return iBooker.book2S(std::forward<Args>(args)...);
221  }
222  };
223  template <>
224  struct HistoTraits<TH2D> {
225  static TH2D *get(MonitorElement *me) { return me->getTH2D(); }
226  template <typename... Args>
227  static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
228  return iBooker.book2DD(std::forward<Args>(args)...);
229  }
230  };
231  template <>
232  struct HistoTraits<TH2I> {
233  static TH2I *get(MonitorElement *me) { return me->getTH2I(); }
234  template <typename... Args>
235  static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
236  return iBooker.book2I(std::forward<Args>(args)...);
237  }
238  };
239  template <>
240  struct HistoTraits<TH3F> {
241  static TH3F *get(MonitorElement *me) { return me->getTH3F(); }
242  template <typename... Args>
243  static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
244  return iBooker.book3D(std::forward<Args>(args)...);
245  }
246  };
247  template <>
248  struct HistoTraits<TProfile> {
249  static TProfile *get(MonitorElement *me) { return me->getTProfile(); }
250  template <typename... Args>
251  static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
252  return iBooker.bookProfile(std::forward<Args>(args)...);
253  }
254  };
255  template <>
256  struct HistoTraits<TProfile2D> {
257  static TProfile2D *get(MonitorElement *me) { return me->getTProfile2D(); }
258  template <typename... Args>
259  static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
260  return iBooker.bookProfile2D(std::forward<Args>(args)...);
261  }
262  };
263 
264  // Default to histograms and similar, others are specialized
265  template <typename T>
266  struct AddMonitorElement {
267  template <typename MEtoEDMObject_object, typename RunOrLumi>
268  static MonitorElement *call(DQMStore::IBooker &iBooker,
269  DQMStore::IGetter &iGetter,
270  MEtoEDMObject_object *metoedmobject,
271  const std::string &dir,
272  const std::string &name,
273  const RunOrLumi &runOrLumi) {
274  MonitorElement *me = iGetter.get(dir + "/" + metoedmobject->GetName());
275 
276  if (me) {
277  auto histo = HistoTraits<T>::get(me);
278  assert(histo);
279  TList list;
280  list.Add(metoedmobject);
281  if (histo->Merge(&list) == -1)
282  edm::LogError("EDMtoMEConverter") << "ERROR EDMtoMEConverter::getData(): merge failed for '"
283  << metoedmobject->GetName() << "'" << std::endl;
284  return me;
285  } else {
286  iBooker.setCurrentFolder(dir);
287  return HistoTraits<T>::book(iBooker, metoedmobject->GetName(), metoedmobject);
288  }
289  }
290  };
291 
292  template <>
293  struct AddMonitorElement<double> {
294  template <typename MEtoEDMObject_object, typename RunOrLumi>
295  static MonitorElement *call(DQMStore::IBooker &iBooker,
296  DQMStore::IGetter &iGetter,
297  MEtoEDMObject_object *metoedmobject,
298  const std::string &dir,
299  const std::string &name,
300  const RunOrLumi &runOrLumi) {
301  iBooker.setCurrentFolder(dir);
302  MonitorElement *me = iBooker.bookFloat(name);
303  me->Fill(*metoedmobject);
304  return me;
305  }
306  };
307 
308  // long long and int share some commonalities, which are captured here (we can have only one default template definition)
309  template <typename T>
310  struct AddMonitorElementForIntegers {
311  template <typename MEtoEDMObject_object, typename RunOrLumi>
312  static MonitorElement *call(DQMStore::IBooker &iBooker,
313  DQMStore::IGetter &iGetter,
314  MEtoEDMObject_object *metoedmobject,
315  const std::string &dir,
316  const std::string &name,
317  const RunOrLumi &runOrLumi) {
318  iBooker.setCurrentFolder(dir);
319  iGetter.setCurrentFolder(dir);
320  T ival = getProcessedEvents(iGetter, dir, name, runOrLumi);
321  MonitorElement *me = iBooker.bookInt(name);
322  me->Fill(*metoedmobject + ival);
323  return me;
324  }
325 
326  static T getProcessedEvents(DQMStore::IGetter &iGetter,
327  const std::string &dir,
328  const std::string &name,
329  const edm::Run &) {
330  if (name.find("processedEvents") != std::string::npos) {
331  if (const MonitorElement *me = iGetter.get(dir + "/" + name)) {
332  return me->getIntValue();
333  }
334  }
335  return 0;
336  }
337 
338  static T getProcessedEvents(DQMStore::IGetter &iGetter,
339  const std::string &dir,
340  const std::string &name,
341  const edm::LuminosityBlock &) {
342  return 0;
343  }
344  };
345  template <>
346  struct AddMonitorElement<long long> {
347  template <typename... Args>
348  static MonitorElement *call(Args &&...args) {
349  return AddMonitorElementForIntegers<long long>::call(std::forward<Args>(args)...);
350  }
351  };
352  template <>
353  struct AddMonitorElement<int> {
354  template <typename... Args>
355  static MonitorElement *call(Args &&...args) {
356  return AddMonitorElementForIntegers<int>::call(std::forward<Args>(args)...);
357  }
358  };
359 
360  template <>
361  struct AddMonitorElement<TString> {
362  template <typename MEtoEDMObject_object, typename RunOrLumi>
363  static MonitorElement *call(DQMStore::IBooker &iBooker,
364  DQMStore::IGetter &iGetter,
365  MEtoEDMObject_object *metoedmobject,
366  const std::string &dir,
367  const std::string &name,
368  const RunOrLumi &runOrLumi) {
369  iBooker.setCurrentFolder(dir);
370  std::string scont = metoedmobject->Data();
371  return iBooker.bookString(name, scont);
372  }
373  };
374 
375  // TODO: might need re-scoping to JOB here.
376  void adjustScope(DQMStore::IBooker &ibooker, const edm::Run &, MonitorElementData::Scope reScope) {
377  if (reScope == MonitorElementData::Scope::JOB) {
378  ibooker.setScope(MonitorElementData::Scope::JOB);
379  } else {
380  ibooker.setScope(MonitorElementData::Scope::RUN);
381  }
382  }
383  void adjustScope(DQMStore::IBooker &ibooker, const edm::LuminosityBlock &, MonitorElementData::Scope reScope) {
384  // will be LUMI for no reScoping, else the expected scope.
385  ibooker.setScope(reScope);
386  }
387 
388 } // namespace
389 
391  const edm::InputTag &runInputTag = iPSet.getParameter<edm::InputTag>("runInputTag");
392  const edm::InputTag &lumiInputTag = iPSet.getParameter<edm::InputTag>("lumiInputTag");
394 
395  for_each(tokens_, [&](auto &tok) { tok.set(runInputTag, lumiInputTag, iC); });
396 
397  constexpr char MsgLoggerCat[] = "EDMtoMEConverter_EDMtoMEConverter";
398 
399  // get information from parameter set
400  name = iPSet.getUntrackedParameter<std::string>("Name");
401  verbosity = iPSet.getUntrackedParameter<int>("Verbosity");
402  frequency = iPSet.getUntrackedParameter<int>("Frequency");
403 
404  convertOnEndLumi = iPSet.getUntrackedParameter<bool>("convertOnEndLumi", true);
405  convertOnEndRun = iPSet.getUntrackedParameter<bool>("convertOnEndRun", true);
406 
407  auto scopeDecode = std::map<std::string, MonitorElementData::Scope>{{"", MonitorElementData::Scope::LUMI},
408  {"LUMI", MonitorElementData::Scope::LUMI},
409  {"RUN", MonitorElementData::Scope::RUN},
410  {"JOB", MonitorElementData::Scope::JOB}};
411  reScope = scopeDecode[iPSet.getUntrackedParameter<std::string>("reScope", "")];
412 
413  // use value of first digit to determine default output level (inclusive)
414  // 0 is none, 1 is basic, 2 is fill output, 3 is gather output
415  verbosity %= 10;
416 
417  // print out Parameter Set information being used
418  if (verbosity >= 0) {
419  edm::LogInfo(MsgLoggerCat) << "\n===============================\n"
420  << "Initialized as EDAnalyzer with parameter values:\n"
421  << " Name = " << name << "\n"
422  << " Verbosity = " << verbosity << "\n"
423  << " Frequency = " << frequency << "\n"
424  << "===============================\n";
425  }
426 
427  assert(sizeof(int64_t) == sizeof(long long));
428  usesResource("DQMStore");
429 
430  dqmLumiToken_ = produces<DQMToken, edm::Transition::EndLuminosityBlock>("endLumi");
431  dqmRunToken_ = produces<DQMToken, edm::Transition::EndRun>("endRun");
432 } // end constructor
433 
435  if (convertOnEndRun) {
437  store->meBookerGetter([&](DQMStore::IBooker &b, DQMStore::IGetter &g) { getData(b, g, iRun); });
438  }
439 
440  iRun.put(dqmRunToken_, std::make_unique<DQMToken>());
441 }
442 
444  if (convertOnEndLumi) {
446  store->meBookerGetter([&](DQMStore::IBooker &b, DQMStore::IGetter &g) { getData(b, g, iLumi); });
447  }
448 
449  iLumi.put(dqmLumiToken_, std::make_unique<DQMToken>());
450 }
451 
452 template <class T>
453 void EDMtoMEConverter::getData(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter, T &iGetFrom) {
454  constexpr char MsgLoggerCat[] = "EDMtoMEConverter_getData";
455 
456  if (verbosity >= 0)
457  edm::LogInfo(MsgLoggerCat) << "\nRestoring MonitorElements.";
458 
459  for_each(tokens_, [&](const auto &tok) {
460  using Tokens_T = typename std::decay<decltype(tok)>::type;
461  using METype = typename Tokens_T::type;
462  using MEtoEDM_T = typename Tokens_T::Product;
463  edm::Handle<MEtoEDM_T> metoedm;
464  tok.getData(iGetFrom, metoedm);
465  if (!metoedm.isValid()) {
466  //edm::LogWarning(MsgLoggerCat)
467  // << "MEtoEDM<TH1F> doesn't exist in run";
468  return;
469  }
470 
471  std::vector<typename MEtoEDM_T::MEtoEDMObject> metoedmobject = metoedm->getMEtoEdmObject();
472 
473  for (unsigned int i = 0; i < metoedmobject.size(); ++i) {
474  // get full path of monitor element
475  const std::string &pathname = metoedmobject[i].name;
476  if (verbosity > 0)
477  std::cout << pathname << std::endl;
478 
480 
481  // deconstruct path from fullpath
482  StringList fulldir = StringOps::split(pathname, "/");
483  std::string name = *(fulldir.end() - 1);
484 
485  for (unsigned j = 0; j < fulldir.size() - 1; ++j) {
486  dir += fulldir[j];
487  if (j != fulldir.size() - 2)
488  dir += "/";
489  }
490 
491  // define new monitor element
492  adjustScope(iBooker, iGetFrom, reScope);
493  AddMonitorElement<METype>::call(iBooker, iGetter, &metoedmobject[i].object, dir, name, iGetFrom);
494 
495  } // end loop thorugh metoedmobject
496  });
497 }
498 
size
Write out results.
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
MonitorElement * bookFloat(TString const &name, FUNC onbooking=NOOP())
Definition: DQMStore.h:80
MonitorElement * bookProfile2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, double lowZ, double highZ, char const *option="s", FUNC onbooking=NOOP())
Definition: DQMStore.h:476
MonitorElement * book1I(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:177
MonitorElement * book2S(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:254
void beginLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) final
EDGetTokenT< ProductType > mayConsume(edm::InputTag const &tag)
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
void endLuminosityBlockProduce(edm::LuminosityBlock &, edm::EventSetup const &) override
dqm::legacy::DQMStore DQMStore
EDMtoMEConverter(const edm::ParameterSet &)
virtual MonitorElementData::Scope setScope(MonitorElementData::Scope newscope)
Definition: DQMStore.cc:50
void beginRun(const edm::Run &, const edm::EventSetup &) final
assert(be >=bs)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
dqm::legacy::MonitorElement MonitorElement
MonitorElement * bookString(TString const &name, TString const &value, FUNC onbooking=NOOP())
Definition: DQMStore.h:87
T getUntrackedParameter(std::string const &, T const &) const
dqm::reco::DQMStore DQMStore
void endRunProduce(edm::Run &run, edm::EventSetup const &setup) override
MonitorElement * book1DD(TString const &name, TString const &title, int nchX, double lowX, double highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:155
edm::EDGetTokenT< Product > runToken
void endRun(const edm::Run &, const edm::EventSetup &) final
~EDMtoMEConverter() override=default
MonitorElement * bookProfile(TString const &name, TString const &title, int nchX, double lowX, double highX, int, double lowY, double highY, char const *option="s", FUNC onbooking=NOOP())
Definition: DQMStore.h:399
void endLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) final
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
void put(std::unique_ptr< PROD > product)
Put a new product.
void produce(edm::Event &, edm::EventSetup const &) final
edm::EDPutTokenT< DQMToken > dqmRunToken_
void getData(const edm::Run &iRun, edm::Handle< Product > &handle) const
void meBookerGetter(iFunc f)
Definition: DQMStore.h:709
MonitorElement * book1S(TString const &name, TString const &title, int nchX, double lowX, double highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:133
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
const int verbosity
edm::EDPutTokenT< DQMToken > dqmLumiToken_
Log< level::Info, false > LogInfo
std::vector< edm::EDGetTokenT< int > > tokens_
std::tuple< Tokens< TH1F >, Tokens< TH1S >, Tokens< TH1D >, Tokens< TH1I >, Tokens< TH2F >, Tokens< TH2S >, Tokens< TH2D >, Tokens< TH2I >, Tokens< TH3F >, Tokens< TProfile >, Tokens< TProfile2D >, Tokens< double >, Tokens< int >, Tokens< long long >, Tokens< TString > > tokens_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
#define N
Definition: blowfish.cc:9
dqm::legacy::MonitorElement MonitorElement
void set(const edm::InputTag &runInputTag, const edm::InputTag &lumiInputTag, edm::ConsumesCollector &iC)
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:212
MonitorElement * bookInt(TString const &name, FUNC onbooking=NOOP())
Definition: DQMStore.h:73
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Run.h:318
double b
Definition: hdecay.h:120
void put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Run.h:109
virtual MonitorElement * get(std::string const &fullpath) const
Definition: DQMStore.cc:712
MonitorElement * book2DD(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:338
bool isValid() const
Definition: HandleBase.h:70
std::vector< uint32_t > TagList
#define get
void getData(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter, T &iGetFrom)
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
long double T
MonitorElement * book3D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, int nchZ, double lowZ, double highZ, FUNC onbooking=NOOP())
Definition: DQMStore.h:367
MonitorElement * book2I(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:296
edm::EDGetTokenT< Product > lumiToken
Definition: Run.h:45
MonitorElementData::Scope reScope