Belle II Software development
harvester.py
1
8
9from tracking.harvest.harvesting import HarvestingModule
10from tracking.harvest import refiners
11
12from ROOT import Belle2
13
14import numpy as np
15
16
18
19 """ Harvester module to check for the reconstructed positions """
20
21 def __init__(self, output_file_name, tracks_store_vector_name="CDCTrackVector"):
22 """ Initialize with the output file name of the root file and the store obj with the
23 CDCTrack vector to use. MC track cands are needed. """
24 super().__init__(
25 foreach=tracks_store_vector_name,
26 output_file_name=output_file_name)
27
28
30
31 def peel(self, track_cand):
32 """ Extract the information """
33 mc_hit_lookup = self.mc_hit_lookup
34 mc_hit_lookup.fill()
35
36 sum_of_difference_norms_stereo = 0
37 num_norms_stereo = 0
38 sum_of_difference_norms_axial = 0
39 num_norms_axial = 0
40
41 number_of_wrong_rl_infos = 0
42
43 for reco_hit3D in list(track_cand.items()):
44 underlaying_cdc_hit = reco_hit3D.getWireHit().getHit()
45 hit_difference = mc_hit_lookup.getRecoPos3D(underlaying_cdc_hit) - reco_hit3D.getRecoPos3D()
46 sum_of_difference_norms_axial += hit_difference.xy().norm()
47 num_norms_axial += 1
48
49 if reco_hit3D.getStereoType() != 0: # AXIAL
50 sum_of_difference_norms_stereo += abs(hit_difference.z())
51 num_norms_stereo += 1
52
53 correct_rl_info = mc_hit_lookup.getRLInfo(underlaying_cdc_hit)
54
55 if correct_rl_info != reco_hit3D.getRLInfo():
56 number_of_wrong_rl_infos += 1
57
58 return dict(sum_of_difference_norms_axial=sum_of_difference_norms_axial,
59 num_norms_axial=num_norms_axial,
60 mean_of_difference_norms_axial=np.true_divide(sum_of_difference_norms_axial, num_norms_axial),
61 sum_of_difference_norms_stereo=sum_of_difference_norms_stereo,
62 num_norms_stereo=num_norms_stereo,
63 mean_of_difference_norms_stereo=np.true_divide(sum_of_difference_norms_stereo, num_norms_stereo),
64 number_of_wrong_rl_infos=number_of_wrong_rl_infos,
65 mean_wrong_rl_infos=np.true_divide(number_of_wrong_rl_infos, num_norms_stereo))
66
67
69 save_tree = refiners.save_tree(
70
71 folder_name="tree"
72
73 )
74
75
77
78 """
79 Harvester module to check for the correct reconstructed orientation.
80 """
81
82 def __init__(self, output_file_name, tracks_store_vector_name="TrackCands"):
83 """
84 Initialize with the root output file name and the store array name of the track cands to use.
85 """
86 HarvestingModule.__init__(self,
87 foreach=tracks_store_vector_name,
88 output_file_name=output_file_name)
89
90
92
93 def peel(self, track_cand):
94 """ Extract the information. """
95 cdc_hits = Belle2.PyStoreArray("CDCHits")
96
97 mc_hit_lookup = self.mc_hit_lookup
98 mc_hit_lookup.fill()
99
100 number_of_wrong_rl_infos = 0
101 number_of_wrong_rl_infos_stereo_only = 0
102
103 number_of_hits = 0
104 number_of_stereo = 0
105
106 for hitID in range(track_cand.getNHits()):
107 hit = track_cand.getHit(hitID)
108 if not hit.__class__.__name__ == "genfit::WireTrackCandHit":
109 continue
110
111 underlaying_cdc_hit = cdc_hits[hit.getHitId()]
112
113 correct_rl_info = mc_hit_lookup.getRLInfo(underlaying_cdc_hit)
114
115 number_of_hits += 1
116
117 if underlaying_cdc_hit.getISuperLayer() % 2 != 0:
118 number_of_stereo += 1
119
120 if correct_rl_info != hit.getLeftRightResolution():
121 if underlaying_cdc_hit.getISuperLayer() % 2 != 0:
122 number_of_wrong_rl_infos_stereo_only += 1
123 number_of_wrong_rl_infos += 1
124
125 return dict(number_of_wrong_rl_infos=number_of_wrong_rl_infos,
126 number_of_wrong_rl_infos_stereo_only=number_of_wrong_rl_infos_stereo_only,
127 number_of_hits=number_of_hits,
128 number_of_stereo=number_of_stereo,
129 mean_wrong_rl=np.true_divide(number_of_wrong_rl_infos, number_of_hits),
130 mean_wrong_rl_stereo=np.true_divide(number_of_wrong_rl_infos_stereo_only, number_of_stereo))
131
132
134 save_tree = refiners.save_tree(
135
136 folder_name="tree"
137
138 )
139
140
142
143 """
144 Harvesting module to check for basic matching information of the found segments.
145 If you want to have matching information, please use the MC matcher module to make all possible
146 combinations between legendre, local and MC track candidates.
147 Also, the Segments must be transformed into GF track cands.
148 """
149
151 self,
152 output_file_name,
153 local_track_cands_store_array_name="LocalTrackCands",
154 mc_track_cands_store_array_name="MCTrackCands",
155 legendre_track_cand_store_array_name="LegendreTrackCands"):
156 """
157 Initialize the harvesting module with
158 Arguments
159 ---------
160 output_file_name Name of the root file
161 local_track_cands_store_array_name Name of the StoreArray for local track cands
162 mc_track_cands_store_array_name Name of the StoreArray for MC track cands
163 legendre_track_cand_store_array_name Name of the StoreArray for legendre track cands
164 """
165 super().__init__(
166 foreach=local_track_cands_store_array_name,
167 output_file_name=output_file_name)
168
169
170 self.mc_track_cands_store_array_name = mc_track_cands_store_array_name
171
172 self.legendre_track_cand_store_array_name = legendre_track_cand_store_array_name
173
174
176
179 legendre_track_cand_store_array_name)
180
181 def prepare(self):
182 """ Prepare the CDC lookup. """
183
184 self.cdcHits = Belle2.PyStoreArray("CDCHits")
185 return HarvestingModule.prepare(self)
186
187 def peel(self, local_track_cand):
188 """ Extract the information from the segments. """
189 mc_track_matcher_local = self.mc_track_matcher_local
190 mc_track_matcher_legendre = self.mc_track_matcher_legendre
191
192 cdc_hits = self.cdcHits
193
194 is_background = mc_track_matcher_local.isBackgroundPRRecoTrack(local_track_cand)
195 is_ghost = mc_track_matcher_local.isGhostPRRecoTrack(local_track_cand)
196 is_matched = mc_track_matcher_local.isAnyChargeMatchedPRRecoTrack(local_track_cand)
197 is_clone = mc_track_matcher_local.isAnyChargeClonePRRecoTrack(local_track_cand)
198 is_clone_or_matched = is_matched or is_clone
199 hit_purity = abs(mc_track_matcher_local.getRelatedPurity(local_track_cand))
200
201 # Stereo Track?
202 first_cdc_hit_id = local_track_cand.getHitIDs(Belle2.Const.CDC)[0]
203 first_cdc_hit = cdc_hits[first_cdc_hit_id]
204 is_stereo = first_cdc_hit.getISuperLayer() % 2 == 1
205 superlayer_of_segment = first_cdc_hit.getISuperLayer()
206
207 has_partner = np.NaN
208 hit_purity_of_partner = np.NaN
209 hit_efficiency_of_partner = np.NaN
210 mc_track_pt = np.NaN
211 mc_track_dist = np.NaN
212 number_of_new_hits = local_track_cand.getNHits()
213 number_of_hits = local_track_cand.getNHits()
214 number_of_hits_in_same_superlayer = np.NaN
215 partner_has_stereo_information = np.NaN
216
217 if is_clone_or_matched:
218 related_mc_track_cand = mc_track_matcher_local.getRelatedMCRecoTrack(local_track_cand)
219 has_partner = (mc_track_matcher_legendre.isAnyChargeMatchedMCRecoTrack(related_mc_track_cand) or
220 mc_track_matcher_legendre.isAnyChargeMergedMCRecoTrack(related_mc_track_cand))
221 mc_track_pt = related_mc_track_cand.getMomSeed().Pt()
222 mc_track_dist = related_mc_track_cand.getPosSeed().Mag()
223 if has_partner:
224 partner_legendre_track_cand = mc_track_matcher_legendre.getRelatedPRRecoTrack(related_mc_track_cand)
225 hit_purity_of_partner = abs(mc_track_matcher_legendre.getRelatedPurity(partner_legendre_track_cand))
226 hit_efficiency_of_partner = abs(mc_track_matcher_legendre.getRelatedEfficiency(related_mc_track_cand))
227
228 # Count number of new hits
229 legendre_hits = set(list(partner_legendre_track_cand.getHitIDs()))
230 local_hits = set(list(local_track_cand.getHitIDs()))
231
232 local_hits_new = local_hits - legendre_hits
233 number_of_new_hits = len(local_hits_new)
234
235 # Count number of hits in this superlayer
236 partner_has_stereo_information = 0
237 number_of_hits_in_same_superlayer = 0
238 for cdc_hit_ID in legendre_hits:
239 cdc_hit = cdc_hits[cdc_hit_ID]
240 if cdc_hit.getISuperLayer() == superlayer_of_segment:
241 number_of_hits_in_same_superlayer += 1
242
243 if cdc_hit.getISuperLayer() % 2 == 1:
244 partner_has_stereo_information = 1
245
246 return dict(superlayer_of_segment=superlayer_of_segment,
247 mc_track_dist=mc_track_dist,
248 is_background=is_background,
249 is_ghost=is_ghost,
250 is_matched=is_matched,
251 is_clone=is_clone,
252 is_clone_or_matched=is_clone_or_matched,
253 is_stereo=is_stereo,
254 mc_track_pt=mc_track_pt,
255 hit_purity=hit_purity,
256 has_partner=has_partner,
257 hit_purity_of_partner=hit_purity_of_partner,
258 hit_efficiency_of_partner=hit_efficiency_of_partner,
259 number_of_new_hits=number_of_new_hits,
260 number_of_hits=number_of_hits,
261 number_of_hits_in_same_superlayer=number_of_hits_in_same_superlayer,
262 partner_has_stereo_information=partner_has_stereo_information)
263
264
266 save_tree = refiners.save_tree(
267
268 folder_name="tree"
269
270 )
271
272
274
275 """
276 Harvester module to extract momentum and position information from the found segments and tracks.
277 You need the apply MC track matcher module.
278 """
279
280 def __init__(self, local_track_cands_store_array_name, mc_track_cands_store_array_name, output_file_name):
281 """ Init the harvester with the local track candidates StoreArray name and the one for MC track cands
282 and the output file name for the result root file.
283 """
284 super().__init__(
285 foreach=local_track_cands_store_array_name,
286 output_file_name=output_file_name)
287
288
289 self.mc_track_cands_store_array_name = mc_track_cands_store_array_name
290
291
293 self.foreach)
294
295 def peel(self, local_track_cand):
296 """ Extract the information from the local track candidate. """
297 mc_track_matcher = self.mc_track_matcher
298
299 is_matched = mc_track_matcher.isAnyChargeMatchedPRRecoTrack(local_track_cand)
300 is_background = mc_track_matcher.isBackgroundPRRecoTrack(local_track_cand)
301 is_ghost = mc_track_matcher.isGhostPRRecoTrack(local_track_cand)
302
303 related_mc_track_cand = mc_track_matcher.getRelatedMCRecoTrack(local_track_cand)
304
305 track_momentum = np.NaN
306 # track_position = np.NaN
307 track_pt = np.NaN
308 track_phi = np.NaN
309
310 segment_momentum = np.NaN
311 # segment_position = np.NaN
312 segment_pt = np.NaN
313 segment_phi = np.NaN
314
315 if is_matched:
316 track_momentum = related_mc_track_cand.getPosSeed()
317 # track_position = related_mc_track_cand.getPosSeed()
318 track_pt = track_momentum.Pt()
319 track_phi = track_momentum.Phi()
320 # trajectory_track = \
321 # Belle2.TrackFindingCDC.CDCTrajectory3D(Belle2.TrackFindingCDC.Vector3D(track_position),
322 # Belle2.TrackFindingCDC.Vector3D(track_momentum),
323 # related_mc_track_cand.getChargeSeed())
324
325 segment_momentum = local_track_cand.getMomSeed()
326 # segment_position = local_track_cand.getPosSeed()
327 segment_pt = segment_momentum.Pt()
328 segment_phi = segment_momentum.Phi()
329 # trajectory_segment = \
330 # Belle2.TrackFindingCDC.CDCTrajectory3D(Belle2.TrackFindingCDC.Vector3D(segment_position),
331 # Belle2.TrackFindingCDC.Vector3D(segment_momentum),
332 # local_track_cand.getChargeSeed())
333
334 return dict(is_matched=is_matched,
335 is_background=is_background,
336 is_ghost=is_ghost,
337 segment_pt=segment_pt,
338 track_pt=track_pt,
339 difference_pt=segment_pt - track_pt,
340 segment_phi=segment_phi,
341 track_phi=track_phi,
342 difference_phi=segment_phi - track_phi)
343
344
346 save_tree = refiners.save_tree(
347
348 folder_name="tree"
349
350 )
351
352
354
355 """
356 Extract the momentum seeds of the first and the last hit of the track candidates (when use_vxd_hits is true),
357 the helx and the mc momentum.
358 """
359
360 def __init__(self, output_file_name, track_cands, use_vxd_hits=True):
361 """
362 Init with the root output file name and the name of the store array of the track cands to use.
363 """
364 HarvestingModule.__init__(self, foreach=track_cands, output_file_name=output_file_name)
365
366
367 self.use_vxd_hits = use_vxd_hits
368
369 def peel(self, legendre_track_cand):
370 """
371 Extract the information.
372 """
373 if legendre_track_cand.getChargeSeed() > 0:
374 helix = Belle2.Helix(legendre_track_cand.getPosSeed(), legendre_track_cand.getMomSeed(), 1, 1.5)
375 if legendre_track_cand.getChargeSeed() < 0:
376 helix = Belle2.Helix(legendre_track_cand.getPosSeed(), legendre_track_cand.getMomSeed(), -1, 1.5)
377
378 matcher = Belle2.TrackMatchLookUp("MCTrackCands", self.foreach)
379 mc_track_cand = matcher.getAnyChargeMatchedMCRecoTrack(legendre_track_cand)
380
381 pxd_clusters = Belle2.PyStoreArray("PXDClusters")
382 svd_clusters = Belle2.PyStoreArray("SVDClusters")
383
384 if mc_track_cand:
385 mc_x = mc_track_cand.getPosSeed().X()
386 mc_y = mc_track_cand.getPosSeed().Y()
387 mc_z = mc_track_cand.getPosSeed().Z()
388 mc_mom_x = mc_track_cand.getMomSeed().X()
389 mc_mom_y = mc_track_cand.getMomSeed().Y()
390 mc_mom_z = mc_track_cand.getMomSeed().Z()
391 else:
392 mc_x = np.NaN
393 mc_y = np.NaN
394 mc_z = np.NaN
395 mc_mom_x = np.NaN
396 mc_mom_y = np.NaN
397 mc_mom_z = np.NaN
398
399 return_dict = dict(
400 helix_z=helix.getZ0(),
401 helix_x=helix.getPerigeeX(),
402 helix_y=helix.getPerigeeY(),
403 helix_mom_z=helix.getMomentumZ(1.5),
404 helix_mom_x=helix.getMomentumX(1.5),
405 helix_mom_y=helix.getMomentumY(1.5),
406 mc_x=mc_x,
407 mc_y=mc_y,
408 mc_z=mc_z,
409 mc_mom_x=mc_mom_x,
410 mc_mom_y=mc_mom_y,
411 mc_mom_z=mc_mom_z)
412
413 if self.use_vxd_hits:
414 first_hit = legendre_track_cand.getHit(0)
415 if first_hit.getDetId() == Belle2.Const.PXD:
416 first_cluster = pxd_clusters[first_hit.getHitId()]
417 first_true_hit = first_cluster.getRelated("PXDTrueHits")
418 elif first_hit.getDetId() == Belle2.Const.SVD:
419 first_cluster = svd_clusters[first_hit.getHitId()]
420 first_true_hit = first_cluster.getRelated("SVDTrueHits")
421
422 vxdID = first_cluster.getSensorID()
423 sensorInfoBase = Belle2.VXD.GeoCache.getInstance().getSensorInfo(vxdID)
424 first_momentum = sensorInfoBase.vectorToGlobal(first_true_hit.getMomentum(), True)
425
426 last_hit = legendre_track_cand.getHit(-1)
427 if last_hit.getDetId() == Belle2.Const.PXD:
428 last_cluster = pxd_clusters[last_hit.getHitId()]
429 last_true_hit = last_cluster.getRelated("PXDTrueHits")
430 elif last_hit.getDetId() == Belle2.Const.SVD:
431 last_cluster = svd_clusters[last_hit.getHitId()]
432 last_true_hit = last_cluster.getRelated("SVDTrueHits")
433
434 vxdID = first_cluster.getSensorID()
435 sensorInfoBase = Belle2.VXD.GeoCache.getInstance().getSensorInfo(vxdID)
436 last_momentum = sensorInfoBase.vectorToGlobal(last_true_hit.getMomentum(), True)
437
438 return_dict.update(dict(first_hit_mom_x=first_momentum.X(),
439 first_hit_mom_y=first_momentum.Y(),
440 first_hit_mom_z=first_momentum.Z(),
441 last_hit_mom_x=last_momentum.X(),
442 last_hit_mom_y=last_momentum.Y(),
443 last_hit_mom_z=last_momentum.Z()))
444
445 return return_dict
446
447
449 save_tree = refiners.SaveTreeRefiner()
Helix parameter class.
Definition: Helix.h:48
A (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:72
Interface class to the Monte Carlo information for individual hits.
Class to provide convenient methods to look up matching information between pattern recognition and M...
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:214
def __init__(self, output_file_name, tracks_store_vector_name="CDCTrackVector")
Definition: harvester.py:21
mc_hit_lookup
function to look up CDC MC hits
Definition: harvester.py:29
use_vxd_hits
cached flag to use VXD hits
Definition: harvester.py:367
def peel(self, legendre_track_cand)
Definition: harvester.py:369
def __init__(self, output_file_name, track_cands, use_vxd_hits=True)
Definition: harvester.py:360
def __init__(self, output_file_name, local_track_cands_store_array_name="LocalTrackCands", mc_track_cands_store_array_name="MCTrackCands", legendre_track_cand_store_array_name="LegendreTrackCands")
Definition: harvester.py:155
mc_track_cands_store_array_name
cached name of the TrackCands StoreArray
Definition: harvester.py:170
mc_track_matcher_local
function to match local tracks to MC tracks
Definition: harvester.py:175
legendre_track_cand_store_array_name
cached name of the Legendre TrackCands StoreArray
Definition: harvester.py:172
cdcHits
cached CDCHits StoreArray
Definition: harvester.py:184
mc_track_matcher_legendre
function to match Legendre tracks to MC tracks
Definition: harvester.py:177
def peel(self, local_track_cand)
Definition: harvester.py:187
mc_track_cands_store_array_name
cached name of the TrackCands StoreArray
Definition: harvester.py:289
def __init__(self, local_track_cands_store_array_name, mc_track_cands_store_array_name, output_file_name)
Definition: harvester.py:280
mc_track_matcher
function to match tracks to MC tracks
Definition: harvester.py:292
mc_hit_lookup
function to look up CDC MC hits
Definition: harvester.py:91
def peel(self, track_cand)
Definition: harvester.py:93
def __init__(self, output_file_name, tracks_store_vector_name="TrackCands")
Definition: harvester.py:82
foreach
Name of the StoreArray or iterable StoreObjPtr that contains the objects to be harvested.
Definition: harvesting.py:196