File indexing completed on 2024-11-25 02:30:00
0001 from builtins import range
0002 import sys
0003 import numpy as np
0004
0005 import ROOT
0006 ROOT.PyConfig.IgnoreCommandLineOptions = True
0007 from optparse import OptionParser
0008 from RecoTauTag.Configuration.tools.DisplayManager import DisplayManager
0009
0010 ROOT.gROOT.SetBatch(True)
0011 ROOT.gStyle.SetOptStat(0)
0012
0013 colours = [1, 2, 3, 6, 8]
0014 styles = [1, 2, 3, 4, 5]
0015
0016 def findTree(f):
0017 for key in f.GetListOfKeys():
0018 if key.GetName() == "Events":
0019 tree = f.Get(key.GetName())
0020 if isinstance(tree, ROOT.TTree):
0021 return tree
0022 elif isinstance(tree, ROOT.TDirectory):
0023 return findTree(tree)
0024 print('Failed to find TTree Events in file', f)
0025 return None
0026
0027 def applyHistStyle(h, i):
0028 h.SetLineColor(colours[i])
0029 h.SetLineStyle(styles[i])
0030 h.SetLineWidth(3)
0031 h.SetStats(False)
0032
0033 def comparisonPlots(u_names, trees, titles, pname='compareTauVariables.pdf', ratio=True):
0034 display = DisplayManager(pname, ratio)
0035 for branch in u_names:
0036 nbins = 50
0037 min_x = min(t.GetMinimum(branch) for t in trees)
0038 max_x = max(t.GetMaximum(branch) for t in trees)
0039 title_x = branch
0040 if min_x == max_x or all(t.GetMinimum(branch) == t.GetMaximum(branch) for t in trees):
0041 continue
0042 if min_x < -900 and max_x < -min_x * 1.5:
0043 min_x = - max_x
0044 min_x = min(0., min_x)
0045 hists = []
0046 for i, t in enumerate(trees):
0047 h_name = branch+t.GetName()+str(i)
0048 h = ROOT.TH1F(h_name, branch, nbins, min_x, max_x + (max_x - min_x) * 0.01)
0049 h.Sumw2()
0050 h.GetXaxis().SetTitle(title_x)
0051 h.GetYaxis().SetTitle('Entries')
0052 applyHistStyle(h, i)
0053 t.Project(h_name, branch, '1')
0054 hists.append(h)
0055 display.Draw(hists, titles)
0056
0057 def interSect(tree1, tree2, var='ull_dumpTauVariables_EventNumber_DUMP.obj', common=False, save=False, titles=[]):
0058 tlist1 = ROOT.TEntryList()
0059 tlist2 = ROOT.TEntryList()
0060 tree1.Draw(var)
0061 r_evt1 = tree1.GetV1()
0062 if len(titles) > 0 and titles[0] == 'Reference':
0063 evt1 = np.array([int(r_evt1[i]) & 0xffffffff for i in range(tree2.GetEntries())], dtype=int)
0064 else:
0065 evt1 = np.array([r_evt1[i] for i in range(tree1.GetEntries())], dtype=int)
0066 tree2.Draw(var)
0067 r_evt2 = tree2.GetV1()
0068 if len(titles) > 1 and titles[1] == 'Reference':
0069 evt2 = np.array([int(r_evt2[i]) & 0xffffffff for i in range(tree2.GetEntries())], dtype=int)
0070 else:
0071 evt2 = np.array([int(r_evt2[i]) for i in range(tree2.GetEntries())], dtype=int)
0072 if common:
0073 indices1 = np.nonzero(np.in1d(evt1, evt2))
0074 indices2 = np.nonzero(np.in1d(evt2, evt1))
0075 else:
0076 indices1 = np.nonzero(np.in1d(evt1, evt2) == 0)
0077 indices2 = np.nonzero(np.in1d(evt2, evt1) == 0)
0078 if save:
0079 if len(titles) < 2:
0080 titles = ['tree1', 'tree2']
0081 evt1[indices1].tofile(titles[0]+'.csv', sep=',', format='%d')
0082 evt2[indices2].tofile(titles[1]+'.csv', sep=',', format='%d')
0083 for ind1 in indices1[0]:
0084 tlist1.Enter(ind1)
0085 for ind2 in indices2[0]:
0086 tlist2.Enter(ind2)
0087 return tlist1, tlist2
0088
0089 def scanForDiff(tree1, tree2, branch_names, scan_var='floats_dumpTauVariables_pt_DUMP.obj', index_var='ull_dumpTauVariables_EventNumber_DUMP.obj'):
0090 tree2.BuildIndex(index_var)
0091 diff_events = []
0092 for entry_1 in tree1:
0093 ind = int(getattr(tree1, index_var))
0094 tree2.GetEntryWithIndex(ind)
0095 var1 = getattr(tree1, scan_var)
0096 var2 = getattr(tree2, scan_var)
0097 if tree1.evt != tree2.evt:
0098 continue
0099 if round(var1, 6) != round(var2, 6):
0100 diff_events.append(ind)
0101 print('Event', ind)
0102 for branch in branch_names:
0103 v1 = getattr(tree1, branch)
0104 v2 = getattr(tree2, branch)
0105 if round(v1, 6) != round(v2, 6) and v1 > -99.:
0106 print('{b:>43}: {v1:>8.4f}, {v2:>8.4f}'.format(b=branch, v1=v1, v2=v2))
0107 print()
0108 print('Found', len(diff_events), 'events with differences in', scan_var)
0109 print(diff_events)
0110
0111
0112 if __name__ == '__main__':
0113
0114 usage = '''
0115 %prog [options] arg1 arg2 ... argN
0116 Compares first found trees in N different root files;
0117 in case of two root files, additional information about the event overlap
0118 can be calculated.
0119 Example run commands:
0120 > python compareTauVariables.py dumpTauVariables_CMSSW_8_0_X.root dumpTauVariables_CMSSW_8_1_X.root -t CMSSW_8_0_X,CMSSW_8_1_X
0121 '''
0122
0123 parser = OptionParser(usage=usage)
0124
0125 parser.add_option('-t', '--titles', type='string', dest='titles', default='Reference,Test', help='Comma-separated list of titles for the N input files (e.g. CMSSW_8_0_X,CMSSW_8_1_X)')
0126 parser.add_option('-i', '--do-intersection', dest='do_intersect', action='store_true', default=False, help='Produce plots for events not in common')
0127 parser.add_option('-c', '--do-common', dest='do_common', action='store_true', default=False, help='Produce plots for events in common')
0128 parser.add_option('-r', '--do-ratio', dest='do_ratio', action='store_true', default=False, help='Show ratio plots')
0129 parser.add_option('-d', '--diff', dest='do_diff', action='store_true', default=False, help='Print events where single variable differs')
0130 parser.add_option('-v', '--var-diff', dest='var_diff', default='floats_dumpTauVariables_pt_DUMP.obj', help='Variable for printing single event diffs')
0131
0132 (options,args) = parser.parse_args()
0133
0134 if len(args) < 2:
0135 print('provide at least 2 input root files')
0136 sys.exit(1)
0137
0138 titles = options.titles.split(',')
0139 if len(titles) < len(args):
0140 print('Provide at least as many titles as input files')
0141 sys.exit(1)
0142
0143 for i, arg in enumerate(args):
0144 if arg.endswith('.txt'):
0145 f_txt = open(arg)
0146 for line in f_txt.read().splitlines():
0147 line.strip()
0148 if line.startswith('/afs'):
0149 args[i] = line
0150 break
0151
0152 tfiles = [ROOT.TFile(arg) for arg in args]
0153 trees = [findTree(f) for f in tfiles]
0154 b_names = []
0155 b_event_number = ''
0156 for t in trees:
0157 bs = []
0158 for b in t.GetListOfBranches():
0159 if "DUMP" in b.GetName():
0160 bs.append(b.GetName().replace("'","\'")+"obj")
0161 b_names.append(set(bs))
0162 if "EventNumber" in bs :
0163 b_event_number = bs
0164 u_names = set.intersection(*b_names)
0165 u_names = sorted(u_names)
0166
0167 print('Making plots for all common branches (', len(u_names), ')')
0168 comparisonPlots(u_names, trees, titles, 'compareTauVariables.pdf', options.do_ratio)
0169
0170 if len(trees) == 2 and options.do_intersect:
0171 intersect = interSect(trees[0], trees[1], var=b_event_number, save=True, titles=titles)
0172 trees[0].SetEntryList(intersect[0])
0173 trees[1].SetEntryList(intersect[1])
0174 if not all(l.GetN() == 0 for l in intersect):
0175 comparisonPlots(u_names, trees, titles, 'compareTauVariables_intersect.pdf', options.do_ratio)
0176
0177 if len(trees) == 2 and options.do_common:
0178 intersect = interSect(trees[0], trees[1], var=b_event_number, common=True)
0179 trees[0].SetEntryList(intersect[0])
0180 trees[1].SetEntryList(intersect[1])
0181 comparisonPlots(u_names, trees, titles, 'compareTauVariables_common.pdf', options.do_ratio)
0182
0183 if len(trees) == 2 and options.do_diff:
0184 scanForDiff(trees[0], trees[1], u_names, scan_var=options.var_diff, index_var=b_event_number)