File indexing completed on 2021-10-08 02:27:21
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 };
0282
0283
0284
0285
0286 EventContentAnalyzer::EventContentAnalyzer(ParameterSet const& iConfig)
0287 : indentation_(iConfig.getUntrackedParameter("indentation", std::string("++"))),
0288 verboseIndentation_(iConfig.getUntrackedParameter("verboseIndentation", std::string(" "))),
0289 moduleLabels_(iConfig.getUntrackedParameter("verboseForModuleLabels", std::vector<std::string>())),
0290 verbose_(iConfig.getUntrackedParameter("verbose", false) || !moduleLabels_.empty()),
0291 getModuleLabels_(iConfig.getUntrackedParameter("getDataForModuleLabels", std::vector<std::string>())),
0292 getData_(iConfig.getUntrackedParameter("getData", false) || !getModuleLabels_.empty()),
0293 evno_(1),
0294 listContent_(iConfig.getUntrackedParameter("listContent", true)),
0295 listProvenance_(iConfig.getUntrackedParameter("listProvenance", false)) {
0296
0297 sort_all(moduleLabels_);
0298 sort_all(getModuleLabels_);
0299 if (getData_) {
0300 callWhenNewProductsRegistered([this](edm::BranchDescription const& iBranch) {
0301 if (getModuleLabels_.empty()) {
0302 const std::string kPathStatus("edm::PathStatus");
0303 const std::string kEndPathStatus("edm::EndPathStatus");
0304 if (iBranch.className() != kPathStatus && iBranch.className() != kEndPathStatus) {
0305 this->consumes(edm::TypeToGet{iBranch.unwrappedTypeID(), PRODUCT_TYPE},
0306 edm::InputTag{iBranch.moduleLabel(), iBranch.productInstanceName(), iBranch.processName()});
0307 }
0308 } else {
0309 for (auto const& mod : this->getModuleLabels_) {
0310 if (iBranch.moduleLabel() == mod) {
0311 this->consumes(edm::TypeToGet{iBranch.unwrappedTypeID(), PRODUCT_TYPE},
0312 edm::InputTag{mod, iBranch.productInstanceName(), iBranch.processName()});
0313 break;
0314 }
0315 }
0316 }
0317 });
0318 }
0319 }
0320
0321 EventContentAnalyzer::~EventContentAnalyzer() {
0322
0323
0324 }
0325
0326
0327
0328
0329
0330
0331 void EventContentAnalyzer::analyze(Event const& iEvent, EventSetup const&) {
0332 typedef std::vector<StableProvenance const*> Provenances;
0333 Provenances provenances;
0334
0335 iEvent.getAllStableProvenance(provenances);
0336
0337 if (listContent_) {
0338 LogAbsolute("EventContent") << "\n"
0339 << indentation_ << "Event " << std::setw(5) << evno_ << " contains "
0340 << provenances.size() << " product" << (provenances.size() == 1 ? "" : "s")
0341 << " with friendlyClassName, moduleLabel, productInstanceName and processName:"
0342 << std::endl;
0343 }
0344
0345 std::string startIndent = indentation_ + verboseIndentation_;
0346 for (auto const& provenance : provenances) {
0347 std::string const& className = provenance->className();
0348 const std::string kPathStatus("edm::PathStatus");
0349 const std::string kEndPathStatus("edm::EndPathStatus");
0350 if (className == kPathStatus || className == kEndPathStatus) {
0351 continue;
0352 }
0353 std::string const& friendlyName = provenance->friendlyClassName();
0354
0355
0356 std::string const& modLabel = provenance->moduleLabel();
0357
0358
0359 std::string const& instanceName = provenance->productInstanceName();
0360
0361
0362 std::string const& processName = provenance->processName();
0363
0364 bool doVerbose = verbose_ && (moduleLabels_.empty() || binary_search_all(moduleLabels_, modLabel));
0365
0366 if (listContent_ || doVerbose) {
0367 LogAbsolute("EventContent") << indentation_ << friendlyName << " \"" << modLabel << "\" \"" << instanceName
0368 << "\" \"" << processName << "\""
0369 << " (productId = " << provenance->productID() << ")" << std::endl;
0370
0371 if (listProvenance_) {
0372 const bool isAlias = provenance->branchDescription().isAlias();
0373 std::string aliasForModLabel;
0374 LogAbsolute("EventContent") << *provenance;
0375 if (isAlias) {
0376 aliasForModLabel = iEvent.getStableProvenance(provenance->originalBranchID()).moduleLabel();
0377 LogAbsolute("EventContent") << "Is an alias for " << aliasForModLabel;
0378 }
0379 ProcessHistory const& processHistory = iEvent.processHistory();
0380 for (ProcessConfiguration const& pc : processHistory) {
0381 if (pc.processName() == provenance->processName()) {
0382 ParameterSetID const& psetID = pc.parameterSetID();
0383 pset::Registry const* psetRegistry = pset::Registry::instance();
0384 ParameterSet const* processPset = psetRegistry->getMapped(psetID);
0385 if (processPset) {
0386 if (processPset->existsAs<ParameterSet>(modLabel)) {
0387 if (isAlias) {
0388 LogAbsolute("EventContent") << "Alias PSet";
0389 }
0390 LogAbsolute("EventContent") << processPset->getParameterSet(modLabel);
0391 }
0392 if (isAlias and processPset->existsAs<ParameterSet>(aliasForModLabel)) {
0393 LogAbsolute("EventContent") << processPset->getParameterSet(aliasForModLabel);
0394 }
0395 }
0396 }
0397 }
0398 }
0399 }
0400 std::string key = friendlyName + std::string(" + \"") + modLabel + std::string("\" + \"") + instanceName +
0401 "\" \"" + processName + "\"";
0402 ++cumulates_[key];
0403
0404 if (doVerbose) {
0405
0406 printObject(iEvent, className, modLabel, instanceName, processName, startIndent, verboseIndentation_);
0407 continue;
0408 }
0409 if (getData_) {
0410 std::string class_and_label = friendlyName + "_" + modLabel;
0411 if (getModuleLabels_.empty() || binary_search_all(getModuleLabels_, modLabel) ||
0412 binary_search_all(getModuleLabels_, class_and_label)) {
0413 try {
0414 GenericHandle handle(className);
0415 } catch (edm::Exception const&) {
0416 LogAbsolute("EventContent") << startIndent << " \"" << className << "\""
0417 << " is an unknown type" << std::endl;
0418 return;
0419 }
0420 GenericHandle handle(className);
0421 iEvent.getByLabel(InputTag(modLabel, instanceName, processName), handle);
0422 }
0423 }
0424 }
0425
0426 ++evno_;
0427 }
0428
0429
0430 void EventContentAnalyzer::endJob() {
0431 typedef std::map<std::string, int> nameMap;
0432
0433 LogAbsolute("EventContent") << "\nSummary for key being the concatenation of friendlyClassName, moduleLabel, "
0434 "productInstanceName and processName"
0435 << std::endl;
0436 for (nameMap::const_iterator it = cumulates_.begin(), itEnd = cumulates_.end(); it != itEnd; ++it) {
0437 LogAbsolute("EventContent") << std::setw(6) << it->second << " occurrences of key " << it->first << std::endl;
0438 }
0439 }
0440
0441 void EventContentAnalyzer::fillDescriptions(ConfigurationDescriptions& descriptions) {
0442 descriptions.setComment(
0443 "This plugin will print a list of all products in the event "
0444 "provenance. It also has options to print and/or get each product.");
0445
0446 ParameterSetDescription desc;
0447
0448 ParameterDescriptionNode* np;
0449
0450 std::string defaultString("++");
0451 np = desc.addOptionalUntracked<std::string>("indentation", defaultString);
0452 np->setComment("This string is printed at the beginning of every line printed during event processing.");
0453
0454 np = desc.addOptionalUntracked<bool>("verbose", false);
0455 np->setComment("If true, the contents of products are printed.");
0456
0457 defaultString = " ";
0458 np = desc.addOptionalUntracked<std::string>("verboseIndentation", defaultString);
0459 np->setComment(
0460 "This string is used to further indent lines when printing the contents of products in verbose mode.");
0461
0462 std::vector<std::string> defaultVString;
0463
0464 np = desc.addOptionalUntracked<std::vector<std::string> >("verboseForModuleLabels", defaultVString);
0465 np->setComment("If this vector is not empty, then only products with module labels on this list are printed.");
0466
0467 np = desc.addOptionalUntracked<bool>("getData", false);
0468 np->setComment("If true the products will be retrieved using getByLabel.");
0469
0470 np = desc.addOptionalUntracked<std::vector<std::string> >("getDataForModuleLabels", defaultVString);
0471 np->setComment(
0472 "If this vector is not empty, then only products with module labels on this list are retrieved by getByLabel.");
0473
0474 np = desc.addOptionalUntracked<bool>("listContent", true);
0475 np->setComment("If true then print a list of all the event content.");
0476
0477 np = desc.addOptionalUntracked<bool>("listProvenance", false);
0478 np->setComment("If true, and if listContent or verbose is true, print provenance information for each product");
0479
0480 descriptions.add("printContent", desc);
0481 }
0482 }
0483
0484 using edm::EventContentAnalyzer;
0485 DEFINE_FWK_MODULE(EventContentAnalyzer);