File indexing completed on 2025-01-31 02:19:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include "DataFormats/Provenance/interface/Provenance.h"
0020 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0021 #include "FWCore/Framework/interface/Event.h"
0022 #include "FWCore/Framework/interface/GenericHandle.h"
0023 #include "FWCore/Framework/interface/MakerMacros.h"
0024 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0025 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0026 #include "FWCore/ParameterSet/interface/ParameterDescriptionNode.h"
0027 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0028 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0029 #include "FWCore/Utilities/interface/Algorithms.h"
0030 #include "FWCore/Reflection/interface/FunctionWithDict.h"
0031 #include "FWCore/Reflection/interface/MemberWithDict.h"
0032 #include "FWCore/Reflection/interface/ObjectWithDict.h"
0033 #include "FWCore/Reflection/interface/TypeWithDict.h"
0034 #include "FWCore/Utilities/interface/TypeToGet.h"
0035 #include "FWCore/ParameterSet/interface/Registry.h"
0036
0037
0038 #include <algorithm>
0039 #include <iomanip>
0040 #include <iostream>
0041 #include <map>
0042 #include <sstream>
0043 #include <string>
0044 #include <vector>
0045
0046 namespace edm {
0047 class ConfigurationDescriptions;
0048 namespace {
0049 std::string formatClassName(std::string const& iName) { return std::string("(") + iName + ")"; }
0050
0051 char const* kNameValueSep = "=";
0052
0053 template <typename T>
0054 void doPrint(std::string const& iName, ObjectWithDict const& iObject, std::string const& iIndent) {
0055 LogAbsolute("EventContent") << iIndent << iName << kNameValueSep
0056 << *reinterpret_cast<T*>(iObject.address());
0057 }
0058
0059 template <>
0060 void doPrint<char>(std::string const& iName, ObjectWithDict const& iObject, std::string const& iIndent) {
0061 LogAbsolute("EventContent") << iIndent << iName << kNameValueSep
0062 << static_cast<int>(*reinterpret_cast<char*>(iObject.address()));
0063 }
0064
0065 template <>
0066 void doPrint<unsigned char>(std::string const& iName, ObjectWithDict const& iObject, std::string const& iIndent) {
0067 LogAbsolute("EventContent") << iIndent << iName << kNameValueSep
0068 << static_cast<unsigned int>(
0069 *reinterpret_cast<unsigned char*>(iObject.address()));
0070 }
0071
0072 template <>
0073 void doPrint<bool>(std::string const& iName, ObjectWithDict const& iObject, std::string const& iIndent) {
0074 LogAbsolute("EventContent") << iIndent << iName << kNameValueSep
0075 << ((*reinterpret_cast<bool*>(iObject.address())) ? "true" : "false");
0076 }
0077
0078 typedef void (*FunctionType)(std::string const&, ObjectWithDict const&, std::string const&);
0079 typedef std::map<std::string, FunctionType> TypeToPrintMap;
0080
0081 template <typename T>
0082 void addToMap(TypeToPrintMap& iMap) {
0083 iMap[typeid(T).name()] = doPrint<T>;
0084 }
0085
0086 bool printAsBuiltin(std::string const& iName, ObjectWithDict const& iObject, std::string const& iIndent) {
0087 typedef void (*FunctionType)(std::string const&, ObjectWithDict const&, std::string const&);
0088 typedef std::map<std::string, FunctionType> TypeToPrintMap;
0089 static TypeToPrintMap s_map;
0090 static bool isFirst = true;
0091 if (isFirst) {
0092 addToMap<bool>(s_map);
0093 addToMap<char>(s_map);
0094 addToMap<short>(s_map);
0095 addToMap<int>(s_map);
0096 addToMap<long>(s_map);
0097 addToMap<unsigned char>(s_map);
0098 addToMap<unsigned short>(s_map);
0099 addToMap<unsigned int>(s_map);
0100 addToMap<unsigned long>(s_map);
0101 addToMap<float>(s_map);
0102 addToMap<double>(s_map);
0103 isFirst = false;
0104 }
0105 TypeToPrintMap::iterator itFound = s_map.find(iObject.typeOf().name());
0106 if (itFound == s_map.end()) {
0107 return false;
0108 }
0109 itFound->second(iName, iObject, iIndent);
0110 return true;
0111 }
0112
0113 bool printAsContainer(std::string const& iName,
0114 ObjectWithDict const& iObject,
0115 std::string const& iIndent,
0116 std::string const& iIndentDelta);
0117
0118 void printObject(std::string const& iName,
0119 ObjectWithDict const& iObject,
0120 std::string const& iIndent,
0121 std::string const& iIndentDelta) {
0122 const std::string& printName = iName;
0123 const ObjectWithDict& objectToPrint = iObject;
0124 std::string indent(iIndent);
0125 if (iObject.typeOf().isPointer()) {
0126 LogAbsolute("EventContent") << iIndent << iName << kNameValueSep << formatClassName(iObject.typeOf().name())
0127 << std::hex << iObject.address() << std::dec;
0128 TypeWithDict pointedType = iObject.typeOf().toType();
0129 if (TypeWithDict::byName("void") == pointedType || pointedType.isPointer() || iObject.address() == nullptr) {
0130 return;
0131 }
0132 return;
0133
0134
0135
0136
0137
0138
0139
0140
0141 }
0142 std::string typeName(objectToPrint.typeOf().name());
0143 if (typeName.empty()) {
0144 typeName = "<unknown>";
0145 }
0146
0147 if (printAsBuiltin(printName, objectToPrint, indent)) {
0148 return;
0149 }
0150 if (printAsContainer(printName, objectToPrint, indent, iIndentDelta)) {
0151 return;
0152 }
0153
0154 LogAbsolute("EventContent") << indent << printName << " " << formatClassName(typeName);
0155 indent += iIndentDelta;
0156
0157 TypeDataMembers dataMembers(objectToPrint.typeOf());
0158 for (auto const& dataMember : dataMembers) {
0159 MemberWithDict const member(dataMember);
0160
0161 try {
0162 printObject(member.name(), member.get(objectToPrint), indent, iIndentDelta);
0163 } catch (std::exception& iEx) {
0164 LogAbsolute("EventContent") << indent << member.name() << " <exception caught(" << iEx.what() << ")>\n";
0165 }
0166 }
0167 }
0168
0169 bool printAsContainer(std::string const& iName,
0170 ObjectWithDict const& iObject,
0171 std::string const& iIndent,
0172 std::string const& iIndentDelta) {
0173 ObjectWithDict sizeObj;
0174 try {
0175 size_t temp;
0176 FunctionWithDict sizeFunc = iObject.typeOf().functionMemberByName("size");
0177 assert(sizeFunc.finalReturnType() == typeid(size_t));
0178 sizeObj = ObjectWithDict(TypeWithDict(typeid(size_t)), &temp);
0179 sizeFunc.invoke(iObject, &sizeObj);
0180
0181 size_t size = *reinterpret_cast<size_t*>(sizeObj.address());
0182 FunctionWithDict atMember;
0183 try {
0184 atMember = iObject.typeOf().functionMemberByName("at");
0185 } catch (std::exception const& x) {
0186
0187 return false;
0188 }
0189 LogAbsolute("EventContent") << iIndent << iName << kNameValueSep << "[size=" << size << "]";
0190 ObjectWithDict contained;
0191 std::string indexIndent = iIndent + iIndentDelta;
0192 TypeWithDict atReturnType(atMember.finalReturnType());
0193
0194
0195
0196
0197
0198
0199 bool const isRef = atReturnType.isReference();
0200 void* refMemoryBuffer = nullptr;
0201 size_t index = 0;
0202
0203
0204
0205 std::vector<void*> args;
0206 args.push_back(&index);
0207 for (; index != size; ++index) {
0208 std::ostringstream sizeS;
0209 sizeS << "[" << index << "]";
0210 if (isRef) {
0211 ObjectWithDict refObject(atReturnType, &refMemoryBuffer);
0212 atMember.invoke(iObject, &refObject, args);
0213
0214
0215 contained = ObjectWithDict(atReturnType, refMemoryBuffer);
0216 } else {
0217 contained = atReturnType.construct();
0218 atMember.invoke(iObject, &contained, args);
0219 }
0220
0221 try {
0222 printObject(sizeS.str(), contained, indexIndent, iIndentDelta);
0223 } catch (std::exception& iEx) {
0224 LogAbsolute("EventContent") << indexIndent << iName << " <exception caught(" << iEx.what() << ")>\n";
0225 }
0226 if (!isRef) {
0227 contained.destruct(true);
0228 }
0229 }
0230 return true;
0231 } catch (std::exception const& x) {
0232
0233 return false;
0234 }
0235 return false;
0236 }
0237
0238 void printObject(Event const& iEvent,
0239 std::string const& iClassName,
0240 std::string const& iModuleLabel,
0241 std::string const& iInstanceLabel,
0242 std::string const& iProcessName,
0243 std::string const& iIndent,
0244 std::string const& iIndentDelta) {
0245 try {
0246 GenericHandle handle(iClassName);
0247 } catch (edm::Exception const&) {
0248 LogAbsolute("EventContent") << iIndent << " \"" << iClassName << "\""
0249 << " is an unknown type" << std::endl;
0250 return;
0251 }
0252 GenericHandle handle(iClassName);
0253 iEvent.getByLabel(InputTag(iModuleLabel, iInstanceLabel, iProcessName), handle);
0254 std::string className = formatClassName(iClassName);
0255 printObject(className, *handle, iIndent, iIndentDelta);
0256 }
0257 }
0258
0259 class EventContentAnalyzer : public one::EDAnalyzer<> {
0260 public:
0261 explicit EventContentAnalyzer(ParameterSet const&);
0262 ~EventContentAnalyzer() override;
0263
0264 void analyze(Event const&, EventSetup const&) override;
0265 void endJob() override;
0266
0267 static void fillDescriptions(ConfigurationDescriptions& descriptions);
0268
0269 private:
0270
0271 std::string indentation_;
0272 std::string verboseIndentation_;
0273 std::vector<std::string> moduleLabels_;
0274 bool verbose_;
0275 std::vector<std::string> getModuleLabels_;
0276 bool getData_;
0277 int evno_;
0278 std::map<std::string, int> cumulates_;
0279 bool listContent_;
0280 bool listProvenance_;
0281 bool listPathStatus_;
0282 };
0283
0284
0285
0286
0287 EventContentAnalyzer::EventContentAnalyzer(ParameterSet const& iConfig)
0288 : indentation_(iConfig.getUntrackedParameter<std::string>("indentation")),
0289 verboseIndentation_(iConfig.getUntrackedParameter<std::string>("verboseIndentation")),
0290 moduleLabels_(iConfig.getUntrackedParameter<std::vector<std::string>>("verboseForModuleLabels")),
0291 verbose_(iConfig.getUntrackedParameter<bool>("verbose") || !moduleLabels_.empty()),
0292 getModuleLabels_(iConfig.getUntrackedParameter<std::vector<std::string>>("getDataForModuleLabels")),
0293 getData_(iConfig.getUntrackedParameter<bool>("getData") || !getModuleLabels_.empty()),
0294 evno_(1),
0295 listContent_(iConfig.getUntrackedParameter<bool>("listContent")),
0296 listProvenance_(iConfig.getUntrackedParameter<bool>("listProvenance")),
0297 listPathStatus_(iConfig.getUntrackedParameter<bool>("listPathStatus")) {
0298
0299 sort_all(moduleLabels_);
0300 sort_all(getModuleLabels_);
0301 if (getData_) {
0302 callWhenNewProductsRegistered([this](edm::ProductDescription const& iBranch) {
0303 if (getModuleLabels_.empty()) {
0304 const std::string kPathStatus("edm::PathStatus");
0305 const std::string kEndPathStatus("edm::EndPathStatus");
0306 if (iBranch.className() != kPathStatus && iBranch.className() != kEndPathStatus) {
0307 this->consumes(edm::TypeToGet{iBranch.unwrappedTypeID(), PRODUCT_TYPE},
0308 edm::InputTag{iBranch.moduleLabel(), iBranch.productInstanceName(), iBranch.processName()});
0309 }
0310 } else {
0311 for (auto const& mod : this->getModuleLabels_) {
0312 if (iBranch.moduleLabel() == mod) {
0313 this->consumes(edm::TypeToGet{iBranch.unwrappedTypeID(), PRODUCT_TYPE},
0314 edm::InputTag{mod, iBranch.productInstanceName(), iBranch.processName()});
0315 break;
0316 }
0317 }
0318 }
0319 });
0320 }
0321 }
0322
0323 EventContentAnalyzer::~EventContentAnalyzer() {
0324
0325
0326 }
0327
0328
0329
0330
0331
0332
0333 void EventContentAnalyzer::analyze(Event const& iEvent, EventSetup const&) {
0334 typedef std::vector<StableProvenance const*> Provenances;
0335 Provenances provenances;
0336
0337 iEvent.getAllStableProvenance(provenances);
0338
0339 if (listContent_) {
0340 LogAbsolute("EventContent") << "\n"
0341 << indentation_ << "Event " << std::setw(5) << evno_ << " contains "
0342 << provenances.size() << " product" << (provenances.size() == 1 ? "" : "s")
0343 << " with friendlyClassName, moduleLabel, productInstanceName and processName:"
0344 << std::endl;
0345 }
0346
0347 std::string startIndent = indentation_ + verboseIndentation_;
0348 for (auto const& provenance : provenances) {
0349 std::string const& className = provenance->className();
0350 const std::string kPathStatus("edm::PathStatus");
0351 const std::string kEndPathStatus("edm::EndPathStatus");
0352 if (not listPathStatus_ and (className == kPathStatus || className == kEndPathStatus)) {
0353 continue;
0354 }
0355 std::string const& friendlyName = provenance->friendlyClassName();
0356
0357
0358 std::string const& modLabel = provenance->moduleLabel();
0359
0360
0361 std::string const& instanceName = provenance->productInstanceName();
0362
0363
0364 std::string const& processName = provenance->processName();
0365
0366 bool doVerbose = verbose_ && (moduleLabels_.empty() || binary_search_all(moduleLabels_, modLabel));
0367
0368 if (listContent_ || doVerbose) {
0369 LogAbsolute("EventContent") << indentation_ << friendlyName << " \"" << modLabel << "\" \"" << instanceName
0370 << "\" \"" << processName << "\""
0371 << " (productId = " << provenance->productID() << ")" << std::endl;
0372
0373 if (listProvenance_) {
0374 const bool isAlias = provenance->productDescription().isAlias();
0375 std::string aliasForModLabel;
0376 LogAbsolute("EventContent") << *provenance;
0377 if (isAlias) {
0378 aliasForModLabel = iEvent.getStableProvenance(provenance->originalBranchID()).moduleLabel();
0379 LogAbsolute("EventContent") << "Is an alias for " << aliasForModLabel;
0380 }
0381 ProcessHistory const& processHistory = iEvent.processHistory();
0382 for (ProcessConfiguration const& pc : processHistory) {
0383 if (pc.processName() == provenance->processName()) {
0384 ParameterSetID const& psetID = pc.parameterSetID();
0385 pset::Registry const* psetRegistry = pset::Registry::instance();
0386 ParameterSet const* processPset = psetRegistry->getMapped(psetID);
0387 if (processPset) {
0388 if (processPset->existsAs<ParameterSet>(modLabel)) {
0389 if (isAlias) {
0390 LogAbsolute("EventContent") << "Alias PSet";
0391 }
0392 LogAbsolute("EventContent") << processPset->getParameterSet(modLabel);
0393 }
0394 if (isAlias and processPset->existsAs<ParameterSet>(aliasForModLabel)) {
0395 LogAbsolute("EventContent") << processPset->getParameterSet(aliasForModLabel);
0396 }
0397 }
0398 }
0399 }
0400 }
0401 }
0402 std::string key = friendlyName + std::string(" + \"") + modLabel + std::string("\" + \"") + instanceName +
0403 "\" \"" + processName + "\"";
0404 ++cumulates_[key];
0405
0406 if (doVerbose) {
0407
0408 printObject(iEvent, className, modLabel, instanceName, processName, startIndent, verboseIndentation_);
0409 continue;
0410 }
0411 if (getData_) {
0412 std::string class_and_label = friendlyName + "_" + modLabel;
0413 if (getModuleLabels_.empty() || binary_search_all(getModuleLabels_, modLabel) ||
0414 binary_search_all(getModuleLabels_, class_and_label)) {
0415 try {
0416 GenericHandle handle(className);
0417 } catch (edm::Exception const&) {
0418 LogAbsolute("EventContent") << startIndent << " \"" << className << "\""
0419 << " is an unknown type" << std::endl;
0420 return;
0421 }
0422 GenericHandle handle(className);
0423 iEvent.getByLabel(InputTag(modLabel, instanceName, processName), handle);
0424 }
0425 }
0426 }
0427
0428 ++evno_;
0429 }
0430
0431
0432 void EventContentAnalyzer::endJob() {
0433 typedef std::map<std::string, int> nameMap;
0434
0435 LogAbsolute("EventContent") << "\nSummary for key being the concatenation of friendlyClassName, moduleLabel, "
0436 "productInstanceName and processName"
0437 << std::endl;
0438 for (nameMap::const_iterator it = cumulates_.begin(), itEnd = cumulates_.end(); it != itEnd; ++it) {
0439 LogAbsolute("EventContent") << std::setw(6) << it->second << " occurrences of key " << it->first << std::endl;
0440 }
0441 }
0442
0443 void EventContentAnalyzer::fillDescriptions(ConfigurationDescriptions& descriptions) {
0444 descriptions.setComment(
0445 "This plugin will print a list of all products in the event "
0446 "provenance. It also has options to print and/or get each product.");
0447
0448 ParameterSetDescription desc;
0449
0450 ParameterDescriptionNode* np;
0451
0452 std::string defaultString("++");
0453 np = desc.addUntracked<std::string>("indentation", defaultString);
0454 np->setComment("This string is printed at the beginning of every line printed during event processing.");
0455
0456 np = desc.addUntracked<bool>("verbose", false);
0457 np->setComment("If true, the contents of products are printed.");
0458
0459 defaultString = " ";
0460 np = desc.addUntracked<std::string>("verboseIndentation", defaultString);
0461 np->setComment(
0462 "This string is used to further indent lines when printing the contents of products in verbose mode.");
0463
0464 std::vector<std::string> defaultVString;
0465
0466 np = desc.addUntracked<std::vector<std::string>>("verboseForModuleLabels", defaultVString);
0467 np->setComment("If this vector is not empty, then only products with module labels on this list are printed.");
0468
0469 np = desc.addUntracked<bool>("getData", false);
0470 np->setComment("If true the products will be retrieved using getByLabel.");
0471
0472 np = desc.addUntracked<std::vector<std::string>>("getDataForModuleLabels", defaultVString);
0473 np->setComment(
0474 "If this vector is not empty, then only products with module labels on this list are retrieved by getByLabel.");
0475
0476 np = desc.addUntracked<bool>("listContent", true);
0477 np->setComment("If true then print a list of all the event content.");
0478
0479 np = desc.addUntracked<bool>("listProvenance", false);
0480 np->setComment("If true, and if listContent or verbose is true, print provenance information for each product");
0481
0482 desc.addUntracked<bool>("listPathStatus", false)
0483 ->setComment("If true, also show PathStatus/EndPathStatus data products.");
0484 descriptions.add("printContent", desc);
0485 descriptions.addDefault(desc);
0486 }
0487 }
0488
0489 using edm::EventContentAnalyzer;
0490 DEFINE_FWK_MODULE(EventContentAnalyzer);