Belle II Software  release-06-00-14
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.getMatchedPRRecoTrack(mc_track)
56  this_best_track_vxd = self.mc_track_matcher_vxdmc_track_matcher_vxd.getMatchedPRRecoTrack(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.isMatchedPRRecoTrack(pr_track)
165  is_clone = mc_track_matcher.isClonePRRecoTrack(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  def __init__(self, foreach, others, output_file_name):
194  """
195  Init harvester
196  Arguments:
197  others (str): name of other-tracks collection related to the reconstructed tracks
198  output_file_name (str): name of the output ROOT file
199  """
200  super().__init__(foreach, output_file_name)
201 
202 
203  self.othersothers = others
204 
205 
206  self.mc_track_matchermc_track_matcher = Belle2.TrackMatchLookUp("MCRecoTracks", foreach)
207 
208  self.mc_track_matcher_othermc_track_matcher_other = Belle2.TrackMatchLookUp("MCRecoTracks", others)
209 
210  def peel(self, pr_track):
211  """Collect information related to the reconstructed track into a dictionary"""
212  event_info = Belle2.PyStoreObj("EventMetaData")
213 
214  result = peelers.peel_reco_track_hit_content(pr_track)
215  result.update(peelers.peel_reco_track_seed(pr_track))
216  result.update(peelers.peel_event_info(event_info))
217 
218  result["store_array_number"] = pr_track.getArrayIndex()
219 
220  mc_track = self.mc_track_matchermc_track_matcher.getMatchedMCRecoTrack(pr_track)
221 
222  if mc_track:
223  result["mc_store_array_number"] = mc_track.getArrayIndex()
224  else:
225  result["mc_store_array_number"] = -1
226 
227  result.update(peel_matching_information((pr_track, self.mc_track_matchermc_track_matcher)))
228 
229  matched_track = pr_track.getRelated(self.othersothers)
230 
231  result.update(peel_matching_information((matched_track, self.mc_track_matcher_othermc_track_matcher_other), key="other_{part_name}"))
232 
233  if matched_track:
234  result["matched_store_array_number"] = matched_track.getArrayIndex()
235  else:
236  result["matched_store_array_number"] = -1
237 
238  result["number_of_matches"] = pr_track.getRelationsWith(self.othersothers).size()
239 
240  return result
241 
242 
243  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:208
def __init__(self, foreach, others, output_file_name)
Definition: validation.py:193
others
cached copy of the 'others' argument
Definition: validation.py:203
mc_track_matcher
function to find the MCRecoTrack related to a reconstructed track
Definition: validation.py:206