7 Compare two sets of beam spots for the same run; can read results from
8 ntuples,CSV, or from COOL; use BeamSpotData class
10 __author__ =
'Martina Hurwitz'
12 __usage__ =
'%prog [options] file1/tag1 file2/tag2'
18 from array
import array
21 from InDetBeamSpotExample.Utils
import getRunFromName
25 'nEvents': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(N_{vert})',
'ytit2':
'Number of vertices',
'title':
'Difference in number of vertices',
'bigchange': 300,
'cannr':2},
26 '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},
27 'posX': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(x) [mm]',
'ytit2':
'X position [mm]',
'title':
'Difference in beamspot x',
'bigchange': 10,
'cannr':7},
28 'posY': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(y) [mm]',
'ytit2':
'Y position [mm]',
'title':
'Difference in beamspot y',
'bigchange': 10,
'cannr':8},
29 'posZ': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(z) [mm]',
'ytit2':
'Z position [mm]',
'title':
'Difference in beamspot z',
'bigchange': 3,
'cannr':9},
30 'sigmaX': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(#sigma_{x}) [mm]',
'ytit2':
'#sigma_{x} [mm]',
'title':
'Difference in beamspot #sigma_{x}',
'bigchange': 3,
'cannr':13},
31 'sigmaY': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(#sigma_{y}) [mm]',
'ytit2':
'#sigma_{y} [mm]',
'title':
'Difference in beamspot #sigma_{y}',
'bigchange': 3,
'cannr':14},
32 'sigmaZ': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(#sigma_{z}) [mm]',
'ytit2':
'#sigma_{z} [mm]',
'title':
'Difference in beamspot #sigma_{z}',
'bigchange': 2,
'cannr':15},
33 '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},
34 '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},
35 'rhoXY': {
'xtit':
'Luminosity Block Number',
'ytit':
'#Delta(#rho_{xy})',
'ytit2':
'#rho_{xy}',
'title':
'Difference in #rho',
'bigchange': 0.15,
'cannr':21}
39 return varDef[what][property]
43 __usage__ +=
'\n\nPossible variables to plot are:\n'
47 from optparse
import OptionParser
48 parser = OptionParser(usage=__usage__, version=__version__)
49 parser.add_option(
'-b',
'--batch', dest=
'batch', action=
'store_true', default=
False, help=
'run in batch mode')
50 parser.add_option(
'-o',
'--output', dest=
'output', default=
'.gif', help=
'comma-separated list of output files or formats (default: .gif)')
51 parser.add_option(
'-r',
'--runNumber', dest=
'runNumber', default=0, help=
'run number')
52 parser.add_option(
'',
'--rl', dest=
'runMin', type=
'int', default=0, help=
'minimum run number (inclusive)')
53 parser.add_option(
'',
'--ru', dest=
'runMax', type=
'int', default=0, help=
'maximum run number (inclusive)')
54 parser.add_option(
'-p',
'--plot', dest=
'plot', default=
'', help=
'quantity to plot, only make one plot')
55 parser.add_option(
'',
'--finder1', dest=
'finder1', action=
'store_true', default=
False, help=
'First ntuple is BeamSpotFinder ntuple')
56 parser.add_option(
'',
'--finder2', dest=
'finder2', action=
'store_true', default=
False, help=
'Second ntuple is BeamSpotFinder ntuple')
57 parser.add_option(
'',
'--online1', dest=
'online1', action=
'store_true', default=
False, help=
'First COOL tag is for online folder')
58 parser.add_option(
'',
'--online2', dest=
'online2', action=
'store_true', default=
False, help=
'Second COOL tag is for online folder')
59 parser.add_option(
'',
'--config', dest=
'config', default=
'', help=
'Use known configuration (OnlineOffline or Reproc)')
60 parser.add_option(
'',
'--plotHistos', dest=
'plotHistos', action=
'store_true', default=
False, help=
'Plot histograms instead of graphs')
61 parser.add_option(
'',
'--label1', dest=
'label1', default=
'', help=
'Description of first argument')
62 parser.add_option(
'',
'--label2', dest=
'label2', default=
'', help=
'Description of second argument')
63 parser.add_option(
'',
'--lbmin', dest=
'lbmin', type=
'int', default=0, help=
'Miminum LB used in comparison')
64 parser.add_option(
'',
'--lbmax', dest=
'lbmax', type=
'int', default=0, help=
'Maximum LB used in comparison')
65 parser.add_option(
'',
'--smallChanges', dest=
'smallChanges', action=
'store_true', default=
False, help=
'Print out changes larger than 0.1 percent')
66 parser.add_option(
'',
'--RooFit', dest=
'RooFit',action=
'store_true',default=
False,help=
'Compare Run 1 Fit Method with RooFit result in same file')
67 parser.add_option(
'',
'--status', dest=
'status',action=
'store',default=59,help=
'default fit status to use for first file')
68 parser.add_option(
'',
'--multicanv', dest=
'multicanv', action=
'store_true',default=
False,help=
"create multiple canvases")
69 parser.add_option(
'',
'--outtag', dest=
'outtag', action=
'store', default=
'', help=
"string to prepend to output file names.")
70 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.")
71 parser.add_option(
'',
'--htmltag', dest=
'htmltag', action=
'store', default=
'', help=
"tag to distinguish different HTML pages")
72 (options,args) = parser.parse_args()
79 parser.error(
'wrong number of command line arguments')
85 parser.error(
'wrong number of command line arguments')
89 if options.runNumber :
90 runNumber =
int(options.runNumber)
91 print (
'Doing comparison for run %i' % runNumber)
92 elif options.config==
'OnlineOffline':
94 print (
'Doing comparison for run %i' % runNumber)
95 elif options.config==
'Reproc':
97 print (
'Doing comparison for run %i' % runNumber)
108 ROOT.gROOT.SetBatch(1)
110 from InDetBeamSpotExample
import ROOTUtils
118 if tag1.find(
'.root') > -1:
121 BSData1 = BeamSpotFinderNt(tag1)
123 BSData1 = BeamSpotNt(tag1)
124 elif tag1.find(
'.csv') > -1:
126 BSData1 = BeamSpotCSV(tag1)
131 BSData1 = BeamSpotCOOL(tag1,
'COOLONL_INDET/CONDBR2',
'/Indet/Onl/Beampos')
133 BSData1 = BeamSpotCOOL(tag1)
136 if tag2.find(
'.root') > -1:
139 BSData2 = BeamSpotFinderNt(tag2)
141 BSData2 = BeamSpotNt(tag2)
142 elif tag2.find(
'.csv') > -1:
144 BSData2 = BeamSpotCSV(tag2)
149 BSData2 = BeamSpotCOOL(tag2,
'COOLONL_INDET/CONDBR2',
'/Indet/Onl/Beampos')
151 BSData2 = BeamSpotCOOL(tag2)
158 varColl.append(options.plot)
161 varColl = [
'posX',
'posY',
'posZ',
'sigmaX',
'sigmaY',
'sigmaZ',
'tiltX',
'tiltY']
163 varColl.append(
'rhoXY')
164 if not fromDB
and not fromCSV:
165 varColl = [
'nEvents',
'k',
'posX',
'posY',
'posZ',
'sigmaX',
'sigmaY',
'sigmaZ',
'tiltX',
'tiltY',
'rhoXY']
170 BSData1.runMin = runNumber
171 BSData1.runMax = runNumber
172 BSData2.runMin = runNumber
173 BSData2.runMax = runNumber
175 if options.runMin != 0 :
176 BSData1.runMin = options.runMin
177 BSData2.runMin = options.runMin
179 if options.runMax != 0 :
180 BSData1.runMax = options.runMax
181 BSData2.runMax = options.runMax
183 if options.lbmin != 0:
184 BSData1.lbmin = options.lbmin
185 BSData2.lbmin = options.lbmin
187 if options.lbmax != 0:
188 BSData1.lbmax = options.lbmax
189 BSData2.lbmax = options.lbmax
192 BS2_status = options.status
194 if options.status==107:
198 if not options.config==
'OnlineOffline':
199 BSData2.statusList=[BS2_status]
200 BS2Dict = BSData2.getDataCache()
203 if options.config ==
'OnlineOffline':
204 print (
'No entries found in Online DB!')
205 elif options.config ==
'Reproc':
206 print (
'No entries in reprocessed sample!')
208 print (
'No entries found for second tag!')
231 if BS1.status == options.status: pass1 =
True
237 if ".csv" in tag1
or ".root" in tag1:
240 if lbmax-lbmin > 100:
243 if options.lbmin != 0
and lbmin < options.lbmin:
244 lbmin = options.lbmin
245 if options.lbmax != 0
and lbmax > options.lbmax:
246 lbmax = options.lbmax
248 for lb
in range(lbmin, lbmax) :
255 if not var
in y1Dict:
256 y1Dict[var] =
array(
'd')
257 ey1Dict[var] =
array(
'd')
258 y1Dict[var].
append(getattr(BS1, var))
260 ey1Dict[var].
append(getattr(BS1, var+
'Err'))
265 if lb
in BS2Dict[run]:
266 BS2 = BS2Dict[run][lb]
270 if options.status==59:
271 if BS2.status == 107: pass2 =
True
272 elif options.status==107:
273 if BS2.status == 59: pass2 =
True
274 elif options.config==
'OnlineOffline':
275 if (BS2.status%8)==7: pass2=
True
277 if BS2.status == options.status: pass2 =
True
279 if pass1
and not pass2:
280 print (
"Warning: run %s lumiBlock %s doesn't have good fit anymore" %(run,lb))
283 if pass2
and not pass1: numNew += 1
284 if not pass1
or not pass2:
continue
290 if not var
in ydDict:
291 ydDict[var] =
array(
'd')
292 eydDict[var] =
array(
'd')
293 diff = getattr(BS1, var) - getattr(BS2, var)
295 ediff =
max(getattr(BS1, var+
'Err'), getattr(BS2, var+
'Err'))
299 eydDict[var].
append(ediff)
302 percdiff = diff /
max(getattr(BS1, var), getattr(BS2, var))
307 sigmaChange = diff/ediff
311 if sigmaChange > 3
and diff >
getVarDef(var,
'bigchange') :
312 print (
"WARNING: Big change in value of %s for lumiBlock %i" % (var, lb))
313 print (
" change in value is %f microns, or %f sigma" % (diff, diff/ediff))
315 if options.smallChanges
and percdiff > 0.001 :
316 print (
"WARNING: value of %s in run %s in lumiBlock %i changed by more than 0.1 percent" % (var, run, lb))
321 print (
"Warning: run %s lumiBlock %s doesn't have beamspot anymore" %(run, lb))
325 for lb
in BS2Dict[run]:
326 BS2 = BS2Dict[run][lb]
329 if options.status==59:
330 if BS2.status == 107: pass2 =
True
331 elif options.status==107:
332 if BS2.status == 59: pass2 =
True
333 elif options.config==
"OnlineOffline":
334 if (BS2.status%8)==7: pass2=
True
336 if BS2.status == options.status: pass2 =
True
342 if not var
in y2Dict:
343 y2Dict[var] =
array(
'd')
344 ey2Dict[var] =
array(
'd')
345 y2Dict[var].
append(getattr(BS2, var))
347 ey2Dict[var].
append(getattr(BS2, var+
'Err'))
351 print (
"Number of LBs where beam spot is good but was bad before: %i" % numNew)
352 print (
"Number of LBs where beam spot is bad but was good before: %i" % numOld)
355 print (
"ERROR: No overlapping LB range found")
360 canvas = ROOT.TCanvas(
'BeamSpotComparison',
'BeamSpotComparison', 600, 500)
361 if options.plotHistos:
362 ROOT.gStyle.SetOptStat(1110)
363 ROOT.gStyle.SetStatW(0.3)
364 ROOT.gStyle.SetStatH(0.2)
366 canvas.Divide(1,2,0,0)
367 elif options.plotHistos:
368 canvas = ROOT.TCanvas(
'BeamSpotComparison',
'BeamSpotComparison', 750, 1000)
370 elif options.multicanv:
376 canvas = ROOT.TCanvas(
'BeamSpotComparison',
'BeamSpotComparison', 750, 1400)
377 ROOT.gPad.SetLeftMargin(0.0)
378 ROOT.gPad.SetBottomMargin(0.0)
379 canvas.Divide(3, 8, 0.01, 0)
390 gr1 = ROOT.TGraphErrors(len(x1), x1, y1Dict[var], ex1, ey1Dict[var])
391 graphColl.append(gr1)
392 gr2 = ROOT.TGraphErrors(len(x2), x2, y2Dict[var], ex2, ey2Dict[var])
393 graphColl.append(gr2)
394 grdiff = ROOT.TGraphErrors(len(xd), xd, ydDict[var], exd, eydDict[var])
395 graphColl.append(grdiff)
408 diffmin =
min(ydDict[var])
409 diffmax =
max(ydDict[var])
410 h = diffmax - diffmin
414 histo = ROOT.TH1F(var, var, 40, diffmin, diffmax)
415 histo.GetXaxis().SetTitle(
getVarDef(var,
'ytit'))
416 histo.GetYaxis().SetTitle(
'LumiBlocks')
418 for i
in range(0, len(ydDict[var])):
419 histo.Fill(ydDict[var][i])
421 histColl.append(histo)
423 if options.plotHistos:
425 histo.GetXaxis().SetTitleOffset(1.7)
431 hdummy = ROOT.TH2D(
'hd'+var,
'hd'+var, 10, xmin, xmax, 10, ymin, ymax)
433 hdummy.GetYaxis().SetTitle(
getVarDef(var,
'ytit2'))
434 hdummy.GetYaxis().SetTitleSize(0.07)
435 hdummy.GetXaxis().SetLabelSize(0)
437 dummyColl.append(hdummy)
439 gr1.SetMarkerSize(0.8)
440 gr1.SetMarkerStyle(22)
441 gr1.SetMarkerColor(4)
444 gr2.SetMarkerSize(0.8)
445 gr2.SetMarkerStyle(21)
446 gr2.SetMarkerColor(2)
449 grdiff.SetMarkerSize(0.8)
450 grdiff.SetLineWidth(1)
453 gr1.SetMarkerSize(0.3)
454 gr2.SetMarkerSize(0.3)
455 grdiff.SetMarkerSize(0.3)
456 gr1.GetYaxis().SetTitleOffset(1.7)
457 grdiff.GetXaxis().SetTitle(
getVarDef(var,
'xtit'))
458 grdiff.GetYaxis().SetTitle(
getVarDef(var,
'ytit'))
459 grdiff.GetXaxis().SetTitleSize(0.07)
460 grdiff.GetYaxis().SetTitleSize(0.07)
461 grdiff.GetXaxis().SetLimits(xmin, xmax)
465 ROOT.gPad.SetTopMargin(0.1)
466 ROOT.gPad.SetLeftMargin(0.2)
467 ROOT.gPad.SetRightMargin(0.1)
473 ROOT.gPad.SetTopMargin(0.05)
474 ROOT.gPad.SetBottomMargin(0.2)
475 ROOT.gPad.SetLeftMargin(0.2)
476 ROOT.gPad.SetRightMargin(0.1)
479 elif options.multicanv:
480 ROOT.gStyle.SetGridColor(ROOT.kGray)
481 ROOT.gStyle.SetGridWidth(1)
482 canvases[var]=ROOT.TCanvas(
'BeamSpotComparison_%s'%var,
483 'BeamSpotComparison_%s'%var,
487 primarypad[var] = ROOT.TPad(
"primarypad",
"primarypad",0,0.35,1,1)
488 primarypad[var].SetBottomMargin(0.03)
489 primarypad[var].Draw()
490 primarytextscale=1./(primarypad[var].GetWh()*primarypad[var].GetAbsHNDC());
492 ratiopad[var] = ROOT.TPad(
"ratiopad",
"ratiopad",0,0.03,1,0.35)
493 ratiopad[var].SetTopMargin(0.03)
494 ratiopad[var].SetBottomMargin(0.3)
495 ratiopad[var].SetGridy(1)
497 ratiotextscale=1./(ratiopad[var].GetWh()*ratiopad[var].GetAbsHNDC())
504 hdummy.GetYaxis().SetTitleSize(0.085)
505 hdummy.GetYaxis().SetTitleOffset(0.75)
506 hdummy.GetYaxis().SetLabelSize(0.06)
507 hdummy.GetXaxis().SetLabelSize(0)
509 minyaxis=hdummy.GetYaxis().GetXmin()
510 maxyaxis=hdummy.GetYaxis().GetXmax()
511 rangeyaxis=abs(minyaxis-maxyaxis)
512 hdummy.GetYaxis().SetLimits(minyaxis,maxyaxis+0.50*rangeyaxis)
513 primarypad[var].Update()
518 diffymax=grdiff.GetYaxis().GetXmax()
519 diffymin=grdiff.GetYaxis().GetXmin()
521 grdiff.GetYaxis().SetRangeUser(0.-0.1*abs(diffymax-diffymin),diffymax)
523 grdiff.GetYaxis().SetRangeUser(diffymin,0.+0.1*abs(diffymax-diffymin))
525 grdiff.GetYaxis().SetTitleSize(0.16)
526 grdiff.GetYaxis().SetTitleOffset(.39)
527 grdiff.GetXaxis().SetTitleOffset(0.9)
528 grdiff.GetXaxis().SetTitleSize(0.16)
529 grdiff.GetYaxis().SetLabelSize(0.12)
530 grdiff.GetYaxis().SetNdivisions(8)
531 grdiff.GetXaxis().SetLabelSize(0.12)
533 zeroline[var]=ROOT.TLine(xmin, 0.0, xmax+1, 0.0)
534 zeroline[var].SetLineWidth(2)
539 ratiopad[var].Update()
541 canvases[var].Update()
544 ROOT.gPad.SetTopMargin(0.1)
545 ROOT.gPad.SetLeftMargin(0.2)
546 ROOT.gPad.SetRightMargin(0.1)
547 ROOT.gPad.SetBottomMargin(0.02)
553 ROOT.gPad.SetTopMargin(0.05)
554 ROOT.gPad.SetBottomMargin(0.2)
555 ROOT.gPad.SetLeftMargin(0.2)
556 ROOT.gPad.SetRightMargin(0.1)
565 if options.config ==
'OnlineOffline':
566 descrText +=
'Online - Offline comparison'
569 elif options.config ==
'Reproc':
570 if not options.multicanv:
571 descrText +=
'Reprocessed - Tier0 comparison'
572 if options.label1 ==
'':
574 if options.label2 ==
'':
577 legText1 =
'Beamspots 1'
578 legText2 =
'Beamspots 2'
580 if options.label1 !=
'':
581 legText1 = options.label1
583 if options.label2 !=
'':
584 legText2 = options.label2
587 if options.multicanv:
589 if not options.multicanv:
597 legendList.append([gr1, legText1,
'LP'])
598 legendList.append([gr2, legText2,
'LP'])
599 legendList.append([grdiff,
'Difference',
'LP'])
600 if options.multicanv:
602 elif not options.plotHistos:
605 if options.multicanv:
609 if options.multicanv:
610 primarypad[var].Update()
613 if options.plotHistos:
616 elif options.multicanv:
617 for var,canv
in canvases.items():
625 if not options.multicanv:
626 newText =
'New fits: %i' % numNew
627 oldText =
'Missing fits: %i' %numOld
632 basename=options.outtag
633 if options.config ==
"Reproc":
634 basename=tag2.replace(
".BeamSpotNt-nt.root",
".PlotBeamSpotCompareReproc").
replace(
".MergeNt-nt.root",
".PlotBeamSpotCompareReproc")
635 basename=basename[basename.rfind(
'/')+1:]
636 if options.html
and options.outtag.find(
'/'):
637 basename=options.outtag[:options.outtag.rfind(
'/')+1]+basename+options.htmltag+
"."
638 elif options.runNumber>0:
639 basename+=
str(options.runNumber)
641 elif options.runMin>0:
642 basename+=
str(options.runMin)
644 basename+=
str(options.runMax)
647 for o
in options.output.split(
','):
648 if options.multicanv:
651 if basename.find(
'/')>0:
652 htmlstart=basename.rfind(
'/')+1
653 htmlfilename=basename[htmlstart:-1]+
".html"
655 print (
"writing html file %s" % htmlfilename)
656 for var,canv
in canvases.items():
657 canv.Print(basename+var+o)
658 if o==
".png" and options.html:
659 for var
in [
'posX',
'posY',
'posZ',
'sigmaX',
'sigmaY',
'sigmaZ',
'rhoXY',
'tiltX',
'tiltY',
'k',
'nEvents']:
661 if "pdf" in options.output:
662 html.write(
"<a href=\""+basename+var+
".pdf\"><img src=\""+basename+var+o+
"\" width=\"33%\"></a>")
664 html.write(
"<img src=\""+basename+var+o+
"\" width=\"33%\">")
671 if not options.batch: