ATLAS Offline Software
Loading...
Searching...
No Matches
BeamSpotData.py
Go to the documentation of this file.
1#!/usr/bin/env python
2
3# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
4
5"""
6Tools for handling beam spot data in ntuples or in COOL.
7For functionality requiring COOL access, you'll probably need to use
8Frontier outside of CERN. For example:
9
10setenv FRONTIER_SERVER "(serverurl=http://squid-frontier.usatlas.bnl.gov:23128/frontieratbnl)"
11"""
12__author__ = 'Juerg Beringer'
13__version__ = '$Id: BeamSpotData.py 759522 2016-07-04 12:47:58Z amorley $'
14
15import time
16import copy
17from array import array
18from math import sqrt, atan
19import csv
20
21import numpy # WARNING: must be last import, so numpy can override sqrt etc
22
23import ROOT
24
25import atexit
26
27#
28# Definition of generic beam spot ntuple variable attributes
29# For definition of LaTeX symbols see beamspot-defs.tex.
30#
31varDefsGen = {
32 'run': {},
33 'fill': {},
34 'bcid': {},
35 'nEvents': {},
36 'nValid': {'altfmt': '%i', 'latexheader': r'$n_{\mathrm{vtx}}$'},
37 'nVtxAll': {},
38 'nVtxPrim': {},
39 'status': {'fmt': '%4i', 'altfmt': '%4i','latexheader' : 'Status' },
40 'posX': {'units': 'mm', 'fmt': '%10.4f', 'latexheader': '$x$ [mm]',
41 'altfmt': '%10.3f', 'altlatexheader': '\\lumposx [mm]',
42 'title': 'Beam Spot Position x', 'atit': 'Luminous centroid x [mm]', 'min': -2, 'max': 6},
43 'posY': {'units': 'mm', 'fmt': '%10.4f', 'latexheader': '$y$ [mm]',
44 'altfmt': '%10.3f', 'altlatexheader': '\\lumposy [mm]',
45 'title': 'Beam Spot Position y', 'atit': 'Luminous centroid y [mm]', 'min': -2, 'max': 6},
46 'posZ': {'units': 'mm', 'fmt': '%10.2f', 'latexheader': '$z$ [mm]',
47 'altfmt': '%10.1f', 'altlatexheader': '\\lumposz [mm]',
48 'title': 'Beam Spot Position z', 'atit': 'Luminous centroid z [mm]', 'min': -100, 'max': 100},
49 'sigmaX': {'units': 'mm', 'fmt': '%10.4f', 'latexheader': r'$\sigma_x$ [mm]',
50 'altfmt': '%10.0f', 'altfactor': 1000., 'altlatexheader': r'\\lumsigx [$\mu$m]',
51 'title': 'Beam Spot Size #sigma_{x}', 'atit': 'Luminous size #sigma_{x} [mm]', 'min': 0, 'max': 0.6},
52 'sigmaY': {'units': 'mm', 'fmt': '%10.4f', 'latexheader': r'$\sigma_y$ [mm]',
53 'altfmt': '%10.0f','altfactor': 1000., 'altlatexheader': r'\\lumsigy [$\mu$m]',
54 'title': 'Beam Spot Size #sigma_{y}', 'atit': 'Luminous size #sigma_{y} [mm]', 'min': 0, 'max': 0.6},
55 'sigmaZ': {'units': 'mm', 'fmt': '%10.2f', 'latexheader': r'$\sigma_z$ [mm]',
56 'altfmt': '%10.0f', 'altlatexheader': '\\lumsigz [mm]',
57 'title': 'Beam Spot Size #sigma_{z}', 'atit': 'Luminous size #sigma_{z} [mm]', 'min': 0, 'max': 150},
58 'tiltX': {'units': 'rad', 'fmt': '%10.6f', 'latexheader': 'tilt$_{xz}$ [rad]',
59 'altfmt': '%10.0f', 'altfactor': 1.E6, 'altlatexheader': '\\lumtiltx [$\\mu$rad]',
60 'title': 'Beam Spot Tilt x-z', 'atit': 'Luminous region tilt in x-z [mrad]', 'arescale': 1000., 'min': -2., 'max': 4.},
61 'tiltY': {'units': 'rad', 'fmt': '%10.6f', 'latexheader': 'tilt$_{yz}$ [rad]',
62 'altfmt': '%10.0f', 'altfactor': 1.E6, 'altlatexheader': '\\lumtilty [$\\mu$rad]',
63 'title': 'Beam Spot Tilt y-z', 'atit': 'Luminous region tilt in y-z [mrad]', 'arescale': 1000., 'min': -2., 'max': 4.},
64 'posXErr': {'units': 'mm', 'fmt': '%10.4f',
65 'title': 'Uncertainty on Beam Spot Position', 'atit': 'Uncertainty on luminous centroid x [mm]', 'min': 0, 'max': .005},
66 'posYErr': {'units': 'mm', 'fmt': '%10.4f',
67 'title': 'Uncertainty on Beam Spot Position', 'atit': 'Uncertainty on luminous centroid y [mm]', 'min': 0, 'max': .005},
68 'posZErr': {'units': 'mm', 'fmt': '%10.2f',
69 'title': 'Uncertainty on Beam Spot Position', 'atit': 'Uncertainty on luminous centroid z [mm]', 'min': 0, 'max': 5},
70 'sigmaXErr': {'units': 'mm', 'fmt': '%10.3f',
71 'title': 'Uncertainty on Beam Spot Size', 'atit': 'Uncertainty on luminous size #sigma_{x} [mm]', 'min': 0, 'max': 0.005},
72 'sigmaYErr': {'units': 'mm', 'fmt': '%10.3f',
73 'title': 'Uncertainty on Beam Spot Size', 'atit': 'Uncertainty on luminous size #sigma_{y} [mm]', 'min': 0, 'max': 0.005},
74 'sigmaZErr': {'units': 'mm', 'fmt': '%10.2f',
75 'title': 'Uncertainty on Beam Spot Size', 'atit': 'Uncertainty on luminous size #sigma_{z} [mm]', 'min': 0, 'max': 5},
76 'tiltXErr': {'units': 'rad', 'fmt': '%10.6f',
77 'title': 'Uncertainty on Beam Spot Tilt', 'atit': 'Uncertainty on luminous region tilt in x-z [rad]', 'min': 0, 'max': .0001},
78 'tiltYErr': {'units': 'rad', 'fmt': '%10.6f',
79 'title': 'Uncertainty on Beam Spot Tilt', 'atit': 'Uncertainty on luminous region tilt in y-z [rad]', 'min': 0, 'max': .0001},
80 'rhoXY': {'fmt': '%10.3f', 'latexheader': '$\\rho_{xy}$',
81 'altfmt': '%10.2f', 'altfactor': 1., 'altlatexheader': '\\lumrhoxy',
82 'title': 'Beam Spot #rho_{xy}', 'atit': '#rho', 'min': -1., 'max': 1.5},
83 'rhoXYErr': {'fmt': '%10.3f',
84 'title': 'Uncertainty on Beam Spot #rho_{xy}', 'atit': 'Uncertainty on #rho', 'min': 0, 'max': .1},
85 'covSxSy': {'fmt': '%10.3f',
86 'title': 'Covariance of Beam Spot #sigma_{x}#sigma_{y}', 'atit': 'Covariance of #sigma_{x}#sigma_{y}', 'min': -.1, 'max': .1},
87 'covSxRhoXY':{'fmt': '%10.3f',
88 'title': 'Covariance of Beam Spot #sigma_{x}#rho_{xy}', 'atit': 'Covariance of #sigma_{x}#rho_{xy}', 'min': -.1, 'max': .1},
89 'covSyRhoXY':{'fmt': '%10.3f',
90 'title': 'Covariance of Beam Spot #sigma_{y}#rho_{xy}', 'atit': 'Covariance of #sigma_{y}#rho_{xy}', 'min': -.1, 'max': .1},
91 'k': {'fmt': '%10.3f', 'latexheader': 'k', 'altlatexheader': 'k',
92 'title': 'Error Scale Factor k', 'atit': 'k', 'min': 0.5, 'max': 2.0},
93 'kErr': {'fmt': '%10.3f',
94 'title': 'Uncertainty on Error Scale Factor k', 'atit': 'Uncertainty on k', 'min': 0, 'max': 0.2},
95 'sigmaXY': {'fmt': '%10.6f', 'latexheader': r'$\sigma_{xy}$',
96 'title': 'Beam Spot Size #sigma_{xy}', 'atit': '#sigma_{xy}', 'min': -0.0005, 'max': 0.0005},
97}
98
99# Version for making LaTeX table of beam spot results
100varDefsTable = copy.deepcopy(varDefsGen)
101varDefsTable['posX']['altfmt'] = '%10.4f'
102varDefsTable['posY']['altfmt'] = '%10.4f'
103varDefsTable['posZ']['altfmt'] = '%10.4f'
104varDefsTable['sigmaX']['altfmt'] = '%10.1f'
105varDefsTable['sigmaY']['altfmt'] = '%10.1f'
106varDefsTable['sigmaZ']['altfmt'] = '%10.1f'
107varDefsTable['tiltX']['altfmt'] = '%10.1f'
108varDefsTable['tiltY']['altfmt'] = '%10.1f'
109varDefsTable['rhoXY']['altfmt'] = '%10.3f'
110
111# Version where default values are tailored for Run 1
112varDefsRun1 = copy.deepcopy(varDefsGen)
113varDefsRun1['posX']['min'] = -1.
114varDefsRun1['posX']['max'] = +1.
115varDefsRun1['posY']['min'] = 0.
116varDefsRun1['posY']['max'] = 2.
117varDefsRun1['posZ']['min'] = -60.
118varDefsRun1['posZ']['max'] = +60.
119varDefsRun1['sigmaX']['max'] = 0.1
120varDefsRun1['sigmaY']['max'] = 0.1
121varDefsRun1['sigmaZ']['max'] = 80.
122varDefsRun1['tiltX']['min'] = -0.4
123varDefsRun1['tiltX']['max'] = +0.4
124varDefsRun1['tiltY']['min'] = -0.4
125varDefsRun1['tiltY']['max'] = +0.4
126
127# Version where default values are tailored for
128varDefsRun1VtxPaper = copy.deepcopy(varDefsGen)
129varDefsRun1VtxPaper['posX']['atit'] = 'x [mm]'
130varDefsRun1VtxPaper['posY']['atit'] = 'y [mm]'
131varDefsRun1VtxPaper['posZ']['atit'] = 'z [mm]'
132varDefsRun1VtxPaper['sigmaX']['atit'] = '#sigma_{x} [mm]'
133varDefsRun1VtxPaper['sigmaY']['atit'] = '#sigma_{y} [mm]'
134varDefsRun1VtxPaper['sigmaZ']['atit'] = '#sigma_{z} [mm]'
135
136# Version where default values are tailored for MC14 validation plots
137varDefsMC14 = copy.deepcopy(varDefsGen)
138varDefsMC14['posX']['min'] = -0.297
139varDefsMC14['posX']['max'] = -0.287
140varDefsMC14['posX']['ndivs'] = 502
141varDefsMC14['posY']['min'] = 0.698
142varDefsMC14['posY']['max'] = 0.708
143varDefsMC14['posY']['ndivs'] = 502
144varDefsMC14['posZ']['min'] = -14
145varDefsMC14['posZ']['max'] = -4
146varDefsMC14['posZ']['ndivs'] = 502
147varDefsMC14['sigmaX']['min'] = 0.00
148varDefsMC14['sigmaX']['max'] = 0.02
149varDefsMC14['sigmaX']['ndivs'] = 502
150varDefsMC14['sigmaY']['min'] = 0.00
151varDefsMC14['sigmaY']['max'] = 0.02
152varDefsMC14['sigmaY']['ndivs'] = 502
153varDefsMC14['sigmaZ']['min'] = 40
154varDefsMC14['sigmaZ']['max'] = 50
155varDefsMC14['sigmaZ']['ndivs'] = 502
156varDefsMC14['tiltX']['min'] = -0.1 #mrad
157varDefsMC14['tiltX']['max'] = -0.0
158varDefsMC14['tiltX']['ndivs'] = 502
159varDefsMC14['tiltY']['min'] = -0.1 #mrad
160varDefsMC14['tiltY']['max'] = -0.0
161varDefsMC14['tiltY']['ndivs'] = 502
162varDefsMC14['k']['min'] = 0.6
163varDefsMC14['k']['max'] = 1.6
164varDefsMC14['k']['ndivs'] = 510
165
166# Version where default values are tailored for MC14 validation plots vs pileup profile plots
167varDefsMC14Profile = copy.deepcopy(varDefsGen)
168varDefsMC14Profile['posX']['min'] = -0.297
169varDefsMC14Profile['posX']['max'] = -0.287
170varDefsMC14Profile['posX']['ndivs'] = 502
171varDefsMC14Profile['posY']['min'] = 0.698
172varDefsMC14Profile['posY']['max'] = 0.708
173varDefsMC14Profile['posY']['ndivs'] = 502
174varDefsMC14Profile['posZ']['min'] = -14
175varDefsMC14Profile['posZ']['max'] = -4
176varDefsMC14Profile['posZ']['ndivs'] = 502
177varDefsMC14Profile['sigmaX']['min'] = 0.013
178varDefsMC14Profile['sigmaX']['max'] = 0.018
179varDefsMC14Profile['sigmaX']['ndivs'] = 505
180varDefsMC14Profile['sigmaY']['min'] = 0.013
181varDefsMC14Profile['sigmaY']['max'] = 0.018
182varDefsMC14Profile['sigmaY']['ndivs'] = 505
183varDefsMC14Profile['sigmaZ']['min'] = 45
184varDefsMC14Profile['sigmaZ']['max'] = 50
185varDefsMC14Profile['sigmaZ']['ndivs'] = 505
186varDefsMC14Profile['tiltX']['min'] = -0.1 #mrad
187varDefsMC14Profile['tiltX']['max'] = -0.0
188varDefsMC14Profile['tiltX']['ndivs'] = 502
189varDefsMC14Profile['tiltY']['min'] = -0.1 #mrad
190varDefsMC14Profile['tiltY']['max'] = -0.0
191varDefsMC14Profile['tiltY']['ndivs'] = 502
192varDefsMC14Profile['k']['min'] = 0.9
193varDefsMC14Profile['k']['max'] = 1.2
194varDefsMC14Profile['k']['ndivs'] = 503
195
196# Version where default values are tailored for truth-subtracted validation plots
197varDefsTruthCorr = copy.deepcopy(varDefsGen)
198varDefsTruthCorr['posX']['atit'] = 'Luminous centroid x - generated value [mm]'
199varDefsTruthCorr['posX']['min'] = -0.005
200varDefsTruthCorr['posX']['max'] = 0.005
201varDefsTruthCorr['posX']['ndivs'] = 502
202varDefsTruthCorr['posY']['atit'] = 'Luminous centroid y - generated value [mm]'
203varDefsTruthCorr['posY']['min'] = -0.005
204varDefsTruthCorr['posY']['max'] = 0.005
205varDefsTruthCorr['posY']['ndivs'] = 502
206varDefsTruthCorr['posZ']['atit'] = 'Luminous centroid z - generated value [mm]'
207varDefsTruthCorr['posZ']['min'] = -5.
208varDefsTruthCorr['posZ']['max'] = 5.
209varDefsTruthCorr['posZ']['ndivs'] = 502
210varDefsTruthCorr['sigmaX']['atit'] = 'Luminous size #sigma_{x} - generated value [mm]'
211varDefsTruthCorr['sigmaX']['min'] = -0.005
212varDefsTruthCorr['sigmaX']['max'] = 0.005
213varDefsTruthCorr['sigmaX']['ndivs'] = 502
214varDefsTruthCorr['sigmaY']['atit'] = 'Luminous size #sigma_{y} - generated value [mm]'
215varDefsTruthCorr['sigmaY']['min'] = -0.005
216varDefsTruthCorr['sigmaY']['max'] = 0.005
217varDefsTruthCorr['sigmaY']['ndivs'] = 502
218varDefsTruthCorr['sigmaZ']['atit'] = 'Luminous size #sigma_{z} - generated value [mm]'
219varDefsTruthCorr['sigmaZ']['min'] = -5.
220varDefsTruthCorr['sigmaZ']['max'] = 5.
221varDefsTruthCorr['sigmaZ']['ndivs'] = 502
222varDefsTruthCorr['tiltX']['atit'] = 'Luminous region tilt in x-z - generated value [mrad]'
223varDefsTruthCorr['tiltX']['min'] = -0.05
224varDefsTruthCorr['tiltX']['max'] = 0.05
225varDefsTruthCorr['tiltX']['ndivs'] = 502
226varDefsTruthCorr['tiltY']['atit'] = 'Luminous region tilt in y-z - generated value [mrad]'
227varDefsTruthCorr['tiltY']['min'] = -0.05
228varDefsTruthCorr['tiltY']['max'] = 0.05
229varDefsTruthCorr['tiltY']['ndivs'] = 502
230varDefsTruthCorr['sigmaXY']['atit'] = '#sigma_{xy} - generated value'
231varDefsTruthCorr['sigmaXY']['min'] = -0.05e-3
232varDefsTruthCorr['sigmaXY']['max'] = 0.05e-3
233varDefsTruthCorr['sigmaXY']['ndivs'] = 502
234
235
236varDefs = varDefsGen # generic settings are default
237def varDef(var,property,default='',useAlternate=False,override=None):
238 if override:
239 return override
240 try:
241 v = varDefs[var].get(property,default)
242 if useAlternate:
243 v = varDefs[var].get('alt'+property,v)
244 return v
245 except Exception:
246 return default
247
248def fmtVal(var,value,strip=False,useAlternate=False):
249 fmt = varDef(var,'fmt','%s')
250 if useAlternate:
251 value *= varDef(var,'altfactor',1.)
252 fmt = varDef(var,'altfmt',fmt)
253 s = fmt % value
254 if strip:
255 return s.strip()
256 else:
257 return s
258
259
260
262 """Class to hold information about a single set of beam spot parameters.
263 The beam spot parametrization follows the COOL convention (see
264 https://twiki.cern.ch/twiki/bin/view/Atlas/CoolBeamSpotParameters)."""
265
266 # Class variables
267 coolQuery = None
268 propertyList = ['sigmaXY', 'sigmaXYErr','thetaXY','thetaXYErr', 'defects', 'fullCorrelations', 'addScanVars']
269 pseudoLbDict = {}
270 defectData = None
271
272 def __init__(self, fullCorrelations=False, addScanVars=False):
273 self.fullCorrelations = fullCorrelations
274 self.addScanVars = addScanVars
275
276 # Run info etc
277 self.run = 0
278 self.fill = 0
279 self.bcid = 0
280 self.lbStart = 0
281 self.lbEnd = 0 # exclusive, like COOL ranges
282 self.timeStart = 0 # Beware - must be int (seconds since epoch), float not precise enough!
283 self.timeEnd = 0 # Beware - must be int (seconds since epoch), float not precise enough!
284 self.nEvents = 0 # Number of vertices input to fit
285 self.nValid = 0 # Number of vertices used by fit
286 self.nVtxAll = 0 # Total number of vertices (no cuts)
287 self.nVtxPrim = 0 # Total number of primary vertices (no cuts)
288
289 # Parameters as stored in COOL
290
291 #self.fitID=0
292 self.status = 0
293 self.posX = 0.
294 self.posY = 0.
295 self.posZ = 0.
296 self.sigmaX = 0.
297 self.sigmaY = 0.
298 self.sigmaZ = 0.
299 self.tiltX = 0.
300 self.tiltY = 0.
301
302 # Errors for the parameters above
303 self.posXErr = 0.
304 self.posYErr = 0.
305 self.posZErr = 0.
306 self.sigmaXErr = 0.
307 self.sigmaYErr = 0.
308 self.sigmaZErr = 0.
309 self.tiltXErr = 0.
310 self.tiltYErr = 0.
311
312 # Offdiagonal covariance matrix parameters
313 self.covSxSy = 0.
314 self.covSxRhoXY = 0.
315 self.covSyRhoXY = 0.
316
317 if self.fullCorrelations :
318 self.covXY = 0.
319 self.covXZ = 0.
320 self.covXTiltX = 0.
321 self.covXTiltY = 0.
322 self.covXSx = 0.
323 self.covXSy = 0.
324 self.covXSz = 0.
325 self.covXRhoXY = 0.
326 self.covXk = 0.
327
328 self.covYZ = 0.
329 self.covYTiltX = 0.
330 self.covYTiltY = 0.
331 self.covYSx = 0.
332 self.covYSy = 0.
333 self.covYSz = 0.
334 self.covYRhoXY = 0.
335 self.covYk = 0.
336
337 self.covZTiltX = 0.
338 self.covZTiltY = 0.
339 self.covZSx = 0.
340 self.covZSy = 0.
341 self.covZSz = 0.
342 self.covZRhoXY = 0.
343 self.covZk = 0.
344
346 self.covTiltXSx = 0.
347 self.covTiltXSy = 0.
348 self.covTiltXSz = 0.
350 self.covTiltXk = 0.
351
352 self.covTiltYSx = 0.
353 self.covTiltYSy = 0.
354 self.covTiltYSz = 0.
356 self.covTiltYk = 0.
357
358 self.covSxSz = 0.
359 self.covSxk = 0.
360
361 self.covSySz = 0.
362 self.covSyk = 0.
363
364 self.covSzRhoXY = 0.
365 self.covSzk = 0.
366
367 self.covRhoXYk = 0.
368
369
370 # Additional fit parameters
371 self.rhoXY = 0.
372 self.rhoXYErr = 0.
373 self.k = 1.
374 self.kErr = 0.
375
376 # Data quality info
377 self.defectWord = 0
378
379 # Additional Luminosity variables (required mainly for VdM scans)
380 if self.addScanVars :
383 self.scanningIP = 0
385 self.B1DeltaXSet = 0.
386 self.B2DeltaXSet = 0.
387 self.B1DeltaYSet = 0.
388 self.B2DeltaYSet = 0.
389
390 @property
391 def sigmaXY(self):
392 return self.rhoXY*self.sigmaX*self.sigmaY
393
394 @property
395 def sigmaXYErr(self):
396 # NOTE: error calculation below neglects covariance matrix
397 ss = self.rhoXYErr*self.rhoXYErr*self.sigmaX*self.sigmaX*self.sigmaY*self.sigmaY
398 ss += self.rhoXY*self.rhoXY*self.sigmaXErr*self.sigmaXErr*self.sigmaY*self.sigmaY
399 ss += self.rhoXY*self.rhoXY*self.sigmaX*self.sigmaX*self.sigmaYErr*self.sigmaYErr
400 return sqrt(ss)
401
402 @property
403 def thetaXY(self):
404 try:
405 txy = .5*atan((2*self.sigmaX*self.sigmaY*self.rhoXY)/(self.sigmaY**2-self.sigmaX**2))
406 except Exception:
407 txy = 0
408 return txy
409
410 @property
411 def thetaXYErr(self):
412 try:
413 tpx = (self.rhoXY*self.sigmaY*(self.sigmaX**2+self.sigmaY**2))/(self.sigmaX**4+2*(2*self.rhoXY**2-1)*self.sigmaX**2*self.sigmaY**2+self.sigmaY**4)
414 tpy = -1*(self.rhoXY*self.sigmaX*(self.sigmaX**2+self.sigmaY**2))/(self.sigmaX**4+2*(2*self.rhoXY**2-1)*self.sigmaX**2*self.sigmaY**2+self.sigmaY**4)
415 tpr = (self.sigmaX*self.sigmaY**3-self.sigmaY*self.sigmaX**3)/(self.sigmaX**4+2*(2*self.rhoXY**2-1)*self.sigmaX**2*self.sigmaY**2+self.sigmaY**4)
416 txye = sqrt(tpx*tpx*self.sigmaXErr**2 + tpy*tpy*self.sigmaYErr**2 + tpr*tpr*self.rhoXYErr**2 + 2*(tpx*tpy*self.covSxSy + tpx*tpr*self.covSxRhoXY + tpy*tpr*self.covSyRhoXY))
417 except Exception:
418 txye = 0
419 return txye
420
421 @property
422 def defects(self):
423
424 # Will raise an error if unknown defect encountered
425 from InDetBeamSpotExample.DQUtilities import IDBSDefectEncoding
426 return IDBSDefectEncoding.intToDefectList(self.defectWord)
427
429 if not BeamSpotValue.coolQuery:
430 from InDetBeamSpotExample.COOLUtils import COOLQuery
431 BeamSpotValue.coolQuery = COOLQuery()
432 try:
433 self.timeStart = BeamSpotValue.coolQuery.lbTime(self.run,self.lbStart)[0]
434 except Exception:
435 pass
436 try:
437 self.timeEnd = BeamSpotValue.coolQuery.lbTime(self.run,self.lbEnd)[1]
438 except Exception:
439 pass
440 try:
441 self.fill = BeamSpotValue.coolQuery.getLHCInfo(self.timeStart).get('FillNumber',0)
442 except Exception:
443 pass
444
445 def fillScanData(self):
446 if not BeamSpotValue.coolQuery:
447 from InDetBeamSpotExample.COOLUtils import COOLQuery
448 BeamSpotValue.coolQuery = COOLQuery()
449 try:
450 scanPars = BeamSpotValue.coolQuery.scanInfo(self.run,self.lbStart)
451 if scanPars is not None:
452 self.scanningIP = scanPars[0]
453 self.acquisitionFlag = scanPars[1]
454 self.nominalSeparation = scanPars[2]
455 self.nominalSeparationPlane = scanPars[3]
456 self.B1DeltaXSet = scanPars[4]
457 self.B2DeltaXSet = scanPars[5]
458 self.B1DeltaYSet = scanPars[6]
459 self.B2DeltaYSet = scanPars[7]
460 else:
461 print('Scan info is not available for ',self.run,self.lbStart)
462 self.scanningIP = 0
463 self.acquisitionFlag = 0
464 self.nominalSeparation = 0.
466 self.B1DeltaXSet = 0.
467 self.B2DeltaXSet = 0.
468 self.B1DeltaYSet = 0.
469 self.B2DeltaYSet = 0.
470
471 except Exception:
472 pass
473
474 def fillDataFromPseudoLb(self, pseudoLbFile, timeUnit = 1.):
475 if not BeamSpotValue.pseudoLbDict:
476 f = open(pseudoLbFile)
477 for pLb, line in enumerate(f):
478 tokens = line.split()
479 if len(tokens) < 5: tokens.append(0.0)
480 point, start, end, sep, acq = tokens
481 print ("point %s %s %s %s" % (point,start,sep,acq))
482 BeamSpotValue.pseudoLbDict[int(point)] = (int(int(start)*timeUnit), int(int(end)*timeUnit), float(sep), float(acq))
483
484 if self.lbStart not in self.pseudoLbDict:
485 print ("Missing %s in pseudoLbDict" % self.lbStart)
486 return
487
488 self.timeStart = self.pseudoLbDict[self.lbStart][0]
489 self.timeEnd = self.pseudoLbDict[self.lbStart][1]
490 self.separation = self.pseudoLbDict[self.lbStart][2]
491 #self.acquisitionFlag = self.pseudoLbDict[self.lbStart][3]
492
493 #print (self.lbStart, self.timeStart, self.timeEnd, time.strftime('%a %b %d %X %Z %Y',time.localtime(self.timeStart)))
494
495 if not BeamSpotValue.coolQuery:
496 from InDetBeamSpotExample.COOLUtils import COOLQuery
497 BeamSpotValue.coolQuery = COOLQuery()
498
499 try:
500 self.fill = BeamSpotValue.coolQuery.getLHCInfo(self.timeStart).get('FillNumber',0)
501 except Exception:
502 pass
503
504 return
505
506 def fillDataFromDQ(self):
507 """
508 Fill DQ defects assuming that any defect is valid for the full fit range
509 """
510 from InDetBeamSpotExample.DQUtilities import IDBSDefectEncoding
511
512 if not BeamSpotValue.defectData:
513 from InDetBeamSpotExample.DQUtilities import IDBSDefectData
514 BeamSpotValue.defectData = IDBSDefectData()
515
516 defects = BeamSpotValue.defectData.defectsRange(self.run, self.lbStart, self.lbEnd)
517 self.defectWord = IDBSDefectEncoding.defectListToInt(defects)
518 return
519
520
521 def __str__(self):
522 s = self.summary()+'\n'
523 if self.timeStart or self.timeEnd:
524 s += '%s - %s\n' % (time.strftime('%a %b %d %X %Z %Y',time.localtime(self.timeStart)),
525 time.strftime('%a %b %d %X %Z %Y',time.localtime(self.timeEnd)))
526 for v in ['posX','posY','posZ',
527 'sigmaX','sigmaY','sigmaZ',
528 'tiltX','tiltY','sigmaXY','k']:
529 s += '... %6s: %s +- %s %s\n' % (v,
530 fmtVal(v,getattr(self,v)),
531 fmtVal(v,getattr(self,v+'Err')),
532 varDef(v,'units'))
533 return s
534
535 def summary(self):
536 """Get one-line summary info."""
537 return '[%i, %i - %i), fill %i, BCID %i: %i events, %i selected, status %i' % (self.run,self.lbStart,self.lbEnd,
538 self.fill,self.bcid,
539 self.nEvents,self.nValid,self.status)
540
541 def dump(self,verbose=False):
542 """Standard printout of beam spot parameters."""
543 if verbose:
544 print (self)
545 else:
546 print (self.summary())
547
548 def varList(self):
549 """Get list of variable names in BeamSpotValue object."""
550 l = []
551 for name in dir(self):
552 # can we test for type(...) == property?
553 if name in BeamSpotValue.propertyList:
554 continue
555 o = getattr(self,name)
556 if isinstance(o,int) or isinstance(o,float):
557 l.append(name)
558 return l
559
560 def getROOTType(self,var):
561 """Get ROOT type of variable (either /I or /F)."""
562 o = getattr(self,var)
563 if isinstance(o,int):
564 return '/I'
565 else:
566 return '/F'
567
568 def getROOTStruct(self):
569 """Return a string with a C struct describing all data members of the instance.
570 Intended for creating ROOT tree buffer objects via ROOT.gROOT.ProcessLine()."""
571 s = 'struct BeamSpotNtBuf {'
572 for name in self.varList():
573 o = getattr(self,name)
574 if isinstance(o,int):
575 s += ' Int_t %s;' % name
576 if isinstance(o,float):
577 s += ' Float_t %s;' % name
578 s += '};'
579 return s
580
581 def __lt__(self, other):
582 if self.run != other.run:
583 return self.run.__lt__(other.run)
584 if self.bcid != other.bcid:
585 return self.bcid.__lt__(other.bcid)
586
587 return self.lbStart.__lt__(other.lbStart)
588
589
591 """A utility class for averaging beam spot data."""
592
593 def __init__(self,varList=None,weightedAverage=True):
594 if varList:
595 self.varList = varList
596 else:
597 self.varList = ['posX','posY','posZ','sigmaX','sigmaY','sigmaZ','tiltX','tiltY','rhoXY','k']
598 self.weightedAverage = weightedAverage
599 self.sumw = numpy.zeros(len(self.varList))
600 self.sumwx = numpy.zeros(len(self.varList))
601 self.sumwxx = numpy.zeros(len(self.varList))
602 self.sumwwee = numpy.zeros(len(self.varList))
603 # Unweighted quantities always needed for RMS
604 self.sum = numpy.zeros(len(self.varList))
605 self.sumx = numpy.zeros(len(self.varList))
606 self.sumxx = numpy.zeros(len(self.varList))
607 self.nWarnings = 0
608 self.lumiData = None # luminosity data in ubarn, indexed by [run][LB]
609
610 def readLumiData(self,lumiCalcNtupleName):
611 """Read iLumiCalc.exe ntuple with luminosity data, store data in self.lumiData dict."""
612 lumiFile = ROOT.TFile(lumiCalcNtupleName)
613 lumiNt = lumiFile.Get('LumiMetaData')
614 print ('Reading',lumiNt.GetEntries(), 'entries from luminosity ntuple',lumiCalcNtupleName)
615 self.lumiData = {}
616 for j in range(lumiNt.GetEntries()):
617 lumiNt.GetEntry(j)
618 run = lumiNt.RunNbr
619 lb = lumiNt.LBStart
620 lumi = lumiNt.IntLumi
621 try:
622 self.lumiData[run][lb] = lumi
623 except Exception:
624 self.lumiData[run] = {}
625 self.lumiData[run][lb] = lumi
626 lumiSum = 0.
627 for (run,lbdict) in self.lumiData.items():
628 for (lb,lumi) in lbdict.items():
629 lumiSum += lumi
630 print ('... total luminosity = %6.1f / pb' % (lumiSum/1.E6))
631 return self.lumiData
632
633 def add(self,b):
634 """Add elements of BeamSpotValue b to average."""
635 if self.lumiData is not None:
636 lumi = 0
637 if b.lbEnd <= b.lbStart:
638 print ('ERROR: Illegal luminosity block range: [%i,%i]' % (b.lbStart,b.lbEnd))
639 self.nWarnings += 1
640 for lb in range(b.lbStart,b.lbEnd):
641 try:
642 lumi += self.lumiData[b.run][lb]
643 except Exception:
644 print ('ERROR: missing luminosity information for run %i LB %i (in [%i,%i]) - weight set to zero!!' % (b.run,lb,b.lbStart,b.lbEnd))
645 self.nWarnings += 1
646 for i in range(len(self.varList)):
647 parName = self.varList[i]
648 val = getattr(b,parName)
649 valErr = getattr(b,parName+'Err')
650 self.sum[i] += 1.
651 self.sumx[i] += val
652 self.sumxx[i] += val*val
653 if self.lumiData is None:
654 if valErr != 0. :
655 w = 1./valErr/valErr
656 else:
657 w = 1e-16
658 print ('WARNING: Divison by zero for parameter %s (val = %f valErr = %f)\n' % (parName,val,valErr))
659 self.nWarnings += 1
660 else:
661 w = lumi
662 self.sumw[i] += w
663 self.sumwx[i] += w*val
664 self.sumwxx[i] += w*val*val
665 self.sumwwee[i] += w*w*valErr*valErr
666
667 def average(self):
668 self.rms = numpy.sqrt(self.sumxx/self.sum - self.sumx*self.sumx/self.sum/self.sum) # factor n/n-1 ?
669 if self.weightedAverage:
670 if self.lumiData is None:
671 self.ave = self.sumwx/self.sumw
672 self.err = 1./numpy.sqrt(self.sumw)
673 else:
674 self.ave = self.sumwx/self.sumw
675 self.err = numpy.sqrt(self.sumwwee)/self.sumw
676 else:
677 self.ave = self.sumx/self.sum
678 self.err = self.rms/numpy.sqrt(self.sum)
679
680 def getIndex(self, varName):
681 for i in range(len(self.varList)):
682 if self.varList[i]==varName:
683 return i
684 return None
685
686
687
689 """A utility class for accumulating beam spot data into TGraphErrors."""
690
691 def __init__(self, timeAxis = False, bcidAxis = False, separationAxis = False):
692 self.timeAxis = timeAxis
693 self.bcidAxis = bcidAxis
694 self.separationAxis = separationAxis
695 self.x = array('d')
696 self.y = array('d')
697 self.ex = array('d')
698 self.ey = array('d')
699 self.xmin = 1E10
700 self.xmax = -1E10
701 self.ymin = 1E10
702 self.ymax = -1E10
703 self.xoffset = 0
704 self.what = None
705
706 def add(self,bs,what,arescale=1.):
707 """Add element what of BeamSpotValue bs to the graph."""
708 self.what = what
709 y = arescale*getattr(bs,what) # Raise exception if not attribute what
710 ey = arescale*getattr(bs,what+'Err',0)
711 ex = (bs.lbEnd - bs.lbStart)/2.
712 x = self.xoffset + bs.lbStart + ex
713
714 if self.timeAxis:
715 ex = (bs.timeEnd - bs.timeStart)/2.
716 x = self.xoffset + bs.timeStart + ex
717 if self.bcidAxis:
718 ex = 0
719 x = bs.bcid
720 if self.separationAxis:
721 ex = 0
722 x = bs.separation
723
724 self.x.append(x)
725 self.ex.append(ex)
726 self.y.append(y)
727 self.ey.append(ey)
728 self.xmin = min(x-ex,self.xmin)
729 self.xmax = max(x+ex,self.xmax)
730 self.ymin = min(y-ey,self.ymin)
731 self.ymax = max(y+ey,self.ymax)
732
733 def getTGraph(self,name=''):
734 if len(self.x)>0:
735 gr = ROOT.TGraphErrors(len(self.x),self.x,self.y,self.ex,self.ey)
736 if not name:
737 name = self.what
738 gr.SetName(name)
739 gr.SetTitle(name)
740 else:
741 gr = None
742 return gr
743
744
746 """Base class for containers of beam spot data such as ntuples or
747 information stored in COOL. Derived classes must implement method
748 allData() to iterate over all elements in the container."""
749
750 def __init__(self):
751 # Cuts for selecting entries in the container
752 self.runMin = 0
753 self.runMax = 9999999
754 self.runList = []
755 self.runListExclude = []
756 self.fillMin = 0
757 self.fillMax = 9999999
758 self.bcidMin = 0
759 self.bcidMax = 9999999
760 self.lbMin = 0
761 self.lbMax = 9999999999
762 self.timeMin = 0
763 self.timeMax = 2000000000
764 self.statusList = []
765 self.acqFlag = None
766 self.grl = ''
767 self.grlIOVs = None
768 self.previousGRLIndex = 0 # Cache last GRL index look up time
769
770 # Iterator
771 self.iter = None
772
773 # Statistics on selected data
774 self.initStatistics()
775
776 def initStatistics(self):
777 self.nTot = 0
778 self.nSel = 0
779 self.selRunMin = 9999999
780 self.selRunMax = 0
781 self.selFillMin = 9999999
782 self.selFillMax = 0
783 self.selBcidMin = 9999999
784 self.selBcidMax = 0
785 self.selTimeMin = 2000000000
786 self.selTimeMax = -1
787
788 #def __call__(self):
789 # """Iterator to iterate over selected elements in the container."""
790 # return self.allData()
791
792 def __iter__(self):
793 """Iterator to iterate over selected elements in the container."""
794 self.iter = self.selectedData()
795 return self
796
797 def next(self):
798 """Return next selected element in the container."""
799 return next(self.iter)
800
801 def __next__(self):
802 """Return next selected element in the container."""
803 return self.next()
804
805 def allData(self):
806 """Default generator to iterate over all data. Must be overridden by derived classes."""
807 raise StopIteration()
808
809 def selectedData(self):
810 """Generator to iterate over selected elements in the container."""
811 self.initStatistics()
812
813 self.previousGRLIndex = 0
814
815 for b in self.allData():
816 self.nTot +=1
817 if b.run<self.runMin: continue
818 if b.run>self.runMax: continue
819 if self.runList and b.run not in self.runList: continue
820 if self.runListExclude and b.run in self.runListExclude: continue
821 if b.fill<self.fillMin: continue
822 if b.fill>self.fillMax: continue
823 if b.bcid<self.bcidMin: continue
824 if b.bcid>self.bcidMax: continue
825 if b.lbStart<self.lbMin: continue
826 if b.lbEnd-1>self.lbMax: continue # lbEnd is exclusive
827 if b.timeStart<self.timeMin: continue
828 if b.timeEnd>self.timeMax: continue
829 if self.statusList and b.status not in self.statusList: continue
830 #if self.acqFlag is not None and b.acquisitionFlag != self.acqFlag: continue
831
832 if self.grl:
833 # Check if in GRL
834 from DQUtils.sugar import RANGEIOV_VAL, RunLumi
835 from DQUtils import IOVSet
836
837 # Get IoVs from GRL
838 if self.grlIOVs is None:
839 self.grlIOVs = IOVSet.from_grl(self.grl)
840
841 idx = self.previousGRLIndex
842
843 # Get current IoV
844 test_iov = RANGEIOV_VAL(RunLumi(b.run, b.lbStart), RunLumi(b.run, b.lbEnd)) # COOL convention, ie lbEnd is exclusive
845
846 # Search for IoV in GRL IoVs
847 for i, iov in enumerate(self.grlIOVs[idx:]):
848 if (test_iov.since >= iov.since and test_iov.until <= iov.until):
849 self.previousGRLIndex = idx + i
850 break
851 else:
852 # Only if don't break -> IOV not found so skip
853 continue
854
855
856 self.nSel += 1
857 self.selRunMin = min(self.selRunMin,b.run)
858 self.selRunMax = max(self.selRunMax,b.run)
859 self.selFillMin = min(self.selFillMin,b.fill)
860 self.selFillMax = max(self.selFillMax,b.fill)
861 self.selBcidMin = min(self.selBcidMin,b.bcid)
862 self.selBcidMax = max(self.selBcidMax,b.bcid)
863 self.selTimeMin = min(self.selTimeMin,b.timeStart)
864 self.selTimeMax = max(self.selTimeMax,b.timeEnd)
865 yield b
866 print ('\n%i entries selected out of total of %i entries in ntuple:' % (self.nSel,self.nTot))
867 print ('... runs %6i - %6i' % (self.selRunMin,self.selRunMax))
868 print ('... fills %6i - %6i' % (self.selFillMin,self.selFillMax))
869 print ('... bcids %6i - %6i' % (self.selBcidMin,self.selBcidMax))
870 print ('... %s - %s' % (time.strftime('%a %b %d %X %Z %Y',time.localtime(self.selTimeMin)),
871 time.strftime('%a %b %d %X %Z %Y',time.localtime(self.selTimeMax))))
872 print()
873
874 def getDataCache(self):
875 """Get a cache of all data in the form of a dict of runs, where each element
876 is a dict with a BeamSpotValue for each individual lumi blocks."""
877 cache = {}
878 for b in self:
879 r = b.run
880 if r not in cache:
881 cache[r] = {}
882 if b.lbEnd-b.lbStart > 500:
883 print ('WARNING: Cannot cache LB range %i ... %i for run %i' % (b.lbStart,b.lbEnd,r))
884 else:
885 for i in range(b.lbStart,b.lbEnd+1):
886 if b.status in self.statusList or not self.statusList:
887 cache[r][i] = b
888 return cache
889
890 def summary(self):
891 """Get one-line info of Ntuple. Should be overridden by derived classes."""
892 return "BeamSpotContainer base class"
893
894 def cutSummary(self):
895 """Get summary of cuts made when looping over selected data."""
896 s = 'Cuts:\n'
897 s += ' run %7i ... %7i\n' % (self.runMin,self.runMax)
898 s += ' runList %7s\n' % str(self.runList)
899 s += ' runListExcluded %7s\n' % str(self.runListExclude)
900 s += ' fill %7i ... %7i\n' % (self.fillMin,self.fillMax)
901 s += ' bcid %7i ... %7i\n' % (self.bcidMin,self.bcidMax)
902 s += ' LB %7i ... %7i\n' % (self.lbMin,self.lbMax)
903 s += ' fit status %7s\n' % str(self.statusList)
904 s += ' %s - %s' % (time.strftime('%a %b %d %X %Z %Y',time.localtime(self.timeMin)),
905 time.strftime('%a %b %d %X %Z %Y',time.localtime(self.timeMax)))
906 s += ' acquisition flag %7s' % self.acqFlag
907 if self.grl:
908 s += ' GRL %s\n' % self.grl
909 return s
910
911
912
913ROOT.gROOT.ProcessLine(BeamSpotValue(fullCorrelations=True,addScanVars=True).getROOTStruct())
914from ROOT import BeamSpotNtBuf
915from cppyy.ll import cast
916
918 """BeamSpotContainer for master beam spot ntuple."""
919
920 def __init__(self,fileName,update=False,fullCorrelations=False,addScanVars=False):
921 BeamSpotContainer.__init__(self)
922 self.treeName = 'BeamSpotNt'
923 self.fileName = fileName
924 self.update = update
925 self.fullCorrelations = fullCorrelations
926 self.addScanVars = addScanVars
927
928 if update:
930 self.rootFile = ROOT.TFile(fileName,'UPDATE')
931 self.ntbuf = BeamSpotNtBuf() # Not intialized
932 self.nt = self.rootFile.Get(self.treeName)
933 if not self.nt:
934 self.nt = ROOT.TTree(self.treeName,'Master beam spot ntuple')
935 for v in bs.varList():
936 varType = bs.getROOTType(v)
937 self.nt.Branch(v,ROOT.addressof( self.ntbuf,v), v+varType)
938 else:
939 for v in bs.varList():
940 self.nt.SetBranchAddress(v,cast['void*'](ROOT.addressof(self.ntbuf,v)))
941 else:
942 self.rootFile = ROOT.TFile(fileName)
943 self.nt = self.rootFile.Get(self.treeName)
944 if not self.nt:
945 raise ValueError ('Tree %s not found in ntuple file %s' % (self.treeName,self.fileName))
946
947 # Register instance's __del__() with exit handler
948 # This is needed for ROOT >= 5.28 to prevent ROOTs exit handler cleaning up the file
949 # before we have closed/written to it. Only needed if use TFile in __del__
950 atexit.register(self.__del__)
951
952 def __del__(self):
953 # Prevent caling more than one (atexit/explicit del)
954 if self.rootFile is not None:
955 if self.update:
956 self.rootFile.Write('',2) # don't keep old versions
957 self.rootFile.Close()
958 self.rootFile = None
959
960 def allData(self):
961 varList = BeamSpotValue(self.fullCorrelations).varList()
962 for j in range(self.nt.GetEntries()):
963 self.nt.GetEntry(j)
965 for v in varList:
966 setattr(bs,v,getattr(self.nt,v,0))
967 yield bs
968
969 def fill(self,bs):
970 for v in bs.varList():
971 setattr(self.ntbuf,v,getattr(bs,v))
972 self.nt.Fill()
973
974 def summary(self):
975 s = '%s:\n' % (self.fileName)
976 if self.update:
977 s += ' UPDATE MODE enabled\n'
978 s += ' %s ntuple in tree %s\n' % (self.__class__.__name__,self.treeName)
979 s += ' %i entries\n' % (self.nt.GetEntries())
980 return s
981
982
984 """BeamSpotContainer for ntuples created by InDetBeamSpotFinder."""
985
986 # Status word conversion maps
987 # For status word definition see https://twiki.cern.ch/twiki/bin/view/Atlas/CoolBeamSpotParameters#Definition_of_the_Status_Word
988 # InDetBeamSpotFinder uses (see InDetBeamSpotFinder/IInDetBeamSpotTool.h):
989 # enum FitResult {unsolved=0, successful, failed, problems};
990 # enum FitID {vertexLL=1, vertexChi2=2, trackChi2=3, userDefined=4,unknown = 99};
991 fitResultToStatusMap = {0: 0, 1: 3, 2: 0, 3: 0}
992 fitIdToStatusMap = {1: 0x38, 2: 0x40, 3: 0x10}
993
994 def __init__(self,fileName,treeName = 'BeamSpotNt',fullCorrelations=True):
995 BeamSpotContainer.__init__(self)
996 self.fileName = fileName
997 self.treeName = treeName
998 self.rootFile = ROOT.TFile(fileName)
999 self.nt = self.rootFile.Get(treeName)
1000 self.fullCorrelations = fullCorrelations
1001 if not self.nt:
1002 raise ValueError ('Tree %s not found in ntuple file %s' % (treeName,fileName))
1003
1004 # Register instance's __del__() with exit handler
1005 # This is needed for ROOT >= 5.28 to prevent ROOTs exit handler cleaning up the file
1006 # before we have closed/written to it. Only needed if use TFile in __del__
1007 atexit.register(self.__del__)
1008
1009 def __del__(self):
1010 # Prevent caling more than one (atexit/explicit del)
1011 if self.rootFile is not None:
1012 self.rootFile.Close()
1013 self.rootFile = None
1014
1015 def allData(self):
1016 for j in range(self.nt.GetEntries()):
1017 self.nt.GetEntry(j)
1019 #try:
1020 # bs.status = BeamSpotFinderNt.fitIdToStatusMap[self.nt.fitID]+BeamSpotFinderNt.fitResultToStatusMap[self.nt.fitStatus]
1021 #except Exception:
1022 # bs.status = 0
1023 # print ("ERROR: can't translate (fitID,fitStatus) = (%i,%i) into status word" % (self.nt.fitID,self.nt.fitStatus))
1024 bs.run = self.nt.run
1025 try:
1026 bs.bcid = self.nt.bcid
1027 except Exception:
1028 pass
1029 bs.lbStart = self.nt.lumiStart
1030 bs.lbEnd = self.nt.lumiStart+self.nt.lumiRange
1031 bs.nEvents = self.nt.nEvents
1032 try:
1033 bs.nValid = self.nt.nValid
1034 except Exception:
1035 pass
1036 try:
1037 bs.nVtxAll = self.nt.nVtxAll
1038 except Exception:
1039 pass
1040 try:
1041 bs.nVtxPrim = self.nt.nVtxPrim
1042 except Exception:
1043 pass
1044 bs.posX = self.nt.xc
1045 bs.posY = self.nt.yc
1046 bs.posZ = self.nt.z
1047 bs.sigmaX = self.nt.sx
1048 bs.sigmaY = self.nt.sy
1049 bs.sigmaZ = self.nt.sz
1050 bs.tiltX = self.nt.ax
1051 bs.tiltY = self.nt.ay
1052 bs.rhoXY = self.nt.rhoxy
1053 bs.k = self.nt.k
1054 bs.posXErr = sqrt(self.nt.xcxc)
1055 bs.posYErr = sqrt(self.nt.ycyc)
1056 bs.posZErr = sqrt(self.nt.zz)
1057 bs.sigmaXErr = sqrt(self.nt.sxsx)
1058 bs.sigmaYErr = sqrt(self.nt.sysy)
1059 bs.sigmaZErr = sqrt(self.nt.szsz)
1060 bs.tiltXErr = sqrt(self.nt.axax)
1061 bs.tiltYErr = sqrt(self.nt.ayay)
1062 bs.rhoXYErr = sqrt(self.nt.rhoxyrhoxy)
1063 bs.kErr = sqrt(self.nt.kk)
1064 bs.covSxSy = self.nt.sxsy
1065 bs.covSxRhoXY = self.nt.sxrhoxy
1066 bs.covSyRhoXY = self.nt.syrhoxy
1067
1068 bs.covXY = self.nt.x0y0
1069 bs.covXZ = self.nt.x0z
1070 bs.covXSx = self.nt.x0sx
1071 bs.covXSy = self.nt.x0sy
1072 bs.covXSz = self.nt.x0sz
1073 bs.covXTiltX = self.nt.x0ax
1074 bs.covXTiltY = self.nt.x0ay
1075 bs.covXRhoXY = self.nt.x0rhoxy
1076 bs.covXk = self.nt.x0k
1077
1078 bs.covYZ = self.nt.y0z
1079 bs.covYSx = self.nt.y0sx
1080 bs.covYSy = self.nt.y0sy
1081 bs.covYSz = self.nt.y0sz
1082 bs.covYTiltX = self.nt.y0ax
1083 bs.covYTiltY = self.nt.y0ay
1084 bs.covYRhoXY = self.nt.y0rhoxy
1085 bs.covYk = self.nt.y0k
1086
1087 bs.covZSx = self.nt.zsx
1088 bs.covZSy = self.nt.zsy
1089 bs.covZSz = self.nt.zsz
1090 bs.covZTiltX = self.nt.zax
1091 bs.covZTiltY = self.nt.zay
1092 bs.covZRhoXY = self.nt.zrhoxy
1093 bs.covZk = self.nt.zk
1094
1095 bs.covTiltXTiltY = self.nt.axay
1096 bs.covTiltXSx = self.nt.axsx
1097 bs.covTiltXSy = self.nt.axsy
1098 bs.covTiltXSz = self.nt.axsz
1099 bs.covTiltXRhoXY = self.nt.axrhoxy
1100 bs.covTiltXk = self.nt.axk
1101
1102 bs.covTiltYSx = self.nt.aysx
1103 bs.covTiltYSy = self.nt.aysy
1104 bs.covTiltYSz = self.nt.aysz
1105 bs.covTiltYRhoXY = self.nt.ayrhoxy
1106 bs.covTiltYk = self.nt.ayk
1107
1108 bs.covSxSz = self.nt.sxsz
1109 bs.covSxk = self.nt.sxk
1110
1111 bs.covSySz = self.nt.sysz
1112 bs.covSyk = self.nt.syk
1113
1114 bs.covSzRhoXY = self.nt.szrhoxy
1115 bs.covSzk = self.nt.szk
1116
1117 bs.covRhoXYk = self.nt.rhoxyk
1118
1119 yield bs
1120
1121 def summary(self):
1122 s = '%s:\n' % (self.fileName)
1123 s += ' %s ntuple in tree %s\n' % (self.__class__.__name__,self.treeName)
1124 s += ' %i entries\n' % (self.nt.GetEntries())
1125 return s
1126
1127
1129 """BeamSpotContainer for beam spot information stored in COOL."""
1130
1131 def __init__(self, tag, database='COOLOFL_INDET/CONDBR2', folder='/Indet/Beampos', fullCorrelations=False):
1132 BeamSpotContainer.__init__(self)
1133 self.database = database
1134 self.tag = tag
1135 self.folder = folder
1136 from CoolConvUtilities import AtlCoolLib
1137 self.cooldb = AtlCoolLib.indirectOpen(database, True, True)
1138
1139 def __del__(self):
1140 self.cooldb.closeDatabase()
1141
1142 def allData(self):
1143 from PyCool import cool
1144
1145 folder = self.cooldb.getFolder(self.folder)
1146
1147 iov1 = self.runMin << 32
1148 iov2 = (self.runMax+1) << 32
1149 if (iov2>cool.ValidityKeyMax):
1150 iov2=cool.ValidityKeyMax
1151
1152 itr = folder.browseObjects(iov1, iov2, cool.ChannelSelection.all(), self.tag)
1153
1154 while itr.goToNext():
1155
1156 obj = itr.currentRef()
1157
1158 since = obj.since()
1159 runBegin = since >> 32
1160 lumiBegin = since & 0xFFFFFFFF
1161
1162 until = obj.until()
1163 lumiUntil = until & 0xFFFFFFFF
1164
1165 bs = BeamSpotValue()
1166 bs.run = int(runBegin)
1167 bs.lbStart = int(lumiBegin)
1168 bs.lbEnd = int(lumiUntil)
1169 bs.posX = float(obj.payloadValue('posX'))
1170 bs.posY = float(obj.payloadValue('posY'))
1171 bs.posZ = float(obj.payloadValue('posZ'))
1172 bs.sigmaX = float(obj.payloadValue('sigmaX'))
1173 bs.sigmaY = float(obj.payloadValue('sigmaY'))
1174 bs.sigmaZ = float(obj.payloadValue('sigmaZ'))
1175 bs.tiltX = float(obj.payloadValue('tiltX'))
1176 bs.tiltY = float(obj.payloadValue('tiltY'))
1177 bs.status = int(obj.payloadValue('status'))
1178 bs.posXErr = float(obj.payloadValue('posXErr'))
1179 bs.posYErr = float(obj.payloadValue('posYErr'))
1180 bs.posZErr = float(obj.payloadValue('posZErr'))
1181 bs.sigmaXErr = float(obj.payloadValue('sigmaXErr'))
1182 bs.sigmaYErr = float(obj.payloadValue('sigmaYErr'))
1183 bs.sigmaZErr = float(obj.payloadValue('sigmaZErr'))
1184 bs.tiltXErr = float(obj.payloadValue('tiltXErr'))
1185 bs.tiltYErr = float(obj.payloadValue('tiltYErr'))
1186
1187 # COOL stores sigmaXY but BeamSpotData wants rho
1188 sigmaXYtmp = float(obj.payloadValue('sigmaXY'))
1189 sigmaXtmp = float(obj.payloadValue('sigmaX'))
1190 sigmaYtmp = float(obj.payloadValue('sigmaY'))
1191 sigmaXYErrtmp = float(obj.payloadValue('sigmaXYErr'))
1192 sigmaXErrtmp = float(obj.payloadValue('sigmaXErr'))
1193 sigmaYErrtmp = float(obj.payloadValue('sigmaYErr'))
1194
1195 try:
1196 rhoXYtmp = sigmaXYtmp / sigmaXtmp / sigmaYtmp
1197 except Exception:
1198 rhoXYtmp = 0
1199 bs.rhoXY = rhoXYtmp
1200
1201 try:
1202 sumtmp = sigmaXYErrtmp * sigmaXYErrtmp / sigmaXYtmp / sigmaXYtmp
1203 sumtmp += sigmaXErrtmp * sigmaXErrtmp / sigmaXtmp / sigmaXtmp
1204 sumtmp += sigmaYErrtmp * sigmaYErrtmp / sigmaYtmp / sigmaYtmp
1205 rhoXYErrtmp = sqrt(rhoXYtmp * rhoXYtmp * sumtmp)
1206 except Exception:
1207 rhoXYErrtmp = 0
1208
1209 bs.rhoXYErr = rhoXYErrtmp
1210
1211 yield bs
1212
1213 def summary(self):
1214 s = 'COOL database %s, tag %s:\n' % (self.database,self.tag)
1215 s += ' %s ntuple, COOL folder %s\n' % (self.__class__.__name__,self.folder)
1216 return s
1217
1219 """BeamSpotContainer for beam spot information stored in online CSV files"""
1220
1221 def __init__(self, filename='/afs/cern.ch/user/a/atlidbs/data/69OnlineBeamspots.csv', delim=','):
1222 BeamSpotContainer.__init__(self)
1223 self.csvFile = open(filename, 'rb')
1224 self.csvReader = csv.DictReader(self.csvFile, delimiter=delim)
1225
1226 def __del__(self):
1227 self.csvFile.close()
1228
1229 def allData(self):
1230
1231 for row in self.csvReader:
1232
1233 bs = BeamSpotValue()
1234
1235 bs.run = int(row['run'])
1236 bs.lbStart = int(row['firstLBN'])
1237 bs.lbEnd = int(row['lastLBN'])
1238 bs.posX = float(row['posX'])
1239 bs.posY = float(row['posY'])
1240 bs.posZ = float(row['posZ'])
1241 bs.sigmaX = float(row['sigmaX'])
1242 bs.sigmaY = float(row['sigmaY'])
1243 bs.sigmaZ = float(row['sigmaZ'])
1244 bs.tiltX = float(row['tiltX'])
1245 bs.tiltY = float(row['tiltY'])
1246 bs.status = int(row['status'])
1247
1248 bs.posXErr = float(row['posXE'])
1249 bs.posYErr = float(row['posYE'])
1250 bs.posZErr = float(row['posZE'])
1251 bs.sigmaXErr = float(row['sigmaXE'])
1252 bs.sigmaYErr = float(row['sigmaYE'])
1253 bs.sigmaZErr = float(row['sigmaZE'])
1254 bs.tiltXErr = float(row['tiltXE'])
1255 bs.tiltYErr = float(row['tiltYE'])
1256
1257 yield bs
1258
1259
1260 def summary(self):
1261 s = 'CSV file %s:\n' % self.filename
1262 s += ' %s ntuple\n' % (self.__class__.__name__)
1263 return s
1264
1265# Test code for modules
1266if __name__ == '__main__':
1267
1268 #Test for ntuple reading
1269 #data = BeamSpotFinderNt('/afs/cern.ch/user/a/atlidbs/jobs/data10_7TeV.00167776.express_express/DB_BEAMSPOT.x50_c323/data10_7TeV.00167776.express_express-DB_BEAMSPOT.x50_c323.MergeNt-nt.root')
1270 data = BeamSpotNt('/afs/cern.ch/user/a/atlidbs/nt/beamspotnt-IndetBeampos-Oct10-Collision_7T_2010_07-v1.root')
1271
1272 #Test for COOL reading
1273 #data = BeamSpotCOOL('IndetBeampos-ES1-UPD2')
1274 #data.runMin = 167844
1275 #data.runMax = 167844
1276
1277 #Test for CSV reading
1278 #data = BeamSpotCSV("/afs/cern.ch/user/a/atlidbs/data/69OnlineBeamspots.csv")
1279 for b in data:
1280 print (b)
1281 pass
void print(char *figname, TCanvas *c1)
TGraphErrors * GetEntries(TH2F *histo)
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
STL class.
__init__(self, varList=None, weightedAverage=True)
readLumiData(self, lumiCalcNtupleName)
__init__(self, tag, database='COOLOFL_INDET/CONDBR2', folder='/Indet/Beampos', fullCorrelations=False)
__init__(self, filename='/afs/cern.ch/user/a/atlidbs/data/69OnlineBeamspots.csv', delim=',')
__init__(self, fileName, treeName='BeamSpotNt', fullCorrelations=True)
add(self, bs, what, arescale=1.)
__init__(self, timeAxis=False, bcidAxis=False, separationAxis=False)
__init__(self, fileName, update=False, fullCorrelations=False, addScanVars=False)
fillDataFromPseudoLb(self, pseudoLbFile, timeUnit=1.)
__init__(self, fullCorrelations=False, addScanVars=False)
T * Get(TFile &f, const std::string &n, const std::string &dir="", const chainmap_t *chainmap=0, std::vector< std::string > *saved=0)
get a histogram given a path, and an optional initial directory if histogram is not found,...
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
-event-from-file
varDef(var, property, default='', useAlternate=False, override=None)
fmtVal(var, value, strip=False, useAlternate=False)