9import getopt,sys,os,math
10os.environ[
'TERM'] =
'linux'
13 print (
"How to use: ",sys.argv[0],
" [OPTION] ... ")
14 print (
"Plots the TileCal constants from various schemas / folders / tags as a function of run number/ lumiblock")
16 print (
"-h, --help shows this help")
17 print (
"-T, --tree save all in a tree")
18 print (
"-o, --opt= specify plotting option: line, noline or graph, bin, dist or 2d, default is dist")
19 print (
"-z, --zAxis= specify label for Z axis on 2d plot")
20 print (
"-x, --noTitle create plot without title")
21 print (
"-L, --label= create plot with ATLAS/Tile label at the very top and this additional text")
22 print (
"-M, --label2= second line of the label, if needed")
23 print (
"-P, --print print all the values on the console")
24 print (
"-n, --norm normalize everything to the first point")
25 print (
"-f, --folder= specify status folder to use f.i. /TILE/OFL02/CALIB/CIS/LIN ")
26 print (
"-t, --tag= specify tag to use, f.i. UPD1 or UPD4 or full suffix like RUN2-HLT-UPD1-00")
27 print (
"-b, --begin= specify the starting run number")
28 print (
"-e, --end= sepcify the last run number")
29 print (
"-r, --run= specify fixed run number, will plot constants as a function of lumi")
30 print (
"-l, --lumi= specify lumi block number, default is 0")
31 print (
"-p, --part= specify which partition to plot, only for --plotopt=2d")
32 print (
"-I, --modmin= specify minimal module to use for 2D plot, default is 1")
33 print (
"-A, --modmax= specify maximal module to use for 2D plot, default is 64")
34 print (
"-N, --chmin= specify minimal channel to use for 2D plot, default is 0")
35 print (
"-X, --chmax= specify maximal channel to use for 2D plot, default is 47")
36 print (
"-Y, --gmin= specify minimal gain to use for print option, default is 0")
37 print (
"-Z, --gmax= specify maximal gain to use for print option, default is 1")
38 print (
"-m, --module= specify module to use for 1D plots, default is LBA01")
39 print (
"-c, --chan= specify channel to use for 1D plots, default is 0")
40 print (
"-g, --gain=, -a, --adc= specify adc(gain) to use, default is 0 (low gain)")
41 print (
"-v, --val=, -i, --ind= specify index of value to use, default is 0 ")
42 print (
"-d, --vmin= specify minimal value for plot")
43 print (
"-u, --vmax= specify maximal value for plot")
44 print (
"-C, --cut= specify additional cut on displayed values")
45 print (
"-s, --schema= specify schema to use, like 'COOLONL_TILE/CONDBR2' or 'sqlite://;schema=tileSqlite.db;dbname=CONDBR2' or tileSqlite.db")
46 print (
"-D, --dbname= specify dbname part of schema if schema only contains file name, default is CONDBR2")
47 print (
"-S, --server= specify server - ORACLE or FRONTIER, default is FRONTIER")
50letters =
"hr:l:s:t:f:D:S:a:g:b:e:o:z:xL:M:Pp:Tv:i:m:c:I:A:N:X:Y:Z:d:u:C:n"
51words = [
"help",
"run=",
"lumi=",
"schema=",
"tag=",
"folder=",
"dbname=",
"server=",
"adc=",
"gain=",
"print",
"module=",
"opt=",
"zAxis=",
"noTitle",
"label=",
"label2=",
"chan=",
"begin=",
"end=",
"tree",
"val=",
"ind=",
"part=",
"modmin=",
"modmax=",
"chmin=",
"chmax=",
"gmin=",
"gmax=",
"vmin=",
"vmax=",
"cut=",
"norm"]
53 options,args = getopt.getopt(sys.argv[1:],letters,words)
54except getopt.GetoptError
as err:
64schema =
'COOLOFL_TILE/CONDBR2'
67folderPath =
"/TILE/OFL02/CALIB/CIS/LIN"
105 if o
in (
"-f",
"--folder"):
107 elif o
in (
"-t",
"--tag"):
109 elif o
in (
"-s",
"--schema"):
111 elif o
in (
"-D",
"--dbname"):
113 elif o
in (
"-S",
"--server"):
115 elif o
in (
"-b",
"--begin"):
117 elif o
in (
"-e",
"--end"):
119 elif o
in (
"-r",
"--run"):
122 elif o
in (
"-l",
"--lumi"):
124 elif o
in (
"-m",
"--module"):
126 elif o
in (
"-c",
"--chan"):
130 elif o
in (
"-a",
"--adc",
"-g",
"--gain"):
134 elif o
in (
"-v",
"--val",
"-i",
"--ind"):
136 elif o
in (
"-p",
"--part"):
138 modulename = partname+
"00"
139 elif o
in (
"-I",
"--modmin"):
141 elif o
in (
"-A",
"--modmax"):
143 elif o
in (
"-N",
"--chmin"):
146 elif o
in (
"-X",
"--chmax"):
148 elif o
in (
"-d",
"--vmin"):
150 elif o
in (
"-u",
"--vmax"):
152 elif o
in (
"-Y",
"--gmin"):
155 elif o
in (
"-Z",
"--gmax"):
157 elif o
in (
"-o",
"--opt"):
159 elif o
in (
"-z",
"--zAxis"):
161 elif o
in (
"-x",
"--noTitle"):
163 elif o
in (
"-L",
"--label"):
165 elif o
in (
"-M",
"--label2"):
167 elif o
in (
"-C",
"--cut"):
169 elif o
in (
"-T",
"--tree"):
171 elif o
in (
"-P",
"--print"):
173 elif o
in (
"-n",
"--norm"):
175 elif o
in (
"-h",
"--help"):
179 raise RuntimeError(
"unhandled option")
184 dbname =
'COMP200' if max(begin,runNum)<232000
else 'CONDBR2'
186if 'COOLO' not in schema
and ':' not in schema
and ';' not in schema:
187 schema=
'sqlite://;schema='+schema+
';dbname='+(dbname
if len(dbname)
else 'CONDBR2')
189if schema==
'COOLONL_TILE/COMP200':
190 if not (folderPath.startswith(
'/TILE/ONL01/')
or folderPath.startswith(
'/TILE/OFL01/')):
191 print (
"Folder %s doesn't exist in schema %s " % (folderPath,schema))
194if schema==
'COOLONL_TILE/CONDBR2':
195 if not folderPath.startswith(
'/TILE/ONL01/'):
196 print (
"Folder %s doesn't exist in schema %s, only /TILE/ONL01 " % (folderPath,schema))
199if schema==
'COOLOFL_TILE/COMP200' or schema==
'COOLOFL_TILE/CONDBR2':
200 if not folderPath.startswith(
'/TILE/OFL02/'):
201 print (
"Folder %s doesn't exist in schema %s " % (folderPath,schema))
207if plotopt ==
"print":
209elif plotopt ==
"line":
211elif plotopt ==
"bin":
213elif plotopt ==
"noline" or plotopt ==
"graph":
224chanmin=
max(0,chanmin)
225chanmax=
min(47,chanmax)
226gainmin=
max(0,gainmin)
227gainmax=
min(5,gainmax)
231 partname=partname[:3]
232 modulename=partname+
"00"
234 if len(modulename) < 5
or len(modulename) > 5:
235 print (
"Wrong module name:",modulename)
237 partname=modulename[:3]
238 modnum=modulename[3:]
241 if mod_n<0
or mod_n>64:
242 print (
"Wrong module name:",modulename)
248 print (
"Wrong module name:",modulename)
251part_dict = {
'AUX':0,
'LBA':1,
'LBC':2,
'EBA':3,
'EBC':4,
'ALL':5}
252if partname
in part_dict:
253 ros=part_dict[partname]
263 print (
"Wrong partition name:",partname)
265 print (
"Wrong module name:",modulename)
271 modulename=
"%s%2.2d-%s%2.2d" % (partname,modmin,partname,modmax)
274 modulename=
"%s%2.2d" % (partname,mod_n)
278 channame=
"%2.2d-%2.2d" % (chanmin,chanmax)
281 channame=
"%2.2d" % (chan_n)
287if one_run
and plotopt ==
"dist":
288 print (
"Switching to noline mode")
293 many=(line
or noline)
295if not many
and gain_n==-1:
305 gainname =
"G"+str(gain_n)
307 gainname +=
" val[%d]" % (val_n)
311from ROOT
import TCanvas, TH2D, TGraph, TTree, TLegend, TLatex
312from ROOT
import kTRUE
316from TileCalibBlobPython
import TileCalibTools
317from TileCalibBlobObjs.Classes
import TileCalibUtils
318from TileCalibBlobPython.TileCalibLogger
import getLogger
319log = getLogger(
"PlotCalibFromCool")
321logLevel=logging.DEBUG
322log.setLevel(logLevel)
323log1 = getLogger(
"PlotCalibFromCool")
324log1.setLevel(logLevel)
326folderPath=folderPath.split(
",")
329 ft = TileCalibTools.getFolderTag(schema , fp, tag)
330 log.info(
"Initializing folder %s with tag %s", fp, ft)
332multi=(len(folderPath)>1)
334 print (
"Can not calculate product of "+
" ".join(folderPath)+
" in multi-channel mode")
341if ros!=-1
and modmin==modmax:
344elif ros==0
and modmin==1:
350idb = TileCalibTools.openDbConn(schema,server)
353for (fp,ft)
in zip(folderPath,folderTag):
355 br = TileCalibTools.TileBlobReader(idb,fp, ft)
357 dbobjs = br.getDBobjsWithinRange(COOL_part, COOL_chan)
359 raise Exception(
"No DB objects retrieved when building IOV list!")
360 while dbobjs.goToNext():
361 obj = dbobjs.currentRef()
362 objsince = obj.since()
363 sinceRun = objsince >> 32
364 sinceLum = objsince & 0xFFFFFFFF
365 since = (sinceRun, sinceLum)
366 objuntil = obj.until()
367 untilRun = objuntil >> 32
368 untilLum = objuntil & 0xFFFFFFFF
369 until = (untilRun, untilLum)
377 print (
"Warning: can not read IOVs from input DB file")
383 for iov
in sorted(iovList):
389 for i
in range(len(il)-1):
390 iovList.append(((il[i][0][0],il[i][0][1]),(il[i+1][1][0],il[i+1][1][1])))
392 iovList.append(((il[i][0][0],il[i][0][1]),(0xFFFFFFFF,0xFFFFFFFF)))
395print (
"\nPlotting in %s mode" % plotopt)
401lastrun=TileCalibTools.getLastRunNumber()
416veryEnd = end
if (end<lastrun
or begin>lastrun)
else lastrun
418if begin != be
or end != en:
421 for i,iovs
in enumerate(iovList):
424 if (run<begin
and run>be)
or (run==begin
and lumi<=lumiNum):
427 if run>end
and run<en:
431 print (
"Changing begin run from",begin,
"to",be,
"(start of IOV)")
435 print (
"Changing end run from",end,
"to",en,
"(start of next IOV)")
437 print (
"Changing end run from",end,
"to",en,
"(start of last IOV)")
439 iovList=iovList[ib:ie]
442 if opt2d
and not (line
or noline):
444 print (
"Plotting values for (Run,Lumi) = (%i,%i) " % (runNum,lumiNum))
445 print (
"from IOV",iovList[0])
446 elif len(iovList)<=2
and iovList[-1][0][0]!=runNum:
447 print (
"Too few points to plot value as a function of lumi block")
448 print (
"Just one IOV around run", runNum)
450 print (
"Plotting value as a function of run number")
453 print (
"Plotting Run: %i" % runNum)
454 print (
"IOV around this run")
456 if not line
and runNum!=iovList[-1][0][0]:
460 print (
"Plotting Runs: %i to %i" % (begin, end))
461 print (len(iovList),
"different IOVs in total")
462 if iovList[0][0][0]!=begin
or iovList[-1][0][0]!=end:
463 print (
"Congratulations! You found the bug in this script")
464 print (
"Please, contact authors")
471ROOT.gROOT.SetBatch(kTRUE)
473labels = ROOT.vector(
'string')()
474vals = ROOT.vector(
'double')()
479 titsuff=
" Run " + str(runNum)
481 titsuff=
" Run " + str(runNum) +
" LB " + str(lumiNum)
482titsuff+=
" Tag " +
" ".join(folderTag)
483rlt=titsuff.replace(
" ",
"_").
replace(
"_Tag",
"")
484gtitle = modulename +
" " +
" Channel" +(
"s " if (chanmin!=chanmax)
else " ") + channame +
" " + gainname + titsuff
487 fname=
"%s_g%d_v%d%s_%s" % ( partname,gain_n,val_n,rlt,plotopt)
489 fname=
"%s_ch%s_g%d_v%d%s_%s" % ( modulename,channame,gain_n,val_n,rlt,plotopt)
492 tree_file = ROOT.TFile(fname+
".root",
"RECREATE")
494tree = TTree(
"tree",
"ttree")
495run_n = np.zeros(1, dtype = float)
496lumi_n = np.zeros(1, dtype = float)
497channel_n = np.zeros(1, dtype = float)
498module_n = np.zeros(1, dtype = int)
499ros_n = np.zeros(1, dtype = int)
500value = np.zeros(1, dtype = float)
501scale = np.zeros(1, dtype = float)
503tree.Branch(
"runnumber",run_n,
'runnumber/D')
504tree.Branch(
"luminum",lumi_n,
'luminum/D')
505tree.Branch(
"channel",channel_n,
'channel/D')
506tree.Branch(
"module",module_n,
'module/I')
507tree.Branch(
"ros",ros_n,
'ros/I')
508tree.Branch(
"labels", labels)
509tree.Branch(
"vals", vals)
511 tree.Branch(
"value", value,
'value/D')
513 tree.Branch(
"scale", scale,
'scale/D')
522one_iov = (len(iovList)<2)
529 rl =
"(%i,%i) - (%i,%i)" % (iovs[0][0],iovs[0][1],iovs[1][0],iovs[1][1])
533 rl =
"(%i,%i)" % (run,lumi)
534 if one_run
and run!=runNum:
552 for ros
in range(rosmin,rosmax):
557 for (fp,ft,br)
in zip(folderPath,folderTag,blobReader):
559 flt = br.getDrawer(ros, mod,(run,lumi),
False,
False)
560 if flt
is None or isinstance(flt, (int)):
561 if one_iov
or ros!=0:
562 print (
"%s is missing in DB" % modName)
564 nchan = flt.getNChans()
565 ngain = flt.getNGains()
566 nval = flt.getObjSizeUint32()
567 for chn
in range(chanmin,
min(chanmax+1,nchan)):
568 for adc
in range(gainmin,
min(gainmax+1,ngain)):
569 msg =
"%s %s %2i %1i " % (rl, modName, chn, adc )
570 for val
in range(nval):
571 msg +=
" %f" % flt.getData(chn, adc, val)
572 vals.push_back(flt.getData(chn, adc, val))
574 value[0] *= flt.getData(chn, adc, val)
582 labels.push_back(str(lumi))
584 labels.push_back(str(run))
585 if not multi
or opt2d:
587 if vals.size()>val_n:
596 except Exception
as e:
599 if multi
and not opt2d
and vals.size()>0:
610if not opt2d
and vals.size()>0:
623if plotopt ==
"print":
629ROOT.gROOT.SetStyle(
"Plain")
630ROOT.gROOT.ForceStyle()
631ROOT.gStyle.SetOptStat(0)
632ROOT.gStyle.SetPalette(1)
633ROOT.gStyle.SetOptTitle(setTitle)
637 cut_cond =
"runnumber == " + str(runNum)
639 cut_cond =
"runnumber >= " + str(begin) +
" && " +
"runnumber <= " + str(veryEnd)
647 data =
"vals[" + str(val_n) +
"]"
652 cut_cond =
"(" + cut_cond +
") && (" + cut +
")"
657if (line
or noline)
and not one_run:
670canv = TCanvas(
"PlotCalib",
"plotCalib",0,0,cx,cy)
673 hhh = TH2D(
"hhh",
"hhh",modmax-modmin+1,modmin-0.5,modmax+0.5,chanmax-chanmin+1,chanmin-0.5,chanmax+0.5)
675if not many
and not opt2d:
676 print (
"Plotting",data)
677 print (
"With cut",cut_cond)
679 tree.Draw(data,cut_cond,
"goff",15)
681 tree.Draw(data,cut_cond,
"goff")
683 if tree.GetSelectedRows() <= 0:
684 print (
"Not enough points to plot")
688 if tree.GetSelectedRows() >= 15:
689 print (
"Maximum number of bins is 15")
700 leg = TLegend(0.7,0.7,0.9,0.9)
701 for ros
in range(rosmin,rosmax):
702 for mod
in range(modmin-1, modmax):
703 for chn
in range(chanmin,chanmax+1):
704 for adc
in range(gainmin,gainmax+1):
706 data1 = data.replace(
"%d",str((adc-gainmin)*nval+val_n))
708 cut0 = cut_cond.replace(
"%d",str((adc-gainmin)*nval+val_n))
709 cut1 =
"(ros == %d && module == %d && channel == %d) && %s" % (ros,mod,chn,cut0)
710 tree.Project(
"htemp",data1,cut1)
711 if tree.GetSelectedRows() > 0:
713 gr = TGraph(tree.GetSelectedRows(),tree.GetV2(),tree.GetV1())
715 for ii
in range(len(yy)):
722 leg.AddEntry(gr,
"%s%2.2d ch %2.2d" % ( list(part_dict.keys())[list(part_dict.values()).
index(ros)],mod+1,chn),
"lep")
723 gr.SetMarkerStyle(20)
724 gr.SetMarkerSize(1.3)
725 gr.SetMarkerColor(color)
726 gr.SetLineColor(color)
728 print (
"First plot:")
729 print (
"Plotting",data1)
730 print (
"With cut",cut1)
731 print (
"Note that in TTree module number starts from 0")
733 gr.GetXaxis().SetNoExponent(kTRUE)
735 gr.GetXaxis().SetTitle(
"Lumi")
737 gr.GetXaxis().SetTitle(
"Runs")
750 print (
"Plotting",data)
751 print (
"With cut",cut_cond)
752 print (
"Not enough points to plot")
757 nc=int(math.sqrt(lg))
761 extra = (2+0.4*int(lg/nc+1))
764 grall[0].SetMinimum(vmin-dv)
766 grall[0].SetMinimum(valmin)
768 grall[0].SetMaximum(vmax+dv*extra)
770 grall[0].SetMaximum(valmax)
773 leg.SetX1(0.9-0.1*nc)
774 leg.SetY1(0.9-0.8*(extra-1)/(11+extra))
777 gr = TGraph(tree.GetSelectedRows(),tree.GetV2(),tree.GetV1())
779 gr.SetMarkerStyle(20)
780 gr.SetMarkerSize(1.3)
783 gr.GetXaxis().SetNoExponent(kTRUE)
785 gr.GetXaxis().SetTitle(
"Lumi")
787 gr.GetXaxis().SetTitle(
"Runs")
788 if valmin
is not None:
789 grall[0].SetMinimum(valmin)
790 if valmax
is not None:
791 grall[0].SetMaximum(valmax)
798 nentries = tree.GetEntries()
799 hhh.SetName(modulename)
801 if 'zAxis' in dir()
and len(zAxis)>0:
802 hhh.GetZaxis().SetTitle(zAxis)
803 canv.SetRightMargin(0.14)
804 hhh.GetYaxis().SetTitle(
"Channel")
805 hhh.GetXaxis().SetTitle(
"Module")
808 Matrix = [[1
for y
in range(48)]
for x
in range(64)]
809 for i
in range(nentries):
814 Matrix[x][y] *= vals[0]
815 sc = Matrix[modmax-1][chanmax]
if norm
and Matrix[modmax-1][chanmax]>0
else 1
816 for x
in range(modmin,modmax+1):
817 for y
in range(chanmin,chanmax+1):
818 hhh.Fill(x, y, Matrix[x-1][y]/sc)
820 for i
in range(nentries):
824 hhh.Fill(module_n[0]+1, channel_n[0],vals[val_n]/scale[0])
826 hhh.Fill(module_n[0]+1, channel_n[0],vals[val_n])
828 if valmin
is not None:
829 hhh.SetMinimum(valmin)
830 if valmax
is not None:
831 hhh.SetMaximum(valmax)
835 h = ROOT.gDirectory.Get(
"htemp")
836 h.SetName(modulename)
840 h.GetXaxis().SetTitle(
"Value")
845 h.GetXaxis().SetTitle(
"Run")
847 h.GetXaxis().SetTitle(
"Lumi")
849 h.GetYaxis().SetTitle(
"")
850 h.GetYaxis().SetTitleOffset(1.35)
851 if valmin
is not None:
853 if valmax
is not None:
861 canv.SetTopMargin(0.15)
865 delx = 0.115*696*ROOT.gPad.GetWh()/(472*ROOT.gPad.GetWw())
870 lat.DrawLatex(x,y,
"ATLAS")
874 p.DrawLatex(x+delx,y,
"Preliminary")
875 p.DrawLatex(x,y-dy,
"Tile Calorimeter")
877 ll =
max(len(label),len(label2))
879 x = 0.9 - delx*ll/6.5
880 p.DrawLatex(x,y,label)
881 p.DrawLatex(x,y-dy,label2)
890if valmin
is not None:
891 fname +=
"_min_%s" % (valmin)
892if valmax
is not None:
893 fname +=
"_max_%s" % (valmax)
895canv.Print(fname+
".eps")
896canv.Print(fname+
".png")
904os.system(
"display "+fname+
".png")
static std::string getDrawerString(unsigned int ros, unsigned int drawer)
Return the drawer name, e.g.
static unsigned int getMaxDrawer(unsigned int ros)
Returns the maximal channel number for a given drawer.
std::string replace(std::string s, const std::string &s2, const std::string &s3)