Belle II Software development
createTSLUT.py
1#!/usr/bin/env python3
2
3
10
11import numpy as np
12
13"""
14Create a left/right LUT from a table of true left/right counts for each pattern.
15(see generateTrueLRTable.py)
16
17Condition for left/right:
18
19left: nBkg <= b * nTotal and nLeft > p * nMC + 3 * sqrt(p * (1 - p) * nMC)
20right: nBkg <= b * nTotal and nRight > p * nMC + 3 * sqrt(p * (1 - p) * nMC)
21unknown: otherwise
22"""
23
24# load table with true left/right
25# shape: [[nTrueRight, nTrueLeft, nTrueBkg], ...]
26innerTrueLRTable = np.loadtxt('innerTrueLRTable_Bkg1.0_1.dat')
27outerTrueLRTable = np.loadtxt('outerTrueLRTable_Bkg1.0_1.dat')
28for i in range(2, 5):
29 innerTrueLRTable += np.loadtxt(f'innerTrueLRTable_Bkg1.0_{int(i)}.dat')
30 outerTrueLRTable += np.loadtxt(f'outerTrueLRTable_Bkg1.0_{int(i)}.dat')
31
32# define thresholds for left/right
33b = 0.8
34p = 0.7
35
36# filenames for the new LUTs
37innerLUTFilename = f"innerLUT_Bkg_p{p:.2f}_b{p:.2f}.coe"
38outerLUTFilename = f"outerLUT_Bkg_p{p:.2f}_b{b:.2f}.coe"
39
40
41def isValidInnerPattern(pattern):
42 masks = [(1 << 1),
43 (1 << 2) + (1 << 3),
44 (1 << 4) + (1 << 5) + (1 << 6),
45 (1 << 7) + (1 << 8) + (1 << 9) + (1 << 10),
46 (1 << 11) + (1 << 12) + (1 << 13) + (1 << 14) + (1 << 15)]
47 nLayers = 0
48 for i in range(5):
49 if pattern & masks[i]:
50 nLayers += 1
51 return (nLayers >= 4)
52
53
54def isValidOuterPattern(pattern):
55 masks = [(1 << 1) + (1 << 2) + (1 << 3),
56 (1 << 4) + (1 << 5),
57 (1 << 6),
58 (1 << 7) + (1 << 8),
59 (1 << 9) + (1 << 10) + (1 << 11)]
60 nLayers = 0
61 for i in range(5):
62 if pattern & masks[i]:
63 nLayers += 1
64 return (nLayers >= 4)
65
66
67def createLUT(TrueLRTable, inner):
68 LUT = np.zeros(len(TrueLRTable))
69 # loop over patterns and check fraction of correct left/right
70 for pattern, trueLR in enumerate(TrueLRTable):
71 # check if pattern is valid
72 if inner:
73 if not isValidInnerPattern(pattern):
74 continue
75 else:
76 if not isValidOuterPattern(pattern):
77 continue
78 if trueLR[2] > b * np.sum(trueLR):
79 LUT[pattern] = 3
80 continue
81 threshold = p * np.sum(trueLR[:2]) + 3 * np.sqrt(p * (1 - p) * np.sum(trueLR[:2]))
82 if trueLR[0] > threshold:
83 LUT[pattern] = 1
84 elif trueLR[1] > threshold:
85 LUT[pattern] = 2
86 else:
87 LUT[pattern] = 3
88 return LUT
89
90
91innerLUT = createLUT(innerTrueLRTable, inner=True)
92outerLUT = createLUT(outerTrueLRTable, inner=False)
93
94# save the resulting LUTs
95innerLUTFile = open(innerLUTFilename, 'w')
96innerLUTFile.write("memory_initialization_radix=10;\n")
97innerLUTFile.write("memory_initialization_vector=\n")
98innerLUTFile.write(",\n".join(f"{int(i)}" for i in innerLUT))
99innerLUTFile.write(";\n\n")
100
101outerLUTFile = open(outerLUTFilename, 'w')
102outerLUTFile.write("memory_initialization_radix=10;\n")
103outerLUTFile.write("memory_initialization_vector=\n")
104outerLUTFile.write(",\n".join(f"{int(i)}" for i in outerLUT))
105outerLUTFile.write(";\n\n")