12This steering file fills an NTuple with the ChargedPidMVA score
13for charged particle identification. By default, global PID info is stored,
14meaning one signal hypothesis is tested against all others.
15Optionally, binary PID can be stored, by testing one (or more) pair of (S,B) mass hypotheses.
19basf2 [-i /PATH/TO/MDST/FILE.root] analysis/examples/PostMdstIdentification/ChargedPidMVAModule.py -- [OPTIONS]
28from modularAnalysis
import getAnalysisGlobaltag
33 parser = argparse.ArgumentParser(description=__doc__,
34 formatter_class=argparse.RawTextHelpFormatter)
38 s, b =
map(int, arg.split(
','))
41 raise argparse.ArgumentTypeError(
"Option string must be of the form 'S,B'")
43 parser.add_argument(
"--matchTruth",
46 help=
"Apply truth-matching on particles.")
47 parser.add_argument(
"--testHyposPDGCodePair",
51 help=
"Option required in binary mode.\n"
52 "A list of pdgId pairs of the (S, B) charged stable particle mass hypotheses to test.\n"
53 "Pass a space-separated list of (>= 1) S,B pdgIds, e.g.:\n"
54 "'--testHyposPDGCodePair 11,211 13,211'")
55 parser.add_argument(
"--addECLOnly",
59 help=
"Apply the BDT also for the ECL-only training."
60 "This will result in a separate score branch in the ntuple.")
61 parser.add_argument(
"--chargeIndependent",
64 help=
"Use a BDT trained on a sample of inclusively charged particles.")
65 parser.add_argument(
"--global_tag_append",
68 default=[getAnalysisGlobaltag()],
69 help=
"List of names of conditions DB global tag(s) to append on top of GT replay.\n"
70 "NB: these GTs will have lowest priority over GT replay.\n"
71 "The order of the sequence passed determines the priority of the GTs, w/ the highest coming first.\n"
72 "Pass a space-separated list of names.")
73 parser.add_argument(
"--global_tag_prepend",
77 help=
"List of names of conditions DB global tag(s) to prepend to GT replay.\n"
78 "NB: these GTs will have highest priority over GT replay.\n"
79 "The order of the sequence passed determines the priority of the GTs, w/ the highest coming first.\n"
80 "Pass a space-separated list of names.")
81 parser.add_argument(
"--append_testing_payloads",
84 help=
"Path to a text file with local test payloads.\n"
85 "NB: these will have higher priority than any payload in the GT(s).\n"
86 "Use ONLY for testing.")
87 parser.add_argument(
"-d",
"--debug",
92 choices=list(range(11, 20)),
93 help=
"Run the ChargedPidMVA module in debug mode. Pass the desired DEBUG level integer.")
98if __name__ ==
'__main__':
100 args = argparser().parse_args()
103 import modularAnalysis
as ma
104 from ROOT
import Belle2
107 for tag
in args.global_tag_append:
108 basf2.conditions.append_globaltag(tag)
109 print(f
"Appending GTs:\n{args.global_tag_append}")
111 if args.global_tag_prepend:
112 for tag
in reversed(args.global_tag_prepend):
113 basf2.conditions.prepend_globaltag(tag)
114 print(f
"Prepending GTs:\n{args.global_tag_prepend}")
116 if args.append_testing_payloads:
117 basf2.conditions.append_testing_payloads(args.append_testing_payloads)
118 print(f
"Appending testing payloads (will have highest priority!)):\n{args.append_testing_payloads}")
124 path = basf2.create_path()
130 ma.inputMdst(filename=basf2.find_file(
"mdst16.root",
"validation"),
139 Belle2.Const.electron.getPDGCode(),
140 Belle2.Const.muon.getPDGCode(),
141 Belle2.Const.pion.getPDGCode(),
142 Belle2.Const.kaon.getPDGCode(),
143 Belle2.Const.proton.getPDGCode(),
144 Belle2.Const.deuteron.getPDGCode(),
147 plists = [(f
"{pdg.to_name(pdgId)}:my_{pdg.to_name(pdgId)}",
"")
for pdgId
in std_charged]
148 ma.fillParticleLists(plists, path=path)
155 for plistname, _
in plists:
156 ma.matchMCTruth(plistname, path=path)
157 ma.applyCuts(plistname,
"isSignal == 1", path=path)
163 global_pid = (args.testHyposPDGCodePair == (0, 0))
164 binary_pid =
not global_pid
171 ma.applyChargedPidMVA(particleLists=[plistname
for plistname, _
in plists],
173 trainingMode=Belle2.ChargedPidMVAWeights.ChargedPidMVATrainingMode.c_Multiclass,
174 chargeIndependent=args.chargeIndependent)
175 if args.add_ecl_only:
176 ma.applyChargedPidMVA(particleLists=[plistname
for plistname, _
in plists],
178 trainingMode=Belle2.ChargedPidMVAWeights.ChargedPidMVATrainingMode.c_ECL_Multiclass)
180 for s, b
in args.testHyposPDGCodePair:
181 ma.applyChargedPidMVA(particleLists=[plistname
for plistname, _
in plists],
183 trainingMode=Belle2.ChargedPidMVAWeights.ChargedPidMVATrainingMode.c_Classification,
184 binaryHypoPDGCodes=(s, b),
185 chargeIndependent=args.chargeIndependent)
186 if args.add_ecl_only:
187 ma.applyChargedPidMVA(particleLists=[plistname
for plistname, _
in plists],
189 trainingMode=Belle2.ChargedPidMVAWeights.ChargedPidMVATrainingMode.c_ECL_Classification,
190 binaryHypoPDGCodes=(s, b))
193 for m
in path.modules():
194 if "ChargedPidMVA" in m.name():
195 m.logging.log_level = basf2.LogLevel.DEBUG
196 m.logging.debug_level = args.debug
204 append =
"_vs_".join(
map(str, std_charged))
206 variables = [f
"pidChargedBDTScore({pdgId}, ALL)" for pdgId
in std_charged]
207 if args.add_ecl_only:
208 variables += [f
"pidChargedBDTScore({pdgId}, ECL)" for pdgId
in std_charged]
212 append =
"__".join([f
"{s}_vs_{b}" for s, b
in args.testHyposPDGCodePair])
214 variables = [f
"pidPairChargedBDTScore({s}, {b}, ALL)" for s, b
in args.testHyposPDGCodePair]
215 if args.add_ecl_only:
216 variables += [f
"pidPairChargedBDTScore({s}, {b}, ECL)" for s, b
in args.testHyposPDGCodePair]
218 filename = f
"chargedpid_ntuples__{append}.root"
220 for plistname, _
in plists:
223 treename = re.sub(
r"[\W]+",
"", plistname.split(
':')[1])
226 ma.variablesToNtuple(decayString=plistname,
232 ma.variablesToNtuple(decayString=plistname,
242 progress = basf2.register_module(
"Progress")
243 path.add_module(progress)