5 from __future__
import print_function
8 Compare two sets of beam spots for the same run; can read results from
9 ntuples,CSV, or from COOL; use BeamSpotData class
11 __author__ =
'Martina Hurwitz'
13 __usage__ =
'%prog [options] file1/tag1 file2/tag2'
19 from array
import array
22 from InDetBeamSpotExample.Utils
import getRunFromName
26 'nEvents': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(N_{vert})',
'ytit2':
'Number of vertices',
'title':
'Difference in number of vertices',
'bigchange': 300,
'cannr':2},
27 'k': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(k)',
'ytit2':
'Error scale factor k',
'title':
'Difference in error scale factor k',
'bigchange': 0.2,
'cannr':3},
28 'posX': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(x) [mm]',
'ytit2':
'X position [mm]',
'title':
'Difference in beamspot x',
'bigchange': 10,
'cannr':7},
29 'posY': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(y) [mm]',
'ytit2':
'Y position [mm]',
'title':
'Difference in beamspot y',
'bigchange': 10,
'cannr':8},
30 'posZ': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(z) [mm]',
'ytit2':
'Z position [mm]',
'title':
'Difference in beamspot z',
'bigchange': 3,
'cannr':9},
31 'sigmaX': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(#sigma_{x}) [mm]',
'ytit2':
'#sigma_{x} [mm]',
'title':
'Difference in beamspot #sigma_{x}',
'bigchange': 3,
'cannr':13},
32 'sigmaY': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(#sigma_{y}) [mm]',
'ytit2':
'#sigma_{y} [mm]',
'title':
'Difference in beamspot #sigma_{y}',
'bigchange': 3,
'cannr':14},
33 'sigmaZ': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(#sigma_{z}) [mm]',
'ytit2':
'#sigma_{z} [mm]',
'title':
'Difference in beamspot #sigma_{z}',
'bigchange': 2,
'cannr':15},
34 'tiltX': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(Tilt_{x-z}) [rad]',
'ytit2':
'Tilt in x-z [rad]',
'title':
'Difference in beamspot tilt in x-z',
'bigchange': 0.15,
'cannr':19},
35 'tiltY': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(Tilt_{y-z}) [rad]',
'ytit2':
'Tilt in y-z [rad]',
'title':
'Difference in beamspot tilt in y-z',
'bigchange': 0.15,
'cannr':20},
36 'rhoXY': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(#rho_{xy})',
'ytit2':
'#rho_{xy}',
'title':
'Difference in #rho',
'bigchange': 0.15,
'cannr':21}
40 return varDef[what][property]
44 __usage__ +=
'\n\nPossible variables to plot are:\n'
48 from optparse
import OptionParser
49 parser = OptionParser(usage=__usage__, version=__version__)
50 parser.add_option(
'-b',
'--batch', dest=
'batch', action=
'store_true', default=
False, help=
'run in batch mode')
51 parser.add_option(
'-o',
'--output', dest=
'output', default=
'.gif', help=
'comma-separated list of output files or formats (default: .gif)')
52 parser.add_option(
'-r',
'--runNumber', dest=
'runNumber', default=0, help=
'run number')
53 parser.add_option(
'',
'--rl', dest=
'runMin', type=
'int', default=0, help=
'minimum run number (inclusive)')
54 parser.add_option(
'',
'--ru', dest=
'runMax', type=
'int', default=0, help=
'maximum run number (inclusive)')
55 parser.add_option(
'-p',
'--plot', dest=
'plot', default=
'', help=
'quantity to plot, only make one plot')
56 parser.add_option(
'',
'--finder1', dest=
'finder1', action=
'store_true', default=
False, help=
'First ntuple is BeamSpotFinder ntuple')
57 parser.add_option(
'',
'--finder2', dest=
'finder2', action=
'store_true', default=
False, help=
'Second ntuple is BeamSpotFinder ntuple')
58 parser.add_option(
'',
'--online1', dest=
'online1', action=
'store_true', default=
False, help=
'First COOL tag is for online folder')
59 parser.add_option(
'',
'--online2', dest=
'online2', action=
'store_true', default=
False, help=
'Second COOL tag is for online folder')
60 parser.add_option(
'',
'--config', dest=
'config', default=
'', help=
'Use known configuration (OnlineOffline or Reproc)')
61 parser.add_option(
'',
'--plotHistos', dest=
'plotHistos', action=
'store_true', default=
False, help=
'Plot histograms instead of graphs')
62 parser.add_option(
'',
'--label1', dest=
'label1', default=
'', help=
'Description of first argument')
63 parser.add_option(
'',
'--label2', dest=
'label2', default=
'', help=
'Description of second argument')
64 parser.add_option(
'',
'--lbmin', dest=
'lbmin', type=
'int', default=0, help=
'Miminum LB used in comparison')
65 parser.add_option(
'',
'--lbmax', dest=
'lbmax', type=
'int', default=0, help=
'Maximum LB used in comparison')
66 parser.add_option(
'',
'--smallChanges', dest=
'smallChanges', action=
'store_true', default=
False, help=
'Print out changes larger than 0.1 percent')
67 parser.add_option(
'',
'--RooFit', dest=
'RooFit',action=
'store_true',default=
False,help=
'Compare Run 1 Fit Method with RooFit result in same file')
68 parser.add_option(
'',
'--status', dest=
'status',action=
'store',default=59,help=
'default fit status to use for first file')
69 parser.add_option(
'',
'--multicanv', dest=
'multicanv', action=
'store_true',default=
False,help=
"create multiple canvases")
70 parser.add_option(
'',
'--outtag', dest=
'outtag', action=
'store', default=
'', help=
"string to prepend to output file names.")
71 parser.add_option(
'',
'--html', dest=
'html', action=
'store_true', default=
False, help=
"create an HTML page to see plots more easily. Only really useful with multicanv.")
72 parser.add_option(
'',
'--htmltag', dest=
'htmltag', action=
'store', default=
'', help=
"tag to distinguish different HTML pages")
73 (options,args) = parser.parse_args()
80 parser.error(
'wrong number of command line arguments')
86 parser.error(
'wrong number of command line arguments')
90 if options.runNumber :
91 runNumber =
int(options.runNumber)
92 print (
'Doing comparison for run %i' % runNumber)
93 elif options.config==
'OnlineOffline':
95 print (
'Doing comparison for run %i' % runNumber)
96 elif options.config==
'Reproc':
98 print (
'Doing comparison for run %i' % runNumber)
109 ROOT.gROOT.SetBatch(1)
111 from InDetBeamSpotExample
import ROOTUtils
119 if tag1.find(
'.root') > -1:
122 BSData1 = BeamSpotFinderNt(tag1)
124 BSData1 = BeamSpotNt(tag1)
125 elif tag1.find(
'.csv') > -1:
127 BSData1 = BeamSpotCSV(tag1)
132 BSData1 = BeamSpotCOOL(tag1,
'COOLONL_INDET/CONDBR2',
'/Indet/Onl/Beampos')
134 BSData1 = BeamSpotCOOL(tag1)
137 if tag2.find(
'.root') > -1:
140 BSData2 = BeamSpotFinderNt(tag2)
142 BSData2 = BeamSpotNt(tag2)
143 elif tag2.find(
'.csv') > -1:
145 BSData2 = BeamSpotCSV(tag2)
150 BSData2 = BeamSpotCOOL(tag2,
'COOLONL_INDET/CONDBR2',
'/Indet/Onl/Beampos')
152 BSData2 = BeamSpotCOOL(tag2)
159 varColl.append(options.plot)
162 varColl = [
'posX',
'posY',
'posZ',
'sigmaX',
'sigmaY',
'sigmaZ',
'tiltX',
'tiltY']
164 varColl.append(
'rhoXY')
165 if not fromDB
and not fromCSV:
166 varColl = [
'nEvents',
'k',
'posX',
'posY',
'posZ',
'sigmaX',
'sigmaY',
'sigmaZ',
'tiltX',
'tiltY',
'rhoXY']
171 BSData1.runMin = runNumber
172 BSData1.runMax = runNumber
173 BSData2.runMin = runNumber
174 BSData2.runMax = runNumber
176 if options.runMin != 0 :
177 BSData1.runMin = options.runMin
178 BSData2.runMin = options.runMin
180 if options.runMax != 0 :
181 BSData1.runMax = options.runMax
182 BSData2.runMax = options.runMax
184 if options.lbmin != 0:
185 BSData1.lbmin = options.lbmin
186 BSData2.lbmin = options.lbmin
188 if options.lbmax != 0:
189 BSData1.lbmax = options.lbmax
190 BSData2.lbmax = options.lbmax
193 BS2_status = options.status
195 if options.status==107:
199 if not options.config==
'OnlineOffline':
200 BSData2.statusList=[BS2_status]
201 BS2Dict = BSData2.getDataCache()
204 if options.config ==
'OnlineOffline':
205 print (
'No entries found in Online DB!')
206 elif options.config ==
'Reproc':
207 print (
'No entries in reprocessed sample!')
209 print (
'No entries found for second tag!')
232 if BS1.status == options.status: pass1 =
True
238 if ".csv" in tag1
or ".root" in tag1:
241 if lbmax-lbmin > 100:
244 if options.lbmin != 0
and lbmin < options.lbmin:
245 lbmin = options.lbmin
246 if options.lbmax != 0
and lbmax > options.lbmax:
247 lbmax = options.lbmax
249 for lb
in range(lbmin, lbmax) :
256 if not var
in y1Dict:
257 y1Dict[var] =
array(
'd')
258 ey1Dict[var] =
array(
'd')
259 y1Dict[var].
append(getattr(BS1, var))
261 ey1Dict[var].
append(getattr(BS1, var+
'Err'))
266 if lb
in BS2Dict[run]:
267 BS2 = BS2Dict[run][lb]
271 if options.status==59:
272 if BS2.status == 107: pass2 =
True
273 elif options.status==107:
274 if BS2.status == 59: pass2 =
True
275 elif options.config==
'OnlineOffline':
276 if (BS2.status%8)==7: pass2=
True
278 if BS2.status == options.status: pass2 =
True
280 if pass1
and not pass2:
281 print (
"Warning: run %s lumiBlock %s doesn't have good fit anymore" %(run,lb))
284 if pass2
and not pass1: numNew += 1
285 if not pass1
or not pass2:
continue
291 if not var
in ydDict:
292 ydDict[var] =
array(
'd')
293 eydDict[var] =
array(
'd')
294 diff = getattr(BS1, var) - getattr(BS2, var)
296 ediff =
max(getattr(BS1, var+
'Err'), getattr(BS2, var+
'Err'))
300 eydDict[var].
append(ediff)
303 percdiff = diff /
max(getattr(BS1, var), getattr(BS2, var))
308 sigmaChange = diff/ediff
312 if sigmaChange > 3
and diff >
getVarDef(var,
'bigchange') :
313 print (
"WARNING: Big change in value of %s for lumiBlock %i" % (var, lb))
314 print (
" change in value is %f microns, or %f sigma" % (diff, diff/ediff))
316 if options.smallChanges
and percdiff > 0.001 :
317 print (
"WARNING: value of %s in run %s in lumiBlock %i changed by more than 0.1 percent" % (var, run, lb))
322 print (
"Warning: run %s lumiBlock %s doesn't have beamspot anymore" %(run, lb))
326 for lb
in BS2Dict[run]:
327 BS2 = BS2Dict[run][lb]
330 if options.status==59:
331 if BS2.status == 107: pass2 =
True
332 elif options.status==107:
333 if BS2.status == 59: pass2 =
True
334 elif options.config==
"OnlineOffline":
335 if (BS2.status%8)==7: pass2=
True
337 if BS2.status == options.status: pass2 =
True
343 if not var
in y2Dict:
344 y2Dict[var] =
array(
'd')
345 ey2Dict[var] =
array(
'd')
346 y2Dict[var].
append(getattr(BS2, var))
348 ey2Dict[var].
append(getattr(BS2, var+
'Err'))
352 print (
"Number of LBs where beam spot is good but was bad before: %i" % numNew)
353 print (
"Number of LBs where beam spot is bad but was good before: %i" % numOld)
356 print (
"ERROR: No overlapping LB range found")
361 canvas = ROOT.TCanvas(
'BeamSpotComparison',
'BeamSpotComparison', 600, 500)
362 if options.plotHistos:
363 ROOT.gStyle.SetOptStat(1110)
364 ROOT.gStyle.SetStatW(0.3)
365 ROOT.gStyle.SetStatH(0.2)
367 canvas.Divide(1,2,0,0)
368 elif options.plotHistos:
369 canvas = ROOT.TCanvas(
'BeamSpotComparison',
'BeamSpotComparison', 750, 1000)
371 elif options.multicanv:
377 canvas = ROOT.TCanvas(
'BeamSpotComparison',
'BeamSpotComparison', 750, 1400)
378 ROOT.gPad.SetLeftMargin(0.0)
379 ROOT.gPad.SetBottomMargin(0.0)
380 canvas.Divide(3, 8, 0.01, 0)
391 gr1 = ROOT.TGraphErrors(len(x1), x1, y1Dict[var], ex1, ey1Dict[var])
392 graphColl.append(gr1)
393 gr2 = ROOT.TGraphErrors(len(x2), x2, y2Dict[var], ex2, ey2Dict[var])
394 graphColl.append(gr2)
395 grdiff = ROOT.TGraphErrors(len(xd), xd, ydDict[var], exd, eydDict[var])
396 graphColl.append(grdiff)
409 diffmin =
min(ydDict[var])
410 diffmax =
max(ydDict[var])
411 h = diffmax - diffmin
415 histo = ROOT.TH1F(var, var, 40, diffmin, diffmax)
416 histo.GetXaxis().SetTitle(
getVarDef(var,
'ytit'))
417 histo.GetYaxis().SetTitle(
'LumiBlocks')
419 for i
in range(0, len(ydDict[var])):
420 histo.Fill(ydDict[var][i])
422 histColl.append(histo)
424 if options.plotHistos:
426 histo.GetXaxis().SetTitleOffset(1.7)
432 hdummy = ROOT.TH2D(
'hd'+var,
'hd'+var, 10, xmin, xmax, 10, ymin, ymax)
434 hdummy.GetYaxis().SetTitle(
getVarDef(var,
'ytit2'))
435 hdummy.GetYaxis().SetTitleSize(0.07)
436 hdummy.GetXaxis().SetLabelSize(0)
438 dummyColl.append(hdummy)
440 gr1.SetMarkerSize(0.8)
441 gr1.SetMarkerStyle(22)
442 gr1.SetMarkerColor(4)
445 gr2.SetMarkerSize(0.8)
446 gr2.SetMarkerStyle(21)
447 gr2.SetMarkerColor(2)
450 grdiff.SetMarkerSize(0.8)
451 grdiff.SetLineWidth(1)
454 gr1.SetMarkerSize(0.3)
455 gr2.SetMarkerSize(0.3)
456 grdiff.SetMarkerSize(0.3)
457 gr1.GetYaxis().SetTitleOffset(1.7)
458 grdiff.GetXaxis().SetTitle(
getVarDef(var,
'xtit'))
459 grdiff.GetYaxis().SetTitle(
getVarDef(var,
'ytit'))
460 grdiff.GetXaxis().SetTitleSize(0.07)
461 grdiff.GetYaxis().SetTitleSize(0.07)
462 grdiff.GetXaxis().SetLimits(xmin, xmax)
466 ROOT.gPad.SetTopMargin(0.1)
467 ROOT.gPad.SetLeftMargin(0.2)
468 ROOT.gPad.SetRightMargin(0.1)
474 ROOT.gPad.SetTopMargin(0.05)
475 ROOT.gPad.SetBottomMargin(0.2)
476 ROOT.gPad.SetLeftMargin(0.2)
477 ROOT.gPad.SetRightMargin(0.1)
480 elif options.multicanv:
481 ROOT.gStyle.SetGridColor(ROOT.kGray)
482 ROOT.gStyle.SetGridWidth(1)
483 canvases[var]=ROOT.TCanvas(
'BeamSpotComparison_%s'%var,
484 'BeamSpotComparison_%s'%var,
488 primarypad[var] = ROOT.TPad(
"primarypad",
"primarypad",0,0.35,1,1)
489 primarypad[var].SetBottomMargin(0.03)
490 primarypad[var].Draw()
491 primarytextscale=1./(primarypad[var].GetWh()*primarypad[var].GetAbsHNDC());
493 ratiopad[var] = ROOT.TPad(
"ratiopad",
"ratiopad",0,0.03,1,0.35)
494 ratiopad[var].SetTopMargin(0.03)
495 ratiopad[var].SetBottomMargin(0.3)
496 ratiopad[var].SetGridy(1)
498 ratiotextscale=1./(ratiopad[var].GetWh()*ratiopad[var].GetAbsHNDC())
505 hdummy.GetYaxis().SetTitleSize(0.085)
506 hdummy.GetYaxis().SetTitleOffset(0.75)
507 hdummy.GetYaxis().SetLabelSize(0.06)
508 hdummy.GetXaxis().SetLabelSize(0)
510 minyaxis=hdummy.GetYaxis().GetXmin()
511 maxyaxis=hdummy.GetYaxis().GetXmax()
512 rangeyaxis=abs(minyaxis-maxyaxis)
513 hdummy.GetYaxis().SetLimits(minyaxis,maxyaxis+0.50*rangeyaxis)
514 primarypad[var].Update()
519 diffymax=grdiff.GetYaxis().GetXmax()
520 diffymin=grdiff.GetYaxis().GetXmin()
522 grdiff.GetYaxis().SetRangeUser(0.-0.1*abs(diffymax-diffymin),diffymax)
524 grdiff.GetYaxis().SetRangeUser(diffymin,0.+0.1*abs(diffymax-diffymin))
526 grdiff.GetYaxis().SetTitleSize(0.16)
527 grdiff.GetYaxis().SetTitleOffset(.39)
528 grdiff.GetXaxis().SetTitleOffset(0.9)
529 grdiff.GetXaxis().SetTitleSize(0.16)
530 grdiff.GetYaxis().SetLabelSize(0.12)
531 grdiff.GetYaxis().SetNdivisions(8)
532 grdiff.GetXaxis().SetLabelSize(0.12)
534 zeroline[var]=ROOT.TLine(xmin, 0.0, xmax+1, 0.0)
535 zeroline[var].SetLineWidth(2)
540 ratiopad[var].Update()
542 canvases[var].Update()
545 ROOT.gPad.SetTopMargin(0.1)
546 ROOT.gPad.SetLeftMargin(0.2)
547 ROOT.gPad.SetRightMargin(0.1)
548 ROOT.gPad.SetBottomMargin(0.02)
554 ROOT.gPad.SetTopMargin(0.05)
555 ROOT.gPad.SetBottomMargin(0.2)
556 ROOT.gPad.SetLeftMargin(0.2)
557 ROOT.gPad.SetRightMargin(0.1)
566 if options.config ==
'OnlineOffline':
567 descrText +=
'Online - Offline comparison'
570 elif options.config ==
'Reproc':
571 if not options.multicanv:
572 descrText +=
'Reprocessed - Tier0 comparison'
573 if options.label1 ==
'':
575 if options.label2 ==
'':
578 legText1 =
'Beamspots 1'
579 legText2 =
'Beamspots 2'
581 if options.label1 !=
'':
582 legText1 = options.label1
584 if options.label2 !=
'':
585 legText2 = options.label2
588 if options.multicanv:
590 if not options.multicanv:
598 legendList.append([gr1, legText1,
'LP'])
599 legendList.append([gr2, legText2,
'LP'])
600 legendList.append([grdiff,
'Difference',
'LP'])
601 if options.multicanv:
603 elif not options.plotHistos:
606 if options.multicanv:
610 if options.multicanv:
611 primarypad[var].Update()
614 if options.plotHistos:
617 elif options.multicanv:
618 for var,canv
in canvases.items():
626 if not options.multicanv:
627 newText =
'New fits: %i' % numNew
628 oldText =
'Missing fits: %i' %numOld
633 basename=options.outtag
634 if options.config ==
"Reproc":
635 basename=tag2.replace(
".BeamSpotNt-nt.root",
".PlotBeamSpotCompareReproc").
replace(
".MergeNt-nt.root",
".PlotBeamSpotCompareReproc")
636 basename=basename[basename.rfind(
'/')+1:]
637 if options.html
and options.outtag.find(
'/'):
638 basename=options.outtag[:options.outtag.rfind(
'/')+1]+basename+options.htmltag+
"."
639 elif options.runNumber>0:
640 basename+=
str(options.runNumber)
642 elif options.runMin>0:
643 basename+=
str(options.runMin)
645 basename+=
str(options.runMax)
648 for o
in options.output.split(
','):
649 if options.multicanv:
652 if basename.find(
'/')>0:
653 htmlstart=basename.rfind(
'/')+1
654 htmlfilename=basename[htmlstart:-1]+
".html"
656 print (
"writing html file %s" % htmlfilename)
657 for var,canv
in canvases.items():
658 canv.Print(basename+var+o)
659 if o==
".png" and options.html:
660 for var
in [
'posX',
'posY',
'posZ',
'sigmaX',
'sigmaY',
'sigmaZ',
'rhoXY',
'tiltX',
'tiltY',
'k',
'nEvents']:
662 if "pdf" in options.output:
663 html.write(
"<a href=\""+basename+var+
".pdf\"><img src=\""+basename+var+o+
"\" width=\"33%\"></a>")
665 html.write(
"<img src=\""+basename+var+o+
"\" width=\"33%\">")
672 if not options.batch: