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