28from matplotlib.ticker
import FormatStrFormatter
29import matplotlib.pyplot
as plt
31from ROOT
import Belle2
34import flavorTagger
as ft
35from inputVariablesPlots
import variablesPlotParamsDict, categories
38import matplotlib
as mpl
40mpl.rcParams.update({
'font.size': 22})
41mpl.rcParams[
'text.usetex'] =
True
42mpl.rcParams[
'text.latex.preamble'] = [
r"\usepackage{amsmath}"]
46 sys.exit(
"Must provide 4 arguments: [Belle or Belle2] [BGx0 or BGx1] [training] [workingDirectory]"
49belleOrBelle2 = sys.argv[1]
50MCtype = str(sys.argv[2])
51decayChannelTrainedOn = str(sys.argv[3])
52workingDirectory = sys.argv[4]
54filesDirectory = workingDirectory +
'/FlavorTagging/TrainedMethods'
56if decayChannelTrainedOn ==
'JPsiKs':
57 decayChannelTrainedOn =
'JpsiKs_mu'
59weightFiles =
'B2' + decayChannelTrainedOn + MCtype
61ROOT.TH1.SetDefaultSumw2()
65belleOrBelle2Flag = belleOrBelle2
67identifiersExtraInfosDict = dict()
68identifiersExtraInfosKaonPion = []
77if belleOrBelle2 ==
"Belle":
83particleConditions = {
'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 "]}
89if not b2.find_file(
'AsymmetriesInVariablesPlots', silent=
True):
90 os.mkdir(
'./AsymmetriesInVariablesPlots')
93for (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 = f
'{binWidth:8.2f}'
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()
393totalNumberOfVariables = 0
395for category
in ft.variables_fict:
396 totalNumberOfVariables += len(ft.getTrainingVariables(category))
398print(
"Total number of variables = ", totalNumberOfVariables)
400totalNumberOfCalculatedVariables = len(identifiersExtraInfosKaonPion)
402print(
"Calculations for Kaon-Pion Category = ", totalNumberOfCalculatedVariables)
404print(
"Variables per particle list:")
405for particleList
in identifiersExtraInfosDict:
407 print(identifiersExtraInfosDict[particleList])
408 totalNumberOfCalculatedVariables += len(identifiersExtraInfosDict[particleList])
410print(
"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.