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