10Validation of the Beam Spot calibration
14from prompt
import ValidationSettings
20import scipy.linalg
as la
22import matplotlib.pyplot
as plt
26from math
import sqrt, frexp, asin
27from itertools
import groupby
29from datetime
import datetime, timedelta
30from ROOT.Belle2
import Unit
33settings = ValidationSettings(name=
'BeamSpot Calibrations',
35 download_files=[
'stdout'],
40def getEigenPars(covM):
41 sxx, syy, szz, sxy, sxz, syz = covM
43 mat = np.array([[sxx, sxy, sxz],
48 eigVals = result[0].real
52 idx = eigVals.argsort()[::-1]
53 eigVals = eigVals[idx]
54 eigVecs = eigVecs[:, idx]
56 assert(eigVals[0] > 1e-4)
57 assert(eigVals[1] > 1e-4)
58 assert(eigVals[2] > 1e-4)
60 sxEig = sqrt(eigVals[1])
61 syEig = sqrt(eigVals[2])
62 szEig = sqrt(eigVals[0])
75 angleXZ = Unit.rad / Unit.mrad * asin(eigVecs[0][0] / sqrt(1 - eigVecs[1][0]**2))
76 angleYZ = Unit.rad / Unit.mrad * asin(eigVecs[1][0])
77 angleXY = Unit.rad / Unit.mrad * asin(eigVecs[1][1] / sqrt(1 - eigVecs[1][0]**2))
79 return [sxEig, syEig, szEig, angleXZ, angleYZ, angleXY]
85 with open(path +
'/database.txt')
as fDB:
91 fN = ll[0].replace(
'/',
'_') +
'_rev_' + ll[1] +
'.root'
94 runDict[fN] = (int(r[0]), int(r[1]))
98 fList = glob(path +
'/*.root')
100 bName = os.path.basename(fName)
101 runExp = runDict[bName]
103 f = ROOT.TFile.Open(fName)
104 bsAll = f.Get(
"BeamSpot")
105 assert(bsAll.ClassName() ==
"Belle2::EventDependency")
107 evNums = bsAll.getEventNumbers()
109 for i
in range(len(evNums) + 1):
110 bs = bsAll.getObjectByIndex(i)
111 ipR = bs.getIPPosition()
112 ip = [ipR(i) * Unit.cm / Unit.um
for i
in range(3)]
113 ipeR = bs.getIPPositionCovMatrix()
114 ipe = [sqrt(ipeR(i, i)) * Unit.cm / Unit.um
for i
in range(3)]
115 covR = bs.getSizeCovMatrix()
116 covM = (covR(0, 0), covR(1, 1), covR(2, 2), covR(0, 1), covR(0, 2), covR(1, 2))
117 covM = [x * (Unit.cm / Unit.um)**2
for x
in covM]
119 tStart = ipeR(0, 1) * 1e20
120 tEnd = ipeR(0, 2) * 1e20
121 tStart = int(frexp(ipeR(0, 1))[0] * 2**53) % 2**32 / 3600.
122 tEnd = int(frexp(ipeR(0, 2))[0] * 2**53) % 2**32 / 3600.
124 eigM = getEigenPars(covM)
125 arr.append((runExp, tStart, tEnd, ip, ipe, covM, eigM))
128 arr = sorted(arr, key=
lambda x: x[1])
137 with open(
'bsData.csv',
'w')
as outFile:
138 outFile.write(
'exp run tStart tEnd xIP yIP zIP xeIP yeIP zeIP sXX sYY sZZ sXY sXZ '
139 +
'sYZ xSizeEig ySizeEig zSizeEig xzAngle yzAngle xyAngle\n')
175def plotVar(arr, limits, vName, getterV, getterE=None):
184 for i, el
in enumerate(arr):
186 s = datetime.utcfromtimestamp((s + 9) * 3600)
187 e = datetime.utcfromtimestamp((e + 9) * 3600)
190 Vals.append(getterV(el))
191 Vals.append(getterV(el))
193 if getterE
is not None:
194 Errs.append(getterE(el))
195 Errs.append(getterE(el))
198 if i >= len(arr) - 1:
201 dt = (arr[i + 1][1] - arr[i][2]) * 3600
208 gS = datetime.utcfromtimestamp((arr[i][2] + 9) * 3600)
209 gE = datetime.utcfromtimestamp((arr[i + 1][1] + 9) * 3600)
211 tVals.append(gS + (gE - gS) / 2)
213 if getterE
is not None:
217 tGapVals.append(gS - timedelta(seconds=1))
220 tGapVals.append(gE + timedelta(seconds=1))
222 GapVals.append(np.nan)
223 GapVals.append(getterV(arr[i]))
224 GapVals.append(getterV(arr[i + 1]))
225 GapVals.append(np.nan)
227 plt.plot(tVals, Vals, linewidth=2, color=
'C0')
228 plt.plot(tGapVals, GapVals, linewidth=2, color=
'C0', alpha=0.35)
230 Vals = np.array(Vals)
231 Errs = np.array(Errs)
233 if getterE
is not None:
234 plt.fill_between(tVals, Vals - Errs, Vals + Errs, alpha=0.2)
238 plt.ylabel(vName +
' [mrad]')
240 plt.ylabel(vName +
' [um]')
242 loc =
'plots/allData'
243 if limits
is not None:
244 plt.xlim(datetime.strptime(limits[0],
'%Y-%m-%d'), datetime.strptime(limits[1],
'%Y-%m-%d'))
245 loc =
'plots/' + limits[0] +
'to' + limits[1]
248 os.makedirs(loc, exist_ok=
True)
250 plt.savefig(loc +
'/' + vName +
'.png')
254def plotPullSpectrum(arr, vName, getterV, getterE):
256 valsOrg = np.array([getterV(v)
for v
in arr])
257 errsOrg = np.array([getterE(v)
for v
in arr])
260 indx = np.array([list(g)[0][0]
for k, g
in groupby(zip(np.arange(len(valsOrg)), valsOrg),
lambda x: x[1])])
264 diffs = (vals[1:] - vals[:-1]) / np.hypot(errs[1:], errs[:-1])
267 n1, n2 = scipy.stats.norm.cdf([-1, 1])
269 q1 = np.quantile(diffs, n1)
270 q2 = np.quantile(diffs, n2)
272 plt.hist(diffs, bins=np.linspace(-20, 20, 80), label=f
'q1={round(q1,1)}, q2={round(q2,1)}')
276 loc =
'plots/allData'
277 plt.savefig(loc +
'/' + vName +
'.png')
281def run_validation(job_path, input_data_path, requested_iov, expert_config):
287 if expert_config !=
'':
288 expert_config = json.loads(expert_config)
291 if expert_config
is not None and 'plotsRanges' in expert_config:
292 allLimits += expert_config[
'plotsRanges']
295 dbFile = glob(f
'{job_path}/**/database.txt', recursive=
True)
296 dbFile = [db
for db
in dbFile
if 'algorithm_output' not in db]
297 assert(len(dbFile) == 1)
299 inputDir = dbFile[:dbFile.rfind(
'/')]
301 arr = getBSvalues(inputDir)
306 plt.figure(figsize=(18, 9))
309 for limits
in allLimits:
310 plotVar(arr, limits,
'xIP',
lambda e: e[3][0],
lambda e: e[4][0])
311 plotVar(arr, limits,
'yIP',
lambda e: e[3][1],
lambda e: e[4][1])
312 plotVar(arr, limits,
'zIP',
lambda e: e[3][2],
lambda e: e[4][2])
314 plotVar(arr, limits,
'xSpotSize',
lambda e: sqrt(e[5][0]))
315 plotVar(arr, limits,
'ySpotSize',
lambda e: sqrt(e[5][1]))
316 plotVar(arr, limits,
'zSpotSize',
lambda e: sqrt(e[5][2]))
318 plotVar(arr, limits,
'xSpotSizeEig',
lambda e: e[6][0])
319 plotVar(arr, limits,
'ySpotSizeEig',
lambda e: e[6][1])
320 plotVar(arr, limits,
'zSpotSizeEig',
lambda e: e[6][2])
322 plotVar(arr, limits,
'xzSpotAngle',
lambda e: e[6][3])
323 plotVar(arr, limits,
'yzSpotAngle',
lambda e: e[6][4])
324 plotVar(arr, limits,
'xySpotAngle',
lambda e: e[6][5])
326 plotPullSpectrum(arr,
'xIPpulls',
lambda e: e[3][0],
lambda e: e[4][0])
327 plotPullSpectrum(arr,
'yIPpulls',
lambda e: e[3][1],
lambda e: e[4][1])
328 plotPullSpectrum(arr,
'zIPpulls',
lambda e: e[3][2],
lambda e: e[4][2])
331if __name__ ==
"__main__":