Belle II Software  release-08-01-10
eventwise_module.py
1 
8 
9 import ROOT
10 from ROOT import Belle2
11 
12 import numpy as np
13 
14 import tracking.validation.utilities as utilities
15 
16 import tracking.harvest.refiners as refiners
17 import tracking.harvest.harvesting as harvesting
18 ROOT.gSystem.Load("libtracking")
19 
20 
21 class EventwiseTrackingValidationModule(harvesting.HarvestingModule):
22  """Module to perform event-by-event tracking validation."""
23 
24  """ Expert level behavior:
25  expert_level <= default_expert_level: all figures and plots from this module except tree entries
26  expert_level > default_expert_level: everything including tree entries
27  """
28 
29 
30  default_expert_level = 10
31 
32  def __init__(self,
33  name,
34  contact,
35  output_file_name=None,
36  reco_tracks_name='RecoTracks',
37  mc_reco_tracks_name='MCRecoTracks',
38  expert_level=None):
39  """Constructor"""
40 
41  output_file_name = output_file_name or name + 'TrackingValidation.root'
42 
43  super().__init__(foreach="EventMetaData", # Dummy for on element per event
44  name=name,
45  output_file_name=output_file_name,
46  contact=contact,
47  expert_level=expert_level)
48 
49 
50  self.reco_tracks_namereco_tracks_name = reco_tracks_name
51 
52  self.mc_reco_tracks_namemc_reco_tracks_name = mc_reco_tracks_name
53 
54  self.cdc_hits_namecdc_hits_name = "CDCHits"
55 
56  def initialize(self):
57  """Initialization signal at the start of the event processing"""
58  super().initialize()
59 
60  self.track_match_look_uptrack_match_look_up = Belle2.TrackMatchLookUp(self.mc_reco_tracks_namemc_reco_tracks_name,
61  self.reco_tracks_namereco_tracks_name)
62 
63  def pick(self, event_meta_data=None):
64  """Always pick"""
65  return True
66 
67  def peel(self, event_meta_data=None):
68  """Peel information from the event"""
69  # Note event_meta_data is just used as a dummy.
70 
71  track_match_look_up = self.track_match_look_uptrack_match_look_up
72  reco_tracks = Belle2.PyStoreArray(self.reco_tracks_namereco_tracks_name)
73  mc_reco_tracks = Belle2.PyStoreArray(self.mc_reco_tracks_namemc_reco_tracks_name)
74  cdc_hits = Belle2.PyStoreArray(self.cdc_hits_namecdc_hits_name)
75  mc_particles = Belle2.PyStoreArray("MCParticles")
76 
77  # General object count in the event.
78  if mc_particles:
79  n_mc_particles = mc_particles.getEntries()
80  else:
81  n_mc_particles = -1
82 
83  if mc_reco_tracks:
84  n_mc_reco_tracks = mc_reco_tracks.getEntries()
85  else:
86  n_mc_reco_tracks = -1
87 
88  n_reco_tracks = reco_tracks.getEntries()
89 
90  # Aggregate information about Monte Carlo tracks
91  all_mc_tracks_det_hit_ids = set()
92  n_matched_mc_reco_tracks = 0
93  n_matched_correct_charge_mc_reco_tracks = 0
94  n_matched_wrong_charge_mc_reco_tracks = 0
95  n_merged_mc_reco_tracks = 0
96  n_merged_correct_charge_mc_reco_tracks = 0
97  n_merged_wrong_charge_mc_reco_tracks = 0
98  n_missing_mc_reco_tracks = 0
99  for mc_reco_track in mc_reco_tracks:
100  mc_reco_track_det_hit_ids = utilities.get_det_hit_ids(mc_reco_track)
101  all_mc_tracks_det_hit_ids.update(mc_reco_track_det_hit_ids)
102 
103  is_matched = track_match_look_up.isAnyChargeMatchedMCRecoTrack(mc_reco_track)
104  is_matched_correct_charge = track_match_look_up.isCorrectChargeMatchedMCRecoTrack(mc_reco_track)
105  is_matched_wrong_charge = track_match_look_up.isWrongChargeMatchedMCRecoTrack(mc_reco_track)
106  is_merged = track_match_look_up.isAnyChargeMergedMCRecoTrack(mc_reco_track)
107  is_merged_correct_charge = track_match_look_up.isCorrectChargeMergedMCRecoTrack(mc_reco_track)
108  is_merged_wrong_charge = track_match_look_up.isWrongChargeMergedMCRecoTrack(mc_reco_track)
109  is_missing = track_match_look_up.isMissingMCRecoTrack(mc_reco_track)
110 
111  if is_matched:
112  n_matched_mc_reco_tracks += 1
113  if is_matched_correct_charge:
114  n_matched_correct_charge_mc_reco_tracks += 1
115  elif is_matched_wrong_charge:
116  n_matched_wrong_charge_mc_reco_tracks += 1
117  elif is_merged:
118  n_merged_mc_reco_tracks += 1
119  if is_merged_correct_charge:
120  n_merged_correct_charge_mc_reco_tracks += 1
121  elif is_merged_wrong_charge:
122  n_merged_wrong_charge_mc_reco_tracks += 1
123  elif is_missing:
124  n_missing_mc_reco_tracks += 1
125 
126  # Aggregate information about pattern recognition tracks
127  n_matched_reco_tracks = 0
128  n_matched_correct_charge_reco_tracks = 0
129  n_matched_wrong_charge_reco_tracks = 0
130  n_clone_reco_tracks = 0
131  n_clone_correct_charge_reco_tracks = 0
132  n_clone_wrong_charge_reco_tracks = 0
133  n_background_reco_tracks = 0
134  n_ghost_reco_tracks = 0
135 
136  all_tracks_det_hit_ids = set()
137  n_matched_hits = 0
138  for reco_track in reco_tracks:
139  is_matched = track_match_look_up.isAnyChargeMatchedPRRecoTrack(reco_track)
140  is_matched_correct_charge = track_match_look_up.isCorrectChargeMatchedPRRecoTrack(reco_track)
141  is_matched_wrong_charge = track_match_look_up.isWrongChargeMatchedPRRecoTrack(reco_track)
142  is_clone = track_match_look_up.isAnyChargeClonePRRecoTrack(reco_track)
143  is_clone_correct_charge = track_match_look_up.isCorrectChargeClonePRRecoTrack(reco_track)
144  is_clone_wrong_charge = track_match_look_up.isWrongChargeClonePRRecoTrack(reco_track)
145  is_background = track_match_look_up.isBackgroundPRRecoTrack(reco_track)
146  is_ghost = track_match_look_up.isGhostPRRecoTrack(reco_track)
147 
148  if is_matched:
149  n_matched_reco_tracks += 1
150  if is_matched_correct_charge:
151  n_matched_correct_charge_reco_tracks += 1
152  elif is_matched_wrong_charge:
153  n_matched_wrong_charge_reco_tracks += 1
154  elif is_clone:
155  n_clone_reco_tracks += 1
156  if is_clone_correct_charge:
157  n_clone_correct_charge_reco_tracks += 1
158  elif is_clone_wrong_charge:
159  n_clone_wrong_charge_reco_tracks += 1
160  elif is_background:
161  n_background_reco_tracks += 1
162  elif is_ghost:
163  n_ghost_reco_tracks += 1
164 
165  reco_track_det_hit_ids = utilities.get_det_hit_ids(reco_track)
166 
167  all_tracks_det_hit_ids.update(reco_track_det_hit_ids)
168  if is_matched or is_clone:
169  mc_reco_track = self.track_match_look_uptrack_match_look_up.getRelatedMCRecoTrack(reco_track)
170 
171  mc_reco_track_det_hit_ids = utilities.get_det_hit_ids(mc_reco_track)
172  n_matched_hits += len(reco_track_det_hit_ids & mc_reco_track_det_hit_ids)
173 
174  return dict(
175  n_mc_particles=n_mc_particles,
176  n_mc_reco_tracks=n_mc_reco_tracks,
177  n_reco_tracks=n_reco_tracks,
178 
179  n_matched_mc_reco_tracks=n_matched_mc_reco_tracks,
180  n_matched_correct_charge_mc_reco_tracks=n_matched_correct_charge_mc_reco_tracks,
181  n_matched_wrong_charge_mc_reco_tracks=n_matched_wrong_charge_mc_reco_tracks,
182 
183  n_merged_mc_reco_tracks=n_merged_mc_reco_tracks,
184  n_merged_correct_charge_mc_reco_tracks=n_merged_correct_charge_mc_reco_tracks,
185  n_merged_wrong_charge_mc_reco_tracks=n_merged_wrong_charge_mc_reco_tracks,
186 
187  n_missing_mc_reco_tracks=n_missing_mc_reco_tracks,
188 
189 
190  n_matched_reco_tracks=n_matched_reco_tracks,
191  n_matched_correct_charge_reco_tracks=n_matched_correct_charge_reco_tracks,
192  n_matched_wrong_charge_reco_tracks=n_matched_wrong_charge_reco_tracks,
193  n_clone_reco_tracks=n_clone_reco_tracks,
194  n_clone_correct_charge_reco_tracks=n_clone_correct_charge_reco_tracks,
195  n_clone_wrong_charge_reco_tracks=n_clone_wrong_charge_reco_tracks,
196 
197  n_background_reco_tracks=n_background_reco_tracks,
198  n_ghost_reco_tracks=n_ghost_reco_tracks,
199 
200  n_cdc_hits=cdc_hits.getEntries(),
201  n_all_mc_track_hits=len(all_mc_tracks_det_hit_ids),
202  n_all_track_hits=len(all_tracks_det_hit_ids),
203  n_found_hits=len(all_mc_tracks_det_hit_ids & all_tracks_det_hit_ids),
204  n_matched_hits=n_matched_hits
205  )
206 
207  # Refiners to be executed on terminate #
208  # ==================================== #
209 
210 
211  save_tree = refiners.save_tree(
212  # using cond to suppress false doxygen warnings
213 
214  folder_name="event_tree",
215  name="event_tree",
216  above_expert_level=default_expert_level
217 
218  )
219 
220 
221  save_clone_rate = refiners.save_fom(
222  # using cond to suppress false doxygen warnings
223 
224  name="{module.id}_hit_figures_of_merit",
225  title="Hit sums in {module.title}",
226  description="", # to be given
227  select=[
228  "n_cdc_hits",
229  "n_all_mc_track_hits",
230  "n_all_track_hits",
231  "n_found_hits",
232  "n_matched_hits",
233  ],
234 
235  aggregation=np.sum,
236  key="{part_name}",
237 
238  )
A (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:72
Class to provide convenient methods to look up matching information between pattern recognition and M...
track_match_look_up
Reference to the track-match object that examines relation information from MCMatcherTracksModule.
def __init__(self, name, contact, output_file_name=None, reco_tracks_name='RecoTracks', mc_reco_tracks_name='MCRecoTracks', expert_level=None)