7 This steering file fills an NTuple with the ChargedPidMVA score
8 for charged particle identification. By default, global PID info is stored,
9 meaning one signal hypothesis is tested against all others.
10 Optionally, binary PID can be stored, by testing one (or more) pair of (S,B) mass hypotheses.
14 basf2 -i /PATH/TO/MDST/FILE.root analysis/examples/PostMdstIdentification/ChargedPidMVAModule.py -- [OPTIONS]
19 Example steering file - 2019 Belle II Collaboration.
22 __author__ =
"Marco Milesi"
23 __email__ =
"marco.milesi@unimelb.edu.au"
27 from modularAnalysis
import getAnalysisGlobaltag
32 parser = argparse.ArgumentParser(description=__doc__,
33 formatter_class=argparse.RawDescriptionHelpFormatter)
37 s, b = map(int, arg.split(
','))
40 raise argparse.ArgumentTypeError(
"Option string must be of the form 'S,B'")
42 parser.add_argument(
"--matchTruth",
45 help=
"Apply truth-matching on particles.")
46 parser.add_argument(
"--testHyposPDGCodePair",
50 help=
"Option required in binary mode."
51 "A list of pdgId pairs of the (S, B) charged stable particle mass hypotheses to test."
52 "Pass a space-separated list of (>= 1) S,B pdgIds, e.g.:"
53 "'--testHyposPDGCodePair 11,211 13,211'")
54 parser.add_argument(
"--addECLOnly",
58 help=
"Apply the BDT also for the ECL-only training."
59 "This will result in a separate score branch in the ntuple.")
60 parser.add_argument(
"--global_tag_append",
63 default=[getAnalysisGlobaltag()],
64 help=
"List of names of conditions DB global tag(s) to append on top of GT replay."
65 "NB: these GTs will have lowest priority."
66 "Pass a space-separated list of names.")
67 parser.add_argument(
"-d",
"--debug",
72 choices=list(range(11, 20)),
73 help=
"Run the ChargedPidMVA module in debug mode. Pass the desired DEBUG level integer.")
78 if __name__ ==
'__main__':
80 args = argparser().parse_args()
83 from modularAnalysis
import inputMdst, fillParticleLists, variablesToNtuple, matchMCTruth, applyCuts, applyChargedPidMVA
84 from variables
import variables
85 from ROOT
import Belle2
87 for tag
in args.global_tag_append:
88 basf2.conditions.append_globaltag(tag)
89 print(f
"Appending GTs:\n{args.global_tag_append}")
95 path = basf2.create_path()
101 inputMdst(environmentType=
"default",
102 filename=basf2.find_file(
"mdst13.root",
"validation"),
111 Belle2.Const.electron.getPDGCode(): {
"EVTGEN_ID":
"e+",
"NAME":
"e",
"FULLNAME":
"electron",
"CUT":
""},
112 Belle2.Const.muon.getPDGCode(): {
"EVTGEN_ID":
"mu+",
"NAME":
"mu",
"FULLNAME":
"muon",
"CUT":
""},
113 Belle2.Const.pion.getPDGCode(): {
"EVTGEN_ID":
"pi+",
"NAME":
"pi",
"FULLNAME":
"pion",
"CUT":
""},
114 Belle2.Const.kaon.getPDGCode(): {
"EVTGEN_ID":
"K+",
"NAME":
"K",
"FULLNAME":
"kaon",
"CUT":
""},
115 Belle2.Const.proton.getPDGCode(): {
"EVTGEN_ID":
"p+",
"NAME":
"p",
"FULLNAME":
"proton",
"CUT":
""},
116 Belle2.Const.deuteron.getPDGCode(): {
"EVTGEN_ID":
"deuteron",
"NAME":
"d",
"FULLNAME":
"deuteron",
"CUT":
""},
119 plists = [(f
"{d.get('EVTGEN_ID')}:{d.get('FULLNAME')}s", d.get(
"CUT"))
for d
in std_charged.values()]
121 fillParticleLists(plists, path=path)
128 for plistname, _
in plists:
129 matchMCTruth(plistname, path=path)
130 applyCuts(plistname,
"isSignal == 1", path=path)
136 global_pid = (args.testHyposPDGCodePair == (0, 0))
137 binary_pid =
not global_pid
143 variables.addAlias(
"__event__",
"evtNum")
144 for det
in [
"SVD",
"CDC",
"TOP",
"ARICH",
"ECL",
"KLM"]:
146 for pdgId, d
in std_charged.items():
147 variables.addAlias(f
"{d.get('FULLNAME')}LogL_{det}", f
"pidLogLikelihoodValueExpert({pdgId}, {det})")
149 for s, b
in args.testHyposPDGCodePair:
150 s_name = std_charged.get(s).get(
"NAME")
151 b_name = std_charged.get(b).get(
"NAME")
152 variables.addAlias(f
"deltaLogL_{s_name}_{b_name}_{det}", f
"pidDeltaLogLikelihoodValueExpert({s}, {b}, {det})")
159 applyChargedPidMVA(particleLists=[plistname
for plistname, _
in plists],
161 trainingMode=Belle2.ChargedPidMVAWeights.ChargedPidMVATrainingMode.c_Multiclass)
162 if args.add_ecl_only:
163 applyChargedPidMVA(particleLists=[plistname
for plistname, _
in plists],
165 trainingMode=Belle2.ChargedPidMVAWeights.ChargedPidMVATrainingMode.c_ECL_Multiclass)
167 for s, b
in args.testHyposPDGCodePair:
168 applyChargedPidMVA(particleLists=[plistname
for plistname, _
in plists],
170 trainingMode=Belle2.ChargedPidMVAWeights.ChargedPidMVATrainingMode.c_Classification,
171 binaryHypoPDGCodes=(s, b))
172 if args.add_ecl_only:
173 applyChargedPidMVA(particleLists=[plistname
for plistname, _
in plists],
175 trainingMode=Belle2.ChargedPidMVAWeights.ChargedPidMVATrainingMode.c_ECL_Classification,
176 binaryHypoPDGCodes=(s, b))
179 for m
in path.modules():
180 if "ChargedPidMVA" in m.name():
181 m.logging.log_level = basf2.LogLevel.DEBUG
182 m.logging.debug_level = args.debug
190 append =
"_vs_".join(map(str, std_charged.keys()))
192 variables = [f
"pidChargedBDTScore({pdgId}, ALL)" for pdgId
in std_charged]
193 if args.add_ecl_only:
194 variables += [f
"pidChargedBDTScore({pdgId}, ECL)" for pdgId
in std_charged]
198 append =
"__".join([f
"{s}_vs_{b}" for s, b
in args.testHyposPDGCodePair])
200 variables = [f
"pidPairChargedBDTScore({s}, {b}, ALL)" for s, b
in args.testHyposPDGCodePair]
201 if args.add_ecl_only:
202 variables += [f
"pidPairChargedBDTScore({s}, {b}, ECL)" for s, b
in args.testHyposPDGCodePair]
204 filename = f
"chargedpid_ntuples__{append}.root"
206 for plistname, _
in plists:
210 treename=plistname.split(
':')[1],
216 treename=plistname.split(
':')[1],
224 progress = basf2.register_module(
"Progress")
225 path.add_module(progress)
235 print(basf2.statistics)