|
| 1 | +/* |
| 2 | + * This EDAnalyzer will query the TClass, ClassProperty and ClassInfo of all the persistent products specified in its |
| 3 | + * configuration. |
| 4 | + * |
| 5 | + * The products can be specified either as module labels (e.g. "<module label>") or as full product names (e.g. |
| 6 | + * "<product type>_<module label>_<instance name>_<process name>"). |
| 7 | + * If a module label is used, no underscore ("_") must be present; this module will check the types of all the |
| 8 | + * collections produced by that module, including those produced by the Transformer functionality (such as the |
| 9 | + * implicitly copied-to-host products in case of Alpaka-based modules). |
| 10 | + * If a full product name is used, all four fields must be present, separated by underscores; this module will depend |
| 11 | + * only on the matching product(s). |
| 12 | + * |
| 13 | + * Glob expressions ("?" and "*") are supported in module labels and within the individual fields of branch names, |
| 14 | + * similar to an OutputModule's "keep" statements. |
| 15 | + * Use "*" to check all products of a given category. |
| 16 | + */ |
| 17 | + |
| 18 | +#include <algorithm> |
| 19 | +#include <string> |
| 20 | +#include <regex> |
| 21 | +#include <vector> |
| 22 | + |
| 23 | +#include "DataFormats/Provenance/interface/ProductDescription.h" |
| 24 | +#include "DataFormats/Provenance/interface/ProductNamePattern.h" |
| 25 | +#include "FWCore/Framework/interface/global/EDAnalyzer.h" |
| 26 | +#include "FWCore/MessageLogger/interface/MessageLogger.h" |
| 27 | +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" |
| 28 | +#include "FWCore/ParameterSet/interface/ParameterDescriptionNode.h" |
| 29 | +#include "FWCore/ParameterSet/interface/ParameterSet.h" |
| 30 | +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" |
| 31 | +#include "FWCore/Utilities/interface/EDMException.h" |
| 32 | + |
| 33 | +namespace edmtest { |
| 34 | + |
| 35 | + class CheckClassInfo : public edm::global::EDAnalyzer<> { |
| 36 | + public: |
| 37 | + explicit CheckClassInfo(edm::ParameterSet const&); |
| 38 | + ~CheckClassInfo() override = default; |
| 39 | + |
| 40 | + void analyze(edm::StreamID, edm::Event const&, edm::EventSetup const&) const override {} |
| 41 | + |
| 42 | + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); |
| 43 | + |
| 44 | + private: |
| 45 | + void check(edm::ProductDescription const& product) const; |
| 46 | + |
| 47 | + std::vector<edm::ProductNamePattern> eventProducts_; |
| 48 | + std::vector<edm::ProductNamePattern> lumiProducts_; |
| 49 | + std::vector<edm::ProductNamePattern> runProducts_; |
| 50 | + std::vector<edm::ProductNamePattern> processProducts_; |
| 51 | + }; |
| 52 | + |
| 53 | + CheckClassInfo::CheckClassInfo(edm::ParameterSet const& config) |
| 54 | + : eventProducts_(edm::productPatterns(config.getUntrackedParameter<std::vector<std::string>>("eventProducts"))), |
| 55 | + lumiProducts_(edm::productPatterns(config.getUntrackedParameter<std::vector<std::string>>("lumiProducts"))), |
| 56 | + runProducts_(edm::productPatterns(config.getUntrackedParameter<std::vector<std::string>>("runProducts"))), |
| 57 | + processProducts_( |
| 58 | + edm::productPatterns(config.getUntrackedParameter<std::vector<std::string>>("processProducts"))) { |
| 59 | + callWhenNewProductsRegistered([this](edm::ProductDescription const& product) { |
| 60 | + switch (product.branchType()) { |
| 61 | + case edm::InEvent: |
| 62 | + for (auto const& label : eventProducts_) |
| 63 | + if (label.match(product)) { |
| 64 | + check(product); |
| 65 | + break; |
| 66 | + } |
| 67 | + break; |
| 68 | + |
| 69 | + case edm::InLumi: |
| 70 | + for (auto const& label : lumiProducts_) |
| 71 | + if (label.match(product)) { |
| 72 | + check(product); |
| 73 | + break; |
| 74 | + } |
| 75 | + break; |
| 76 | + |
| 77 | + case edm::InRun: |
| 78 | + for (auto const& label : runProducts_) |
| 79 | + if (label.match(product)) { |
| 80 | + check(product); |
| 81 | + break; |
| 82 | + } |
| 83 | + break; |
| 84 | + |
| 85 | + case edm::InProcess: |
| 86 | + for (auto const& label : processProducts_) |
| 87 | + if (label.match(product)) { |
| 88 | + check(product); |
| 89 | + break; |
| 90 | + } |
| 91 | + break; |
| 92 | + |
| 93 | + default: |
| 94 | + throw edm::Exception(edm::errors::LogicError) |
| 95 | + << "Unexpected branch type " << product.branchType() << "\nPlease contact a Framework developer\n"; |
| 96 | + } |
| 97 | + }); |
| 98 | + } |
| 99 | + |
| 100 | + void CheckClassInfo::check(edm::ProductDescription const& product) const { |
| 101 | + if (product.transient()) { |
| 102 | + edm::LogVerbatim("CheckClassInfo") << "The product " << product.friendlyClassName() << '_' |
| 103 | + << product.moduleLabel() << '_' << product.productInstanceName() << '_' |
| 104 | + << product.processName() << " is transient, and will not be queried.\n"; |
| 105 | + } else { |
| 106 | + edm::LogVerbatim log("CheckClassInfo"); |
| 107 | + log << "product " << product.friendlyClassName() << '_' << product.moduleLabel() << '_' |
| 108 | + << product.productInstanceName() << '_' << product.processName() << " :\n"; |
| 109 | + log << " wrapper type " << product.wrappedType().name() << '\n'; |
| 110 | + TClass* type = product.wrappedType().getClass(); |
| 111 | + log << " TClass pointer " << type << '\n'; |
| 112 | + if (type == nullptr) { |
| 113 | + throw edm::Exception(edm::errors::DictionaryNotFound) |
| 114 | + << "Failed to get a valid TClass pointer for the persistent type " << product.wrappedType().name(); |
| 115 | + } |
| 116 | + auto prop = type->ClassProperty(); |
| 117 | + log << " TClass property " << prop << '\n'; |
| 118 | + ClassInfo_t* info = type->GetClassInfo(); |
| 119 | + log << " ClassInfo pointer" << info << '\n'; |
| 120 | + if (info == nullptr) { |
| 121 | + throw edm::Exception(edm::errors::DictionaryNotFound) |
| 122 | + << "Failed to get a valid ClassInfo_t pointer for the persistent type " << product.wrappedType().name(); |
| 123 | + } |
| 124 | + } |
| 125 | + } |
| 126 | + |
| 127 | + void CheckClassInfo::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { |
| 128 | + descriptions.setComment( |
| 129 | + R"(This EDAnalyzer will query the TClass, ClassProperty and ClassInfo of all the persistent products specified in its |
| 130 | +configuration. |
| 131 | +
|
| 132 | +The products can be specified either as module labels (e.g. "<module label>") or as full product names (e.g. |
| 133 | +"<product type>_<module label>_<instance name>_<process name>"). |
| 134 | +If a module label is used, no underscore ("_") must be present; this module will check the types of all the collections |
| 135 | +produced by that module, including those produced by the Transformer functionality (such as the implicitly copied-to-host |
| 136 | +products in case of Alpaka-based modules). |
| 137 | +If a full product name is used, all four fields must be present, separated by underscores; this module will depend only |
| 138 | +on the matching product(s). |
| 139 | +
|
| 140 | +Glob expressions ("?" and "*") are supported in module labels and within the individual fields of branch names, similar |
| 141 | +to an OutputModule's "keep" statements. Use "*" to check all products of a given category.)"); |
| 142 | + |
| 143 | + edm::ParameterSetDescription desc; |
| 144 | + desc.addUntracked<std::vector<std::string>>("eventProducts", {}) |
| 145 | + ->setComment("List of modules or product names whose event products this module will check."); |
| 146 | + desc.addUntracked<std::vector<std::string>>("lumiProducts", {}) |
| 147 | + ->setComment("List of modules or product names whose lumi products this module will check."); |
| 148 | + desc.addUntracked<std::vector<std::string>>("runProducts", {}) |
| 149 | + ->setComment("List of modules or product names whose run products this module will check."); |
| 150 | + desc.addUntracked<std::vector<std::string>>("processProducts", {}) |
| 151 | + ->setComment("List of modules or product names whose process products this module will check."); |
| 152 | + descriptions.addWithDefaultLabel(desc); |
| 153 | + } |
| 154 | + |
| 155 | +} // namespace edmtest |
| 156 | + |
| 157 | +#include "FWCore/Framework/interface/MakerMacros.h" |
| 158 | +DEFINE_FWK_MODULE(edmtest::CheckClassInfo); |
0 commit comments