Belle II Software  release-08-01-10
validation.py
1 
8 
9 from tracking.harvest import peelers, refiners
10 from tracking.harvest.harvesting import HarvestingModule
11 
12 from ROOT import Belle2
13 
14 from tracking.harvest.peelers import format_crop_keys
15 
16 
18  """Gather the MC VXD-CDC-merger results into ROOT file"""
19 
20  def __init__(self, output_file_name):
21  """
22  Init harvester
23  Arguments:
24  output_file_name (str): name of the output ROOT file
25  """
26  HarvestingModule.__init__(self, foreach="MCParticles", output_file_name=output_file_name)
27 
28 
29  self.mc_track_matcher_cdcmc_track_matcher_cdc = Belle2.TrackMatchLookUp("MCRecoTracks", "CDCRecoTracks")
30 
31  self.mc_track_matcher_vxdmc_track_matcher_vxd = Belle2.TrackMatchLookUp("MCRecoTracks", "SVDRecoTracks")
32 
33  def pick(self, mc_particle):
34  """Return true if the MCParticle has a related MCRecoTrack"""
35  # mc_track = mc_particle.getRelated("MCRecoTracks")
36  # return mc_track != None
37  mc_track = mc_particle.getRelatedFrom("MCRecoTracks")
38  if mc_track:
39  return True
40  else:
41  return False
42 
43  def peel(self, mc_particle):
44  """Collect information related to the MCParticle into a dictionary"""
45  mc_track = mc_particle.getRelatedFrom("MCRecoTracks")
46 
47  event_info = Belle2.PyStoreObj("EventMetaData")
48 
49  result = peelers.peel_mc_particle(mc_particle)
50  result.update(peelers.peel_reco_track_hit_content(mc_track))
51  result.update(peelers.peel_event_info(event_info))
52 
53  result["mc_store_array_number"] = mc_track.getArrayIndex()
54 
55  this_best_track_cdc = self.mc_track_matcher_cdcmc_track_matcher_cdc.getAnyChargeMatchedPRRecoTrack(mc_track)
56  this_best_track_vxd = self.mc_track_matcher_vxdmc_track_matcher_vxd.getAnyChargeMatchedPRRecoTrack(mc_track)
57 
58  result.update(peelers.peel_reco_track_hit_content(this_best_track_cdc, key="cdc_{part_name}"))
59  result.update(peelers.peel_reco_track_seed(this_best_track_cdc, key="cdc_{part_name}"))
60  if this_best_track_cdc:
61  result["cdc_store_array_number"] = this_best_track_cdc.getArrayIndex()
62  result["cdc_was_fitted"] = this_best_track_cdc.wasFitSuccessful()
63  else:
64  result["cdc_store_array_number"] = -1
65  result["cdc_was_fitted"] = -1
66 
67  result.update(peelers.peel_reco_track_hit_content(this_best_track_vxd, key="vxd_{part_name}"))
68  result.update(peelers.peel_reco_track_seed(this_best_track_vxd, key="vxd_{part_name}"))
69  if this_best_track_vxd:
70  result["vxd_store_array_number"] = this_best_track_vxd.getArrayIndex()
71  result["vxd_was_fitted"] = this_best_track_vxd.wasFitSuccessful()
72  else:
73  result["vxd_store_array_number"] = -1
74  result["vxd_was_fitted"] = -1
75 
76  if this_best_track_cdc:
77  merged_vxd_track = this_best_track_cdc.getRelated("SVDRecoTracks")
78  else:
79  merged_vxd_track = None
80  if this_best_track_vxd:
81  merged_cdc_track = this_best_track_vxd.getRelated("CDCRecoTracks")
82  else:
83  merged_cdc_track = None
84 
85  flag_incorrect_not_merged = False
86  flag_correct_merged = False
87  flag_not_found = False
88  flag_correct_not_merged_cdcmissing = False
89  flag_incorrect_merged_cdcwrong_although_not_there = False
90  flag_correct_not_merged_vxdmissing = False
91  flag_incorrect_merged_vxdwrong_although_not_there = False
92 
93  flag_incorrect_merged = False
94 
95  # Separate out *all* different cases!
96 
97  # No tracks exists at all --> Problem of Trackfinder
98  if not this_best_track_cdc and not this_best_track_vxd:
99  # Case 7
100  flag_not_found = True
101 
102  # CDC track not existing
103  elif not this_best_track_cdc:
104  # Cross-check: merged track == best track !!
105  if not merged_cdc_track:
106  # Case 4
107  flag_correct_not_merged_cdcmissing = True
108  # If merged track is not empty, merger made a mistake
109  else:
110  # Case 2 !!
111  flag_incorrect_merged_cdcwrong_although_not_there = True
112 
113  # VXD track not existing
114  elif not this_best_track_vxd:
115  # Cross check> merged track == best track!!
116  if not merged_vxd_track:
117  # Case 5
118  flag_correct_not_merged_vxdmissing = True
119  # If merged track i is not emtpy, merger made a mistake
120  else:
121  # Case 3 !!
122  flag_incorrect_merged_vxdwrong_although_not_there = True
123 
124  # Both tracks exists but have not been merged, although they should have
125  elif not merged_vxd_track and not merged_cdc_track:
126  # Case 6
127  flag_incorrect_not_merged = True
128 
129  # Tracks are merged correctly
130  elif this_best_track_cdc == merged_cdc_track and this_best_track_vxd == merged_vxd_track:
131  # Case 1
132  flag_correct_merged = True
133 
134  # If all operations above have failed than the merger failed
135  else:
136  # Case 2 + 3 !!
137  if merged_cdc_track != this_best_track_cdc:
138  flag_incorrect_merged = True
139  # The other combinations must then also be false
140 
141  # We miss the unmatched cdc/vxd reco tracks which are fakes!!!
142 
143  result.update({
144  "flag_correct_not_merged_cdcmissing": flag_correct_not_merged_cdcmissing,
145  "flag_correct_not_merged_vxdmissing": flag_correct_not_merged_vxdmissing,
146  "flag_correct_merged": flag_correct_merged,
147  "flag_incorrect_not_merged": flag_incorrect_not_merged,
148  "flag_incorrect_merged": flag_incorrect_merged,
149  "flag_incorrect_merged_cdcwrong_although_not_there": flag_incorrect_merged_cdcwrong_although_not_there,
150  "flag_incorrect_merged_vxdwrong_although_not_there": flag_incorrect_merged_vxdwrong_although_not_there,
151  "flag_not_found": flag_not_found,
152  })
153 
154  return result
155 
156 
157  save_tree = refiners.SaveTreeRefiner()
158 
159 
160 @format_crop_keys
161 def peel_matching_information(pr_track_and_mc_track_matcher, key="{part_name}"):
162  pr_track, mc_track_matcher = pr_track_and_mc_track_matcher
163  if pr_track:
164  is_matched = mc_track_matcher.isAnyChargeMatchedPRRecoTrack(pr_track)
165  is_clone = mc_track_matcher.isAnyChargeClonePRRecoTrack(pr_track)
166  is_background = mc_track_matcher.isBackgroundPRRecoTrack(pr_track)
167  is_ghost = mc_track_matcher.isGhostPRRecoTrack(pr_track)
168 
169  return dict(
170  is_matched=is_matched,
171  is_clone=is_clone,
172  is_background=is_background,
173  is_ghost=is_ghost,
174  is_clone_or_match=(is_matched or is_clone),
175  is_fake=not (is_matched or is_clone),
176  hit_purity=mc_track_matcher.getRelatedPurity(pr_track),
177  )
178  else:
179  nan = float("nan")
180  return dict(
181  is_matched=nan,
182  is_clone=nan,
183  is_background=nan,
184  is_ghost=nan,
185  is_clone_or_match=nan,
186  is_fake=nan,
187  hit_purity=nan,
188  )
189 
190 
192  """Gather the reconstructed VXD-CDC-merger results into ROOT file"""
193 
194  def __init__(self, foreach, others, output_file_name):
195  """
196  Init harvester
197  Arguments:
198  others (str): name of other-tracks collection related to the reconstructed tracks
199  output_file_name (str): name of the output ROOT file
200  """
201  super().__init__(foreach, output_file_name)
202 
203 
204  self.othersothers = others
205 
206 
207  self.mc_track_matchermc_track_matcher = Belle2.TrackMatchLookUp("MCRecoTracks", foreach)
208 
209  self.mc_track_matcher_othermc_track_matcher_other = Belle2.TrackMatchLookUp("MCRecoTracks", others)
210 
211  def peel(self, pr_track):
212  """Collect information related to the reconstructed track into a dictionary"""
213  event_info = Belle2.PyStoreObj("EventMetaData")
214 
215  result = peelers.peel_reco_track_hit_content(pr_track)
216  result.update(peelers.peel_reco_track_seed(pr_track))
217  result.update(peelers.peel_event_info(event_info))
218 
219  result["store_array_number"] = pr_track.getArrayIndex()
220 
221  mc_track = self.mc_track_matchermc_track_matcher.getAnyChargeMatchedMCRecoTrack(pr_track)
222 
223  if mc_track:
224  result["mc_store_array_number"] = mc_track.getArrayIndex()
225  else:
226  result["mc_store_array_number"] = -1
227 
228  result.update(peel_matching_information((pr_track, self.mc_track_matchermc_track_matcher)))
229 
230  matched_track = pr_track.getRelated(self.othersothers)
231 
232  result.update(peel_matching_information((matched_track, self.mc_track_matcher_othermc_track_matcher_other), key="other_{part_name}"))
233 
234  if matched_track:
235  result["matched_store_array_number"] = matched_track.getArrayIndex()
236  else:
237  result["matched_store_array_number"] = -1
238 
239  result["number_of_matches"] = pr_track.getRelationsWith(self.othersothers).size()
240 
241  return result
242 
243 
244  save_tree = refiners.SaveTreeRefiner()
a (simplified) python wrapper for StoreObjPtr.
Definition: PyStoreObj.h:67
Class to provide convenient methods to look up matching information between pattern recognition and M...
mc_track_matcher_vxd
matcher used for the MCTracks from the VXD
Definition: validation.py:31
mc_track_matcher_cdc
matcher used for the MCTracks from the CDC
Definition: validation.py:29
def __init__(self, output_file_name)
Definition: validation.py:20
mc_track_matcher_other
function to find the MCRecoTrack related to an other-tracks entry
Definition: validation.py:209
def __init__(self, foreach, others, output_file_name)
Definition: validation.py:194
others
cached copy of the 'others' argument
Definition: validation.py:204
mc_track_matcher
function to find the MCRecoTrack related to a reconstructed track
Definition: validation.py:207