ATLAS Offline Software
Loading...
Searching...
No Matches
bsPlotVsMu.py
Go to the documentation of this file.
1#! /usr/bin/env python
2
3# Copyright (C) 2020-2020 CERN for the benefit of the ATLAS collaboration
4
5
6"""
7Plot beamspot properties vs mu
8"""
9__author__ = 'Anthony Morley'
10__version__ = ''
11__usage__ = '''%prog [options] [database1] [database2]
12
13Database can be either connection string or db file:
14
15 e.g COOLOFL_INDET/CONDBR2 (default)
16 beamspot.db/BEAMSPOT
17
18Example:
19
20 PlotVsMu --rl 341123 --ru 341123
21
22'''
23
24from DQUtils import fetch_iovs, process_iovs
25from DQUtils.sugar import IOVSet,RANGEIOV_VAL,RunLumiType
26from array import array
27import math
28import time, datetime
29from InDetBeamSpotExample import BeamSpotData
30BeamSpotData.varDefs = getattr(BeamSpotData,'varDefsGen')
32from CoolLumiUtilities.CoolDataReader import CoolDataReader
33
34import ROOT
35ROOT.gROOT.SetBatch(1)
36
37lumiTag_default = 'OflLumi-Run3-001' # For Run 2 was OflPrefLumi-RUN2-UPD4-12
38indetbsTag_default = 'IndetBeampos-RUN3-ES1-UPD2-02' # For Run 2 was IndetBeampos-RUN2-ES1-UPD2-15
39
40from optparse import OptionParser
41parser = OptionParser(usage=__usage__, version=__version__)
42parser.add_option('', '--folderBS', dest='folderBS', default='/Indet/Beampos', help='Folder name (default: /Indet/Beampos)')
43parser.add_option('', '--folderLumi', dest='folderLumi', default='/TRIGGER/OFLLUMI/OflPrefLumi', help='Folder name (default: /TRIGGER/OFLLUMI/OflPrefLumi')
44parser.add_option('', '--tagBS', dest='tagBS', default=indetbsTag_default, help='Tag to compare (default: '+indetbsTag_default+')')
45parser.add_option('', '--tagLumi', dest='tagLumi', default=lumiTag_default, help='Tag to compare to (default: '+lumiTag_default+')')
46parser.add_option('', '--rl', dest='runMin', type='int', default=None, help='Start run number (default: None)')
47parser.add_option('', '--ru', dest='runMax', type='int', default=None, help='Max run number (default: None)')
48parser.add_option('-p', '--plot', dest='plot', default='', help='quantity to plot, only make one plot')
49parser.add_option('', '--plotGraph' , dest='plotGraph', action="store_true", default=False, help='plot a graph instead of an histogram')
50parser.add_option('', '--noPlot', dest='plotSomething', action="store_false", default=True, help='plot something')
51(options,args) = parser.parse_args()
52
53db1 = args[0] if len(args)==1 else 'COOLOFL_INDET/CONDBR2'
54db2 = args[1] if len(args)==2 else 'COOLOFL_TRIGGER/CONDBR2'
55
56# What variables to look at
57varColl = []
58varPlot = []
59
60if options.plot:
61 varColl = ['posX','posY','posZ','sigmaX','sigmaY','sigmaZ']
62 varPlot.append(options.plot)
63else:
64 varColl = ['posX','posY','posZ','sigmaX','sigmaY','sigmaZ']
65 varPlot.append(options.plot)
66
67
68
69def main():
70 f1 = "%s::%s" % (db1, options.folderBS)
71 f2 = "%s::%s" % (db2, options.folderLumi)
72
73 print( "="*100 )
74 print( "Comparing: " )
75 print( " * ", f1, options.tagBS )
76 print( " * ", f2, options.tagLumi )
77 print( "="*100 )
78
79 requiredForNtuple = ['posX','posY','posZ','sigmaX','sigmaY','sigmaZ']
80 checkNtupleProd = all(item in varColl for item in requiredForNtuple)
81 if not checkNtupleProd:
82 print( 'Ntuple will not be filled missing vars' )
83
84
85 #Open up required databases
86 from PyCool import cool
87 from CoolConvUtilities import AtlCoolLib
88 cooldbBS = AtlCoolLib.indirectOpen(db1, True, False)
89 cooldbLumi = AtlCoolLib.indirectOpen(db2, True, False)
90
91 folderBS = cooldbBS.getFolder(options.folderBS)
92 folderLumi = cooldbLumi.getFolder(options.folderLumi)
93
94 from InDetBeamSpotExample.COOLUtils import COOLQuery
95 coolQuery = COOLQuery()
96
97 if options.runMin is not None:
98 iov1 = options.runMin << 32
99 if options.runMax is not None:
100 iov2 = (options.runMax +1) << 32
101 else :
102 iov2 = (options.runMin +1) << 32
103 print( 'Plotting iovs %i to %i ' % (iov1,iov2) )
104 else :
105 print( 'No run selected -- ERROR' )
106 return
107
108 if (iov2>cool.ValidityKeyMax):
109 iov2=cool.ValidityKeyMax
110
111 print( "Reading data from database" )
112 itrBS = folderBS.browseObjects(iov1, iov2, cool.ChannelSelection.all(), options.tagBS)
113 print( "...finished getting BS data" )
114
115 lbDict = dict()
116
117 startRLB =0x7FFFFFFFFFFFFFFF
118 endRLB =0
119
120 outfile = ROOT.TFile("BeamspotLumi_%i.root" % (options.runMin),"recreate")
121 ntuple = ROOT.TNtupleD( 'BeamspotLumi', 'BeamSpotLumi', "x:y:z:sigma_x:sigma_y:sigma_z:run:mu:lumi:year:month:day:hour:minute:epoch" )
122
123
124 runs = set()
125 while itrBS.goToNext():
126
127 obj = itrBS.currentRef()
128
129 since = obj.since()
130
131 runBegin = since >> 32
132 lumiBegin = since & 0xFFFFFFFF
133
134 until = obj.until()
135 runUntil = until >> 32
136 lumiUntil = until & 0xFFFFFFFF
137
138 status = int(obj.payloadValue('status'))
139 if status != 59:
140 continue
141
142 runs.add(runBegin)
143
144 if since < startRLB:
145 startRLB = since
146 if until > endRLB:
147 endRLB = until
148
149
150 values={}
151 for var in varColl:
152 values[var] = float(obj.payloadValue(var))
153 values[var+'Err'] = float(obj.payloadValue(var+'Err'))
154 values['until'] = until
155 lbDict[since] = values
156
157 print( 'Runs: ',runs )
158
159 lumi = array('d')
160 xd = array('d')
161 exd = array('d')
162 ydDict = {}
163 eydDict = {}
164 ydDict2 = {}
165
166 sqtrt2pi = math.sqrt(2*math.pi)
167
168 lblb = CoolDataReader('COOLONL_TRIGGER/CONDBR2', '/TRIGGER/LUMI/LBLB')
169 from DQUtils.sugar import RANGEIOV_VAL, RunLumi
170 from DQUtils import IOVSet
171
172 # 2022 GRL
173 grlIOVs=IOVSet.from_grl("/cvmfs/atlas.cern.ch/repo/sw/database/GroupData/GoodRunsLists/data22_13p6TeV/20221123/data22_13p6TeV.periodEFH_DetStatus-v108-pro28-01_MERGED_PHYS_StandardGRL_All_Good_25ns_ignore__TRIG_HLT_MUO_Upstream_Barrel_problem__TRIG_HLT_MUO_Upstream_Endcap_problem__TRIG_L1_MUB_coverage__TRIG_L1_MUE_misconf_electronics__TRIG_L1_MUB_lost_sync.xml")
174
175 # Run 2 GRLs
176 #grlIOVs=IOVSet.from_grl("data15_13TeV.periodAllYear_DetStatus-v89-pro21-02_Unknown_PHYS_StandardGRL_All_Good_25ns.xml")
177 #grlIOVs+=IOVSet.from_grl("data16_13TeV.periodAllYear_DetStatus-v89-pro21-01_DQDefects-00-02-04_PHYS_StandardGRL_All_Good_25ns.xml")
178 #grlIOVs+=IOVSet.from_grl("data17_13TeV.periodAllYear_DetStatus-v99-pro22-01_Unknown_PHYS_StandardGRL_All_Good_25ns_Triggerno17e33prim.xml")
179 #grlIOVs+=IOVSet.from_grl("data18_13TeV.periodAllYear_DetStatus-v102-pro22-04_Unknown_PHYS_StandardGRL_All_Good_25ns_Triggerno17e33prim.xml")
180
181 for run in runs:
182 iov1 = run << 32
183 iov2 = (run + 1) << 32
184
185 itrLumi = folderLumi.browseObjects(iov1, iov2, cool.ChannelSelection(0), options.tagLumi)
186 print( "...finished getting Lumi data for run %i" % run )
187
188 lblb.setIOVRangeFromRun(run)
189 lblb.readData()
190 if len(lblb.data) < 1:
191 print( 'No LBLB data found!' )
192 continue
193 # Make time map
194 lblbMap = dict()
195 for obj in lblb.data:
196 lblbMap[obj.since()] = (obj.payload()['StartTime'], obj.payload()['EndTime'])
197
198
199 while itrLumi.goToNext():
200 obj = itrLumi.currentRef()
201
202 since = obj.since()
203 runBegin = since >> 32
204 lumiBegin = since & 0xFFFFFFFF
205
206 until = obj.until()
207 runUntil = until >> 32
208 lumiUntil = until & 0xFFFFFFFF
209
210 inGRL = False
211 for sinceGRL, untilGRL, grl_states in process_iovs(grlIOVs):
212 if grl_states[0].since==None:
213 continue
214 if ( sinceGRL.run <= runBegin and untilGRL.run >= runUntil and sinceGRL.lumi <= lumiBegin and untilGRL.lumi >= lumiUntil ):
215 inGRL = True
216 break
217
218 if not inGRL:
219 continue
220
221 mu = float(obj.payloadValue('LBAvEvtsPerBX'))
222 instlumi = float(obj.payloadValue('LBAvInstLumi'))
223
224 #if( mu < 10 or mu > 65 ):
225 # print('Mu: %2.1f Run : %d LB: %d - %d Lumi: %f' % (mu,runBegin,lumiBegin,lumiUntil,instlumi))
226
227 if since in lbDict:
228 if lbDict[ since ]['sigmaX'] > 0.1 :
229 continue
230 startTime = lblbMap.get(obj.since(), (0., 0.))[0]
231 endTime = lblbMap.get(lbDict[ since ]['until'], (0., 0.))[0] #[1] end of lumiblock
232 mylumi = (endTime - startTime)/1e9 * instlumi/1e9
233 thisTime = time.gmtime( startTime /1.e9 )
234 year = thisTime[0]
235 month = thisTime[1]
236 day = thisTime[2]
237 hour = thisTime[3]
238 mins = thisTime[4]
239 sec = thisTime[5]
240 lumi.append( mylumi ); # in fb^-1
241 xd.append(mu)
242 exd.append(0)
243
244 if options.plotSomething:
245 for var in varColl:
246 if not var in ydDict:
247 ydDict[var] = array('d')
248 ydDict2[var] = array('d')
249 eydDict[var] = array('d')
250
251 ydDict2[var].append( mu/(lbDict[ since ][var] * sqtrt2pi ))
252 ydDict[var].append( lbDict[ since ][var] )
253 eydDict[var].append( lbDict[ since ][var+'Err'] )
254
255 if checkNtupleProd and lbDict[ since ]['sigmaZErr'] < 5 :
256 ntuple.Fill( lbDict[ since ][ 'posX'], lbDict[ since ][ 'posY'], lbDict[ since ][ 'posZ'], lbDict[ since ][ 'sigmaX'], lbDict[ since ][ 'sigmaY'], lbDict[ since ][ 'sigmaZ'],runBegin, mu, mylumi, year, month, day,hour, mins, startTime /1.e9 )
257
258
259 runStart = startRLB >> 32
260 runEnd = endRLB >> 32
261 fillStart = fillEnd = 0
262 timeStart = timeEnd = 0
263 beamEnergy = 13.6
264 try:
265 timeStart = coolQuery.lbTime( int(startRLB >> 32), int(startRLB & 0xFFFFFFFF) )[0]
266 except:
267 pass
268 try:
269 timeEnd = coolQuery.lbTime( int(endRLB >> 32), int(endRLB & 0xFFFFFFFF)-1 )[1]
270 except:
271 pass
272 try:
273 fillStart = coolQuery.getLHCInfo(timeStart).get('FillNumber',0)
274 except:
275 pass
276 try:
277 fillEnd = coolQuery.getLHCInfo(timeEnd).get('FillNumber',0)
278 except:
279 pass
280
281 ntuple.Write()
282
283 if not options.plotSomething:
284 return
285
286 from InDetBeamSpotExample import ROOTUtils
288 canvas = ROOT.TCanvas('BeamSpotComparison', 'BeamSpotComparison', 1600, 1200)
289
290 canvas.cd()
291 ROOT.gPad.SetTopMargin(0.05)
292 ROOT.gPad.SetLeftMargin(0.15)
293 ROOT.gPad.SetRightMargin(0.05)
294
295 if not options.plotGraph:
296 ROOT.gPad.SetRightMargin(0.15)
297
298
299 #Plot each variable
300 for var in varPlot:
301 if var not in ydDict:
302 print( 'Missing yd: ',var )
303 if var not in eydDict:
304 print( 'Missing eyd: ',var )
305 continue
306
307 gr = ROOT.TGraphErrors(len(xd), xd, ydDict[var], exd, eydDict[var])
308 xmin = min(xd)
309 xmax = max(xd)
310 ymin = min(ydDict[var])
311 ymax = max(ydDict[var])
312
313 h = (ymax-ymin)
314 ymin -= 0.25*h
315 ymaxSmall = ymax + 0.25*h
316 ymax += 0.75*h
317
318 ymin2 = min(ydDict2[var])
319 ymax2 = max(ydDict2[var])
320
321 h = (ymax2-ymin2)
322 ymin2 -= 0.25*h
323 ymax2 += 0.75*h
324
325 h = (xmax-xmin)
326 xmin -= 0.05*h
327 xmax += 0.05*h
328
329 #This histogram is made just to make it easier to manipulate the margins
330 histo = ROOT.TH2D('hd'+var, 'hd'+var, 100, xmin, xmax, 100, ymin, ymax)
331 histo.GetYaxis().SetTitle(varDef(var,'atit',var))
332 histo.GetXaxis().SetTitle('Average interactions per bunch crossing')
333 histo.GetZaxis().SetTitle('Entries')
334
335 histo2 = ROOT.TH2D('hd2'+var, 'hd2'+var, 100, xmin, xmax, 100, ymin2, ymax2)
336 histo2.GetYaxis().SetTitle( "<Interaction density> @ z=0 [interactions/mm]")
337 histo2.GetXaxis().SetTitle('Average interactions per bunch crossing')
338 histo2.GetZaxis().SetTitle('Entries')
339
340 histo2W = ROOT.TH2D('hd3'+var, 'hd3'+var, 100, xmin, xmax, 100, ymin2, ymax2)
341 histo2W.GetYaxis().SetTitle( "<Interaction density> @ z=0 [interactions/mm]")
342 histo2W.GetXaxis().SetTitle('Average interactions per bunch crossing')
343 histo2W.GetZaxis().SetTitle('Integrated Luminosity (fb^{-1}/bin)')
344
345 histoW = ROOT.TH2D('hdW'+var, 'hdW'+var, 100, xmin, xmax, 100, ymin, ymax)
346 histoW.GetYaxis().SetTitle(varDef(var,'atit',var))
347 histoW.GetXaxis().SetTitle('Average interactions per bunch crossing')
348 histoW.GetZaxis().SetTitle('Integrated Luminosity (fb^{-1}/bin)')
349
350 histoW1D = ROOT.TH1D('hd1D'+var, 'hd1D'+var, 100, ymin, ymaxSmall)
351 histoW1D.GetXaxis().SetTitle(varDef(var,'atit',var))
352 histoW1D.GetYaxis().SetTitle('Integrated Luminosity (fb^{-1}/bin)')
353
354 histo.Draw();
355 if options.plotGraph:
356 gr.Draw("p");
357 else:
358 for mu, x, l in zip(xd, ydDict[var], lumi):
359 histo.Fill( mu, x )
360 histoW.Fill( mu, x , l)
361 histoW1D.Fill( x, l)
362 for mu, x, l in zip(xd, ydDict2[var], lumi):
363 histo2.Fill( mu, x )
364 histo2W.Fill( mu,x, l)
365 histo.Draw("colz")
366
367 histo.Write()
368 histoW.Write()
369 histo2.Write()
370 histo2W.Write()
371 histoW1D.Write()
372
373 # Add some information to the graph
374 ROOTUtils.atlasLabel( 0.53,0.87,False,offset=0.12,isForApproval=False,customstring="Internal",energy='%2.1f' % beamEnergy,size=0.055)
375 ROOTUtils.drawText(0.18,0.87,0.055, varDef(var,'title',var) )
376
377 comments = []
378
379 if runStart==runEnd:
380 comments.append('Run %i' % runStart)
381 else:
382 comments.append('Runs %i - %i' % (runStart,runEnd))
383
384 if fillStart==fillEnd:
385 comments.append('Fill %i' % fillStart)
386 else:
387 comments.append('Fills %i - %i' % (fillStart,fillEnd))
388
389 t1 = time.strftime('%d %b %Y',time.localtime(timeStart))
390 t2 = time.strftime('%d %b %Y',time.localtime(timeEnd))
391 if t1==t2:
392 comments.append(t1)
393 else:
394 comments.append('%s - %s' % (t1,t2))
395
396 ROOTUtils.drawText(0.18,0.81,0.05,';'.join(comments),font=42)
397
398 canvas.Print( "Run_%d_%sVsMu.png" % ( options.runMin,var ) )
399 canvas.Print( "Run_%d_%sVsMu.pdf" % ( options.runMin,var ) )
400 if not options.plotGraph:
401 canvas.SetLogz(True)
402 canvas.Print( "Run_%d_%sVsMuLog.png" % ( options.runMin,var ) )
403 canvas.Print( "Run_%d_%sVsMuLog.pdf" % ( options.runMin,var ) )
404 canvas.SetLogz(False)
405
406 histo2.Draw("colz");
407 ROOTUtils.atlasLabel( 0.53,0.87,False,offset=0.12,isForApproval=False,customstring="Internal",energy='%2.1f' % beamEnergy,size=0.055)
408 ROOTUtils.drawText(0.18,0.87,0.055, "Interaction density" )
409 ROOTUtils.drawText(0.18,0.81,0.05,';'.join(comments),font=42)
410 canvas.Print( "Run_%d_Mu%sVsMu.png" % ( options.runMin,var ) )
411 canvas.Print( "Run_%d_Mu%sVsMu.pdf" % ( options.runMin,var ) )
412 canvas.SetLogz(True)
413 canvas.Print( "Run_%d_Mu%sVsMuLog.png" % ( options.runMin,var ) )
414 canvas.Print( "Run_%d_Mu%sVsMuLog.pdf" % ( options.runMin,var ) )
415 canvas.SetLogz(False)
416
417 histoW.Draw("colz");
418 histoW.SetMinimum(0.005);
419 ROOTUtils.atlasLabel( 0.53,0.87,False,offset=0.12,isForApproval=False,customstring="Internal",energy='%2.1f' % beamEnergy,size=0.055)
420 ROOTUtils.drawText(0.18,0.87,0.055, varDef(var,'title',var) )
421 ROOTUtils.drawText(0.18,0.81,0.05,';'.join(comments),font=42)
422 canvas.Print( "Run_%d_%sVsMuW.png" % ( options.runMin,var ) )
423 canvas.Print( "Run_%d_%sVsMuW.pdf" % ( options.runMin,var ) )
424 canvas.SetLogz(True)
425 canvas.Print( "Run_%d_%sVsMuWLog.png" % ( options.runMin,var ) )
426 canvas.Print( "Run_%d_%sVsMuWLog.pdf" % ( options.runMin,var ) )
427 canvas.SetLogz(False)
428
429 histo2W.Draw("colz");
430 histo2W.SetMinimum(0.01);
431
432 ROOTUtils.atlasLabel( 0.53,0.87,False,offset=0.12,isForApproval=False,customstring="Internal",energy='%2.1f' % beamEnergy,size=0.055)
433 ROOTUtils.drawText(0.18,0.87,0.055, "Interaction density" )
434 ROOTUtils.drawText(0.18,0.81,0.05,';'.join(comments),font=42)
435 canvas.Print( "Run_%d_Mu%sVsMuW.png" % ( options.runMin,var ) )
436 canvas.Print( "Run_%d_Mu%sVsMuW.pdf" % ( options.runMin,var ) )
437 canvas.SetLogz(True)
438 canvas.Print( "Run_%d_Mu%sVsMuWLog.png" % ( options.runMin,var ) )
439 canvas.Print( "Run_%d_Mu%sVsMuWLog.pdf" % ( options.runMin,var ) )
440 canvas.SetLogz(False)
441
442 histoW1D.Draw("colz");
443 ROOTUtils.atlasLabel( 0.53,0.87,False,offset=0.12,isForApproval=False,customstring="Internal",energy='%2.1f' % beamEnergy,size=0.055)
444 ROOTUtils.drawText(0.18,0.87,0.055, varDef(var,'title',var) )
445 ROOTUtils.drawText(0.18,0.81,0.05,"#mu=%2.4f RMS=%2.4f" % ( histoW1D.GetMean(), histoW1D.GetRMS() ),font=42)
446 canvas.Print( "Run_%d_%s1D.png" % ( options.runMin,var ) )
447 canvas.Print( "Run_%d_%s1D.pdf" % ( options.runMin,var ) )
448 canvas.SetLogy(True)
449 canvas.Print( "Run_%d_%s1DLog.png" % ( options.runMin,var ) )
450 canvas.Print( "Run_%d_%s1DLog.pdf" % ( options.runMin,var ) )
451 canvas.SetLogy(False)
452
453
454
455if __name__ == "__main__":
456 main()
void print(char *figname, TCanvas *c1)
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
STL class.
STL class.
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
atlasLabel(x, y, isPreliminary=False, color=1, offset=0.115, isForApproval=False, energy=8, customstring="", size=0.05)
setStyle(style=None)
drawText(x=0.74, y=0.87, dy=0.06, text='', font=62, color=1, align=11, linesep=';')