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