1
|
#!/usr/bin/env python
|
2
|
|
3
|
""" Check tracker efficiency """
|
4
|
|
5
|
import sys
|
6
|
import os
|
7
|
import ROOT
|
8
|
import libMausCpp #pylint: disable = W0611
|
9
|
|
10
|
#pylint: disable = R0902
|
11
|
#pylint: disable = R0912
|
12
|
#pylint: disable = R0914
|
13
|
#pylint: disable = R0915
|
14
|
#pylint: disable = C0103
|
15
|
#pylint: disable = W0612
|
16
|
|
17
|
class PatRecEfficiency():
|
18
|
""" Class to check Pattern Recognition efficiency with real data """
|
19
|
|
20
|
def __init__(self):
|
21
|
""" Initialise member variables """
|
22
|
self.check_helical = False
|
23
|
self.check_straight = True
|
24
|
self.cut_on_tof = True
|
25
|
self.cut_on_trackers = True
|
26
|
|
27
|
self.root_files = []
|
28
|
|
29
|
self.num_total_events = 0
|
30
|
self.num_12spoint_events = 0
|
31
|
self.num_10spoint_events = 0
|
32
|
self.num_5spoint_tkus_events = 0
|
33
|
self.num_5spoint_tkds_events = 0
|
34
|
|
35
|
self.num_10spoint_tracks = 0
|
36
|
self.num_5spoint_tkus_tracks = 0
|
37
|
self.num_5spoint_tkds_tracks = 0
|
38
|
self.num_3to5spoint_tkus_tracks = 0
|
39
|
self.num_3to5spoint_tkds_tracks = 0
|
40
|
|
41
|
def run(self, files):
|
42
|
""" Calculate the Pattern Recognition efficiency for the given files """
|
43
|
print '\nPattern Recognition Efficiency Calculator'
|
44
|
print '*****************************************\n'
|
45
|
|
46
|
print 'Parameters:'
|
47
|
print 'Check helical\t' + str(self.check_helical)
|
48
|
print 'Check straight\t' + str(self.check_straight)
|
49
|
print 'Cut on TOF\t' + str(self.cut_on_tof)
|
50
|
print 'Cut on trackers\t' + str(self.cut_on_trackers) + '\n'
|
51
|
|
52
|
self.root_files = self.load_data(files)
|
53
|
if len(self.root_files) < 1:
|
54
|
return False
|
55
|
|
56
|
print '\nFile\t\t\t#_Recon_Events\tTkUS_5pt\tTkUS_3-5_pt\t',
|
57
|
print 'TkDS_5pt\tTkDS_3-5pt'
|
58
|
for root_file_name in self.root_files:
|
59
|
self.calculate_efficiency(root_file_name)
|
60
|
self.print_file_info(root_file_name)
|
61
|
return True
|
62
|
|
63
|
def load_data(self, files):
|
64
|
""" Load data from files. If a dir is given, search recursively """
|
65
|
root_files = []
|
66
|
|
67
|
if type(files) is not list:
|
68
|
files = [files]
|
69
|
|
70
|
for file_name in files:
|
71
|
# Check if file_name is a ROOT file
|
72
|
if os.path.isfile(file_name):
|
73
|
file_suffix, file_extension = os.path.splitext(file_name)
|
74
|
if file_extension == '.root':
|
75
|
root_files.append(file_name)
|
76
|
else:
|
77
|
print 'Bad file name, aborting'
|
78
|
return root_files
|
79
|
|
80
|
# If file_name is a directory, walk it and save any ROOT files found
|
81
|
if os.path.isdir(file_name):
|
82
|
self.root_files_dir_search(file_name, root_files)
|
83
|
if len(root_files) < 1:
|
84
|
print 'No data files found'
|
85
|
return root_files
|
86
|
|
87
|
print '\nFound ' + str(len(root_files)) + ' ROOT files:'
|
88
|
for f in root_files:
|
89
|
print f
|
90
|
return root_files
|
91
|
|
92
|
@staticmethod
|
93
|
def root_files_dir_search(top_dir, root_files):
|
94
|
""" Appends any ROOT files found in the directory to root_files """
|
95
|
for dir_name, subdir_list, file_list in os.walk(top_dir):
|
96
|
print('Searching directory: %s' % dir_name)
|
97
|
for fname in file_list:
|
98
|
file_suffix, file_extension = os.path.splitext(fname)
|
99
|
if file_extension == '.root':
|
100
|
print('\t%s' % fname)
|
101
|
root_files.append(dir_name + '/' + fname)
|
102
|
|
103
|
def calculate_efficiency(self, root_file_name):
|
104
|
""" Calculate the Pattern Recognition efficiency for the input file """
|
105
|
|
106
|
self.clear_counters() # Start clean each time
|
107
|
|
108
|
# Load the ROOT file
|
109
|
# print "Loading ROOT file", root_file_name
|
110
|
root_file = ROOT.TFile(root_file_name, "READ") # pylint: disable = E1101
|
111
|
|
112
|
# Set up the data tree to be filled by ROOT IO
|
113
|
# print "Setting up data tree"
|
114
|
|
115
|
tree = root_file.Get("Spill")
|
116
|
data = ROOT.MAUS.Data() # pylint: disable = E1101
|
117
|
tree.SetBranchAddress("data", data)
|
118
|
|
119
|
# Loop over spills
|
120
|
for i in range(tree.GetEntries()):
|
121
|
tree.GetEntry(i)
|
122
|
spill = data.GetSpill()
|
123
|
# Print some basic information about the spill
|
124
|
# print "Found spill number", spill.GetSpillNumber(),
|
125
|
# print "in run number", spill.GetRunNumber()
|
126
|
if spill.GetDaqEventType() != "physics_event":
|
127
|
continue
|
128
|
for i in range(spill.GetReconEvents().size()):
|
129
|
self.num_total_events += 1
|
130
|
|
131
|
# Pull out tof data
|
132
|
#------------------
|
133
|
tof_evt = spill.GetReconEvents()[i].GetTOFEvent()
|
134
|
tof1 = tof_evt.GetTOFEventSpacePoint().GetTOF1SpacePointArray()
|
135
|
tof2 = tof_evt.GetTOFEventSpacePoint().GetTOF1SpacePointArray()
|
136
|
|
137
|
bool_2tof_spoint_event = True
|
138
|
if ((len(tof1) != 1) or (len(tof2) != 1)):
|
139
|
bool_2tof_spoint_event = False
|
140
|
if self.cut_on_tof:
|
141
|
continue
|
142
|
|
143
|
# Pull out tracker data
|
144
|
#----------------------
|
145
|
|
146
|
# All spacepoint data
|
147
|
tk_evt = spill.GetReconEvents()[i].GetSciFiEvent()
|
148
|
tk_spoints = tk_evt.spacepoints()
|
149
|
bool_10spoint_event = True
|
150
|
bool_tkus_5spoint_event = True
|
151
|
bool_tkds_5spoint_event = True
|
152
|
for i in range(2):
|
153
|
tracker = [sp for sp in tk_spoints if sp.get_tracker() == i]
|
154
|
for j in range(1, 6):
|
155
|
station = \
|
156
|
[sp for sp in tracker if sp.get_station() == j]
|
157
|
if len(station) != 1:
|
158
|
bool_10spoint_event = False
|
159
|
if i == 0:
|
160
|
bool_tkus_5spoint_event = False
|
161
|
elif i == 1:
|
162
|
bool_tkds_5spoint_event = False
|
163
|
|
164
|
if self.cut_on_trackers and (not bool_10spoint_event):
|
165
|
continue
|
166
|
|
167
|
if bool_2tof_spoint_event and bool_10spoint_event:
|
168
|
self.num_12spoint_events += 1
|
169
|
if bool_10spoint_event:
|
170
|
self.num_10spoint_events += 1
|
171
|
if bool_tkus_5spoint_event:
|
172
|
self.num_5spoint_tkus_events += 1
|
173
|
if bool_tkds_5spoint_event:
|
174
|
self.num_5spoint_tkds_events += 1
|
175
|
|
176
|
# Pat Rec seed data
|
177
|
if (self.check_helical) and (not self.check_straight):
|
178
|
prtracks = tk_evt.helicalprtracks()
|
179
|
# print 'Looking at helical tracks'
|
180
|
elif (not self.check_helical) and (self.check_straight):
|
181
|
prtracks = tk_evt.straightprtracks()
|
182
|
# print 'Looking at straight tracks'
|
183
|
elif (self.check_helical) and (self.check_straight):
|
184
|
prtracks = []
|
185
|
prtracks.append(tk_evt.helicalprtracks())
|
186
|
prtracks.append(tk_evt.straightprtracks())
|
187
|
# print 'Looking at helical and straight tracks'
|
188
|
else:
|
189
|
print 'Both track options set, aborting'
|
190
|
return
|
191
|
|
192
|
# Is there at least 1 track present in either tracker
|
193
|
bool_tkus_1track = False
|
194
|
bool_tkds_1track = False
|
195
|
if len(prtracks) < 1:
|
196
|
continue
|
197
|
|
198
|
num_tkus_tracks = 0
|
199
|
num_tkds_tracks = 0
|
200
|
# Require 1 and only 1 track in a tracker
|
201
|
for trk in prtracks:
|
202
|
if trk.get_tracker() == 0:
|
203
|
num_tkus_tracks += 1
|
204
|
elif trk.get_tracker() == 1:
|
205
|
num_tkds_tracks += 1
|
206
|
if num_tkus_tracks == 1:
|
207
|
bool_tkus_1track = True
|
208
|
if num_tkds_tracks == 1:
|
209
|
bool_tkds_1track = True
|
210
|
|
211
|
# If there were 5 spacepoints in a tracker and 1 track only was
|
212
|
# found in it, increment the 3 to 5 spoint track counter
|
213
|
if bool_tkus_5spoint_event and bool_tkus_1track:
|
214
|
self.num_3to5spoint_tkus_tracks += 1
|
215
|
if bool_tkds_5spoint_event and bool_tkds_1track:
|
216
|
self.num_3to5spoint_tkds_tracks += 1
|
217
|
|
218
|
# Now check the tracks found had 5 spoints, 1 from each station
|
219
|
bool_tkus_5spoint_track = False
|
220
|
bool_tkds_5spoint_track = False
|
221
|
for trk in prtracks:
|
222
|
if trk.get_tracker() == 0:
|
223
|
if (len(trk.get_spacepoints()) == 5) \
|
224
|
and bool_tkus_1track:
|
225
|
self.num_5spoint_tkus_tracks += 1
|
226
|
bool_tkus_5spoint_track = True
|
227
|
elif trk.get_tracker() == 1:
|
228
|
if (len(trk.get_spacepoints()) == 5) \
|
229
|
and bool_tkds_1track:
|
230
|
self.num_5spoint_tkds_tracks += 1
|
231
|
bool_tkds_5spoint_track = True
|
232
|
|
233
|
# Lastly see if we found one 5 spoint track in BOTH trackers
|
234
|
if (len(prtracks) != 2):
|
235
|
continue
|
236
|
if (bool_tkus_5spoint_track and bool_tkds_5spoint_track):
|
237
|
self.num_10spoint_tracks += 1
|
238
|
|
239
|
#print 'Total recon events: ' + str(num_total_events)
|
240
|
#print '12 spacepoint events: ' + str(num_12spoint_events)
|
241
|
#print '10 spacepoint events: ' + str(num_10spoint_events)
|
242
|
#print 'TkUS 5 spoint events: ' + str(num_5spoint_tkus_events)
|
243
|
#print 'TkDS 5 spoint events: ' + str(num_5spoint_tkds_events)
|
244
|
#print '10 spoint PR tracks: ' + str(num_10spoint_tracks)
|
245
|
#print 'TkUS 5 spoint PR tracks: ' + str(num_5spoint_tkus_tracks)
|
246
|
#print 'TkDS 5 spoint PR tracks: ' + str(num_5spoint_tkds_tracks)
|
247
|
#print 'TkUS 3to5 spoint PR tracks: ' + str(num_3to5spoint_tkus_tracks)
|
248
|
#print 'TkDS 3to5 spoint PR tracks: ' + str(num_3to5spoint_tkds_tracks)
|
249
|
|
250
|
# Close the ROOT file
|
251
|
# print "Closing root file"
|
252
|
root_file.Close()
|
253
|
|
254
|
def clear_counters(self):
|
255
|
""" Set the internal counters to zero """
|
256
|
self.num_total_events = 0
|
257
|
self.num_12spoint_events = 0
|
258
|
self.num_10spoint_events = 0
|
259
|
self.num_5spoint_tkus_events = 0
|
260
|
self.num_5spoint_tkds_events = 0
|
261
|
|
262
|
self.num_10spoint_tracks = 0
|
263
|
self.num_5spoint_tkus_tracks = 0
|
264
|
self.num_5spoint_tkds_tracks = 0
|
265
|
self.num_3to5spoint_tkus_tracks = 0
|
266
|
self.num_3to5spoint_tkds_tracks = 0
|
267
|
|
268
|
def print_file_info(self, root_file_name):
|
269
|
""" Calculate the efficiencies and print """
|
270
|
try:
|
271
|
us_5pt = float(self.num_5spoint_tkus_tracks) \
|
272
|
/ float(self.num_5spoint_tkus_events)
|
273
|
except ZeroDivisionError:
|
274
|
us_5pt = 0.0
|
275
|
try:
|
276
|
us_3to5pt = float(self.num_3to5spoint_tkus_tracks) \
|
277
|
/ float(self.num_5spoint_tkus_events)
|
278
|
except ZeroDivisionError:
|
279
|
us_3to5pt = 0.0
|
280
|
try:
|
281
|
ds_5pt = float(self.num_5spoint_tkds_tracks) \
|
282
|
/ float(self.num_5spoint_tkds_events)
|
283
|
except ZeroDivisionError:
|
284
|
ds_5pt = 0.0
|
285
|
try:
|
286
|
ds_3to5pt = float(self.num_3to5spoint_tkds_tracks) \
|
287
|
/ float(self.num_5spoint_tkds_events)
|
288
|
except ZeroDivisionError:
|
289
|
ds_3to5pt = 0.0
|
290
|
|
291
|
print os.path.basename(root_file_name) + '\t',
|
292
|
print str(self.num_total_events) + '\t\t',
|
293
|
|
294
|
print '%.5f \t%.5f \t%.5f \t%.5f' % \
|
295
|
(us_5pt, us_3to5pt, ds_5pt, ds_3to5pt)
|
296
|
|
297
|
if __name__ == "__main__":
|
298
|
eff = PatRecEfficiency()
|
299
|
args = sys.argv
|
300
|
args.pop(0)
|
301
|
eff.run(args)
|