Belle II Software  release-05-02-19
module.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 import math
5 import collections
6 import numpy as np
7 
8 import tracking.metamodules as metamodules
9 from tracking.root_utils import root_save_name
10 
11 from .plot import ValidationPlot, compose_axis_label
12 
13 from .pull import PullAnalysis
14 from .resolution import ResolutionAnalysis
15 from .fom import ValidationFiguresOfMerit
16 from .utilities import (
17  getHelixFromMCParticle,
18  getSeedTrackFitResult,
19  is_primary,
20  get_det_hit_ids,
21  calc_ndf_from_det_hit_ids
22 )
23 
24 import basf2
25 
26 import logging
27 
28 import ROOT
29 ROOT.gSystem.Load("libtracking")
30 from ROOT import Belle2
31 
32 import os
33 
34 
35 class FilterProperties(object):
36  """
37  contains all informations necessary for track filters to decide whether
38  track will be included into the processed list of tracks
39  This class is used for both providing information on pattern reco and
40  MC tracks
41  """
42 
43  def __init__(
44  self,
45  trackCand=None,
46  mcParticle=None,
47  mcParticles=None,
48  wasFitted=False,
49  fitResult=None,
50  seedResult=None,
51  ):
52  """Constructor"""
53 
54 
55  self.trackCand = trackCand
56 
57  self.mcParticle = mcParticle
58 
59  self.mcParticles = mcParticles
60 
61  self.wasFitted = wasFitted
62 
63  self.fitResult = fitResult
64 
65  self.seedResult = seedResult
66 
67 
68 # This class will accept all pattern reco and mctracks
69 # It is used as the default option for the TrackingValidationModule
70 #
71 # It can be used as a starting point to implement your own particle filter class
72 # and supply it to the TrackingValidationModule via the init method's
73 # track_filter_object property.
74 #
75 # doesPrPass is called for all pattern reconstructed tracks
76 # Objects available infilterProperties:
77 # trackCand is guaranteed to be != None
78 # If wasFitted == True, fitResult will be set
79 # otherwise seedResult will be set
80 #
81 # doesMcPass is called for all MC tracks
82 # Objects available infilterProperties:
83 # mcParticle is guaranteed to be != None
84 #
85 
86 class AlwaysPassFilter(object):
87  """Filter that always passes"""
88 
89  def doesPrPass(self, filterProperties):
90  """Pattern-reconstructed track always passes"""
91  return True
92 
93  def doesMcPass(self, filterProperties):
94  """MC track always passes"""
95  return True
96 
97 
98 class TrackingValidationModule(basf2.Module):
99 
100  """Module to collect matching information about the found particles and to
101  generate validation plots and figures of merit on the performance of track finding."""
102 
103  def __init__(
104  self,
105  name,
106  contact,
107  fit=False,
108  pulls=False,
109  resolution=False,
110  output_file_name=None,
111  track_filter_object=AlwaysPassFilter(),
112  plot_name_postfix='',
113  plot_title_postfix='',
114  exclude_profile_mc_parameter='',
115  exclude_profile_pr_parameter='',
116  use_expert_folder=True,
117  trackCandidatesColumnName="RecoTracks",
118  mcTrackCandidatesColumName="MCRecoTracks"
119  ):
120  """Constructor"""
121 
122  super(TrackingValidationModule, self).__init__()
123 
124 
125  self.validation_name = name
126 
127  self.contact = contact
128 
129  self.fit = fit
130 
131  self.pulls = pulls
132 
133  self.resolution = resolution
134 
135  self.output_file_name = output_file_name or self.validation_name \
136  + 'TrackingValidation.root'
137 
138  self.track_filter_object = track_filter_object
139 
140  self.plot_name_postfix = plot_name_postfix
141 
142  self.plot_title_postfix = plot_title_postfix
143 
144  self.exclude_profile_pr_parameter = exclude_profile_pr_parameter
145 
146  self.exclude_profile_mc_parameter = exclude_profile_mc_parameter
147 
148  self.use_expert_folder = use_expert_folder
149 
150  self.trackCandidatesColumnName = trackCandidatesColumnName
151 
152  self.mcTrackCandidatesColumnName = mcTrackCandidatesColumName
153 
154 
155  self.resolution_pt_binning = [0.05, 0.1, 0.25, 0.4, 0.6, 1., 1.5, 2., 3., 4.]
156 
157 
161  self.referenceFileName = None
162  if "DO_NOT_READ_BINNING" not in os.environ:
163  # the validity of the file will be checked later
164  self.referenceFileName = Belle2.FileSystem.findFile("tracking/validation/" + self.output_file_name, True)
165  basf2.B2INFO("Will read binning from: " + self.referenceFileName)
166  basf2.B2INFO("If this is not wanted set the environment variable DO_NOT_READ_BINNING or remove reference files.")
167  else:
168  basf2.B2INFO("Will not read binning from reference files.")
169 
170  def initialize(self):
171  """Receive signal at the start of event processing"""
172 
173 
175 
176 
177 
178 
179  self.pr_clones_and_matches = collections.deque()
180 
181  self.pr_matches = collections.deque()
182 
183  self.pr_fakes = collections.deque()
184 
185 
186  self.pr_seed_tan_lambdas = collections.deque()
187 
188  self.pr_seed_phi = collections.deque()
189 
190  self.pr_seed_theta = collections.deque()
191 
192 
193  self.pr_omega_truths = collections.deque()
194 
195  self.pr_omega_estimates = collections.deque()
196 
197  self.pr_omega_variances = collections.deque()
198 
199 
200  self.pr_tan_lambda_truths = collections.deque()
201 
202  self.pr_tan_lambda_estimates = collections.deque()
203 
204  self.pr_tan_lambda_variances = collections.deque()
205 
206 
207  self.pr_d0_truths = collections.deque()
208 
209  self.pr_d0_estimates = collections.deque()
210 
211  self.pr_d0_variances = collections.deque()
212 
213 
214  self.pr_z0_truths = collections.deque()
215 
216  self.pr_z0_estimates = collections.deque()
217 
218 
219  self.pr_pt_truths = collections.deque()
220 
221  self.pr_pt_estimates = collections.deque()
222 
223 
224  self.pr_bining_pt = collections.deque()
225 
226 
227  self.mc_matches = collections.deque()
228 
229  self.mc_primaries = collections.deque()
230 
231  self.mc_d0s = collections.deque()
232 
233  self.mc_tan_lambdas = collections.deque()
234 
235  self.mc_theta = collections.deque()
236 
237  self.mc_phi = collections.deque()
238 
239  self.mc_pts = collections.deque()
240 
241  self.mc_hit_efficiencies = collections.deque()
242 
243  self.mc_multiplicities = collections.deque()
244 
245  self.mc_ndf = collections.deque()
246 
247  def event(self):
248  """Event method"""
249 
250  self.examine_pr_tracks()
251  self.examine_mc_tracks()
252 
253  def examine_pr_tracks(self):
254  """Looks at the individual pattern reconstructed tracks and store information about them"""
255 
256  # Analyse from the pattern recognition side
257  trackMatchLookUp = self.trackMatchLookUp
258 
260  mcParticles = Belle2.PyStoreArray("MCParticles")
261  if not trackCands:
262  return
263 
264  for trackCand in trackCands:
265  is_matched = trackMatchLookUp.isMatchedPRRecoTrack(trackCand)
266  is_clone = trackMatchLookUp.isClonePRRecoTrack(trackCand)
267 
268  pt_truth = float('nan')
269  omega_truth = float('nan')
270  tan_lambda_truth = float('nan')
271  d0_truth = float('nan')
272  z0_truth = float('nan')
273 
274  mcParticle = None
275  if is_matched or is_clone:
276  # Only matched and clone tracks have a related MCParticle
277  mcParticle = trackMatchLookUp.getRelatedMCParticle(trackCand)
278  mcHelix = getHelixFromMCParticle(mcParticle)
279  omega_truth = mcHelix.getOmega()
280  tan_lambda_truth = mcHelix.getTanLambda()
281  pt_truth = mcParticle.getMomentum().Perp()
282  d0_truth = mcHelix.getD0()
283  z0_truth = mcHelix.getZ0()
284 
285  # fill the FilterProperties will all properties on this track
286  # gathered so far
287  filterProperties = FilterProperties(trackCand=trackCand,
288  mcParticle=mcParticle, mcParticles=mcParticles)
289 
290  if self.fit:
291  prTrackFitResult = \
292  trackMatchLookUp.getRelatedTrackFitResult(trackCand)
293  filterProperties.wasFitted = prTrackFitResult is not None
294  filterProperties.fitResult = prTrackFitResult
295  else:
296  prTrackFitResult = getSeedTrackFitResult(trackCand)
297  filterProperties.seedResult = prTrackFitResult
298 
299  # skip this track due to the filtering rules ?
300  if not self.track_filter_object.doesPrPass(filterProperties):
301  continue
302 
303  omega_estimate = float('nan')
304  omega_variance = float('nan')
305  tan_lambda_estimate = float('nan')
306  tan_lambda_variance = float('nan')
307  d0_estimate = float('nan')
308  d0_variance = float('nan')
309  z0_estimate = float('nan')
310  pt_estimate = float('nan')
311 
312  momentum_pt = float('nan')
313  momentum = float('nan')
314 
315  # store seed information, they are always available from the pattern reco
316  # even if the fit was no successful
317  # this information can we used when plotting fake tracks, for example
318  seed_position = trackCand.getPositionSeed()
319  seed_momentum = trackCand.getMomentumSeed()
320  # Avoid zero division exception
321  seed_tan_lambda = np.divide(1.0, math.tan(seed_momentum.Theta()))
322  seed_phi = seed_position.Phi()
323  seed_theta = seed_position.Theta()
324 
325  if prTrackFitResult:
326  omega_estimate = prTrackFitResult.getOmega()
327  omega_variance = prTrackFitResult.getCov()[9]
328 
329  tan_lambda_estimate = prTrackFitResult.getCotTheta()
330  tan_lambda_variance = prTrackFitResult.getCov()[14]
331 
332  d0_estimate = prTrackFitResult.getD0()
333  d0_variance = prTrackFitResult.getCov()[0]
334 
335  z0_estimate = prTrackFitResult.getZ0()
336 
337  momentum = prTrackFitResult.getMomentum()
338  pt_estimate = momentum.Perp()
339 
340  # store properties of the seed
341  self.pr_seed_tan_lambdas.append(seed_tan_lambda)
342  self.pr_seed_phi.append(seed_phi)
343  self.pr_seed_theta.append(seed_theta)
344 
345  self.pr_bining_pt.append(pt_truth)
346 
347  # store properties resulting from this trackfit
348  isMatchedOrIsClone = is_matched or is_clone
349  self.pr_clones_and_matches.append(isMatchedOrIsClone)
350  self.pr_matches.append(is_matched)
351  self.pr_fakes.append(not isMatchedOrIsClone)
352 
353  self.pr_omega_estimates.append(omega_estimate)
354  self.pr_omega_variances.append(omega_variance)
355  self.pr_omega_truths.append(omega_truth)
356 
357  self.pr_tan_lambda_estimates.append(tan_lambda_estimate)
358  self.pr_tan_lambda_variances.append(tan_lambda_variance)
359  self.pr_tan_lambda_truths.append(tan_lambda_truth)
360 
361  self.pr_d0_estimates.append(d0_estimate)
362  self.pr_d0_variances.append(d0_variance)
363  self.pr_d0_truths.append(d0_truth)
364 
365  self.pr_z0_estimates.append(z0_estimate)
366  self.pr_z0_truths.append(z0_truth)
367 
368  self.pr_pt_estimates.append(pt_estimate)
369  self.pr_pt_truths.append(pt_truth)
370 
371  def examine_mc_tracks(self):
372  """Looks at the individual Monte Carlo tracks and store information about them"""
373 
374  trackMatchLookUp = self.trackMatchLookUp
375 
376  # Analyse from the Monte Carlo reference side
378  mcParticles = Belle2.PyStoreArray('MCParticles')
379  if not mcTrackCands:
380  return
381 
382  multiplicity = mcTrackCands.getEntries()
383 
384  for mcTrackCand in mcTrackCands:
385  is_matched = trackMatchLookUp.isMatchedMCRecoTrack(mcTrackCand)
386 
387  hit_efficiency = trackMatchLookUp.getRelatedEfficiency(mcTrackCand)
388  if math.isnan(hit_efficiency):
389  hit_efficiency = 0
390 
391  mcParticle = trackMatchLookUp.getRelatedMCParticle(mcTrackCand)
392  mcHelix = getHelixFromMCParticle(mcParticle)
393 
394  # fill the FilterProperties will all properties on this track
395  # gathered so far
396  filterProperties = FilterProperties(mcParticle=mcParticle,
397  mcParticles=mcParticles)
398 
399  if not self.track_filter_object.doesMcPass(filterProperties):
400  continue
401 
402  momentum = mcParticle.getMomentum()
403  pt = momentum.Perp()
404  tan_lambda = np.divide(1.0, math.tan(momentum.Theta())) # Avoid zero division exception
405  d0 = mcHelix.getD0()
406  det_hit_ids = get_det_hit_ids(mcTrackCand)
407  ndf = calc_ndf_from_det_hit_ids(det_hit_ids)
408 
409  self.mc_matches.append(is_matched)
410  self.mc_primaries.append(is_primary(mcParticle))
411  self.mc_hit_efficiencies.append(hit_efficiency)
412  self.mc_pts.append(pt)
413  self.mc_d0s.append(d0)
414  self.mc_tan_lambdas.append(tan_lambda)
415  self.mc_multiplicities.append(multiplicity)
416  self.mc_theta.append(momentum.Theta())
417  self.mc_phi.append(momentum.Phi())
418  self.mc_ndf.append(ndf)
419 
420  def terminate(self):
421  """Receive signal at the end of event processing"""
422  name = self.validation_name
423  contact = self.contact
424 
425  # Overall figures of merit #
426 
427  finding_efficiency = np.average(self.mc_matches, weights=self.mc_primaries)
428  fake_rate = 1.0 - np.mean(self.pr_clones_and_matches)
429  # can only be computed if there are entries
430  if len(self.pr_clones_and_matches) > 0 and sum(self.pr_clones_and_matches) > 0:
431  clone_rate = 1.0 - np.average(self.pr_matches,
432  weights=self.pr_clones_and_matches)
433  else:
434  clone_rate = float('nan')
435 
436  mc_matched_primaries = np.logical_and(self.mc_primaries, self.mc_matches)
437  hit_efficiency = np.average(self.mc_hit_efficiencies, weights=mc_matched_primaries)
438 
439  figures_of_merit = ValidationFiguresOfMerit('%s_figures_of_merit'
440  % name)
441  figures_of_merit['finding_efficiency'] = finding_efficiency
442  figures_of_merit['fake_rate'] = fake_rate
443  figures_of_merit['clone_rate'] = clone_rate
444  figures_of_merit['hit_efficiency'] = hit_efficiency
445 
446  figures_of_merit.description = \
447  """
448 finding_efficiency - the ratio of matched Monte Carlo tracks to all Monte Carlo tracks <br/>
449 fake_rate - ratio of pattern recognition tracks that are not related to a particle
450  (background, ghost) to all pattern recognition tracks <br/>
451 clone_rate - ratio of clones divided the number of tracks that are related to a particle (clones and matches) <br/>
452 """
453  figures_of_merit.check = 'Compare for degradations with respect to the reference'
454  figures_of_merit.contact = contact
455  print(figures_of_merit)
456 
457  # Validation plots #
458 
459  validation_plots = []
460  pull_analyses = []
461 
462  # Finding efficiency #
463 
464  plots = self.profiles_by_mc_parameters(self.mc_matches,
465  'finding efficiency',
466  make_hist=False,
467  weights=self.mc_primaries)
468 
469  validation_plots.extend(plots)
470 
471  # Fake rate (all tracks not matched or clone #
472  # use TrackCand seeds for the fake track plotting #
473  # as the fit (if successful) is probably not meaningful #
474 
475  print('fake list: ' + str(len(self.pr_fakes)))
476  plots = self.profiles_by_pr_parameters(self.pr_fakes, 'fake rate',
477  make_hist=False)
478  validation_plots.extend(plots)
479 
480  # Hit efficiency #
481 
483  'hit efficiency with matched tracks',
484  weights=mc_matched_primaries)
485  validation_plots.extend(plots)
486 
487  # Fit quality #
488 
489  if self.pulls:
490  all_but_diagonal_plots = list(PullAnalysis.default_which_plots)
491  all_but_diagonal_plots.remove("diag_profile")
492  all_but_diagonal_plots.remove("diag_scatter")
493 
494  plot_name_prefix = name + self.plot_name_postfix
495  if not self.fit:
496  plot_name_prefix += '_seed'
497 
498  # Omega / curvature pull
499  pr_omega_truths = np.array(self.pr_omega_truths)
500  pr_omega_estimates = np.array(self.pr_omega_estimates)
501  pr_omega_variances = np.array(self.pr_omega_variances)
502 
503  curvature_pull_analysis = PullAnalysis('#omega', unit='1/cm',
504  plot_name_prefix=plot_name_prefix + '_omega',
505  plot_title_postfix=self.plot_title_postfix,
506  referenceFileName=self.referenceFileName)
507 
508  curvature_pull_analysis.analyse(pr_omega_truths,
509  pr_omega_estimates,
510  pr_omega_variances,
511  which_plots=all_but_diagonal_plots)
512 
513  curvature_pull_analysis.contact = contact
514  pull_analyses.append(curvature_pull_analysis)
515 
516  # Tan lambda pull
517  pr_tan_lambda_truths = np.array(self.pr_tan_lambda_truths)
518  pr_tan_lambda_estimates = np.array(self.pr_tan_lambda_estimates)
519  pr_tan_lambda_variances = np.array(self.pr_tan_lambda_variances)
520 
521  curvature_pull_analysis = PullAnalysis('tan #lambda',
522  plot_name_prefix=plot_name_prefix + '_tan_lambda',
523  plot_title_postfix=self.plot_title_postfix,
524  referenceFileName=self.referenceFileName)
525 
526  curvature_pull_analysis.analyse(pr_tan_lambda_truths,
527  pr_tan_lambda_estimates,
528  pr_tan_lambda_variances,
529  which_plots=all_but_diagonal_plots)
530 
531  curvature_pull_analysis.contact = contact
532  pull_analyses.append(curvature_pull_analysis)
533 
534  # d0 pull
535  curvature_pull_analysis = PullAnalysis('d0',
536  plot_name_prefix=plot_name_prefix + '_d0',
537  plot_title_postfix=self.plot_title_postfix,
538  referenceFileName=self.referenceFileName)
539 
540  curvature_pull_analysis.analyse(np.array(self.pr_d0_truths),
541  np.array(self.pr_d0_estimates),
542  np.array(self.pr_d0_variances),
543  which_plots=all_but_diagonal_plots)
544 
545  curvature_pull_analysis.contact = contact
546  pull_analyses.append(curvature_pull_analysis)
547 
548  # Resolution plots
549 
550  if self.resolution:
551  # d0 impact parameter resolution plot
552  d0_resolution_analysis = ResolutionAnalysis('d0_res',
554  'Pt',
555  plot_name_prefix=plot_name_prefix + '_d0_res',
556  plot_title_postfix=self.plot_title_postfix,
557  referenceFileName=self.referenceFileName)
558  d0_resolution_analysis.analyse(np.array(self.pr_bining_pt),
559  np.array(self.pr_d0_truths),
560  np.array(self.pr_d0_estimates))
561  d0_resolution_analysis.contact = contact
562  pull_analyses.append(d0_resolution_analysis)
563 
564  # z0 impact parameter resolution plot
565  z0_resolution_analysis = ResolutionAnalysis('z0_res',
567  "Pt",
568  plot_name_prefix=plot_name_prefix + '_z0_res',
569  plot_title_postfix=self.plot_title_postfix,
570  referenceFileName=self.referenceFileName)
571  z0_resolution_analysis.analyse(np.array(self.pr_bining_pt),
572  np.array(self.pr_z0_truths),
573  np.array(self.pr_z0_estimates))
574  z0_resolution_analysis.contact = contact
575  pull_analyses.append(z0_resolution_analysis)
576 
577  # omega curvature parameter resolution plot
578  omega_resolution_analysis = ResolutionAnalysis('omega_res',
580  "Pt",
581  plot_name_prefix=plot_name_prefix + '_omega_res',
582  plot_title_postfix=self.plot_title_postfix,
583  referenceFileName=self.referenceFileName)
584  omega_resolution_analysis.analyse(np.array(self.pr_bining_pt),
585  np.array(self.pr_omega_truths),
586  np.array(self.pr_omega_estimates))
587  omega_resolution_analysis.contact = contact
588  pull_analyses.append(omega_resolution_analysis)
589 
590  # transverse momentum resolution plot
591  pt_resolution_analysis = ResolutionAnalysis('pt_res',
593  "Pt",
594  plot_name_prefix=plot_name_prefix + '_pt_res',
595  plot_title_postfix=self.plot_title_postfix,
596  referenceFileName=self.referenceFileName)
597  pt_resolution_analysis.analyse(np.array(self.pr_bining_pt),
598  np.array(self.pr_pt_truths),
599  np.array(self.pr_pt_estimates))
600  pt_resolution_analysis.contact = contact
601  pull_analyses.append(pt_resolution_analysis)
602 
603  # Saving #
604 
605 
606  # Save everything to a ROOT file
607  output_tfile = ROOT.TFile(self.output_file_name, 'recreate')
608 
609  # Show all parameters and the fit result in the plots
610  # if viewed in the browser or the validation
611  opt_fit = 0o112
612  ROOT.gStyle.SetOptFit(opt_fit)
613 
614  figures_of_merit.write()
615 
616  for validation_plot in validation_plots:
617  validation_plot.write()
618 
619  if self.use_expert_folder:
620  expert_tdirectory = output_tfile.mkdir('expert', 'Expert')
621  expert_tdirectory.cd()
622  ROOT.gStyle.SetOptFit(opt_fit)
623 
624  for pull_analysis in pull_analyses:
625  pull_analysis.write()
626 
627  output_tfile.Close()
628 
630  self,
631  xs,
632  quantity_name,
633  unit=None,
634  parameter_names=[
635  'd_0',
636  'p_t',
637  'tan_lambda',
638  'multiplicity',
639  'phi',
640  'theta',
641  'ndf',
642  ],
643  non_expert_parameters=['p_{t}'],
644  make_hist=True,
645  weights=None
646  ):
647  """Create profile histograms by MC-track parameters"""
648 
649  # apply exclusion list
650  new_parameter_names = [item for item in parameter_names if item
651  not in self.exclude_profile_mc_parameter]
652 
653  # Profile versus the various parameters
654  profile_parameters = {
655  'd_{0}': self.mc_d0s,
656  'p_{t}': self.mc_pts,
657  'tan #lambda': self.mc_tan_lambdas,
658  '#phi': self.mc_phi,
659  '#theta': self.mc_theta,
660  'multiplicity': self.mc_multiplicities,
661  'ndf': self.mc_ndf,
662  }
663 
664  return self.profiles_by_parameters_base(
665  xs,
666  quantity_name,
667  new_parameter_names,
668  profile_parameters,
669  unit,
670  make_hist,
671  non_expert_parameters=non_expert_parameters,
672  weights=weights
673  )
674 
676  self,
677  xs,
678  quantity_name,
679  unit=None,
680  parameter_names=['Seed tan #lambda', 'Seed #phi', 'Seed #theta'],
681  make_hist=True,
682  ):
683  """Create profile histograms by PR-track parameters"""
684 
685  # apply exclusion list
686  new_parameter_names = [item for item in parameter_names if item
687  not in self.exclude_profile_pr_parameter]
688 
689  # Profile versus the various parameters
690  profile_parameters = {'Seed tan #lambda': self.pr_seed_tan_lambdas,
691  'Seed #phi': self.pr_seed_phi,
692  'Seed #theta': self.pr_seed_theta}
693 
694  return self.profiles_by_parameters_base(
695  xs,
696  quantity_name,
697  new_parameter_names,
698  profile_parameters,
699  unit,
700  make_hist,
701  )
702 
704  self,
705  xs,
706  quantity_name,
707  parameter_names,
708  profile_parameters,
709  unit,
710  make_hist,
711  non_expert_parameters=[],
712  weights=None,
713  ):
714  """Create profile histograms for generic parameters"""
715 
716  contact = self.contact
717 
718  validation_plots = []
719  plot_name_prefix = self.validation_name + '_' + root_save_name(quantity_name) \
720  + self.plot_name_postfix
721 
722  if make_hist:
723  # Histogram of the quantity
724  histogram = ValidationPlot(plot_name_prefix, self.referenceFileName)
725  histogram.hist(xs, weights=weights)
726 
727  histogram.xlabel = quantity_name
728  histogram.description = 'Not a serious plot yet.'
729  histogram.check = ''
730  histogram.contact = contact
731  histogram.title = quantity_name + self.plot_title_postfix
732 
733  validation_plots.append(histogram)
734 
735  for (parameter_name, parameter_values) in list(profile_parameters.items()):
736  if parameter_name in parameter_names \
737  or root_save_name(parameter_name) in parameter_names:
738 
739  is_expert = not(parameter_name in non_expert_parameters)
740 
741  # Apply some boundaries for the maximal tracking acceptance
742  # such that the plots look more instructive
743  if root_save_name(parameter_name) == 'tan_lambda':
744  lower_bound = -1.73
745  upper_bound = 3.27
746  elif root_save_name(parameter_name) == 'theta':
747  lower_bound = 17 * math.pi / 180
748  upper_bound = 150 * math.pi / 180
749  elif root_save_name(parameter_name) == 'ndf':
750  lower_bound = 0
751  upper_bound = min(200, np.max(parameter_values))
752  else:
753  lower_bound = None
754  upper_bound = None
755 
756  profile_plot_name = plot_name_prefix + '_by_' \
757  + root_save_name(parameter_name)
758  profile_plot = ValidationPlot(profile_plot_name, self.referenceFileName)
759  profile_plot.profile(parameter_values,
760  xs,
761  weights=weights,
762  outlier_z_score=10.0,
763  lower_bound=lower_bound,
764  upper_bound=upper_bound,
765  y_binary=True,
766  is_expert=is_expert)
767 
768  profile_plot.xlabel = compose_axis_label(parameter_name)
769  profile_plot.ylabel = compose_axis_label(quantity_name, unit)
770  profile_plot.title = quantity_name + ' by ' + parameter_name \
771  + ' profile' + self.plot_title_postfix
772 
773  profile_plot.description = \
774  'Dependence of %s of the track over the true %s' \
775  % (quantity_name, parameter_name)
776  profile_plot.check = 'Variations should be low'
777  profile_plot.contact = contact
778  validation_plots.append(profile_plot)
779 
780  return validation_plots
781 
782 
783 def main():
784  from tracking.run.tracked_event_generation import StandardReconstructionEventsRun
785  standard_reco_run = StandardReconstructionEventsRun()
786  standard_reco_run.configure_from_commandline()
787 
788  validation_module = SeparatedTrackingValidationModule(name="test_run",
789  contact="dummy",
790  output_file_name="test_separated_module.root",
791  expert_level=0)
792 
793  standard_reco_run.add_module(validation_module)
794  standard_reco_run.execute()
795 
796 
797 if __name__ == "__main__":
798  logging.basicConfig(level=logging.INFO)
799  main()
tracking.validation.module.TrackingValidationModule.plot_title_postfix
plot_title_postfix
cached value of the suffix appended to the plot titles
Definition: module.py:126
tracking.validation.fom.ValidationFiguresOfMerit
Definition: fom.py:11
tracking.validation.module.TrackingValidationModule.examine_pr_tracks
def examine_pr_tracks(self)
Definition: module.py:253
tracking.validation.module.TrackingValidationModule.pr_z0_truths
pr_z0_truths
list of PR-track seed z0-truth values
Definition: module.py:214
tracking.validation.module.TrackingValidationModule.pr_clones_and_matches
pr_clones_and_matches
Use deques in favour of lists to prevent repeated memory allocation of cost O(n)
Definition: module.py:179
tracking.validation.module.TrackingValidationModule.pr_seed_phi
pr_seed_phi
list of PR-track seed phi values
Definition: module.py:188
tracking.validation.module.TrackingValidationModule.validation_name
validation_name
cached value of the tracking-validation name
Definition: module.py:109
tracking.validation.module.TrackingValidationModule.pr_d0_truths
pr_d0_truths
list of PR-track seed d0-truth values
Definition: module.py:207
tracking.validation.module.TrackingValidationModule.mcTrackCandidatesColumnName
mcTrackCandidatesColumnName
cached name of the MCRecoTracks StoreArray
Definition: module.py:136
tracking.validation.module.TrackingValidationModule.pr_d0_variances
pr_d0_variances
list of PR-track seed d0-variance values
Definition: module.py:211
tracking.validation.module.TrackingValidationModule.fit
fit
cached value of the track fit
Definition: module.py:113
tracking.validation.module.TrackingValidationModule.pr_seed_theta
pr_seed_theta
list of PR-track seed theta values
Definition: module.py:190
tracking.validation.pull.PullAnalysis
Definition: pull.py:20
tracking.validation.module.TrackingValidationModule.profiles_by_pr_parameters
def profiles_by_pr_parameters(self, xs, quantity_name, unit=None, parameter_names=['Seed tan #lambda', 'Seed #phi', 'Seed #theta'], make_hist=True)
Definition: module.py:675
tracking.validation.module.TrackingValidationModule.resolution
resolution
cached value of the resolution
Definition: module.py:117
tracking.validation.module.TrackingValidationModule.profiles_by_mc_parameters
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)
Definition: module.py:629
tracking.validation.module.TrackingValidationModule.trackCandidatesColumnName
trackCandidatesColumnName
cached name of the RecoTracks StoreArray
Definition: module.py:134
tracking.validation.module.FilterProperties.__init__
def __init__(self, trackCand=None, mcParticle=None, mcParticles=None, wasFitted=False, fitResult=None, seedResult=None)
Definition: module.py:43
tracking.validation.module.TrackingValidationModule
Definition: module.py:98
tracking.validation.module.TrackingValidationModule.mc_theta
mc_theta
direction of the track in theta
Definition: module.py:235
tracking.validation.module.TrackingValidationModule.trackMatchLookUp
trackMatchLookUp
Track-match object that examines relation information from MCMatcherTracksModule.
Definition: module.py:174
tracking.validation.module.TrackingValidationModule.mc_pts
mc_pts
list of MC-track pt values
Definition: module.py:239
tracking.validation.module.TrackingValidationModule.initialize
def initialize(self)
Definition: module.py:170
tracking.validation.module.TrackingValidationModule.resolution_pt_binning
resolution_pt_binning
default binning used for resolution plots over pt
Definition: module.py:139
tracking.validation.module.TrackingValidationModule.pr_bining_pt
pr_bining_pt
list of PR-track binning values
Definition: module.py:224
tracking.validation.module.TrackingValidationModule.pr_tan_lambda_estimates
pr_tan_lambda_estimates
list of PR-track seed tan(lambda)-estimate values
Definition: module.py:202
tracking.validation.module.TrackingValidationModule.mc_d0s
mc_d0s
list of MC-track d0 values
Definition: module.py:231
tracking.validation.module.TrackingValidationModule.pr_omega_estimates
pr_omega_estimates
list of PR-track seed omega-estimate values
Definition: module.py:195
tracking.validation.module.TrackingValidationModule.pr_d0_estimates
pr_d0_estimates
list of PR-track seed d0-estimate values
Definition: module.py:209
tracking.validation.module.TrackingValidationModule.mc_phi
mc_phi
direction of the track in phi
Definition: module.py:237
tracking.validation.module.FilterProperties.trackCand
trackCand
cached value of the track candidate
Definition: module.py:47
tracking.validation.module.TrackingValidationModule.mc_hit_efficiencies
mc_hit_efficiencies
list of MC-track hit efficiencies
Definition: module.py:241
Belle2::TrackMatchLookUp
Class to provide convenient methods to look up matching information between pattern recognition and M...
Definition: TrackMatchLookUp.h:43
tracking.validation.module.TrackingValidationModule.mc_tan_lambdas
mc_tan_lambdas
list of MC-track tan(lambda) values
Definition: module.py:233
tracking.validation.module.TrackingValidationModule.mc_multiplicities
mc_multiplicities
list of MC-track multiplicities
Definition: module.py:243
tracking.validation.module.TrackingValidationModule.referenceFileName
referenceFileName
If this variable is set the code will open the file with same name as the file created here and will ...
Definition: module.py:145
tracking.validation.module.TrackingValidationModule.pr_pt_estimates
pr_pt_estimates
list of PR-track seed pt-estimate values
Definition: module.py:221
tracking.validation.module.TrackingValidationModule.pr_tan_lambda_truths
pr_tan_lambda_truths
list of PR-track seed tan(lambda)-truth values
Definition: module.py:200
tracking.validation.resolution.ResolutionAnalysis
Definition: resolution.py:20
tracking.validation.module.TrackingValidationModule.use_expert_folder
use_expert_folder
cached flag to use the "expert" folder for the pull and residual plots
Definition: module.py:132
tracking.validation.module.TrackingValidationModule.profiles_by_parameters_base
def profiles_by_parameters_base(self, xs, quantity_name, parameter_names, profile_parameters, unit, make_hist, non_expert_parameters=[], weights=None)
Definition: module.py:703
tracking.validation.module.AlwaysPassFilter.doesMcPass
def doesMcPass(self, filterProperties)
Definition: module.py:93
tracking.validation.module.TrackingValidationModule.pr_seed_tan_lambdas
pr_seed_tan_lambdas
list of PR-track seed tan(lambda) values
Definition: module.py:186
tracking.validation.module.TrackingValidationModule.pr_omega_truths
pr_omega_truths
list of PR-track seed omega-truth values
Definition: module.py:193
tracking.validation.module.TrackingValidationModule.exclude_profile_mc_parameter
exclude_profile_mc_parameter
cached list of perigee parameters excluded from MC side plots
Definition: module.py:130
tracking.validation.module.TrackingValidationModule.examine_mc_tracks
def examine_mc_tracks(self)
Definition: module.py:371
tracking.validation.module.TrackingValidationModule.terminate
def terminate(self)
Definition: module.py:420
tracking.validation.module.TrackingValidationModule.contact
contact
cached value of the contact person name
Definition: module.py:111
main
int main(int argc, char **argv)
Run all tests.
Definition: test_main.cc:77
tracking.validation.module.TrackingValidationModule.plot_name_postfix
plot_name_postfix
cached value of the suffix appended to the plot names
Definition: module.py:124
tracking.validation.module.TrackingValidationModule.exclude_profile_pr_parameter
exclude_profile_pr_parameter
cached list of perigee parameters excluded from PR side plots
Definition: module.py:128
tracking.validation.module.FilterProperties.fitResult
fitResult
cached value of the fit result
Definition: module.py:55
tracking.validation.module.TrackingValidationModule.pr_pt_truths
pr_pt_truths
list of PR-track seed pt-truth values
Definition: module.py:219
tracking.validation.module.TrackingValidationModule.track_filter_object
track_filter_object
cached value of the track-filter object
Definition: module.py:122
tracking.metamodules
Definition: metamodules.py:1
tracking.validation.module.TrackingValidationModule.pulls
pulls
cached values of the track-fit pulls
Definition: module.py:115
tracking.root_utils
Definition: root_utils.py:1
tracking.validation.module.AlwaysPassFilter
Definition: module.py:86
tracking.validation.module.TrackingValidationModule.pr_tan_lambda_variances
pr_tan_lambda_variances
list of PR-track seed tan(lambda)-variance values
Definition: module.py:204
tracking.validation.module.FilterProperties.mcParticles
mcParticles
cached value of the MCParticles StoreArray
Definition: module.py:51
tracking.validation.module.FilterProperties.wasFitted
wasFitted
cached value of the fitted flag
Definition: module.py:53
tracking.validation.module.TrackingValidationModule.pr_z0_estimates
pr_z0_estimates
list of PR-track seed z0-estimate values
Definition: module.py:216
tracking.validation.module.FilterProperties.mcParticle
mcParticle
cached value of the MC particle
Definition: module.py:49
Belle2::PyStoreArray
a (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:58
tracking.validation.plot.ValidationPlot
Definition: plot.py:152
tracking.validation.module.FilterProperties
Definition: module.py:35
tracking.validation.module.FilterProperties.seedResult
seedResult
cached value of the seed result
Definition: module.py:57
tracking.validation.module.TrackingValidationModule.pr_omega_variances
pr_omega_variances
list of PR-track seed omega-variance values
Definition: module.py:197
tracking.validation.module.TrackingValidationModule.pr_fakes
pr_fakes
list of PR-track fakes
Definition: module.py:183
tracking.validation.module.TrackingValidationModule.mc_ndf
mc_ndf
list of MC-track number of degrees of freedom
Definition: module.py:245
tracking.run.tracked_event_generation
Definition: tracked_event_generation.py:1
Belle2::FileSystem::findFile
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...
Definition: FileSystem.cc:147
tracking.validation.module.TrackingValidationModule.__init__
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")
Definition: module.py:103
tracking.validation.module.TrackingValidationModule.event
def event(self)
Definition: module.py:247
tracking.validation.module.TrackingValidationModule.mc_primaries
mc_primaries
list of MC-track primaries
Definition: module.py:229
tracking.validation.module.TrackingValidationModule.pr_matches
pr_matches
list of PR-track matches
Definition: module.py:181
tracking.validation.module.AlwaysPassFilter.doesPrPass
def doesPrPass(self, filterProperties)
Definition: module.py:89
tracking.validation.module.TrackingValidationModule.mc_matches
mc_matches
list of MC-track matches
Definition: module.py:227
tracking.validation.module.TrackingValidationModule.output_file_name
output_file_name
cached value of the output ROOT TFile
Definition: module.py:119