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