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