00001
00002
00003
00004
00005
00012
00013
00014
00015
00016
00017
00018
00019 #include "DataFormats/Provenance/interface/Provenance.h"
00020 #include "FWCore/Framework/interface/EDAnalyzer.h"
00021 #include "FWCore/Framework/interface/Event.h"
00022 #include "FWCore/Framework/interface/GenericHandle.h"
00023 #include "FWCore/Framework/interface/MakerMacros.h"
00024 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00025 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
00026 #include "FWCore/ParameterSet/interface/ParameterDescriptionNode.h"
00027 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00028 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
00029 #include "FWCore/Utilities/interface/Algorithms.h"
00030 #include "FWCore/Utilities/interface/FunctionWithDict.h"
00031 #include "FWCore/Utilities/interface/MemberWithDict.h"
00032 #include "FWCore/Utilities/interface/ObjectWithDict.h"
00033 #include "FWCore/Utilities/interface/TypeWithDict.h"
00034
00035
00036 #include <algorithm>
00037 #include <iomanip>
00038 #include <iostream>
00039 #include <map>
00040 #include <sstream>
00041 #include <string>
00042 #include <vector>
00043
00044 namespace edm {
00045 class ConfigurationDescriptions;
00046 namespace {
00047 std::string formatClassName(std::string const& iName) {
00048 return std::string("(")+iName+")";
00049 }
00050
00051 char const* kNameValueSep = "=";
00053 template<typename T>
00054 void doPrint(std::string const& iName, ObjectWithDict const& iObject, std::string const& iIndent) {
00055 LogAbsolute("EventContent") << iIndent << iName << kNameValueSep << *reinterpret_cast<T*>(iObject.address());
00056 }
00057
00058 template<>
00059 void doPrint<char>(std::string const& iName, ObjectWithDict const& iObject, std::string const& iIndent) {
00060 LogAbsolute("EventContent") << iIndent << iName << kNameValueSep << static_cast<int>(*reinterpret_cast<char*>(iObject.address()));
00061 }
00062
00063 template<>
00064 void doPrint<unsigned char>(std::string const& iName, ObjectWithDict const& iObject, std::string const& iIndent) {
00065 LogAbsolute("EventContent") << iIndent << iName << kNameValueSep << static_cast<unsigned int>(*reinterpret_cast<unsigned char*>(iObject.address()));
00066 }
00067
00068 template<>
00069 void doPrint<bool>(std::string const& iName, ObjectWithDict const& iObject, std::string const& iIndent) {
00070 LogAbsolute("EventContent") << iIndent << iName << kNameValueSep << ((*reinterpret_cast<bool*>(iObject.address()))?"true":"false");
00071 }
00072
00073 typedef void(*FunctionType)(std::string const&, ObjectWithDict const&, std::string const&);
00074 typedef std::map<std::string, FunctionType> TypeToPrintMap;
00075
00076 template<typename T>
00077 void addToMap(TypeToPrintMap& iMap) {
00078 iMap[typeid(T).name()] = doPrint<T>;
00079 }
00080
00081 bool printAsBuiltin(std::string const& iName,
00082 ObjectWithDict const& iObject,
00083 std::string const& iIndent) {
00084 typedef void(*FunctionType)(std::string const&, ObjectWithDict const&, std::string const&);
00085 typedef std::map<std::string, FunctionType> TypeToPrintMap;
00086 static TypeToPrintMap s_map;
00087 static bool isFirst = true;
00088 if(isFirst) {
00089 addToMap<bool>(s_map);
00090 addToMap<char>(s_map);
00091 addToMap<short>(s_map);
00092 addToMap<int>(s_map);
00093 addToMap<long>(s_map);
00094 addToMap<unsigned char>(s_map);
00095 addToMap<unsigned short>(s_map);
00096 addToMap<unsigned int>(s_map);
00097 addToMap<unsigned long>(s_map);
00098 addToMap<float>(s_map);
00099 addToMap<double>(s_map);
00100 isFirst = false;
00101 }
00102 TypeToPrintMap::iterator itFound = s_map.find(iObject.typeOf().name());
00103 if(itFound == s_map.end()) {
00104
00105 return false;
00106 }
00107 itFound->second(iName, iObject, iIndent);
00108 return true;
00109 }
00110
00111 bool printAsContainer(std::string const& iName,
00112 ObjectWithDict const& iObject,
00113 std::string const& iIndent,
00114 std::string const& iIndentDelta);
00115
00116 void printObject(std::string const& iName,
00117 ObjectWithDict const& iObject,
00118 std::string const& iIndent,
00119 std::string const& iIndentDelta) {
00120 std::string printName = iName;
00121 ObjectWithDict objectToPrint = iObject;
00122 std::string indent(iIndent);
00123 if(iObject.typeOf().isPointer()) {
00124 LogAbsolute("EventContent") << iIndent << iName << kNameValueSep << formatClassName(iObject.typeOf().name()) << std::hex << iObject.address() << std::dec;
00125 TypeWithDict pointedType = iObject.typeOf().toType();
00126 if(TypeWithDict::byName("void") == pointedType ||
00127 pointedType.isPointer() ||
00128 iObject.address() == 0) {
00129 return;
00130 }
00131 return;
00132
00133
00134
00135
00136
00137
00138
00139
00140 }
00141 std::string typeName(objectToPrint.typeOf().name());
00142 if(typeName.empty()) {
00143 typeName = "<unknown>";
00144 }
00145
00146 if(printAsBuiltin(printName, objectToPrint, indent)) {
00147 return;
00148 }
00149 if(printAsContainer(printName, objectToPrint, indent, iIndentDelta)) {
00150 return;
00151 }
00152
00153 LogAbsolute("EventContent") << indent << printName << " " << formatClassName(typeName);
00154 indent += iIndentDelta;
00155
00156 TypeDataMembers dataMembers(objectToPrint.typeOf());
00157 for(auto const& dataMember : dataMembers) {
00158 MemberWithDict const member(dataMember);
00159
00160 try {
00161 printObject(member.name(),
00162 member.get(objectToPrint),
00163 indent,
00164 iIndentDelta);
00165 }catch(std::exception& iEx) {
00166 LogAbsolute("EventContent") << indent << member.name() << " <exception caught(" << iEx.what() << ")>\n";
00167 }
00168 }
00169 }
00170
00171 bool printAsContainer(std::string const& iName,
00172 ObjectWithDict const& iObject,
00173 std::string const& iIndent,
00174 std::string const& iIndentDelta) {
00175 ObjectWithDict sizeObj;
00176 try {
00177 size_t temp;
00178 sizeObj = ObjectWithDict(TypeWithDict(typeid(size_t)), &temp);
00179 iObject.typeOf().functionMemberByName("size").invoke(iObject, &sizeObj);
00180 assert(iObject.typeOf().functionMemberByName("size").returnType().typeInfo() == typeid(size_t));
00181
00182 assert(sizeObj.typeOf().typeInfo() == typeid(size_t));
00183 size_t size = *reinterpret_cast<size_t*>(sizeObj.address());
00184 FunctionWithDict atMember;
00185 try {
00186 atMember = iObject.typeOf().functionMemberByName("at");
00187 } catch(std::exception const& x) {
00188
00189 return false;
00190 }
00191 LogAbsolute("EventContent") << iIndent << iName << kNameValueSep << "[size=" << size << "]";
00192 ObjectWithDict contained;
00193 std::string indexIndent = iIndent + iIndentDelta;
00194 TypeWithDict atReturnType(atMember.returnType());
00195
00196
00197
00198
00199
00200
00201 bool const isRef = atReturnType.isReference();
00202 void* refMemoryBuffer = 0;
00203 size_t index = 0;
00204
00205
00206
00207 std::vector<void*> args;
00208 args.push_back(&index);
00209 for(; index != size; ++index) {
00210 std::ostringstream sizeS;
00211 sizeS << "[" << index << "]";
00212 if(isRef) {
00213 ObjectWithDict refObject(atReturnType, &refMemoryBuffer);
00214 atMember.invoke(iObject, &refObject, args);
00215
00216
00217 contained = ObjectWithDict(atReturnType, refMemoryBuffer);
00218 } else {
00219 contained = atReturnType.construct();
00220 atMember.invoke(iObject, &contained, args);
00221 }
00222
00223 try {
00224 printObject(sizeS.str(), contained, indexIndent, iIndentDelta);
00225 } catch(std::exception& iEx) {
00226 LogAbsolute("EventContent") << indexIndent << iName << " <exception caught("
00227 << iEx.what() << ")>\n";
00228 }
00229 if(!isRef) {
00230 atReturnType.destruct(contained.address(), true);
00231 }
00232 }
00233 return true;
00234 } catch(std::exception const& x) {
00235
00236 return false;
00237 }
00238 return false;
00239 }
00240
00241 void printObject(Event const& iEvent,
00242 std::string const& iClassName,
00243 std::string const& iModuleLabel,
00244 std::string const& iInstanceLabel,
00245 std::string const& iProcessName,
00246 std::string const& iIndent,
00247 std::string const& iIndentDelta) {
00248 try {
00249 GenericHandle handle(iClassName);
00250 }catch(edm::Exception const&) {
00251 LogAbsolute("EventContent") << iIndent << " \"" << iClassName << "\"" << " is an unknown type" << std::endl;
00252 return;
00253 }
00254 GenericHandle handle(iClassName);
00255 iEvent.getByLabel(InputTag(iModuleLabel, iInstanceLabel, iProcessName), handle);
00256 std::string className = formatClassName(iClassName);
00257 printObject(className, *handle, iIndent, iIndentDelta);
00258 }
00259 }
00260
00261 class EventContentAnalyzer : public EDAnalyzer {
00262 public:
00263 explicit EventContentAnalyzer(ParameterSet const&);
00264 ~EventContentAnalyzer();
00265
00266 virtual void analyze(Event const&, EventSetup const&);
00267 virtual void endJob();
00268
00269 static void fillDescriptions(ConfigurationDescriptions& descriptions);
00270
00271 private:
00272
00273
00274 std::string indentation_;
00275 std::string verboseIndentation_;
00276 std::vector<std::string> moduleLabels_;
00277 bool verbose_;
00278 std::vector<std::string> getModuleLabels_;
00279 bool getData_;
00280 int evno_;
00281 std::map<std::string, int> cumulates_;
00282 bool listContent_;
00283 };
00284
00285
00286
00287
00288 EventContentAnalyzer::EventContentAnalyzer(ParameterSet const& iConfig) :
00289 indentation_(iConfig.getUntrackedParameter("indentation", std::string("++"))),
00290 verboseIndentation_(iConfig.getUntrackedParameter("verboseIndentation", std::string(" "))),
00291 moduleLabels_(iConfig.getUntrackedParameter("verboseForModuleLabels", std::vector<std::string>())),
00292 verbose_(iConfig.getUntrackedParameter("verbose", false) || moduleLabels_.size()>0),
00293 getModuleLabels_(iConfig.getUntrackedParameter("getDataForModuleLabels", std::vector<std::string>())),
00294 getData_(iConfig.getUntrackedParameter("getData", false) || getModuleLabels_.size()>0),
00295 evno_(1),
00296 listContent_(iConfig.getUntrackedParameter("listContent", true)){
00297
00298 sort_all(moduleLabels_);
00299 sort_all(getModuleLabels_);
00300 }
00301
00302 EventContentAnalyzer::~EventContentAnalyzer() {
00303
00304
00305
00306
00307 }
00308
00309
00310
00311
00312
00313
00314 void
00315 EventContentAnalyzer::analyze(Event const& iEvent, EventSetup const&) {
00316 typedef std::vector<Provenance const*> Provenances;
00317 Provenances provenances;
00318
00319 iEvent.getAllProvenance(provenances);
00320
00321 if(listContent_) {
00322 LogAbsolute("EventContent") << "\n" << indentation_ << "Event " << std::setw(5) << evno_ << " contains "
00323 << provenances.size() << " product" << (provenances.size() == 1 ? "" : "s")
00324 << " with friendlyClassName, moduleLabel, productInstanceName and processName:"
00325 << std::endl;
00326 }
00327
00328 std::string startIndent = indentation_+verboseIndentation_;
00329 for(Provenances::iterator itProv = provenances.begin(), itProvEnd = provenances.end();
00330 itProv != itProvEnd;
00331 ++itProv) {
00332 std::string const& className = (*itProv)->className();
00333
00334 std::string const& friendlyName = (*itProv)->friendlyClassName();
00335
00336
00337 std::string const& modLabel = (*itProv)->moduleLabel();
00338
00339
00340 std::string const& instanceName = (*itProv)->productInstanceName();
00341
00342
00343 std::string const& processName = (*itProv)->processName();
00344
00345 bool doVerbose = verbose_ && (moduleLabels_.empty() ||
00346 binary_search_all(moduleLabels_, modLabel));
00347
00348 if(listContent_ || doVerbose) {
00349 LogAbsolute("EventContent") << indentation_ << friendlyName
00350 << " \"" << modLabel
00351 << "\" \"" << instanceName << "\" \""
00352 << processName << "\""
00353 << " (productId = " << (*itProv)->productID() << ")"
00354 << std::endl;
00355 }
00356
00357 std::string key = friendlyName
00358 + std::string(" + \"") + modLabel
00359 + std::string("\" + \"") + instanceName + "\" \"" + processName + "\"";
00360 ++cumulates_[key];
00361
00362 if(doVerbose) {
00363
00364 printObject(iEvent,
00365 className,
00366 modLabel,
00367 instanceName,
00368 processName,
00369 startIndent,
00370 verboseIndentation_);
00371 continue;
00372 }
00373 if(getData_) {
00374 std::string class_and_label = friendlyName + "_" + modLabel;
00375 if(getModuleLabels_.empty() ||
00376 binary_search_all(getModuleLabels_, modLabel) ||
00377 binary_search_all(getModuleLabels_, class_and_label)) {
00378 try {
00379 GenericHandle handle(className);
00380 } catch(edm::Exception const&) {
00381 LogAbsolute("EventContent") << startIndent << " \"" << className << "\"" << " is an unknown type" << std::endl;
00382 return;
00383 }
00384 GenericHandle handle(className);
00385 iEvent.getByLabel(InputTag(modLabel,
00386 instanceName,
00387 processName),
00388 handle);
00389 }
00390 }
00391 }
00392
00393 ++evno_;
00394 }
00395
00396
00397 void
00398 EventContentAnalyzer::endJob() {
00399 typedef std::map<std::string, int> nameMap;
00400
00401 LogAbsolute("EventContent") << "\nSummary for key being the concatenation of friendlyClassName, moduleLabel, productInstanceName and processName" << std::endl;
00402 for(nameMap::const_iterator it = cumulates_.begin(), itEnd = cumulates_.end();
00403 it != itEnd;
00404 ++it) {
00405 LogAbsolute("EventContent") << std::setw(6) << it->second << " occurrences of key " << it->first << std::endl;
00406 }
00407
00408
00409
00410
00411
00412 }
00413
00414 void
00415 EventContentAnalyzer::fillDescriptions(ConfigurationDescriptions& descriptions) {
00416
00417 descriptions.setComment("This plugin will print a list of all products in the event "
00418 "provenance. It also has options to print and/or get each product.");
00419
00420 ParameterSetDescription desc;
00421
00422 ParameterDescriptionNode* np;
00423
00424 std::string defaultString("++");
00425 np = desc.addOptionalUntracked<std::string>("indentation", defaultString);
00426 np->setComment("This string is printed at the beginning of every line printed during event processing.");
00427
00428 np = desc.addOptionalUntracked<bool>("verbose", false);
00429 np->setComment("If true, the contents of products are printed.");
00430
00431 defaultString = " ";
00432 np = desc.addOptionalUntracked<std::string>("verboseIndentation", defaultString);
00433 np->setComment("This string is used to further indent lines when printing the contents of products in verbose mode.");
00434
00435 std::vector<std::string> defaultVString;
00436
00437 np = desc.addOptionalUntracked<std::vector<std::string> >("verboseForModuleLabels", defaultVString);
00438 np->setComment("If this vector is not empty, then only products with module labels on this list are printed.");
00439
00440 np = desc.addOptionalUntracked<bool>("getData", false);
00441 np->setComment("If true the products will be retrieved using getByLabel.");
00442
00443 np = desc.addOptionalUntracked<std::vector<std::string> >("getDataForModuleLabels", defaultVString);
00444 np->setComment("If this vector is not empty, then only products with module labels on this list are retrieved by getByLabel.");
00445
00446 np = desc.addOptionalUntracked<bool>("listContent", true);
00447 np->setComment("If true then print a list of all the event content.");
00448
00449
00450 descriptions.add("printContent", desc);
00451 }
00452 }
00453
00454 using edm::EventContentAnalyzer;
00455 DEFINE_FWK_MODULE(EventContentAnalyzer);