Belle II Software development
prepareAsicCrosstalkSimDB.py
1
8'''
9 Prepare CDC x-talk simulation DB object, usage:
10
11 python3 prepareAsicCrosstalkSimDB.py <input_asic_root> <output_path> <exp_num> <data_type>
12
13 input_asic_root: input path and files containing asic information,
14 produced by AsicBackgroundLibraryCreator.py
15 output_path: output path
16 exp_num: experiment number of raw data or mc samples
17 data_type: data or mc
18
19'''
20
21import uproot
22import matplotlib.pyplot as plt
23import numpy as np
24from scipy.interpolate import UnivariateSpline
25
26import basf2
27from ROOT import Belle2 # noqa: make the Belle2 namespace available
28from ROOT.Belle2 import FileSystem
29from ROOT.Belle2 import CDCDatabaseImporter
30from ROOT import TH1F, TFile
31import sys
32
33
34def getEff(var, cut, n=40, limits=(0., 2500.)):
35 ''' Simple efficiency estimator
36 var: pandas series/np array of variable to study
37 cut: bool series/np array pass/fail
38 n : number of bins
39 limits : histogram limits
40 '''
41 a = np.histogram(var, n, limits)
42 b = np.histogram(var[cut], n, limits)
43 eff = b[0]/a[0]
44 # Simple binomial formula:
45 effErr = 1/a[0]*np.sqrt(a[0]*eff*(1-eff))
46 x = 0.5*(a[1][1:]+a[1][:-1])
47 return x, eff, effErr
48
49
50# Problematic boards ID in each run
51bad_boards = {'22': [24, 196],
52 '24': [0, 15, 24, 40, 117, 175, 196, 202, 86, 89],
53 '25': [0, 24, 15],
54 '26': [24, 210, 62],
55 '27': [92, 24, 51, 106, 53],
56 }
57# Input arguments
58if len(sys.argv) != 5:
59 sys.exit("Four arguments are required: input_root, output_path, experiemnt numebr and data_type")
60InputFile = sys.argv[1]
61OutputPath = sys.argv[2]
62exp = sys.argv[3]
63data_type = sys.argv[4]
64
65# Dataframe, containing relevant variables from the root file
66df = uproot.open(InputFile, flatten=True)["ASIC"].arrays(["Channel", "ADC", "Board", "Nhit", "Asic"], library="pd")
67df.columns = ['_'.join(col) if col[1] != '' else col[0] for col in df.columns.values]
68# Defining asic
69df['asic'] = df.Channel//8
70# Remove the problematic boards
71mask = df['Board'].isin([m for m in bad_boards[f'{exp}']])
72df = df[~mask]
73
74nhits = 3
75
76u1 = getEff(df[(df.asic % 3 == 1)].ADC_ADC_Sig, df.Nhit > f'{nhits}', 128, (0, 1024.))
77
78u2 = getEff(df[(df.asic % 3 == 1)].ADC_ADC_Sig, df.Nhit > f'{nhits}', 8, (1024, 4096.))
79
80u = np.append(u1, u2, axis=1)
81
82plt.figure(figsize=(10, 4))
83
84x = np.nan_to_num(u[0])
85
86e = np.nan_to_num(u[1])
87
88ee = np.where(np.nan_to_num(u[2]) == 0, 1000., u[2])
89
90
91f = UnivariateSpline(x, e, 1/ee)
92
93xp = np.arange(-0.5, 4096.5, 1)
94
95plt.subplot(121)
96plt.xlim(0, 4096.)
97plt.ylim(0., 1.02)
98plt.errorbar(x, e, u[2], fmt='.')
99plt.ylabel(f'Fraction of Nhit>{nhits}')
100plt.title(f'exp{exp} {data_type}')
101plt.plot(xp, f(xp))
102
103plt.subplot(122)
104plt.xlim(0, 1000.)
105plt.ylim(0., 0.5)
106plt.errorbar(x, e, u[2], fmt='.', label='eff: asic=1,4; Nhit>3')
107plt.plot(xp, f(xp), label='spline fit')
108plt.xlabel('ADC')
109plt.legend()
110plt.savefig(f'{OutputPath}/xTalkProb_{exp}_{data_type}.pdf')
111
112# Write out root file
113
114names = ["Board", "Channel", 'Nhit', 'asic']
115for i in range(8):
116 names += [f'Asic_ADC{i:d}', f'Asic_TDC{i:d}', f'Asic_TOT{i:d}']
117
118with uproot.recreate(f'{OutputPath}/xTalkProb_{exp}_{data_type}.root') as output:
119 df_tmp = df.query('nhit>3 & asic==1')
120 output['ASIC'] = uproot.newtree({name: df_tmp[name].dtype for name in names})
121 output['ASIC'].extend({name: df_tmp[name].values for name in names})
122
123
124fi = TFile(f'{OutputPath}/xTalkProb_{exp}_{data_type}.root', "update")
125
126t = TH1F("ProbXTalk", "Prob xTalk", 4096, 0, 4096)
127t.SetContent(f(xp))
128fi.Write()
129fi.Close()
130
131
132INPUT = FileSystem.findFile(f'{OutputPath}/xTalkProb_{exp}_{data_type}.root')
133
134# Specify the exp and run where iov is valid.
135# N.B. -1 means unbound.
136
137expFirst = 0
138
139expLast = -1
140
141runFirst = 0
142
143runLast = -1
144# basf2.use_local_database("localdb/database.txt", "localdb")
145basf2.conditions.testing_payloads = [f'localdb/exp{exp}/database_{exp}.txt']
146
147
148main = basf2.create_path()
149
150
151eventinfosetter = basf2.register_module('EventInfoSetter')
152main.add_module(eventinfosetter)
153
154# process single event
155basf2.process(main)
156
157
158dbImporter = CDCDatabaseImporter(expFirst, runFirst, expLast, runLast)
159dbImporter.importCDCCrossTalkLibrary(INPUT)
160
161dbImporter.printCDCCrossTalkLibrary()
162dbImporter.testCDCCrossTalkLibrary()