ATLAS Offline Software
plotBeamSpotVert.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
4 
5 from __future__ import print_function
6 
7 """
8 Create beam spot primary vertex plots (e.g. for approved plots).
9 """
10 __author__ = 'Juerg Beringer'
11 __version__ = '$Id:$'
12 __usage__ = '%prog [options] nt.root'
13 
14 
15 # Argument parsing
16 from optparse import OptionParser
17 parser = OptionParser(usage=__usage__, version=__version__)
18 parser.add_option('-p', '--plot', dest='plot', default='', help='what to plot')
19 parser.add_option('-c', '--comment', dest='comment', default=None, help='additional text (use semicolon to indicate line breaks)')
20 parser.add_option('-m', '--more', dest='more', default='', help='more info (displayed beneath statistics box)')
21 parser.add_option('-o', '--output', dest='output', default='.gif', help='comma-separated list of output files or formats (default: .gif')
22 parser.add_option('', '--name', dest='name', default=None, help='base name for plots (default: ntuple name)')
23 parser.add_option('-n', '--ntracks', dest='ntracks', type='int', default=5, help='Number of tracks/vtx (default: 4)')
24 parser.add_option('', '--lbmin', dest='lbmin', type='int', default=-1, help='Minimum LB to consider')
25 parser.add_option('', '--lbmax', dest='lbmax', type='int', default=9999999, help='Maximum LB to consider')
26 parser.add_option('', '--xmin', dest='xmin', type='float', default=None, help='x axis minimum')
27 parser.add_option('', '--xmax', dest='xmax', type='float', default=None, help='x axis maximum')
28 parser.add_option('', '--ymin', dest='ymin', type='float', default=None, help='y axis minimum')
29 parser.add_option('', '--ymax', dest='ymax', type='float', default=None, help='y axis maximum')
30 parser.add_option('', '--passed', dest='passed', action='store_true', default=False, help='vertex must have passed athena selection')
31 parser.add_option('', '--cuts', dest='cuts', default='', help='additional cuts (in addition to vertex type and what can be set with other options)')
32 parser.add_option('', '--bins', dest='nbins', type='int', default=200, help='number of bins')
33 parser.add_option('', '--fit', dest='fit', default='', help='fit histogram with function (e.g. gaus) (default: no fit)')
34 parser.add_option('', '--logy', dest='logy', action='store_true', default=False, help='log scale')
35 parser.add_option('', '--optstat', dest='optstat', default='emruo', help='default OptStat value (Default: emruo)')
36 parser.add_option('', '--energy', dest='energy', action='store_true', default=False, help='add energy label')
37 parser.add_option('', '--public', dest='public', action='store_true', default=False, help='use labelling for public plots')
38 parser.add_option('', '--prelim', dest='prelim', action='store_true', default=False, help='Add ATLAS Preliminary to figure')
39 parser.add_option('', '--approval', dest='approval', action='store_true', default=False, help='Label figure ATLAS for approval')
40 parser.add_option('', '--published', dest='published', action='store_true', default=False, help='add ATLAS to figure')
41 parser.add_option('', '--canvas', dest='canvas', default='default', help='canvas size: default, page, wide, extrawide or square')
42 parser.add_option('', '--atlasx', dest='atlasx', type='float', default=None, help='x position for drawing ATLAS label')
43 parser.add_option('', '--atlasy', dest='atlasy', type='float', default=None, help='y position for drawing ATLAS label')
44 parser.add_option('', '--atlasdx', dest='atlasdx', type='float', default=None, help='x position offset for drawing Preliminary label')
45 parser.add_option('-i', '--interactive', dest='interactive', action='store_true', default=False, help='interactive')
46 parser.add_option('-b', '--batch', dest='batch', action='store_true', default=False, help='run in batch mode')
47 (options,args) = parser.parse_args()
48 if len(args) != 1:
49  parser.error('wrong number of command line arguments')
50 ntFile = args[0]
51 ntName = ntFile.split('/')[-1][:-5] if not options.name else options.name
52 
53 
54 # Definition of generic plots
55 plotDef = {
56  'x': {'code': 'hist', 'var': 'x', 'hname': 'pvX', 'xmin': -2, 'xmax': 2, 'units': '[mm]'},
57  'y': {'code': 'hist', 'var': 'y', 'hname': 'pvY', 'xmin': -2, 'xmax': 2, 'units': '[mm]'},
58  'z': {'code': 'hist', 'var': 'z', 'hname': 'pvZ', 'xmin': -500, 'xmax': 500, 'units': '[mm]'},
59  'errX': {'code': 'histErr', 'var': 'vxx', 'hname': 'errX', 'xmin': 0, 'xmax': 500, 'units': '[mm]'},
60  'errXComp': {'code': 'histErrComp', 'var': 'vxx', 'hname': 'errX', 'xmin': 0, 'xmax': 100, 'units': '[mm]'},
61  'errY': {'code': 'histErr', 'var': 'vyy', 'hname': 'errY', 'xmin': 0, 'xmax': 500, 'units': '[mm]'},
62  'errZ': {'code': 'histErr', 'var': 'vzz', 'hname': 'errZ', 'xmin': 0, 'xmax': 500, 'units': '[mm]'},
63  'ntracks': {'code': 'hist', 'var': 'nTracks', 'hname': 'pvNTracks', 'xmin': 0, 'xmax': 200, 'nbins': 200},
64  'xz': {'xmin': -250, 'xmax': 250, 'ymin': -1.5, 'ymax': 2.5},
65  'yz': {'xmin': -250, 'xmax': 250, 'ymin': -0.5, 'ymax': 3.5},
66  'yx': {'xmin': -1.4, 'xmax': 0.6, 'ymin': 0, 'ymax': 2}
67 }
68 def getPlotDef(what,property,default=''):
69  try:
70  return plotDef[what][property]
71  except:
72  return default
73 
74 # Plot defaults
75 xmin = options.xmin if options.xmin else getPlotDef(options.plot,'xmin',-500)
76 xmax = options.xmax if options.xmax else getPlotDef(options.plot,'xmax',+500)
77 ymin = options.ymin if options.ymin else getPlotDef(options.plot,'ymin',-500)
78 ymax = options.ymax if options.ymax else getPlotDef(options.plot,'ymax',+500)
79 nbins = getPlotDef(options.plot,'nbins',options.nbins)
80 
81 # Graphics defaults
82 if options.atlasx==None:
83  if options.published:
84  options.atlasx = 0.2
85  else:
86  options.atlasx = 0.2
87 if options.atlasy==None:
88  options.atlasy = 0.86
89 if options.atlasdx==None:
90  options.atlasdx = 0.115
91 
92 # Set cuts
93 cuts = 'vType==1 && lb>=%i && lb<%i' % (options.lbmin,options.lbmax)
94 if options.ntracks:
95  cuts += ' && nTracks>=%i' % options.ntracks
96 if options.passed:
97  cuts += ' && passed==1'
98 if options.cuts:
99  cuts += ' && %s' % options.cuts
100 print()
101 print ('Using cuts: ',cuts)
102 print()
103 
104 
105 # Reset DISPLAY if in batch
106 import os
107 if options.batch:
108  os.unsetenv('DISPLAY')
109 
110 
111 # Import ROOT (do this only now to avoid conlicts w/OptionParser)
112 import ROOT
113 from InDetBeamSpotExample import ROOTUtils
114 from InDetBeamSpotExample.Utils import getRunFromName
115 # TODO: Switch to using COOLQuery from COOLUtils for LHC info
116 from InDetBeamSpotExample.LHCInfoUtils import lhcFillData
117 from InDetBeamSpotExample.LHCInfoUtils import lhcEnergyData
120 ROOT.gStyle.SetPalette(1) # Better color scheme than default
121 
122 
124  if options.prelim:
125  ROOTUtils.atlasLabel(options.atlasx,options.atlasy,True,offset=options.atlasdx,energy=None)
126  if options.approval:
127  ROOTUtils.atlasLabel(options.atlasx,options.atlasy,False,offset=options.atlasdx,isForApproval=True,energy=None)
128  if options.published:
129  ROOTUtils.atlasLabel(options.atlasx,options.atlasy,False,offset=options.atlasdx,energy=None)
130 
131  ROOTUtils.drawText(options.atlasx,0.77,0.06,runFillInfo,font=42)
132  comment = options.comment if options.comment is not None else '#geq %i tracks/vertex' % (options.ntracks)
133  ROOTUtils.drawText(options.atlasx,0.71,0.06,lhcEnergyInfo+comment,font=42)
134 
135 
136 def drawInfo(c,h,more,x=0.6,size=0.04):
137  what = c.GetName()
138  info = 'Entries %5i' % h.GetEntries()
139  info += ';RMS %s %6.3g mm' % (what[0],h.GetRMS(2))
140  info += ';RMS %s %6.3g mm' % (what[1],h.GetRMS(1))
141  ROOTUtils.drawText(x,0.88,size,info,font=102)
142  if more:
143  ROOTUtils.drawText(x,0.73,size,more,font=102)
144 
145 
147 
148  def hist(self):
149  hname = getPlotDef(options.plot,'hname','h')
150  var = getPlotDef(options.plot,'var')
151  units = getPlotDef(options.plot,'units','')
152  ROOT.gStyle.SetOptStat(options.optstat)
153  if options.fit:
154  ROOT.gStyle.SetOptFit(1111)
155  c = ROOTUtils.protect(ROOTUtils.MyCanvas(var,options.canvas))
156  c.SetRightMargin(0.14)
157  h = ROOTUtils.protect(ROOT.TH1F(hname,'Primary vertex: %s;Primary vertex %s %s' % (var,var,units),nbins,xmin,xmax))
158  nt.Draw('%s >> %s' % (var,hname),cuts)
159  if options.fit:
160  h.Fit(options.fit)
161  ROOTUtils.drawText(0.2,0.77,0.06,runFillInfo,font=42)
162  comment = options.comment if options.comment is not None else '#geq %i tracks/vertex;%s' % (options.ntracks,options.cuts)
163  ROOTUtils.drawText(0.2,0.71,0.06,lhcEnergyInfo+comment,font=42)
164  ROOT.gPad.SetLogy(options.logy)
165  ROOT.gPad.Update()
166  c.save()
167 
168  def histErr(self):
169  hname = getPlotDef(options.plot,'hname','h')
170  var = getPlotDef(options.plot,'var')
171  vName = var[1:] # Ugly - should take from plotDef
172  ROOT.gStyle.SetOptStat(options.optstat)
173  ROOT.gStyle.SetOptFit(0)
174  c = ROOTUtils.protect(ROOTUtils.MyCanvas(var,options.canvas))
175  c.SetRightMargin(0.14)
176  h = ROOTUtils.protect(ROOT.TH1F(hname,'Primary vertex error: %s;Primary vertex error #sqrt{V_{%s}} (#mum);Number of vertices' % (hname,vName),
177  nbins,xmin,xmax))
178  nt.Draw('1e3*sqrt(%s) >> %s' % (var,hname),cuts)
179  ROOTUtils.drawText(0.45,0.86,0.06,'Primary Vertex Error #sqrt{V_{%s}}' % vName)
180  comment = options.comment if options.comment is not None else '#geq %i tracks/vertex;%s' % (options.ntracks,options.cuts)
181  ROOTUtils.drawText(0.45,0.8,0.06,lhcEnergyInfo+comment,font=42)
182  ROOT.gPad.SetLogy(options.logy)
183  ROOT.gPad.Update()
184  c.save()
185 
186  def histErrComp(self):
187  hname = getPlotDef(options.plot,'hname','h')
188  var = getPlotDef(options.plot,'var')
189  vName = var[1:] # Ugly - should take from plotDef
190  ROOT.gStyle.SetOptStat(0)
191  ROOT.gStyle.SetOptFit(0)
192  c = ROOTUtils.protect(ROOTUtils.MyCanvas(var,options.canvas))
193  c.SetRightMargin(0.14)
194  h = ROOTUtils.protect(ROOT.TH1F(hname,'Vertex Error: %s;Vertex error #sqrt{V_{%s}} [#mum];Fraction of entries' % (hname,vName),
195  nbins,xmin,xmax))
196  nt.Draw('1e3*sqrt(%s) >> %s' % (var,hname),cuts)
197  norm = h.Integral()
198  h.Scale(1./norm)
199  pname = hname+'_pileup'
200  p = ROOTUtils.protect(ROOT.TH1F(pname,'Vertex Error: %s;Vertex error #sqrt{V_{%s}} [#mum];Fraction of entries' % (hname,vName),
201  nbins,xmin,xmax))
202  pcuts = cuts.replace('vType==1','vType==3')
203  print (pcuts)
204  nt.Draw('1e3*sqrt(%s) >> %s' % (var,pname),pcuts,"SAME")
205  pnorm = p.Integral()
206  p.Scale(1./pnorm)
207  p.SetLineColor(4)
208  p.SetLineStyle(2)
209  ROOTUtils.drawText(0.51,0.86,0.06,'Vertex error #sqrt{V_{%s}}' % vName)
210  comment = options.comment if options.comment is not None else '#geq %i tracks/vertex;%s' % (options.ntracks,options.cuts)
211  ROOTUtils.drawText(0.51,0.8,0.06,lhcEnergyInfo+comment,font=42)
212  legend = ROOT.TLegend(.50,.6,.85,.72)
213  legend.AddEntry(h,'Primary vertices','L')
214  legend.AddEntry(p,'Pileup vertices','L')
215  legend.SetFillColor(0)
216  legend.SetBorderSize(0)
217  legend.Draw()
218  ROOT.gPad.SetLogy(options.logy)
219  ROOT.gPad.Update()
220  c.save()
221 
222  def xz(self):
223  #ROOT.gStyle.SetOptStat(1010)
224  ROOT.gStyle.SetOptStat(0)
225  c = ROOTUtils.protect(ROOTUtils.MyCanvas('xz',options.canvas))
226  c.SetRightMargin(0.14)
227  h = ROOTUtils.protect(ROOT.TH2F('pvXZ','Primary vertex: x vs z;Primary vertex z [mm];Primary vertex x [mm]',nbins,xmin,xmax,nbins,ymin,ymax))
228  nt.Draw('x:z >> pvXZ',cuts)
229  h.Draw('COLZ')
230  h.GetYaxis().SetTitleOffset(1.0)
231  drawLabels()
232  #ROOTUtils.moveStats(h,-0.16,-0.08)
233  drawInfo(c,h,options.more)
234  ROOT.gPad.Update()
235  c.save()
236 
237  def yz(self):
238  ROOT.gStyle.SetOptStat(0)
239  c = ROOTUtils.protect(ROOTUtils.MyCanvas('yz',options.canvas))
240  c.SetRightMargin(0.14)
241  h = ROOTUtils.protect(ROOT.TH2F('pvYZ','Primary vertex: y vs z;Primary vertex z [mm];Primary vertex y [mm]',nbins,xmin,xmax,nbins,ymin,ymax))
242  nt.Draw('y:z >> pvYZ',cuts)
243  h.Draw('COLZ')
244  h.GetYaxis().SetTitleOffset(1.0)
245  drawLabels()
246  drawInfo(c,h,options.more)
247  ROOT.gPad.Update()
248  c.save()
249 
250  def yx(self):
251  ROOT.gStyle.SetOptStat(0)
252  c = ROOTUtils.protect(ROOTUtils.MyCanvas('yx',options.canvas))
253  c.SetRightMargin(0.14)
254  h = ROOTUtils.protect(ROOT.TH2F('pvYX','Primary vertex: y vs x;Primary vertex x [mm];Primary vertex y [mm]',nbins,xmin,xmax,nbins,ymin,ymax))
255  nt.Draw('y:x >> pvYX',cuts)
256  h.Draw('COLZ')
257  h.GetYaxis().SetTitleOffset(1.0)
258  drawLabels()
259  drawInfo(c,h,options.more)
260  ROOT.gPad.Update()
261  c.save()
262 
263 
264 # Start processing
265 run = getRunFromName(ntFile)
266 if options.public:
267  runFillInfo = 'Fill %s' % (lhcFillData.get(run,'') if lhcFillData.get(run,'') else '')
268 else:
269  runFillInfo = 'Run %s (LHC Fill %s)' % (run,lhcFillData.get(run,'') if lhcFillData.get(run,'') else '')
270 
271 if options.energy:
272  lhcEnergyInfo = '#sqrt{s} = %s;' % lhcEnergyData.get(run,'') if lhcEnergyData.get(run,'') else ''
273 else:
274  lhcEnergyInfo = ''
275 
276 f = ROOT.TFile(ntFile)
277 if f.Get('Vertices'):
278  nt = f.Get('Vertices')
279 elif f.Get('Beamspot/Vertices'):
280  nt = f.Get('Beamspot/Vertices')
281 #nt = f.Get('Beamspot/Vertices')
282 
283 ROOTUtils.MyCanvas.saveAsList = options.output.split(',')
284 ROOTUtils.MyCanvas.autoName = '%s-%%s%%s' % ntName
285 
286 plots = Plots('Primary Vertex Plots',['hist','histErr'])
287 plots.plot(getPlotDef(options.plot,'code',options.plot))
288 
289 if options.interactive:
290  os.environ['PYTHONINSPECT'] = '1'
ROOTUtils.drawText
def drawText(x=0.74, y=0.87, dy=0.06, text='', font=62, color=1, align=11, linesep=';')
Definition: roofit/ROOTUtils.py:243
BeamSpotData
plotBeamSpotVert.Plots.xz
def xz(self)
Definition: plotBeamSpotVert.py:222
plotBeamSpotVert.drawInfo
def drawInfo(c, h, more, x=0.6, size=0.04)
Definition: plotBeamSpotVert.py:136
plotBeamSpotVert.Plots.histErr
def histErr(self)
Definition: plotBeamSpotVert.py:168
ROOTUtils.MyCanvas
Definition: roofit/ROOTUtils.py:40
ROOTUtils.setStyle
def setStyle(style=None)
Definition: roofit/ROOTUtils.py:413
ROOTUtils.protect
def protect(obj)
Definition: roofit/ROOTUtils.py:17
python.Utils.getRunFromName
def getRunFromName(name, default='', asInt=False)
Definition: InnerDetector/InDetExample/InDetBeamSpotExample/python/Utils.py:13
ROOTUtils.atlasLabel
def atlasLabel(x, y, isPreliminary=False, color=1, offset=0.115, isForApproval=False, energy=8, customstring="", size=0.05)
Definition: roofit/ROOTUtils.py:303
plotBeamSpotVert.Plots.histErrComp
def histErrComp(self)
Definition: plotBeamSpotVert.py:186
plotBeamSpotVert.Plots
Definition: plotBeamSpotVert.py:146
plotBeamSpotVert.getPlotDef
def getPlotDef(what, property, default='')
Definition: plotBeamSpotVert.py:68
plotBeamSpotVert.Plots.hist
def hist(self)
Definition: plotBeamSpotVert.py:148
ROOTUtils.PlotLibrary
Definition: roofit/ROOTUtils.py:77
plotBeamSpotVert.Plots.yx
def yx(self)
Definition: plotBeamSpotVert.py:250
plotBeamSpotVert.drawLabels
def drawLabels()
Definition: plotBeamSpotVert.py:123
dbg::print
void print(std::FILE *stream, std::format_string< Args... > fmt, Args &&... args)
Definition: SGImplSvc.cxx:70
plotBeamSpotVert.Plots.yz
def yz(self)
Definition: plotBeamSpotVert.py:237