24 getHelixFromMCParticle,
25 getSeedTrackFitResult,
28 calc_ndf_from_det_hit_ids
34 from ROOT
import Belle2
37 ROOT.gSystem.Load(
"libtracking")
42 contains all informations necessary for track filters to decide whether
43 track will be included into the processed list of tracks
44 This class is used for both providing information on pattern reco and
92 """Filter that always passes"""
95 """Pattern-reconstructed track always passes"""
99 """MC track always passes"""
105 """Module to collect matching information about the found particles and to
106 generate validation plots and figures of merit on the performance of track finding."""
115 output_file_name=None,
116 track_filter_object=AlwaysPassFilter(),
117 plot_name_postfix=
'',
118 plot_title_postfix=
'',
119 exclude_profile_mc_parameter=
'',
120 exclude_profile_pr_parameter=
'',
121 use_expert_folder=
True,
122 trackCandidatesColumnName=
"RecoTracks",
123 mcTrackCandidatesColumName=
"MCRecoTracks"
127 super(TrackingValidationModule, self).
__init__()
141 +
'TrackingValidation.root'
167 if "DO_NOT_READ_BINNING" not in os.environ:
170 basf2.B2INFO(
"Will read binning from: " + self.
referenceFileNamereferenceFileName)
171 basf2.B2INFO(
"If this is not wanted set the environment variable DO_NOT_READ_BINNING or remove reference files.")
173 basf2.B2INFO(
"Will not read binning from reference files.")
176 """Receive signal at the start of event processing"""
259 """Looks at the individual pattern reconstructed tracks and store information about them"""
269 for trackCand
in trackCands:
270 is_matched = trackMatchLookUp.isMatchedPRRecoTrack(trackCand)
271 is_clone = trackMatchLookUp.isClonePRRecoTrack(trackCand)
273 pt_truth = float(
'nan')
274 omega_truth = float(
'nan')
275 tan_lambda_truth = float(
'nan')
276 d0_truth = float(
'nan')
277 z0_truth = float(
'nan')
280 if is_matched
or is_clone:
282 mcParticle = trackMatchLookUp.getRelatedMCParticle(trackCand)
283 mcHelix = getHelixFromMCParticle(mcParticle)
284 omega_truth = mcHelix.getOmega()
285 tan_lambda_truth = mcHelix.getTanLambda()
286 pt_truth = mcParticle.getMomentum().Perp()
287 d0_truth = mcHelix.getD0()
288 z0_truth = mcHelix.getZ0()
293 mcParticle=mcParticle, mcParticles=mcParticles)
297 trackMatchLookUp.getRelatedTrackFitResult(trackCand)
298 filterProperties.wasFitted = prTrackFitResult
is not None
299 filterProperties.fitResult = prTrackFitResult
301 prTrackFitResult = getSeedTrackFitResult(trackCand)
302 filterProperties.seedResult = prTrackFitResult
308 omega_estimate = float(
'nan')
309 omega_variance = float(
'nan')
310 tan_lambda_estimate = float(
'nan')
311 tan_lambda_variance = float(
'nan')
312 d0_estimate = float(
'nan')
313 d0_variance = float(
'nan')
314 z0_estimate = float(
'nan')
315 pt_estimate = float(
'nan')
317 momentum = float(
'nan')
322 seed_position = trackCand.getPositionSeed()
323 seed_momentum = trackCand.getMomentumSeed()
325 seed_tan_lambda = np.divide(1.0, math.tan(seed_momentum.Theta()))
326 seed_phi = seed_position.Phi()
327 seed_theta = seed_position.Theta()
330 omega_estimate = prTrackFitResult.getOmega()
331 omega_variance = prTrackFitResult.getCov()[9]
333 tan_lambda_estimate = prTrackFitResult.getCotTheta()
334 tan_lambda_variance = prTrackFitResult.getCov()[14]
336 d0_estimate = prTrackFitResult.getD0()
337 d0_variance = prTrackFitResult.getCov()[0]
339 z0_estimate = prTrackFitResult.getZ0()
341 momentum = prTrackFitResult.getMomentum()
342 pt_estimate = momentum.Perp()
352 isMatchedOrIsClone = is_matched
or is_clone
355 self.
pr_fakespr_fakes.append(
not isMatchedOrIsClone)
376 """Looks at the individual Monte Carlo tracks and store information about them"""
386 multiplicity = mcTrackCands.getEntries()
388 for mcTrackCand
in mcTrackCands:
389 is_matched = trackMatchLookUp.isMatchedMCRecoTrack(mcTrackCand)
391 hit_efficiency = trackMatchLookUp.getRelatedEfficiency(mcTrackCand)
392 if math.isnan(hit_efficiency):
395 mcParticle = trackMatchLookUp.getRelatedMCParticle(mcTrackCand)
396 mcHelix = getHelixFromMCParticle(mcParticle)
401 mcParticles=mcParticles)
406 momentum = mcParticle.getMomentum()
408 tan_lambda = np.divide(1.0, math.tan(momentum.Theta()))
410 det_hit_ids = get_det_hit_ids(mcTrackCand)
411 ndf = calc_ndf_from_det_hit_ids(det_hit_ids)
414 self.
mc_primariesmc_primaries.append(is_primary(mcParticle))
416 self.
mc_ptsmc_pts.append(pt)
417 self.
mc_d0smc_d0s.append(d0)
420 self.
mc_thetamc_theta.append(momentum.Theta())
421 self.
mc_phimc_phi.append(momentum.Phi())
422 self.
mc_ndfmc_ndf.append(ndf)
425 """Receive signal at the end of event processing"""
435 clone_rate = 1.0 - np.average(self.
pr_matchespr_matches,
438 clone_rate = float(
'nan')
441 hit_efficiency = np.average(self.
mc_hit_efficienciesmc_hit_efficiencies, weights=mc_matched_primaries)
445 figures_of_merit[
'finding_efficiency'] = finding_efficiency
446 figures_of_merit[
'fake_rate'] = fake_rate
447 figures_of_merit[
'clone_rate'] = clone_rate
448 figures_of_merit[
'hit_efficiency'] = hit_efficiency
450 figures_of_merit.description = \
452 finding_efficiency - the ratio of matched Monte Carlo tracks to all Monte Carlo tracks <br/>
453 fake_rate - ratio of pattern recognition tracks that are not related to a particle
454 (background, ghost) to all pattern recognition tracks <br/>
455 clone_rate - ratio of clones divided the number of tracks that are related to a particle (clones and matches) <br/>
457 figures_of_merit.check =
'Compare for degradations with respect to the reference'
458 figures_of_merit.contact = contact
459 print(figures_of_merit)
463 validation_plots = []
469 'finding efficiency',
473 validation_plots.extend(plots)
479 print(
'fake list: ' + str(len(self.
pr_fakespr_fakes)))
482 validation_plots.extend(plots)
487 'hit efficiency with matched tracks',
488 weights=mc_matched_primaries)
489 validation_plots.extend(plots)
494 all_but_diagonal_plots = list(PullAnalysis.default_which_plots)
495 all_but_diagonal_plots.remove(
"diag_profile")
496 all_but_diagonal_plots.remove(
"diag_scatter")
500 plot_name_prefix +=
'_seed'
507 curvature_pull_analysis =
PullAnalysis(
'#omega', unit=
'1/cm',
508 plot_name_prefix=plot_name_prefix +
'_omega',
512 curvature_pull_analysis.analyse(pr_omega_truths,
515 which_plots=all_but_diagonal_plots)
517 curvature_pull_analysis.contact = contact
518 pull_analyses.append(curvature_pull_analysis)
526 plot_name_prefix=plot_name_prefix +
'_tan_lambda',
530 curvature_pull_analysis.analyse(pr_tan_lambda_truths,
531 pr_tan_lambda_estimates,
532 pr_tan_lambda_variances,
533 which_plots=all_but_diagonal_plots)
535 curvature_pull_analysis.contact = contact
536 pull_analyses.append(curvature_pull_analysis)
540 plot_name_prefix=plot_name_prefix +
'_d0',
544 curvature_pull_analysis.analyse(np.array(self.
pr_d0_truthspr_d0_truths),
547 which_plots=all_but_diagonal_plots)
549 curvature_pull_analysis.contact = contact
550 pull_analyses.append(curvature_pull_analysis)
559 plot_name_prefix=plot_name_prefix +
'_d0_res',
562 d0_resolution_analysis.analyse(np.array(self.
pr_bining_ptpr_bining_pt),
565 d0_resolution_analysis.contact = contact
566 pull_analyses.append(d0_resolution_analysis)
572 plot_name_prefix=plot_name_prefix +
'_z0_res',
575 z0_resolution_analysis.analyse(np.array(self.
pr_bining_ptpr_bining_pt),
578 z0_resolution_analysis.contact = contact
579 pull_analyses.append(z0_resolution_analysis)
585 plot_name_prefix=plot_name_prefix +
'_omega_res',
588 omega_resolution_analysis.analyse(np.array(self.
pr_bining_ptpr_bining_pt),
591 omega_resolution_analysis.contact = contact
592 pull_analyses.append(omega_resolution_analysis)
598 plot_name_prefix=plot_name_prefix +
'_pt_res',
601 pt_resolution_analysis.analyse(np.array(self.
pr_bining_ptpr_bining_pt),
604 pt_resolution_analysis.contact = contact
605 pull_analyses.append(pt_resolution_analysis)
611 output_tfile = ROOT.TFile(self.
output_file_nameoutput_file_name,
'recreate')
616 ROOT.gStyle.SetOptFit(opt_fit)
618 figures_of_merit.write()
620 for validation_plot
in validation_plots:
621 validation_plot.write()
624 expert_tdirectory = output_tfile.mkdir(
'expert',
'Expert')
625 expert_tdirectory.cd()
626 ROOT.gStyle.SetOptFit(opt_fit)
628 for pull_analysis
in pull_analyses:
629 pull_analysis.write()
647 non_expert_parameters=['p_{t}'],
651 """Create profile histograms by MC-track parameters"""
654 new_parameter_names = [item
for item
in parameter_names
if item
658 profile_parameters = {
659 'd_{0}': self.
mc_d0smc_d0s,
660 'p_{t}': self.
mc_ptsmc_pts,
662 '#phi': self.
mc_phimc_phi,
675 non_expert_parameters=non_expert_parameters,
684 parameter_names=['Seed tan
687 """Create profile histograms by PR-track parameters"""
690 new_parameter_names = [item
for item
in parameter_names
if item
715 non_expert_parameters=[],
718 """Create profile histograms for generic parameters"""
722 validation_plots = []
723 plot_name_prefix = self.
validation_namevalidation_name +
'_' + root_save_name(quantity_name) \
729 histogram.hist(xs, weights=weights)
731 histogram.xlabel = quantity_name
732 histogram.description =
'Not a serious plot yet.'
734 histogram.contact = contact
737 validation_plots.append(histogram)
739 for (parameter_name, parameter_values)
in list(profile_parameters.items()):
740 if parameter_name
in parameter_names \
741 or root_save_name(parameter_name)
in parameter_names:
743 is_expert = not(parameter_name
in non_expert_parameters)
747 if root_save_name(parameter_name) ==
'tan_lambda':
750 elif root_save_name(parameter_name) ==
'theta':
751 lower_bound = 17 * math.pi / 180
752 upper_bound = 150 * math.pi / 180
753 elif root_save_name(parameter_name) ==
'ndf':
755 upper_bound = min(200, np.max(parameter_values))
760 profile_plot_name = plot_name_prefix +
'_by_' \
761 + root_save_name(parameter_name)
763 profile_plot.profile(parameter_values,
766 outlier_z_score=10.0,
767 lower_bound=lower_bound,
768 upper_bound=upper_bound,
772 profile_plot.xlabel = compose_axis_label(parameter_name)
773 profile_plot.ylabel = compose_axis_label(quantity_name, unit)
774 profile_plot.title = quantity_name +
' by ' + parameter_name \
777 profile_plot.description = \
778 'Dependence of %s of the track over the true %s' \
779 % (quantity_name, parameter_name)
780 profile_plot.check =
'Variations should be low'
781 profile_plot.contact = contact
782 validation_plots.append(profile_plot)
784 return validation_plots
static std::string findFile(const std::string &path, bool silent=false)
Search for given file or directory in local or central release directory, and return absolute path if...
a (simplified) python wrapper for StoreArray.
Class to provide convenient methods to look up matching information between pattern recognition and M...
def doesPrPass(self, filterProperties)
def doesMcPass(self, filterProperties)
mcParticle
cached value of the MC particle
wasFitted
cached value of the fitted flag
def __init__(self, trackCand=None, mcParticle=None, mcParticles=None, wasFitted=False, fitResult=None, seedResult=None)
trackCand
cached value of the track candidate
seedResult
cached value of the seed result
fitResult
cached value of the fit result
mcParticles
cached value of the MCParticles StoreArray
mc_d0s
list of MC-track d0 values
pr_omega_variances
list of PR-track seed omega-variance values
exclude_profile_mc_parameter
cached list of perigee parameters excluded from MC side plots
track_filter_object
cached value of the track-filter object
pr_seed_tan_lambdas
list of PR-track seed tan(lambda) values
pr_tan_lambda_estimates
list of PR-track seed tan(lambda)-estimate values
mc_theta
direction of the track in theta
pr_fakes
list of PR-track fakes
contact
cached value of the contact person name
fit
cached value of the track fit
pr_matches
list of PR-track matches
pr_bining_pt
list of PR-track binning values
def examine_pr_tracks(self)
pr_tan_lambda_variances
list of PR-track seed tan(lambda)-variance values
pr_pt_estimates
list of PR-track seed pt-estimate values
trackCandidatesColumnName
cached name of the RecoTracks StoreArray
pr_pt_truths
list of PR-track seed pt-truth values
pulls
cached values of the track-fit pulls
mc_ndf
list of MC-track number of degrees of freedom
pr_omega_truths
list of PR-track seed omega-truth values
def profiles_by_mc_parameters(self, xs, quantity_name, unit=None, parameter_names=['d_0', 'p_t', 'tan_lambda', 'multiplicity', 'phi', 'theta', 'ndf',], non_expert_parameters=['p_{t}'], make_hist=True, weights=None)
pr_seed_theta
list of PR-track seed theta values
pr_seed_phi
list of PR-track seed phi values
output_file_name
cached value of the output ROOT TFile
plot_name_postfix
cached value of the suffix appended to the plot names
trackMatchLookUp
Track-match object that examines relation information from MCMatcherTracksModule.
pr_omega_estimates
list of PR-track seed omega-estimate values
plot_title_postfix
cached value of the suffix appended to the plot titles
pr_z0_estimates
list of PR-track seed z0-estimate values
pr_d0_variances
list of PR-track seed d0-variance values
mc_pts
list of MC-track pt values
resolution_pt_binning
default binning used for resolution plots over pt
def profiles_by_pr_parameters(self, xs, quantity_name, unit=None, parameter_names=['Seed tan #lambda', 'Seed #phi', 'Seed #theta'], make_hist=True)
mc_multiplicities
list of MC-track multiplicities
mc_matches
list of MC-track matches
def examine_mc_tracks(self)
pr_clones_and_matches
Use deques in favour of lists to prevent repeated memory allocation of cost O(n)
mc_primaries
list of MC-track primaries
resolution
cached value of the resolution
def profiles_by_parameters_base(self, xs, quantity_name, parameter_names, profile_parameters, unit, make_hist, non_expert_parameters=[], weights=None)
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", mcTrackCandidatesColumName="MCRecoTracks")
referenceFileName
If this variable is set the code will open the file with same name as the file created here and will ...
use_expert_folder
cached flag to use the "expert" folder for the pull and residual plots
pr_z0_truths
list of PR-track seed z0-truth values
mc_phi
direction of the track in phi
mcTrackCandidatesColumnName
cached name of the MCRecoTracks StoreArray
pr_tan_lambda_truths
list of PR-track seed tan(lambda)-truth values
pr_d0_estimates
list of PR-track seed d0-estimate values
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
pr_d0_truths
list of PR-track seed d0-truth values
exclude_profile_pr_parameter
cached list of perigee parameters excluded from PR side plots