13 import ftPlotting
as plotting
18 from B2Tools
import b2latex, format
24 from ROOT
import Belle2
25 from flavorTagger
import KId, muId, eId
26 import flavorTagger
as ft
29 def getCommandLineOptions():
30 """ Parses the command line options of the fei and returns the corresponding arguments. """
31 parser = argparse.ArgumentParser()
32 parser.add_argument(
'-id',
'--identifiers', dest=
'identifiers', type=str, required=
True, action=
'append', nargs=
'+',
33 help=
'DB Identifier or weightfile')
34 parser.add_argument(
'-train',
'--train_datafiles', dest=
'train_datafiles', type=str, required=
False, action=
'append', nargs=
'+',
35 help=
'Data file containing ROOT TTree used during training')
36 parser.add_argument(
'-data',
'--datafiles', dest=
'datafiles', type=str, required=
True, action=
'append', nargs=
'+',
37 help=
'Data file containing ROOT TTree with independent test data')
38 parser.add_argument(
'-tree',
'--treename', dest=
'treename', type=str, default=
'tree', help=
'Treename in data file')
39 parser.add_argument(
'-out',
'--outputfile', dest=
'outputfile', type=str, default=
'output.pdf',
40 help=
'Name of the outputted pdf file')
41 parser.add_argument(
'-w',
'--working_directory', dest=
'working_directory', type=str, default=
'',
42 help=
"""Working directory where the created images and root files are stored,
43 default is to create a temporary directory.""")
44 parser.add_argument(
'-b2Orb',
'--BelleOrBelle2', dest=
'BelleOrBelle2', type=str, default=
'Belle2',
45 help=
"""Tell me if this is Belle or Belle2 MC please.""")
46 args = parser.parse_args()
52 Returns a list containing only unique elements, keeps the original order of the list
53 @param input list containing the elements
62 def create_abbreviations(names, length=5):
64 variablesPlotParamsDict = {
'useCMSFrame(p)': [
r'$p^*$',
r"{\rm GeV}/c\, "],
65 'useCMSFrame(pt)': [
r'$p_{\rm t}^*$',
r"{\rm GeV}/c\, "],
66 'p': [
r'$p$',
r"{\rm GeV}/c\, "],
67 'pt': [
r'$p_{\rm t}$',
r"{\rm GeV}/c\, "],
68 'pLambda': [
r'$p_{\Lambda}$',
r"{\rm GeV}/c\, "],
69 'useCMSFrame(p)Lambda': [
r'$p^*_{\Lambda}$',
r"{\rm GeV}/c\, "],
70 'useCMSFrame(p)FSC': [
r'$p^*_{\rm Slow}$',
r"{\rm GeV}/c\, "],
71 'cosTheta': [
r'$\cos{\theta}$',
""],
72 eId[args.BelleOrBelle2]: [
r'$\mathcal{L}_{e}$',
""],
73 'eid_dEdx': [
r'$\mathcal{L}_{e}^{{\rm d}E/{\rm d}x}$',
""],
74 'eid_TOP': [
r'$\mathcal{L}_{e}^{\rm TOP}$',
""],
75 'eid_ARICH': [
r'$\mathcal{L}_{e}^{\rm ARICH}$',
""],
76 'eid_ECL': [
r'$\mathcal{L}_{e}^{\rm ECL}$',
""],
77 'BtagToWBosonVariables(recoilMassSqrd)': [
r'$M_{\rm rec}^2$',
r"{\rm GeV}^2/c^4"],
78 'BtagToWBosonVariables(pMissCMS)': [
r'$p^*_{\rm miss}$',
r"{\rm GeV}/c\, "],
79 'BtagToWBosonVariables(cosThetaMissCMS)': [
r'$\cos{\theta^*_{\rm miss}}$',
""],
80 'BtagToWBosonVariables(EW90)': [
r'$E_{90}^{W}$',
r"{\rm GeV}\, "],
81 'BtagToWBosonVariables(recoilMass)': [
r'$M_{\rm rec}$',
r"{\rm GeV}/c^2\, "],
82 'cosTPTO': [
r'$\vert\cos{\theta^*_{\rm T}}\vert$',
""],
83 'cosTPTOFSC': [
r'$\vert\cos{\theta^*_{\rm T,Slow}}\vert$',
""],
84 'ImpactXY': [
r'$d_0$',
r"{\rm mm}\, "],
85 'distance': [
r'$\xi_0$',
r"{\rm mm}\, "],
86 'chiProb': [
r'$p$-${\rm value}$',
""],
87 muId[args.BelleOrBelle2]: [
r'$\mathcal{L}_{\mu}$',
""],
88 'muid_dEdx': [
r'$\mathcal{L}_{\mu}^{{\rm d}E/{\rm d}x}$',
""],
89 'muid_TOP': [
r'$\mathcal{L}_{\mu}^{\rm TOP}$',
""],
90 'muid_ARICH': [
r'$\mathcal{L}_{\mu}^{\rm ARICH}$',
""],
91 'muid_KLM': [
r'$\mathcal{L}_{\mu}^{\rm KLM}$',
""],
92 KId[args.BelleOrBelle2]: [
r'$\mathcal{L}_{K}$',
""],
93 'Kid_dEdx': [
r'$\mathcal{L}_{K}^{{\rm d}E/{\rm d}x}$',
""],
94 'Kid_TOP': [
r'$\mathcal{L}_{K}^{\rm TOP}$',
""],
95 'Kid_ARICH': [
r'$\mathcal{L}_{K}^{\rm ARICH}$',
""],
96 'NumberOfKShortsInRoe': [
r'$n_{K^0_S}$',
""],
97 'ptTracksRoe': [
r'$\Sigma\, p_{\rm t}^2$',
r"{\rm GeV^2}/c^2"],
98 'extraInfo(isRightCategory(Kaon))': [
r"$y_{\rm Kaon}$",
""],
99 'HighestProbInCat(pi+:inRoe, isRightCategory(SlowPion))': [
r"$y_{\rm SlowPion}$",
""],
100 'KaonPionVariables(cosKaonPion)': [
r'$\cos{\theta^*_{K\pi}}$',
""],
101 'KaonPionVariables(HaveOpositeCharges)': [
r'$\frac{1 - q_{K} \cdot q_\pi}{2}$',
""],
102 'pionID': [
r'$\mathcal{L}_{\pi}$',
""],
103 'piid_dEdx': [
r'$\mathcal{L}_{\pi}^{{\rm d}E/{\rm d}x}$',
""],
104 'piid_TOP': [
r'$\mathcal{L}_{\pi}^{\rm TOP}$',
""],
105 'piid_ARICH': [
r'$\mathcal{L}_{\pi}^{\rm ARICH}$',
""],
106 'pi_vs_edEdxid': [
r'$\mathcal{L}_{\pi/e}^{{\rm d}E/{\rm d}x}$',
""],
107 'FSCVariables(pFastCMS)': [
r'$p^*_{\rm Fast}$',
r"{\rm GeV}/c\, "],
108 'FSCVariables(cosSlowFast)': [
r'$\cos{\theta^*_{\rm SlowFast}}$',
''],
109 'FSCVariables(cosTPTOFast)': [
r'$\vert\cos{\theta^*_{\rm T, Fast}}\vert$',
''],
110 'FSCVariables(SlowFastHaveOpositeCharges)': [
r'$\frac{1 - q_{\rm Slow} \cdot q_{\rm Fast}}{2}$',
""],
111 'lambdaFlavor': [
r'$q_{\Lambda}$',
""],
112 'M': [
r'$M_{\Lambda}$',
r"{\rm MeV}/c^2\, "],
113 'cosAngleBetweenMomentumAndVertexVector': [
114 r'$\cos{\theta_{\boldsymbol{x}_{\Lambda},\boldsymbol{p}_{\Lambda}}}$',
""],
115 'lambdaZError': [
r'$\sigma_{\Lambda}^{zz}$',
r"{\rm mm}\, "],
116 'daughter(0,p)': [
r'$p_{\pi}$',
r"{\rm GeV}/c\, "],
117 'daughter(0,useCMSFrame(p))': [
r'$p^*_{\pi}$',
r"{\rm GeV}/c\, "],
118 'daughter(1,p)': [
r'$p_{p}$',
r"{\rm GeV}/c"],
119 'daughter(1,useCMSFrame(p))': [
r'$p^*_{p}$',
r"{\rm GeV}/c\, "],
120 'daughter(1,protonID)': [
r'$\mathcal{L}_{p}$',
""],
121 'daughter(0,pionID)': [
r'$\mathcal{L}_{\pi}$',
""],
122 'QpOf(mu+:inRoe, isRightCategory(IntermediateMuon), isRightCategory(IntermediateMuon))': [
123 r'${\rm Int.\ Muon}$'],
124 'QpOf(mu+:inRoe, isRightCategory(Muon), isRightCategory(Muon))': [
r'${\rm Muon}$'],
125 'QpOf(pi+:inRoe, isRightCategory(FSC), isRightCategory(SlowPion))': [
r'${\rm FSC}$'],
126 'QpOf(e+:inRoe, isRightCategory(Electron), isRightCategory(Electron))': [
r'${\rm Electron}$'],
127 'QpOf(e+:inRoe, isRightCategory(IntermediateElectron), isRightCategory(IntermediateElectron))': [
128 r'${\rm Int.\ El.}$'],
129 'weightedQpOf(Lambda0:inRoe, isRightCategory(Lambda), isRightCategory(Lambda))': [
r'${\rm Lambda}$'],
130 'QpOf(K+:inRoe, isRightCategory(KaonPion), isRightCategory(Kaon))': [
r'${\rm Kaon}$' +
'-' +
r'${\rm Pion}$'],
131 'QpOf(pi+:inRoe, isRightCategory(FastHadron), isRightCategory(FastHadron))': [
r'${\rm Fast\ Hadron}$'],
132 'QpOf(mu+:inRoe, isRightCategory(IntermediateKinLepton), isRightCategory(IntermediateKinLepton))': [
133 r'${\rm Int.\ Kin.\ Lep.}$'],
134 'QpOf(pi+:inRoe, isRightCategory(MaximumPstar), isRightCategory(MaximumPstar))': [
r'${\rm Max.}\,p^*$'],
135 'QpOf(pi+:inRoe, isRightCategory(SlowPion), isRightCategory(SlowPion))': [
r'${\rm Slow\ Pion}$'],
136 'QpOf(mu+:inRoe, isRightCategory(KinLepton), isRightCategory(KinLepton))': [
r'${\rm Kin.\ Lep.}$'],
137 'weightedQpOf(K+:inRoe, isRightCategory(Kaon), isRightCategory(Kaon))': [
r'${\rm Kaon}$']}
139 if sum(args.identifiers, [])[0].find(
'LevelLambdaFBDT') != -1:
140 variablesPlotParamsDict[
'distance'] = [
r'$\vert \boldsymbol{x}_{\Lambda}\vert$',
r"{\rm mm}\, "]
146 if name
in variablesPlotParamsDict:
147 abbreviation = variablesPlotParamsDict[name][0]
149 abbreviation = name[:length]
151 if abbreviation
not in count:
152 count[abbreviation] = 0
153 count[abbreviation] += 1
154 abbreviations = collections.OrderedDict()
159 if name
in variablesPlotParamsDict:
160 abbreviation = variablesPlotParamsDict[name][0]
162 abbreviation = name[:length]
164 abbreviations[name] = abbreviation
165 if count[abbreviation] > 1:
166 if abbreviation
not in count2:
167 count2[abbreviation] = 0
168 count2[abbreviation] += 1
169 abbreviations[name] += str(count2[abbreviation])
173 if __name__ ==
'__main__':
175 ROOT.gROOT.SetBatch(
True)
177 old_cwd = os.getcwd()
178 args = getCommandLineOptions()
180 identifiers = sum(args.identifiers, [])
181 identifier_abbreviations = create_abbreviations(identifiers)
183 datafiles = sum(args.datafiles, [])
185 print(
"Load methods")
188 print(
"Apply experts on independent data")
189 test_probability = {}
191 for method
in methods:
192 p, t = method.apply_expert(datafiles, args.treename)
193 test_probability[identifier_abbreviations[method.identifier]] = p
194 test_target[identifier_abbreviations[method.identifier]] = t
196 print(
"Apply experts on training data")
197 train_probability = {}
199 if args.train_datafiles
is not None:
200 train_datafiles = sum(args.train_datafiles, [])
201 for method
in methods:
202 p, t = method.apply_expert(train_datafiles, args.treename)
203 train_probability[identifier_abbreviations[method.identifier]] = p
204 train_target[identifier_abbreviations[method.identifier]] = t
206 variables = unique(v
for method
in methods
for v
in method.variables)
207 root_variables = unique(v
for method
in methods
for v
in method.root_variables)
209 print(
"Here Variables")
213 displayHeatMap =
False
214 classOutputLabel =
r'${\rm Classifier\ Output}$'
217 if identifiers[0].find(
'Combiner') != -1
or identifiers[0].find(
'KaonFBDT') != -1
or \
218 identifiers[0].find(
'Electron') != -1
or identifiers[0].find(
'Muon') != -1
or \
219 identifiers[0].find(
'Lepton') != -1
or \
220 identifiers[0].find(
'SlowPion') != -1
or identifiers[0].find(
'FastHadron') != -1
or \
221 identifiers[0].find(
'KaonPion') != -1
or identifiers[0].find(
'FSC') != -1
or \
222 identifiers[0].find(
'MaximumPstar') != -1
or identifiers[0].find(
'Lambda') != -1:
224 if identifiers[0].find(
'Combiner') != -1:
225 displayHeatMap =
True
229 'weightedQpOf(Lambda0:inRoe, isRightCategory(Lambda), isRightCategory(Lambda))',
230 'QpOf(pi+:inRoe, isRightCategory(FastHadron), isRightCategory(FastHadron))',
231 'QpOf(pi+:inRoe, isRightCategory(MaximumPstar), isRightCategory(MaximumPstar))',
232 'QpOf(pi+:inRoe, isRightCategory(FSC), isRightCategory(SlowPion))',
233 'QpOf(pi+:inRoe, isRightCategory(SlowPion), isRightCategory(SlowPion))',
234 'QpOf(K+:inRoe, isRightCategory(KaonPion), isRightCategory(Kaon))',
235 'weightedQpOf(K+:inRoe, isRightCategory(Kaon), isRightCategory(Kaon))',
236 'QpOf(mu+:inRoe, isRightCategory(IntermediateKinLepton), isRightCategory(IntermediateKinLepton))',
237 'QpOf(mu+:inRoe, isRightCategory(KinLepton), isRightCategory(KinLepton))',
238 'QpOf(mu+:inRoe, isRightCategory(IntermediateMuon), isRightCategory(IntermediateMuon))',
239 'QpOf(mu+:inRoe, isRightCategory(Muon), isRightCategory(Muon))',
240 'QpOf(e+:inRoe, isRightCategory(IntermediateElectron), isRightCategory(IntermediateElectron))',
241 'QpOf(e+:inRoe, isRightCategory(Electron), isRightCategory(Electron))'
243 variables = list(reversed(variables))
245 if identifiers[0].find(
'Electron') != -1:
246 if identifiers[0].find(
'Intermediate') != -1:
247 variables = ft.getTrainingVariables(
'IntermediateElectron')
249 variables = ft.getTrainingVariables(
'Electron')
251 if identifiers[0].find(
'Muon') != -1:
252 if identifiers[0].find(
'Intermediate') != -1:
253 variables = ft.getTrainingVariables(
'IntermediateMuon')
255 variables = ft.getTrainingVariables(
'Muon')
257 if identifiers[0].find(
'Lepton') != -1:
258 if identifiers[0].find(
'Intermediate') != -1:
259 variables = ft.getTrainingVariables(
'IntermediateKinLepton')
261 variables = ft.getTrainingVariables(
'KinLepton')
263 if identifiers[0].find(
'KaonFBDT') != -1:
264 displayHeatMap =
True
265 variables = ft.getTrainingVariables(
'Kaon')
267 if identifiers[0].find(
'SlowPion') != -1:
268 variables = ft.getTrainingVariables(
'SlowPion')
270 if identifiers[0].find(
'FastHadron') != -1:
271 variables = ft.getTrainingVariables(
'FastHadron')
273 if identifiers[0].find(
'KaonPion') != -1:
274 variables = ft.getTrainingVariables(
'KaonPion')
276 if identifiers[0].find(
'FSC') != -1:
277 variables = ft.getTrainingVariables(
'FSC')
279 if identifiers[0].find(
'MaximumPstar') != -1:
280 variables = ft.getTrainingVariables(
'MaximumPstar')
282 if identifiers[0].find(
'Lambda') != -1:
283 displayHeatMap =
True
284 variables = ft.getTrainingVariables(
'Lambda')
286 variables = list(reversed(variables))
287 for iVarPosition
in range(len(variables)):
291 if identifiers[0].find(
'FSC') != -1:
292 variables = [
'useCMSFrame(p)FSC' if v ==
'useCMSFrame(p)' else v
for v
in variables]
294 if identifiers[0].find(
'Lambda') != -1:
295 displayHeatMap =
True
296 variables = [
'useCMSFrame(p)Lambda' if v ==
'useCMSFrame(p)' else v
for v
in variables]
298 if identifiers[0].find(
'Combiner') != -1:
299 if identifiers[0].find(
'FANN') != -1:
300 classOutputLabel =
r'$(q\cdot r)_{\rm MLP}$'
302 if identifiers[0].find(
'FBDT') != -1:
303 classOutputLabel =
r'$(q\cdot r)_{\rm FBDT}$'
304 elif identifiers[0].find(
'LevelMaximumPstar') != -1:
305 classOutputLabel =
r'$y_{{\rm Maximum}\, p^*}$'
306 elif identifiers[0].find(
'LevelFSCFBDT') != -1:
307 classOutputLabel =
r'$y_{\rm FSC}$'
308 elif identifiers[0].find(
'LevelMuonFBDT') != -1:
309 classOutputLabel =
r'$y_{\rm Muon}$'
310 elif identifiers[0].find(
'LevelElectronFBDT') != -1:
311 classOutputLabel =
r'$y_{\rm Electron}$'
312 elif identifiers[0].find(
'LevelKaonFBDT') != -1:
313 classOutputLabel =
r'$y_{\rm Kaon}$'
314 elif identifiers[0].find(
'LevelLambdaFBDT') != -1:
315 classOutputLabel =
r'$y_{\rm Lambda}$'
316 elif identifiers[0].find(
'LevelIntermediateKinLeptonFBDT') != -1:
317 classOutputLabel =
r'$y_{\rm Int.\, Kin.\, Lepton}$'
318 elif identifiers[0].find(
'LevelKinLeptonFBDT') != -1:
319 classOutputLabel =
r'$y_{\rm Kin.\, Lepton}$'
320 elif identifiers[0].find(
'LevelIntermediateMuon') != -1:
321 classOutputLabel =
r'$y_{\rm Int.\, Muon}$'
322 elif identifiers[0].find(
'LevelIntermediateElectron') != -1:
323 classOutputLabel =
r'$y_{\rm Int.\, Electron}$'
324 elif identifiers[0].find(
'LevelKaonPionFBDT') != -1:
325 classOutputLabel =
r'$y_{\rm Kaon-Pion}$'
326 elif identifiers[0].find(
'LevelFastHadron') != -1:
327 classOutputLabel =
r'$y_{\rm Fast\, Hadron}$'
328 elif identifiers[0].find(
'LevelSlowPion') != -1:
329 classOutputLabel =
r'$y_{\rm Slow\, Pion}$'
331 variable_abbreviations = create_abbreviations(variables)
333 spectators = unique(v
for method
in methods
for v
in method.spectators)
334 spectator_abbreviations = create_abbreviations(spectators)
335 root_spectators = unique(v
for method
in methods
for v
in method.root_spectators)
337 print(
"Load variables array")
338 rootchain = ROOT.TChain(args.treename)
339 for datafile
in datafiles:
340 rootchain.Add(datafile)
342 variables_data = basf2_mva_util.tree2dict(rootchain, root_variables, list(variable_abbreviations.values()))
343 spectators_data = basf2_mva_util.tree2dict(rootchain, root_spectators, list(spectator_abbreviations.values()))
345 print(
"Create latex file")
348 with tempfile.TemporaryDirectory()
as tempdir:
349 if args.working_directory ==
'':
352 os.chdir(args.working_directory)
354 o = b2latex.LatexFile()
355 o += b2latex.TitlePage(title=
'Automatic MVA Evaluation',
356 authors=[
r'Thomas Keck\\ Moritz Gelb\\ Nils Braun'],
357 abstract=
'Evaluation plots',
358 add_table_of_contents=
True).finish()
360 o += b2latex.Section(
"Classifiers")
361 o += b2latex.String(
r"""
362 This section contains the GeneralOptions and SpecificOptions of all classifiers represented by an XML tree.
363 The same information can be retrieved using the basf2\_mva\_info tool.
366 table = b2latex.LongTable(
r"ll",
"Abbreviations of identifiers",
"{name} & {abbr}",
r"Identifier & Abbreviation")
367 for identifier
in identifiers:
368 table.add(name=format.string(identifier), abbr=format.string(identifier_abbreviations[identifier]))
375 o += b2latex.Section(
"Variables")
376 o += b2latex.String(
"""
377 This section contains an overview of the importance and correlation of the variables used by the classifiers.
378 And distribution plots of the variables on the independent dataset. The distributions are normed for signal and
379 background separately, and only the region +- 3 sigma around the mean is shown.
382 table = b2latex.LongTable(
r"ll",
"Abbreviations of variables",
"{name} & {abbr}",
r"Variable & Abbreviation")
385 table.add(name=format.string(v), abbr=variable_abbreviations[v])
388 o += b2latex.SubSection(
"Importance")
389 graphics = b2latex.Graphics()
391 p.add({identifier_abbreviations[i.identifier]: np.array([i.importances.get(v, 0.0)
for v
in variables])
for i
in methods},
392 identifier_abbreviations.values(), variable_abbreviations.values(), displayHeatMap)
394 p.save(
'importance.pdf')
395 graphics.add(
'importance.pdf', width=1.0)
396 o += graphics.finish()
398 o += b2latex.SubSection(
"Correlation")
399 first_identifier_abbr = list(identifier_abbreviations.values())[0]
400 graphics = b2latex.Graphics()
402 p.add(variables_data, variable_abbreviations.values(),
403 test_target[first_identifier_abbr] == 1,
404 test_target[first_identifier_abbr] == bkgrOutput, bkgrOutput)
406 p.save(
'correlation_plot.pdf')
407 graphics.add(
'correlation_plot.pdf', width=1.0)
408 o += graphics.finish()
411 graphics = b2latex.Graphics()
413 p.add(variables_data, variable_abbreviations.values(),
414 test_target[first_identifier_abbr] == 1,
415 test_target[first_identifier_abbr] == bkgrOutput)
417 p.save(
'tsne_plot.pdf')
418 graphics.add(
'tsne_plot.pdf', width=1.0)
419 o += graphics.finish()
433 o += b2latex.Section(
"Classifier Plot")
434 o += b2latex.String(
"This section contains the receiver operating characteristics (ROC), purity projection, ..."
435 "of the classifiers on training and independent data."
436 "The legend of each plot contains the shortened identifier and the area under the ROC curve"
439 o += b2latex.Section(
"ROC Plot")
440 graphics = b2latex.Graphics()
442 for identifier
in identifier_abbreviations.values():
443 auc = p.add(test_probability, identifier, test_target[identifier] == 1, test_target[identifier] == bkgrOutput)
444 o += b2latex.String(
"This is the Area under the ROC " +
" ({:.2f})".format(auc) +
".")
445 f = open(
"AUCROCTest.txt",
"w")
446 f.write(
"{:.6f}".format(auc))
450 p.save(
'roc_plot_test.pdf')
451 graphics.add(
'roc_plot_test.pdf', width=1.0)
452 o += graphics.finish()
454 if train_probability:
455 for i, identifier
in enumerate(identifiers):
456 graphics = b2latex.Graphics()
458 identifier_abbr = identifier_abbreviations[identifier]
459 aucTrain = p.add(train_probability, identifier_abbr, train_target[identifier_abbr] == 1,
460 train_target[identifier_abbr] == bkgrOutput, label=
r'{\rm Train}')
461 o += b2latex.String(
"This is the Area under the train ROC " +
" ({:.2f})".format(aucTrain) +
". ")
462 f = open(
"AUCROCTrain.txt",
"w")
463 f.write(
"{:.6f}".format(auc))
465 aucTest = p.add(test_probability, identifier_abbr, test_target[identifier_abbr] == 1,
466 test_target[identifier_abbr] == bkgrOutput, label=
r'{\rm Test}')
467 o += b2latex.String(
"This is the Area under the test ROC " +
" ({:.2f})".format(aucTest) +
".")
470 p.save(
'roc_test.pdf')
471 graphics.add(
'roc_test.pdf', width=1.0)
472 o += graphics.finish()
474 o += b2latex.Section(
"Classification Results")
476 for identifier
in identifiers:
477 identifier_abbr = identifier_abbreviations[identifier]
478 o += b2latex.SubSection(format.string(identifier_abbr))
479 graphics = b2latex.Graphics()
481 p.add(0, test_probability, identifier_abbr, test_target[identifier_abbr] == 1,
482 test_target[identifier_abbr] == bkgrOutput, normed=
True)
483 p.sub_plots[0].axis.set_title(
"Classification result in test data ")
485 p.add(1, test_probability, identifier_abbr, test_target[identifier_abbr] == 1,
486 test_target[identifier_abbr] == bkgrOutput, normed=
False)
487 p.sub_plots[1].axis.set_title(
"Classification result in test data ")
490 p.save(
'classification_result.pdf')
491 graphics.add(
'classification_result.pdf', width=1)
492 o += graphics.finish()
494 o += b2latex.Section(
"Diagonal Plot")
495 graphics = b2latex.Graphics()
497 for identifier
in identifiers:
498 o += b2latex.SubSection(format.string(identifier_abbr))
499 identifier_abbr = identifier_abbreviations[identifier]
500 p.add(test_probability, identifier_abbr, test_target[identifier_abbr] == 1, test_target[identifier_abbr] == bkgrOutput)
502 p.axis.set_title(
"Diagonal plot on independent data")
503 p.save(
'diagonal_plot_test.pdf')
504 graphics.add(
'diagonal_plot_test.pdf', width=1.0)
505 o += graphics.finish()
507 if train_probability:
508 o += b2latex.SubSection(
"Overtraining Plot")
509 for identifier
in identifiers:
510 identifier_abbr = identifier_abbreviations[identifier]
511 probability = {identifier_abbr: np.r_[train_probability[identifier_abbr], test_probability[identifier_abbr]]}
512 target = np.r_[train_target[identifier_abbr], test_target[identifier_abbr]]
513 train_mask = np.r_[np.ones(len(train_target[identifier_abbr])), np.zeros(len(test_target[identifier_abbr]))]
514 graphics = b2latex.Graphics()
516 p.add(probability, identifier_abbr,
517 train_mask == 1, train_mask == 0,
518 target == 1, target == bkgrOutput,
None, bkgrOutput, isNN)
519 p.finish(xLabel=classOutputLabel)
521 p.save(
'overtraining_plot.pdf')
522 graphics.add(
'overtraining_plot.pdf', width=1.0)
523 o += graphics.finish()
524 print(
"Finished Overtraining plot")
526 o += b2latex.Section(
"Spectators")
527 o += b2latex.String(
"This section contains the distribution and dependence on the"
528 "classifier outputs of all spectator variables.")
530 table = b2latex.LongTable(
r"ll",
"Abbreviations of spectators",
"{name} & {abbr}",
r"Spectator & Abbreviation")
532 table.add(name=format.string(s), abbr=format.string(spectator_abbreviations[s]))
535 for spectator
in spectators:
536 spectator_abbr = spectator_abbreviations[spectator]
537 o += b2latex.SubSection(format.string(spectator))
538 graphics = b2latex.Graphics()
540 p.add(spectators_data, spectator_abbr, test_target[first_identifier_abbr] == 1, label=
"Signal")
541 p.add(spectators_data, spectator_abbr, test_target[first_identifier_abbr] == bkgrOutput, label=
"Background")
543 p.save(
'spectator_{}.pdf'.format(hash(spectator)))
544 graphics.add(
'spectator_{}.pdf'.format(hash(spectator)), width=1.0)
545 o += graphics.finish()
547 for identifier
in identifiers:
548 o += b2latex.SubSubSection(format.string(spectator) +
" with classifier " + format.string(identifier))
549 identifier_abbr = identifier_abbreviations[identifier]
550 data = {identifier_abbr: test_probability[identifier_abbr], spectator_abbr: spectators_data[spectator_abbr]}
551 graphics = b2latex.Graphics()
553 p.add(data, spectator_abbr, identifier_abbr, list(range(10, 100, 10)),
554 test_target[identifier_abbr] == 1,
555 test_target[identifier_abbr] == bkgrOutput)
557 p.save(
'correlation_plot_{}_{}.pdf'.format(hash(spectator), hash(identifier)))
558 graphics.add(
'correlation_plot_{}_{}.pdf'.format(hash(spectator), hash(identifier)), width=1.0)
559 o += graphics.finish()
561 o.save(
'latex.tex', compile=
True)
563 if args.working_directory ==
'':
564 shutil.copy(tempdir +
'/latex.pdf', args.outputfile)
566 shutil.copy(args.working_directory +
'/latex.pdf', args.outputfile)
static std::string makeROOTCompatible(std::string str)
Remove special characters that ROOT dislikes in branch names, e.g.