CMS 3D CMS Logo

EventContentAnalyzer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Modules
4 // Class: EventContentAnalyzer
5 //
12 //
13 // Original Author: Chris Jones
14 // Created: Mon Sep 19 11:47:28 CEST 2005
15 //
16 //
17 
18 // user include files
35 
36 // system include files
37 #include <algorithm>
38 #include <iomanip>
39 #include <iostream>
40 #include <map>
41 #include <sstream>
42 #include <string>
43 #include <vector>
44 
45 namespace edm {
47  namespace {
48  std::string formatClassName(std::string const& iName) {
49  return std::string("(")+iName+")";
50  }
51 
52  char const* kNameValueSep = "=";
54  template<typename T>
55  void doPrint(std::string const& iName, ObjectWithDict const& iObject, std::string const& iIndent) {
56  LogAbsolute("EventContent") << iIndent << iName << kNameValueSep << *reinterpret_cast<T*>(iObject.address());// << "\n";
57  }
58 
59  template<>
60  void doPrint<char>(std::string const& iName, ObjectWithDict const& iObject, std::string const& iIndent) {
61  LogAbsolute("EventContent") << iIndent << iName << kNameValueSep << static_cast<int>(*reinterpret_cast<char*>(iObject.address()));// << "\n";
62  }
63 
64  template<>
65  void doPrint<unsigned char>(std::string const& iName, ObjectWithDict const& iObject, std::string const& iIndent) {
66  LogAbsolute("EventContent") << iIndent << iName << kNameValueSep << static_cast<unsigned int>(*reinterpret_cast<unsigned char*>(iObject.address()));// << "\n";
67  }
68 
69  template<>
70  void doPrint<bool>(std::string const& iName, ObjectWithDict const& iObject, std::string const& iIndent) {
71  LogAbsolute("EventContent") << iIndent << iName << kNameValueSep << ((*reinterpret_cast<bool*>(iObject.address()))?"true":"false");// << "\n";
72  }
73 
74  typedef void(*FunctionType)(std::string const&, ObjectWithDict const&, std::string const&);
75  typedef std::map<std::string, FunctionType> TypeToPrintMap;
76 
77  template<typename T>
78  void addToMap(TypeToPrintMap& iMap) {
79  iMap[typeid(T).name()] = doPrint<T>;
80  }
81 
82  bool printAsBuiltin(std::string const& iName,
83  ObjectWithDict const& iObject,
84  std::string const& iIndent) {
85  typedef void(*FunctionType)(std::string const&, ObjectWithDict const&, std::string const&);
86  typedef std::map<std::string, FunctionType> TypeToPrintMap;
87  static TypeToPrintMap s_map;
88  static bool isFirst = true;
89  if(isFirst) {
90  addToMap<bool>(s_map);
91  addToMap<char>(s_map);
92  addToMap<short>(s_map);
93  addToMap<int>(s_map);
94  addToMap<long>(s_map);
95  addToMap<unsigned char>(s_map);
96  addToMap<unsigned short>(s_map);
97  addToMap<unsigned int>(s_map);
98  addToMap<unsigned long>(s_map);
99  addToMap<float>(s_map);
100  addToMap<double>(s_map);
101  isFirst = false;
102  }
103  TypeToPrintMap::iterator itFound = s_map.find(iObject.typeOf().name());
104  if(itFound == s_map.end()) {
105 
106  return false;
107  }
108  itFound->second(iName, iObject, iIndent);
109  return true;
110  }
111 
112  bool printAsContainer(std::string const& iName,
113  ObjectWithDict const& iObject,
114  std::string const& iIndent,
115  std::string const& iIndentDelta);
116 
117  void printObject(std::string const& iName,
118  ObjectWithDict const& iObject,
119  std::string const& iIndent,
120  std::string const& iIndentDelta) {
121  const std::string& printName = iName;
122  const ObjectWithDict& objectToPrint = iObject;
123  std::string indent(iIndent);
124  if(iObject.typeOf().isPointer()) {
125  LogAbsolute("EventContent") << iIndent << iName << kNameValueSep << formatClassName(iObject.typeOf().name()) << std::hex << iObject.address() << std::dec;// << "\n";
126  TypeWithDict pointedType = iObject.typeOf().toType(); // for Pointers, I get the real type this way
127  if(TypeWithDict::byName("void") == pointedType ||
128  pointedType.isPointer() ||
129  iObject.address() == nullptr) {
130  return;
131  }
132  return;
133  /*
134  //have the code that follows print the contents of the data to which the pointer points
135  objectToPrint = ObjectWithDict(pointedType, iObject.address());
136  //try to convert it to its actual type (assuming the original type was a base class)
137  objectToPrint = ObjectWithDict(objectToPrint.castObject(objectToPrint.dynamicType()));
138  printName = std::string("*")+iName;
139  indent += iIndentDelta;
140  */
141  }
142  std::string typeName(objectToPrint.typeOf().name());
143  if(typeName.empty()) {
144  typeName = "<unknown>";
145  }
146 
147  if(printAsBuiltin(printName, objectToPrint, indent)) {
148  return;
149  }
150  if(printAsContainer(printName, objectToPrint, indent, iIndentDelta)) {
151  return;
152  }
153 
154  LogAbsolute("EventContent") << indent << printName << " " << formatClassName(typeName);// << "\n";
155  indent += iIndentDelta;
156  //print all the data members
157  TypeDataMembers dataMembers(objectToPrint.typeOf());
158  for(auto const& dataMember : dataMembers) {
159  MemberWithDict const member(dataMember);
160  //LogAbsolute("EventContent") << " debug " << member.name() << " " << member.typeName() << "\n";
161  try {
162  printObject(member.name(),
163  member.get(objectToPrint),
164  indent,
165  iIndentDelta);
166  }catch(std::exception& iEx) {
167  LogAbsolute("EventContent") << indent << member.name() << " <exception caught(" << iEx.what() << ")>\n";
168  }
169  }
170  }
171 
172  bool printAsContainer(std::string const& iName,
173  ObjectWithDict const& iObject,
174  std::string const& iIndent,
175  std::string const& iIndentDelta) {
176  ObjectWithDict sizeObj;
177  try {
178  size_t temp; //used to hold the memory for the return value
179  FunctionWithDict sizeFunc = iObject.typeOf().functionMemberByName("size");
180  assert(sizeFunc.finalReturnType() == typeid(size_t));
181  sizeObj = ObjectWithDict(TypeWithDict(typeid(size_t)), &temp);
182  sizeFunc.invoke(iObject, &sizeObj);
183  //std::cout << "size of type '" << sizeObj.name() << "' " << sizeObj.typeName() << std::endl;
184  size_t size = *reinterpret_cast<size_t*>(sizeObj.address());
185  FunctionWithDict atMember;
186  try {
187  atMember = iObject.typeOf().functionMemberByName("at");
188  } catch(std::exception const& x) {
189  //std::cerr << "could not get 'at' member because " << x.what() << std::endl;
190  return false;
191  }
192  LogAbsolute("EventContent") << iIndent << iName << kNameValueSep << "[size=" << size << "]";//"\n";
193  ObjectWithDict contained;
194  std::string indexIndent = iIndent + iIndentDelta;
195  TypeWithDict atReturnType(atMember.finalReturnType());
196  //std::cout << "return type " << atReturnType.name() << " size of " << atReturnType.SizeOf()
197  // << " pointer? " << atReturnType.isPointer() << " ref? " << atReturnType.isReference() << std::endl;
198 
199  //Return by reference must be treated differently since reflex will not properly create
200  // memory for a ref (which should just be a pointer to the object and not the object itself)
201  //So we will create memory on the stack which can be used to hold a reference
202  bool const isRef = atReturnType.isReference();
203  void* refMemoryBuffer = nullptr;
204  size_t index = 0;
205  //The argument to the 'at' function is the index. Since the argument list holds pointers to the arguments
206  // we only need to create it once and then when the value of index changes the pointer already
207  // gets the new value
208  std::vector<void*> args;
209  args.push_back(&index);
210  for(; index != size; ++index) {
211  std::ostringstream sizeS;
212  sizeS << "[" << index << "]";
213  if(isRef) {
214  ObjectWithDict refObject(atReturnType, &refMemoryBuffer);
215  atMember.invoke(iObject, &refObject, args);
216  //Although to hold the return value from a reference reflex requires you to pass it a
217  // void** when it tries to call methods on the reference it expects to be given a void*
218  contained = ObjectWithDict(atReturnType, refMemoryBuffer);
219  } else {
220  contained = atReturnType.construct();
221  atMember.invoke(iObject, &contained, args);
222  }
223  //LogAbsolute("EventContent") << "invoked 'at'" << std::endl;
224  try {
225  printObject(sizeS.str(), contained, indexIndent, iIndentDelta);
226  } catch(std::exception& iEx) {
227  LogAbsolute("EventContent") << indexIndent << iName << " <exception caught("
228  << iEx.what() << ")>\n";
229  }
230  if(!isRef) {
231  contained.destruct(true);
232  }
233  }
234  return true;
235  } catch(std::exception const& x) {
236  //std::cerr << "failed to invoke 'at' because " << x.what() << std::endl;
237  return false;
238  }
239  return false;
240  }
241 
242  void printObject(Event const& iEvent,
243  std::string const& iClassName,
244  std::string const& iModuleLabel,
245  std::string const& iInstanceLabel,
246  std::string const& iProcessName,
247  std::string const& iIndent,
248  std::string const& iIndentDelta) {
249  try {
250  GenericHandle handle(iClassName);
251  }catch(edm::Exception const&) {
252  LogAbsolute("EventContent") << iIndent << " \"" << iClassName << "\"" << " is an unknown type" << std::endl;
253  return;
254  }
255  GenericHandle handle(iClassName);
256  iEvent.getByLabel(InputTag(iModuleLabel, iInstanceLabel, iProcessName), handle);
257  std::string className = formatClassName(iClassName);
258  printObject(className, *handle, iIndent, iIndentDelta);
259  }
260  }
261 
263  public:
264  explicit EventContentAnalyzer(ParameterSet const&);
265  ~EventContentAnalyzer() override;
266 
267  void analyze(Event const&, EventSetup const&) override;
268  void endJob() override;
269 
270  static void fillDescriptions(ConfigurationDescriptions& descriptions);
271 
272  private:
273 
274  // ----------member data ---------------------------
275  std::string indentation_;
276  std::string verboseIndentation_;
277  std::vector<std::string> moduleLabels_;
278  bool verbose_;
279  std::vector<std::string> getModuleLabels_;
280  bool getData_;
281  int evno_;
282  std::map<std::string, int> cumulates_;
284  };
285 
286  //
287  // constructors and destructor
288  //
290  indentation_(iConfig.getUntrackedParameter("indentation", std::string("++"))),
291  verboseIndentation_(iConfig.getUntrackedParameter("verboseIndentation", std::string(" "))),
292  moduleLabels_(iConfig.getUntrackedParameter("verboseForModuleLabels", std::vector<std::string>())),
293  verbose_(iConfig.getUntrackedParameter("verbose", false) || !moduleLabels_.empty()),
294  getModuleLabels_(iConfig.getUntrackedParameter("getDataForModuleLabels", std::vector<std::string>())),
295  getData_(iConfig.getUntrackedParameter("getData", false) || !getModuleLabels_.empty()),
296  evno_(1),
297  listContent_(iConfig.getUntrackedParameter("listContent", true))
298  {
299  //now do what ever initialization is needed
302  if(getData_) {
304  if(getModuleLabels_.empty()) {
305  const std::string kPathStatus("edm::PathStatus");
306  const std::string kEndPathStatus("edm::EndPathStatus");
307  if(iBranch.className() != kPathStatus && iBranch.className() != kEndPathStatus) {
309  edm::InputTag{iBranch.moduleLabel(),iBranch.productInstanceName(),iBranch.processName()});
310  }
311  } else {
312  for (auto const& mod : this->getModuleLabels_) {
313  if (iBranch.moduleLabel() == mod) {
315  edm::InputTag{mod,iBranch.productInstanceName(),iBranch.processName()});
316  break;
317  }
318  }
319  }
320  }
321  );
322  }
323 
324  }
325 
327 
328  // do anything here that needs to be done at destruction time
329  // (e.g. close files, deallocate resources etc.)
330 
331  }
332 
333  //
334  // member functions
335  //
336 
337  // ------------ method called to produce the data ------------
338  void
340  typedef std::vector<StableProvenance const*> Provenances;
341  Provenances provenances;
342 
343  iEvent.getAllStableProvenance(provenances);
344 
345  if(listContent_) {
346  LogAbsolute("EventContent") << "\n" << indentation_ << "Event " << std::setw(5) << evno_ << " contains "
347  << provenances.size() << " product" << (provenances.size() == 1 ? "" : "s")
348  << " with friendlyClassName, moduleLabel, productInstanceName and processName:"
349  << std::endl;
350  }
351 
352  std::string startIndent = indentation_+verboseIndentation_;
353  for(auto const& provenance : provenances) {
354  std::string const& className = provenance->className();
355  const std::string kPathStatus("edm::PathStatus");
356  const std::string kEndPathStatus("edm::EndPathStatus");
357  if(className == kPathStatus || className == kEndPathStatus) {
358  continue;
359  }
360  std::string const& friendlyName = provenance->friendlyClassName();
361  //if(friendlyName.empty()) friendlyName = std::string("||");
362 
363  std::string const& modLabel = provenance->moduleLabel();
364  //if(modLabel.empty()) modLabel = std::string("||");
365 
366  std::string const& instanceName = provenance->productInstanceName();
367  //if(instanceName.empty()) instanceName = std::string("||");
368 
369  std::string const& processName = provenance->processName();
370 
371  bool doVerbose = verbose_ && (moduleLabels_.empty() ||
372  binary_search_all(moduleLabels_, modLabel));
373 
374  if(listContent_ || doVerbose) {
375  LogAbsolute("EventContent") << indentation_ << friendlyName
376  << " \"" << modLabel
377  << "\" \"" << instanceName << "\" \""
378  << processName << "\""
379  << " (productId = " << provenance->productID() << ")"
380  << std::endl;
381  }
382 
383  std::string key = friendlyName
384  + std::string(" + \"") + modLabel
385  + std::string("\" + \"") + instanceName + "\" \"" + processName + "\"";
386  ++cumulates_[key];
387 
388  if(doVerbose) {
389  //indent one level before starting to print
390  printObject(iEvent,
391  className,
392  modLabel,
393  instanceName,
394  processName,
395  startIndent,
396  verboseIndentation_);
397  continue;
398  }
399  if(getData_) {
400  std::string class_and_label = friendlyName + "_" + modLabel;
401  if(getModuleLabels_.empty() ||
402  binary_search_all(getModuleLabels_, modLabel) ||
403  binary_search_all(getModuleLabels_, class_and_label)) {
404  try {
405  GenericHandle handle(className);
406  } catch(edm::Exception const&) {
407  LogAbsolute("EventContent") << startIndent << " \"" << className << "\"" << " is an unknown type" << std::endl;
408  return;
409  }
410  GenericHandle handle(className);
411  iEvent.getByLabel(InputTag(modLabel,
412  instanceName,
413  processName),
414  handle);
415  }
416  }
417  }
418  //std::cout << "Mine" << std::endl;
419  ++evno_;
420  }
421 
422  // ------------ method called at end of job -------------------
423  void
425  typedef std::map<std::string, int> nameMap;
426 
427  LogAbsolute("EventContent") << "\nSummary for key being the concatenation of friendlyClassName, moduleLabel, productInstanceName and processName" << std::endl;
428  for(nameMap::const_iterator it = cumulates_.begin(), itEnd = cumulates_.end();
429  it != itEnd;
430  ++it) {
431  LogAbsolute("EventContent") << std::setw(6) << it->second << " occurrences of key " << it->first << std::endl;
432  }
433 
434  // Test boost::lexical_cast We don't need this right now so comment it out.
435  // int k = 137;
436  // std::string ktext = boost::lexical_cast<std::string>(k);
437  // std::cout << "\nInteger " << k << " expressed as a string is |" << ktext << "|" << std::endl;
438  }
439 
440  void
442 
443  descriptions.setComment("This plugin will print a list of all products in the event "
444  "provenance. It also has options to print and/or get each product.");
445 
447 
449 
450  std::string defaultString("++");
451  np = desc.addOptionalUntracked<std::string>("indentation", defaultString);
452  np->setComment("This string is printed at the beginning of every line printed during event processing.");
453 
454  np = desc.addOptionalUntracked<bool>("verbose", false);
455  np->setComment("If true, the contents of products are printed.");
456 
457  defaultString = " ";
458  np = desc.addOptionalUntracked<std::string>("verboseIndentation", defaultString);
459  np->setComment("This string is used to further indent lines when printing the contents of products in verbose mode.");
460 
461  std::vector<std::string> defaultVString;
462 
463  np = desc.addOptionalUntracked<std::vector<std::string> >("verboseForModuleLabels", defaultVString);
464  np->setComment("If this vector is not empty, then only products with module labels on this list are printed.");
465 
466  np = desc.addOptionalUntracked<bool>("getData", false);
467  np->setComment("If true the products will be retrieved using getByLabel.");
468 
469  np = desc.addOptionalUntracked<std::vector<std::string> >("getDataForModuleLabels", defaultVString);
470  np->setComment("If this vector is not empty, then only products with module labels on this list are retrieved by getByLabel.");
471 
472  np = desc.addOptionalUntracked<bool>("listContent", true);
473  np->setComment("If true then print a list of all the event content.");
474 
475 
476  descriptions.add("printContent", desc);
477  }
478 }
479 
size
Write out results.
std::vector< std::string > getModuleLabels_
void setComment(std::string const &value)
virtual example_stream void analyze(const edm::Event &, const edm::EventSetup &) override
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
std::string const & processName() const
std::map< std::string, int > cumulates_
static TypeWithDict byName(std::string const &name)
Definition: TypeWithDict.cc:59
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
int iEvent
Definition: GenABIO.cc:230
void analyze(Event const &, EventSetup const &) override
std::string const & className() const
int np
Definition: AMPTWrapper.h:33
std::string friendlyName(std::string const &iFullName)
std::string const & moduleLabel() const
std::string const & productInstanceName() const
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
TypeID unwrappedTypeID() const
static void fillDescriptions(ConfigurationDescriptions &descriptions)
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:475
isFirst
Definition: cuy.py:417
void setComment(std::string const &value)
void sort_all(RandomAccessSequence &s)
wrappers for std::sort
Definition: Algorithms.h:120
std::vector< std::string > moduleLabels_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void callWhenNewProductsRegistered(std::function< void(BranchDescription const &)> const &func)
Definition: EDAnalyzer.cc:104
HLT enums.
bool binary_search_all(ForwardSequence const &s, Datum const &d)
wrappers for std::binary_search
Definition: Algorithms.h:76
ParameterDescriptionBase * addOptionalUntracked(U const &iLabel, T const &value)
bool isPointer() const
long double T
T mod(const T &a, const T &b)
Definition: ecalDccMap.h:4
static const bool doPrint
EventContentAnalyzer(ParameterSet const &)
std::string className(const T &t)
Definition: ClassName.h:30
void getAllStableProvenance(std::vector< StableProvenance const * > &provenances) const
Definition: Event.cc:144