29 from matplotlib.ticker
import FormatStrFormatter
30 import matplotlib.pyplot
as plt
32 from ROOT
import Belle2
35 import flavorTagger
as ft
36 from inputVariablesPlots
import variablesPlotParamsDict, categories
39 import matplotlib
as mpl
41 mpl.rcParams.update({
'font.size': 22})
42 mpl.rcParams[
'text.usetex'] =
True
43 mpl.rcParams[
'text.latex.preamble'] = [
r"\usepackage{amsmath}"]
46 if len(sys.argv) != 5:
47 sys.exit(
"Must provide 4 arguments: [Belle or Belle2] [BGx0 or BGx1] [training] [workingDirectory]"
50 belleOrBelle2 = sys.argv[1]
51 MCtype = str(sys.argv[2])
52 decayChannelTrainedOn = str(sys.argv[3])
53 workingDirectory = sys.argv[4]
55 filesDirectory = workingDirectory +
'/FlavorTagging/TrainedMethods'
57 if decayChannelTrainedOn ==
'JPsiKs':
58 decayChannelTrainedOn =
'JpsiKs_mu'
60 weightFiles =
'B2' + decayChannelTrainedOn + MCtype
62 ROOT.TH1.SetDefaultSumw2()
64 allInputVariables = []
66 belleOrBelle2Flag = belleOrBelle2
68 identifiersExtraInfosDict = dict()
69 identifiersExtraInfosKaonPion = []
78 if belleOrBelle2 ==
"Belle":
84 particleConditions = {
'e+:inRoe': [
'e',
" mcPDG > 0 ",
" mcPDG < 0 "],
'mu+:inRoe': [
r'\mu',
" mcPDG > 0 ",
" mcPDG < 0 "],
85 'lepton+:inRoe': [
'l',
" mcPDG > 0 ",
" mcPDG < 0 "],
86 'K+:inRoe': [
'K',
" mcPDG < 0 ",
" mcPDG > 0 "],
'pi+:inRoe': [
r'\pi',
" mcPDG < 0 ",
" mcPDG > 0 "],
87 'h+:inRoe': [
'h',
" mcPDG < 0 ",
" mcPDG > 0 "],
'Lambda0:inRoe': [
r'\Lambda',
" mcPDG < 0 ",
" mcPDG > 0 "]}
90 if not b2.find_file(
'AsymmetriesInVariablesPlots', silent=
True):
91 os.mkdir(
'./AsymmetriesInVariablesPlots')
94 for (particleList, category, _)
in ft.getEventLevelParticleLists(categories):
99 if not b2.find_file(
'AsymmetriesInVariablesPlots/' + category, silent=
True):
100 os.mkdir(
'./AsymmetriesInVariablesPlots/' + category)
102 if particleList
not in identifiersExtraInfosDict
and category !=
'KaonPion':
103 identifiersExtraInfosDict[particleList] = []
105 methodPrefixEventLevel =
"FlavorTagger_" + belleOrBelle2Flag +
"_" + weightFiles +
'EventLevel' + category +
'FBDT'
106 treeName = methodPrefixEventLevel +
"_tree"
107 targetVariable =
'isRightCategory(' + category +
')'
109 tree = ROOT.TChain(treeName)
111 workingFiles = glob.glob(filesDirectory +
'/' + methodPrefixEventLevel +
'sampled*.root')
114 for iFile
in workingFiles:
117 categoryInputVariables = []
118 trulyUsedInputVariables = []
119 for iVariable
in tree.GetListOfBranches():
123 if managerVariableName
in ft.getTrainingVariables(category)
or managerVariableName ==
'distance' or\
124 managerVariableName ==
'z0' or managerVariableName ==
'ImpactXY' or\
125 managerVariableName ==
'y' or managerVariableName ==
'OBoost':
126 if managerVariableName
in categoryInputVariables:
129 categoryInputVariables.append(managerVariableName)
130 if managerVariableName
in ft.getTrainingVariables(category):
131 allInputVariables.append((category, managerVariableName))
132 trulyUsedInputVariables.append((category, managerVariableName))
134 if managerVariableName
not in identifiersExtraInfosDict[particleList]
and category !=
'KaonPion':
135 identifiersExtraInfosDict[particleList].append(managerVariableName)
137 elif category ==
'KaonPion' and managerVariableName
not in identifiersExtraInfosKaonPion:
138 identifiersExtraInfosKaonPion.append(managerVariableName)
140 print(
"The number of variables used in " + category +
" is = ", len(trulyUsedInputVariables))
142 if category !=
'KaonPion' and category !=
'FSC' and category !=
'MaximumPstar' and\
143 category !=
'FastHadron' and category !=
'Lambda':
144 categoryInputVariables.append(
'BtagToWBosonVariables(recoilMass)')
146 for inputVariable
in categoryInputVariables:
153 nBins = variablesPlotParamsDict[inputVariable][1]
154 limXmin = variablesPlotParamsDict[inputVariable][2]
155 limXmax = variablesPlotParamsDict[inputVariable][3]
157 if belleOrBelle2 ==
"Belle2":
158 if inputVariable ==
'distance':
161 if inputVariable ==
'ImpactXY':
164 if category ==
"SlowPion":
165 if inputVariable ==
'p' or inputVariable ==
'useCMSFrame(p)' or\
166 inputVariable ==
'pt' or inputVariable ==
'useCMSFrame(pt)':
170 if inputVariable ==
'distance':
174 if inputVariable ==
'ImpactXY':
178 if category ==
"Lambda":
179 if inputVariable ==
'distance':
183 if inputVariable ==
'chiProb':
186 additionalCond = str()
188 if category ==
"FastHadron":
189 particleList =
'h+:inRoe'
191 if category ==
"KinLepton" or category ==
"IntermediateKinLepton":
192 particleList =
'lepton+:inRoe'
203 factorMultiplication = str()
205 if belleOrBelle2 ==
"Belle2" and ((category !=
"Lambda" and inputVariable ==
'distance')
or inputVariable ==
206 'z0' or inputVariable ==
'ImpactXY' or inputVariable ==
'y' or inputVariable ==
'OBoost'):
207 factorMultiplication =
"*10 "
209 tree.Draw(variablesPlotParamsDict[inputVariable][0] +
210 factorMultiplication +
217 particleConditions[particleList][1])
219 tree.Draw(variablesPlotParamsDict[inputVariable][0] +
220 factorMultiplication +
227 particleConditions[particleList][2])
229 negativeScalingFactor = negativeHistogram.Integral()
230 positiveScalingFactor = positiveHistogram.Integral()
232 if negativeScalingFactor == 0:
233 negativeScalingFactor = 1
235 if positiveScalingFactor == 0:
236 positiveScalingFactor = 1
238 negativeHistogram.Scale(1 / negativeScalingFactor)
239 positiveHistogram.Scale(1 / positiveScalingFactor)
241 negativeArray = np.zeros((negativeHistogram.GetNbinsX(), 2))
242 positiveArray = np.zeros((positiveHistogram.GetNbinsX(), 2))
244 asymmetryArray = np.zeros((positiveHistogram.GetNbinsX(), 2))
245 asymmetryArrayUncertainties = np.zeros((positiveHistogram.GetNbinsX(), 2))
247 for i
in range(0, negativeHistogram.GetNbinsX()):
248 negativeArray[i] = np.array([negativeHistogram.GetBinCenter(i + 1), negativeHistogram.GetBinContent(i + 1)])
249 positiveArray[i] = np.array([positiveHistogram.GetBinCenter(i + 1), positiveHistogram.GetBinContent(i + 1)])
251 numerator = float(positiveArray[i][1] - negativeArray[i][1])
252 denominator = float(positiveArray[i][1] + negativeArray[i][1])
255 asymmetryArray[i] = np.array([negativeHistogram.GetBinCenter(i + 1), 0])
256 asymmetryArrayUncertainties[i] = np.array([negativeHistogram.GetBinCenter(i + 1), 0])
258 asymmetryArray[i] = np.array([negativeHistogram.GetBinCenter(i + 1), float(numerator / denominator)])
260 uncertainty = 2 * math.sqrt((negativeArray[i][1] * negativeHistogram.GetBinError(i + 1))**2 + (
261 positiveArray[i][1] * positiveHistogram.GetBinError(i + 1))**2) / (negativeArray[i][1] + positiveArray[i][1])**2
263 asymmetryArrayUncertainties[i] = np.array([negativeHistogram.GetBinCenter(i + 1), uncertainty])
265 fig1 = plt.figure(1, figsize=(11, 11))
272 ax1 = plt.axes([0.19, 0.37, 0.76, 0.60])
277 negativeArray[:, 0], weights=negativeArray[:, 1], bins=negativeHistogram.GetNbinsX(),
278 histtype=
'step', edgecolor=
'b', linewidth=4.5, linestyle=
'dashed',
279 label=
r'$' + particleConditions[particleList][0] +
'^{-} $')
281 ax1.hist(positiveArray[:, 0], weights=positiveArray[:, 1], bins=positiveHistogram.GetNbinsX(),
282 histtype=
'step', edgecolor=
'r', linewidth=4, alpha=0.7,
283 label=
r'$' + particleConditions[particleList][0] +
'^{+} $')
285 p1, = ax1.plot([], label=
r'$' + particleConditions[particleList][0] +
'^{-} $',
286 linewidth=5.5, linestyle=
'dashed', c=
'b')
287 p2, = ax1.plot([], label=
r'$' + particleConditions[particleList][0] +
288 '^{+} $', linewidth=5, linestyle=
'solid', alpha=0.9, c=
'r')
290 binWidth = negativeHistogram.GetBinWidth(2)
292 if inputVariable ==
'lambdaZError':
294 binWidth = binWidth * 10
296 if inputVariable ==
'M':
297 binWidth = binWidth * 1000
299 if category ==
"Lambda" and inputVariable ==
'distance':
300 variablesPlotParamsDict[inputVariable][5] =
r"{\rm cm}\, "
302 binWidth =
'{:8.2f}'.format(binWidth)
305 ax1.set_ylabel(
r'${\rm Fraction\hspace{0.25em} of\hspace{0.25em} Events}\, /\, (\, ' + binWidth +
r'\, ' +
306 variablesPlotParamsDict[inputVariable][5] +
r')$', fontsize=35)
307 if inputVariable ==
'extraInfo(isRightCategory(Kaon))' or\
308 inputVariable ==
'HighestProbInCat(pi+:inRoe, isRightCategory(SlowPion))':
310 ax1.set_yscale(
'log', nonposy=
'clip')
312 ax1.yaxis.set_major_formatter(FormatStrFormatter(
r'$%.2f$'))
315 ax1.set_xlim(limXmin, limXmax)
317 locs, labels = plt.xticks()
318 empty_string_labels = [
''] * len(labels)
319 plt.locator_params(axis=
'x', nbins=len(labels))
320 ax1.set_xticklabels(empty_string_labels)
321 ax1.tick_params(axis=
'y', labelsize=37)
323 if inputVariable.find(
'ARICH') != -1
or inputVariable.find(
'TOP') != -1
or \
324 inputVariable ==
'cosTPTO' or inputVariable.find(
'KLM') != -1
or\
325 inputVariable ==
'cosTheta' or inputVariable ==
'FSCVariables(cosTPTOFast)' or\
326 inputVariable ==
'KaonPionVariables(cosKaonPion)':
329 elif inputVariable ==
'FSCVariables(SlowFastHaveOpositeCharges)' or \
330 inputVariable ==
'KaonPionVariables(HaveOpositeCharges)' or inputVariable ==
"eid_ECL" or \
331 inputVariable.find(
'ID') != -1
or inputVariable.find(
'dEdx') != -1:
334 if inputVariable ==
'muid_dEdx':
335 if category !=
'KinLepton':
338 ax1.legend([p1, p2], [
r'$' +
339 particleConditions[particleList][0] +
341 particleConditions[particleList][0] +
342 '^{+} $'], prop={
'size': 50}, loc=legendLocation, numpoints=1, handlelength=1)
345 ax2 = plt.axes([0.19, 0.15, 0.76, 0.2])
349 ax2.errorbar(asymmetryArray[:, 0], asymmetryArray[:, 1], xerr=float(negativeHistogram.GetBinWidth(2) / 2),
350 yerr=asymmetryArrayUncertainties[:, 1], elinewidth=2, mew=2, ecolor=
'k',
351 fmt=
'o', mfc=
'k', mec=
'k', markersize=6, label=
r'${\rm Data}$')
353 ax2.set_ylabel(
r'$\frac{f^{+}\; -\;\, f^{-}}{f^{+}\; +\;\, f^{-}}$', fontsize=50, labelpad=20)
354 ax2.yaxis.labelpad = 8
356 plt.yticks([-0.75, -0.5, -0.25, 0, 0.25, 0.5, 0.75],
357 [
r'',
r'$-0.5$',
r'',
r'$0.0$',
r'',
r'$0.5$',
r''], rotation=0, size=25)
358 ax2.set_ylim(-0.75, 0.75)
360 plt.axhline(y=0.5, linewidth=2, color=
'tab:gray', linestyle=
'-')
361 plt.axhline(y=0.25, linewidth=2, color=
'tab:gray', linestyle=
'-')
362 plt.axhline(y=0, linewidth=2, color=
'tab:gray', linestyle=
'-')
363 plt.axhline(y=-0.25, linewidth=2, color=
'tab:gray', linestyle=
'-')
364 plt.axhline(y=-0.5, linewidth=2, color=
'tab:gray', linestyle=
'-')
366 xLabel = variablesPlotParamsDict[inputVariable][4]
367 if category ==
"FSC":
368 if inputVariable ==
'cosTPTO':
369 xLabel =
r'$\vert\cos{\theta^*_{\rm T, Slow}}\vert$'
370 if inputVariable ==
'useCMSFrame(p)':
371 xLabel =
r'$p^*_{\rm Slow}\ [{\rm GeV}/c]$'
372 if category ==
'Lambda':
373 if inputVariable ==
'useCMSFrame(p)':
374 xLabel =
r'$p^*_{\Lambda}\ [{\rm GeV}/c]$'
375 if inputVariable ==
'p':
376 xLabel =
r'$p_{\Lambda}\ [{\rm GeV}/c]$'
378 if inputVariable ==
'pi_vs_edEdxid':
379 ax2.xaxis.labelpad = 5
381 ax2.xaxis.labelpad = 15
382 plt.locator_params(axis=
'x', nbins=len(labels))
384 ax2.set_xlim(limXmin, limXmax)
385 ax2.tick_params(axis=
'x', labelsize=40)
386 ax2.set_xlabel(xLabel, fontsize=50)
387 plt.savefig(
'./AsymmetriesInVariablesPlots/' + category +
'/' + category +
391 negativeHistogram.Delete()
392 positiveHistogram.Delete()
394 totalNumberOfVariables = 0
396 for category
in ft.variables_fict:
397 totalNumberOfVariables += len(ft.getTrainingVariables(category))
399 print(
"Total number of variables = ", totalNumberOfVariables)
401 totalNumberOfCalculatedVariables = len(identifiersExtraInfosKaonPion)
403 print(
"Calculations for Kaon-Pion Category = ", totalNumberOfCalculatedVariables)
405 print(
"Variables per particle list:")
406 for particleList
in identifiersExtraInfosDict:
408 print(identifiersExtraInfosDict[particleList])
409 totalNumberOfCalculatedVariables += len(identifiersExtraInfosDict[particleList])
411 print(
"Total number of calculated variables = ", totalNumberOfCalculatedVariables)
static std::string makeROOTCompatible(std::string str)
Remove special characters that ROOT dislikes in branch names, e.g.
static std::string invertMakeROOTCompatible(std::string str)
Invert makeROOTCompatible operation.