File indexing completed on 2023-03-17 11:29:14
0001
0002
0003 from __future__ import print_function
0004 from builtins import range
0005 import inspect
0006 import itertools
0007 import logging
0008 import optparse
0009 import pprint
0010 import random
0011 import sys
0012
0013 import ROOT
0014 from DataFormats.FWLite import Events, Handle
0015
0016 typeMap = { 'double' : ['double', 'vector<double>'],
0017 'int' : ['int', 'vector<int>'],}
0018
0019 class ProductNotFoundError(RuntimeError):
0020 """
0021 Special exception for a product not in file
0022 """
0023 pass
0024
0025 def compareEvents(event1, event2, handleName, label, options):
0026 """
0027 Compare two events
0028 """
0029
0030
0031 isSimpleObject = (handleName.find('vector') == -1)
0032
0033
0034 aux1 = event1.eventAuxiliary()
0035 aux2 = event2.eventAuxiliary()
0036
0037 rle1 = (aux1.run(), aux1.luminosityBlock(), aux1.event())
0038 rle2 = (aux2.run(), aux2.luminosityBlock(), aux2.event())
0039
0040 logging.debug("Comparing RLE #'s %s and %s" % (rle1, rle2))
0041
0042 if rle1 != rle2:
0043 raise RuntimeError("Run/Lumi/Events don't match: %s vs %s" % (rle1, rle2))
0044 handle1 = Handle(handleName)
0045 handle2 = Handle(handleName)
0046
0047 if event1.getByLabel(label, handle1) and event2.getByLabel(label, handle2):
0048 objects1 = handle1.product()
0049 objects2 = handle1.product()
0050 else:
0051 raise ProductNotFoundError("Product %s %s not found." % (handleName, label))
0052
0053 if isSimpleObject:
0054 val1 = objects1[0]
0055 val2 = objects2[0]
0056 if options.blurRate and options.blur and random.random() < options.blurRate:
0057
0058 val1 += (random.random()-0.5) * options.blur
0059 if val1 != val2:
0060 logging.error("Mismatch %s and %s in %s" % (val1, val2, aux2.event()))
0061 return (1, 1)
0062 else:
0063 logging.debug("Match of %s in %s" % (objects1[0], aux2.event()))
0064 return (1, 0)
0065 else:
0066 count = 0
0067 mismatch = 0
0068 for val1, val2 in itertools.izip_longest(objects1, objects2):
0069 count += 1
0070 if options.blurRate and options.blur and random.random() < options.blurRate:
0071
0072 val1 += (random.random()-0.5) * options.blur * val1
0073 if val1 != val2:
0074 mismatch += 1
0075 logging.error("Comparison problem %s != %s" % (val1, val2))
0076 logging.debug("Compared %s elements" % count)
0077 return (count, mismatch)
0078
0079 if __name__ == "__main__":
0080
0081
0082
0083
0084
0085 random.seed()
0086 logging.basicConfig(level=logging.INFO)
0087
0088 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.")
0089 modeGroup = optparse.OptionGroup (parser, "Mode Conrols")
0090 tupleGroup = optparse.OptionGroup (parser, "Tuple Controls")
0091 optionsGroup = optparse.OptionGroup (parser, "Options")
0092
0093 modeGroup.add_option ('--compare', dest='compare', action='store_true',
0094 help='Compare tuple1 to tuple2')
0095
0096 tupleGroup.add_option ('--numEvents', dest='numEvents', type='int',
0097 default=1e9,
0098 help="number of events for first and second file")
0099
0100 tupleGroup.add_option ('--label', dest='label', type='string',
0101 action='append',
0102 help="Change label ('tuple^object^label')")
0103
0104 optionsGroup.add_option ('--blur1', dest='blur', type='float',
0105 default=0.05,
0106 help="Randomly changes values by 'BLUR' " +\
0107 "from tuple1. For debugging only.")
0108 optionsGroup.add_option ('--blurRate', dest='blurRate', type='float',
0109 default=0.00,
0110 help="Rate at which objects will be changed. " + \
0111 "(%default default)")
0112
0113 parser.add_option_group (modeGroup)
0114 parser.add_option_group (tupleGroup)
0115 parser.add_option_group (optionsGroup)
0116 (options, args) = parser.parse_args()
0117
0118 if len(args) != 3:
0119 parser.error("Too many or too few arguments")
0120 options.config = args[0]
0121 options.file1 = args[1]
0122 options.file2 = args[2]
0123
0124
0125 tName, objName, lName = options.label[0].split('^')
0126 label = lName.split(',')
0127
0128 ROOT.gROOT.SetBatch()
0129
0130 ROOT.gSystem.Load("libFWCoreFWLite.so")
0131 ROOT.gSystem.Load("libDataFormatsFWLite.so")
0132 ROOT.FWLiteEnabler.enable()
0133
0134 chain1 = Events ([options.file1], forceEvent=True)
0135 chain2 = Events ([options.file2], forceEvent=True)
0136
0137 if chain1.size() != chain1.size():
0138 raise RuntimeError("Files have different #'s of events")
0139 numEvents = min(options.numEvents, chain1.size())
0140
0141
0142
0143 productsCompared = 0
0144 totalCount = 0
0145 mismatches = 0
0146 for handleName in typeMap[objName]:
0147 try:
0148 chain1.toBegin()
0149 chain2.toBegin()
0150 logging.info("Testing identity for handle=%s, label=%s" % (handleName, label))
0151
0152 for ev1, ev2, count in itertools.izip(chain1, chain2, range(numEvents)):
0153 evCount, evMismatch = compareEvents(event1=ev1, event2=ev2, handleName=handleName, label=label, options=options)
0154 totalCount += evCount
0155 mismatches += evMismatch
0156 logging.info("Compared %s events" % (count+1))
0157 productsCompared += 1
0158
0159 plagerDict = {'eventsCompared' : count+1}
0160 plagerDict.update({'count_%s' % objName : totalCount})
0161 if mismatches:
0162 plagerDict.update({objName: {'_var' : {handleName:mismatches}}})
0163 print("Summary")
0164 pprint.pprint(plagerDict)
0165 except ProductNotFoundError:
0166 logging.info("No product found for handle=%s, label=%s" % (handleName, label))
0167
0168 logging.info("Total products compared: %s, %s/%s" % (productsCompared, mismatches, totalCount))
0169
0170 if not productsCompared:
0171 print("Plager compatible message: not able to get any products")
0172 sys.exit()