CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
simpleEdmComparison.py
Go to the documentation of this file.
1 #! /usr/bin/env python
2 
3 import inspect
4 import itertools
5 import logging
6 import optparse
7 import pprint
8 import random
9 import sys
10 
11 import ROOT
12 from DataFormats.FWLite import Events, Handle
13 
14 typeMap = { 'double' : ['double', 'vector<double>'],
15  'int' : ['int', 'vector<int>'],}
16 
17 class ProductNotFoundError(RuntimeError):
18  """
19  Special exception for a product not in file
20  """
21  pass
22 
23 def compareEvents(event1, event2, handleName, label, options):
24  """
25  Compare two events
26  """
27 
28  # Is it a vector of objects or object (funky ROOT buffer for single value)
29  isSimpleObject = (handleName.find('vector') == -1)
30 
31  # Compare run, lumi, event
32  aux1 = event1.eventAuxiliary()
33  aux2 = event2.eventAuxiliary()
34 
35  rle1 = (aux1.run(), aux1.luminosityBlock(), aux1.event())
36  rle2 = (aux2.run(), aux2.luminosityBlock(), aux2.event())
37 
38  logging.debug("Comparing RLE #'s %s and %s" % (rle1, rle2))
39 
40  if rle1 != rle2:
41  raise RuntimeError("Run/Lumi/Events don't match: %s vs %s" % (rle1, rle2))
42  handle1 = Handle(handleName)
43  handle2 = Handle(handleName)
44 
45  if event1.getByLabel(label, handle1) and event2.getByLabel(label, handle2):
46  objects1 = handle1.product()
47  objects2 = handle1.product()
48  else:
49  raise ProductNotFoundError("Product %s %s not found." % (handleName, label))
50 
51  if isSimpleObject:
52  val1 = objects1[0]
53  val2 = objects2[0]
54  if options.blurRate and options.blur and random.random() < options.blurRate:
55  # This is different than Charles's method, which makes no sense to me
56  val1 += (random.random()-0.5) * options.blur
57  if val1 != val2:
58  logging.error("Mismatch %s and %s in %s" % (val1, val2, aux2.event()))
59  return (1, 1)
60  else:
61  logging.debug("Match of %s in %s" % (objects1[0], aux2.event()))
62  return (1, 0)
63  else:
64  count = 0
65  mismatch = 0
66  for val1, val2 in itertools.izip_longest(objects1, objects2):
67  count += 1
68  if options.blurRate and options.blur and random.random() < options.blurRate:
69  # This is different than Charles's method, which makes no sense to me
70  val1 += (random.random()-0.5) * options.blur * val1
71  if val1 != val2:
72  mismatch += 1
73  logging.error("Comparison problem %s != %s" % (val1, val2))
74  logging.debug("Compared %s elements" % count)
75  return (count, mismatch)
76 
77 if __name__ == "__main__":
78 
79  ###################
80  ## Setup Options ##
81  ###################
82 
83  random.seed()
84  logging.basicConfig(level=logging.INFO)
85 
86  parser = optparse.OptionParser("usage: %prog [options] config.txt file1.root file2.root\nVisit https://twiki.cern.ch/twiki/bin/view/CMS/SWGuidePhysicsToolsEdmOneToOneComparison\nfor full documentation.")
87  modeGroup = optparse.OptionGroup (parser, "Mode Conrols")
88  tupleGroup = optparse.OptionGroup (parser, "Tuple Controls")
89  optionsGroup = optparse.OptionGroup (parser, "Options")
90 
91  modeGroup.add_option ('--compare', dest='compare', action='store_true',
92  help='Compare tuple1 to tuple2')
93 
94  tupleGroup.add_option ('--numEvents', dest='numEvents', type='int',
95  default=1e9,
96  help="number of events for first and second file")
97 
98  tupleGroup.add_option ('--label', dest='label', type='string',
99  action='append',
100  help="Change label ('tuple^object^label')")
101 
102  optionsGroup.add_option ('--blur1', dest='blur', type='float',
103  default=0.05,
104  help="Randomly changes values by 'BLUR' " +\
105  "from tuple1. For debugging only.")
106  optionsGroup.add_option ('--blurRate', dest='blurRate', type='float',
107  default=0.00,
108  help="Rate at which objects will be changed. " + \
109  "(%default default)")
110 
111  parser.add_option_group (modeGroup)
112  parser.add_option_group (tupleGroup)
113  parser.add_option_group (optionsGroup)
114  (options, args) = parser.parse_args()
115 
116  if len(args) != 3:
117  parser.error("Too many or too few arguments")
118  options.config = args[0]
119  options.file1 = args[1]
120  options.file2 = args[2]
121 
122  # Parse object name and label out of Charles format
123  tName, objName, lName = options.label[0].split('^')
124  label = lName.split(',')
125 
126  ROOT.gROOT.SetBatch()
127 
128  ROOT.gSystem.Load("libFWCoreFWLite.so")
129  ROOT.gSystem.Load("libDataFormatsFWLite.so")
130  ROOT.AutoLibraryLoader.enable()
131 
132  chain1 = Events ([options.file1], forceEvent=True)
133  chain2 = Events ([options.file2], forceEvent=True)
134 
135  if chain1.size() != chain1.size():
136  raise RuntimeError("Files have different #'s of events")
137  numEvents = min(options.numEvents, chain1.size())
138 
139  # Parameters to this script are the same regardless if the
140  # product is double or vector<double> so have to try both
141  productsCompared = 0
142  totalCount = 0
143  mismatches = 0
144  for handleName in typeMap[objName]:
145  try:
146  chain1.toBegin()
147  chain2.toBegin()
148  logging.info("Testing identity for handle=%s, label=%s" % (handleName, label))
149  # Use itertools to iterate over lists in ||
150  for ev1, ev2, count in itertools.izip(chain1, chain2, xrange(numEvents)):
151  evCount, evMismatch = compareEvents(event1=ev1, event2=ev2, handleName=handleName, label=label, options=options)
152  totalCount += evCount
153  mismatches += evMismatch
154  logging.info("Compared %s events" % (count+1))
155  productsCompared += 1
156  # Try to reproduce the output that Charles's summary script is expecting
157  plagerDict = {'eventsCompared' : count+1}
158  plagerDict.update({'count_%s' % objName : totalCount})
159  if mismatches:
160  plagerDict.update({objName: {'_var' : {handleName:mismatches}}})
161  print "Summary"
162  pprint.pprint(plagerDict)
163  except ProductNotFoundError:
164  logging.info("No product found for handle=%s, label=%s" % (handleName, label))
165 
166  logging.info("Total products compared: %s, %s/%s" % (productsCompared, mismatches, totalCount))
167 
168  if not productsCompared:
169  print "Plager compatible message: not able to get any products"
170  sys.exit()
double split
Definition: MVATrainer.cc:139