SND@LHC Software
Loading...
Searching...
No Matches
MufluxPatRec Namespace Reference

Functions

 initialize (fgeo)
 
 execute (SmearedHits, TaggerHits, withNTaggerHits, withDist2Wire, debug=0)
 
 finalize ()
 
 hits_split (SmearedHits)
 
 pat_rec_y_views (SmearedHits, min_hits=3, max_shared_hits=2)
 
 pet_rec_stereo_views (SmearedHits_stereo, short_tracks_y, min_hits=3)
 
 combine_tracks_before_and_after_the_magnet (short_tracks_12, short_tracks_34, z_center)
 
 reduce_clones (long_tracks, min_hits=3, max_shared_hits=2)
 
 decodeDetectorID (detID)
 
 hit_in_bin (x, y, k_bin, b_bin, k_size, b_size)
 
 hit_in_window (x, y, k_bin, b_bin, window_width=1.)
 
 get_zy_projection (z, xtop, ytop, xbot, ybot, k_y, b_y)
 
 sort_hits (hits)
 

Variables

str __author__ = 'Mikhail Hushchyn'
 
list ReconstructibleMCTracks = []
 
list theTracks = []
 

Function Documentation

◆ combine_tracks_before_and_after_the_magnet()

MufluxPatRec.combine_tracks_before_and_after_the_magnet (   short_tracks_12,
  short_tracks_34,
  z_center 
)

Definition at line 315 of file MufluxPatRec.py.

315def combine_tracks_before_and_after_the_magnet(short_tracks_12, short_tracks_34, z_center):
316
317 # Combine track y12 and 34 and momentum calculation
318 i_track_12 = []
319 i_track_34 = []
320 deltas_y = []
321 momentums = []
322 for i_12 in range(len(short_tracks_12)):
323 atrack_12 = short_tracks_12[i_12]
324 y_center_12 = atrack_12['k_y'] * z_center + atrack_12['b_y']
325 alpha_12 = np.arctan(atrack_12['k_y'])
326 for i_34 in range(len(short_tracks_34)):
327 atrack_34 = short_tracks_34[i_34]
328 y_center_34 = atrack_34['k_y'] * z_center + atrack_34['b_y']
329 alpha_34 = np.arctan(atrack_34['k_y'])
330 i_track_12.append(i_12)
331 i_track_34.append(i_34)
332 deltas_y.append(abs(y_center_12 - y_center_34))
333 momentums.append(1.03 / (alpha_12 - alpha_34))
334
335 max_dy = 50
336 used_12 = []
337 used_34 = []
338 track_combinations = []
339 for i in np.argsort(deltas_y):
340 dy = deltas_y[i]
341 mom = momentums[i]
342 i_12 = i_track_12[i]
343 i_34 = i_track_34[i]
344 if dy < max_dy:
345 if i_12 not in used_12:
346 if i_34 not in used_34:
347 atrack = {}
348 for key in short_tracks_12[i_12].keys():
349 atrack[key+'12'] = short_tracks_12[i_12][key]
350 for key in short_tracks_34[i_34].keys():
351 atrack[key+'34'] = short_tracks_34[i_34][key]
352 atrack['p'] = abs(mom)
353 track_combinations.append(atrack)
354 #used_12.append(i_12)
355 #used_34.append(i_34)
356
357 return track_combinations
358
359

◆ decodeDetectorID()

MufluxPatRec.decodeDetectorID (   detID)
Decodes detector ID.

Parameters
----------
detID : int or array-like
    Detector ID values.

Returns
-------
statnb : int or array-like
    Station numbers.
vnb : int or array-like
    View numbers.
pnb : int or array-like
    Plane numbers.
lnb : int or array-like
    Layer numbers.
snb : int or array-like
    Straw tube numbers.

Definition at line 388 of file MufluxPatRec.py.

388def decodeDetectorID(detID):
389 """
390 Decodes detector ID.
391
392 Parameters
393 ----------
394 detID : int or array-like
395 Detector ID values.
396
397 Returns
398 -------
399 statnb : int or array-like
400 Station numbers.
401 vnb : int or array-like
402 View numbers.
403 pnb : int or array-like
404 Plane numbers.
405 lnb : int or array-like
406 Layer numbers.
407 snb : int or array-like
408 Straw tube numbers.
409 """
410
411 statnb = detID // 10000000
412 vnb = (detID - statnb * 10000000) // 1000000
413 pnb = (detID - statnb * 10000000 - vnb * 1000000) // 100000
414 lnb = (detID - statnb * 10000000 - vnb * 1000000 - pnb * 100000) // 10000
415 snb = detID - statnb * 10000000 - vnb * 1000000 - pnb * 100000 - lnb * 10000 - 2000
416
417 return statnb, vnb, pnb, lnb, snb
418
419

