File indexing completed on 2022-05-07 00:41:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "DataFormats/Common/interface/Handle.h"
0011 #include "DataFormats/Histograms/interface/DQMToken.h"
0012 #include "FWCore/Framework/interface/ConsumesCollector.h"
0013 #include "FWCore/Framework/interface/ESHandle.h"
0014 #include "FWCore/Framework/interface/Event.h"
0015 #include "FWCore/Framework/interface/EventSetup.h"
0016 #include "FWCore/Framework/interface/FileBlock.h"
0017 #include "FWCore/Framework/interface/Frameworkfwd.h"
0018 #include "FWCore/Framework/interface/LuminosityBlock.h"
0019 #include "FWCore/Framework/interface/MakerMacros.h"
0020 #include "FWCore/Framework/interface/Run.h"
0021 #include "FWCore/Framework/interface/one/EDProducer.h"
0022 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0023 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0024 #include "FWCore/Utilities/interface/EDPutToken.h"
0025 #include "FWCore/Utilities/interface/InputTag.h"
0026
0027
0028 #include "DQMServices/Core/interface/DQMStore.h"
0029 #include "FWCore/ServiceRegistry/interface/Service.h"
0030
0031
0032 #include "DataFormats/Histograms/interface/MEtoEDMFormat.h"
0033 #include "DataFormats/Histograms/interface/DQMToken.h"
0034
0035
0036 #include <cassert>
0037 #include <iostream>
0038 #include <cstdlib>
0039 #include <string>
0040 #include <memory>
0041 #include <vector>
0042 #include <map>
0043 #include <tuple>
0044
0045 #include "TString.h"
0046 #include "TList.h"
0047
0048 #include "classlib/utils/StringList.h"
0049 #include "classlib/utils/StringOps.h"
0050
0051 class EDMtoMEConverter : public edm::one::EDProducer<edm::one::WatchRuns,
0052 edm::one::WatchLuminosityBlocks,
0053 edm::one::SharedResources,
0054 edm::EndLuminosityBlockProducer,
0055 edm::EndRunProducer> {
0056 public:
0057 typedef dqm::legacy::DQMStore DQMStore;
0058 typedef dqm::legacy::MonitorElement MonitorElement;
0059
0060 explicit EDMtoMEConverter(const edm::ParameterSet &);
0061 ~EDMtoMEConverter() override = default;
0062
0063 void beginRun(const edm::Run &, const edm::EventSetup &) final{};
0064 void endRun(const edm::Run &, const edm::EventSetup &) final{};
0065 void beginLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) final{};
0066 void endLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) final{};
0067 void produce(edm::Event &, edm::EventSetup const &) final{};
0068
0069 void endLuminosityBlockProduce(edm::LuminosityBlock &, edm::EventSetup const &) override;
0070 void endRunProduce(edm::Run &run, edm::EventSetup const &setup) override;
0071
0072 template <class T>
0073 void getData(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter, T &iGetFrom);
0074
0075 using TagList = std::vector<uint32_t>;
0076
0077 private:
0078 std::string name;
0079 int verbosity;
0080 int frequency;
0081
0082 bool convertOnEndLumi;
0083 bool convertOnEndRun;
0084 MonitorElementData::Scope reScope;
0085
0086 template <typename T>
0087 class Tokens {
0088 public:
0089 using type = T;
0090 using Product = MEtoEDM<T>;
0091
0092 Tokens() = default;
0093
0094 void set(const edm::InputTag &runInputTag, const edm::InputTag &lumiInputTag, edm::ConsumesCollector &iC);
0095
0096 void getData(const edm::Run &iRun, edm::Handle<Product> &handle) const;
0097 void getData(const edm::LuminosityBlock &iLumi, edm::Handle<Product> &handle) const;
0098
0099 private:
0100 edm::EDGetTokenT<Product> runToken;
0101 edm::EDGetTokenT<Product> lumiToken;
0102 };
0103
0104 std::tuple<Tokens<TH1F>,
0105 Tokens<TH1S>,
0106 Tokens<TH1D>,
0107 Tokens<TH1I>,
0108 Tokens<TH2F>,
0109 Tokens<TH2S>,
0110 Tokens<TH2D>,
0111 Tokens<TH2I>,
0112 Tokens<TH3F>,
0113 Tokens<TProfile>,
0114 Tokens<TProfile2D>,
0115 Tokens<double>,
0116 Tokens<int>,
0117 Tokens<long long>,
0118 Tokens<TString> >
0119 tokens_;
0120
0121 edm::EDPutTokenT<DQMToken> dqmLumiToken_;
0122 edm::EDPutTokenT<DQMToken> dqmRunToken_;
0123 };
0124
0125 using namespace lat;
0126 using dqm::legacy::DQMStore;
0127 using dqm::legacy::MonitorElement;
0128
0129 template <typename T>
0130 void EDMtoMEConverter::Tokens<T>::set(const edm::InputTag &runInputTag,
0131 const edm::InputTag &lumiInputTag,
0132 edm::ConsumesCollector &iC) {
0133 runToken = iC.mayConsume<MEtoEDM<T>, edm::InRun>(runInputTag);
0134 lumiToken = iC.mayConsume<MEtoEDM<T>, edm::InLumi>(lumiInputTag);
0135 }
0136
0137 template <typename T>
0138 void EDMtoMEConverter::Tokens<T>::getData(const edm::Run &iRun, edm::Handle<Product> &handle) const {
0139 iRun.getByToken(runToken, handle);
0140 }
0141
0142 template <typename T>
0143 void EDMtoMEConverter::Tokens<T>::getData(const edm::LuminosityBlock &iLumi, edm::Handle<Product> &handle) const {
0144 iLumi.getByToken(lumiToken, handle);
0145 }
0146
0147 namespace {
0148
0149 template <size_t I, size_t N>
0150 struct ForEachHelper {
0151 template <typename Tuple, typename Func>
0152 static void call(Tuple &&tpl, Func &&func) {
0153 func(std::get<I - 1>(tpl));
0154 ForEachHelper<I + 1, N>::call(std::forward<Tuple>(tpl), std::forward<Func>(func));
0155 }
0156 };
0157
0158 template <size_t N>
0159 struct ForEachHelper<N, N> {
0160 template <typename Tuple, typename Func>
0161 static void call(Tuple &&tpl, Func &&func) {
0162 func(std::get<N - 1>(tpl));
0163 }
0164 };
0165
0166
0167 template <typename Tuple, typename Func>
0168 void for_each(Tuple &&tpl, Func &&func) {
0169 constexpr auto size = std::tuple_size<typename std::decay<Tuple>::type>::value;
0170 ForEachHelper<1, size>::call(std::forward<Tuple>(tpl), std::forward<Func>(func));
0171 }
0172
0173 template <typename T>
0174 struct HistoTraits;
0175 template <>
0176 struct HistoTraits<TH1F> {
0177 static TH1F *get(MonitorElement *me) { return me->getTH1F(); }
0178 template <typename... Args>
0179 static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
0180 return iBooker.book1D(std::forward<Args>(args)...);
0181 }
0182 };
0183 template <>
0184 struct HistoTraits<TH1S> {
0185 static TH1S *get(MonitorElement *me) { return me->getTH1S(); }
0186 template <typename... Args>
0187 static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
0188 return iBooker.book1S(std::forward<Args>(args)...);
0189 }
0190 };
0191 template <>
0192 struct HistoTraits<TH1D> {
0193 static TH1D *get(MonitorElement *me) { return me->getTH1D(); }
0194 template <typename... Args>
0195 static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
0196 return iBooker.book1DD(std::forward<Args>(args)...);
0197 }
0198 };
0199 template <>
0200 struct HistoTraits<TH1I> {
0201 static TH1I *get(MonitorElement *me) { return me->getTH1I(); }
0202 template <typename... Args>
0203 static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
0204 return iBooker.book1I(std::forward<Args>(args)...);
0205 }
0206 };
0207 template <>
0208 struct HistoTraits<TH2F> {
0209 static TH2F *get(MonitorElement *me) { return me->getTH2F(); }
0210 template <typename... Args>
0211 static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
0212 return iBooker.book2D(std::forward<Args>(args)...);
0213 }
0214 };
0215 template <>
0216 struct HistoTraits<TH2S> {
0217 static TH2S *get(MonitorElement *me) { return me->getTH2S(); }
0218 template <typename... Args>
0219 static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
0220 return iBooker.book2S(std::forward<Args>(args)...);
0221 }
0222 };
0223 template <>
0224 struct HistoTraits<TH2D> {
0225 static TH2D *get(MonitorElement *me) { return me->getTH2D(); }
0226 template <typename... Args>
0227 static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
0228 return iBooker.book2DD(std::forward<Args>(args)...);
0229 }
0230 };
0231 template <>
0232 struct HistoTraits<TH2I> {
0233 static TH2I *get(MonitorElement *me) { return me->getTH2I(); }
0234 template <typename... Args>
0235 static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
0236 return iBooker.book2I(std::forward<Args>(args)...);
0237 }
0238 };
0239 template <>
0240 struct HistoTraits<TH3F> {
0241 static TH3F *get(MonitorElement *me) { return me->getTH3F(); }
0242 template <typename... Args>
0243 static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
0244 return iBooker.book3D(std::forward<Args>(args)...);
0245 }
0246 };
0247 template <>
0248 struct HistoTraits<TProfile> {
0249 static TProfile *get(MonitorElement *me) { return me->getTProfile(); }
0250 template <typename... Args>
0251 static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
0252 return iBooker.bookProfile(std::forward<Args>(args)...);
0253 }
0254 };
0255 template <>
0256 struct HistoTraits<TProfile2D> {
0257 static TProfile2D *get(MonitorElement *me) { return me->getTProfile2D(); }
0258 template <typename... Args>
0259 static MonitorElement *book(DQMStore::IBooker &iBooker, Args &&...args) {
0260 return iBooker.bookProfile2D(std::forward<Args>(args)...);
0261 }
0262 };
0263
0264
0265 template <typename T>
0266 struct AddMonitorElement {
0267 template <typename MEtoEDMObject_object, typename RunOrLumi>
0268 static MonitorElement *call(DQMStore::IBooker &iBooker,
0269 DQMStore::IGetter &iGetter,
0270 MEtoEDMObject_object *metoedmobject,
0271 const std::string &dir,
0272 const std::string &name,
0273 const RunOrLumi &runOrLumi) {
0274 MonitorElement *me = iGetter.get(dir + "/" + metoedmobject->GetName());
0275
0276 if (me) {
0277 auto histo = HistoTraits<T>::get(me);
0278 assert(histo);
0279 TList list;
0280 list.Add(metoedmobject);
0281 if (histo->Merge(&list) == -1)
0282 edm::LogError("EDMtoMEConverter") << "ERROR EDMtoMEConverter::getData(): merge failed for '"
0283 << metoedmobject->GetName() << "'" << std::endl;
0284 return me;
0285 } else {
0286 iBooker.setCurrentFolder(dir);
0287 return HistoTraits<T>::book(iBooker, metoedmobject->GetName(), metoedmobject);
0288 }
0289 }
0290 };
0291
0292 template <>
0293 struct AddMonitorElement<double> {
0294 template <typename MEtoEDMObject_object, typename RunOrLumi>
0295 static MonitorElement *call(DQMStore::IBooker &iBooker,
0296 DQMStore::IGetter &iGetter,
0297 MEtoEDMObject_object *metoedmobject,
0298 const std::string &dir,
0299 const std::string &name,
0300 const RunOrLumi &runOrLumi) {
0301 iBooker.setCurrentFolder(dir);
0302 MonitorElement *me = iBooker.bookFloat(name);
0303 me->Fill(*metoedmobject);
0304 return me;
0305 }
0306 };
0307
0308
0309 template <typename T>
0310 struct AddMonitorElementForIntegers {
0311 template <typename MEtoEDMObject_object, typename RunOrLumi>
0312 static MonitorElement *call(DQMStore::IBooker &iBooker,
0313 DQMStore::IGetter &iGetter,
0314 MEtoEDMObject_object *metoedmobject,
0315 const std::string &dir,
0316 const std::string &name,
0317 const RunOrLumi &runOrLumi) {
0318 iBooker.setCurrentFolder(dir);
0319 iGetter.setCurrentFolder(dir);
0320 T ival = getProcessedEvents(iGetter, dir, name, runOrLumi);
0321 MonitorElement *me = iBooker.bookInt(name);
0322 me->Fill(*metoedmobject + ival);
0323 return me;
0324 }
0325
0326 static T getProcessedEvents(DQMStore::IGetter &iGetter,
0327 const std::string &dir,
0328 const std::string &name,
0329 const edm::Run &) {
0330 if (name.find("processedEvents") != std::string::npos) {
0331 if (const MonitorElement *me = iGetter.get(dir + "/" + name)) {
0332 return me->getIntValue();
0333 }
0334 }
0335 return 0;
0336 }
0337
0338 static T getProcessedEvents(DQMStore::IGetter &iGetter,
0339 const std::string &dir,
0340 const std::string &name,
0341 const edm::LuminosityBlock &) {
0342 return 0;
0343 }
0344 };
0345 template <>
0346 struct AddMonitorElement<long long> {
0347 template <typename... Args>
0348 static MonitorElement *call(Args &&...args) {
0349 return AddMonitorElementForIntegers<long long>::call(std::forward<Args>(args)...);
0350 }
0351 };
0352 template <>
0353 struct AddMonitorElement<int> {
0354 template <typename... Args>
0355 static MonitorElement *call(Args &&...args) {
0356 return AddMonitorElementForIntegers<int>::call(std::forward<Args>(args)...);
0357 }
0358 };
0359
0360 template <>
0361 struct AddMonitorElement<TString> {
0362 template <typename MEtoEDMObject_object, typename RunOrLumi>
0363 static MonitorElement *call(DQMStore::IBooker &iBooker,
0364 DQMStore::IGetter &iGetter,
0365 MEtoEDMObject_object *metoedmobject,
0366 const std::string &dir,
0367 const std::string &name,
0368 const RunOrLumi &runOrLumi) {
0369 iBooker.setCurrentFolder(dir);
0370 std::string scont = metoedmobject->Data();
0371 return iBooker.bookString(name, scont);
0372 }
0373 };
0374
0375
0376 void adjustScope(DQMStore::IBooker &ibooker, const edm::Run &, MonitorElementData::Scope reScope) {
0377 if (reScope == MonitorElementData::Scope::JOB) {
0378 ibooker.setScope(MonitorElementData::Scope::JOB);
0379 } else {
0380 ibooker.setScope(MonitorElementData::Scope::RUN);
0381 }
0382 }
0383 void adjustScope(DQMStore::IBooker &ibooker, const edm::LuminosityBlock &, MonitorElementData::Scope reScope) {
0384
0385 ibooker.setScope(reScope);
0386 }
0387
0388 }
0389
0390 EDMtoMEConverter::EDMtoMEConverter(const edm::ParameterSet &iPSet) : verbosity(0), frequency(0) {
0391 const edm::InputTag &runInputTag = iPSet.getParameter<edm::InputTag>("runInputTag");
0392 const edm::InputTag &lumiInputTag = iPSet.getParameter<edm::InputTag>("lumiInputTag");
0393 edm::ConsumesCollector iC = consumesCollector();
0394
0395 for_each(tokens_, [&](auto &tok) { tok.set(runInputTag, lumiInputTag, iC); });
0396
0397 constexpr char MsgLoggerCat[] = "EDMtoMEConverter_EDMtoMEConverter";
0398
0399
0400 name = iPSet.getUntrackedParameter<std::string>("Name");
0401 verbosity = iPSet.getUntrackedParameter<int>("Verbosity");
0402 frequency = iPSet.getUntrackedParameter<int>("Frequency");
0403
0404 convertOnEndLumi = iPSet.getUntrackedParameter<bool>("convertOnEndLumi", true);
0405 convertOnEndRun = iPSet.getUntrackedParameter<bool>("convertOnEndRun", true);
0406
0407 auto scopeDecode = std::map<std::string, MonitorElementData::Scope>{{"", MonitorElementData::Scope::LUMI},
0408 {"LUMI", MonitorElementData::Scope::LUMI},
0409 {"RUN", MonitorElementData::Scope::RUN},
0410 {"JOB", MonitorElementData::Scope::JOB}};
0411 reScope = scopeDecode[iPSet.getUntrackedParameter<std::string>("reScope", "")];
0412
0413
0414
0415 verbosity %= 10;
0416
0417
0418 if (verbosity >= 0) {
0419 edm::LogInfo(MsgLoggerCat) << "\n===============================\n"
0420 << "Initialized as EDAnalyzer with parameter values:\n"
0421 << " Name = " << name << "\n"
0422 << " Verbosity = " << verbosity << "\n"
0423 << " Frequency = " << frequency << "\n"
0424 << "===============================\n";
0425 }
0426
0427 assert(sizeof(int64_t) == sizeof(long long));
0428 usesResource("DQMStore");
0429
0430 dqmLumiToken_ = produces<DQMToken, edm::Transition::EndLuminosityBlock>("endLumi");
0431 dqmRunToken_ = produces<DQMToken, edm::Transition::EndRun>("endRun");
0432 }
0433
0434 void EDMtoMEConverter::endRunProduce(edm::Run &iRun, edm::EventSetup const &iSetup) {
0435 if (convertOnEndRun) {
0436 DQMStore *store = edm::Service<DQMStore>().operator->();
0437 store->meBookerGetter([&](DQMStore::IBooker &b, DQMStore::IGetter &g) { getData(b, g, iRun); });
0438 }
0439
0440 iRun.put(dqmRunToken_, std::make_unique<DQMToken>());
0441 }
0442
0443 void EDMtoMEConverter::endLuminosityBlockProduce(edm::LuminosityBlock &iLumi, edm::EventSetup const &iSetup) {
0444 if (convertOnEndLumi) {
0445 DQMStore *store = edm::Service<DQMStore>().operator->();
0446 store->meBookerGetter([&](DQMStore::IBooker &b, DQMStore::IGetter &g) { getData(b, g, iLumi); });
0447 }
0448
0449 iLumi.put(dqmLumiToken_, std::make_unique<DQMToken>());
0450 }
0451
0452 template <class T>
0453 void EDMtoMEConverter::getData(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter, T &iGetFrom) {
0454 constexpr char MsgLoggerCat[] = "EDMtoMEConverter_getData";
0455
0456 if (verbosity >= 0)
0457 edm::LogInfo(MsgLoggerCat) << "\nRestoring MonitorElements.";
0458
0459 for_each(tokens_, [&](const auto &tok) {
0460 using Tokens_T = typename std::decay<decltype(tok)>::type;
0461 using METype = typename Tokens_T::type;
0462 using MEtoEDM_T = typename Tokens_T::Product;
0463 edm::Handle<MEtoEDM_T> metoedm;
0464 tok.getData(iGetFrom, metoedm);
0465 if (!metoedm.isValid()) {
0466
0467
0468 return;
0469 }
0470
0471 std::vector<typename MEtoEDM_T::MEtoEDMObject> metoedmobject = metoedm->getMEtoEdmObject();
0472
0473 for (unsigned int i = 0; i < metoedmobject.size(); ++i) {
0474
0475 const std::string &pathname = metoedmobject[i].name;
0476 if (verbosity > 0)
0477 std::cout << pathname << std::endl;
0478
0479 std::string dir;
0480
0481
0482 StringList fulldir = StringOps::split(pathname, "/");
0483 std::string name = *(fulldir.end() - 1);
0484
0485 for (unsigned j = 0; j < fulldir.size() - 1; ++j) {
0486 dir += fulldir[j];
0487 if (j != fulldir.size() - 2)
0488 dir += "/";
0489 }
0490
0491
0492 adjustScope(iBooker, iGetFrom, reScope);
0493 AddMonitorElement<METype>::call(iBooker, iGetter, &metoedmobject[i].object, dir, name, iGetFrom);
0494
0495 }
0496 });
0497 }
0498
0499 #include "FWCore/PluginManager/interface/ModuleDef.h"
0500 #include "FWCore/Framework/interface/MakerMacros.h"
0501 DEFINE_FWK_MODULE(EDMtoMEConverter);