File indexing completed on 2025-02-27 07:20:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include <algorithm>
0030 #include <string>
0031 #include <regex>
0032 #include <vector>
0033
0034 #include <boost/algorithm/string/replace.hpp>
0035
0036 #include "DataFormats/Provenance/interface/ProductDescription.h"
0037 #include "DataFormats/Provenance/interface/ProductNamePattern.h"
0038 #include "FWCore/Framework/interface/global/EDAnalyzer.h"
0039 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0040 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0041 #include "FWCore/ParameterSet/interface/ParameterDescriptionNode.h"
0042 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0043 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0044
0045 namespace edm {
0046 class GenericConsumer : public edm::global::EDAnalyzer<> {
0047 public:
0048 explicit GenericConsumer(ParameterSet const&);
0049 ~GenericConsumer() override = default;
0050
0051 void analyze(StreamID, Event const&, EventSetup const&) const override {}
0052
0053 static void fillDescriptions(ConfigurationDescriptions& descriptions);
0054
0055 private:
0056 std::vector<edm::ProductNamePattern> eventProducts_;
0057 std::vector<edm::ProductNamePattern> lumiProducts_;
0058 std::vector<edm::ProductNamePattern> runProducts_;
0059 std::vector<edm::ProductNamePattern> processProducts_;
0060 std::string label_;
0061 bool verbose_;
0062 };
0063
0064 GenericConsumer::GenericConsumer(ParameterSet const& config)
0065 : eventProducts_(edm::productPatterns(config.getUntrackedParameter<std::vector<std::string>>("eventProducts"))),
0066 lumiProducts_(edm::productPatterns(config.getUntrackedParameter<std::vector<std::string>>("lumiProducts"))),
0067 runProducts_(edm::productPatterns(config.getUntrackedParameter<std::vector<std::string>>("runProducts"))),
0068 processProducts_(
0069 edm::productPatterns(config.getUntrackedParameter<std::vector<std::string>>("processProducts"))),
0070 label_(config.getParameter<std::string>("@module_label")),
0071 verbose_(config.getUntrackedParameter<bool>("verbose")) {
0072 callWhenNewProductsRegistered([this](edm::ProductDescription const& branch) {
0073 static const std::string kPathStatus("edm::PathStatus");
0074 static const std::string kEndPathStatus("edm::EndPathStatus");
0075
0076 switch (branch.branchType()) {
0077 case InEvent:
0078 if (branch.className() == kPathStatus or branch.className() == kEndPathStatus)
0079 return;
0080 for (auto const& label : eventProducts_)
0081 if (label.match(branch)) {
0082 this->consumes(edm::TypeToGet{branch.unwrappedTypeID(), PRODUCT_TYPE},
0083 edm::InputTag{branch.moduleLabel(), branch.productInstanceName(), branch.processName()});
0084 if (verbose_) {
0085 edm::LogVerbatim("GenericConsumer")
0086 << label_ << " consumes Event product " << branch.friendlyClassName() << '_' << branch.moduleLabel()
0087 << '_' << branch.productInstanceName() << '_' << branch.processName() << '\n';
0088 }
0089 break;
0090 }
0091 break;
0092
0093 case InLumi:
0094 for (auto const& label : lumiProducts_)
0095 if (label.match(branch)) {
0096 this->consumes<edm::InLumi>(
0097 edm::TypeToGet{branch.unwrappedTypeID(), PRODUCT_TYPE},
0098 edm::InputTag{branch.moduleLabel(), branch.productInstanceName(), branch.processName()});
0099 if (verbose_) {
0100 edm::LogVerbatim("GenericConsumer")
0101 << label_ << " consumes LuminosityBlock product " << branch.friendlyClassName() << '_'
0102 << branch.moduleLabel() << '_' << branch.productInstanceName() << '_' << branch.processName()
0103 << '\n';
0104 }
0105 break;
0106 }
0107 break;
0108
0109 case InRun:
0110 for (auto const& label : runProducts_)
0111 if (label.match(branch)) {
0112 this->consumes<edm::InRun>(
0113 edm::TypeToGet{branch.unwrappedTypeID(), PRODUCT_TYPE},
0114 edm::InputTag{branch.moduleLabel(), branch.productInstanceName(), branch.processName()});
0115 if (verbose_) {
0116 edm::LogVerbatim("GenericConsumer")
0117 << label_ << " consumes Run product " << branch.friendlyClassName() << '_' << branch.moduleLabel()
0118 << '_' << branch.productInstanceName() << '_' << branch.processName() << '\n';
0119 }
0120 break;
0121 }
0122 break;
0123
0124 case InProcess:
0125 for (auto const& label : processProducts_)
0126 if (label.match(branch)) {
0127 this->consumes<edm::InProcess>(
0128 edm::TypeToGet{branch.unwrappedTypeID(), PRODUCT_TYPE},
0129 edm::InputTag{branch.moduleLabel(), branch.productInstanceName(), branch.processName()});
0130 if (verbose_) {
0131 edm::LogVerbatim("GenericConsumer")
0132 << label_ << " consumes Process product " << branch.friendlyClassName() << '_'
0133 << branch.moduleLabel() << '_' << branch.productInstanceName() << '_' << branch.processName()
0134 << '\n';
0135 }
0136 break;
0137 }
0138 break;
0139
0140 default:
0141 throw Exception(errors::LogicError)
0142 << "Unexpected branch type " << branch.branchType() << "\nPlease contact a Framework developer\n";
0143 }
0144 });
0145 }
0146
0147 void GenericConsumer::fillDescriptions(ConfigurationDescriptions& descriptions) {
0148 descriptions.setComment(
0149 R"(This EDAnalyzer will depend on all the event, lumi, run or process products declared by its configuration, both transient and persistent.
0150
0151 The dependencies can be specified either as module labels (e.g. "<module label>") or as branch names (e.g. "<product type>_<module label>_<instance name>_<process name>").
0152 If a module label is used, no underscore ("_") must be present; this module will depend all the products produced by that module, including those produced by the Transformer functionality (such as the implicitly copied-to-host products in case of Alpaka-based modules).
0153 If a branch name is used, all four fields must be present, separated by underscores; this module will depend only on the matching product(s).
0154
0155 Glob expressions ("?" and "*") are supported in module labels and within the individual fields of branch names, similar to an OutputModule's "keep" statements.
0156 Use "*" to depend on all products of a given category.
0157
0158 For example, in the case of Alpaka-based modules running on a device, using
0159
0160 eventProducts = cms.untracked.vstring( "module" )
0161
0162 will cause "module" to run, along with automatic copy of its device products to the host.
0163 To avoid the copy, the DeviceProduct branch can be specified explicitly with
0164
0165 eventProducts = cms.untracked.vstring( "*DeviceProduct_module_*_*" )
0166
0167 .)");
0168
0169 ParameterSetDescription desc;
0170 desc.addUntracked<std::vector<std::string>>("eventProducts", {})
0171 ->setComment("List of modules or branches whose event products this module will depend on.");
0172 desc.addUntracked<std::vector<std::string>>("lumiProducts", {})
0173 ->setComment("List of modules or branches whose lumi products this module will depend on.");
0174 desc.addUntracked<std::vector<std::string>>("runProducts", {})
0175 ->setComment("List of modules or branches whose run products this module will depend on.");
0176 desc.addUntracked<std::vector<std::string>>("processProducts", {})
0177 ->setComment("List of modules or branches whose process products this module will depend on.");
0178 desc.addUntracked<bool>("verbose", false)
0179 ->setComment("Print the actual branch names for which the dependency are declared.");
0180 descriptions.addWithDefaultLabel(desc);
0181 }
0182
0183 }
0184
0185 #include "FWCore/Framework/interface/MakerMacros.h"
0186 using edm::GenericConsumer;
0187 DEFINE_FWK_MODULE(GenericConsumer);