CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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  std::string printName = iName;
122  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() == 0) {
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  sizeObj = ObjectWithDict(TypeWithDict(typeid(size_t)), &temp);
180  iObject.typeOf().functionMemberByName("size").invoke(iObject, &sizeObj);
181  assert(iObject.typeOf().functionMemberByName("size").returnType().typeInfo() == typeid(size_t));
182  //std::cout << "size of type '" << sizeObj.name() << "' " << sizeObj.typeName() << std::endl;
183  assert(sizeObj.typeOf().typeInfo() == typeid(size_t));
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.returnType());
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 = 0;
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  atReturnType.destruct(contained.address(), 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&);
266 
267  virtual void analyze(Event const&, EventSetup const&) override;
268  virtual 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_.size()>0),
294  getModuleLabels_(iConfig.getUntrackedParameter("getDataForModuleLabels", std::vector<std::string>())),
295  getData_(iConfig.getUntrackedParameter("getData", false) || getModuleLabels_.size()>0),
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()) {
306  edm::InputTag{iBranch.moduleLabel(),iBranch.productInstanceName(),iBranch.processName()});
307  } else {
308  for (auto const& mod : this->getModuleLabels_) {
309  if (iBranch.moduleLabel() == mod) {
311  edm::InputTag{mod,iBranch.productInstanceName(),iBranch.processName()});
312  break;
313  }
314  }
315  }
316  }
317  );
318  }
319 
320  }
321 
323 
324  // do anything here that needs to be done at destruction time
325  // (e.g. close files, deallocate resources etc.)
326 
327  }
328 
329  //
330  // member functions
331  //
332 
333  // ------------ method called to produce the data ------------
334  void
336  typedef std::vector<Provenance const*> Provenances;
337  Provenances provenances;
338 
339  iEvent.getAllProvenance(provenances);
340 
341  if(listContent_) {
342  LogAbsolute("EventContent") << "\n" << indentation_ << "Event " << std::setw(5) << evno_ << " contains "
343  << provenances.size() << " product" << (provenances.size() == 1 ? "" : "s")
344  << " with friendlyClassName, moduleLabel, productInstanceName and processName:"
345  << std::endl;
346  }
347 
348  std::string startIndent = indentation_+verboseIndentation_;
349  for(Provenances::iterator itProv = provenances.begin(), itProvEnd = provenances.end();
350  itProv != itProvEnd;
351  ++itProv) {
352  std::string const& className = (*itProv)->className();
353 
354  std::string const& friendlyName = (*itProv)->friendlyClassName();
355  //if(friendlyName.empty()) friendlyName = std::string("||");
356 
357  std::string const& modLabel = (*itProv)->moduleLabel();
358  //if(modLabel.empty()) modLabel = std::string("||");
359 
360  std::string const& instanceName = (*itProv)->productInstanceName();
361  //if(instanceName.empty()) instanceName = std::string("||");
362 
363  std::string const& processName = (*itProv)->processName();
364 
365  bool doVerbose = verbose_ && (moduleLabels_.empty() ||
366  binary_search_all(moduleLabels_, modLabel));
367 
368  if(listContent_ || doVerbose) {
369  LogAbsolute("EventContent") << indentation_ << friendlyName
370  << " \"" << modLabel
371  << "\" \"" << instanceName << "\" \""
372  << processName << "\""
373  << " (productId = " << (*itProv)->productID() << ")"
374  << std::endl;
375  }
376 
377  std::string key = friendlyName
378  + std::string(" + \"") + modLabel
379  + std::string("\" + \"") + instanceName + "\" \"" + processName + "\"";
380  ++cumulates_[key];
381 
382  if(doVerbose) {
383  //indent one level before starting to print
384  printObject(iEvent,
385  className,
386  modLabel,
387  instanceName,
388  processName,
389  startIndent,
390  verboseIndentation_);
391  continue;
392  }
393  if(getData_) {
394  std::string class_and_label = friendlyName + "_" + modLabel;
395  if(getModuleLabels_.empty() ||
396  binary_search_all(getModuleLabels_, modLabel) ||
397  binary_search_all(getModuleLabels_, class_and_label)) {
398  try {
399  GenericHandle handle(className);
400  } catch(edm::Exception const&) {
401  LogAbsolute("EventContent") << startIndent << " \"" << className << "\"" << " is an unknown type" << std::endl;
402  return;
403  }
404  GenericHandle handle(className);
405  iEvent.getByLabel(InputTag(modLabel,
406  instanceName,
407  processName),
408  handle);
409  }
410  }
411  }
412  //std::cout << "Mine" << std::endl;
413  ++evno_;
414  }
415 
416  // ------------ method called at end of job -------------------
417  void
419  typedef std::map<std::string, int> nameMap;
420 
421  LogAbsolute("EventContent") << "\nSummary for key being the concatenation of friendlyClassName, moduleLabel, productInstanceName and processName" << std::endl;
422  for(nameMap::const_iterator it = cumulates_.begin(), itEnd = cumulates_.end();
423  it != itEnd;
424  ++it) {
425  LogAbsolute("EventContent") << std::setw(6) << it->second << " occurrences of key " << it->first << std::endl;
426  }
427 
428  // Test boost::lexical_cast We don't need this right now so comment it out.
429  // int k = 137;
430  // std::string ktext = boost::lexical_cast<std::string>(k);
431  // std::cout << "\nInteger " << k << " expressed as a string is |" << ktext << "|" << std::endl;
432  }
433 
434  void
436 
437  descriptions.setComment("This plugin will print a list of all products in the event "
438  "provenance. It also has options to print and/or get each product.");
439 
441 
443 
444  std::string defaultString("++");
445  np = desc.addOptionalUntracked<std::string>("indentation", defaultString);
446  np->setComment("This string is printed at the beginning of every line printed during event processing.");
447 
448  np = desc.addOptionalUntracked<bool>("verbose", false);
449  np->setComment("If true, the contents of products are printed.");
450 
451  defaultString = " ";
452  np = desc.addOptionalUntracked<std::string>("verboseIndentation", defaultString);
453  np->setComment("This string is used to further indent lines when printing the contents of products in verbose mode.");
454 
455  std::vector<std::string> defaultVString;
456 
457  np = desc.addOptionalUntracked<std::vector<std::string> >("verboseForModuleLabels", defaultVString);
458  np->setComment("If this vector is not empty, then only products with module labels on this list are printed.");
459 
460  np = desc.addOptionalUntracked<bool>("getData", false);
461  np->setComment("If true the products will be retrieved using getByLabel.");
462 
463  np = desc.addOptionalUntracked<std::vector<std::string> >("getDataForModuleLabels", defaultVString);
464  np->setComment("If this vector is not empty, then only products with module labels on this list are retrieved by getByLabel.");
465 
466  np = desc.addOptionalUntracked<bool>("listContent", true);
467  np->setComment("If true then print a list of all the event content.");
468 
469 
470  descriptions.add("printContent", desc);
471  }
472 }
473 
std::vector< std::string > getModuleLabels_
void setComment(std::string const &value)
void getAllProvenance(std::vector< Provenance const * > &provenances) const
Definition: Event.cc:83
static TypeWithDict byName(std::string const &className)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
isFirst
Definition: cuy.py:417
std::string const & processName() const
std::map< std::string, int > cumulates_
virtual void endJob() override
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
int iEvent
Definition: GenABIO.cc:230
virtual void analyze(Event const &, EventSetup const &) override
int np
Definition: AMPTWrapper.h:33
std::string friendlyName(std::string const &iFullName)
std::string const & moduleLabel() const
std::string const & productInstanceName() const
TypeID unwrappedTypeID() const
tuple handle
Definition: patZpeak.py:22
static void fillDescriptions(ConfigurationDescriptions &descriptions)
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:402
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:117
list key
Definition: combine.py:13
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)
volatile std::atomic< bool > shutdown_flag false
Definition: DDAxes.h:10
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 &)
tuple size
Write out results.
std::string className(const T &t)
Definition: ClassName.h:30