◆ execute()

MufluxPatRec.execute (   SmearedHits,
  TaggerHits,
  withNTaggerHits,
  withDist2Wire,
  debug = 0 
)
Main function of track pattern recognition.

Parameters:
-----------
SmearedHits : list
    Smeared hits. SmearedHits = [{'digiHit': key, 
                                  'xtop': xtop, 'ytop': ytop, 'z': ztop, 
                                  'xbot': xbot, 'ybot': ybot, 
                                  'dist': dist2wire, 'detID': detID}, {...}, ...]

Definition at line 15 of file MufluxPatRec.py.

15def execute(SmearedHits, TaggerHits, withNTaggerHits, withDist2Wire, debug=0):
16 """
17 Main function of track pattern recognition.
18
19 Parameters:
20 -----------
21 SmearedHits : list
22 Smeared hits. SmearedHits = [{'digiHit': key,
23 'xtop': xtop, 'ytop': ytop, 'z': ztop,
24 'xbot': xbot, 'ybot': ybot,
25 'dist': dist2wire, 'detID': detID}, {...}, ...]
26 """
27
28 # withDist2Wire = False
29 # withNTaggerHits = 0
30 # TaggerHits = []
31
32
33 fittedtrackids = []
34 track_hits = {}
35 if len(SmearedHits) > 100:
36 print("Too large hits in the event!")
37 return track_hits
38
39 min_hits = 3
40 max_shared_hits = 2
41
42
43 SmearedHits_y12, SmearedHits_stereo12, SmearedHits_34 = hits_split(SmearedHits)
44
45
46
47 short_tracks_y12 = pat_rec_y_views(SmearedHits_y12, min_hits, max_shared_hits)
48
49
50
51 short_tracks_12 = pet_rec_stereo_views(SmearedHits_stereo12, short_tracks_y12, min_hits)
52
53
54
55 short_tracks_34 = pat_rec_y_views(SmearedHits_34, min_hits, max_shared_hits)
56
57
58
59 z_center=350.75
60 track_combinations = combine_tracks_before_and_after_the_magnet(short_tracks_12, short_tracks_34, z_center)
61
62
63
64
65
66 # Prepare output of PatRec
67 track_hits = {}
68 for i_track in range(len(track_combinations)):
69
70 atrack = track_combinations[i_track]
71
72 hits_y12 = atrack['hits_y12']
73 hits_stereo12 = atrack['hits_stereo12']
74 hits_34 = atrack['hits_y34']
75 p = atrack['p']
76
77 [k, b] = np.polyfit(atrack['z_y12'], atrack['x_y12'], deg=1)
78 x_in_magnet = k * z_center + b
79
80 [k, b] = np.polyfit(atrack['z_stereo12'], atrack['y_stereo12'], deg=1)
81 y_in_magnet = k * z_center + b
82
83 if len(hits_y12) >= min_hits and len(hits_stereo12) >= min_hits and len(hits_34) >= min_hits:
84
85 atrack = {'y12': sort_hits(hits_y12),
86 'stereo12': sort_hits(hits_stereo12),
87 '34': sort_hits(hits_34),
88 'y_tagger': [],
89 'p': p,
90 'x_in_magnet': x_in_magnet,
91 'y_in_magnet': y_in_magnet}
92 track_hits[i_track] = atrack
93
94
95 if debug:
96 print("Recognized tracks:")
97 for i_track in track_hits.keys():
98 atrack = track_hits[i_track]
99 print("Track ", i_track)
100 print("Z_y12", [str(np.around(hit['z'], 2)) for hit in atrack['y12']])
101 print("X_y12", [str(np.around(hit['xtop'], 2)) for hit in atrack['y12']])
102 print("Z_stereo12", [str(np.around(hit['z'], 2)) for hit in atrack['stereo12']])
103 print("X_stereo12", [str(np.around(hit['xtop'], 2)) for hit in atrack['stereo12']])
104 print("Z_34", [str(np.around(hit['z'], 2)) for hit in atrack['34']])
105 print("X_34", [str(np.around(hit['xtop'], 2)) for hit in atrack['34']])
106
107 return track_hits
108
109

◆ finalize()

MufluxPatRec.finalize ( )

Definition at line 110 of file MufluxPatRec.py.

110def finalize():
111 pass
112

◆ get_zy_projection()

