Belle II Software  light-2205-abys
trackIsolationVariables.py
1 #!/usr/bin/env python3
2 
3 
10 
11 # Doxygen should skip this script
12 # @cond
13 
14 """
15 Example script to calculate track isolation variables.
16 
17 For each particle's track in the input charged stable particle list,
18 calculate the minimal distance to the other candidates' tracks at a given detector surface.
19 """
20 
21 import argparse
22 
23 
24 def argparser():
25  """ Argument parser
26  """
27 
28  import stdCharged as stdc
29 
30  parser = argparse.ArgumentParser(description=__doc__,
31  formatter_class=argparse.RawTextHelpFormatter)
32 
33  parser.add_argument("--std_charged_ref", type=str, choices=stdc._chargednames, default="pi",
34  help="The base name of the reference standard charged particle list\n"
35  "against which to calculate the distance.")
36  parser.add_argument("--detectors",
37  type=str,
38  nargs="+",
39  default=["CDC", "TOP", "ARICH", "ECL", "KLM"],
40  choices=["CDC", "TOP", "ARICH", "ECL", "KLM"],
41  help="List of detectors at whose entry surface track isolation variables will be calculated.\n"
42  "Pass a space-separated list of names.")
43  parser.add_argument("-d", "--debug",
44  action="store",
45  default=0,
46  type=int,
47  choices=list(range(11, 20)),
48  help="Run the TrackIsoCalculator module in debug mode. Pass the desired DEBUG level integer.")
49 
50  return parser
51 
52 
53 if __name__ == "__main__":
54 
55  # Argparse options.
56  # NB: Command line arguments are parsed before importing basf2, to avoid PyROOT hijacking them
57  # in case of overlapping option names.
58  args = argparser().parse_args()
59 
60  import basf2 as b2
61  import modularAnalysis as ma
62  from variables import variables
63  import variables.utils as vu
64  import variables.collections as vc
65 
66  # Create path. Register necessary modules to this path.
67  path = b2.create_path()
68 
69  # Add input data and ParticleLoader modules to the path.
70  ma.inputMdst(filename=b2.find_file("mdst14.root", "validation"), path=path)
71 
72  # Fill a particle list of muons, with some quality selection.
73  base_trk_selection = "[dr < 3] and [abs(dz) < 5] and [thetaInCDCAcceptance] and [pt > 0.1]"
74  ma.fillParticleList("mu+:muons", f"{base_trk_selection} and [muonID > 0.5]", path=path)
75 
76  # Fill a reference charged stable particle list to calculate the distances against.
77  # Generally, this list should have a very loose selection applied (if none at all).
78  ref = f"{args.std_charged_ref}+:presel"
79  ma.fillParticleList(ref, f"{base_trk_selection}", path=path)
80 
81  # Mode 1: calculate the track isolation variables
82  # directly on the muons particle list.
83  trackiso_vars = ma.calculateTrackIsolation("mu+:muons",
84  path,
85  *args.detectors,
86  reference_list_name=ref,
87  highest_prob_mass_for_ext=False)
88 
89  # Reconstruct the J/psi decay.
90  jpsimumu = "J/psi:mumu -> mu+:muons mu-:muons"
91  jpsi_cuts = [
92  "[2.8 < M < 3.3]",
93  "[daughterSumOf(charge) == 0]",
94  ]
95  jpsi_cut = " and ".join(jpsi_cuts)
96 
97  ma.reconstructDecay(jpsimumu, jpsi_cut, path=path)
98 
99  # Mode 2: calculate the track isolation variables
100  # on the selected muon daughters in the decay.
101  # This time, use the mass hypotheiss w/ highest probability for the track extrapolation.
102  trackiso_vars_highestprobmass = ma.calculateTrackIsolation("J/psi:mumu -> ^mu+ ^mu-",
103  path,
104  *args.detectors,
105  reference_list_name=ref,
106  highest_prob_mass_for_ext=True)
107 
108  variables_jpsi = vc.kinematics + ["daughterDiffOfPhi(0, 1)"]
109  variables_jpsi += vu.create_aliases(variables_jpsi, "useCMSFrame({variable})", "CMS")
110  variables_jpsi += vc.inv_mass
111  variables_mu = vc.kinematics + ["theta", "phi", "clusterE"] + trackiso_vars + trackiso_vars_highestprobmass + [
112  "inARICHAcceptance",
113  "inCDCAcceptance",
114  "inECLAcceptance",
115  "inKLMAcceptance",
116  "inTOPAcceptance",
117  "ptInBECLAcceptance",
118  "ptInBKLMAcceptance",
119  "ptInTOPAcceptance",
120  "thetaInARICHAcceptance",
121  "thetaInBECLAcceptance",
122  "thetaInBKLMAcceptance",
123  "thetaInCDCAcceptance",
124  "thetaInECLAcceptance",
125  "thetaInEECLAcceptance",
126  "thetaInEKLMAcceptance",
127  "thetaInKLMAcceptance",
128  "thetaInKLMOverlapAcceptance",
129  "thetaInTOPAcceptance"
130  ]
131 
132  aliases_jpsimumu = vu.create_aliases_for_selected(
133  variables_jpsi,
134  "^J/psi:mumu -> mu+:muons mu-:muons",
135  prefix=["jpsi"])
136 
137  aliases_mu = vu.create_aliases_for_selected(
138  variables_mu,
139  "J/psi:mumu -> ^mu+:muons ^mu-:muons",
140  use_names=True)
141 
142  variables.addAlias("nReferenceTracks", f"nCleanedTracks({base_trk_selection})")
143  aliases_event = ["nReferenceTracks"]
144 
145  variables.printAliases()
146 
147  # Saving variables to ntuple
148  ma.variablesToNtuple(decayString="J/psi:mumu",
149  variables=aliases_event+aliases_jpsimumu+aliases_mu,
150  treename="jpsimumu",
151  filename="TrackIsolationVariables.root",
152  path=path)
153 
154  # Optionally activate debug mode for the TrackIsoCalculator module(s).
155  if args.debug:
156  for m in path.modules():
157  if "TrackIsoCalculator" in m.name():
158  m.set_log_level(b2.LogLevel.DEBUG)
159  m.set_debug_level(args.debug)
160 
161  path.add_module("Progress")
162 
163  # Process the data.
164  b2.process(path)
165 
166  print(b2.statistics)
167 
168 # @endcond