Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-02-27 07:20:01

0001 /*
0002  *  This EDAnalyzer will depend on all the event, lumi, run or process products declared by its configuration, both
0003  *  transient and persistent.
0004  *
0005  *  The dependencies can be specified either as module labels (e.g. "<module label>") or as branch names (e.g. 
0006  *  "<product type>_<module label>_<instance name>_<process name>").
0007  *  If a module label is used, no underscore ("_") must be present; this module will depend all the products produced
0008  *  by that module, including those produced by the Transformer functionality (such as the implicitly copied-to-host
0009  *  products in case of Alpaka-based modules).
0010  *  If a branch name is used, all four fields must be present, separated by underscores; this module will depend only
0011  *  on the matching product(s).
0012  *  
0013  *  Glob expressions ("?" and "*") are supported in module labels and within the individual fields of branch names,
0014  *  similar to an OutputModule's "keep" statements.
0015  *  Use "*" to depend on all products of a given category.
0016  *
0017  *  For example, in the case of Alpaka-based modules running on a device, using
0018  *
0019  *      eventProducts = cms.untracked.vstring( "module" )
0020  *
0021  *  will cause "module" to run, along with automatic copy of its device products to the host.
0022  *  To avoid the copy, the DeviceProduct branch can be specified explicitly with
0023  *
0024  *      eventProducts = cms.untracked.vstring( "*DeviceProduct_module_*_*" )
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 }  // namespace edm
0184 
0185 #include "FWCore/Framework/interface/MakerMacros.h"
0186 using edm::GenericConsumer;
0187 DEFINE_FWK_MODULE(GenericConsumer);