16 ValidationFiguresOfMerit,
17 ValidationManyFiguresOfMerit
22 TrackingValidationModule
31 from ROOT
import Belle2
33 ROOT.gSystem.Load(
'libtracking')
37 ROOT.genfit.TrackCand.__hash__ =
lambda x: id(x)
42 """Module to collect more matching information about the found particles and to generate validation
43 plots and figures of merit on the performance of track finding. This module gives information on the
44 number of hits etc. """
53 output_file_name=None,
54 track_filter_object=AlwaysPassFilter(),
56 plot_title_postfix=
'',
57 exclude_profile_mc_parameter=
'',
58 exclude_profile_pr_parameter=
'',
59 use_expert_folder=
True,
60 trackCandidatesColumnName=
'RecoTracks',
61 mcTrackCandidatesColumnName=
'MCRecoTracks',
62 cdcHitsColumnName=
'CDCHits',
66 TrackingValidationModule.__init__(
77 exclude_profile_mc_parameter,
78 exclude_profile_pr_parameter,
80 trackCandidatesColumnName,
81 mcTrackCandidatesColumnName)
89 """Receive signal at the start of event processing"""
90 TrackingValidationModule.initialize(self)
140 TrackingValidationModule.event(self)
144 """Classify all of the hits in the event according to the parent track(s)"""
156 for mcTrackCand
in mcTrackCands:
157 cdcHitIDs = [cdcHit.getArrayIndex()
for cdcHit
in getObjectList(mcTrackCand.getCDCHitList())]
159 if len(cdcHitIDs) == 0:
162 cdcHitIDs = set(cdcHitIDs)
163 totalHitListMC.extend(cdcHitIDs)
166 totalHitListMC = set(totalHitListMC)
170 totalHitListPRGood = []
171 totalHitListPRClone = []
172 totalHitListPRFake = []
173 for trackCand
in trackCands:
174 if trackCand.getNumberOfTotalHits() == 0:
175 basf2.B2WARNING(
"Encountered a pattern recognition track with no hits")
178 cdcHitIDs = [cdcHit.getArrayIndex()
for cdcHit
in getObjectList(trackCand.getCDCHitList())]
180 if len(cdcHitIDs) == 0:
183 cdcHitIDs = set(cdcHitIDs)
185 totalHitListPR.extend(cdcHitIDs)
186 if self.
trackMatchLookUptrackMatchLookUp.isAnyChargeMatchedPRRecoTrack(trackCand):
187 totalHitListPRGood.extend(cdcHitIDs)
189 if self.
trackMatchLookUptrackMatchLookUp.isAnyChargeClonePRRecoTrack(trackCand):
190 totalHitListPRClone.extend(cdcHitIDs)
192 if (self.
trackMatchLookUptrackMatchLookUp.isBackgroundPRRecoTrack(trackCand)
or
194 totalHitListPRFake.extend(cdcHitIDs)
197 totalHitListPR = set(totalHitListPR)
198 totalHitListPRGood = set(totalHitListPRGood)
199 totalHitListPRClone = set(totalHitListPRClone)
200 totalHitListPRFake = set(totalHitListPRFake)
203 totalHitList = set([cdcHit.getArrayIndex()
for cdcHit
in cdcHits])
205 number_of_mc_hits = len(totalHitListMC)
206 number_of_pr_hits = len(totalHitListPR)
207 number_of_all_hits = len(totalHitList)
210 is_hit_found = len(totalHitListMC & totalHitListPR)
212 for trackCand
in trackCands:
214 is_matched = self.
trackMatchLookUptrackMatchLookUp.isAnyChargeMatchedPRRecoTrack(trackCand)
215 is_clone = self.
trackMatchLookUptrackMatchLookUp.isAnyChargeClonePRRecoTrack(trackCand)
217 trackCandHits = [cdcHit.getArrayIndex()
for cdcHit
in getObjectList(trackCand.getCDCHitList())]
219 if len(trackCandHits) == 0:
220 trackCandHits = set()
222 trackCandHits = set(trackCandHits)
225 list_of_connected_mc_tracks = set()
226 list_of_numbers_of_hits_for_connected_tracks = collections.deque()
230 for mcTrackCand
in mcTrackCands:
231 mcTrackCandHits = [cdcHit.getArrayIndex()
for cdcHit
in getObjectList(mcTrackCand.getCDCHitList())]
233 if len(mcTrackCandHits) == 0:
234 mcTrackCandHits = set()
236 mcTrackCandHits = set(mcTrackCandHits)
238 length_of_intersection = len(mcTrackCandHits & trackCandHits)
239 if length_of_intersection > 0:
240 list_of_connected_mc_tracks.add(mcTrackCand)
241 list_of_numbers_of_hits_for_connected_tracks.append(length_of_intersection)
243 if len(list_of_numbers_of_hits_for_connected_tracks) == 0:
247 maximum_intersection = \
248 max(list_of_numbers_of_hits_for_connected_tracks)
250 self.
number_of_wrong_hitsnumber_of_wrong_hits.append(sum(list_of_numbers_of_hits_for_connected_tracks) -
251 maximum_intersection)
255 if is_matched
or is_clone:
258 mcTrackCandHits = [cdcHit.getArrayIndex()
for cdcHit
in getObjectList(mcTrackCand.getCDCHitList())]
260 if len(mcTrackCandHits) == 0:
261 mcTrackCandHits = set()
263 mcTrackCandHits = set(mcTrackCandHits)
265 is_hit_matched += len(trackCandHits & mcTrackCandHits)
269 for mcTrackCand
in mcTrackCands:
273 mcTrackCandHits = [cdcHit.getArrayIndex()
for cdcHit
in getObjectList(mcTrackCand.getCDCHitList())]
276 if len(mcTrackCandHits) == 0:
279 mcTrackCandHits = set(mcTrackCandHits)
281 ratio = 1.0 * len(mcTrackCandHits & totalHitListPR) / len(mcTrackCandHits)
288 1.0 * len(mcTrackCandHits & totalHitListPRGood) / len(mcTrackCandHits))
290 1.0 * len(mcTrackCandHits & totalHitListPRFake) / len(mcTrackCandHits))
295 mcParticle.hasStatus(Belle2.MCParticle.c_PrimaryParticle)
309 """Receive signal at the end of event processing"""
310 TrackingValidationModule.terminate(self)
314 validation_plots = []
320 quantity_name=
"ratio of hits in MCTracks found by the track finder",
323 profile_parameters={},
326 validation_plots.extend(all_tracks_plot)
330 quantity_name=
"ratio of hits in missing MCTracks found by the track finder",
333 profile_parameters={},
336 validation_plots.extend(missing_tracks_plot)
338 for validation_plot
in validation_plots:
339 validation_plot.write()
343 mc_figures_of_merit = \
346 mc_figures_of_merit[
'mc_pts'] = self.
mc_ptsmc_pts
347 mc_figures_of_merit[
'mc_d0s'] = self.
mc_d0smc_d0s
348 mc_figures_of_merit[
'mc_matches'] = self.
mc_matchesmc_matches
350 mc_figures_of_merit[
'mc_multiplicities'] = self.
mc_multiplicitiesmc_multiplicities
351 mc_figures_of_merit[
'mc_phis'] = self.
mc_phimc_phi
352 mc_figures_of_merit[
'mc_tan_lambdas'] = self.
mc_tan_lambdasmc_tan_lambdas
353 mc_figures_of_merit[
'mc_missing'] = self.
mc_missingmc_missing
354 mc_figures_of_merit[
'mc_is_primary'] = self.
mc_is_primarymc_is_primary
355 mc_figures_of_merit[
'mc_number_of_hits'] = self.
mc_number_of_hitsmc_number_of_hits
356 mc_figures_of_merit[
'ratio_hits_in_mc_tracks_and_in_good_pr_tracks'] = \
358 mc_figures_of_merit[
'ratio_hits_in_mc_tracks_and_in_fake_pr_tracks'] = \
360 mc_figures_of_merit[
'ratio_hits_in_mc_tracks_and_not_in_pr_tracks'] = \
363 mc_figures_of_merit.write()
366 pr_figures_of_merit = \
369 pr_figures_of_merit[
'pr_clones_and_matches'] = \
371 pr_figures_of_merit[
'pr_matches'] = self.
pr_matchespr_matches
372 pr_figures_of_merit[
'pr_fakes'] = self.
pr_fakespr_fakes
373 pr_figures_of_merit[
'pr_number_of_hits'] = self.
pr_number_of_hitspr_number_of_hits
374 pr_figures_of_merit[
'pr_number_of_matched_hits'] = \
377 pr_figures_of_merit[
'pr_seed_phi'] = self.
pr_seed_phipr_seed_phi
379 pr_figures_of_merit[
'number_of_connected_tracks'] = \
383 pr_figures_of_merit.write()
386 hit_figures_of_merit = \
389 hit_figures_of_merit[
'number_of_total_hits'] = \
391 hit_figures_of_merit[
'number_of_mc_hits'] = \
393 hit_figures_of_merit[
'number_of_pr_hits'] = \
395 hit_figures_of_merit[
'is_hit_found'] = np.sum(self.
is_hit_foundis_hit_found)
396 hit_figures_of_merit[
'is_hit_matched'] = np.sum(self.
is_hit_matchedis_hit_matched)
398 print(hit_figures_of_merit)
399 hit_figures_of_merit.write()
A (simplified) python wrapper for StoreArray.
static std::vector< std::string > list(DataStore::EDurability durability=DataStore::EDurability::c_Event)
Return list of available arrays for given durability.
ratio_hits_in_mc_tracks_and_in_pr_tracks
list of fraction of number of hits in MC track and in PR track
pr_number_of_hits
list of the number of pattern-reconstructed hits
mc_is_primary
list of flags indicating that the MC track is [not] a primary MCParticle
ratio_hits_in_missing_mc_tracks_and_in_pr_tracks
list of fraction of number of hits in missing MC track and in PR track
number_of_total_hits
number of all hits
ratio_hits_in_mc_tracks_and_in_good_pr_tracks
list of fraction of number of hits in MC track and in good PR track
def __init__(self, name, contact, fit=False, pulls=False, resolution=False, output_file_name=None, track_filter_object=AlwaysPassFilter(), plot_name_postfix='', plot_title_postfix='', exclude_profile_mc_parameter='', exclude_profile_pr_parameter='', use_expert_folder=True, trackCandidatesColumnName='RecoTracks', mcTrackCandidatesColumnName='MCRecoTracks', cdcHitsColumnName='CDCHits', write_tables=False)
mc_number_of_hits
list of the number of MCTrackCandHits on the MC track
number_of_connected_tracks
This is the number of mcTrackCands sharing a hit with the track cand.
ratio_hits_in_mc_tracks_and_not_in_pr_tracks
list of fraction of number of hits in MC track but not in PR track
write_tables
cached value of the flag to write the validation figures of merit
number_of_wrong_hits
This number gives information about the "badness" of the fake.
number_of_pr_hits
number of hits on pattern reconstructed tracks
is_hit_found
list of flags for [not-]found hits
def examine_hits_in_event(self)
cdcHitsColumnname
cached name of the CDCHits StoreArray
pr_number_of_matched_hits
list of the number of pattern-reconstructed hits matched to MC track
ratio_hits_in_mc_tracks_and_in_fake_pr_tracks
list of fraction of number of hits in MC track and in fake PR track
is_hit_matched
list of flags for [not-]matched hits
number_of_mc_hits
number of hits on MC track
mc_missing
list of flags where MCRecoTrack is [not] missing MCTrackCand
mc_d0s
list of MC-track d0 values
pr_seed_tan_lambdas
list of PR-track seed tan(lambda) values
pr_fakes
list of PR-track fakes
pr_matches
list of PR-track matches
trackCandidatesColumnName
cached name of the RecoTracks StoreArray
pr_seed_phi
list of PR-track seed phi values
output_file_name
cached value of the output ROOT TFile
trackMatchLookUp
Track-match object that examines relation information from MCMatcherTracksModule.
mc_pts
list of MC-track pt values
mc_multiplicities
list of MC-track multiplicities
mc_matches
list of MC-track matches
pr_clones_and_matches
Use deques in favour of lists to prevent repeated memory allocation of cost O(n)
mc_phi
direction of the track in phi
mcTrackCandidatesColumnName
cached name of the MCRecoTracks StoreArray
validation_name
cached value of the tracking-validation name
mc_tan_lambdas
list of MC-track tan(lambda) values
mc_hit_efficiencies
list of MC-track hit efficiencies
def profiles_by_parameters_base(self, xs, quantity_name, parameter_names, profile_parameters, unit, make_hist, weights=None, is_asymmetry=False)