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