Belle II Software development
plotUtils.py
1# !/usr/bin/env python3
2
3
10
11"""
12<header>
13<noexecute>Used as library.</noexecute>
14</header>
15"""
16
17import ROOT as R
18
19
20def create1DHist(name, title, n_bins, x_min, x_max, x_label, y_label):
21 h = R.TH1F(name, title, n_bins, x_min, x_max)
22 h.GetXaxis().SetTitle(x_label)
23 h.GetYaxis().SetTitle(y_label)
24 return h
25
26
27def addDetails(h, descr, check, contact_str, isShifter):
28 h.GetListOfFunctions().Add(R.TNamed("Description", descr))
29 h.GetListOfFunctions().Add(R.TNamed("Check", check))
30 h.GetListOfFunctions().Add(R.TNamed("Contact", contact_str))
31 if isShifter:
32 h.GetListOfFunctions().Add(R.TNamed("MetaOptions", "shifter"))
33
34
35# constants
36SVDContact = "SVD Software Group, svd-software@belle2.org"
37
38# selection of different parts of detector
39cut_L3 = R.TCut('layer==3')
40cut_L4 = R.TCut('layer==4')
41cut_L5 = R.TCut('layer==5')
42cut_L6 = R.TCut('layer==6')
43cut_L456 = R.TCut('(layer==4)||(layer==5)||(layer==6)')
44cut_s = R.TCut('sensor_type==0') # slanted
45cut_b = R.TCut('sensor_type==1') # barrel
46cut_matched = R.TCut('matched==1') # (cluster) matched to TrueHit
47cut_reco = R.TCut('reconstructed==1') # (trueHit) matched to Cluster
48cut_U = R.TCut('strip_dir==0') # U_P
49cut_V = R.TCut('strip_dir==1') # V_N
50cut_notV = R.TCut('strip_dir!=1') # not V (U or a true Hit)
51cut_notU = R.TCut('strip_dir!=0') # not U (V or a true Hit)
52cut_size1 = R.TCut('(cluster_size==1)')
53cut_size2 = R.TCut('(cluster_size==2)')
54cut_size3plus = R.TCut('(cluster_size>2)')
55
56
57# default granularity
58gD = ((cut_L3 + cut_b + cut_U, 'L3_barrel_U_side'),
59 (cut_L3 + cut_b + cut_V, 'L3_barrel_V_side'),
60 (cut_L456 + cut_b + cut_U, 'L456_barrel_U_side'),
61 (cut_L456 + cut_b + cut_V, 'L456_barrel_V_side'),
62 (cut_L456 + cut_s + cut_U, 'L456_slanted_U_side'),
63 (cut_L456 + cut_s + cut_V, 'L456_slanted_V_side'))
64
65gD2 = ((cut_L3 + cut_b, 'L3_barrel'),
66 (cut_L456 + cut_b, 'L456_barrel'),
67 (cut_L456 + cut_s, 'L456_slanted'))
68
69# granularity taking into account layers and type of sensor;
70granulesLayersTypes = ((cut_L3 + cut_b, 'L3_barrel'),
71 (cut_L4 + cut_b, 'L4_barrel'),
72 (cut_L4 + cut_s, 'L4_slanted'),
73 (cut_L5 + cut_b, 'L5_barrel'),
74 (cut_L5 + cut_s, 'L5_slanted'),
75 (cut_L6 + cut_b, 'L6_barrel'),
76 (cut_L6 + cut_s, 'L6_slanted'))
77
78# granularity for time differences between neighbour layers
79granulesTD = ((cut_L3, 'L3-L4'),
80 (cut_L4, 'L4-L5'),
81 (cut_L5, 'L5-L6'))
82
83granulesL3456 = ((cut_L3, 'L3456'),) # characteristic of track saved in 3rd layer cluster
84
85g_L3_V = ((cut_L3 + cut_V, 'L3_V'),)
86
87
88def plotter(name, title, nbins, xmin, xmax, x_label, y_label,
89 granules,
90 tree, expr, cut,
91 descr, check, contact_str=SVDContact, isShifter=False):
92 for g in granules:
93 hName = f'{name}_{g[1]}'
94 h = create1DHist(hName, title, nbins, xmin, xmax, x_label, y_label)
95 if cut == "":
96 selection = g[0]
97 else:
98 selection = g[0] + cut
99 tree.Draw(f'{expr}>>{hName}', selection, 'goff')
100 addDetails(h, descr, check, contact_str, isShifter)
101 h.SetTitle(f'{title} ({g[1]})')
102 h.Write(hName)
103
104
105def plotRegions(name, title, x_label, y_label,
106 granules,
107 tree, expr, cutALL, cut,
108 descr, check, contact_str=SVDContact, isShifter=False):
109 hName = f'{name}'
110 h = create1DHist(hName, title, len(granules), 1, len(granules) + 1, x_label, y_label)
111 h.GetYaxis().SetRangeUser(0, 1.4)
112 for i, g in enumerate(granules, 1):
113 h.GetXaxis().SetBinLabel(i, g[1])
114 if cutALL == "":
115 selectionALL = g[0]
116 else:
117 selectionALL = g[0] + cutALL
118 n_all = tree.Draw(f'{expr}', selectionALL, 'goff')
119 if cut == "":
120 selection = g[0]
121 else:
122 selection = g[0] + cut
123 n_selected = tree.Draw(f'{expr}', selectionALL + selection, 'goff')
124 h.SetBinContent(i, n_selected / n_all)
125 h.SetBinError(i, (n_selected / n_all) * (1 / n_selected + 1 / n_all)**0.5)
126 addDetails(h, descr, check, contact_str, isShifter)
127 h.SetTitle(f'{title}')
128 h.Write(hName)