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