28 from matplotlib.ticker
import FormatStrFormatter
29 import matplotlib.pyplot
as plt
31 from ROOT
import Belle2
34 import flavorTagger
as ft
35 from inputVariablesPlots
import variablesPlotParamsDict, categories
38 import matplotlib
as mpl
40 mpl.rcParams.update({
'font.size': 22})
41 mpl.rcParams[
'text.usetex'] =
True
42 mpl.rcParams[
'text.latex.preamble'] = [
r"\usepackage{amsmath}"]
45 if len(sys.argv) != 5:
46 sys.exit(
"Must provide 4 arguments: [Belle or Belle2] [BGx0 or BGx1] [training] [workingDirectory]"
49 belleOrBelle2 = sys.argv[1]
50 MCtype = str(sys.argv[2])
51 decayChannelTrainedOn = str(sys.argv[3])
52 workingDirectory = sys.argv[4]
54 filesDirectory = workingDirectory +
'/FlavorTagging/TrainedMethods'
56 if decayChannelTrainedOn ==
'JPsiKs':
57 decayChannelTrainedOn =
'JpsiKs_mu'
59 weightFiles =
'B2' + decayChannelTrainedOn + MCtype
61 ROOT.TH1.SetDefaultSumw2()
63 allInputVariables = []
65 belleOrBelle2Flag = belleOrBelle2
67 identifiersExtraInfosDict = dict()
68 identifiersExtraInfosKaonPion = []
77 if belleOrBelle2 ==
"Belle":
83 particleConditions = {
'e+:inRoe': [
'e',
" mcPDG > 0 ",
" mcPDG < 0 "],
'mu+:inRoe': [
r'\mu',
" mcPDG > 0 ",
" mcPDG < 0 "],
84 'lepton+:inRoe': [
'l',
" mcPDG > 0 ",
" mcPDG < 0 "],
85 'K+:inRoe': [
'K',
" mcPDG < 0 ",
" mcPDG > 0 "],
'pi+:inRoe': [
r'\pi',
" mcPDG < 0 ",
" mcPDG > 0 "],
86 'h+:inRoe': [
'h',
" mcPDG < 0 ",
" mcPDG > 0 "],
'Lambda0:inRoe': [
r'\Lambda',
" mcPDG < 0 ",
" mcPDG > 0 "]}
89 if not b2.find_file(
'AsymmetriesInVariablesPlots', silent=
True):
90 os.mkdir(
'./AsymmetriesInVariablesPlots')
93 for (particleList, category, _)
in ft.getEventLevelParticleLists(categories):
98 if not b2.find_file(
'AsymmetriesInVariablesPlots/' + category, silent=
True):
99 os.mkdir(
'./AsymmetriesInVariablesPlots/' + category)
101 if particleList
not in identifiersExtraInfosDict
and category !=
'KaonPion':
102 identifiersExtraInfosDict[particleList] = []
104 methodPrefixEventLevel =
"FlavorTagger_" + belleOrBelle2Flag +
"_" + weightFiles +
'EventLevel' + category +
'FBDT'
105 treeName = methodPrefixEventLevel +
"_tree"
106 targetVariable =
'isRightCategory(' + category +
')'
108 tree = ROOT.TChain(treeName)
110 workingFiles = glob.glob(filesDirectory +
'/' + methodPrefixEventLevel +
'sampled*.root')
113 for iFile
in workingFiles:
116 categoryInputVariables = []
117 trulyUsedInputVariables = []
118 for iVariable
in tree.GetListOfBranches():
122 if managerVariableName
in ft.getTrainingVariables(category)
or managerVariableName ==
'distance' or\
123 managerVariableName ==
'z0' or managerVariableName ==
'ImpactXY' or\
124 managerVariableName ==
'y' or managerVariableName ==
'OBoost':
125 if managerVariableName
in categoryInputVariables:
128 categoryInputVariables.append(managerVariableName)
129 if managerVariableName
in ft.getTrainingVariables(category):
130 allInputVariables.append((category, managerVariableName))
131 trulyUsedInputVariables.append((category, managerVariableName))
133 if managerVariableName
not in identifiersExtraInfosDict[particleList]
and category !=
'KaonPion':
134 identifiersExtraInfosDict[particleList].append(managerVariableName)
136 elif category ==
'KaonPion' and managerVariableName
not in identifiersExtraInfosKaonPion:
137 identifiersExtraInfosKaonPion.append(managerVariableName)
139 print(
"The number of variables used in " + category +
" is = ", len(trulyUsedInputVariables))
141 if category !=
'KaonPion' and category !=
'FSC' and category !=
'MaximumPstar' and\
142 category !=
'FastHadron' and category !=
'Lambda':
143 categoryInputVariables.append(
'BtagToWBosonVariables(recoilMass)')
145 for inputVariable
in categoryInputVariables:
152 nBins = variablesPlotParamsDict[inputVariable][1]
153 limXmin = variablesPlotParamsDict[inputVariable][2]
154 limXmax = variablesPlotParamsDict[inputVariable][3]
156 if belleOrBelle2 ==
"Belle2":
157 if inputVariable ==
'distance':
160 if inputVariable ==
'ImpactXY':
163 if category ==
"SlowPion":
164 if inputVariable ==
'p' or inputVariable ==
'useCMSFrame(p)' or\
165 inputVariable ==
'pt' or inputVariable ==
'useCMSFrame(pt)':
169 if inputVariable ==
'distance':
173 if inputVariable ==
'ImpactXY':
177 if category ==
"Lambda":
178 if inputVariable ==
'distance':
182 if inputVariable ==
'chiProb':
187 if category ==
"FastHadron":
188 particleList =
'h+:inRoe'
190 if category ==
"KinLepton" or category ==
"IntermediateKinLepton":
191 particleList =
'lepton+:inRoe'
202 factorMultiplication =
''
204 if belleOrBelle2 ==
"Belle2" and ((category !=
"Lambda" and inputVariable ==
'distance')
or inputVariable ==
205 'z0' or inputVariable ==
'ImpactXY' or inputVariable ==
'y' or inputVariable ==
'OBoost'):
206 factorMultiplication =
"*10 "
208 tree.Draw(variablesPlotParamsDict[inputVariable][0] +
209 factorMultiplication +
216 particleConditions[particleList][1])
218 tree.Draw(variablesPlotParamsDict[inputVariable][0] +
219 factorMultiplication +
226 particleConditions[particleList][2])
228 negativeScalingFactor = negativeHistogram.Integral()
229 positiveScalingFactor = positiveHistogram.Integral()
231 if negativeScalingFactor == 0:
232 negativeScalingFactor = 1
234 if positiveScalingFactor == 0:
235 positiveScalingFactor = 1
237 negativeHistogram.Scale(1 / negativeScalingFactor)
238 positiveHistogram.Scale(1 / positiveScalingFactor)
240 negativeArray = np.zeros((negativeHistogram.GetNbinsX(), 2))
241 positiveArray = np.zeros((positiveHistogram.GetNbinsX(), 2))
243 asymmetryArray = np.zeros((positiveHistogram.GetNbinsX(), 2))
244 asymmetryArrayUncertainties = np.zeros((positiveHistogram.GetNbinsX(), 2))
246 for i
in range(0, negativeHistogram.GetNbinsX()):
247 negativeArray[i] = np.array([negativeHistogram.GetBinCenter(i + 1), negativeHistogram.GetBinContent(i + 1)])
248 positiveArray[i] = np.array([positiveHistogram.GetBinCenter(i + 1), positiveHistogram.GetBinContent(i + 1)])
250 numerator = float(positiveArray[i][1] - negativeArray[i][1])
251 denominator = float(positiveArray[i][1] + negativeArray[i][1])
254 asymmetryArray[i] = np.array([negativeHistogram.GetBinCenter(i + 1), 0])
255 asymmetryArrayUncertainties[i] = np.array([negativeHistogram.GetBinCenter(i + 1), 0])
257 asymmetryArray[i] = np.array([negativeHistogram.GetBinCenter(i + 1), float(numerator / denominator)])
259 uncertainty = 2 * math.sqrt((negativeArray[i][1] * negativeHistogram.GetBinError(i + 1))**2 + (
260 positiveArray[i][1] * positiveHistogram.GetBinError(i + 1))**2) / (negativeArray[i][1] + positiveArray[i][1])**2
262 asymmetryArrayUncertainties[i] = np.array([negativeHistogram.GetBinCenter(i + 1), uncertainty])
264 fig1 = plt.figure(1, figsize=(11, 11))
271 ax1 = plt.axes([0.19, 0.37, 0.76, 0.60])
276 negativeArray[:, 0], weights=negativeArray[:, 1], bins=negativeHistogram.GetNbinsX(),
277 histtype=
'step', edgecolor=
'b', linewidth=4.5, linestyle=
'dashed',
278 label=
r'$' + particleConditions[particleList][0] +
'^{-} $')
280 ax1.hist(positiveArray[:, 0], weights=positiveArray[:, 1], bins=positiveHistogram.GetNbinsX(),
281 histtype=
'step', edgecolor=
'r', linewidth=4, alpha=0.7,
282 label=
r'$' + particleConditions[particleList][0] +
'^{+} $')
284 p1, = ax1.plot([], label=
r'$' + particleConditions[particleList][0] +
'^{-} $',
285 linewidth=5.5, linestyle=
'dashed', c=
'b')
286 p2, = ax1.plot([], label=
r'$' + particleConditions[particleList][0] +
287 '^{+} $', linewidth=5, linestyle=
'solid', alpha=0.9, c=
'r')
289 binWidth = negativeHistogram.GetBinWidth(2)
291 if inputVariable ==
'lambdaZError':
293 binWidth = binWidth * 10
295 if inputVariable ==
'M':
296 binWidth = binWidth * 1000
298 if category ==
"Lambda" and inputVariable ==
'distance':
299 variablesPlotParamsDict[inputVariable][5] =
r"{\rm cm}\, "
301 binWidth =
'{:8.2f}'.format(binWidth)
304 ax1.set_ylabel(
r'${\rm Fraction\hspace{0.25em} of\hspace{0.25em} Events}\, /\, (\, ' + binWidth +
r'\, ' +
305 variablesPlotParamsDict[inputVariable][5] +
r')$', fontsize=35)
306 if inputVariable ==
'extraInfo(isRightCategory(Kaon))' or\
307 inputVariable ==
'HighestProbInCat(pi+:inRoe, isRightCategory(SlowPion))':
309 ax1.set_yscale(
'log', nonposy=
'clip')
311 ax1.yaxis.set_major_formatter(FormatStrFormatter(
r'$%.2f$'))
314 ax1.set_xlim(limXmin, limXmax)
316 locs, labels = plt.xticks()
317 empty_string_labels = [
''] * len(labels)
318 plt.locator_params(axis=
'x', nbins=len(labels))
319 ax1.set_xticklabels(empty_string_labels)
320 ax1.tick_params(axis=
'y', labelsize=37)
322 if inputVariable.find(
'ARICH') != -1
or inputVariable.find(
'TOP') != -1
or \
323 inputVariable ==
'cosTPTO' or inputVariable.find(
'KLM') != -1
or\
324 inputVariable ==
'cosTheta' or inputVariable ==
'FSCVariables(cosTPTOFast)' or\
325 inputVariable ==
'KaonPionVariables(cosKaonPion)':
328 elif inputVariable ==
'FSCVariables(SlowFastHaveOpositeCharges)' or \
329 inputVariable ==
'KaonPionVariables(HaveOpositeCharges)' or inputVariable ==
"eid_ECL" or \
330 inputVariable.find(
'ID') != -1
or inputVariable.find(
'dEdx') != -1:
333 if inputVariable ==
'muid_dEdx':
334 if category !=
'KinLepton':
337 ax1.legend([p1, p2], [
r'$' +
338 particleConditions[particleList][0] +
340 particleConditions[particleList][0] +
341 '^{+} $'], prop={
'size': 50}, loc=legendLocation, numpoints=1, handlelength=1)
344 ax2 = plt.axes([0.19, 0.15, 0.76, 0.2])
348 ax2.errorbar(asymmetryArray[:, 0], asymmetryArray[:, 1], xerr=float(negativeHistogram.GetBinWidth(2) / 2),
349 yerr=asymmetryArrayUncertainties[:, 1], elinewidth=2, mew=2, ecolor=
'k',
350 fmt=
'o', mfc=
'k', mec=
'k', markersize=6, label=
r'${\rm Data}$')
352 ax2.set_ylabel(
r'$\frac{f^{+}\; -\;\, f^{-}}{f^{+}\; +\;\, f^{-}}$', fontsize=50, labelpad=20)
353 ax2.yaxis.labelpad = 8
355 plt.yticks([-0.75, -0.5, -0.25, 0, 0.25, 0.5, 0.75],
356 [
r'',
r'$-0.5$',
r'',
r'$0.0$',
r'',
r'$0.5$',
r''], rotation=0, size=25)
357 ax2.set_ylim(-0.75, 0.75)
359 plt.axhline(y=0.5, linewidth=2, color=
'tab:gray', linestyle=
'-')
360 plt.axhline(y=0.25, linewidth=2, color=
'tab:gray', linestyle=
'-')
361 plt.axhline(y=0, linewidth=2, color=
'tab:gray', linestyle=
'-')
362 plt.axhline(y=-0.25, linewidth=2, color=
'tab:gray', linestyle=
'-')
363 plt.axhline(y=-0.5, linewidth=2, color=
'tab:gray', linestyle=
'-')
365 xLabel = variablesPlotParamsDict[inputVariable][4]
366 if category ==
"FSC":
367 if inputVariable ==
'cosTPTO':
368 xLabel =
r'$\vert\cos{\theta^*_{\rm T, Slow}}\vert$'
369 if inputVariable ==
'useCMSFrame(p)':
370 xLabel =
r'$p^*_{\rm Slow}\ [{\rm GeV}/c]$'
371 if category ==
'Lambda':
372 if inputVariable ==
'useCMSFrame(p)':
373 xLabel =
r'$p^*_{\Lambda}\ [{\rm GeV}/c]$'
374 if inputVariable ==
'p':
375 xLabel =
r'$p_{\Lambda}\ [{\rm GeV}/c]$'
377 if inputVariable ==
'pi_vs_edEdxid':
378 ax2.xaxis.labelpad = 5
380 ax2.xaxis.labelpad = 15
381 plt.locator_params(axis=
'x', nbins=len(labels))
383 ax2.set_xlim(limXmin, limXmax)
384 ax2.tick_params(axis=
'x', labelsize=40)
385 ax2.set_xlabel(xLabel, fontsize=50)
386 plt.savefig(
'./AsymmetriesInVariablesPlots/' + category +
'/' + category +
390 negativeHistogram.Delete()
391 positiveHistogram.Delete()
393 totalNumberOfVariables = 0
395 for category
in ft.variables_fict:
396 totalNumberOfVariables += len(ft.getTrainingVariables(category))
398 print(
"Total number of variables = ", totalNumberOfVariables)
400 totalNumberOfCalculatedVariables = len(identifiersExtraInfosKaonPion)
402 print(
"Calculations for Kaon-Pion Category = ", totalNumberOfCalculatedVariables)
404 print(
"Variables per particle list:")
405 for particleList
in identifiersExtraInfosDict:
407 print(identifiersExtraInfosDict[particleList])
408 totalNumberOfCalculatedVariables += len(identifiersExtraInfosDict[particleList])
410 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.