MufluxPatRec.get_zy_projection (   z,
  xtop,
  ytop,
  xbot,
  ybot,
  k_y,
  b_y 
)

Definition at line 481 of file MufluxPatRec.py.

481def get_zy_projection(z, xtop, ytop, xbot, ybot, k_y, b_y):
482
483 x = k_y * z + b_y
484
485 k = (ytop - ybot) / (xtop - xbot + 10**-6)
486 b = ytop - k * xtop
487 y = k * x + b
488
489 return y
490
491

◆ hit_in_bin()

MufluxPatRec.hit_in_bin (   x,
  y,
  k_bin,
  b_bin,
  k_size,
  b_size 
)
    Counts hits in a bin of track parameter space (b, k).

    Parameters
    ---------
    x : array-like
        Array of x coordinates of hits.
    y : array-like
        Array of x coordinates of hits.
    k_bin : float
        Track parameter: y = k_bin * x + b_bin
    b_bin : float
        Track parameter: y = k_bin * x + b_bin

    Return
    ------
    track_inds : array-like
        Hit indexes of a track: [ind1, ind2, ...]

Definition at line 420 of file MufluxPatRec.py.

420def hit_in_bin(x, y, k_bin, b_bin, k_size, b_size):
421 """
422 Counts hits in a bin of track parameter space (b, k).
423
424 Parameters
425 ---------
426 x : array-like
427 Array of x coordinates of hits.
428 y : array-like
429 Array of x coordinates of hits.
430 k_bin : float
431 Track parameter: y = k_bin * x + b_bin
432 b_bin : float
433 Track parameter: y = k_bin * x + b_bin
434
435 Return
436 ------
437 track_inds : array-like
438 Hit indexes of a track: [ind1, ind2, ...]
439 """
440
441
442 b_left = y - (k_bin - 0.5 * k_size) * x
443 b_right = y - (k_bin + 0.5 * k_size) * x
444
445 sel = (b_left >= b_bin - 0.5 * b_size) * (b_right <= b_bin + 0.5 * b_size) + \
446 (b_left <= b_bin + 0.5 * b_size) * (b_right >= b_bin - 0.5 * b_size)
447
448 return sel
449

◆ hit_in_window()

MufluxPatRec.hit_in_window (   x,
  y,
  k_bin,
  b_bin,
  window_width = 1. 
)
    Counts hits in a bin of track parameter space (b, k).

    Parameters
    ---------
    x : array-like
        Array of x coordinates of hits.
    y : array-like
        Array of x coordinates of hits.
    k_bin : float
        Track parameter: y = k_bin * x + b_bin
    b_bin : float
        Track parameter: y = k_bin * x + b_bin

    Return
    ------
    track_inds : array-like
        Hit indexes of a track: [ind1, ind2, ...]

Definition at line 450 of file MufluxPatRec.py.

450def hit_in_window(x, y, k_bin, b_bin, window_width=1.):
451 """
452 Counts hits in a bin of track parameter space (b, k).
453
454 Parameters
455 ---------
456 x : array-like
457 Array of x coordinates of hits.
458 y : array-like
459 Array of x coordinates of hits.
460 k_bin : float
461 Track parameter: y = k_bin * x + b_bin
462 b_bin : float
463 Track parameter: y = k_bin * x + b_bin
464
465 Return
466 ------
467 track_inds : array-like
468 Hit indexes of a track: [ind1, ind2, ...]
469 """
470
471
472 y_approx = k_bin * x + b_bin
473
474 flag = False
475 if np.abs(y_approx - y) <= window_width:
476 flag = True
477
478 return flag
479
480

◆ hits_split()

MufluxPatRec.hits_split (   SmearedHits)

Definition at line 115 of file MufluxPatRec.py.

115def hits_split(SmearedHits):
116
117 # Separate hits
118 SmearedHits_12y = []
119 SmearedHits_12stereo = []
120 SmearedHits_34 = []
121 for i_hit in range(len(SmearedHits)):
122 ahit = SmearedHits[i_hit]
123 detID = ahit['detID']
124 statnb, vnb, pnb, lnb, snb = decodeDetectorID(detID)
125 is_y12 = (statnb == 1) * (vnb == 0) + (statnb == 2) * (vnb == 1)
126 is_stereo12 = (statnb == 1) * (vnb == 1) + (statnb == 2) * (vnb == 0)
127 is_34 = (statnb == 3) + (statnb == 4)
128 if is_y12:
129 SmearedHits_12y.append(ahit)
130 if is_stereo12:
131 SmearedHits_12stereo.append(ahit)
132 if is_34:
133 SmearedHits_34.append(ahit)
134
135 return SmearedHits_12y, SmearedHits_12stereo, SmearedHits_34
136
137

