Project

General

Profile

Meeting 09-3-2016 » efficiency.py

Dobbs, Adam, 09 March 2016 15:22

 
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)
(1-1/2)