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