◆ initialize()

MufluxPatRec.initialize (   fgeo)

Definition at line 11 of file MufluxPatRec.py.

11def initialize(fgeo):
12 pass
13
14

◆ pat_rec_y_views()

MufluxPatRec.pat_rec_y_views (   SmearedHits,
  min_hits = 3,
  max_shared_hits = 2 
)

Definition at line 138 of file MufluxPatRec.py.

138def pat_rec_y_views(SmearedHits, min_hits=3, max_shared_hits=2):
139
140 long_tracks = []
141
142 # Take 2 hits as a track seed
143 for ahit1 in SmearedHits:
144 for ahit2 in SmearedHits:
145
146 if ahit1['z'] >= ahit2['z']:
147 continue
148 if ahit1['detID'] == ahit2['detID']:
149 continue
150
151 x1 = ahit1['xtop']
152 x2 = ahit2['xtop']
153 z1 = ahit1['z']
154 z2 = ahit2['z']
155 layer1 = ahit1['detID'] // 10000
156 layer2 = ahit2['detID'] // 10000
157
158 k_bin = 1. * (x2 - x1) / (z2 - z1)
159 b_bin = x1 - k_bin * z1
160
161 if abs(k_bin) > 1:
162 continue
163
164 atrack = {}
165 atrack['hits_y'] = [ahit1, ahit2]
166 atrack['x_y'] = [x1, x2]
167 atrack['z_y'] = [z1, z2]
168 atrack['layer'] = [layer1, layer2]
169
170 # Add new hits to the seed
171 for ahit3 in SmearedHits:
172
173 if ahit3['detID'] == ahit1['detID'] or ahit3['detID'] == ahit2['detID']:
174 continue
175
176 x3 = ahit3['xtop']
177 z3 = ahit3['z']
178 layer3 = ahit3['detID'] // 10000
179
180 if layer3 in atrack['layer']:
181 continue
182
183 in_bin = hit_in_window(z3, x3, k_bin, b_bin, window_width=3.0)#3
184 if in_bin:
185 atrack['hits_y'].append(ahit3)
186 atrack['z_y'].append(z3)
187 atrack['x_y'].append(x3)
188 atrack['layer'].append(layer3)
189
190 if len(atrack['hits_y']) >= min_hits:
191 long_tracks.append(atrack)
192
193 # Reduce number of clones
194 short_tracks = reduce_clones(long_tracks, min_hits, max_shared_hits)
195
196 # Fit tracks y12
197 for atrack in short_tracks:
198 [atrack['k_y'], atrack['b_y']] = np.polyfit(atrack['z_y'], atrack['x_y'], deg=1)
199
200 return short_tracks
201
202

◆ pet_rec_stereo_views()

MufluxPatRec.pet_rec_stereo_views (   SmearedHits_stereo,
  short_tracks_y,
  min_hits = 3 
)

Definition at line 203 of file MufluxPatRec.py.

