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