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