203def pet_rec_stereo_views(SmearedHits_stereo, short_tracks_y, min_hits=3):
204
205
206 long_tracks_stereo = []
207 short_tracks_stereo = []
208 used_hits = []
209 # deg = np.deg2rad(ShipGeo['MufluxSpectrometer']['ViewAngle'])
210
211 for i_track_y in range(len(short_tracks_y)):
212
213 atrack_y = short_tracks_y[i_track_y]
214 k_y = atrack_y['k_y']
215 b_y = atrack_y['b_y']
216
217 # Get hit zx projections
218 for ahit in SmearedHits_stereo:
219 y_center = get_zy_projection(ahit['z'], ahit['xtop'], ahit['ytop'], ahit['xbot'], ahit['ybot'], k_y, b_y)
220 ahit['zy_projection'] = y_center
221
222
223 temp_tracks_stereo = []
224
225 for ahit1 in SmearedHits_stereo:
226 for ahit2 in SmearedHits_stereo:
227
228 if ahit1['z'] >= ahit2['z']:
229 continue
230 if ahit1['detID'] == ahit2['detID']:
231 continue
232 if ahit1['digiHit'] in used_hits:
233 continue
234 if ahit2['digiHit'] in used_hits:
235 continue
236
237 y1_center = ahit1['zy_projection']
238 y2_center = ahit2['zy_projection']
239
240 if abs(y1_center ) > 70 or abs(y2_center ) > 70:
241 continue
242
243 y1 = y1_center
244 y2 = y2_center
245 z1 = ahit1['z']
246 z2 = ahit2['z']
247 layer1 = ahit1['detID'] // 10000
248 layer2 = ahit2['detID'] // 10000
249
250 k_bin = 1. * (y2 - y1) / (z2 - z1)
251 b_bin = y1 - k_bin * z1
252
253 atrack = {}
254 atrack['hits_stereo'] = [ahit1, ahit2]
255 atrack['y_stereo'] = [y1, y2]
256 atrack['z_stereo'] = [z1, z2]
257 atrack['layer'] = [layer1, layer2]
258
259 for ahit3 in SmearedHits_stereo:
260
261 if ahit3['digiHit'] == ahit1['digiHit'] or ahit3['digiHit'] == ahit2['digiHit']:
262 continue
263 if ahit3['digiHit'] in used_hits:
264 continue
265
266 y3_center = ahit3['zy_projection']
267 z3 = ahit3['z']
268 layer3 = ahit3['detID'] // 10000
269
270 if abs(y3_center) > 70:
271 continue
272
273 if layer3 in atrack['layer']:
274 continue
275
276 in_bin = hit_in_window(z3, y3_center, k_bin, b_bin, window_width=10.0)#10.0
277 if in_bin:
278 atrack['hits_stereo'].append(ahit3)
279 atrack['z_stereo'].append(z3)
280 atrack['y_stereo'].append(y3_center)
281 atrack['layer'].append(layer3)
282
283 if len(atrack['hits_stereo']) >= min_hits:
284 temp_tracks_stereo.append(atrack)
285 long_tracks_stereo.append(atrack)
286
287 # Remove clones
288 max_track = None
289 max_n_hits = -999
290
291 for atrack in temp_tracks_stereo:
292 if len(atrack['hits_stereo']) > max_n_hits:
293 max_track = atrack
294 max_n_hits = len(atrack['hits_stereo'])
295
296 if max_track is not None:
297 atrack = {}
298 atrack['hits_y'] = atrack_y['hits_y']
299 atrack['z_y'] = atrack_y['z_y']
300 atrack['x_y'] = atrack_y['x_y']
301 atrack['k_y'] = atrack_y['k_y']
302 atrack['b_y'] = atrack_y['b_y']
303 atrack['hits_stereo'] = max_track['hits_stereo']
304 atrack['z_stereo'] = max_track['z_stereo']
305 atrack['y_stereo'] = max_track['y_stereo']
306
307 short_tracks_stereo.append(atrack)
308 for ahit in max_track['hits_stereo']:
309 #used_hits.append(ahit['digiHit'])
310 pass
311
312 return short_tracks_stereo
313
314

◆ reduce_clones()

MufluxPatRec.reduce_clones (   long_tracks,
  min_hits = 3,
  max_shared_hits = 2 
)

Definition at line 360 of file MufluxPatRec.py.

360def reduce_clones(long_tracks, min_hits=3, max_shared_hits=2):
361
362 # Remove clones in y12
363 used_hits = []
364 short_tracks = []
365 n_hits = [len(atrack['hits_y']) for atrack in long_tracks]
366
367 for i_track in np.argsort(n_hits)[::-1]:
368
369 atrack = long_tracks[i_track]
370 n_shared_hits = 0
371
372 for i_hit in range(len(atrack['hits_y'])):
373 ahit = atrack['hits_y'][i_hit]
374 if ahit['digiHit'] in used_hits: #digiHit
375 n_shared_hits += 1
376
377 if len(atrack['hits_y']) >= min_hits and n_shared_hits <= max_shared_hits:
378 short_tracks.append(atrack)
379 for ahit in atrack['hits_y']:
380 used_hits.append(ahit['digiHit']) #digiHit
381
382 return short_tracks
383
384

◆ sort_hits()

MufluxPatRec.sort_hits (   hits)

Definition at line 492 of file MufluxPatRec.py.

492def sort_hits(hits):
493
494 sorted_hits = []
495 hits_z = [ahit['z'] for ahit in hits]
496 sort_index = np.argsort(hits_z)
497 for i_hit in sort_index:
498 sorted_hits.append(hits[i_hit])
499
500 return sorted_hits
501
502
503
504
505
506
507
508
509

Variable Documentation

◆ __author__

str MufluxPatRec.__author__ = 'Mikhail Hushchyn'
private

Definition at line 2 of file MufluxPatRec.py.

◆ ReconstructibleMCTracks

list MufluxPatRec.ReconstructibleMCTracks = []

Definition at line 7 of file MufluxPatRec.py.

◆ theTracks

list MufluxPatRec.theTracks = []

Definition at line 8 of file MufluxPatRec.py.