SND@LHC Software
Loading...
Searching...
No Matches
MufluxMuonTaggerPatRec.py
Go to the documentation of this file.
1from __future__ import print_function
2__author__ = 'Mikhail Hushchyn'
3
4import numpy as np
5
6def initialize(fgeo):
7 pass
8
9
10def execute(TaggerHits, debug=0):
11 """
12 Main function of muon tagger track pattern recognition.
13
14 Parameters:
15 -----------
16 TaggerHits : list
17 Muon tagger hits. TaggerHits = [{'digiHit': key,
18 'xtop': xtop, 'ytop': ytop, 'z': ztop,
19 'xbot': xbot, 'ybot': ybot,
20 'detID': detID}, {...}, ...]
21 """
22
23 track_hits = {}
24
25 if debug:
26 print("From MuonTaggerPatRec.py: ")
27 print("Input hits: ")
28 #print TaggerHits
29 print([hit['digiHit'] for hit in TaggerHits])
30
31 if len(TaggerHits) > 200:
32 print("Too many hits.")
33 return track_hits
34
35 min_hits = 3
36 max_shared_hits = 0
37
38 # Split hits into ortogonal planes
39 TaggerHits_x, TaggerHits_y = split_hits(TaggerHits)
40
41 # PatRec in zx plane
42 tracks_zx = pat_rec_plane(TaggerHits_x, coord='x', min_hits=min_hits, max_shared_hits=max_shared_hits)
43
44 # PatRec in zy plane
45 tracks_zy = pat_rec_plane(TaggerHits_y, coord='y', min_hits=min_hits, max_shared_hits=max_shared_hits)
46
47 # Combine tracks
48 track_combinations = combine_tracks(tracks_zx, tracks_zy)
49
50 # Generate output
51 for i_track in range(len(track_combinations)):
52
53 atrack = track_combinations[i_track]
54
55 if len(atrack['hits_x']) >= min_hits and len(atrack['hits_y']) >= min_hits:
56 track_hits[i_track] = {}
57 track_hits[i_track]['hits_x'] = sort_hits(atrack['hits_x'])
58 track_hits[i_track]['hits_y'] = sort_hits(atrack['hits_y'])
59
60
61 if debug:
62 print("From MuonTaggerPatRec.py: ")
63 print("tracks_zx: ")
64 print(len(tracks_zx))
65 print("tracks_zy: ")
66 print(len(tracks_zy))
67 print("track_combinations: ")
68 print(len(track_combinations))
69 print("Recognized tracks: ")
70 for i_track in track_hits.keys():
71 print("Track ", i_track)
72 print("Hits_x: ", [hit['digiHit'] for hit in track_hits[i_track]['hits_x']])
73 print("Hits_y: ", [hit['digiHit'] for hit in track_hits[i_track]['hits_y']])
74
75 return track_hits
76
77
78
80 pass
81
82
83
84
85
86def split_hits(TaggerHits):
87
88 TaggerHits_x = []
89 TaggerHits_y = []
90 for ahit in TaggerHits:
91 if abs(ahit['xtop'] - ahit['xbot']) < 10:
92 TaggerHits_x.append(ahit)
93 if abs(ahit['ytop'] - ahit['ybot']) < 10:
94 TaggerHits_y.append(ahit)
95
96 return TaggerHits_x, TaggerHits_y
97
98
99def pat_rec_plane(TaggerHits, coord='x', min_hits=3, max_shared_hits=2):
100
101 long_tracks = []
102
103 # Take 2 hits as a track seed
104 for ahit1 in TaggerHits:
105 for ahit2 in TaggerHits:
106
107 if ahit1['z'] >= ahit2['z']:
108 continue
109 if ahit1['detID'] == ahit2['detID']:
110 continue
111
112 x1 = 0.5 * (ahit1[coord+'top'] + ahit1[coord+'bot'])
113 x2 = 0.5 * (ahit2[coord+'top'] + ahit2[coord+'bot'])
114 z1 = ahit1['z']
115 z2 = ahit2['z']
116 layer1 = ahit1['detID'] // 10000
117 layer2 = ahit2['detID'] // 10000
118
119 k_bin = 1. * (x2 - x1) / (z2 - z1)
120 b_bin = x1 - k_bin * z1
121
122 if abs(k_bin) > 1:
123 continue
124
125 atrack = {}
126 atrack['hits_'+coord] = [ahit1, ahit2]
127 atrack[coord+'_'+coord] = [x1, x2]
128 atrack['z_'+coord] = [z1, z2]
129 atrack['layer'] = [layer1, layer2]
130
131 # Add new hits to the seed
132 for ahit3 in TaggerHits:
133
134 if ahit3['detID'] == ahit1['detID'] or ahit3['detID'] == ahit2['detID']:
135 continue
136
137 x3 = 0.5 * (ahit3[coord+'top'] + ahit3[coord+'bot'])
138 z3 = ahit3['z']
139 layer3 = ahit3['detID'] // 10000
140
141 if layer3 in atrack['layer']:
142 continue
143 #pass
144
145 in_bin = hit_in_window(z3, x3, k_bin, b_bin, window_width=5.0)
146 if in_bin:
147 atrack['hits_'+coord].append(ahit3)
148 atrack['z_'+coord].append(z3)
149 atrack[coord+'_'+coord].append(x3)
150 atrack['layer'].append(layer3)
151
152 if len(atrack['hits_'+coord]) >= min_hits:
153 long_tracks.append(atrack)
154
155 # Reduce number of clones
156 short_tracks = reduce_clones(long_tracks, coord, min_hits, max_shared_hits)
157
158 # Fit tracks y12
159 for atrack in short_tracks:
160 [atrack['k_'+coord], atrack['b_'+coord]] = np.polyfit(atrack['z_'+coord], atrack[coord+'_'+coord], deg=1)
161
162 return short_tracks
163
164
165def combine_tracks(tracks_zx, tracks_zy):
166
167 track_combinations = []
168 for atrack_zx in tracks_zx:
169 for atrack_zy in tracks_zy:
170 atrack_comb = atrack_zx.copy()
171 atrack_comb.update(atrack_zy)
172 track_combinations.append(atrack_comb)
173
174 return track_combinations
175
176
177
178def reduce_clones(long_tracks, coord='x', min_hits=3, max_shared_hits=2):
179
180 # Remove clones
181 used_hits = []
182 short_tracks = []
183 n_hits = [len(atrack['hits_'+coord]) for atrack in long_tracks]
184
185 for i_track in np.argsort(n_hits)[::-1]:
186
187 atrack = long_tracks[i_track]
188 n_shared_hits = 0
189
190 for i_hit in range(len(atrack['hits_'+coord])):
191 ahit = atrack['hits_'+coord][i_hit]
192 if ahit['digiHit'] in used_hits: #digiHit
193 n_shared_hits += 1
194
195 if len(atrack['hits_'+coord]) >= min_hits and n_shared_hits <= max_shared_hits:
196 short_tracks.append(atrack)
197 for ahit in atrack['hits_'+coord]:
198 used_hits.append(ahit['digiHit']) #digiHit
199
200 return short_tracks
201
202
203def hit_in_window(x, y, k_bin, b_bin, window_width=1.):
204 """
205 Counts hits in a bin of track parameter space (b, k).
206
207 Parameters
208 ---------
209 x : array-like
210 Array of x coordinates of hits.
211 y : array-like
212 Array of x coordinates of hits.
213 k_bin : float
214 Track parameter: y = k_bin * x + b_bin
215 b_bin : float
216 Track parameter: y = k_bin * x + b_bin
217
218 Return
219 ------
220 track_inds : array-like
221 Hit indexes of a track: [ind1, ind2, ...]
222 """
223
224
225 y_approx = k_bin * x + b_bin
226
227 flag = False
228 if np.abs(y_approx - y) <= window_width:
229 flag = True
230
231 return flag
232
233
234def sort_hits(hits):
235
236 sorted_hits = []
237 hits_z = [ahit['z'] for ahit in hits]
238 sort_index = np.argsort(hits_z)
239 for i_hit in sort_index:
240 sorted_hits.append(hits[i_hit])
241
242 return sorted_hits
243
244
245
246
247
248
249
execute(TaggerHits, debug=0)
pat_rec_plane(TaggerHits, coord='x', min_hits=3, max_shared_hits=2)
combine_tracks(tracks_zx, tracks_zy)
hit_in_window(x, y, k_bin, b_bin, window_width=1.)
reduce_clones(long_tracks, coord='x', min_hits=3, max_shared_hits=2)